Crud removal: Context is gone. Added missing FakeSDL.h

develop
Petr Mrázek 2011-06-17 15:02:43 +02:00
parent 4da11927af
commit e0fb8f7c81
36 changed files with 600 additions and 1186 deletions

@ -18,7 +18,6 @@ SET(PROJECT_HDRS_INTERNAL
SET(PROJECT_HDRS SET(PROJECT_HDRS
include/DFHack.h include/DFHack.h
include/dfhack/Context.h
include/dfhack/Error.h include/dfhack/Error.h
include/dfhack/Export.h include/dfhack/Export.h
include/dfhack/MiscUtils.h include/dfhack/MiscUtils.h
@ -47,12 +46,10 @@ include/dfhack/modules/World.h
) )
SET(PROJECT_SRCS SET(PROJECT_SRCS
Core.cpp
VersionInfo.cpp VersionInfo.cpp
VersionInfoFactory.cpp VersionInfoFactory.cpp
Context.cpp
Core.cpp
TileTypes.cpp TileTypes.cpp
ContextShared.cpp
depends/md5/md5.cpp depends/md5/md5.cpp
depends/md5/md5wrapper.cpp depends/md5/md5wrapper.cpp
@ -84,15 +81,11 @@ SET(PROJECT_HDRS_WINDOWS
SET(PROJECT_SRCS_LINUX SET(PROJECT_SRCS_LINUX
Core-linux.cpp Core-linux.cpp
Process-linux.cpp Process-linux.cpp
#DFProcess-linux-base.cpp
#DFProcess-linux-wine.cpp
#modules/WindowIO-linux.cpp
) )
SET(PROJECT_SRCS_WINDOWS SET(PROJECT_SRCS_WINDOWS
Core-windows.cpp Core-windows.cpp
Process-windows.cpp Process-windows.cpp
#modules/WindowIO-windows.cpp
) )
IF(UNIX) IF(UNIX)

@ -1,181 +0,0 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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>
using namespace std;
#include "dfhack/Process.h"
#include "dfhack/Context.h"
#include "dfhack/Error.h"
#include "dfhack/Module.h"
#include "private/ContextShared.h"
#include "private/ModuleFactory.h"
using namespace DFHack;
Context::Context (Process* p) : d (new DFContextShared())
{
d->p = p;
d->offset_descriptor = p->getDescriptor();
d->shm_start = 0;
}
Context::~Context()
{
//Detach();
delete d;
}
bool Context::isValid()
{
//FIXME: check for error states here
if(d->p->isIdentified())
return true;
return false;
}
/*
bool Context::Attach()
{
if (!d->p->attach())
{
//throw Error::CantAttach();
return false;
}
d->shm_start = d->p->getSHMStart();
// process is attached, everything went just fine... hopefully
return true;
}
bool Context::Detach()
{
if (!d->p->detach())
{
cerr << "Context::Detach failed!" << endl;
return false;
}
d->shm_start = 0;
// invalidate all modules
for(unsigned int i = 0 ; i < d->allModules.size(); i++)
{
delete d->allModules[i];
}
d->allModules.clear();
memset(&(d->s_mods), 0, sizeof(d->s_mods));
return true;
}
bool Context::isAttached()
{
return d->p->isAttached();
}
*/
bool Context::Suspend()
{
// return d->p->suspend();
return true;
}
bool Context::AsyncSuspend()
{
// return d->p->asyncSuspend();
return true;
}
bool Context::Resume()
{
for(unsigned int i = 0 ; i < d->allModules.size(); i++)
{
d->allModules[i]->OnResume();
}
//return d->p->resume();
return true;
}
/*
bool Context::ForceResume()
{
for(unsigned int i = 0 ; i < d->allModules.size(); i++)
{
d->allModules[i]->OnResume();
}
return d->p->forceresume();
}
*/
bool Context::isSuspended()
{
return d->p->isSuspended();
}
/*
void Context::ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target)
{
d->p->read (offset, size, target);
}
void Context::WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source)
{
d->p->write (offset, size, source);
}
*/
VersionInfo *Context::getMemoryInfo()
{
return d->offset_descriptor;
}
Process * Context::getProcess()
{
return d->p;
}
/*******************************************************************************
M O D U L E S
*******************************************************************************/
#define MODULE_GETTER(TYPE) \
TYPE * Context::get##TYPE() \
{ \
if(!d->s_mods.p##TYPE)\
{\
Module * mod = create##TYPE(d);\
d->s_mods.p##TYPE = (TYPE *) mod;\
d->allModules.push_back(mod);\
}\
return d->s_mods.p##TYPE;\
}
MODULE_GETTER(Creatures);
MODULE_GETTER(Engravings);
MODULE_GETTER(Maps);
MODULE_GETTER(Gui);
MODULE_GETTER(World);
MODULE_GETTER(Materials);
MODULE_GETTER(Items);
MODULE_GETTER(Translation);
MODULE_GETTER(Vegetation);
MODULE_GETTER(Buildings);
MODULE_GETTER(Constructions);

@ -1,112 +0,0 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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>
#include <cstring>
using namespace std;
#include "private/ContextShared.h"
#include "dfhack/VersionInfo.h"
#include "dfhack/Process.h"
#include "dfhack/Module.h"
using namespace DFHack;
DFContextShared::DFContextShared()
{
// init modules
allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods));
namesInited = false;
namesFailed = false;
}
DFContextShared::~DFContextShared()
{
// invalidate all modules
for(unsigned int i = 0 ; i < allModules.size(); i++)
{
delete allModules[i];
}
allModules.clear();
}
bool DFContextShared::InitReadNames()
{
try
{
OffsetGroup * OG = offset_descriptor->getGroup("name");
name_firstname_offset = OG->getOffset("first");
name_nickname_offset = OG->getOffset("nick");
name_words_offset = OG->getOffset("second_words");
name_parts_offset = OG->getOffset("parts_of_speech");
name_language_offset = OG->getOffset("language");
name_set_offset = OG->getOffset("has_name");
}
catch(exception &)
{
namesFailed = true;
return false;
}
namesInited = true;
return true;
}
void DFContextShared::readName(t_name & name, uint32_t address)
{
if(namesFailed)
{
return;
}
if(!namesInited)
{
if(!InitReadNames()) return;
}
p->readSTLString(address + name_firstname_offset , name.first_name, 128);
p->readSTLString(address + name_nickname_offset , name.nickname, 128);
p->read(address + name_words_offset, 7*4, (uint8_t *)name.words);
p->read(address + name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech);
name.language = p->readDWord(address + name_language_offset);
name.has_name = p->readByte(address + name_set_offset);
}
void DFContextShared::copyName(uint32_t address, uint32_t target)
{
uint8_t buf[28];
if (address == target)
return;
p->copySTLString(address + name_firstname_offset, target + name_firstname_offset);
p->copySTLString(address + name_nickname_offset, target + name_nickname_offset);
p->read(address + name_words_offset, 7*4, buf);
p->write(target + name_words_offset, 7*4, buf);
p->read(address + name_parts_offset, 7*2, buf);
p->write(target + name_parts_offset, 7*2, buf);
p->writeDWord(target + name_language_offset, p->readDWord(address + name_language_offset));
p->writeByte(target + name_set_offset, p->readByte(address + name_set_offset));
}

@ -35,9 +35,9 @@ using namespace std;
#include "dfhack/Core.h" #include "dfhack/Core.h"
#include "dfhack/VersionInfoFactory.h" #include "dfhack/VersionInfoFactory.h"
#include "ModuleFactory.h"
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Context.h"
#include "dfhack/modules/Gui.h" #include "dfhack/modules/Gui.h"
#include "dfhack/modules/Vegetation.h" #include "dfhack/modules/Vegetation.h"
#include "dfhack/modules/Maps.h" #include "dfhack/modules/Maps.h"
@ -52,13 +52,13 @@ int kittenz (void)
{ {
" ____", " ____",
" (. \\", " (. \\",
" \\ | ", " \\ | ",
" \\ |___(\\--/)", " \\ |___(\\--/)",
" __/ ( . . )", " __/ ( . . )",
" \"'._. '-.O.'", " \"'._. '-.O.'",
" '-. \\ \"|\\", " '-. \\ \"|\\",
" '.,,/'.,,mrf", " '.,,/'.,,mrf",
0 0
}; };
rlutil::hidecursor(); rlutil::hidecursor();
rlutil::cls(); rlutil::cls();
@ -95,10 +95,9 @@ struct hideblock
int reveal (void) int reveal (void)
{ {
Core & c = DFHack::Core::getInstance(); Core & c = DFHack::Core::getInstance();
Context * DF = c.getContext();
c.Suspend(); c.Suspend();
DFHack::Maps *Maps =DF->getMaps(); DFHack::Maps *Maps =c.getMaps();
DFHack::World *World =DF->getWorld(); DFHack::World *World =c.getWorld();
// init the map // init the map
if(!Maps->Start()) if(!Maps->Start())
@ -152,7 +151,7 @@ int reveal (void)
cout << "Unrevealing... please wait." << endl; cout << "Unrevealing... please wait." << endl;
// FIXME: do some consistency checks here! // FIXME: do some consistency checks here!
c.Suspend(); c.Suspend();
Maps = DF->getMaps(); Maps = c.getMaps();
Maps->Start(); Maps->Start();
for(size_t i = 0; i < hidesaved.size();i++) for(size_t i = 0; i < hidesaved.size();i++)
{ {
@ -208,15 +207,24 @@ int fIOthread(void * _core)
Core::Core() Core::Core()
{ {
// find out what we are...
vif = new DFHack::VersionInfoFactory("Memory.xml"); vif = new DFHack::VersionInfoFactory("Memory.xml");
p = new DFHack::Process(vif); p = new DFHack::Process(vif);
if (!p->isIdentified()) if (!p->isIdentified())
{ {
std::cerr << "Couldn't identify this version of DF." << std::endl; std::cerr << "Couldn't identify this version of DF." << std::endl;
errorstate = true; errorstate = true;
delete p;
p = NULL;
return; return;
} }
c = new DFHack::Context(p); vinfo = p->getDescriptor();
// init module storage
allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods));
// create mutex for syncing with interactive tasks
AccessMutex = SDL_CreateMutex(); AccessMutex = SDL_CreateMutex();
if(!AccessMutex) if(!AccessMutex)
{ {
@ -224,6 +232,7 @@ Core::Core()
errorstate = true; errorstate = true;
return; return;
} }
// all OK
errorstate = false; errorstate = false;
// lock mutex // lock mutex
SDL_mutexP(AccessMutex); SDL_mutexP(AccessMutex);
@ -239,6 +248,10 @@ void Core::Suspend()
void Core::Resume() void Core::Resume()
{ {
for(unsigned int i = 0 ; i < allModules.size(); i++)
{
allModules[i]->OnResume();
}
SDL_mutexV(AccessMutex); SDL_mutexV(AccessMutex);
} }
@ -256,8 +269,42 @@ int Core::Update()
int Core::Shutdown ( void ) int Core::Shutdown ( void )
{ {
if(errorstate) errorstate = 1;
return -1; // invalidate all modules
return 0; for(unsigned int i = 0 ; i < allModules.size(); i++)
// do something here, eventually. {
delete allModules[i];
}
allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods));
// maybe do more
return -1;
}
/*******************************************************************************
M O D U L E S
*******************************************************************************/
#define MODULE_GETTER(TYPE) \
TYPE * Core::get##TYPE() \
{ \
if(!s_mods.p##TYPE)\
{\
Module * mod = create##TYPE();\
s_mods.p##TYPE = (TYPE *) mod;\
allModules.push_back(mod);\
}\
return s_mods.p##TYPE;\
} }
MODULE_GETTER(Creatures);
MODULE_GETTER(Engravings);
MODULE_GETTER(Maps);
MODULE_GETTER(Gui);
MODULE_GETTER(World);
MODULE_GETTER(Materials);
MODULE_GETTER(Items);
MODULE_GETTER(Translation);
MODULE_GETTER(Vegetation);
MODULE_GETTER(Buildings);
MODULE_GETTER(Constructions);

@ -48,7 +48,6 @@ distribution.
// DFHack core classes and types // DFHack core classes and types
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "dfhack/Context.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"

@ -1,169 +0,0 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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.
*/
#pragma once
#ifndef CONTEXT_H_INCLUDED
#define CONTEXT_H_INCLUDED
#include "dfhack/Export.h"
namespace DFHack
{
class Creatures;
class Engravings;
class Maps;
class Gui;
class World;
class Materials;
class Items;
class Translation;
class Vegetation;
class Buildings;
class Constructions;
class VersionInfo;
class DFContextShared;
class Process;
/**
* This class wraps all the different related objects for a particular Process
* \ingroup grp_context
*/
class DFHACK_EXPORT Context
{
public:
Context(Process * p);
~Context();
/// @return true if there's version information for the associated Process
bool isValid();
/// attach to the related process. Claims OS debugging resources
bool Attach();
/// detach from the related process. Releases OS debugging resources
bool Detach();
/// @return true if the process is attached.
bool isAttached();
/// stop the tracked process
bool Suspend();
/// @return true if the process is stopped
bool isSuspended();
/// stop the tracked process, asynchronous
bool AsyncSuspend();
/// resume the tracked process
bool Resume();
/// forces resume on Windows. This can be a bad thing with multiple tools running!
bool ForceResume();
VersionInfo *getMemoryInfo();
Process* getProcess();
void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target);
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
/// get the creatures module
Creatures * getCreatures();
/// get the engravings module
Engravings * getEngravings();
/// get the maps module
Maps * getMaps();
/// get the gui module
Gui * getGui();
/// get the world module
World * getWorld();
/// get the materials module
Materials * getMaterials();
/// get the items module
Items * getItems();
/// get the translation module
Translation * getTranslation();
/// get the vegetation module
Vegetation * getVegetation();
/// get the buildings module
Buildings * getBuildings();
/// get the constructions module
Constructions * getConstructions();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/*
* Effects like mist, dragonfire or dust
*/
/*
bool InitReadEffects ( uint32_t & numeffects );
bool ReadEffect(const uint32_t index, t_effect_df40d & effect);
bool WriteEffect(const uint32_t index, const t_effect_df40d & effect);
void FinishReadEffects();
*/
/*
* Notes placed by the player
*/
/*
/// start reading notes. numnotes is an output - total notes present
bool InitReadNotes( uint32_t & numnotes );
/// read note from the note vector at index
bool ReadNote(const int32_t index, t_note & note);
/// free the note vector
void FinishReadNotes();
*/
/*
* Settlements
*/
/*
bool InitReadSettlements( uint32_t & numsettlements );
bool ReadSettlement(const int32_t index, t_settlement & settlement);
bool ReadCurrentSettlement(t_settlement & settlement);
void FinishReadSettlements();
*/
/*
* Item reading
*/
/*
bool InitReadItems(uint32_t & numitems);
bool getItemIndexesInBox(std::vector<uint32_t> &indexes,
const uint16_t x1, const uint16_t y1, const uint16_t z1,
const uint16_t x2, const uint16_t y2, const uint16_t z2);
bool ReadItem(const uint32_t index, t_item & item);
void FinishReadItems();
*/
/*
* Get the other API parts for raw access
*/
private:
DFContextShared * d;
};
}
#endif //CONTEXT_H_INCLUDED

@ -29,9 +29,23 @@ distribution.
#include "dfhack/FakeSDL.h" #include "dfhack/FakeSDL.h"
namespace DFHack namespace DFHack
{ {
class VersionInfoFactory;
class Process; class Process;
class Module;
class Context; class Context;
class Creatures;
class Engravings;
class Maps;
class Gui;
class World;
class Materials;
class Items;
class Translation;
class Vegetation;
class Buildings;
class Constructions;
class VersionInfo;
class VersionInfoFactory;
// Core is a singleton. Why? Because it is closely tied to SDL calls. It tracks the global state of DF. // 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 // There should never be more than one instance
// Better than tracking some weird variables all over the place. // Better than tracking some weird variables all over the place.
@ -40,18 +54,45 @@ namespace DFHack
friend int ::SDL_NumJoysticks(void); friend int ::SDL_NumJoysticks(void);
friend void ::SDL_Quit(void); friend void ::SDL_Quit(void);
public: public:
/// Get the single Core instance or make one.
static Core& getInstance() static Core& getInstance()
{ {
// FIXME: add critical section for thread safety here. // FIXME: add critical section for thread safety here.
static Core instance; static Core instance;
return instance; return instance;
} }
/// try to acquire the activity lock
void Suspend(void); void Suspend(void);
/// return activity lock
void Resume(void); void Resume(void);
DFHack::Context *getContext() /// Is everything OK?
{ bool isValid(void) { return !errorstate; }
return c;
} /// get the creatures module
Creatures * getCreatures();
/// get the engravings module
Engravings * getEngravings();
/// get the maps module
Maps * getMaps();
/// get the gui module
Gui * getGui();
/// get the world module
World * getWorld();
/// get the materials module
Materials * getMaterials();
/// get the items module
Items * getItems();
/// get the translation module
Translation * getTranslation();
/// get the vegetation module
Vegetation * getVegetation();
/// get the buildings module
Buildings * getBuildings();
/// get the constructions module
Constructions * getConstructions();
DFHack::Process * p;
DFHack::VersionInfo * vinfo;
private: private:
Core(); Core();
int Update (void); int Update (void);
@ -60,9 +101,23 @@ namespace DFHack
void operator=(Core const&); // Don't implement void operator=(Core const&); // Don't implement
bool errorstate; bool errorstate;
DFMutex * AccessMutex; DFMutex * AccessMutex;
// legacy mess. // FIXME: shouldn't be kept around like this
DFHack::VersionInfoFactory * vif; DFHack::VersionInfoFactory * vif;
DFHack::Process * p; // Module storage
DFHack::Context * c; struct
{
Creatures * pCreatures;
Engravings * pEngravings;
Maps * pMaps;
Gui * pGui;
World * pWorld;
Materials * pMaterials;
Items * pItems;
Translation * pTranslation;
Vegetation * pVegetation;
Buildings * pBuildings;
Constructions * pConstructions;
} s_mods;
std::vector <Module *> allModules;
}; };
} }

@ -0,0 +1,63 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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.
*/
#pragma once
/*
* Some much needed SDL fakery.
*/
#include "dfhack/Pragma.h"
#include "dfhack/Export.h"
#ifdef LINUX_BUILD
#define DFhackCExport extern "C" __attribute__ ((visibility("default")))
#else
#define DFhackCExport extern "C" __declspec(dllexport)
#endif
// function and variable pointer... we don't try to understand what SDL does here
typedef void * fPtr;
typedef void * vPtr;
struct DFMutex;
struct DFThread;
// mutex and thread functions. We can call these.
DFhackCExport DFMutex * SDL_CreateMutex(void);
DFhackCExport int SDL_mutexP(DFMutex *);
DFhackCExport int SDL_mutexV(DFMutex *);
DFhackCExport void SDL_DestroyMutex(DFMutex *);
DFhackCExport DFThread *SDL_CreateThread(int (*fn)(void *), void *data);
// these functions are here because they call into DFHack::Core and therefore need to
// be declared as friend functions/known
DFhackCExport int SDL_NumJoysticks(void);
DFhackCExport void SDL_Quit(void);
/*
// not yet.
DFhackCExport int SDL_Init(uint32_t flags);
DFhackCExport int SDL_PollEvent(vPtr event);
*/
// Other crud is in the OS-specific core files.

@ -42,7 +42,7 @@ namespace DFHack
class DFVector; class DFVector;
class VersionInfoFactory; class VersionInfoFactory;
class PlatformSpecific; class PlatformSpecific;
/** /**
* A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification) * A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification)
* \ingroup grp_context * \ingroup grp_context
@ -65,7 +65,7 @@ namespace DFHack
uint64_t time; uint64_t time;
uint64_t pid; uint64_t pid;
}; };
/** /**
* Structure describing a section of virtual memory inside a process * Structure describing a section of virtual memory inside a process
* \ingroup grp_context * \ingroup grp_context
@ -92,12 +92,6 @@ namespace DFHack
bool valid; bool valid;
uint8_t * buffer; uint8_t * buffer;
}; };
struct t_vecTriplet
{
uint32_t start;
uint32_t end;
uint32_t alloc_end;
};
/** /**
* Allows low-level access to the memory of an OS process. OS processes can be enumerated by \ref ProcessEnumerator * Allows low-level access to the memory of an OS process. OS processes can be enumerated by \ref ProcessEnumerator

@ -108,15 +108,6 @@ struct t_effect_df40d //size 40
*/ */
//#pragma pack(push,4) //#pragma pack(push,4)
struct t_name
{
char first_name[128];
char nickname[128];
int32_t words[7];
uint16_t parts_of_speech[7];
uint32_t language;
bool has_name;
};
struct t_note struct t_note
{ {
@ -129,18 +120,14 @@ struct t_note
uint16_t z; uint16_t z;
}; };
struct t_name
// local are numbered with top left as 0,0, name is indexes into the item vector
struct t_settlement
{ {
uint32_t origin; char first_name[128];
t_name name; char nickname[128];
int16_t world_x; int32_t words[7];
int16_t world_y; uint16_t parts_of_speech[7];
int16_t local_x1; uint32_t language;
int16_t local_x2; bool has_name;
int16_t local_y1;
int16_t local_y2;
}; };
struct t_attrib struct t_attrib

@ -55,7 +55,6 @@ namespace DFHack
}; };
#ifdef __cplusplus #ifdef __cplusplus
class DFContextShared;
/** /**
* The Buildings module - allows reading DF buildings * The Buildings module - allows reading DF buildings
* \ingroup grp_modules * \ingroup grp_modules
@ -64,7 +63,7 @@ namespace DFHack
class DFHACK_EXPORT Buildings : public Module class DFHACK_EXPORT Buildings : public Module
{ {
public: public:
Buildings(DFContextShared * d); Buildings();
~Buildings(); ~Buildings();
bool Start(uint32_t & numBuildings); bool Start(uint32_t & numBuildings);
// read one building at offset // read one building at offset

@ -86,7 +86,7 @@ namespace DFHack
class DFHACK_EXPORT Constructions : public Module class DFHACK_EXPORT Constructions : public Module
{ {
public: public:
Constructions(DFContextShared * d); Constructions();
~Constructions(); ~Constructions();
bool Start(uint32_t & numConstructions); bool Start(uint32_t & numConstructions);
bool Read (const uint32_t index, t_construction & constr); bool Read (const uint32_t index, t_construction & constr);

@ -329,7 +329,7 @@ namespace DFHack
class DFHACK_EXPORT Creatures : public Module class DFHACK_EXPORT Creatures : public Module
{ {
public: public:
Creatures(DFHack::DFContextShared * d); Creatures();
~Creatures(); ~Creatures();
bool Start( uint32_t & numCreatures ); bool Start( uint32_t & numCreatures );
bool Finish(); bool Finish();

@ -99,7 +99,6 @@ namespace DFHack
t_engraving s; t_engraving s;
uint32_t origin; uint32_t origin;
}; };
class DFContextShared;
/** /**
* The Engravings module - allows reading engravings :D * The Engravings module - allows reading engravings :D
* \ingroup grp_modules * \ingroup grp_modules
@ -108,7 +107,7 @@ namespace DFHack
class DFHACK_EXPORT Engravings : public Module class DFHACK_EXPORT Engravings : public Module
{ {
public: public:
Engravings(DFContextShared * d); Engravings();
~Engravings(); ~Engravings();
bool Start(uint32_t & numEngravings); bool Start(uint32_t & numEngravings);
bool Read (const uint32_t index, dfh_engraving & engr); bool Read (const uint32_t index, dfh_engraving & engr);

@ -79,7 +79,7 @@ namespace DFHack
{ {
public: public:
Gui(DFHack::DFContextShared * d); Gui();
~Gui(); ~Gui();
bool Start(); bool Start();
bool Finish(); bool Finish();

@ -143,7 +143,7 @@ struct t_improvement
class DFHACK_EXPORT Items : public Module class DFHACK_EXPORT Items : public Module
{ {
public: public:
Items(DFContextShared * _d); Items();
~Items(); ~Items();
bool Start(); bool Start();
bool Finish(); bool Finish();

@ -518,7 +518,6 @@ namespace DFHack
int32_t mystery; int32_t mystery;
} mapblock40d; } mapblock40d;
class DFContextShared;
/** /**
* The Maps module * The Maps module
* \ingroup grp_modules * \ingroup grp_modules
@ -528,7 +527,7 @@ namespace DFHack
{ {
public: public:
Maps(DFHack::DFContextShared * d); Maps();
~Maps(); ~Maps();
bool Start(); bool Start();
bool Finish(); bool Finish();

@ -173,7 +173,7 @@ namespace DFHack
class DFHACK_EXPORT Materials : public Module class DFHACK_EXPORT Materials : public Module
{ {
public: public:
Materials(DFHack::DFContextShared * _d); Materials();
~Materials(); ~Materials();
bool Finish(); bool Finish();

@ -32,8 +32,10 @@ distribution.
#include "dfhack/Export.h" #include "dfhack/Export.h"
#include "dfhack/Module.h" #include "dfhack/Module.h"
#include "dfhack/Types.h"
namespace DFHack namespace DFHack
{ {
class DFContextShared; class DFContextShared;
/** /**
* \ingroup grp_translation * \ingroup grp_translation
@ -55,13 +57,18 @@ namespace DFHack
class DFHACK_EXPORT Translation : public Module class DFHACK_EXPORT Translation : public Module
{ {
public: public:
Translation(DFContextShared * d); Translation();
~Translation(); ~Translation();
bool Start(); bool Start();
bool Finish(); bool Finish();
// Get pointer to the two dictionary structures // Get pointer to the two dictionary structures
Dicts * getDicts(); Dicts * getDicts();
// names, used by a few other modules.
bool InitReadNames();
bool readName(t_name & name, uint32_t address);
bool copyName(uint32_t address, uint32_t target);
// translate a name using the loaded dictionaries // translate a name using the loaded dictionaries
std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true); std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true);

@ -74,7 +74,6 @@ namespace DFHack
// some more temperature stuff after that // some more temperature stuff after that
}; };
#pragma pack(pop) #pragma pack(pop)
class DFContextShared;
/** /**
* The Vegetation module * The Vegetation module
* \ingroup grp_vegetation * \ingroup grp_vegetation
@ -83,7 +82,7 @@ namespace DFHack
class DFHACK_EXPORT Vegetation : public Module class DFHACK_EXPORT Vegetation : public Module
{ {
public: public:
Vegetation(DFContextShared * d); Vegetation();
~Vegetation(); ~Vegetation();
bool Finish(){return true;}; bool Finish(){return true;};
std::vector <df_plant *> *all_plants; std::vector <df_plant *> *all_plants;

@ -1,120 +0,0 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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.
*/
#pragma once
#ifndef KEYS_H_INCLUDED
#define KEYS_H_INCLUDED
/**
* \defgroup grp_windowio WindowIO: Send events to DF's window
* @ingroup grp_modules
*/
#include "dfhack/Pragma.h"
#include "dfhack/Export.h"
#include "dfhack/Module.h"
namespace DFHack
{
class Process;
/**
* enum of all possible special keys
* \ingroup grp_windowio
*/
enum t_special
{
ENTER,
SPACE,
BACK_SPACE,
TAB,
CAPS_LOCK,
LEFT_SHIFT,
RIGHT_SHIFT,
LEFT_CONTROL,
RIGHT_CONTROL,
ALT,
WAIT,
ESCAPE,
UP,
DOWN,
LEFT,
RIGHT,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
PAGE_UP,
PAGE_DOWN,
INSERT,
DFK_DELETE, // stupid windows fails here
HOME,
END,
KEYPAD_DIVIDE,
KEYPAD_MULTIPLY,
KEYPAD_SUBTRACT,
KEYPAD_ADD,
KEYPAD_ENTER,
KEYPAD_0,
KEYPAD_1,
KEYPAD_2,
KEYPAD_3,
KEYPAD_4,
KEYPAD_5,
KEYPAD_6,
KEYPAD_7,
KEYPAD_8,
KEYPAD_9,
KEYPAD_DECIMAL_POINT,
NUM_SPECIALS
};
class DFContextShared;
/**
* The WindowIO module
* \ingroup grp_windowio
* \ingroup grp_modules
*/
class DFHACK_EXPORT WindowIO : public Module
{
class Private;
private:
Private * d;
public:
bool Finish(){return true;};
WindowIO(DFHack::DFContextShared * d);
~WindowIO();
void TypeStr (const char *input, int delay = 0, bool useShift = false);
void TypeSpecial (t_special command, int count = 1, int delay = 0);
};
}
#endif // KEYS_H_INCLUDED

