Merge branch 'shm-only'
commit
5c4ef73f4d
@ -0,0 +1,292 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/dfhack
|
||||
Copyright (c) 2009 Petr Mrázek (peterix)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the source for the DF <-> dfhack shm bridge's core module.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../library/integers.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define SHM_INTERNAL // for things only visible to the SHM
|
||||
|
||||
#include "shms.h"
|
||||
#include "mod-core.h"
|
||||
#include "mod-maps.h"
|
||||
|
||||
std::vector <DFPP_module> module_registry;
|
||||
|
||||
// various crud
|
||||
extern int errorstate;
|
||||
extern char *shm;
|
||||
extern int shmid;
|
||||
bool useYield = 0;
|
||||
|
||||
#define SHMHDR ((shm_core_hdr *)shm)
|
||||
#define SHMCMD ((shm_cmd *)shm)->pingpong
|
||||
#define SHMDATA(type) ((type *)(shm + SHM_HEADER))
|
||||
|
||||
void ReadRaw (void * data)
|
||||
{
|
||||
memcpy(shm + SHM_HEADER, (void *) SHMHDR->address,SHMHDR->length);
|
||||
}
|
||||
|
||||
void ReadDWord (void * data)
|
||||
{
|
||||
SHMHDR->value = *((uint32_t*) SHMHDR->address);
|
||||
}
|
||||
|
||||
void ReadWord (void * data)
|
||||
{
|
||||
SHMHDR->value = *((uint16_t*) SHMHDR->address);
|
||||
}
|
||||
|
||||
void ReadByte (void * data)
|
||||
{
|
||||
SHMHDR->value = *((uint8_t*) SHMHDR->address);
|
||||
}
|
||||
|
||||
void WriteRaw (void * data)
|
||||
{
|
||||
memcpy((void *)SHMHDR->address, shm + SHM_HEADER,SHMHDR->length);
|
||||
}
|
||||
|
||||
void WriteDWord (void * data)
|
||||
{
|
||||
(*(uint32_t*)SHMHDR->address) = SHMHDR->value;
|
||||
}
|
||||
|
||||
void WriteWord (void * data)
|
||||
{
|
||||
(*(uint16_t*)SHMHDR->address) = SHMHDR->value;
|
||||
}
|
||||
|
||||
void WriteByte (void * data)
|
||||
{
|
||||
(*(uint8_t*)SHMHDR->address) = SHMHDR->value;
|
||||
}
|
||||
|
||||
void ReadSTLString (void * data)
|
||||
{
|
||||
std::string * myStringPtr = (std::string *) SHMHDR->address;
|
||||
unsigned int l = myStringPtr->length();
|
||||
SHMHDR->value = l;
|
||||
// FIXME: there doesn't have to be a null terminator!
|
||||
strncpy(shm+SHM_HEADER,myStringPtr->c_str(),l+1);
|
||||
}
|
||||
|
||||
void WriteSTLString (void * data)
|
||||
{
|
||||
std::string * myStringPtr = (std::string *) SHMHDR->address;
|
||||
// here we DO expect a 0 terminator
|
||||
myStringPtr->assign((const char *) (shm + SHM_HEADER));
|
||||
}
|
||||
|
||||
// MIT HAKMEM bitcount
|
||||
int bitcount(uint32_t n)
|
||||
{
|
||||
register uint32_t tmp;
|
||||
|
||||
tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);
|
||||
return ((tmp + (tmp >> 3)) & 030707070707) % 63;
|
||||
}
|
||||
|
||||
// get local and remote affinity, set up yield if required (single core available)
|
||||
void CoreAttach (void * data)
|
||||
{
|
||||
// sync affinity
|
||||
uint32_t local = OS_getAffinity();
|
||||
uint32_t remote = SHMDATA(coreattach)->cl_affinity;
|
||||
uint32_t pool = local | remote;
|
||||
SHMDATA(coreattach)->sv_useYield = useYield = (bitcount(pool) == 1);
|
||||
// return our PID
|
||||
SHMDATA(coreattach)->sv_PID = OS_getPID();
|
||||
// return core version
|
||||
SHMDATA(coreattach)->sv_version = module_registry[0].version;
|
||||
}
|
||||
|
||||
void FindModule (void * data)
|
||||
{
|
||||
bool found = false;
|
||||
modulelookup * payload = (modulelookup *) (shm + SHM_HEADER);
|
||||
std::string test = payload->name;
|
||||
uint32_t version = payload->version;
|
||||
for(unsigned int i = 0; i < module_registry.size();i++)
|
||||
{
|
||||
if(module_registry[i].name == test && module_registry[i].version == version)
|
||||
{
|
||||
// gotcha
|
||||
SHMHDR->value = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SHMHDR->error = !found;
|
||||
}
|
||||
|
||||
void FindCommand (void * data)
|
||||
{
|
||||
bool found = false;
|
||||
commandlookup * payload = SHMDATA(commandlookup);
|
||||
std::string modname = payload->module;
|
||||
std::string cmdname = payload->name;
|
||||
uint32_t version = payload->version;
|
||||
for(unsigned int i = 0; i < module_registry.size();i++)
|
||||
{
|
||||
if(module_registry[i].name == modname && module_registry[i].version == version)
|
||||
{
|
||||
for(unsigned int j = 0 ; j < module_registry[i].commands.size();j++)
|
||||
{
|
||||
if(module_registry[i].commands[j].name == cmdname)
|
||||
{
|
||||
// gotcha
|
||||
SHMHDR->value = j + (i << 16);
|
||||
SHMHDR->error = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SHMHDR->error = true;
|
||||
}
|
||||
|
||||
DFPP_module InitCore(void)
|
||||
{
|
||||
DFPP_module core;
|
||||
core.name = "Core";
|
||||
core.version = CORE_VERSION;
|
||||
core.modulestate = 0; // this one is dumb and has no real state
|
||||
|
||||
core.reserve(NUM_CORE_CMDS);
|
||||
// basic states
|
||||
core.set_command(CORE_RUNNING, CANCELLATION, "Running");
|
||||
core.set_command(CORE_SUSPEND, CLIENT_WAIT, "Suspend", 0 , CORE_SUSPENDED);
|
||||
core.set_command(CORE_SUSPENDED, CLIENT_WAIT, "Suspended");
|
||||
core.set_command(CORE_ERROR, CANCELLATION, "Error");
|
||||
|
||||
// utility commands
|
||||
core.set_command(CORE_ATTACH, FUNCTION,"Core attach",CoreAttach, CORE_SUSPENDED);
|
||||
core.set_command(CORE_ACQUIRE_MODULE, FUNCTION, "Module lookup", FindModule, CORE_SUSPENDED);
|
||||
core.set_command(CORE_ACQUIRE_COMMAND, FUNCTION, "Command lookup", FindCommand, CORE_SUSPENDED);
|
||||
|
||||
// raw reads
|
||||
core.set_command(CORE_DFPP_READ, FUNCTION,"Raw read",ReadRaw, CORE_SUSPENDED);
|
||||
core.set_command(CORE_READ_DWORD, FUNCTION,"Read DWORD",ReadDWord, CORE_SUSPENDED);
|
||||
core.set_command(CORE_READ_WORD, FUNCTION,"Read WORD",ReadWord, CORE_SUSPENDED);
|
||||
core.set_command(CORE_READ_BYTE, FUNCTION,"Read BYTE",ReadByte, CORE_SUSPENDED);
|
||||
|
||||
// raw writes
|
||||
core.set_command(CORE_WRITE, FUNCTION, "Raw write", WriteRaw, CORE_SUSPENDED);
|
||||
core.set_command(CORE_WRITE_DWORD, FUNCTION, "Write DWORD", WriteDWord, CORE_SUSPENDED);
|
||||
core.set_command(CORE_WRITE_WORD, FUNCTION, "Write WORD", WriteWord, CORE_SUSPENDED);
|
||||
core.set_command(CORE_WRITE_BYTE, FUNCTION, "Write BYTE", WriteByte, CORE_SUSPENDED);
|
||||
|
||||
// stl string commands
|
||||
core.set_command(CORE_READ_STL_STRING, FUNCTION, "Read STL string", ReadSTLString, CORE_SUSPENDED);
|
||||
core.set_command(CORE_READ_C_STRING, CLIENT_WAIT, "RESERVED");
|
||||
core.set_command(CORE_WRITE_STL_STRING, FUNCTION, "Write STL string", WriteSTLString, CORE_SUSPENDED);
|
||||
return core;
|
||||
}
|
||||
|
||||
void InitModules (void)
|
||||
{
|
||||
// create the core module
|
||||
module_registry.push_back(InitCore());
|
||||
module_registry.push_back(InitMaps());
|
||||
// TODO: dynamic module init
|
||||
}
|
||||
|
||||
void KillModules (void)
|
||||
{
|
||||
for(unsigned int i = 0; i < module_registry.size();i++)
|
||||
{
|
||||
if(module_registry[i].modulestate)
|
||||
free(module_registry[i].modulestate);
|
||||
}
|
||||
module_registry.clear();
|
||||
}
|
||||
|
||||
void SHM_Act (void)
|
||||
{
|
||||
if(errorstate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t numwaits = 0;
|
||||
check_again: // goto target!!!
|
||||
if(numwaits == 10000)
|
||||
{
|
||||
// this tests if there's a process on the other side
|
||||
if(isValidSHM())
|
||||
{
|
||||
numwaits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
full_barrier
|
||||
SHMCMD = CORE_RUNNING;
|
||||
fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// this is very important! copying two words separately from the command variable leads to inconsistency.
|
||||
// Always copy the thing in one go.
|
||||
// Also, this whole SHM thing probably only works on intel processors
|
||||
|
||||
volatile shm_cmd atomic = SHMHDR->cmd;
|
||||
full_barrier
|
||||
DFPP_module & mod = module_registry[atomic.parts.module];
|
||||
DFPP_command & cmd = mod.commands[atomic.parts.command];
|
||||
full_barrier
|
||||
/*
|
||||
fprintf(stderr, "Called %x\0", cmd._function);
|
||||
fprintf(stderr, "Client invoked %d:%d = ",atomic.parts.module,atomic.parts.command);
|
||||
fprintf(stderr, "%s\n",cmd.name.c_str());
|
||||
*/
|
||||
full_barrier
|
||||
if(cmd._function)
|
||||
{
|
||||
cmd._function(mod.modulestate);
|
||||
}
|
||||
full_barrier
|
||||
if(cmd.nextState != -1)
|
||||
{
|
||||
SHMCMD = cmd.nextState;
|
||||
}
|
||||
full_barrier
|
||||
if(cmd.type != CANCELLATION)
|
||||
{
|
||||
if(useYield)
|
||||
{
|
||||
SCHED_YIELD
|
||||
}
|
||||
numwaits ++; // watchdog timeout
|
||||
goto check_again;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/dfhack
|
||||
Copyright (c) 2009 Petr Mrázek (peterix)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef SHMS_CORE_H
|
||||
#define SHMS_CORE_H
|
||||
|
||||
// increment on every core change
|
||||
#define CORE_VERSION 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
shm_cmd cmd;
|
||||
uint32_t address;
|
||||
uint32_t value;
|
||||
uint32_t length;
|
||||
uint32_t error;
|
||||
} shm_core_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t version;
|
||||
char name[256];
|
||||
} modulelookup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t version;
|
||||
char module[256];
|
||||
char name[256];
|
||||
} commandlookup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t sv_version; // output
|
||||
uint32_t cl_affinity; // input
|
||||
uint32_t sv_PID; // output
|
||||
uint32_t sv_useYield; // output
|
||||
} coreattach;
|
||||
|
||||
enum CORE_COMMAND
|
||||
{
|
||||
// basic states
|
||||
CORE_RUNNING = 0, // no command, normal server execution
|
||||
CORE_SUSPEND, // client notifies server to wait for commands (server is stalled in busy wait)
|
||||
CORE_SUSPENDED, // response to WAIT, server is stalled in busy wait
|
||||
CORE_ERROR, // there was a server error
|
||||
|
||||
// utility commands
|
||||
CORE_ATTACH, // compare affinity, get core version and process ID
|
||||
CORE_ACQUIRE_MODULE, // get index of a loaded module by name and version
|
||||
CORE_ACQUIRE_COMMAND, // get module::command callsign by module name, command name and module version
|
||||
|
||||
// raw reads
|
||||
CORE_DFPP_READ, // cl -> sv, read some data
|
||||
CORE_READ_DWORD, // cl -> sv, read a dword
|
||||
CORE_READ_WORD, // cl -> sv, read a word
|
||||
CORE_READ_BYTE, // cl -> sv, read a byte
|
||||
|
||||
// raw writes
|
||||
CORE_WRITE,// client writes to server
|
||||
CORE_WRITE_DWORD,// client writes a DWORD to server
|
||||
CORE_WRITE_WORD,// client writes a WORD to server
|
||||
CORE_WRITE_BYTE,// client writes a BYTE to server
|
||||
|
||||
// string functions
|
||||
CORE_READ_STL_STRING,// client requests contents of STL string at address
|
||||
CORE_READ_C_STRING,// client requests contents of a C string at address, max length (0 means zero terminated)
|
||||
CORE_WRITE_STL_STRING,// client wants to set STL string at address to something
|
||||
|
||||
// total commands
|
||||
NUM_CORE_CMDS
|
||||
};
|
||||
#endif
|
@ -0,0 +1,121 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <integers.h>
|
||||
|
||||
#include "shms.h"
|
||||
#include "mod-core.h"
|
||||
#include "mod-maps.h"
|
||||
#include <DFTypes.h>
|
||||
using namespace DFHack;
|
||||
using namespace DFHack::Maps;
|
||||
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
extern char *shm;
|
||||
|
||||
//TODO: circular buffer streaming primitives required
|
||||
//TODO: commands can fail without the proper offsets. Hot to handle that?
|
||||
|
||||
#define SHMHDR ((shm_maps_hdr *)shm)
|
||||
#define SHMCMD ((shm_cmd *)shm)->pingpong
|
||||
#define SHMDATA ((char *)(shm + SHM_HEADER))
|
||||
|
||||
void NullCommand (void* data)
|
||||
{
|
||||
};
|
||||
|
||||
void InitOffsets (void* data)
|
||||
{
|
||||
maps_modulestate * state = (maps_modulestate *) data;
|
||||
memcpy((void *) &(state->offsets), SHMDATA, sizeof(maps_offsets));
|
||||
((maps_modulestate *) data)->inited = true;
|
||||
}
|
||||
|
||||
void GetMapSize (void *data)
|
||||
{
|
||||
maps_modulestate * state = (maps_modulestate *) data;
|
||||
if(state->inited)
|
||||
{
|
||||
SHMHDR->x = *(uint32_t *) (state->offsets.x_count_offset);
|
||||
SHMHDR->y = *(uint32_t *) (state->offsets.y_count_offset);
|
||||
SHMHDR->z = *(uint32_t *) (state->offsets.z_count_offset);
|
||||
SHMHDR->error = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHMHDR->error = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct mblock
|
||||
{
|
||||
uint32_t * ptr_to_dirty;
|
||||
};
|
||||
|
||||
#define SHMBLOCK ((mapblock40d *)(shm + SHM_HEADER))
|
||||
|
||||
inline void ReadBlockByAddress (void * data)
|
||||
{
|
||||
maps_modulestate * state = (maps_modulestate *) data;
|
||||
maps_offsets & offsets = state->offsets;
|
||||
mblock * block = (mblock *) SHMHDR->address;
|
||||
if(block)
|
||||
{
|
||||
memcpy(&(SHMBLOCK->tiletypes), ((char *) block) + offsets.tile_type_offset, sizeof(SHMBLOCK->tiletypes));
|
||||
memcpy(&(SHMBLOCK->designaton), ((char *) block) + offsets.designation_offset, sizeof(SHMBLOCK->designaton));
|
||||
memcpy(&(SHMBLOCK->occupancy), ((char *) block) + offsets.occupancy_offset, sizeof(SHMBLOCK->occupancy));
|
||||
memcpy(&(SHMBLOCK->biome_indices), ((char *) block) + offsets.biome_stuffs, sizeof(SHMBLOCK->biome_indices));
|
||||
SHMBLOCK->dirty_dword = *block->ptr_to_dirty;
|
||||
|
||||
SHMBLOCK->origin = (uint32_t)block;
|
||||
SHMHDR->error = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHMHDR->error = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadBlockByCoords (void * data)
|
||||
{
|
||||
maps_modulestate * state = (maps_modulestate *) data;
|
||||
maps_offsets & offsets = state->offsets;
|
||||
/* map_offset is a pointer to
|
||||
a pointer to
|
||||
an X block of pointers to
|
||||
an Y blocks of pointers to
|
||||
a Z blocks of pointers to
|
||||
map blocks
|
||||
only Z blocks can have NULL pointers? TODO: verify
|
||||
*/
|
||||
mblock * *** mapArray = *(mblock * ****)offsets.map_offset;
|
||||
SHMHDR->address = (uint32_t) mapArray[SHMHDR->x][SHMHDR->y][SHMHDR->z];
|
||||
ReadBlockByAddress(data); // I wonder... will this inline properly?
|
||||
}
|
||||
|
||||
DFPP_module InitMaps( void )
|
||||
{
|
||||
DFPP_module maps;
|
||||
maps.name = "Maps";
|
||||
maps.version = MAPS_VERSION;
|
||||
// freed by the core
|
||||
maps.modulestate = malloc(sizeof(maps_modulestate)); // we store a flag
|
||||
memset(maps.modulestate,0,sizeof(maps_modulestate));
|
||||
|
||||
maps.reserve(NUM_MAPS_CMDS);
|
||||
|
||||
// client sends a maps_offsets struct -> inited = true;
|
||||
maps.set_command(MAP_INIT, FUNCTION, "Supply the module with offsets",InitOffsets,CORE_SUSPENDED);
|
||||
maps.set_command(MAP_GET_SIZE, FUNCTION, "Get map size in 16x16x1 tile blocks", GetMapSize, CORE_SUSPENDED);
|
||||
maps.set_command(MAP_READ_BLOCK_BY_COORDS, FUNCTION, "Read the whole block with specified coords", ReadBlockByCoords, CORE_SUSPENDED);
|
||||
maps.set_command(MAP_READ_BLOCK_BY_ADDRESS, FUNCTION, "Read the whole block from an address", ReadBlockByAddress, CORE_SUSPENDED);
|
||||
|
||||
// will it fit into 1MB? We shouldn't assume this is the case
|
||||
maps.set_command(MAP_READ_BLOCKTREE, FUNCTION,"Get the tree of block pointers as a single structure", NullCommand, CORE_SUSPENDED);
|
||||
|
||||
// really doesn't fit into 1MB, there should be a streaming variant to better utilize context switches
|
||||
maps.set_command(MAP_READ_BLOCKS_3D, FUNCTION, "Read a range of blocks between two sets of coords", NullCommand, CORE_SUSPENDED);
|
||||
|
||||
return maps;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/dfhack
|
||||
Copyright (c) 2009 Petr Mrázek (peterix)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef MOD_MAPS_H
|
||||
#define MOD_MAPS_H
|
||||
|
||||
// increment on every change
|
||||
#include <DFTypes.h>
|
||||
|
||||
namespace DFHack
|
||||
{
|
||||
namespace Maps
|
||||
{
|
||||
|
||||
#define MAPS_VERSION 2
|
||||
typedef struct
|
||||
{
|
||||
uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data");
|
||||
uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count");
|
||||
uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count");
|
||||
uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count");
|
||||
uint32_t tile_type_offset;// = d->offset_descriptor->getOffset ("type");
|
||||
uint32_t designation_offset;// = d->offset_descriptor->getOffset ("designation");
|
||||
uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy");
|
||||
uint32_t biome_stuffs;// = d->offset_descriptor->getOffset ("biome_stuffs");
|
||||
uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein");
|
||||
uint32_t vein_mineral_vptr;
|
||||
uint32_t vein_ice_vptr;
|
||||
/*
|
||||
GEOLOGY
|
||||
uint32_t region_x_offset;// = minfo->getAddress ("region_x");
|
||||
uint32_t region_y_offset;// = minfo->getAddress ("region_y");
|
||||
uint32_t region_z_offset;// = minfo->getAddress ("region_z");
|
||||
uint32_t world_offset;// = minfo->getAddress ("world");
|
||||
uint32_t world_regions_offset;// = minfo->getOffset ("w_regions_arr");
|
||||
uint32_t region_size;// = minfo->getHexValue ("region_size");
|
||||
uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off");
|
||||
uint32_t world_geoblocks_offset;// = minfo->getOffset ("w_geoblocks");
|
||||
uint32_t world_size_x;// = minfo->getOffset ("world_size_x");
|
||||
uint32_t world_size_y;// = minfo->getOffset ("world_size_y");
|
||||
uint32_t geolayer_geoblock_offset;// = minfo->getOffset ("geolayer_geoblock_offset");
|
||||
*/
|
||||
} maps_offsets;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool inited;
|
||||
maps_offsets offsets;
|
||||
} maps_modulestate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
shm_cmd cmd;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t z;
|
||||
uint32_t x2;
|
||||
uint32_t y2;
|
||||
uint32_t z2;
|
||||
uint32_t address;
|
||||
uint32_t error;
|
||||
} shm_maps_hdr;
|
||||
|
||||
enum MAPS_COMMAND
|
||||
{
|
||||
MAP_INIT = 0, // initialization
|
||||
MAP_PROBE, // check if the map is still there
|
||||
MAP_GET_SIZE, // get the map size in 16x16x1 blocks
|
||||
MAP_READ_BLOCKTREE, // read the structure of pointers to blocks
|
||||
MAP_READ_BLOCK_BY_COORDS, // read block by cords
|
||||
MAP_READ_BLOCK_BY_ADDRESS, // read block by address
|
||||
MAP_WRITE_BLOCK,
|
||||
MAP_READ_BLOCKS_3D, // read blocks between two coords (volumetric)
|
||||
MAP_READ_ALL_BLOCKS, // read the entire map
|
||||
MAP_REVEAL, // reveal the whole map
|
||||
NUM_MAPS_CMDS,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/dfhack
|
||||
Copyright (c) 2009 Petr Mrázek (peterix)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the source for the DF <-> dfhack shm bridge, server protocol part
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "../library/integers.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
//#include <unistd.h>
|
||||
#include "shms.h"
|
||||
// various crud
|
||||
extern int errorstate;
|
||||
extern char *shm;
|
||||
extern int shmid;
|
||||
|
||||
void SHM_Act (void)
|
||||
{
|
||||
if(errorstate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t numwaits = 0;
|
||||
uint32_t length;
|
||||
uint32_t address;
|
||||
std::string * myStringPtr;
|
||||
check_again: // goto target!!!
|
||||
SCHED_YIELD // yield the CPU, valid only on single-core CPUs
|
||||
if(numwaits == 10000)
|
||||
{
|
||||
// this tests if there's a process on the other side
|
||||
if(isValidSHM())
|
||||
{
|
||||
numwaits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_RUNNING;
|
||||
fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
|
||||
//MessageBox(0,"Broke out of loop, other process disappeared.","FUN", MB_OK);
|
||||
}
|
||||
}
|
||||
switch (((shm_cmd *)shm)->pingpong)
|
||||
{
|
||||
case DFPP_RET_VERSION:
|
||||
case DFPP_RET_DATA:
|
||||
case DFPP_RET_DWORD:
|
||||
case DFPP_RET_WORD:
|
||||
case DFPP_RET_BYTE:
|
||||
case DFPP_RET_STRING:
|
||||
case DFPP_SUSPENDED:
|
||||
case DFPP_RET_PID:
|
||||
case DFPP_SV_ERROR:
|
||||
numwaits++;
|
||||
goto check_again;
|
||||
case DFPP_SUSPEND:
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
/*
|
||||
case DFPP_BOUNCE:
|
||||
length = ((shm_bounce *)shm)->length;
|
||||
memcpy(BigFat,shm + SHM_HEADER,length);
|
||||
memcpy(shm + SHM_HEADER,BigFat,length);
|
||||
((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
|
||||
goto check_again;
|
||||
*/
|
||||
case DFPP_PID:
|
||||
((shm_retval *)shm)->value = getPID();
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_PID;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_VERSION:
|
||||
((shm_retval *)shm)->value = PINGPONG_VERSION;
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_VERSION;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_READ:
|
||||
length = ((shm_read *)shm)->length;
|
||||
address = ((shm_read *)shm)->address;
|
||||
memcpy(shm + SHM_HEADER, (void *) address,length);
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_READ_DWORD:
|
||||
address = ((shm_read_small *)shm)->address;
|
||||
((shm_retval *)shm)->value = *((uint32_t*) address);
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_DWORD;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_READ_WORD:
|
||||
address = ((shm_read_small *)shm)->address;
|
||||
((shm_retval *)shm)->value = *((uint16_t*) address);
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_WORD;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_READ_BYTE:
|
||||
address = ((shm_read_small *)shm)->address;
|
||||
((shm_retval *)shm)->value = *((uint8_t*) address);
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_BYTE;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_WRITE:
|
||||
address = ((shm_write *)shm)->address;
|
||||
length = ((shm_write *)shm)->length;
|
||||
memcpy((void *)address, shm + SHM_HEADER,length);
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_WRITE_DWORD:
|
||||
(*(uint32_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_WRITE_WORD:
|
||||
(*(uint16_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_WRITE_BYTE:
|
||||
(*(uint8_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_CL_ERROR:
|
||||
case DFPP_RUNNING:
|
||||
//fprintf(stderr, "no. of waits: %d\n", numwaits);
|
||||
//MessageBox(0,"Broke out of loop properly","FUN", MB_OK);
|
||||
break;
|
||||
|
||||
case DFPP_READ_STL_STRING:
|
||||
myStringPtr = (std::string *) ((shm_read_small *)shm)->address;
|
||||
((shm_retval *)shm)->value = myStringPtr->length();
|
||||
strncpy(shm+SHM_HEADER,myStringPtr->c_str(),myStringPtr->length()+1);// length + 1 for the null terminator
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_RET_STRING;
|
||||
goto check_again;
|
||||
|
||||
case DFPP_WRITE_STL_STRING:
|
||||
myStringPtr = (std::string *) ((shm_write *)shm)->address;
|
||||
myStringPtr->assign((const char *) (shm + SHM_HEADER));
|
||||
full_barrier
|
||||
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
|
||||
goto check_again;
|
||||
|
||||
|
||||
default:
|
||||
((shm_retval *)shm)->value = DFEE_INVALID_COMMAND;
|
||||
full_barrier
|
||||
((shm_retval *)shm)->pingpong = DFPP_SV_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue