Windows side of the Console rewrite

develop
Petr Mrázek 2011-07-14 04:05:27 +02:00
parent 630b746cfe
commit 792d272fbf
16 changed files with 386 additions and 185 deletions

@ -29,6 +29,9 @@ SET(DFHACK_OUTPUT_DIR "${dfhack_BINARY_DIR}/bin" CACHE STRING "Where should be t
SET(DFHACK_PLUGIN_OUTPUT_DIR "${DFHACK_OUTPUT_DIR}/plugins")
## where to put things during the build (force MSVC to behave)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR})
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR})
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR})
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR})

@ -66,6 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "dfhack/Console.h"
#include "dfhack/extra/stdiostream.h"
#include <cstdio>
#include <cstdlib>
#include <sstream>
@ -78,6 +79,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>
#include <deque>
using namespace DFHack;
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
@ -94,28 +96,7 @@ namespace DFHack
dfout_C = 0;
stream_o = 0;
rawmode = 0;
history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
history_len = 0;
history = NULL;
};
int get_columns(void)
{
winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 80;
return ws.ws_col;
}
int get_rows(void)
{
winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 25;
return ws.ws_row;
}
void clear()
{
const char * clr = "\033c\033[3J\033[H";
write(STDIN_FILENO,clr,strlen(clr));
}
int isUnsupportedTerm(void)
{
@ -132,13 +113,10 @@ namespace DFHack
duthomhas::stdiobuf * stream_o;
termios orig_termios; /* in order to restore at exit */
int rawmode; /* for atexit() function to check if restore is needed*/
int history_max_len;
int history_len;
char **history;
std::deque <std::string> history;
};
}
// FIXME: prime candidate for being a singleton...
Console::Console()
Console::Console():std::ostream(0), std::ios(0)
{
d = new Private();
}
@ -175,18 +153,30 @@ int Console::print( const char* format, ... )
int Console::get_columns(void)
{
return d->get_columns();
winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 80;
return ws.ws_col;
}
int Console::get_rows(void)
{
return d->get_rows();
winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 25;
return ws.ws_row;
}
void Console::clear()
{
*this << "\033c";
*this << "\033[3J\033[H";
if(d->rawmode)
{
const char * clr = "\033c\033[3J\033[H";
::write(STDIN_FILENO,clr,strlen(clr));
}
else
{
*this << "\033c";
*this << "\033[3J\033[H";
}
}
void Console::gotoxy(int x, int y)
@ -344,7 +334,7 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
int fd = STDIN_FILENO;
size_t plen = prompt.size();
size_t pos = 0;
size_t cols = d->get_columns();
size_t cols = get_columns();
int history_index = 0;
/* The latest history entry is always our current buffer, that
@ -386,7 +376,7 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
switch(c) {
case 13: /* enter */
history.pop_front();
d->history.pop_front();
return buffer.size();
case 3: /* ctrl-c */
errno = EAGAIN;
@ -400,41 +390,6 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
prompt_refresh(prompt,buffer,pos);
}
break;
// I fail to see how is this useful to anyone but hardcore emacs users
/*
case 4: // ctrl-d, remove char at right of cursor
if (len > 1 && pos < (len-1)) {
memmove(buf+pos,buf+pos+1,len-pos);
len--;
buf[len] = '\0';
prompt_refresh(prompt,buffer,pos);
} else if (len == 0) {
history_len--;
free(history[history_len]);
return -1;
}
break;
case 20: // ctrl-t
if (pos > 0 && pos < len) {
int aux = buf[pos-1];
buf[pos-1] = buf[pos];
buf[pos] = aux;
if (pos != len-1) pos++;
prompt_refresh(prompt,buffer,pos);
}
break;
case 2: // ctrl-b
goto left_arrow;
case 6: // ctrl-f
goto right_arrow;
case 16: // ctrl-p
seq[1] = 65;
goto up_down_arrow;
case 14: // ctrl-n
seq[1] = 66;
goto up_down_arrow;
break;
*/
case 27: /* escape sequence */
if (::read(fd,seq,2) == -1) break;
if(seq[0] == '[')
@ -460,13 +415,12 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
}
else if (seq[1] == 'A' || seq[1] == 'B')
{
up_down_arrow:
/* up and down arrow: history */
if (history.size() > 1)
if (d->history.size() > 1)
{
/* Update the current history entry before to
* overwrite it with tne next one. */
history[history_index] = buffer;
d->history[history_index] = buffer;
/* Show the new entry */
history_index += (seq[1] == 'A') ? 1 : -1;
if (history_index < 0)
@ -474,12 +428,12 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
history_index = 0;
break;
}
else if (history_index >= history.size())
else if (history_index >= d->history.size())
{
history_index = history.size()-1;
history_index = d->history.size()-1;
break;
}
buffer = history[history_index];
buffer = d->history[history_index];
pos = buffer.size();
prompt_refresh(prompt,buffer,pos);
}
@ -562,11 +516,11 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
// push to front, remove from back if we are above maximum. ignore immediate duplicates
void Console::history_add(const std::string & command)
{
if(history.front() == command)
if(d->history.front() == command)
return;
history.push_front(command);
if(history.size() > 100)
history.pop_back();
d->history.push_front(command);
if(d->history.size() > 100)
d->history.pop_back();
}
int Console::lineedit(const std::string & prompt, std::string & output)

