Now works on Windows again, some more cleanups, added a singleton Core object for holding all the globals.

develop
Petr Mrázek 2011-06-14 16:13:28 +02:00
parent 0a428b509e
commit 22b79bb46e
24 changed files with 309 additions and 3964 deletions

@ -51,6 +51,7 @@ SET(PROJECT_SRCS
VersionInfo.cpp
VersionInfoFactory.cpp
Context.cpp
Core.cpp
TileTypes.cpp
ContextShared.cpp
@ -79,7 +80,7 @@ SET(PROJECT_HDRS_LINUX
)
SET(PROJECT_HDRS_WINDOWS
include/dfhack/DFstdint_win.h
include/dfhack/stdint_win.h
)
SET(PROJECT_SRCS_LINUX

@ -48,7 +48,7 @@ Context::Context (Process* p) : d (new DFContextShared())
Context::~Context()
{
Detach();
//Detach();
delete d;
}
@ -99,10 +99,12 @@ bool Context::isAttached()
bool Context::Suspend()
{
// return d->p->suspend();
return true;
}
bool Context::AsyncSuspend()
{
// return d->p->asyncSuspend();
return true;
}
bool Context::Resume()
@ -112,6 +114,7 @@ bool Context::Resume()
d->allModules[i]->OnResume();
}
//return d->p->resume();
return true;
}
/*
bool Context::ForceResume()
@ -168,7 +171,6 @@ MODULE_GETTER(Creatures);
MODULE_GETTER(Engravings);
MODULE_GETTER(Maps);
MODULE_GETTER(Gui);
MODULE_GETTER(WindowIO);
MODULE_GETTER(World);
MODULE_GETTER(Materials);
MODULE_GETTER(Items);

@ -36,138 +36,20 @@ distribution.
#include <vector>
#include <string>
#include <map>
#include "core.h"
#include "DFHack.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/Context.h"
#include "dfhack/modules/Vegetation.h"
#include "dfhack/Core.h"
#include <iostream>
#define DFhackCExport extern "C" __attribute__ ((visibility("default")))
int errorstate = 0;
bool inited = 0;
DFHack::VersionInfoFactory * vif = 0;
DFHack::Process * p = 0;
DFHack::Context * c = 0;
DFHack::Gui * gui = 0;
DFHack::Maps * maps = 0;
DFHack::Vegetation * veg = 0;
uint32_t OS_getPID()
{
return getpid();
}
void SHM_Init ( void )
{
// check that we do this only once per process
if(inited)
{
std::cerr << "SDL_Init was called twice or more!" << std::endl;
return;
}
vif = new DFHack::VersionInfoFactory("Memory.xml");
p = new DFHack::Process(vif);
if (!p->isIdentified())
{
std::cerr << "Couldn't identify this version of DF." << std::endl;
errorstate = 1;
}
c = new DFHack::Context(p);
gui = c->getGui();
gui->Start();
veg = c->getVegetation();
veg->Start();
maps = c->getMaps();
maps->Start();
inited = true;
}
int32_t x = 0,y = 0,z = 0;
int32_t xo = 0,yo = 0,zo = 0;
void print_tree( DFHack::df_plant & tree)
{
//DFHack::Materials * mat = DF->getMaterials();
printf("%d:%d = ",tree.type,tree.material);
if(tree.watery)
{
std::cout << "near-water ";
}
//std::cout << mat->organic[tree.material].id << " ";
if(!tree.is_shrub)
{
std::cout << "tree";
}
else
{
std::cout << "shrub";
}
std::cout << std::endl;
printf("Grow counter: 0x%08x\n", tree.grow_counter);
printf("temperature 1: %d\n", tree.temperature_1);
printf("temperature 2: %d\n", tree.temperature_2);
printf("On fire: %d\n", tree.is_burning);
printf("hitpoints: 0x%08x\n", tree.hitpoints);
printf("update order: %d\n", tree.update_order);
printf("Address: 0x%x\n", &tree);
//hexdump(DF,tree.address,13*16);
}
void SHM_Act()
{
maps->Start();
gui->getCursorCoords(x,y,z);
if(x != xo || y!= yo || z != zo)
{
xo = x;
yo = y;
zo = z;
std::cout << "Cursor: " << x << "/" << y << "/" << z << std::endl;
if(x != -30000)
{
std::vector <DFHack::df_plant *> * vec;
if(maps->ReadVegetation(x/16,y/16,z,vec))
{
for(size_t i = 0; i < vec->size();i++)
{
DFHack::df_plant * p = vec->at(i);
if(p->x == x && p->y == y && p->z == z)
{
print_tree(*p);
}
}
}
else
std::cout << "No veg vector..." << std::endl;
}
}
};
void SHM_Destroy ( void )
{
if(inited && !errorstate)
{
inited = false;
}
}
/*******************************************************************************
* SDL part starts here *
*******************************************************************************/
DFhackCExport int SDL_NumJoysticks(void)
{
if(errorstate)
return -1;
if(!inited)
{
SHM_Init();
return -2;
}
SHM_Act();
return -3;
DFHack::Core & c = DFHack::Core::getInstance();
return c.Update();
}
// ptr to the real functions
@ -210,11 +92,8 @@ DFhackCExport int SDL_Flip(void * some_ptr)
// hook - called at program exit
DFhackCExport void SDL_Quit(void)
{
if(!errorstate)
{
SHM_Destroy();
errorstate = true;
}
DFHack::Core & c = DFHack::Core::getInstance();
c.Shutdown();
if(_SDL_Quit)
{
_SDL_Quit();
@ -239,30 +118,21 @@ DFhackCExport int SDL_Init(uint32_t flags)
{
// bail, this would be a disaster otherwise
fprintf(stderr,"dfhack: something went horribly wrong\n");
errorstate = true;
exit(1);
}
//SHM_Init();
return _SDL_Init(flags);
}
//*/
/*******************************************************************************
* NCURSES part starts here *
*******************************************************************************/
/*
static int (*_refresh)(void) = 0;
DFhackCExport int refresh (void)
{
if(_refresh)
{
/*
if(!errorstate)
{
SHM_Act();
}
counter ++;
*/
return _refresh();
}
return 0;
@ -273,7 +143,7 @@ DFhackCExport int endwin (void)
{
if(!errorstate)
{
SHM_Destroy();
HOOK_Shutdown();
errorstate = true;
}
if(_endwin)
@ -305,3 +175,4 @@ DFhackCExport WINDOW * initscr (void)
//SHM_Init();
return _initscr();
}
*/