@ -90,7 +90,7 @@ namespace DFHack
{ {
public: public:
World(DFHack::DFContextShared * d); World();
~World(); ~World();
bool Start(); bool Start();
bool Finish(); bool Finish();

@ -30,8 +30,6 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
@ -39,6 +37,7 @@ using namespace std;
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "dfhack/modules/Buildings.h" #include "dfhack/modules/Buildings.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "dfhack/Core.h"
using namespace DFHack; using namespace DFHack;
//raw //raw
@ -66,26 +65,25 @@ struct Buildings::Private
uint32_t custom_workshop_name; uint32_t custom_workshop_name;
int32_t custom_workshop_id; int32_t custom_workshop_id;
DfVector <uint32_t> * p_bld; DfVector <uint32_t> * p_bld;
DFContextShared *d;
Process * owner; Process * owner;
bool Inited; bool Inited;
bool hasCustomWorkshops; bool hasCustomWorkshops;
bool Started; bool Started;
}; };
Module* DFHack::createBuildings(DFContextShared * d) Module* DFHack::createBuildings()
{ {
return new Buildings(d); return new Buildings();
} }
Buildings::Buildings(DFContextShared * d_) Buildings::Buildings()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_;
d->owner = d_->p;
d->p_bld = NULL; d->p_bld = NULL;
d->Inited = d->Started = d->hasCustomWorkshops = false; d->Inited = d->Started = d->hasCustomWorkshops = false;
VersionInfo * mem = d->d->offset_descriptor; VersionInfo * mem = c.vinfo;
d->owner = c.p;
OffsetGroup * OG_build = mem->getGroup("Buildings"); OffsetGroup * OG_build = mem->getGroup("Buildings");
d->Inited = true; d->Inited = true;
try try