@ -25,6 +25,7 @@ distribution.
#include <conio.h>
#include <stdarg.h>
#include "dfhack/extra/stdiostream.h"
#include < process.h>
#include <errno.h>
#include <stdio.h>
@ -39,21 +40,57 @@ distribution.
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <deque>
using namespace DFHack;
// FIXME: maybe make configurable with an ini option?
#define MAX_CONSOLE_LINES 999;
duthomhas::stdiostream dfout;
FILE * dfout_C = 0;
duthomhas::stdiobuf * stream_o = 0;
namespace DFHack
{
class Private
{
public:
Private()
{
dfout_C = 0;
stream_o = 0;
rawmode = 0;
console_in = 0;
console_out = 0;
ConsoleWindow = 0;
default_attributes = 0;
};
void output(const char* str, size_t len, int x, int y)
{
COORD pos = { (SHORT)x, (SHORT)y };
DWORD count = 0;
WriteConsoleOutputCharacterA(console_out, str, len, pos, &count);
}
FILE * dfout_C;
duthomhas::stdiobuf * stream_o;
int rawmode; /* for atexit() function to check if restore is needed*/
std::deque <std::string> history;
HANDLE console_in;
HANDLE console_out;
HWND ConsoleWindow;
WORD default_attributes;
};
}
Console::Console():std::ostream(0), std::ios(0)
{
d = new Private();
}
HANDLE g_hConsoleOut; // Handle to debug console
HWND ConsoleWindow;
WORD default_attributes;
Console::~Console()
{
}
// FIXME: prime candidate for being a singleton... indeed.
Console::Console()
bool Console::init(void)
{
int hConHandle;
long lStdHandle;
@ -63,25 +100,26 @@ Console::Console()
// Allocate a console!
AllocConsole();
ConsoleWindow = GetConsoleWindow();
HMENU hm = GetSystemMenu(ConsoleWindow,false);
d->ConsoleWindow = GetConsoleWindow();
HMENU hm = GetSystemMenu(d->ConsoleWindow,false);
DeleteMenu(hm, SC_CLOSE, MF_BYCOMMAND);
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
default_attributes = coninfo.wAttributes;
d->default_attributes = coninfo.wAttributes;
coninfo.dwSize.Y = MAX_CONSOLE_LINES; // How many lines do you want to have in the console buffer
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDOUT to the console
g_hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
d->console_out = GetStdHandle(STD_OUTPUT_HANDLE);
lStdHandle = (long)d->console_out;
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
dfout_C = _fdopen( hConHandle, "w" );
setvbuf( dfout_C, NULL, _IONBF, 0 );
d->dfout_C = _fdopen( hConHandle, "w" );
setvbuf( d->dfout_C, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
d->console_in = GetStdHandle(STD_INPUT_HANDLE);
lStdHandle = (long)d->console_in;
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
@ -92,16 +130,40 @@ Console::Console()
std::ios::sync_with_stdio();
// make our own weird streams so our IO isn't redirected
stream_o = new duthomhas::stdiobuf(dfout_C);
dfout.rdbuf(stream_o);
std::cin.tie(&dfout);
d->stream_o = new duthomhas::stdiobuf(d->dfout_C);
rdbuf(d->stream_o);
std::cin.tie(this);
clear();
// result is a terminal controlled by the parasitic code!
return true;
}
Console::~Console()
bool Console::shutdown(void)
{
FreeConsole();
return true;
}
int Console::print( const char* format, ... )
{
va_list args;
va_start( args, format );
int ret = vfprintf( d->dfout_C, format, args );
va_end( args );
return ret;
}
int Console::get_columns(void)
{
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
GetConsoleScreenBufferInfo(d->console_out, &inf);
return (size_t)inf.dwSize.X;
}
int Console::get_rows(void)
{
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
GetConsoleScreenBufferInfo(d->console_out, &inf);
return (size_t)inf.dwSize.Y;
}
void Console::clear()
@ -124,7 +186,7 @@ void Console::color(int index)
void Console::reset_color( void )
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, default_attributes);
SetConsoleTextAttribute(hConsole, d->default_attributes);
}
@ -153,4 +215,178 @@ void Console::cursor(bool enable)
void Console::msleep (unsigned int msec)
{
Sleep(msec);
}
int Console::enable_raw()
{
return 0;
}
void Console::disable_raw()
{
/* Nothing to do yet */
}
void Console::prompt_refresh( const std::string& prompt, const std::string& buffer, size_t pos)
{
size_t cols = get_columns();
size_t plen = prompt.size();
const char * buf = buffer.c_str();
size_t len = buffer.size();
while ((plen + pos) >= cols)
{
buf++;
len--;
pos--;
}
while (plen + len > cols)
{
len--;
}
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
GetConsoleScreenBufferInfo(d->console_out, &inf);
d->output(prompt.c_str(), plen, 0, inf.dwCursorPosition.Y);
d->output(buf, len, plen, inf.dwCursorPosition.Y);
if (plen + len < (size_t)inf.dwSize.X)
{
/* Blank to EOL */
char* tmp = (char*)malloc(inf.dwSize.X - (plen + len));
memset(tmp, ' ', inf.dwSize.X - (plen + len));
d->output(tmp, inf.dwSize.X - (plen + len), len + plen, inf.dwCursorPosition.Y);
free(tmp);
}
inf.dwCursorPosition.X = (SHORT)(pos + plen);
SetConsoleCursorPosition(d->console_out, inf.dwCursorPosition);
}
int Console::prompt_loop(const std::string & prompt, std::string & buffer)
{
buffer.clear(); // make sure the buffer is empty!
size_t plen = prompt.size();
size_t pos = 0;
int history_index = 0;
/* The latest history entry is always our current buffer, that
* initially is just an empty string. */
history_add("");
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
GetConsoleScreenBufferInfo(d->console_out, &inf);
size_t cols = inf.dwSize.X;
d->output(prompt.c_str(), plen, 0, inf.dwCursorPosition.Y);
inf.dwCursorPosition.X = (SHORT)plen;
SetConsoleCursorPosition(d->console_out, inf.dwCursorPosition);
while (1)
{
INPUT_RECORD rec;
DWORD count;
ReadConsoleInputA(d->console_in, &rec, 1, &count);
if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown)
continue;
switch (rec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_RETURN: // enter
d->history.pop_front();
return buffer.size();
case VK_BACK: // backspace
if (pos > 0 && buffer.size() > 0)
{
buffer.erase(pos-1,1);
pos--;
prompt_refresh(prompt,buffer,pos);
}
break;
case VK_LEFT: // left arrow
if (pos > 0)
{
pos--;
prompt_refresh(prompt,buffer,pos);
}
break;
case VK_RIGHT: // right arrow
if (pos != buffer.size())
{
pos++;
prompt_refresh(prompt,buffer,pos);
}
break;
case VK_UP:
case VK_DOWN:
/* up and down arrow: history */
if (d->history.size() > 1)
{
/* Update the current history entry before to
* overwrite it with tne next one. */
d->history[history_index] = buffer;
/* Show the new entry */
history_index += (rec.Event.KeyEvent.wVirtualKeyCode == VK_UP) ? 1 : -1;
if (history_index < 0)
{
history_index = 0;
break;
}
else if (history_index >= d->history.size())
{
history_index = d->history.size()-1;
break;
}
buffer = d->history[history_index];
pos = buffer.size();
prompt_refresh(prompt,buffer,pos);
}
break;
case VK_DELETE:
// delete
if (buffer.size() > 0 && pos < buffer.size())
{
buffer.erase(pos,1);
prompt_refresh(prompt,buffer,pos);
}
break;
case VK_HOME:
pos = 0;
prompt_refresh(prompt,buffer,pos);
break;
case VK_END:
pos = buffer.size();
prompt_refresh(prompt,buffer,pos);
break;
default:
if (rec.Event.KeyEvent.uChar.AsciiChar < ' ' ||
rec.Event.KeyEvent.uChar.AsciiChar > '~')
continue;
if (buffer.size() == pos)
buffer.append(1,rec.Event.KeyEvent.uChar.AsciiChar);
else
buffer.insert(pos,1,rec.Event.KeyEvent.uChar.AsciiChar);
pos++;
prompt_refresh(prompt,buffer,pos);
break;
}
}
}
// push to front, remove from back if we are above maximum. ignore immediate duplicates
void Console::history_add(const std::string & command)
{
if(d->history.front() == command)
return;
d->history.push_front(command);
if(d->history.size() > 100)
d->history.pop_back();
}
int Console::lineedit(const std::string & prompt, std::string & output)
{
output.clear();
int count;
if (enable_raw() == -1)
return -1;
count = prompt_loop(prompt,output);
disable_raw();
*this << std::endl;
return count;
}