@ -31,226 +31,83 @@ distribution.
#include <windows.h>
#include <stdarg.h>
#define DFhackCExport extern "C" __declspec(dllexport)
#include "dfhack/DFIntegers.h"
#include <vector>
#include <string>
#include "shms.h"
#include "mod-core.h"
#include < process.h>
#include <errno.h>
#include <stdio.h>
int errorstate = 0;
char *shm = 0;
int shmid = 0;
bool inited = 0;
HANDLE shmHandle = 0;
HANDLE DFSVMutex = 0;
HANDLE DFCLMutex[SHM_MAX_CLIENTS];
HANDLE DFCLSuspendMutex[SHM_MAX_CLIENTS];
int held_DFCLSuspendMutex[SHM_MAX_CLIENTS];
int numheld = SHM_MAX_CLIENTS;
bool FirstCall();
void OS_lockSuspendLock(int which)
{
if(numheld == SHM_MAX_CLIENTS)
return;
// lock not held by server and can be picked up. OK.
if(held_DFCLSuspendMutex[which] == 0)
{
uint32_t state = WaitForSingleObject(DFCLSuspendMutex[which],INFINITE);
if(state == WAIT_ABANDONED || state == WAIT_OBJECT_0)
{
held_DFCLSuspendMutex[which] = 1;
numheld++;
return;
}
// lock couldn't be picked up!
errorstate = 1;
MessageBox(0,"Suspend lock locking failed. Further communication disabled!","Error", MB_OK);
return;
}
errorstate = 1;
MessageBox(0,"Server tried to lock already locked suspend lock? Further communication disabled!","Error", MB_OK);
return;
}
void OS_releaseSuspendLock(int which)
{
/*
if(which >=0 && which < SHM_MAX_CLIENTS)
return;
*/
if(numheld != SHM_MAX_CLIENTS)
{
MessageBox(0,"Locking system failure. Further communication disabled!","Error", MB_OK);
errorstate = 1;
return;
}
// lock hel by server and can be released -> OK
if(held_DFCLSuspendMutex[which] == 1 && ReleaseMutex(DFCLSuspendMutex[which]))
{
numheld--;
held_DFCLSuspendMutex[which] = 0;
}
// locked and not can't be released? FAIL!
else if (held_DFCLSuspendMutex[which] == 1)
{
MessageBox(0,"Suspend lock failed to unlock. Further communication disabled!","Error", MB_OK);
return;
}
}
void SHM_Init ( void )
{
// check that we do this only once per process
if(inited)
{
MessageBox(0,"SHM_Init was called twice or more!","FUN", MB_OK);
return;
}
inited = true;
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#define MAX_CONSOLE_LINES 250;
HANDLE g_hConsoleOut; // Handle to debug console
void RedirectIOToConsole();
// This function dynamically creates a "Console" window and points stdout and stderr to it.
// It also hooks stdin to the window
// You must free it later with FreeConsole
void RedirectIOToConsole()
{
int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// allocate a console for this app
AllocConsole();
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
&coninfo);
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);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
SetConsoleTitle("The Console Titlebar Text");
char clmutexname [256];
char clsmutexname [256];
char shmname [256];
sprintf(shmname,"DFShm-%d",OS_getPID());
// create a locked server mutex
char svmutexname [256];
sprintf(svmutexname,"DFSVMutex-%d",OS_getPID());
DFSVMutex = CreateMutex( 0, 1, svmutexname);
if(DFSVMutex == 0)
{
MessageBox(0,"Server mutex creation failed. Further communication disabled!","Error", MB_OK);
errorstate = 1;
return;
}
// the mutex already existed. we don't want to know.
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(0,"Server mutex already existed. Further communication disabled!","Error", MB_OK);
errorstate = 1;
return;
}
// create client and suspend mutexes
for(int i = 0; i < SHM_MAX_CLIENTS; i++)
{
sprintf(clmutexname,"DFCLMutex-%d-%d",OS_getPID(),i);
sprintf(clsmutexname,"DFCLSuspendMutex-%d-%d",OS_getPID(),i);
DFCLMutex[i] = CreateMutex( 0, 0, clmutexname); // client mutex, not held
DFCLSuspendMutex[i] = CreateMutex( 0, 1, clsmutexname); // suspend mutexes held on start
held_DFCLSuspendMutex[i] = 1;
if(DFCLMutex[i] == 0 || DFCLSuspendMutex[i] == 0 || GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(0,"Client mutex creation failed. Close all tools before starting DF.","Error", MB_OK);
errorstate = 1;
return;
}
}
// create virtual memory mapping
shmHandle = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,SHM_SIZE,shmname);
// if can't create or already exists -> nothing happens
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(0,"SHM bridge already in use","Error", MB_OK);
errorstate = 1;
return;
}
if(!shmHandle)
{
MessageBox(0,"Couldn't create SHM bridge","Error", MB_OK);
errorstate = 1;
return;
}
// attempt to attach the created mapping
shm = (char *) MapViewOfFile(shmHandle,FILE_MAP_ALL_ACCESS, 0,0, SHM_SIZE);
if(shm)
{
// make sure we don't stall or do crazy stuff
for(int i = 0; i < SHM_MAX_CLIENTS;i++)
{
((uint32_t *)shm)[i] = CORE_RUNNING;
}
// init modules :)
InitModules();
}
else
{
MessageBox(0,"Couldn't attach SHM bridge","Error", MB_OK);
errorstate = 1;
return;
}
}
void SHM_Destroy ( void )
{
if(errorstate)
return;
KillModules();
// get rid of all the locks
CloseHandle(DFSVMutex);
for(int i=0; i < SHM_MAX_CLIENTS; i++)
{
CloseHandle(DFCLSuspendMutex[i]);
CloseHandle(DFCLMutex[i]);
}
}
uint32_t OS_getPID()
{
return GetCurrentProcessId();
}
// TODO: move to some utils file
uint32_t OS_getAffinity()
{
HANDLE hProcess = GetCurrentProcess();
DWORD dwProcessAffinityMask, dwSystemAffinityMask;
GetProcessAffinityMask( hProcess, &dwProcessAffinityMask, &dwSystemAffinityMask );
return dwProcessAffinityMask;
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well Uncomment the next line if you are using c++ cio or comment if you don't
std::ios::sync_with_stdio();
}
#define DFhackCExport extern "C" __declspec(dllexport)
// is the other side still there?
bool isValidSHM(int which)
{
// try if CL mutex is free (by locking client mutex)
uint32_t result = WaitForSingleObject(DFCLMutex[which],0);
switch (result)
{
case WAIT_ABANDONED:
case WAIT_OBJECT_0:
{
OS_lockSuspendLock(which);
ReleaseMutex(DFCLMutex[which]);
return false;
}
case WAIT_TIMEOUT:
{
// mutex is held by a process already
return true;
}
default:
case WAIT_FAILED:
{
// TODO: now how do I respond to this?
return false;
}
}
}
#include "dfhack/Integers.h"
#include <vector>
#include <string>
#include "dfhack/Core.h"
#include <stdio.h>
/*************************************************************************/
// boring wrappers beyond this point. Only fix when broken
// extremely boring wrappers beyond this point. Only fix when broken
// we don't know which of the SDL functions will be called first... so we
// just catch the first one and init all our function pointers at that time
bool FirstCall(void);
bool inited = false;
// function and variable pointer... we don't try to understand what SDL does here
typedef void * fPtr;
@ -738,11 +595,8 @@ static void (*_SDL_Quit)(void) = 0;
DFhackCExport void SDL_Quit(void)
{
fprintf(stderr,"Quitting!\n");
if(!errorstate)
{
SHM_Destroy();
errorstate = true;
}
DFHack::Core & c = DFHack::Core::getInstance();
c.Shutdown();
if(_SDL_Quit)
{
_SDL_Quit();
@ -751,15 +605,8 @@ DFhackCExport void SDL_Quit(void)
// this is supported from 0.31.04 forward
DFhackCExport int SDL_NumJoysticks(void)
{
if(errorstate)
return -1;
if(!inited)
{
SHM_Init();
return -2;
}
SHM_Act();
return -3;
DFHack::Core & c = DFHack::Core::getInstance();
return c.Update();
}
static void (*_SDL_GL_SwapBuffers)(void) = 0;
@ -882,6 +729,7 @@ DFhackCExport uint32_t SDL_ThreadID(void)
// this has to be thread-safe. Let's hope it is.
bool FirstCall()
{
RedirectIOToConsole();
HMODULE realSDLlib = LoadLibrary("SDLreal.dll");
if(!realSDLlib)
{
@ -961,5 +809,6 @@ bool FirstCall()
_SDL_ThreadID = (uint32_t (*)(void))GetProcAddress(realSDLlib,"SDL_ThreadID");
fprintf(stderr,"Initized HOOKS!\n");
inited = true;
return 1;
}

@ -0,0 +1,117 @@
#include "Internal.h"
#include "PlatformInternal.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;
#include "dfhack/Core.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/Error.h"
#include "dfhack/Process.h"
#include "dfhack/Context.h"
#include "dfhack/modules/Gui.h"
#include "dfhack/modules/Vegetation.h"
#include "dfhack/modules/Maps.h"
using namespace DFHack;
DFHack::Gui * gui = 0;
DFHack::Maps * maps = 0;
DFHack::Vegetation * veg = 0;
Core::Core()
{
vif = new DFHack::VersionInfoFactory("Memory.xml");
p = new DFHack::Process(vif);
if (!p->isIdentified())
{
std::cerr << "Couldn't identify this version of DF." << std::endl;
errorstate = true;
}
c = new DFHack::Context(p);
errorstate = false;
// bullcrud, push it back to a tool
gui = c->getGui();
gui->Start();
veg = c->getVegetation();
veg->Start();
maps = c->getMaps();
maps->Start();
};
// more bullcrud
int32_t x = 0,y = 0,z = 0;
int32_t xo = 0,yo = 0,zo = 0;
void print_tree( DFHack::df_plant & tree)
{
//DFHack::Materials * mat = DF->getMaterials();
printf("%d:%d = ",tree.type,tree.material);
if(tree.watery)
{
std::cout << "near-water ";
}
//std::cout << mat->organic[tree.material].id << " ";
if(!tree.is_shrub)
{
std::cout << "tree";
}
else
{
std::cout << "shrub";
}
std::cout << std::endl;
printf("Grow counter: 0x%08x\n", tree.grow_counter);
printf("temperature 1: %d\n", tree.temperature_1);
printf("temperature 2: %d\n", tree.temperature_2);
printf("On fire: %d\n", tree.is_burning);
printf("hitpoints: 0x%08x\n", tree.hitpoints);
printf("update order: %d\n", tree.update_order);
printf("Address: 0x%x\n", &tree);
//hexdump(DF,tree.address,13*16);
}
int Core::Update()
{
if(errorstate)
return -1;
// And more bullcrud. Predictable!
maps->Start();
gui->getCursorCoords(x,y,z);
if(x != xo || y!= yo || z != zo)
{
xo = x;
yo = y;
zo = z;
std::cout << "Cursor: " << x << "/" << y << "/" << z << std::endl;
if(x != -30000)
{
std::vector <DFHack::df_plant *> * vec;
if(maps->ReadVegetation(x/16,y/16,z,vec))
{
for(size_t i = 0; i < vec->size();i++)
{
DFHack::df_plant * p = vec->at(i);
if(p->x == x && p->y == y && p->z == z)
{
print_tree(*p);
}
}
}
else
std::cout << "No veg vector..." << std::endl;
}
}
return 0;
};
int Core::Shutdown ( void )
{
if(errorstate)
return -1;
return 0;
// do something here, eventually.
}

@ -31,309 +31,101 @@ distribution.
#include <map>
using namespace std;
#include "ProcessFactory.h"
#include "MicrosoftSTL.h"
#include "dfhack/VersionInfo.h"
#include "dfhack/DFError.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/Error.h"
#include "dfhack/Process.h"
using namespace DFHack;
namespace
namespace DFHack
{
class NormalProcess : public Process
class PlatformSpecific
{
private:
VersionInfo * my_descriptor;
HANDLE my_handle;
vector <HANDLE> threads;
vector <HANDLE> stoppedthreads;
uint32_t my_pid;
string memFile;
bool attached;
bool suspended;
bool identified;
uint8_t vector_start;
IMAGE_NT_HEADERS pe_header;
IMAGE_SECTION_HEADER * sections;
uint32_t base;
MicrosoftSTL stl;
public:
NormalProcess(uint32_t pid, VersionInfoFactory * factory);
~NormalProcess();
bool attach();
bool detach();
bool suspend();
bool asyncSuspend();
bool resume();
bool forceresume();
void readQuad(const uint32_t address, uint64_t & value);
void writeQuad(const uint32_t address, const uint64_t value);
void readDWord(const uint32_t address, uint32_t & value);
void writeDWord(const uint32_t address, const uint32_t value);
void readFloat(const uint32_t address, float & value);
void readWord(const uint32_t address, uint16_t & value);
void writeWord(const uint32_t address, const uint16_t value);
void readByte(const uint32_t address, uint8_t & value);
void writeByte(const uint32_t address, const uint8_t value);
void read( uint32_t address, uint32_t length, uint8_t* buffer);
void write(uint32_t address, uint32_t length, uint8_t* buffer);
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
void writeSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
size_t writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info
std::string doReadClassName(uint32_t vptr);
const std::string readCString (uint32_t offset);
bool isSuspended();
bool isAttached();
bool isIdentified();
bool getThreadIDs(std::vector<uint32_t> & threads );
void getMemRanges(std::vector<t_memrange> & ranges );
VersionInfo *getDescriptor();
int getPID();
std::string getPath();
// get module index by name and version. bool 1 = error
bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { OUTPUT=0; return false;};
// get the SHM start if available
char * getSHMStart (void){return 0;};
// set a SHM command and wait for a response
bool SetAndWait (uint32_t state){return false;};
public:
PlatformSpecific()
{
base = 0;
sections = 0;
};
HANDLE my_handle;
vector <HANDLE> threads;
vector <HANDLE> stoppedthreads;
uint32_t my_pid;
IMAGE_NT_HEADERS pe_header;
IMAGE_SECTION_HEADER * sections;
uint32_t base;
};
}
Process* DFHack::createNormalProcess(uint32_t pid, VersionInfoFactory * factory)
{
return new NormalProcess(pid, factory);
}
NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
: my_pid(pid)
Process::Process(VersionInfoFactory * factory)
{
my_descriptor = NULL;
attached = false;
suspended = false;
base = 0;
sections = 0;
HMODULE hmod = NULL;
DWORD needed;
bool found = false;
identified = false;
// open process
my_handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, my_pid );
if (NULL == my_handle)
return;
my_descriptor = NULL;
d = new PlatformSpecific();
// open process
d->my_pid = GetCurrentProcessId();
d->my_handle = GetCurrentProcess();
// try getting the first module of the process
if(EnumProcessModules(my_handle, &hmod, sizeof(hmod), &needed) == 0)
if(EnumProcessModules(d->my_handle, &hmod, sizeof(hmod), &needed) == 0)
{
CloseHandle(my_handle);
my_handle=0;
// cout << "EnumProcessModules fail'd" << endl;
return; //if enumprocessModules fails, give up
}
// got base ;)
base = (uint32_t)hmod;
d->base = (uint32_t)hmod;
// read from this process
try
{
uint32_t pe_offset = Process::readDWord(base+0x3C);
read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header);
const size_t sectionsSize = sizeof(IMAGE_SECTION_HEADER) * pe_header.FileHeader.NumberOfSections;
sections = (IMAGE_SECTION_HEADER *) malloc(sectionsSize);
read(base + pe_offset + sizeof(pe_header), sectionsSize, (uint8_t *)sections);
uint32_t pe_offset = Process::readDWord(d->base+0x3C);
read(d->base + pe_offset, sizeof(d->pe_header), (uint8_t *)&(d->pe_header));
const size_t sectionsSize = sizeof(IMAGE_SECTION_HEADER) * d->pe_header.FileHeader.NumberOfSections;
d->sections = (IMAGE_SECTION_HEADER *) malloc(sectionsSize);
read(d->base + pe_offset + sizeof(d->pe_header), sectionsSize, (uint8_t *)(d->sections));
}
catch (exception &)
{
CloseHandle(my_handle);
my_handle = 0;
return;
}
//cout << "PE Timestamp: " << hex << pe_header.FileHeader.TimeDateStamp << dec << endl;
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp);
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(d->pe_header.FileHeader.TimeDateStamp);
if(vinfo)
{
/*
cout << "Using version " << vinfo->getName() << ". Offsets follow:" << endl;
cout << "--------------------------------------------------------------" << endl;
cout << vinfo->PrintOffsets();
cout << "--------------------------------------------------------------" << endl;
*/
// only enumerate threads if this is a valid DF process. the enumeration is costly.
vector<uint32_t> threads_ids;
if(!getThreadIDs( threads_ids ))
{
// thread enumeration failed.
CloseHandle(my_handle);
my_handle = 0;
return;
}
identified = true;
// give the process a data model and memory layout fixed for the base of first module
my_descriptor = new VersionInfo(*vinfo);
my_descriptor->RebaseAll(base);
my_descriptor->RebaseAll(d->base);
// keep track of created memory_info object so we can destroy it later
my_descriptor->setParentProcess(this);
try
{
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
stl.init(this);
}
catch (DFHack::Error::UnsetMemoryDefinition &)
{
CloseHandle(my_handle);
my_handle = 0;
identified = false;
return;
}
for(size_t i = 0; i < threads_ids.size();i++)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]);
if(hThread)
threads.push_back(hThread);
d->threads.push_back(hThread);
else
cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl;
}
}
else
{
// close handles of processes that aren't DF
//cout << "ABOUT TO FREE HANDLE" << endl;
CloseHandle(my_handle);
//cout << "FREE'D HANDLE" << endl;
my_handle = 0;
}
}
NormalProcess::~NormalProcess()
Process::~Process()
{
if(attached)
{
detach();
}
// destroy our rebased copy of the memory descriptor
delete my_descriptor;
if(my_handle != NULL)
{
CloseHandle(my_handle);
}
for(size_t i = 0; i < threads.size(); i++)
CloseHandle(threads[i]);
if(sections != NULL)
free(sections);
for(size_t i = 0; i < d->threads.size(); i++)
CloseHandle(d->threads[i]);
if(d->sections != NULL)
free(d->sections);
}
VersionInfo * NormalProcess::getDescriptor()
{
return my_descriptor;
}
int NormalProcess::getPID()
{
return my_pid;
}
bool NormalProcess::isSuspended()
{
return suspended;
}
bool NormalProcess::isAttached()
{
return attached;
}
bool NormalProcess::isIdentified()
{
return identified;
}
bool NormalProcess::asyncSuspend()
{
return suspend();
}
bool NormalProcess::suspend()
{
if(!attached)
return false;
if(suspended)
{
return true;
}
for(size_t i = 0; i < threads.size(); i++)
{
stoppedthreads.push_back(threads[i]);
SuspendThread(threads[i]);
}
suspended = true;
return true;
}
bool NormalProcess::forceresume()
{
if(!attached)
return false;
for(size_t i = 0; i < threads.size(); i++)
while (ResumeThread(threads[i]) > 1);
suspended = false;
return true;
}
bool NormalProcess::resume()
{
if(!attached)
return false;
if(!suspended)
{
return true;
}
for(size_t i = 0; i < stoppedthreads.size(); i++)
ResumeThread(stoppedthreads[i]);
stoppedthreads.clear();
suspended = false;
return true;
}
bool NormalProcess::attach()
{
if(attached)
{
if(!suspended)
return suspend();
return true;
}
attached = true;
suspend();
return true;
}
bool NormalProcess::detach()
{
if(!attached) return true;
resume();
attached = false;
return true;
}
bool NormalProcess::getThreadIDs(vector<uint32_t> & threads )
bool Process::getThreadIDs(vector<uint32_t> & threads )
{
HANDLE AllThreads = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
@ -353,7 +145,7 @@ bool NormalProcess::getThreadIDs(vector<uint32_t> & threads )
do
{
if( te32.th32OwnerProcessID == my_pid )
if( te32.th32OwnerProcessID == d->my_pid )
{
threads.push_back(te32.th32ThreadID);
}
@ -402,7 +194,7 @@ void HeapNodes(DWORD pid, map<uint64_t, unsigned int> & heaps)
}
// FIXME: NEEDS TESTING!
void NormalProcess::getMemRanges( vector<t_memrange> & ranges )
void Process::getMemRanges( vector<t_memrange> & ranges )
{
MEMORY_BASIC_INFORMATION MBI;
map<uint64_t, unsigned int> heaps;
@ -414,9 +206,9 @@ void NormalProcess::getMemRanges( vector<t_memrange> & ranges )
GetSystemInfo(&si);
uint64_t PageSize = si.dwPageSize;
// enumerate heaps
HeapNodes(my_pid, heaps);
HeapNodes(d->my_pid, heaps);
// go through all the VM regions, convert them to our internal format
while (VirtualQueryEx(this->my_handle, (const void*) (movingStart), &MBI, sizeof(MBI)) == sizeof(MBI))
while (VirtualQueryEx(d->my_handle, (const void*) (movingStart), &MBI, sizeof(MBI)) == sizeof(MBI))
{
movingStart = ((uint64_t)MBI.BaseAddress + MBI.RegionSize);
if(movingStart % PageSize != 0)
@ -431,7 +223,7 @@ void NormalProcess::getMemRanges( vector<t_memrange> & ranges )
temp.write = MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READWRITE;
temp.execute = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_EXECUTE;
temp.valid = true;
if(!GetModuleBaseName(this->my_handle, (HMODULE) temp.start, temp.name, 1024))
if(!GetModuleBaseName(d->my_handle, (HMODULE) temp.start, temp.name, 1024))
{
if(nameMap.count(temp.start))
{
@ -452,26 +244,23 @@ void NormalProcess::getMemRanges( vector<t_memrange> & ranges )
}
else temp.name[0]=0;
}
}
}
else
{
// this is our executable! (could be generalized to pull segments from libs, but whatever)
if(base == temp.start)
if(d->base == temp.start)
{
for(int i = 0; i < pe_header.FileHeader.NumberOfSections; i++)
for(int i = 0; i < d->pe_header.FileHeader.NumberOfSections; i++)
{
char sectionName[9];
memcpy(sectionName,sections[i].Name,8);
memcpy(sectionName,d->sections[i].Name,8);
sectionName[8] = 0;
string nm;
nm.append(temp.name);
nm.append(" : ");
nm.append(sectionName);
nameMap[temp.start + sections[i].VirtualAddress] = nm;
nameMap[temp.start + d->sections[i].VirtualAddress] = nm;
}
}
else
@ -481,131 +270,22 @@ void NormalProcess::getMemRanges( vector<t_memrange> & ranges )
}
}
void NormalProcess::readByte (const uint32_t offset,uint8_t &result)
{
if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint8_t), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::readWord (const uint32_t offset, uint16_t &result)
{
if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint16_t), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::readDWord (const uint32_t offset, uint32_t &result)
{
if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint32_t), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::readQuad (const uint32_t offset, uint64_t &result)
{
if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint64_t), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::readFloat (const uint32_t offset, float &result)
{
if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(float), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::read (const uint32_t offset, uint32_t size, uint8_t *target)
{
if(!ReadProcessMemory(my_handle, (int*) offset, target, size, NULL))
throw Error::MemoryAccessDenied(offset);
}
// WRITING
void NormalProcess::writeQuad (const uint32_t offset, uint64_t data)
{
if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::writeDWord (const uint32_t offset, uint32_t data)
{
if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL))
throw Error::MemoryAccessDenied(offset);
}
// using these is expensive.
void NormalProcess::writeWord (uint32_t offset, uint16_t data)
{
if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::writeByte (uint32_t offset, uint8_t data)
{
if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL))
throw Error::MemoryAccessDenied(offset);
}
void NormalProcess::write (uint32_t offset, uint32_t size, uint8_t *source)
{
if(!WriteProcessMemory(my_handle, (int*) offset, source, size, NULL))
throw Error::MemoryAccessDenied(offset);
}
// FIXME: could exploit the fact we can read more than one byte... but still, this is almost unused.
const std::string NormalProcess::readCString (const uint32_t offset)
{
std::string temp;
int counter = 0;
char r;
while (1)
{
if(!ReadProcessMemory(my_handle, (int*) (offset + counter), &r, sizeof(uint8_t), NULL)) break;
r = Process::readByte(offset+counter);
// order is important. even if the first character is \0, we cound that as a success. It's an empty string.
counter++;
if(!r) break;
temp.append(1,r);
}
if(!counter)
throw Error::MemoryAccessDenied(offset);
return temp;
}
void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
void NormalProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{
return stl.readSTLString(offset, buffer, bufcapacity);
}
const string NormalProcess::readSTLString (uint32_t offset)
{
return stl.readSTLString(offset);
}
size_t NormalProcess::writeSTLString (uint32_t address, string str)
{
return stl.writeSTLString(address, str);
}
string NormalProcess::doReadClassName (uint32_t vptr)
string Process::doReadClassName (uint32_t vptr)
{
return stl.readClassName(vptr);
int rtti = readDWord(vptr - 0x4);
int typeinfo = readDWord(rtti + 0xC);
string raw = readCString(typeinfo + 0xC); // skips the .?AV
raw.resize(raw.length() - 2);// trim @@ from end
return raw;
}
string NormalProcess::getPath()
string Process::getPath()
{
HMODULE hmod;
DWORD junk;
char String[255];
EnumProcessModules(my_handle, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle
GetModuleFileNameEx(my_handle,hmod,String,sizeof(String)); //get the filename from the module
EnumProcessModules(d->my_handle, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle
GetModuleFileNameEx(d->my_handle,hmod,String,sizeof(String)); //get the filename from the module
string out(String);
return(out.substr(0,out.find_last_of("\\")));
}

@ -43,7 +43,6 @@ namespace DFHack
class Constructions;
class VersionInfo;
class DFContextShared;
class WindowIO;
class Process;
/**
* This class wraps all the different related objects for a particular Process
@ -117,9 +116,6 @@ namespace DFHack
/// get the constructions module
Constructions * getConstructions();
/// get the Window management and I/O module
WindowIO * getWindowIO();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/*
* Effects like mist, dragonfire or dust

@ -0,0 +1,34 @@
#pragma once
#include "dfhack/Pragma.h"
#include "dfhack/Export.h"
namespace DFHack
{
class VersionInfoFactory;
class Process;
class Context;
// Core is a singleton. Why? Because it is closely tied to SDL calls. It tracks the global state of DF.
// There should never be more than one instance
// Better than tracking some weird variables all over the place.
class DFHACK_EXPORT Core
{
public:
static Core& getInstance()
{
// FIXME: add critical section for thread safety here.
static Core instance;
return instance;
}
int Update (void);
int Shutdown (void);
private:
Core();
Core(Core const&); // Don't Implement
void operator=(Core const&); // Don't implement
bool errorstate;
// legacy mess.
DFHack::VersionInfoFactory * vif;
DFHack::Process * p;
DFHack::Context * c;
};
}

@ -40,6 +40,7 @@ namespace DFHack
class Window;
class DFVector;
class VersionInfoFactory;
class PlatformSpecific;
/**
* A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification)
@ -205,7 +206,9 @@ namespace DFHack
if(!bufcapacity || bufcapacity == 1)
return 0;
std::string * str = (std::string *) offset;
size_t copied = str->copy(buffer,bufcapacity-1);
buffer[copied] = 0;
return copied;
};
/**
* write an STL string
@ -272,7 +275,10 @@ namespace DFHack
std::string getPath();
private:
VersionInfo * my_descriptor;
PlatformSpecific *d;
bool identified;
uint32_t my_pid;
uint32_t base;
std::map<uint32_t, std::string> classNameCache;
};

@ -1,102 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
using namespace std;
#include "dfhack-c/modules/Buildings_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int Buildings_Start(DFHackObject* b_Ptr, uint32_t* numBuildings)
{
if(b_Ptr != NULL)
{
return ((DFHack::Buildings*)b_Ptr)->Start(*numBuildings);
}
return -1;
}
int Buildings_Finish(DFHackObject* b_Ptr)
{
if(b_Ptr != NULL)
{
return ((DFHack::Buildings*)b_Ptr)->Finish();
}
return -1;
}
int Buildings_Read(DFHackObject* b_Ptr, const uint32_t index, t_building* building)
{
if(b_Ptr != NULL)
{
return ((DFHack::Buildings*)b_Ptr)->Read(index, *building);
}
return -1;
}
int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building)
{
if(b_Ptr != NULL)
{
return ((DFHack::Buildings*)b_Ptr)->GetCustomWorkshopType(*building);
}
return -1;
}
t_customWorkshop* Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr)
{
if(b_Ptr != NULL)
{
int i;
t_customWorkshop* cw_Ptr = NULL;
std::map<uint32_t, string> bTypes;
map<uint32_t, string>::iterator bIter;
if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes))
return NULL;
(*alloc_customWorkshop_buffer_callback)(&cw_Ptr, bTypes.size());
if(cw_Ptr == NULL)
return NULL;
for(i = 0, bIter = bTypes.begin(); bIter != bTypes.end(); bIter++, i++)
{
cw_Ptr[i].index = (*bIter).first;
size_t length = (*bIter).second.copy(cw_Ptr[i].name, 256);
cw_Ptr[i].name[length] = '\0';
}
return cw_Ptr;
}
return NULL;
}
#ifdef __cplusplus
}
#endif

@ -1,66 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
using namespace std;
#include "dfhack-c/modules/Constructions_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int Constructions_Start(DFHackObject* c_Ptr, uint32_t* numConstructions)
{
if(c_Ptr != NULL)
{
return ((DFHack::Constructions*)c_Ptr)->Start(*numConstructions);
}
return -1;
}
int Constructions_Finish(DFHackObject* c_Ptr)
{
if(c_Ptr != NULL)
{
return ((DFHack::Constructions*)c_Ptr)->Finish();
}
return -1;
}
int Constructions_Read(DFHackObject* c_Ptr, const uint32_t index, t_construction* construction)
{
if(c_Ptr != NULL)
{
return ((DFHack::Constructions*)c_Ptr)->Read(index, *construction);
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,314 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#include "dfhack-c/modules/Creatures_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int Creatures_Start(DFHackObject* cPtr, uint32_t* numCreatures)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->Start(*numCreatures);
}
return -1;
}
int Creatures_Finish(DFHackObject* cPtr)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->Finish();
}
return -1;
}
int32_t Creatures_ReadCreatureInBox(DFHackObject* cPtr, const int32_t index, t_creature* furball, const uint16_t x1, const uint16_t y1, const uint16_t z1, const uint16_t x2, const uint16_t y2, const uint16_t z2)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->ReadCreatureInBox(index, *furball, x1, y1, z1, x2, y2, z2);
}
return -1;
}
int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* furball)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->ReadCreature(index, *furball);
}
return -1;
}
t_material* Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball)
{
if(cPtr != NULL)
{
std::vector<t_material> mat;
if(((DFHack::Creatures*)cPtr)->ReadJob(furball, mat))
{
if(mat.size() <= 0)
return NULL;
t_material* buf = NULL;
(*alloc_material_buffer_callback)(&buf, mat.size());
if(buf != NULL)
{
copy(mat.begin(), mat.end(), buf);
return buf;
}
else
return NULL;
}
else
return NULL;
}
return NULL;
}
uint32_t* Creatures_ReadInventoryIdx(DFHackObject* cPtr, const uint32_t index)
{
if(cPtr != NULL)
{
std::vector<uint32_t> item;
if(((DFHack::Creatures*)cPtr)->ReadInventoryIdx(index, item))
{
if(item.size() <= 0)
return NULL;
uint32_t* buf = NULL;
(*alloc_uint_buffer_callback)(&buf, item.size());
if(buf != NULL)
{
copy(item.begin(), item.end(), buf);
return buf;
}
else
return NULL;
}
}
return NULL;
}
uint32_t* Creatures_ReadInventoryPtr(DFHackObject* cPtr, const uint32_t index)
{
if(cPtr != NULL)
{
std::vector<uint32_t> item;
if(((DFHack::Creatures*)cPtr)->ReadInventoryPtr(index, item))
{
if(item.size() <= 0)
return NULL;
uint32_t* buf = NULL;
(*alloc_uint_buffer_callback)(&buf, item.size());
if(buf != NULL)
{
copy(item.begin(), item.end(), buf);
return buf;
}
else
return NULL;
}
}
return NULL;
}
uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->GetDwarfRaceIndex();
}
return 0;
}
int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->GetDwarfCivId();
}
return -1;
}
int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors);
}
return -1;
}
int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteHappiness(index, happiness_value);
}
return -1;
}
int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteFlags(index, flags1, flags2);
}
return -1;
}
int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul)
{
if(cPtr != NULL && soul != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteSkills(index, *soul);
}
return -1;
}
int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature)
{
if(cPtr != NULL && creature != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteAttributes(index, *creature);
}
return -1;
}
int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteSex(index, sex);
}
return -1;
}
int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul)
{
if(cPtr != NULL && soul != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteTraits(index, *soul);
}
return -1;
}
int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteMood(index, mood);
}
return -1;
}
int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteMoodSkill(index, moodSkill);
}
return -1;
}
int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count)
{
if(cPtr != NULL && furball != NULL && mat != NULL)
{
if(mat_count == 0)
return 0;
std::vector<t_material> mat_vec;
copy(mat, mat + mat_count, mat_vec.begin());
return ((DFHack::Creatures*)cPtr)->WriteJob(furball, mat_vec);
}
return -1;
}
int Creatures_WritePos(DFHackObject* cPtr, const uint32_t index, const t_creature* creature)
{
if(cPtr != NULL && creature != NULL)
{
return ((DFHack::Creatures*)cPtr)->WritePos(index, *creature);
}
return -1;
}
int Creatures_WriteCiv(DFHackObject* cPtr, const uint32_t index, const int32_t civ)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteCiv(index, civ);
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,210 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
using namespace std;
#include "dfhack-c/modules/Gui_C.h"
#include "dfhack-c/DFTypes_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int Gui_Start(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->Start();
}
return -1;
}
int Gui_Finish(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->Finish();
}
return -1;
}
int Gui_getViewCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z)
{
if(gui != NULL)
{
int32_t tx, ty, tz;
if(((DFHack::Gui*)gui)->getViewCoords(tx, ty, tz))
{
*x = tx;
*y = ty;
*z = tz;
return 1;
}
else
return 0;
}
return -1;
}
int Gui_setViewCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z)
{
if(gui != NULL)
{
if(((DFHack::Gui*)gui)->setViewCoords(x, y, z))
return 1;
else
return 0;
}
return -1;
}
int Gui_getCursorCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z)
{
if(gui != NULL)
{
int32_t tx, ty, tz;
if(((DFHack::Gui*)gui)->getCursorCoords(tx, ty, tz))
{
*x = tx;
*y = ty;
*z = tz;
return 1;
}
else
return 0;
}
return -1;
}
int Gui_setCursorCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z)
{
if(gui != NULL)
{
if(((DFHack::Gui*)gui)->setCursorCoords(x, y, z))
return 1;
else
return 0;
}
return -1;
}
t_hotkey* Gui_ReadHotkeys(DFHackObject* gui)
{
if(gui != NULL)
{
t_hotkey* buf;
(*alloc_hotkey_buffer_callback)(&buf, NUM_HOTKEYS);
if(buf != NULL)
{
if(((DFHack::Gui*)gui)->ReadHotkeys(buf))
return buf;
else
return NULL;
}
else
return NULL;
}
return NULL;
}
int Gui_getWindowSize(DFHackObject* gui, int32_t* width, int32_t* height)
{
if(gui != NULL)
{
int32_t tw, th;
if(((DFHack::Gui*)gui)->getWindowSize(tw, th))
{
*width = tw;
*height = th;
return 1;
}
else
return 0;
}
return -1;
}
t_screen* Gui_getScreenTiles(DFHackObject* gui, int32_t width, int32_t height)
{
if(gui != NULL)
{
t_screen* buf;
(*alloc_screen_buffer_callback)(&buf, width * height);
if(buf == NULL)
return NULL;
if(((DFHack::Gui*)gui)->getScreenTiles(width, height, buf))
return buf;
else
return NULL;
}
return NULL;
}
int Gui_ReadViewScreen(DFHackObject* gui, t_viewscreen* viewscreen)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->ReadViewScreen(*viewscreen);
}
return -1;
}
int Gui_ReadMenuState(DFHackObject* gui, uint32_t* menuState)
{
if(gui != NULL)
{
*menuState = ((DFHack::Gui*)gui)->ReadMenuState();
return 1;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,127 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
using namespace std;
#include "dfhack-c/modules/Items_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int Items_Start(DFHackObject* items)
{
if(items != NULL)
{
return ((DFHack::Items*)items)->Start();
}
return -1;
}
int Items_Finish(DFHackObject* items)
{
if(items != NULL)
{
return ((DFHack::Items*)items)->Finish();
}
return -1;
}
//FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings.
char* Items_getItemDescription(DFHackObject* items, dfh_item * item, DFHackObject* mats)
{
if(items != NULL && mats != NULL)
{
std::string desc = ((DFHack::Items*)items)->getItemDescription(*item, (DFHack::Materials*)mats);
if(desc.size() > 0)
{
char* buf = NULL;
(*alloc_char_buffer_callback)(&buf, desc.size());
if(buf != NULL)
{
size_t len = desc.copy(buf, desc.size());
if(len > 0)
buf[len] = '\0';
else
buf[0] = '\0';
}
return buf;
}
}
return NULL;
}
char* Items_getItemClass(DFHackObject* items, int32_t index)
{
if(items != NULL)
{
std::string iclass = ((DFHack::Items*)items)->getItemClass(index);
if(iclass.size() > 0)
{
char* buf = NULL;
(*alloc_char_buffer_callback)(&buf, iclass.size());
if(buf != NULL)
{
size_t len = iclass.copy(buf, iclass.size());
if(len > 0)
buf[len] = '\0';
else
buf[0] = '\0';
}
return buf;
}
}
return NULL;
}
int Items_getItemData(DFHackObject* items, uint32_t itemptr, dfh_item* item)
{
if(items != NULL)
{
return ((DFHack::Items*)items)->readItem(itemptr, *item);
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,706 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "dfhack/DFPragma.h"
#include <vector>
#include <map>
#include <algorithm>
#include <string>
using namespace std;
#include "dfhack-c/DFTypes_C.h"
#include "dfhack-c/modules/Maps_C.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
int Maps_Start(DFHackObject* maps)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->Start();
}
return -1;
}
int Maps_Finish(DFHackObject* maps)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->Finish();
}
return -1;
}
uint16_t* Maps_ReadGeology(DFHackObject* maps)
{
if(maps != NULL)
{
std::vector < std::vector <uint16_t> > geology;
if(((DFHack::Maps*)maps)->ReadGeology(geology))
{
uint16_t** buf = NULL;
uint32_t geoLength = 0;
for(unsigned int i = 0; i < geology.size(); i++)
{
for(unsigned int j = 0; j < geology[i].size(); j++)
{
geoLength += geology[i].size();
}
}
((*alloc_ushort_buffer_callback)(buf, geoLength));
if(buf != NULL)
{
uint16_t* bufCopyPtr = *buf;
for(unsigned int i = 0; i < geology.size(); i++)
{
copy(geology[i].begin(), geology[i].end(), bufCopyPtr);
bufCopyPtr += geology[i].size();
}
return *buf;
}
else
return NULL;
}
}
return NULL;
}
t_feature* Maps_ReadGlobalFeatures(DFHackObject* maps)
{
if(maps != NULL)
{
std::vector<t_feature> featureVec;
if(((DFHack::Maps*)maps)->ReadGlobalFeatures(featureVec))
{
if(featureVec.size() <= 0)
return NULL;
t_feature** buf = NULL;
((*alloc_feature_buffer_callback)(buf, featureVec.size()));
if(buf != NULL)
{
copy(featureVec.begin(), featureVec.end(), *buf);
return *buf;
}
else
return NULL;
}
else
return NULL;
}
return NULL;
}
c_featuremap_node* Maps_ReadLocalFeatures(DFHackObject* maps)
{
if(maps != NULL)
{
std::map <DFCoord, std::vector<t_feature *> > local_features;
std::map <DFCoord, std::vector<t_feature *> >::iterator iterate;
uint32_t i;
if(((DFHack::Maps*)maps)->ReadLocalFeatures(local_features))
{
if(local_features.empty() == true)
return NULL;
c_featuremap_node* featuremap;
uint32_t* featuremap_size = (uint32_t*)calloc(local_features.size(), sizeof(uint32_t));
for(i = 0, iterate = local_features.begin(); iterate != local_features.end(); i++, iterate++)
featuremap_size[i] = (*iterate).second.size();
((*alloc_featuremap_buffer_callback)(&featuremap, featuremap_size, local_features.size()));
free(featuremap_size);
if(featuremap == NULL)
return NULL;
for(i = 0, iterate = local_features.begin(); iterate != local_features.end(); i++, iterate++)
{
uint32_t j;
featuremap[i].coordinate.comparate = (*iterate).first.comparate;
for(j = 0; j < (*iterate).second.size(); j++)
featuremap[i].features[j] = *((*iterate).second[j]);
//copy((*iterate).second.begin(), (*iterate).second.end(), featuremap[i].features);
featuremap[i].feature_length = (*iterate).second.size();
}
return featuremap;
}
else
return NULL;
}
return NULL;
}
void Maps_getSize(DFHackObject* maps, uint32_t* x, uint32_t* y, uint32_t* z)
{
if(maps != NULL)
{
((DFHack::Maps*)maps)->getSize(*x, *y, *z);
}
}
void Maps_getPosition(DFHackObject* maps, int32_t* x, int32_t* y, int32_t* z)
{
if(maps != NULL)
{
((DFHack::Maps*)maps)->getPosition(*x, *y, *z);
}
}
int Maps_isValidBlock(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->isValidBlock(x, y, z);
}
return -1;
}
uint32_t Maps_getBlockPtr(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->getBlockPtr(x, y, z);
}
return 0;
}
int Maps_ReadBlock40d(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, mapblock40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->ReadBlock40d(x, y, z, buffer);
}
return -1;
}
int Maps_ReadTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->ReadTileTypes(x, y, z, buffer);
}
return -1;
}
int Maps_WriteTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->WriteTileTypes(x, y, z, buffer);
}
return -1;
}
int Maps_ReadDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->ReadDesignations(x, y, z, buffer);
}
return -1;
}
int Maps_WriteDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->WriteDesignations(x, y, z, buffer);
}
return -1;
}
int Maps_ReadTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2)
{
if(maps != NULL && temp1 != NULL && temp2 != NULL)
{
return ((DFHack::Maps*)maps)->ReadTemperatures(x, y, z, temp1, temp2);
}
return -1;
}
int Maps_WriteTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2)
{
if(maps != NULL && temp1 != NULL && temp2 != NULL)
{
return ((DFHack::Maps*)maps)->WriteTemperatures(x, y, z, temp1, temp2);
}
return -1;
}
int Maps_ReadOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->ReadOccupancy(x, y, z, buffer);
}
return -1;
}
int Maps_WriteOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer)
{
if(maps != NULL && buffer != NULL)
{
return ((DFHack::Maps*)maps)->WriteOccupancy(x, y, z, buffer);
}
return -1;
}
int Maps_ReadDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int* dirtybit)
{
if(maps != NULL)
{
bool bit;
int result = ((DFHack::Maps*)maps)->ReadDirtyBit(x, y, z, bit);
*dirtybit = bit;
return result;
}
return -1;
}
int Maps_WriteDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int dirtybit)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteDirtyBit(x, y, z, (bool)dirtybit);
}
return -1;
}
int Maps_ReadFeatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t* local, int16_t* global)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->ReadFeatures(x, y, z, *local, *global);
}
return -1;
}
int Maps_WriteLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, local);
}
return -1;
}
int Maps_WriteEmptyLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, -1);
}
return -1;
}
int Maps_WriteGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, local);
}
return -1;
}
int Maps_WriteEmptyGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, -1);
}
return -1;
}
int Maps_ReadBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags* blockflags)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->ReadBlockFlags(x, y, z, *blockflags);
}
return -1;
}
int Maps_WriteBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteBlockFlags(x, y, z, blockflags);
}
return -1;
}
int Maps_ReadRegionOffsets(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, biome_indices40d* buffer)
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->ReadRegionOffsets(x, y, z, buffer);
}
return -1;
}
t_vein* Maps_ReadStandardVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_vein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins);
if(result)
{
t_vein* v_buf = NULL;
if(veins.size() > 0)
{
((*alloc_vein_buffer_callback)(&v_buf, veins.size()));
if(v_buf == NULL)
return NULL;
copy(veins.begin(), veins.end(), v_buf);
}
return v_buf;
}
else
return NULL;
}
return NULL;
}
t_frozenliquidvein* Maps_ReadFrozenVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_frozenliquidvein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_frozenliquidvein> frozen_veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, &frozen_veins);
if(result)
{
t_frozenliquidvein* fv_buf = NULL;
if(frozen_veins.size() > 0)
{
((*alloc_frozenliquidvein_buffer_callback)(&fv_buf, frozen_veins.size()));
if(fv_buf == NULL)
return NULL;
copy(frozen_veins.begin(), frozen_veins.end(), fv_buf);
}
return fv_buf;
}
else
return NULL;
}
return NULL;
}
t_spattervein* Maps_ReadSpatterVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_spattervein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_spattervein> spatter_veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, &spatter_veins);
if(result)
{
t_spattervein* sv_buf = NULL;
if(spatter_veins.size() > 0)
{
((*alloc_spattervein_buffer_callback)(&sv_buf, spatter_veins.size()));
if(sv_buf == NULL)
return NULL;
copy(spatter_veins.begin(), spatter_veins.end(), sv_buf);
}
return sv_buf;
}
else
return NULL;
}
return NULL;
}
t_grassvein* Maps_ReadGrassVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_grassvein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_grassvein> grass_veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, 0, &grass_veins);
if(result)
{
t_grassvein* gs_buf = NULL;
if(grass_veins.size() > 0)
{
((*alloc_grassvein_buffer_callback)(&gs_buf, grass_veins.size()));
if(gs_buf == NULL)
return NULL;
copy(grass_veins.begin(), grass_veins.end(), gs_buf);
}
return gs_buf;
}
else
return NULL;
}
return NULL;
}
t_worldconstruction* Maps_ReadWorldConstructions(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_worldconstruction_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_worldconstruction> constructions;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, 0, 0, &constructions);
if(result)
{
t_worldconstruction* ct_buf = NULL;
if(constructions.size() > 0)
{
((*alloc_worldconstruction_buffer_callback)(&ct_buf, constructions.size()));
if(ct_buf == NULL)
return NULL;
copy(constructions.begin(), constructions.end(), ct_buf);
}
return ct_buf;
}
else
return NULL;
}
return NULL;
}
int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_allveins* vein_struct)
{
if(maps != NULL)
{
if(alloc_vein_buffer_callback == NULL || alloc_frozenliquidvein_buffer_callback == NULL ||
alloc_spattervein_buffer_callback == NULL || alloc_grassvein_buffer_callback == NULL ||
alloc_worldconstruction_buffer_callback == NULL)
return -1;
vector<t_vein> veins;
vector<t_frozenliquidvein> frozen_veins;
vector<t_spattervein> spatter_veins;
vector<t_grassvein> grass_veins;
vector<t_worldconstruction> constructions;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, &frozen_veins, &spatter_veins, &grass_veins, &constructions);
if(result)
{
t_vein* v_buf = NULL;
t_frozenliquidvein* fv_buf = NULL;
t_spattervein* sv_buf = NULL;
t_grassvein* gs_buf = NULL;
t_worldconstruction* ct_buf = NULL;
if(veins.size() > 0)
{
((*alloc_vein_buffer_callback)(&v_buf, veins.size()));
if(v_buf == NULL)
return -1;
copy(veins.begin(), veins.end(), v_buf);
vein_struct->veins = v_buf;
}
if(frozen_veins.size() > 0)
{
((*alloc_frozenliquidvein_buffer_callback)(&fv_buf, frozen_veins.size()));
if(fv_buf == NULL)
return -1;
copy(frozen_veins.begin(), frozen_veins.end(), fv_buf);
vein_struct->frozen_veins = fv_buf;
}
if(spatter_veins.size() > 0)
{
((*alloc_spattervein_buffer_callback)(&sv_buf, spatter_veins.size()));
if(sv_buf == NULL)
return -1;
copy(spatter_veins.begin(), spatter_veins.end(), sv_buf);
vein_struct->spatter_veins = sv_buf;
}
if(grass_veins.size() > 0)
{
((*alloc_grassvein_buffer_callback)(&gs_buf, grass_veins.size()));
if(gs_buf == NULL)
return -1;
copy(grass_veins.begin(), grass_veins.end(), gs_buf);
vein_struct->grass_veins = gs_buf;
}
if(constructions.size() > 0)
{
((*alloc_worldconstruction_buffer_callback)(&ct_buf, constructions.size()));
if(ct_buf == NULL)
return -1;
copy(constructions.begin(), constructions.end(), ct_buf);
vein_struct->world_constructions = ct_buf;
}
return 1;
}
else
return 0;
}
return -1;
}
//FIXME: doesn't copy out the address and name variables!
dfh_plant* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps == NULL)
return NULL;
else
{
std::vector<dfh_plant> plants;
dfh_plant* buf = NULL;
bool result = ((DFHack::Maps*)maps)->ReadVegetation(x, y, z, &plants);
if(!result || plants.size() <= 0)
{
return NULL;
}
else
{
((*alloc_tree_buffer_callback)(&buf, plants.size()));
if(buf == NULL)
return NULL;
copy(plants.begin(), plants.end(), buf);
return buf;
}
}
return NULL;
}
#ifdef __cplusplus
}
#endif

@ -1,636 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#include "dfhack-c/modules/Materials_C.h"
#ifdef __cplusplus
extern "C" {
#endif
void BuildDescriptorList(std::vector<t_creaturetype> & src, c_creaturetype_descriptor** dest)
{
c_creaturetype_descriptor* descriptor = NULL;
descriptor = (c_creaturetype_descriptor*)calloc(src.size(), sizeof(c_creaturetype_descriptor));
for(uint32_t i = 0; i < src.size(); i++)
{
uint32_t castes_size = src[i].castes.size();
c_creaturetype_descriptor* current = &descriptor[i];
current->castesCount = castes_size;
current->caste_descriptors = (c_creaturecaste_descriptor*)calloc(castes_size, sizeof(c_creaturecaste_descriptor));
for(uint32_t j = 0; j < castes_size; j++)
{
uint32_t color_size = src[i].castes[j].ColorModifier.size();
c_creaturecaste_descriptor* current_caste = &current->caste_descriptors[j];
current_caste->colorModifierLength = color_size;
current_caste->color_descriptors = (c_colormodifier_descriptor*)calloc(color_size, sizeof(c_colormodifier_descriptor));
for(uint32_t k = 0; k < color_size; k++)
{
c_colormodifier_descriptor* current_color = &current_caste->color_descriptors[k];
current_color->colorlistLength = src[i].castes[j].ColorModifier[k].colorlist.size();
}
current_caste->bodypartLength = src[i].castes[j].bodypart.size();
}
current->extractCount = src[i].extract.size();
}
*dest = descriptor;
}
void FreeDescriptorList(c_creaturetype_descriptor* d, uint32_t length)
{
for(uint32_t i = 0; i < length; i++)
{
c_creaturetype_descriptor* desc = &d[i];
for(uint32_t j = 0; j < desc->castesCount; j++)
free(desc->caste_descriptors[j].color_descriptors);
free(desc->caste_descriptors);
}
free(d);
}
int CreatureTypeConvert(std::vector<t_creaturetype> & src, c_creaturetype** out_buf)
{
if(src.size() <= 0)
return 0;
else if(alloc_creaturetype_buffer_callback == NULL)
return -1;
else
{
c_creaturetype_descriptor* descriptor;
c_creaturetype* buf;
BuildDescriptorList(src, &descriptor);
((*alloc_creaturetype_buffer_callback)(out_buf, descriptor, src.size()));
FreeDescriptorList(descriptor, src.size());
if(out_buf == NULL)
return -1;
buf = out_buf[0];
for(uint32_t i = 0; i < src.size(); i++)
{
c_creaturetype* current = &(buf[i]);
memset(current->rawname, '\0', 128);
strncpy(current->rawname, src[i].rawname, 128);
for(uint32_t j = 0; j < current->castesCount; j++)
{
c_creaturecaste* current_caste = &current->castes[j];
t_creaturecaste* src_caste = &src[i].castes[j];
memset(current_caste->rawname, '\0', 128);
memset(current_caste->singular, '\0', 128);
memset(current_caste->plural, '\0', 128);
memset(current_caste->adjective, '\0', 128);
strncpy(current_caste->rawname, src_caste->rawname, 128);
strncpy(current_caste->singular, src_caste->singular, 128);
strncpy(current_caste->plural, src_caste->plural, 128);
strncpy(current_caste->adjective, src_caste->adjective, 128);
for(uint32_t k = 0; k < src[i].castes[j].ColorModifier.size(); k++)
{
c_colormodifier* current_color = &current_caste->colorModifier[k];
memset(current_color->part, '\0', 128);
strncpy(current_color->part, src_caste->ColorModifier[k].part, 128);
copy(src_caste->ColorModifier[k].colorlist.begin(), src_caste->ColorModifier[k].colorlist.end(), current_color->colorlist);
current_color->colorlistLength = src_caste->ColorModifier[k].colorlist.size();
current_color->startdate = src_caste->ColorModifier[k].startdate;
current_color->enddate = src_caste->ColorModifier[k].enddate;
}
current_caste->colorModifierLength = src_caste->ColorModifier.size();
copy(src_caste->bodypart.begin(), src_caste->bodypart.end(), current_caste->bodypart);
current_caste->bodypartLength = src_caste->bodypart.size();
current_caste->strength = src_caste->strength;
current_caste->agility = src_caste->agility;
current_caste->toughness = src_caste->toughness;
current_caste->endurance = src_caste->endurance;
current_caste->recuperation = src_caste->recuperation;
current_caste->disease_resistance = src_caste->disease_resistance;
current_caste->analytical_ability = src_caste->analytical_ability;
current_caste->focus = src_caste->focus;
current_caste->willpower = src_caste->willpower;
current_caste->creativity = src_caste->creativity;
current_caste->intuition = src_caste->intuition;
current_caste->patience = src_caste->patience;
current_caste->memory = src_caste->memory;
current_caste->linguistic_ability = src_caste->linguistic_ability;
current_caste->spatial_sense = src_caste->spatial_sense;
current_caste->musicality = src_caste->musicality;
current_caste->kinesthetic_sense = src_caste->kinesthetic_sense;
}
copy(src[i].extract.begin(), src[i].extract.end(), current->extract);
current->extractCount = src[i].extract.size();
current->tile_character = src[i].tile_character;
current->tilecolor.fore = src[i].tilecolor.fore;
current->tilecolor.back = src[i].tilecolor.back;
current->tilecolor.bright = src[i].tilecolor.bright;
}
return 1;
}
}
int Materials_ReadInorganicMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadInorganicMaterials() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadOrganicMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadOrganicMaterials() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadWoodMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadWoodMaterials() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadPlantMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadPlantMaterials() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadCreatureTypes(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadCreatureTypes() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadCreatureTypesEx(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadCreatureTypesEx() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadDescriptorColors(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadDescriptorColors() == true)
return 1;
else
return 0;
}
return -1;
}
int Materials_ReadOthers(DFHackObject* mat)
{
if(mat != NULL)
{
if(((DFHack::Materials*)mat)->ReadOthers() == true)
return 1;
else
return 0;
}
return -1;
}
void Materials_ReadAllMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
((DFHack::Materials*)mat)->ReadAllMaterials();
}
}
const char* Materials_getType(DFHackObject* mat, t_material* material)
{
if(mat != NULL)
{
std::string type = ((DFHack::Materials*)mat)->getType(*material);
return type.c_str();
}
return "\0";
}
const char* Materials_getDescription(DFHackObject* mat, t_material* material)
{
if(mat != NULL)
{
std::string description = ((DFHack::Materials*)mat)->getDescription(*material);
return description.c_str();
}
return "\0";
}
//vector size getters
int Materials_getInorganicSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->inorganic.size();
}
return -1;
}
int Materials_getOrganicSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->organic.size();
}
return -1;
}
int Materials_getTreeSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->tree.size();
}
return -1;
}
int Materials_getPlantSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->plant.size();
}
return -1;
}
int Materials_getRaceSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->race.size();
}
return -1;
}
int Materials_getRaceExSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->raceEx.size();
}
return -1;
}
int Materials_getColorSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->color.size();
}
return -1;
}
int Materials_getOtherSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->other.size();
}
return -1;
}
//vector getters
t_matgloss* Materials_getInorganic(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->inorganic.size() > 0)
{
t_matgloss* buf = NULL;
if(alloc_matgloss_buffer_callback == NULL)
return NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->inorganic.size()));
if(buf != NULL)
{
copy(materials->inorganic.begin(), materials->inorganic.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matgloss* Materials_getOrganic(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->organic.size() > 0)
{
t_matgloss* buf = NULL;
if(alloc_matgloss_buffer_callback == NULL)
return NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->organic.size()));
if(buf != NULL)
{
copy(materials->organic.begin(), materials->organic.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matgloss* Materials_getTree(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->tree.size() > 0)
{
t_matgloss* buf = NULL;
if(alloc_matgloss_buffer_callback == NULL)
return NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->tree.size()));
if(buf != NULL)
{
copy(materials->tree.begin(), materials->tree.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matgloss* Materials_getPlant(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->plant.size() > 0)
{
t_matgloss* buf = NULL;
if(alloc_matgloss_buffer_callback == NULL)
return NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->plant.size()));
if(buf != NULL)
{
copy(materials->plant.begin(), materials->plant.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matgloss* Materials_getRace(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->race.size() > 0)
{
t_matgloss* buf = NULL;
if(alloc_matgloss_buffer_callback == NULL)
return NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->race.size()));
if(buf != NULL)
{
copy(materials->race.begin(), materials->race.end(), buf);
return buf;
}
}
}
return NULL;
}
//race_ex getter goes here...
c_creaturetype* Materials_getRaceEx(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
int matSize = materials->raceEx.size();
if(matSize > 0)
{
c_creaturetype* buf = NULL;
CreatureTypeConvert(((DFHack::Materials*)mat)->raceEx, &buf);
return buf;
}
}
return NULL;
}
t_descriptor_color* Materials_getColor(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->color.size() > 0)
{
t_descriptor_color* buf = NULL;
((*alloc_descriptor_buffer_callback)(&buf, materials->color.size()));
if(buf != NULL)
{
copy(materials->color.begin(), materials->color.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matglossOther* Materials_getOther(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->other.size() > 0)
{
t_matglossOther* buf = NULL;
((*alloc_matgloss_other_buffer_callback)(&buf, materials->other.size()));
if(buf != NULL)
{
copy(materials->other.begin(), materials->other.end(), buf);
return buf;
}
}
}
return NULL;
}
t_matgloss* Materials_getAllDesc(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->alldesc.size() > 0)
{
t_matgloss* buf = NULL;
((*alloc_matgloss_buffer_callback)(&buf, materials->alldesc.size()));
if(buf != NULL)
{
copy(materials->race.begin(), materials->alldesc.end(), buf);
return buf;
}
}
}
return NULL;
}
#ifdef __cplusplus
}
#endif

@ -1,127 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "Internal.h"
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Translation.h"
#include "dfhack-c/modules/Translation_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int Translation_Start(DFHackObject* trans)
{
if(trans != NULL)
{
return ((DFHack::Translation*)trans)->Start();
}
return -1;
}
int Translation_Finish(DFHackObject* trans)
{
if(trans != NULL)
{
return ((DFHack::Translation*)trans)->Finish();
}
return -1;
}
char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name)
{
if(trans != NULL)
{
std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, true);
if(nameTrans.size() > 0)
{
char* buf = NULL;
(*alloc_char_buffer_callback)(&buf, nameTrans.size());
if(buf != NULL)
{
size_t len = nameTrans.copy(buf, nameTrans.size());
if(len > 0)
buf[len] = '\0';
else
buf[0] = '\0';
}
return buf;
}
else
return NULL;
}
return NULL;
}
char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name)
{
if(trans != NULL)
{
std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, false);
if(nameTrans.size() > 0)
{
char* buf = NULL;
(*alloc_char_buffer_callback)(&buf, nameTrans.size());
if(buf != NULL)
{
size_t len = nameTrans.copy(buf, nameTrans.size());
if(len > 0)
buf[len] = '\0';
else
buf[0] = '\0';
}
return buf;
}
else
return NULL;
}
return NULL;
}
#ifdef __cplusplus
}
#endif

@ -1,72 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "Internal.h"
#include <vector>
#include <string>
using namespace std;
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Vegetation.h"
#include "dfhack-c/modules/Vegetation_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees)
{
if(veg != NULL)
{
return ((DFHack::Vegetation*)veg)->Start(*numTrees);
}
return -1;
}
int Vegetation_Finish(DFHackObject* veg)
{
if(veg != NULL)
{
return ((DFHack::Vegetation*)veg)->Finish();
}
return -1;
}
int Vegetation_Read(DFHackObject* veg, const uint32_t index, dfh_plant* shrubbery)
{
if(veg != NULL)
{
return ((DFHack::Vegetation*)veg)->Read(index, *shrubbery);
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,282 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "Internal.h"
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#include "dfhack/modules/WindowIO.h"
#include <X11/Xlib.h> //need for X11 functions
#include <X11/keysym.h>
#include "ContextShared.h"
#include "ModuleFactory.h"
using namespace DFHack;
Module* DFHack::createWindowIO(DFContextShared * d)
{
return new WindowIO(d);
}
// should always reflect the enum in DFkeys.h
const static KeySym ksTable[NUM_SPECIALS]=
{
XK_Return,
XK_space,
XK_BackSpace,
XK_Tab,
XK_Caps_Lock,
XK_Shift_L,
XK_Shift_R,
XK_Control_L,
XK_Control_R,
XK_Alt_L,
XK_VoidSymbol, // WAIT
XK_Escape,
XK_Up,
XK_Down,
XK_Left,
XK_Right,
XK_F1,
XK_F2,
XK_F3,
XK_F4,
XK_F5,
XK_F6,
XK_F7,
XK_F8,
XK_F9,
XK_F10,
XK_F11,
XK_F12,
XK_Page_Up,
XK_Page_Down,
XK_Insert,
XK_Delete,
XK_Home,
XK_End,
XK_KP_Divide,
XK_KP_Multiply,
XK_KP_Subtract,
XK_KP_Add,
XK_KP_Enter,
XK_KP_0,
XK_KP_1,
XK_KP_2,
XK_KP_3,
XK_KP_4,
XK_KP_5,
XK_KP_6,
XK_KP_7,
XK_KP_8,
XK_KP_9,
XK_KP_Decimal
};
class WindowIO::Private
{
public:
Private(Process * _p)
{
p=_p;
};
~Private(){};
// Source: http://www.experts-exchange.com/OS/Unix/X_Windows/Q_21341279.html
// find named window recursively
Window EnumerateWindows (Display *display, Window rootWindow, const char *searchString);
// iterate through X screens, find the window
// FIXME: use _NET_WM_PID primarily and this current stuff only as a fallback
// see http://www.mail-archive.com/devel@xfree86.org/msg05818.html
bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow);
// send synthetic key events to a window
// Source: http://homepage3.nifty.com/tsato/xvkbd/events.html
void send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay);
// our parent process
Process * p;
};
// ctor
WindowIO::WindowIO (DFContextShared * csh)
{
d = new Private(csh->p);
}
// dtor
WindowIO::~WindowIO ()
{
delete d;
}
Window WindowIO::Private::EnumerateWindows (Display *display, Window rootWindow, const char *searchString)
{
Window parent;
Window *children;
Window retWindow = BadWindow;
unsigned int noOfChildren;
int status;
// get name of current window, compare to control, return if found
char * win_name;
status = XFetchName (display, rootWindow, &win_name);
if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0)
{
return rootWindow;
}
// look at surrounding window tree nodes, bailout on error or no children
status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren);
if (!status || !noOfChildren)
{
return BadWindow;
}
// recurse into children
for (uint32_t i = 0; i < noOfChildren; i++)
{
Window tempWindow = EnumerateWindows (display, children[i], searchString);
if (tempWindow != BadWindow)
{
retWindow = tempWindow;
break;
}
}
// free resources
XFree ( (char*) children);
return retWindow;
}
bool WindowIO::Private::getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow)
{
// int numScreeens = ScreenCount(dpy);
for (int i = 0;i < ScreenCount (dpy);i++)
{
rootWindow = RootWindow (dpy, i);
Window retWindow = EnumerateWindows (dpy, rootWindow, "Dwarf Fortress");
if (retWindow != BadWindow)
{
dfWindow = retWindow;
return true;
}
}
return false;
}
void WindowIO::Private::send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay)
{
XKeyEvent event;
event.display = display;
event.window = dfW;
event.root = rootW;
event.subwindow = None;
event.time = CurrentTime;
event.x = 1;
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = true;
event.type = (is_press ? KeyPress : KeyRelease);
event.keycode = keycode;
event.state = modstate;
XSendEvent(event.display, event.window, true, KeyPressMask, (XEvent *) &event);
usleep(delay);
}
void WindowIO::TypeStr (const char *input, int delay, bool useShift)
{
Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY
Window dfWin;
Window rootWin;
if (d->getDFWindow (dpy, dfWin, rootWin))
{
char cChar;
int realDelay = delay * 1000;
KeyCode xkeycode;
while ( (cChar = *input++)) // loops through chars
{
// HACK: the timing here is a strange beast
xkeycode = XKeysymToKeycode (dpy, cChar);
d->send_xkeyevent(dpy,dfWin,rootWin,XKeysymToKeycode(dpy, ksTable[DFHack::LEFT_SHIFT]),0,false, realDelay);
if (useShift || (cChar >= 'A' && cChar <= 'Z'))
{
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, realDelay);
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, realDelay);
XSync (dpy, false);
}
else
{
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay);
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay);
XSync (dpy, false);
}
}
}
else
{
cout << "FAIL!" << endl;
}
}
void WindowIO::TypeSpecial (t_special command, int count, int delay)
{
if (command != WAIT)
{
KeySym mykeysym;
KeyCode xkeycode;
Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY
int realDelay = delay * 1000;
Window dfWin;
Window rootWin;
if (d->getDFWindow (dpy, dfWin, rootWin))
{
for (int i = 0;i < count; i++)
{
// HACK: the timing here is a strange beast
mykeysym = ksTable[command];
xkeycode = XKeysymToKeycode (dpy, mykeysym);
d->send_xkeyevent(dpy,dfWin,rootWin,XKeysymToKeycode(dpy, ksTable[DFHack::LEFT_SHIFT]),0,false, realDelay);
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay);
d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay);
XSync (dpy, false);
}
}
else
{
cout << "FAIL!" << endl;
}
}
else
{
usleep (delay*1000 * count);
}
}

@ -1,197 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "Internal.h"
#include "PlatformInternal.h"
#include <vector>
#include <string>
using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/WindowIO.h"
#include "dfhack/DFProcess.h"
#include "ModuleFactory.h"
using namespace DFHack;
Module* DFHack::createWindowIO(DFContextShared * d)
{
return new WindowIO(d);
}
// should always reflect the enum in DFkeys.h
const static int ksTable[NUM_SPECIALS]=
{
VK_RETURN,
VK_SPACE,
VK_BACK,
VK_TAB,
VK_CAPITAL,
VK_LSHIFT,
VK_RSHIFT,
VK_LCONTROL,
VK_RCONTROL,
VK_MENU,
0, //XK_VoidSymbol, // WAIT
VK_ESCAPE,
VK_UP,
VK_DOWN,
VK_LEFT,
VK_RIGHT,
VK_F1,
VK_F2,
VK_F3,
VK_F4,
VK_F5,
VK_F6,
VK_F7,
VK_F8,
VK_F9,
VK_F10,
VK_F11,
VK_F12,
VK_PRIOR,
VK_NEXT,
VK_INSERT,
VK_DELETE,
VK_HOME,
VK_END,
VK_DIVIDE,
VK_MULTIPLY,
VK_SUBTRACT,
VK_ADD,
VK_RETURN,
VK_NUMPAD0,
VK_NUMPAD1,
VK_NUMPAD2,
VK_NUMPAD3,
VK_NUMPAD4,
VK_NUMPAD5,
VK_NUMPAD6,
VK_NUMPAD7,
VK_NUMPAD8,
VK_NUMPAD9,
VK_SEPARATOR
};
//Windows key handlers
struct window
{
HWND windowHandle;
uint32_t pid;
};
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
{
uint32_t pid;
GetWindowThreadProcessId (hwnd, (LPDWORD) &pid);
if (pid == ( (window *) lParam)->pid)
{
( (window *) lParam)->windowHandle = hwnd;
return FALSE;
}
return TRUE;
}
class WindowIO::Private
{
public:
Private(Process * _p)
{
p=_p;
};
~Private(){};
// our parent process
Process * p;
};
// ctor
WindowIO::WindowIO (DFContextShared * schr)
{
d = new Private(schr->p);
}
// dtor
WindowIO::~WindowIO ()
{
delete d;
}
// TODO: also investigate possible problems with UIPI on Vista and 7
void WindowIO::TypeStr (const char *input, int delay, bool useShift)
{
//sendmessage needs a window handle HWND, so have to get that from the process HANDLE
window myWindow;
myWindow.pid = d->p->getPID();
EnumWindows (EnumWindowsProc, (LPARAM) &myWindow);
char cChar;
DWORD dfProcess = GetWindowThreadProcessId(myWindow.windowHandle,NULL);
DWORD currentProcess = GetCurrentThreadId();
AttachThreadInput(currentProcess,dfProcess,TRUE); //The two threads have to have attached input in order to change the keyboard state, which is needed to set the shift state
while ( (cChar = *input++)) // loops through chars
{
short vk = VkKeyScan (cChar); // keycode of char
if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift
{
vk = vk & 0xFF; // remove the shift state from the virtual key code
BYTE keybstate[256] = {0};
BYTE keybstateOrig[256] = {0};
GetKeyboardState((LPBYTE)&keybstateOrig);
GetKeyboardState((LPBYTE)&keybstate);
keybstate[VK_SHIFT] |= 0x80; //Set shift state to on in variable
SetKeyboardState((LPBYTE)&keybstate); //set the current state to the variable
SendMessage(myWindow.windowHandle,WM_KEYDOWN,vk,0);
SendMessage(myWindow.windowHandle,WM_KEYUP,vk,0);
SetKeyboardState((LPBYTE)&keybstateOrig); // reset the shift state to the original state
}
else
{
SendMessage(myWindow.windowHandle,WM_KEYDOWN,vk,0);
SendMessage(myWindow.windowHandle,WM_KEYUP,vk,0);
}
}
AttachThreadInput(currentProcess,dfProcess,FALSE); //detach the threads
Sleep (delay);
}
void WindowIO::TypeSpecial (t_special command, int count, int delay)
{
if (command != WAIT)
{
HWND currentWindow = GetForegroundWindow();
window myWindow;
myWindow.pid = d->p->getPID();
EnumWindows (EnumWindowsProc, (LPARAM) &myWindow);
for (int i = 0; i < count;i++)
{
SendMessage(myWindow.windowHandle,WM_KEYDOWN,ksTable[command],0);
SendMessage(myWindow.windowHandle,WM_KEYUP,ksTable[command],0);
}
Sleep (delay);
}
else
{
Sleep (delay*count);
}
}

@ -1,71 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <vector>
#include <map>
#include <string>
using namespace std;
#include "dfhack-c/Common.h"
#include "dfhack/DFIntegers.h"
#include "dfhack/modules/WindowIO.h"
#include "dfhack-c/modules/WindowIO_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int WindowIO_TypeStr(DFHackObject* window, const char* input, uint32_t delay, int8_t useShift)
{
if(window != NULL)
{
bool shifting = false;
if(useShift > 0)
shifting = true;
((DFHack::WindowIO*)window)->TypeStr(input, delay, shifting);
return 1;
}
return -1;
}
int WindowIO_TypeSpecial(DFHackObject* window, t_special command, uint32_t count, uint32_t delay)
{
if(window != NULL)
{
((DFHack::WindowIO*)window)->TypeSpecial(command, count, delay);
return 1;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -1,185 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <vector>
#include <map>
#include <string>
using namespace std;
#include "dfhack-c/Common.h"
#include "dfhack/modules/World.h"
#include "dfhack-c/modules/World_C.h"
#include "dfhack-c/DFTypes_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int World_Start(DFHackObject* world)
{
if(world != NULL)
{
if(((DFHack::World*)world)->Start())
return 1;
else
return 0;
}
return -1;
}
int World_Finish(DFHackObject* world)
{
if(world != NULL)
{
if(((DFHack::World*)world)->Finish())
return 1;
else
return 0;
}
return -1;
}
int World_ReadCurrentTick(DFHackObject* world, uint32_t* tick)
{
if(world != NULL)
{
*tick = ((DFHack::World*)world)->ReadCurrentTick();
return 1;
}
return -1;
}
int World_ReadCurrentYear(DFHackObject* world, uint32_t* year)
{
if(world != NULL)
{
*year = ((DFHack::World*)world)->ReadCurrentYear();
return 1;
}
return -1;
}
int World_ReadCurrentMonth(DFHackObject* world, uint32_t* month)
{
if(world != NULL)
{
*month = ((DFHack::World*)world)->ReadCurrentMonth();
return 1;
}
return -1;
}
int World_ReadCurrentDay(DFHackObject* world, uint32_t* day)
{
if(world != NULL)
{
*day = ((DFHack::World*)world)->ReadCurrentDay();
return 1;
}
return -1;
}
int World_ReadCurrentWeather(DFHackObject* world, uint8_t* weather)
{
if(world != NULL)
{
*weather = ((DFHack::World*)world)->ReadCurrentWeather();
return 1;
}
return -1;
}
int World_WriteCurrentWeather(DFHackObject* world, uint8_t weather)
{
if(world != NULL)
{
((DFHack::World*)world)->SetCurrentWeather(weather);
return 1;
}
return -1;
}
int World_ReadGameMode(DFHackObject* world, t_gamemodes* modes)
{
if(world != NULL)
{
if(((DFHack::World*)world)->ReadGameMode(*modes))
return 1;
else
return 0;
}
return -1;
}
int World_WriteGameMode(DFHackObject* world, t_gamemodes modes)
{
if(world != NULL)
{
if(((DFHack::World*)world)->WriteGameMode(modes))
return 1;
else
return 0;
}
return -1;
}
int World_ReadPauseState(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::World*)gui)->ReadPauseState();
}
return -1;
}
int World_SetPauseState(DFHackObject* gui, int8_t paused)
{
if(gui != NULL)
{
bool pauseState = false;
if(paused > 0)
pauseState = true;
((DFHack::World*)gui)->SetPauseState(pauseState);
return 1;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -34,7 +34,6 @@ namespace DFHack
Module* createCreatures(DFContextShared * d);
Module* createEngravings(DFContextShared * d);
Module* createGui(DFContextShared * d);
Module* createWindowIO(DFContextShared * d);
Module* createWorld(DFContextShared * d);
Module* createMaterials(DFContextShared * d);
Module* createItems(DFContextShared * d);

@ -1,115 +0,0 @@
#ifndef DFCONNECT_H
#define DFCONNECT_H
#define SHM_KEY 123466
#define SHM_MAX_CLIENTS 4
#define SHM_HEADER 1024 // 1kB reserved for a header
#define SHM_BODY 1024*1024 // 4MB reserved for bulk data transfer
#define SHM_SIZE SHM_HEADER+SHM_BODY
//#define SHM_ALL_CLIENTS SHM_MAX_CLIENTS*(SHM_SIZE)
//#define SHM_CL(client_idx) client_idx*(SHM_SIZE)
// FIXME: add YIELD for linux, add single-core and multi-core compile targets for optimal speed
#ifdef LINUX_BUILD
// a full memory barrier! better be safe than sorry.
#define full_barrier asm volatile("" ::: "memory"); __sync_synchronize();
#define SCHED_YIELD sched_yield(); // a requirement for single-core
#else
// we need windows.h for Sleep()
#define _WIN32_WINNT 0x0501 // needed for INPUT struct
#define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define SCHED_YIELD Sleep(0); // avoids infinite lockup on single core
// FIXME: detect MSVC here and use the right barrier magic
#ifdef __MINGW32__
#define full_barrier asm volatile("" ::: "memory");
#else
#include <intrin.h>
#pragma intrinsic(_ReadWriteBarrier)
#define full_barrier _ReadWriteBarrier();
#endif
#endif
enum DFPP_Locking
{
LOCKING_BUSY = 0,
LOCKING_LOCKS = 1
};
enum DFPP_CmdType
{
CANCELLATION, // we should jump out of the Act()
CLIENT_WAIT, // we are waiting for the client
FUNCTION // we call a function as a result of the command
};
struct DFPP_command
{
void (*_function)(void *);
DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons
std::string name;
uint32_t nextState;
DFPP_Locking locking;
};
struct DFPP_module
{
DFPP_module()
{
name = "Uninitialized module";
version = 0;
modulestate = 0;
}
// ALERT: the structures share state
DFPP_module(const DFPP_module & orig)
{
commands = orig.commands;
name = orig.name;
modulestate = orig.modulestate;
version = orig.version;
}
inline void set_command(const unsigned int index, const DFPP_CmdType type, const char * name, void (*_function)(void *) = 0,uint32_t nextState = -1, DFPP_Locking locking = LOCKING_BUSY)
{
commands[index].type = type;
commands[index].name = name;
commands[index]._function = _function;
commands[index].nextState = nextState;
commands[index].locking = locking;
}
inline void reserve (unsigned int numcommands)
{
commands.clear();
DFPP_command cmd = {0,CANCELLATION,"",0};
commands.resize(numcommands,cmd);
}
std::string name;
uint32_t version; // version
std::vector <DFPP_command> commands;
void * modulestate;
};
union shm_cmd
{
struct
{
volatile uint16_t command;
volatile uint16_t module;
} parts;
volatile uint32_t pingpong;
shm_cmd(volatile uint32_t z)
{
pingpong = z;
}
};
void SHM_Act (void);
void InitModules (void);
void KillModules (void);
bool isValidSHM(int current);
uint32_t OS_getPID();
uint32_t OS_getAffinity(); // limited to 32 processors. Silly, eh?
void OS_releaseSuspendLock(int currentClient);
void OS_lockSuspendLock(int currentClient);
#endif