@ -30,7 +30,6 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
@ -38,6 +37,7 @@ using namespace std;
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/modules/Constructions.h" #include "dfhack/modules/Constructions.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "dfhack/Core.h"
using namespace DFHack; using namespace DFHack;
@ -47,25 +47,24 @@ struct Constructions::Private
// translation // translation
DfVector <uint32_t> * p_cons; DfVector <uint32_t> * p_cons;
DFContextShared *d;
Process * owner; Process * owner;
bool Inited; bool Inited;
bool Started; bool Started;
}; };
Module* DFHack::createConstructions(DFContextShared * d) Module* DFHack::createConstructions()
{ {
return new Constructions(d); return new Constructions();
} }
Constructions::Constructions(DFContextShared * d_) Constructions::Constructions()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_; d->owner = c.p;
d->owner = d_->p;
d->p_cons = 0; d->p_cons = 0;
d->Inited = d->Started = false; d->Inited = d->Started = false;
VersionInfo * mem = d->d->offset_descriptor; VersionInfo * mem = c.vinfo;
d->construction_vector = mem->getGroup("Constructions")->getAddress ("vector"); d->construction_vector = mem->getGroup("Constructions")->getAddress ("vector");
d->Inited = true; d->Inited = true;
} }

@ -32,7 +32,6 @@ distribution.
#include <cstring> #include <cstring>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
@ -43,7 +42,9 @@ using namespace std;
// we connect to those // we connect to those
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
#include "dfhack/modules/Creatures.h" #include "dfhack/modules/Creatures.h"
#include "dfhack/modules/Translation.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
@ -113,26 +114,28 @@ struct Creatures::Private
bool IdMapReady; bool IdMapReady;
std::map<int32_t, int32_t> IdMap; std::map<int32_t, int32_t> IdMap;
DfVector <uint32_t> *p_cre; DfVector <uint32_t> *p_cre;
DFContextShared *d;
Process *owner; Process *owner;
Translation * trans;
}; };
Module* DFHack::createCreatures(DFContextShared * d) Module* DFHack::createCreatures()
{ {
return new Creatures(d); return new Creatures();
} }
Creatures::Creatures(DFContextShared* _d) Creatures::Creatures()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = _d; d->owner = c.p;
d->owner = _d->p; VersionInfo * minfo = c.vinfo;
d->Inited = false; d->Inited = false;
d->Started = false; d->Started = false;
d->IdMapReady = false; d->IdMapReady = false;
d->p_cre = NULL; d->p_cre = NULL;
d->d->InitReadNames(); // throws on error d->trans = c.getTranslation();
VersionInfo * minfo = d->d->offset_descriptor; d->trans->InitReadNames(); // throws on error
OffsetGroup *OG_Creatures = minfo->getGroup("Creatures"); OffsetGroup *OG_Creatures = minfo->getGroup("Creatures");
OffsetGroup *OG_creature = OG_Creatures->getGroup("creature"); OffsetGroup *OG_creature = OG_Creatures->getGroup("creature");
OffsetGroup *OG_creature_ex = OG_creature->getGroup("advanced"); OffsetGroup *OG_creature_ex = OG_creature->getGroup("advanced");
@ -274,7 +277,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
if(d->Ft_basic) if(d->Ft_basic)
{ {
// name // name
d->d->readName(furball.name,addr_cr + offs.name_offset); d->trans->readName(furball.name,addr_cr + offs.name_offset);
// basic stuff // basic stuff
p->readDWord (addr_cr + offs.id_offset, furball.id); p->readDWord (addr_cr + offs.id_offset, furball.id);
@ -303,7 +306,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
// mood stuff // mood stuff
furball.mood = (int16_t) p->readWord (addr_cr + offs.mood_offset); furball.mood = (int16_t) p->readWord (addr_cr + offs.mood_offset);
furball.mood_skill = p->readWord (addr_cr + offs.mood_skill_offset); furball.mood_skill = p->readWord (addr_cr + offs.mood_skill_offset);
d->d->readName(furball.artifact_name, addr_cr + offs.artifact_name_offset); d->trans->readName(furball.artifact_name, addr_cr + offs.artifact_name_offset);
// labors // labors
p->read (addr_cr + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors); p->read (addr_cr + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors);
@ -756,6 +759,6 @@ void Creatures::CopyNameTo(t_creature &creature, uint32_t address)
Private::t_offsets &offs = d->creatures; Private::t_offsets &offs = d->creatures;
if(d->Ft_basic) if(d->Ft_basic)
d->d->copyName(creature.origin + offs.name_offset, address); d->trans->copyName(creature.origin + offs.name_offset, address);
} }