@ -121,22 +121,24 @@ int fHKthread(void * iodata)
// A thread function... for the interactive console.
int fIOthread(void * iodata)
{
Core * core = ((IODATA*) iodata)->core;
IODATA * iod = ((IODATA*) iodata);
Core * core = iod->core;
PluginManager * plug_mgr = ((IODATA*) iodata)->plug_mgr;
Console & con = core->con;
if(plug_mgr == 0 || core == 0)
{
core->con << "Something horrible happened to the plugin manager in Core's constructor..." << std::endl;
con.print("Something horrible happened to the plugin manager in Core's constructor...\n");
return 0;
}
core->con.print("DFHack is ready. Have a nice day! Type in '?' or 'help' for help.\n");
con.print("DFHack is ready. Have a nice day! Type in '?' or 'help' for help.\n");
//dfterm << << endl;
int clueless_counter = 0;
while (true)
{
string command = "";
core->con.lineedit("[DFHack]# ",command);
core->con.history_add(command);
//core->con <<"[DFHack]# ";
con.lineedit("[DFHack]# ",command);
con.history_add(command);
//con <<"[DFHack]# ";
//char * line = linenoise("[DFHack]# ", core->con.dfout_C);
// dfout <<"[DFHack]# ";
/*
@ -149,20 +151,20 @@ int fIOthread(void * iodata)
//getline(cin, command);
if(command=="help" || command == "?")
{
core->con << "Available commands" << endl;
core->con << "------------------" << endl;
con.print("Available commands\n");
con.print("------------------\n");
for(int i = 0; i < plug_mgr->size();i++)
{
const Plugin * plug = (plug_mgr->operator[](i));
if(!plug->size())
continue;
core->con << "Plugin " << plug->getName() << " :" << std::endl;
con.print("Plugin %s :\n", plug->getName().c_str());
for (int j = 0; j < plug->size();j++)
{
const PluginCommand & pcmd = (plug->operator[](j));
core->con << setw(12) << pcmd.name << "| " << pcmd.description << endl;
con << setw(12) << pcmd.name << "| " << pcmd.description << endl;
}
core->con << endl;
con << endl;
}
}
else if( command == "" )
@ -184,18 +186,18 @@ int fIOthread(void * iodata)
command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED)
{
core->con << "Invalid command." << endl;
con << "Invalid command." << endl;
clueless_counter ++;
}
else if(res == CR_FAILURE)
{
core->con << "ERROR!" << endl;
con << "ERROR!" << endl;
}
}
}
if(clueless_counter == 3)
{
core->con << "Do 'help' or '?' for the list of available commands." << endl;
con << "Do 'help' or '?' for the list of available commands." << endl;
clueless_counter = 0;
}
}

@ -538,6 +538,10 @@ DFhackCExport size_t SDL_strlcpy(char *dst, const char *src, size_t maxlen)
if(!_SDL_strlcpy)
{
HMODULE realSDLlib = LoadLibrary("SDLreal.dll");
if(!realSDLlib)
{
exit(-111);
}
_SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy");
}
return _SDL_strlcpy(dst,src,maxlen);
@ -698,6 +702,7 @@ bool FirstCall()
fprintf(stderr, "Can't load SDLreal.dll\n");
return 0;
}
fprintf(stderr, "FirstCall()\n");
// stuff for DF
_SDL_AddTimer = (void*(*)(uint32_t, void*, void*)) GetProcAddress(realSDLlib,"SDL_AddTimer");
_SDL_CondSignal = (int (*)(SDL::Cond*))GetProcAddress(realSDLlib,"SDL_CondSignal");

@ -71,6 +71,7 @@ bool hasEnding (std::string const &fullString, std::string const &ending)
Plugin::Plugin(Core * core, const std::string & file)
{
filename = file;
Console & con = core->con;
plugin_lib = 0;
plugin_init = 0;
plugin_shutdown = 0;
@ -80,20 +81,20 @@ Plugin::Plugin(Core * core, const std::string & file)
DFLibrary * plug = OpenPlugin(file.c_str());
if(!plug)
{
core->con << "Can't load plugin " << filename << endl;
con << "Can't load plugin " << filename << endl;
return;
}
const char * (*_PlugName)() =(const char * (*)()) LookupPlugin(plug, "plugin_name");
if(!_PlugName)
{
core->con << "Plugin " << filename << " has no name." << endl;
con << "Plugin " << filename << " has no name." << endl;
ClosePlugin(plug);
return;
}
plugin_init = (command_result (*)(Core *, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init");
if(!plugin_init)
{
core->con << "Plugin " << filename << " has no init function." << endl;
con << "Plugin " << filename << " has no init function." << endl;
ClosePlugin(plug);
return;
}

@ -168,13 +168,13 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
string type = pClassEntry->Value();
const char *cstr_name = pClassEntry->Attribute("name");
const char *cstr_vtable = pClassEntry->Attribute("vtable");
uint32_t vtable = 0;
uint32_t vtable_num = 0;
if(cstr_vtable)
vtable = strtol(cstr_vtable, NULL, 16);
vtable_num = strtol(cstr_vtable, NULL, 16);
// it's a simple class
if(type== "class")
{
mem->setClass(cstr_name, vtable);
mem->setClass(cstr_name, vtable_num);
}
// it's a multi-type class
else if (type == "multiclass")
@ -184,7 +184,7 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
uint32_t typeoffset = 0;
if(cstr_typeoffset)
typeoffset = strtol(cstr_typeoffset, NULL, 16);
t_class * mclass = mem->setClass(cstr_name, vtable, typeoffset);
t_class * mclass = mem->setClass(cstr_name, vtable_num, typeoffset);
// parse class sub-entries
pClassSubEntry = pClassEntry->FirstChildElement();
for(;pClassSubEntry;pClassSubEntry=pClassSubEntry->NextSiblingElement())

@ -25,13 +25,11 @@ distribution.
#pragma once
#include "dfhack/Pragma.h"
#include "dfhack/Export.h"
#include "dfhack/extra/stdiostream.h"
#include <deque>
#include <ostream>
namespace DFHack
{
class Private;
class DFHACK_EXPORT Console : public duthomhas::stdiostream
class DFHACK_EXPORT Console : public std::ostream
{
public:
Console();
@ -69,7 +67,6 @@ namespace DFHack
void prompt_refresh( const std::string & prompt, const std::string & buffer, size_t pos);
int enable_raw();
void disable_raw();
std::deque <std::string> history;
void history_clear();
Private * d;
};

@ -50,7 +50,6 @@ namespace DFHack
class Constructions;
class VersionInfo;
class VersionInfoFactory;
class Console;
class PluginManager;
class Core;
// anon type, pretty much

@ -213,7 +213,7 @@ protected:
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out
) {
pushbacks.clear();
return std::fseek( fp, position, SEEK_SET )
return std::fseek( fp, (long) position, SEEK_SET )
? (-1)
: std::ftell( fp );
}

@ -787,7 +787,7 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector <t_vein *>
if(veins) veins->clear();
if(ices) ices->clear();
if(splatter) splatter->clear();
if(grass) splatter->clear();
if(grass) grass->clear();
if(constructions) constructions->clear();
Private::t_offsets &off = d->offsets;

@ -106,10 +106,10 @@ bool Translation::Start()
for (uint32_t i = 0;i < genericVec.size();i++)
{
uint32_t genericNamePtr = genericVec.at(i);
for(int i=0; i<10;i++)
for(int j=0; j<10;i++)
{
string word = p->readSTLString (genericNamePtr + i * d->sizeof_string);
translations[i].push_back (word);
string word = p->readSTLString (genericNamePtr + j * d->sizeof_string);
translations[j].push_back (word);
}
}

@ -89,6 +89,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
bool showPlants = true;
bool showSlade = true;
bool showTemple = true;
Console & con = c->con;
if(parameters.size() && parameters[0] == "all")
{
showHidden = true;
@ -98,7 +99,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
DFHack::Maps *maps = c->getMaps();
if (!maps->Start())
{
c->con << "Cannot get map info!" << std::endl;
con << "Cannot get map info!" << std::endl;
c->Resume();
return CR_FAILURE;
}
@ -108,13 +109,13 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
DFHack::Materials *mats = c->getMaterials();
if (!mats->ReadInorganicMaterials())
{
c->con << "Unable to read inorganic material definitons!" << std::endl;
con << "Unable to read inorganic material definitons!" << std::endl;
c->Resume();
return CR_FAILURE;
}
if (showPlants && !mats->ReadOrganicMaterials())
{
c->con << "Unable to read organic material definitons; plants won't be listed!" << std::endl;
con << "Unable to read organic material definitons; plants won't be listed!" << std::endl;
showPlants = false;
}
@ -134,21 +135,21 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
if (!(showSlade && maps->ReadGlobalFeatures(globalFeatures)))
{
c->con << "Unable to read global features; slade won't be listed!" << std::endl;
con << "Unable to read global features; slade won't be listed!" << std::endl;
}
if (!maps->ReadLocalFeatures(localFeatures))
{
c->con << "Unable to read local features; adamantine "
<< (showTemple ? "and demon temples " : "")
<< "won't be listed!" << std::endl;
con << "Unable to read local features; adamantine "
<< (showTemple ? "and demon temples " : "")
<< "won't be listed!" << std::endl;
}
uint32_t vegCount = 0;
DFHack::Vegetation *veg = c->getVegetation();
if (showPlants && !veg->Start())
{
c->con << "Unable to read vegetation; plants won't be listed!" << std::endl;
con << "Unable to read vegetation; plants won't be listed!" << std::endl;
}
for(uint32_t z = 0; z < z_max; z++)
@ -217,7 +218,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
if (!info)
{
c->con << "Bad type: " << type << std::endl;
con << "Bad type: " << type << std::endl;
continue;
}
@ -306,39 +307,39 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
MatMap::const_iterator it;
c->con << "Base materials:" << std::endl;
con << "Base materials:" << std::endl;
for (it = baseMats.begin(); it != baseMats.end(); ++it)
{
c->con << std::setw(25) << DFHack::TileMaterialString[it->first] << " : " << it->second << std::endl;
con << std::setw(25) << DFHack::TileMaterialString[it->first] << " : " << it->second << std::endl;
}
c->con << std::endl << "Layer materials:" << std::endl;
printMats(c->con, layerMats, mats->inorganic);
con << std::endl << "Layer materials:" << std::endl;
printMats(con, layerMats, mats->inorganic);
c->con << "Vein materials:" << std::endl;
printMats(c->con, veinMats, mats->inorganic);
con << "Vein materials:" << std::endl;
printMats(con, veinMats, mats->inorganic);
if (showPlants)
{
c->con << "Shrubs:" << std::endl;
printMats(c->con, plantMats, mats->organic);
c->con << "Wood in trees:" << std::endl;
printMats(c->con, treeMats, mats->organic);
con << "Shrubs:" << std::endl;
printMats(con, plantMats, mats->organic);
con << "Wood in trees:" << std::endl;
printMats(con, treeMats, mats->organic);
}
if (hasAquifer)
{
c->con << "Has aquifer" << std::endl;
con << "Has aquifer" << std::endl;
}
if (hasDemonTemple)
{
c->con << "Has demon temple" << std::endl;
con << "Has demon temple" << std::endl;
}
if (hasLair)
{
c->con << "Has lair" << std::endl;
con << "Has lair" << std::endl;
}
// Cleanup
@ -349,6 +350,6 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
mats->Finish();
maps->Finish();
c->Resume();
c->con << std::endl;
con << std::endl;
return CR_OK;
}

@ -101,10 +101,10 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
{
no_hell = false;
}
Console & con = c->con;
if(revealed != NOT_REVEALED)
{
c->con << "Map is already revealed or this is a different map." << std::endl;
con << "Map is already revealed or this is a different map." << std::endl;
return CR_FAILURE;
}
@ -115,20 +115,20 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF)
{
c->con << "Only in fortress mode." << std::endl;
con << "Only in fortress mode." << std::endl;
c->Resume();
return CR_FAILURE;
}
if(!Maps->Start())
{
c->con << "Can't init map." << std::endl;
con << "Can't init map." << std::endl;
c->Resume();
return CR_FAILURE;
}
if(no_hell && !Maps->StartFeatures())
{
c->con << "Unable to read local features; can't reveal map safely" << std::endl;
con << "Unable to read local features; can't reveal map safely" << std::endl;
c->Resume();
return CR_FAILURE;
}
@ -175,19 +175,19 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
World->SetPauseState(true);
}
c->Resume();
c->con << "Map revealed." << std::endl;
con << "Map revealed." << std::endl;
if(!no_hell)
c->con << "Unpausing can unleash the forces of hell, so it has been temporarily disabled." << std::endl;
c->con << "Run 'unreveal' to revert to previous state." << std::endl;
con << "Unpausing can unleash the forces of hell, so it has been temporarily disabled." << std::endl;
con << "Run 'unreveal' to revert to previous state." << std::endl;
return CR_OK;
}
DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
{
DFHack::designations40d designations;
Console & con = c->con;
if(!revealed)
{
c->con << "There's nothing to revert!" << std::endl;
con << "There's nothing to revert!" << std::endl;
return CR_FAILURE;
}
c->Suspend();
@ -197,14 +197,14 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
World->ReadGameMode(gm);
if(gm.g_mode != GAMEMODE_DWARF)
{
c->con << "Only in fortress mode." << std::endl;
con << "Only in fortress mode." << std::endl;
c->Resume();
return CR_FAILURE;
}
Maps = c->getMaps();
if(!Maps->Start())
{
c->con << "Can't init map." << std::endl;
con << "Can't init map." << std::endl;
c->Resume();
return CR_FAILURE;
}
@ -214,7 +214,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
Maps->getSize(x_max_b,y_max_b,z_max_b);
if(x_max != x_max_b || y_max != y_max_b || z_max != z_max_b)
{
c->con << "The map is not of the same size..." << std::endl;
con << "The map is not of the same size..." << std::endl;
c->Resume();
return CR_FAILURE;
}
@ -233,7 +233,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
// give back memory.
hidesaved.clear();
revealed = NOT_REVEALED;
c->con << "Map hidden!" << std::endl;
con << "Map hidden!" << std::endl;
c->Resume();
return CR_OK;
}

@ -43,13 +43,15 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
if(parameters.size() && parameters[0]=="x")
updown = true;
Console & con = c->con;
c->Suspend();
DFHack::Maps * Maps = c->getMaps();
DFHack::Gui * Gui = c->getGui();
// init the map
if(!Maps->Start())
{
c->con << "Can't init map. Make sure you have a map loaded in DF.\n";
con << "Can't init map. Make sure you have a map loaded in DF.\n";
c->Resume();
return CR_FAILURE;
}
@ -61,14 +63,14 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
Gui->getCursorCoords(cx,cy,cz);
while(cx == -30000)
{
c->con << "Cursor is not active. Point the cursor at a vein.\n";
con << "Cursor is not active. Point the cursor at a vein.\n";
c->Resume();
return CR_FAILURE;
}
DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
if(xy.x == 0 || xy.x == tx_max - 1 || xy.y == 0 || xy.y == ty_max - 1)
{
c->con << "I won't dig the borders. That would be cheating!\n";
con << "I won't dig the borders. That would be cheating!\n";
c->Resume();
return CR_FAILURE;
}
@ -78,12 +80,12 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
int16_t veinmat = MCache->veinMaterialAt(xy);
if( veinmat == -1 )
{
c->con << "This tile is not a vein.\n";
con << "This tile is not a vein.\n";
delete MCache;
c->Resume();
return CR_FAILURE;
}
c->con.print("%d/%d/%d tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);
con.print("%d/%d/%d tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);
stack <DFHack::DFCoord> flood;
flood.push(xy);

@ -38,6 +38,7 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
DFhackCExport command_result weather (Core * c, vector <string> & parameters)
{
Console & con = c->con;
bool lock = false;
bool unlock = false;
bool snow = false;
@ -58,7 +59,7 @@ DFhackCExport command_result weather (Core * c, vector <string> & parameters)
}
if(lock && unlock)
{
c->con << "Lock or unlock? DECIDE!" << std::endl;
con << "Lock or unlock? DECIDE!" << std::endl;
return CR_FAILURE;
}
int cnt = 0;
@ -67,7 +68,7 @@ DFhackCExport command_result weather (Core * c, vector <string> & parameters)
cnt += clear;
if(cnt > 1)
{
c->con << "Rain, snow or clear sky? DECIDE!" << std::endl;
con << "Rain, snow or clear sky? DECIDE!" << std::endl;
return CR_FAILURE;
}
bool something = lock || unlock || rain || snow || clear;
@ -75,14 +76,14 @@ DFhackCExport command_result weather (Core * c, vector <string> & parameters)
DFHack::World * w = c->getWorld();
if(!w->wmap)
{
c->con << "Weather support seems broken :(" << std::endl;
con << "Weather support seems broken :(" << std::endl;
c->Resume();
return CR_FAILURE;
}
if(!something)
{
// paint weather map
c->con << "Weather map (C = clear, R = rain, S = snow):" << std::endl;
con << "Weather map (C = clear, R = rain, S = snow):" << std::endl;
for(int y = 0; y<5;y++)
{
for(int x = 0; x<5;x++)
@ -90,20 +91,20 @@ DFhackCExport command_result weather (Core * c, vector <string> & parameters)
switch((*w->wmap)[x][y])
{
case DFHack::CLEAR:
c->con << "C ";
con << "C ";
break;
case DFHack::RAINING:
c->con << "R ";
con << "R ";
break;
case DFHack::SNOWING:
c->con << "S ";
con << "S ";
break;
default:
c->con << (int) (*w->wmap)[x][y] << " ";
con << (int) (*w->wmap)[x][y] << " ";
break;
}
}
c->con << std::endl;
con << std::endl;
}
}
else
@ -111,17 +112,17 @@ DFhackCExport command_result weather (Core * c, vector <string> & parameters)
// weather changing action!
if(rain)
{
c->con << "Here comes the rain." << std::endl;
con << "Here comes the rain." << std::endl;
w->SetCurrentWeather(RAINING);
}
if(snow)
{
c->con << "Snow everywhere!" << std::endl;
con << "Snow everywhere!" << std::endl;
w->SetCurrentWeather(SNOWING);
}
if(clear)
{
c->con << "Suddenly, sunny weather!" << std::endl;
con << "Suddenly, sunny weather!" << std::endl;
w->SetCurrentWeather(CLEAR);
}
// FIXME: weather lock needs map ID to work reliably... needs to be implemented.