@ -30,14 +30,13 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/modules/Engravings.h" #include "dfhack/modules/Engravings.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "dfhack/Core.h"
using namespace DFHack; using namespace DFHack;
@ -47,26 +46,24 @@ struct Engravings::Private
// translation // translation
DfVector <uint32_t> * p_engr; DfVector <uint32_t> * p_engr;
DFContextShared *d;
Process * owner; Process * owner;
bool Inited; bool Inited;
bool Started; bool Started;
}; };
Module* DFHack::createEngravings(DFContextShared * d) Module* DFHack::createEngravings()
{ {
return new Engravings(d); return new Engravings();
} }
Engravings::Engravings(DFContextShared * d_) Engravings::Engravings()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_; d->owner = c.p;
d->owner = d_->p;
d->p_engr = 0; d->p_engr = 0;
d->Inited = d->Started = false; d->Inited = d->Started = false;
VersionInfo * mem = d->d->offset_descriptor; d->engraving_vector = c.vinfo->getGroup("Engravings")->getAddress ("vector");
d->engraving_vector = mem->getGroup("Engravings")->getAddress ("vector");
d->Inited = true; d->Inited = true;
} }

@ -30,18 +30,18 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/Gui.h" #include "dfhack/modules/Gui.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "dfhack/Core.h"
using namespace DFHack; using namespace DFHack;
Module* DFHack::createGui(DFContextShared * d) Module* DFHack::createGui()
{ {
return new Gui(d); return new Gui();
} }
struct Gui::Private struct Gui::Private
@ -67,17 +67,15 @@ struct Gui::Private
bool StartedScreen; bool StartedScreen;
uint32_t screen_tiles_ptr_offset; uint32_t screen_tiles_ptr_offset;
DFContextShared *d;
Process * owner; Process * owner;
}; };
Gui::Gui(DFContextShared * _d) Gui::Gui()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = _d; d->owner = c.p;
d->owner = _d->p; VersionInfo * mem = c.vinfo;
VersionInfo * mem = d->d->offset_descriptor;
OffsetGroup * OG_Gui = mem->getGroup("GUI"); OffsetGroup * OG_Gui = mem->getGroup("GUI");
try try
{ {
@ -156,7 +154,8 @@ bool Gui::ReadViewScreen (t_viewscreen &screen)
screenAddr = p->readDWord (nextScreenPtr); screenAddr = p->readDWord (nextScreenPtr);
nextScreenPtr = p->readDWord (nextScreenPtr + 4); nextScreenPtr = p->readDWord (nextScreenPtr + 4);
} }
return d->d->offset_descriptor->resolveObjectToClassID (last, screen.type); Core & c = Core::getInstance();
return c.vinfo->resolveObjectToClassID (last, screen.type);
} }
bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z)

@ -32,7 +32,6 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
@ -41,12 +40,13 @@ using namespace std;
#include "dfhack/modules/Items.h" #include "dfhack/modules/Items.h"
#include "dfhack/modules/Creatures.h" #include "dfhack/modules/Creatures.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
Module* DFHack::createItems(DFContextShared * d) Module* DFHack::createItems()
{ {
return new Items(d); return new Items();
} }
enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT}; enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT};
@ -434,17 +434,17 @@ class Items::Private
ClassNameCheck isContainsRefClass; ClassNameCheck isContainsRefClass;
}; };
Items::Items(DFContextShared * d_) Items::Items()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_; d->owner = c.p;
d->owner = d_->p;
d->isOwnerRefClass = ClassNameCheck("general_ref_unit_itemownerst"); d->isOwnerRefClass = ClassNameCheck("general_ref_unit_itemownerst");
d->isContainerRefClass = ClassNameCheck("general_ref_contained_in_itemst"); d->isContainerRefClass = ClassNameCheck("general_ref_contained_in_itemst");
d->isContainsRefClass = ClassNameCheck("general_ref_contains_itemst"); d->isContainsRefClass = ClassNameCheck("general_ref_contains_itemst");
DFHack::OffsetGroup* itemGroup = d_->offset_descriptor->getGroup("Items"); DFHack::OffsetGroup* itemGroup = c.vinfo->getGroup("Items");
d->itemVectorAddress = itemGroup->getAddress("items_vector"); d->itemVectorAddress = itemGroup->getAddress("items_vector");
d->idFieldOffset = itemGroup->getOffset("id"); d->idFieldOffset = itemGroup->getOffset("id");
d->refVectorOffset = itemGroup->getOffset("item_ref_vector"); d->refVectorOffset = itemGroup->getOffset("item_ref_vector");

@ -32,21 +32,21 @@ distribution.
#include <cassert> #include <cassert>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/Maps.h" #include "dfhack/modules/Maps.h"
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized(); #define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack; using namespace DFHack;
Module* DFHack::createMaps(DFContextShared * d) Module* DFHack::createMaps()
{ {
return new Maps(d); return new Maps();
} }
const char * DFHack::sa_feature(e_feature index) const char * DFHack::sa_feature(e_feature index)
@ -133,7 +133,6 @@ struct Maps::Private
uint32_t tree_desc_offset; uint32_t tree_desc_offset;
} offsets; } offsets;
DFContextShared *d;
Process * owner; Process * owner;
OffsetGroup *OG_vector; OffsetGroup *OG_vector;
bool Inited; bool Inited;
@ -153,15 +152,15 @@ struct Maps::Private
vector<uint16_t> v_geology[eBiomeCount]; vector<uint16_t> v_geology[eBiomeCount];
}; };
Maps::Maps(DFContextShared* _d) Maps::Maps()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = _d; Process *p = d->owner = c.p;
Process *p = d->owner = _d->p;
d->Inited = d->FeaturesStarted = d->Started = false; d->Inited = d->FeaturesStarted = d->Started = false;
d->block = NULL; d->block = NULL;
DFHack::VersionInfo * mem = p->getDescriptor(); DFHack::VersionInfo * mem = c.vinfo;
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
d->hasFeatures = d->hasGeology = d->hasVeggies = true; d->hasFeatures = d->hasGeology = d->hasVeggies = true;
@ -233,7 +232,7 @@ Maps::Maps(DFContextShared* _d)
try try
{ {
OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation"); OffsetGroup * OG_Veg = c.vinfo->getGroup("Vegetation");
off.vegvector = OG_MapBlock->getOffset ("vegetation_vector"); off.vegvector = OG_MapBlock->getOffset ("vegetation_vector");
off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset"); off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset");
} }

@ -31,7 +31,6 @@ distribution.
#include <cstring> #include <cstring>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
@ -39,18 +38,18 @@ using namespace std;
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
#include <dfhack/Error.h> #include <dfhack/Error.h>
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
Module* DFHack::createMaterials(DFContextShared * d) Module* DFHack::createMaterials()
{ {
return new Materials(d); return new Materials();
} }
class Materials::Private class Materials::Private
{ {
public: public:
DFContextShared *d;
Process * owner; Process * owner;
OffsetGroup * OG_Materials; OffsetGroup * OG_Materials;
uint32_t vector_inorganic; uint32_t vector_inorganic;
@ -59,18 +58,14 @@ class Materials::Private
uint32_t vector_organic_trees; uint32_t vector_organic_trees;
uint32_t vector_races; uint32_t vector_races;
uint32_t vector_other; uint32_t vector_other;
/*
bool Inited;
bool Started;
*/
}; };
Materials::Materials(DFContextShared * d_) Materials::Materials()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_; d->owner = c.p;
d->owner = d_->p; OffsetGroup *OG_Materials = d->OG_Materials = c.vinfo->getGroup("Materials");
OffsetGroup *OG_Materials = d->OG_Materials = d->owner->getDescriptor()->getGroup("Materials");
{ {
d->vector_inorganic = OG_Materials->getAddress("inorganics"); d->vector_inorganic = OG_Materials->getAddress("inorganics");
d->vector_organic_all = OG_Materials->getAddress ("organics_all"); d->vector_organic_all = OG_Materials->getAddress ("organics_all");
@ -86,112 +81,9 @@ Materials::~Materials()
bool Materials::Finish() bool Materials::Finish()
{ {
/*
inorganic.clear();
organic.clear();
tree.clear();
plant.clear();
race.clear();
raceEx.clear();
color.clear();
other.clear();
alldesc.clear();
*/
return true; return true;
} }
/*
{
LABEL_53:
if ( a1
|| (signed int)a2 < 0
|| a2 >= (inorg_end - inorg_start) >> 2
|| (v13 = *(_DWORD *)(inorg_start + 4 * a2), !v13) )
{
switch ( a1 )
{
case 1:
sub_40FDD0("AMBER");
break;
case 2:
sub_40FDD0("CORAL");
break;
case 3:
sub_40FDD0("GLASS_GREEN");
break;
case 4:
sub_40FDD0("GLASS_CLEAR");
break;
case 5:
sub_40FDD0("GLASS_CRYSTAL");
break;
case 6:
sub_40FDD0("WATER");
break;
case 7:
sub_40FDD0("COAL");
break;
case 8:
sub_40FDD0("POTASH");
break;
case 9:
sub_40FDD0("ASH");
break;
case 10:
sub_40FDD0("PEARLASH");
break;
case 11:
sub_40FDD0("LYE");
break;
case 12:
sub_40FDD0("MUD");
break;
case 13:
sub_40FDD0("VOMIT");
break;
case 14:
sub_40FDD0("SALT");
break;
case 15:
sub_40FDD0("FILTH_B");
break;
case 16:
sub_40FDD0("FILTH_Y");
break;
case 17:
sub_40FDD0("UNKNOWN_SUBSTANCE");
break;
case 18:
sub_40FDD0("GRIME");
break;
default:
sub_40A070("NONE", 4u);
break;
}
result = sub_40A070("NONE", 4u);
if ( a1 == 7 )
{
result = a2;
if ( a2 )
{
if ( a2 == 1 )
result = sub_40A070("CHARCOAL", 8u);
}
else
{
result = sub_40A070("COKE", 4u);
}
}
}
else
{
sub_40A070("INORGANIC", 9u);
result = sub_409CA0(v13, 0, -1);
}
}
*/
/* /*
bool API::ReadInorganicMaterials (vector<t_matgloss> & inorganic) bool API::ReadInorganicMaterials (vector<t_matgloss> & inorganic)
{ {

@ -30,18 +30,18 @@ distribution.
#include <cassert> #include <cassert>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/Translation.h" #include "dfhack/modules/Translation.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
Module* DFHack::createTranslation(DFContextShared * d) Module* DFHack::createTranslation()
{ {
return new Translation(d); return new Translation();
} }
struct Translation::Private struct Translation::Private
@ -54,23 +54,33 @@ struct Translation::Private
// translation // translation
Dicts dicts; Dicts dicts;
DFContextShared *d;
bool Inited; bool Inited;
bool Started; bool Started;
// names
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
uint32_t name_parts_offset;
uint32_t name_language_offset;
uint32_t name_set_offset;
bool namesInited;
bool namesFailed;
}; };
Translation::Translation(DFContextShared * d_) Translation::Translation()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = d_;
d->Inited = d->Started = false; d->Inited = d->Started = false;
OffsetGroup * OG_Translation = d->d->offset_descriptor->getGroup("Translations"); OffsetGroup * OG_Translation = c.vinfo->getGroup("Translations");
OffsetGroup * OG_String = d->d->offset_descriptor->getGroup("string"); OffsetGroup * OG_String = c.vinfo->getGroup("string");
d->genericAddress = OG_Translation->getAddress ("language_vector"); d->genericAddress = OG_Translation->getAddress ("language_vector");
d->transAddress = OG_Translation->getAddress ("translation_vector"); d->transAddress = OG_Translation->getAddress ("translation_vector");
d->word_table_offset = OG_Translation->getOffset ("word_table"); d->word_table_offset = OG_Translation->getOffset ("word_table");
d->sizeof_string = OG_String->getHexValue ("sizeof"); d->sizeof_string = OG_String->getHexValue ("sizeof");
d->Inited = true; d->Inited = true;
d->namesInited = false;
d->namesFailed = false;
} }
Translation::~Translation() Translation::~Translation()
@ -82,9 +92,10 @@ Translation::~Translation()
bool Translation::Start() bool Translation::Start()
{ {
Core & c = Core::getInstance();
if(!d->Inited) if(!d->Inited)
return false; return false;
Process * p = d->d->p; Process * p = c.p;
Finish(); Finish();
DfVector <uint32_t> genericVec (d->genericAddress); DfVector <uint32_t> genericVec (d->genericAddress);
DfVector <uint32_t> transVec (d->transAddress); DfVector <uint32_t> transVec (d->transAddress);
@ -135,6 +146,69 @@ Dicts * Translation::getDicts()
return 0; return 0;
} }
bool Translation::InitReadNames()
{
Core & c = Core::getInstance();
try
{
OffsetGroup * OG = c.vinfo->getGroup("name");
d->name_firstname_offset = OG->getOffset("first");
d->name_nickname_offset = OG->getOffset("nick");
d->name_words_offset = OG->getOffset("second_words");
d->name_parts_offset = OG->getOffset("parts_of_speech");
d->name_language_offset = OG->getOffset("language");
d->name_set_offset = OG->getOffset("has_name");
}
catch(exception &)
{
d->namesFailed = true;
return false;
}
d->namesInited = true;
return true;
}
bool Translation::readName(t_name & name, uint32_t address)
{
Core & c = Core::getInstance();
Process * p = c.p;
if(d->namesFailed)
{
return false;
}
if(!d->namesInited)
{
if(!InitReadNames()) return false;
}
p->readSTLString(address + d->name_firstname_offset , name.first_name, 128);
p->readSTLString(address + d->name_nickname_offset , name.nickname, 128);
p->read(address + d->name_words_offset, 7*4, (uint8_t *)name.words);
p->read(address + d->name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech);
name.language = p->readDWord(address + d->name_language_offset);
name.has_name = p->readByte(address + d->name_set_offset);
return true;
}
bool Translation::copyName(uint32_t address, uint32_t target)
{
uint8_t buf[28];
if (address == target)
return true;
Core & c = Core::getInstance();
Process * p = c.p;
p->copySTLString(address + d->name_firstname_offset, target + d->name_firstname_offset);
p->copySTLString(address + d->name_nickname_offset, target + d->name_nickname_offset);
p->read(address + d->name_words_offset, 7*4, buf);
p->write(target + d->name_words_offset, 7*4, buf);
p->read(address + d->name_parts_offset, 7*2, buf);
p->write(target + d->name_parts_offset, 7*2, buf);
p->writeDWord(target + d->name_language_offset, p->readDWord(address + d->name_language_offset));
p->writeByte(target + d->name_set_offset, p->readByte(address + d->name_set_offset));
return true;
}
string Translation::TranslateName(const t_name &name, bool inEnglish) string Translation::TranslateName(const t_name &name, bool inEnglish)
{ {
string out; string out;

@ -30,8 +30,6 @@ distribution.
#include <map> #include <map>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/Vector.h" #include "dfhack/Vector.h"
@ -39,18 +37,20 @@ using namespace std;
#include "dfhack/modules/Vegetation.h" #include "dfhack/modules/Vegetation.h"
#include "dfhack/modules/Translation.h" #include "dfhack/modules/Translation.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
Module* DFHack::createVegetation(DFContextShared * d) Module* DFHack::createVegetation()
{ {
return new Vegetation(d); return new Vegetation();
} }
Vegetation::Vegetation(DFContextShared * d_) Vegetation::Vegetation()
{ {
Core & c = Core::getInstance();
try try
{ {
OffsetGroup * OG_Veg = d_->offset_descriptor->getGroup("Vegetation"); OffsetGroup * OG_Veg = c.vinfo->getGroup("Vegetation");
all_plants = (vector<df_plant *> *) OG_Veg->getAddress ("vector"); all_plants = (vector<df_plant *> *) OG_Veg->getAddress ("vector");
} }
catch(exception &) catch(exception &)

@ -30,19 +30,19 @@ distribution.
#include <cstring> #include <cstring>
using namespace std; using namespace std;
#include "ContextShared.h"
#include "dfhack/modules/World.h" #include "dfhack/modules/World.h"
#include "dfhack/Process.h" #include "dfhack/Process.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/Types.h" #include "dfhack/Types.h"
#include "dfhack/Error.h" #include "dfhack/Error.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include <dfhack/Core.h>
using namespace DFHack; using namespace DFHack;
Module* DFHack::createWorld(DFContextShared * d) Module* DFHack::createWorld()
{ {
return new World(d); return new World();
} }
struct World::Private struct World::Private
@ -67,18 +67,16 @@ struct World::Private
uint32_t gamemode_offset; uint32_t gamemode_offset;
uint32_t controlmode_offset; uint32_t controlmode_offset;
uint32_t controlmodecopy_offset; uint32_t controlmodecopy_offset;
DFContextShared *d;
Process * owner; Process * owner;
}; };
World::World(DFContextShared * _d) World::World()
{ {
Core & c = Core::getInstance();
d = new Private; d = new Private;
d->d = _d; d->owner = c.p;
d->owner = _d->p;
OffsetGroup * OG_World = d->d->offset_descriptor->getGroup("World"); OffsetGroup * OG_World = c.vinfo->getGroup("World");
try try
{ {
d->year_offset = OG_World->getAddress( "current_year" ); d->year_offset = OG_World->getAddress( "current_year" );
@ -86,7 +84,7 @@ World::World(DFContextShared * _d)
d->StartedTime = true; d->StartedTime = true;
} }
catch(Error::All &){}; catch(Error::All &){};
OffsetGroup * OG_Gui = d->d->offset_descriptor->getGroup("GUI"); // FIXME: legacy OffsetGroup * OG_Gui = c.vinfo->getGroup("GUI");
try try
{ {
d->pause_state_offset = OG_Gui->getAddress ("pause_state"); d->pause_state_offset = OG_Gui->getAddress ("pause_state");
@ -127,7 +125,6 @@ bool World::Finish()
bool World::ReadPauseState() bool World::ReadPauseState()
{ {
if(!d->PauseInited) return false; if(!d->PauseInited) return false;
uint32_t pauseState = d->owner->readDWord (d->pause_state_offset); uint32_t pauseState = d->owner->readDWord (d->pause_state_offset);
return pauseState & 1; return pauseState & 1;
} }

@ -1,118 +0,0 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
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.
*/
#pragma once
#ifndef APIPRIVATE_H_INCLUDED
#define APIPRIVATE_H_INCLUDED
namespace DFHack
{
class Module;
class Creatures;
class Engravings;
class Maps;
class Gui;
class World;
class Materials;
class Items;
class Translation;
class Vegetation;
class Buildings;
class Constructions;
class WindowIO;
class ProcessEnumerator;
class Process;
class VersionInfo;
struct t_name;
class DFContextShared
{
public:
DFContextShared();
~DFContextShared();
// names, used by a few other modules.
void readName(t_name & name, uint32_t address);
void copyName(uint32_t address, uint32_t target);
// get the name offsets
bool InitReadNames();
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
uint32_t name_parts_offset;
uint32_t name_language_offset;
uint32_t name_set_offset;
bool namesInited;
bool namesFailed;
ProcessEnumerator* pm;
Process* p;
char * shm_start;
VersionInfo* offset_descriptor;
string xml;
// Modules
struct
{
Creatures * pCreatures;
Engravings * pEngravings;
Maps * pMaps;
Gui * pPosition; // blerp
Gui * pGui;
World * pWorld;
Materials * pMaterials;
Items * pItems;
Translation * pTranslation;
Vegetation * pVegetation;
Buildings * pBuildings;
Constructions * pConstructions;
WindowIO * pWindowIO;
} s_mods;
std::vector <Module *> allModules;
/*
uint32_t item_material_offset;
uint32_t note_foreground_offset;
uint32_t note_background_offset;
uint32_t note_name_offset;
uint32_t note_xyz_offset;
uint32_t settlement_name_offset;
uint32_t settlement_world_xy_offset;
uint32_t settlement_local_xy_offset;
uint32_t dwarf_lang_table_offset;
DfVector *p_effect;
DfVector *p_itm;
DfVector *p_notes;
DfVector *p_settlements;
DfVector *p_current_settlement;
*/
};
}
#endif

@ -30,17 +30,16 @@ distribution.
namespace DFHack namespace DFHack
{ {
class Module; class Module;
class DFContextShared; Module* createCreatures();
Module* createCreatures(DFContextShared * d); Module* createEngravings();
Module* createEngravings(DFContextShared * d); Module* createGui();
Module* createGui(DFContextShared * d); Module* createWorld();
Module* createWorld(DFContextShared * d); Module* createMaterials();
Module* createMaterials(DFContextShared * d); Module* createItems();
Module* createItems(DFContextShared * d); Module* createTranslation();
Module* createTranslation(DFContextShared * d); Module* createVegetation();
Module* createVegetation(DFContextShared * d); Module* createBuildings();
Module* createBuildings(DFContextShared * d); Module* createConstructions();
Module* createConstructions(DFContextShared * d); Module* createMaps();
Module* createMaps(DFContextShared * d);
} }
#endif #endif

@ -29,69 +29,72 @@
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
/// Common C++ headers /// Common C++ headers
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <sstream> #include <sstream>
/// Namespace forward declarations /// Namespace forward declarations
namespace rlutil { namespace rlutil
void locate(int x, int y); {
} void locate(int x, int y);
}
#endif // __cplusplus #endif // __cplusplus
#ifdef WIN32 #ifdef WIN32
#include <windows.h> // for WinAPI and Sleep() #include <windows.h> // for WinAPI and Sleep()
#include <conio.h> // for getch() and kbhit() #include <conio.h> // for getch() and kbhit()
#else #else
#ifdef __cplusplus #ifdef __cplusplus
#include <cstdio> // for getch() #include <cstdio> // for getch()
#else // __cplusplus #else // __cplusplus
#include <stdio.h> // for getch() #include <stdio.h> // for getch()
#endif // __cplusplus #endif // __cplusplus
#include <termios.h> // for getch() and kbhit() #include <termios.h> // for getch() and kbhit()
#include <unistd.h> // for getch(), kbhit() and (u)sleep() #include <unistd.h> // for getch(), kbhit() and (u)sleep()
#include <sys/ioctl.h> // for getkey() #include <sys/ioctl.h> // for getkey()
#include <sys/types.h> // for kbhit() #include <sys/types.h> // for kbhit()
#include <sys/time.h> // for kbhit() #include <sys/time.h> // for kbhit()
/// Function: getch /// Function: getch
/// Get character without waiting for Return to be pressed. /// Get character without waiting for Return to be pressed.
/// Windows has this in conio.h /// Windows has this in conio.h
int getch() { int getch()
// Here be magic. {
struct termios oldt, newt; // Here be magic.
int ch; struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt); int ch;
newt = oldt; tcgetattr(STDIN_FILENO, &oldt);
newt.c_lflag &= ~(ICANON | ECHO); newt = oldt;
tcsetattr(STDIN_FILENO, TCSANOW, &newt); newt.c_lflag &= ~(ICANON | ECHO);
ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &newt);
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); ch = getchar();
return ch; tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return ch;
} }
/// Function: kbhit /// Function: kbhit
/// Determines if keyboard has been hit. /// Determines if keyboard has been hit.
/// Windows has this in conio.h /// Windows has this in conio.h
int kbhit() { int kbhit()
// Here be dragons. {
static struct termios oldt, newt; // Here be dragons.
int cnt = 0; static struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt); int cnt = 0;
newt = oldt; tcgetattr(STDIN_FILENO, &oldt);
newt.c_lflag &= ~(ICANON | ECHO); newt = oldt;
newt.c_iflag = 0; // input mode newt.c_lflag &= ~(ICANON | ECHO);
newt.c_oflag = 0; // output mode newt.c_iflag = 0; // input mode
newt.c_cc[VMIN] = 1; // minimum time to wait newt.c_oflag = 0; // output mode
newt.c_cc[VTIME] = 1; // minimum characters to wait for newt.c_cc[VMIN] = 1; // minimum time to wait
tcsetattr(STDIN_FILENO, TCSANOW, &newt); newt.c_cc[VTIME] = 1; // minimum characters to wait for
ioctl(0, FIONREAD, &cnt); // Read count tcsetattr(STDIN_FILENO, TCSANOW, &newt);
struct timeval tv; ioctl(0, FIONREAD, &cnt); // Read count
tv.tv_sec = 0; struct timeval tv;
tv.tv_usec = 100; tv.tv_sec = 0;
select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay tv.tv_usec = 100;
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay
return cnt; // Return number of characters tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return cnt; // Return number of characters
} }
#endif // WIN32 #endif // WIN32
@ -99,10 +102,10 @@ int kbhit() {
/// Function: gotoxy /// Function: gotoxy
/// Same as <rlutil.locate>. /// Same as <rlutil.locate>.
void inline gotoxy(int x, int y) { void inline gotoxy(int x, int y) {
#ifdef __cplusplus #ifdef __cplusplus
rlutil:: rlutil::
#endif #endif
locate(x,y); locate(x,y);
} }
#endif // gotoxy #endif // gotoxy
@ -121,18 +124,18 @@ namespace rlutil {
*/ */
#ifdef __cplusplus #ifdef __cplusplus
#ifndef RLUTIL_STRING_T #ifndef RLUTIL_STRING_T
typedef std::string RLUTIL_STRING_T; typedef std::string RLUTIL_STRING_T;
#endif // RLUTIL_STRING_T #endif // RLUTIL_STRING_T
void inline RLUTIL_PRINT(RLUTIL_STRING_T st) { std::cout << st; } void inline RLUTIL_PRINT(RLUTIL_STRING_T st) { std::cout << st; }
#else // __cplusplus #else // __cplusplus
#ifndef RLUTIL_STRING_T #ifndef RLUTIL_STRING_T
typedef char* RLUTIL_STRING_T; typedef char* RLUTIL_STRING_T;
#endif // RLUTIL_STRING_T #endif // RLUTIL_STRING_T
#define RLUTIL_PRINT(st) printf("%s", st) #define RLUTIL_PRINT(st) printf("%s", st)
#endif // __cplusplus #endif // __cplusplus
/** /**
@ -156,22 +159,22 @@ namespace rlutil {
* WHITE - White (bright) * WHITE - White (bright)
*/ */
enum { enum {
BLACK, BLACK,
RED, RED,
GREEN, GREEN,
BROWN, BROWN,
BLUE, BLUE,
MAGENTA, MAGENTA,
CYAN, CYAN,
GREY, GREY,
DARKGREY, DARKGREY,
LIGHTRED, LIGHTRED,
LIGHTGREEN, LIGHTGREEN,
YELLOW, YELLOW,
LIGHTBLUE, LIGHTBLUE,
LIGHTMAGENTA, LIGHTMAGENTA,
LIGHTCYAN, LIGHTCYAN,
WHITE WHITE
}; };
/** /**
@ -301,68 +304,79 @@ const int KEY_NUMPAD9 = 135;
/// ///
/// Note: /// Note:
/// Only Arrows, Esc, Enter and Space are currently working properly. /// Only Arrows, Esc, Enter and Space are currently working properly.
int getkey(void) { int getkey(void)
#ifndef WIN32 {
int cnt = kbhit(); // for ANSI escapes processing #ifndef WIN32
#endif int cnt = kbhit(); // for ANSI escapes processing
int k = getch(); #endif
switch(k) { int k = getch();
case 0: { switch(k)
int kk; {
switch (kk = getch()) { case 0:
case 71: return KEY_NUMPAD7; {
case 72: return KEY_NUMPAD8; int kk;
case 73: return KEY_NUMPAD9; switch (kk = getch())
case 75: return KEY_NUMPAD4; {
case 77: return KEY_NUMPAD6; case 71: return KEY_NUMPAD7;
case 79: return KEY_NUMPAD1; case 72: return KEY_NUMPAD8;
case 80: return KEY_NUMPAD4; case 73: return KEY_NUMPAD9;
case 81: return KEY_NUMPAD3; case 75: return KEY_NUMPAD4;
case 82: return KEY_NUMPAD0; case 77: return KEY_NUMPAD6;
case 83: return KEY_NUMDEL; case 79: return KEY_NUMPAD1;
default: return kk-59+KEY_F1; // Function keys case 80: return KEY_NUMPAD4;
}} case 81: return KEY_NUMPAD3;
case 224: { case 82: return KEY_NUMPAD0;
int kk; case 83: return KEY_NUMDEL;
switch (kk = getch()) { default: return kk-59+KEY_F1; // Function keys
case 71: return KEY_HOME; }
case 72: return KEY_UP; }
case 73: return KEY_PGUP; case 224:
case 75: return KEY_LEFT; {
case 77: return KEY_RIGHT; int kk;
case 79: return KEY_END; switch (kk = getch())
case 80: return KEY_DOWN; {
case 81: return KEY_PGDOWN; case 71: return KEY_HOME;
case 82: return KEY_INSERT; case 72: return KEY_UP;
case 83: return KEY_DELETE; case 73: return KEY_PGUP;
default: return kk-123+KEY_F1; // Function keys case 75: return KEY_LEFT;
}} case 77: return KEY_RIGHT;
case 13: return KEY_ENTER; case 79: return KEY_END;
case 80: return KEY_DOWN;
case 81: return KEY_PGDOWN;
case 82: return KEY_INSERT;
case 83: return KEY_DELETE;
default: return kk-123+KEY_F1; // Function keys
}
}
case 13: return KEY_ENTER;
#ifdef WIN32 #ifdef WIN32
case 27: return KEY_ESCAPE; case 27: return KEY_ESCAPE;
#else // WIN32 #else // WIN32
case 155: // single-character CSI case 155: // single-character CSI
case 27: { case 27:
// Process ANSI escape sequences {
if (cnt >= 3 && getch() == '[') { // Process ANSI escape sequences
switch (k = getch()) { if (cnt >= 3 && getch() == '[')
case 'A': return KEY_UP; {
case 'B': return KEY_DOWN; switch (k = getch())
case 'C': return KEY_RIGHT; {
case 'D': return KEY_LEFT; case 'A': return KEY_UP;
} case 'B': return KEY_DOWN;
} else return KEY_ESCAPE; case 'C': return KEY_RIGHT;
} case 'D': return KEY_LEFT;
}
} else return KEY_ESCAPE;
}
#endif // WIN32 #endif // WIN32
default: return k; default: return k;
} }
} }
/// Function: nb_getch /// Function: nb_getch
/// Non-blocking getch(). Returns 0 if no key was pressed. /// Non-blocking getch(). Returns 0 if no key was pressed.
int inline nb_getch() { int inline nb_getch() {
if (kbhit()) return getch(); if (kbhit()) return getch();
else return 0; else return 0;
} }
/// Function: getANSIColor /// Function: getANSIColor
@ -370,25 +384,25 @@ int inline nb_getch() {
/// ///
/// See <Color Codes> /// See <Color Codes>
RLUTIL_STRING_T getANSIColor(const int c) { RLUTIL_STRING_T getANSIColor(const int c) {
switch (c) { switch (c) {
case 0 : return ANSI_BLACK; case 0 : return ANSI_BLACK;
case 1 : return ANSI_BLUE; // non-ANSI case 1 : return ANSI_BLUE; // non-ANSI
case 2 : return ANSI_GREEN; case 2 : return ANSI_GREEN;
case 3 : return ANSI_CYAN; // non-ANSI case 3 : return ANSI_CYAN; // non-ANSI
case 4 : return ANSI_RED; // non-ANSI case 4 : return ANSI_RED; // non-ANSI
case 5 : return ANSI_MAGENTA; case 5 : return ANSI_MAGENTA;
case 6 : return ANSI_BROWN; case 6 : return ANSI_BROWN;
case 7 : return ANSI_GREY; case 7 : return ANSI_GREY;
case 8 : return ANSI_DARKGREY; case 8 : return ANSI_DARKGREY;
case 9 : return ANSI_LIGHTBLUE; // non-ANSI case 9 : return ANSI_LIGHTBLUE; // non-ANSI
case 10: return ANSI_LIGHTGREEN; case 10: return ANSI_LIGHTGREEN;
case 11: return ANSI_LIGHTCYAN; // non-ANSI; case 11: return ANSI_LIGHTCYAN; // non-ANSI;
case 12: return ANSI_LIGHTRED; // non-ANSI; case 12: return ANSI_LIGHTRED; // non-ANSI;
case 13: return ANSI_LIGHTMAGENTA; case 13: return ANSI_LIGHTMAGENTA;
case 14: return ANSI_YELLOW; // non-ANSI case 14: return ANSI_YELLOW; // non-ANSI
case 15: return ANSI_WHITE; case 15: return ANSI_WHITE;
default: return ""; default: return "";
} }
} }
/// Function: setColor /// Function: setColor
@ -397,10 +411,10 @@ RLUTIL_STRING_T getANSIColor(const int c) {
/// See <Color Codes> /// See <Color Codes>
void inline setColor(int c) { void inline setColor(int c) {
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI) #if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, c); SetConsoleTextAttribute(hConsole, c);
#else #else
RLUTIL_PRINT(getANSIColor(c)); RLUTIL_PRINT(getANSIColor(c));
#endif #endif
} }
@ -408,44 +422,46 @@ void inline setColor(int c) {
/// Clears screen and moves cursor home. /// Clears screen and moves cursor home.
void inline cls() { void inline cls() {
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI) #if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
// TODO: This is cheating... // TODO: This is cheating...
system("cls"); system("cls");
#else #else
RLUTIL_PRINT("\033[2J\033[H"); RLUTIL_PRINT("\033[2J\033[H");
#endif #endif
} }
/// Function: locate /// Function: locate
/// Sets the cursor position to 1-based x,y. /// Sets the cursor position to 1-based x,y.
void locate(int x, int y) { void locate(int x, int y)
{
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI) #if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
COORD coord = {x-1, y-1}; // Windows uses 0-based coordinates COORD coord = {x-1, y-1}; // Windows uses 0-based coordinates
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
#else // WIN32 || USE_ANSI #else // WIN32 || USE_ANSI
#ifdef __cplusplus #ifdef __cplusplus
std::ostringstream oss; std::ostringstream oss;
oss << "\033[" << y << ";" << x << "H"; oss << "\033[" << y << ";" << x << "H";
RLUTIL_PRINT(oss.str()); RLUTIL_PRINT(oss.str());
#else // __cplusplus #else // __cplusplus
char buf[32]; char buf[32];
sprintf(buf, "\033[%d;%df", y, x); sprintf(buf, "\033[%d;%df", y, x);
RLUTIL_PRINT(buf); RLUTIL_PRINT(buf);
#endif // __cplusplus #endif // __cplusplus
#endif // WIN32 || USE_ANSI #endif // WIN32 || USE_ANSI
} }
/// Function: hidecursor /// Function: hidecursor
/// Hides the cursor. /// Hides the cursor.
void inline hidecursor() { void inline hidecursor()
{
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI) #if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsoleOutput; HANDLE hConsoleOutput;
CONSOLE_CURSOR_INFO structCursorInfo; CONSOLE_CURSOR_INFO structCursorInfo;
hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE ); hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
structCursorInfo.bVisible = FALSE; structCursorInfo.bVisible = FALSE;
SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
#else // WIN32 || USE_ANSI #else // WIN32 || USE_ANSI
RLUTIL_PRINT("\033[?25l"); RLUTIL_PRINT("\033[?25l");
#endif // WIN32 || USE_ANSI #endif // WIN32 || USE_ANSI
} }
@ -453,14 +469,14 @@ void inline hidecursor() {
/// Shows the cursor. /// Shows the cursor.
void inline showcursor() { void inline showcursor() {
#if defined(WIN32) && !defined(RLUTIL_USE_ANSI) #if defined(WIN32) && !defined(RLUTIL_USE_ANSI)
HANDLE hConsoleOutput; HANDLE hConsoleOutput;
CONSOLE_CURSOR_INFO structCursorInfo; CONSOLE_CURSOR_INFO structCursorInfo;
hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE ); hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
structCursorInfo.bVisible = TRUE; structCursorInfo.bVisible = TRUE;
SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
#else // WIN32 || USE_ANSI #else // WIN32 || USE_ANSI
RLUTIL_PRINT("\033[?25h"); RLUTIL_PRINT("\033[?25h");
#endif // WIN32 || USE_ANSI #endif // WIN32 || USE_ANSI
} }
@ -468,11 +484,11 @@ void inline showcursor() {
/// Waits given number of milliseconds before continuing. /// Waits given number of milliseconds before continuing.
void inline msleep(unsigned int ms) { void inline msleep(unsigned int ms) {
#ifdef WIN32 #ifdef WIN32
Sleep(ms); Sleep(ms);
#else #else
// usleep argument must be under 1 000 000 // usleep argument must be under 1 000 000
if (ms > 1000) sleep(ms/1000000); if (ms > 1000) sleep(ms/1000000);
usleep((ms % 1000000) * 1000); usleep((ms % 1000000) * 1000);
#endif #endif
} }
@ -481,7 +497,7 @@ void inline msleep(unsigned int ms) {
/// Function: anykey /// Function: anykey
/// Waits until a key is pressed. /// Waits until a key is pressed.
void inline anykey() { void inline anykey() {
getch(); getch();
} }
#ifndef min #ifndef min
@ -512,8 +528,8 @@ template <class T> const T& max ( const T& a, const T& b ) { return (b<a)?a:b; }
/// Hides the cursor and shows it again /// Hides the cursor and shows it again
/// when the object goes out of scope. /// when the object goes out of scope.
struct CursorHider { struct CursorHider {
CursorHider() { hidecursor(); } CursorHider() { hidecursor(); }
~CursorHider() { showcursor(); } ~CursorHider() { showcursor(); }
}; };
} // namespace rlutil } // namespace rlutil