develop
Petr Mrázek 2010-08-23 16:11:46 +02:00
commit 0ddc431013
25 changed files with 612 additions and 87 deletions

@ -33,6 +33,7 @@ using namespace std;
#include "Internal.h" #include "Internal.h"
#include "dfhack/DFTypes.h" #include "dfhack/DFTypes.h"
#include "dfhack/DFTileTypes.h"
#include "dfhack-c/DFTypes_C.h" #include "dfhack-c/DFTypes_C.h"
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
@ -56,6 +57,9 @@ int (*alloc_matgloss_buffer_callback)(t_matgloss*, uint32_t) = NULL;
int (*alloc_descriptor_buffer_callback)(t_descriptor_color*, uint32_t) = NULL; int (*alloc_descriptor_buffer_callback)(t_descriptor_color*, uint32_t) = NULL;
int (*alloc_matgloss_other_buffer_callback)(t_matglossOther*, uint32_t) = NULL; int (*alloc_matgloss_other_buffer_callback)(t_matglossOther*, uint32_t) = NULL;
int (*alloc_t_customWorkshop_buffer_callback)(t_customWorkshop*, uint32_t) = NULL;
int (*alloc_t_material_buffer_callback)(t_material*, uint32_t) = NULL;
int (*alloc_empty_colormodifier_callback)(c_colormodifier*) = NULL; int (*alloc_empty_colormodifier_callback)(c_colormodifier*) = NULL;
int (*alloc_colormodifier_callback)(c_colormodifier*, const char*, uint32_t) = NULL; int (*alloc_colormodifier_callback)(c_colormodifier*, const char*, uint32_t) = NULL;
int (*alloc_colormodifier_buffer_callback)(c_colormodifier*, uint32_t) = NULL; int (*alloc_colormodifier_buffer_callback)(c_colormodifier*, uint32_t) = NULL;
@ -102,6 +106,16 @@ int DFHack_getVegetationType(int in)
return DFHack::getVegetationType(in); return DFHack::getVegetationType(in);
} }
int DFHack_getTileType(int index, TileRow* tPtr)
{
if(index >= TILE_TYPE_ARRAY_LENGTH)
return 0;
*tPtr = tileTypeTable[index];
return 1;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -31,24 +31,102 @@ distribution.
extern "C" { extern "C" {
#endif #endif
/**
Allocates a new ContextManager.
@param path_to_xml A const string pointer containing the path to the Memory.xml file.
@return A DFHackObject pointer that points to the allocated ContextManager.
*/
DFHACK_EXPORT DFHackObject* ContextManager_Alloc(const char* path_to_xml); DFHACK_EXPORT DFHackObject* ContextManager_Alloc(const char* path_to_xml);
/**
Frees a previously allocated ContextManager.
@param contextMgr A DFHackObject pointer that points to a previously allocated ContextManager.
@return None.
*/
DFHACK_EXPORT void ContextManager_Free(DFHackObject* contextMgr); DFHACK_EXPORT void ContextManager_Free(DFHackObject* contextMgr);
DFHACK_EXPORT int ContextManager_Refresh(DFHackObject* contextMgr); DFHACK_EXPORT int ContextManager_Refresh(DFHackObject* contextMgr);
/**
Gets the number of active DF processes.
@param contextMgr A pointer to an active ContextManager.
@param size A pointer to an unsigned 32-bit integer that will contain the count of active DF processes.
@return
- 0: Failure.
- 1: Success.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int ContextManager_size(DFHackObject* contextMgr, uint32_t* size); DFHACK_EXPORT int ContextManager_size(DFHackObject* contextMgr, uint32_t* size);
DFHACK_EXPORT int ContextManager_purge(DFHackObject* contextMgr);
DFHACK_EXPORT int ContextManager_purge(DFHackObject* contextMgr);
DFHACK_EXPORT DFHackObject* ContextManager_getContext(DFHackObject* contextMgr, uint32_t index); DFHACK_EXPORT DFHackObject* ContextManager_getContext(DFHackObject* contextMgr, uint32_t index);
DFHACK_EXPORT DFHackObject* ContextManager_getSingleContext(DFHackObject* contextMgr); DFHACK_EXPORT DFHackObject* ContextManager_getSingleContext(DFHackObject* contextMgr);
/**
Frees a previously allocated Context.
@param context A DFHackObject pointer that points to a previously allocated Context.
@return None.
*/
DFHACK_EXPORT void Context_Free(DFHackObject* context); DFHACK_EXPORT void Context_Free(DFHackObject* context);
/**
Attaches to a running DF process.
@param context A pointer to an unattached Context.
@return
- 0: Failure.
- 1: Success.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_Attach(DFHackObject* context); DFHACK_EXPORT int Context_Attach(DFHackObject* context);
/**
Detaches from a tracked DF process.
@param context A pointer to an attached Context.
@return
- 0: Failure.
- 1: Success.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_Detach(DFHackObject* context); DFHACK_EXPORT int Context_Detach(DFHackObject* context);
/**
Determines whether or not the given Context is attached to a running DF process.
@param context A pointer to an attached Context.
@return
- 0: The supplied Context is not attached.
- 1: The supplied Context is attached.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_isAttached(DFHackObject* context); DFHACK_EXPORT int Context_isAttached(DFHackObject* context);
/**
Suspends a running DF process.
@param context A pointer to an attached Context.
@return
- 0: The tracked process was not suspended.
- 1: The tracked process was suspended.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_Suspend(DFHackObject* context); DFHACK_EXPORT int Context_Suspend(DFHackObject* context);
/**
Resume a running DF process.
@param context A pointer to an attached Context.
@return
- 0: The tracked process was not resumed.
- 1: The tracked process was resumed.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_Resume(DFHackObject* context); DFHACK_EXPORT int Context_Resume(DFHackObject* context);
/**
Determines whether or not the given Context's tracked process is suspended.
@param context A pointer to an attached Context.
@return
- 0: The tracked process is not suspended.
- 1: The tracked process is suspended.
- -1: An invalid pointer was supplied.
*/
DFHACK_EXPORT int Context_isSuspended(DFHackObject* context); DFHACK_EXPORT int Context_isSuspended(DFHackObject* context);
DFHACK_EXPORT int Context_ForceResume(DFHackObject* context); DFHACK_EXPORT int Context_ForceResume(DFHackObject* context);
DFHACK_EXPORT int Context_AsyncSuspend(DFHackObject* context); DFHACK_EXPORT int Context_AsyncSuspend(DFHackObject* context);

@ -29,6 +29,7 @@ distribution.
#include "dfhack/DFTypes.h" #include "dfhack/DFTypes.h"
#include "dfhack/modules/Maps.h" #include "dfhack/modules/Maps.h"
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
#include "dfhack/DFTileTypes.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -48,6 +49,16 @@ DFHACK_EXPORT extern int (*alloc_matgloss_buffer_callback)(t_matgloss*, uint32_t
DFHACK_EXPORT extern int (*alloc_descriptor_buffer_callback)(t_descriptor_color*, uint32_t); DFHACK_EXPORT extern int (*alloc_descriptor_buffer_callback)(t_descriptor_color*, uint32_t);
DFHACK_EXPORT extern int (*alloc_matgloss_other_buffer_callback)(t_matglossOther*, uint32_t); DFHACK_EXPORT extern int (*alloc_matgloss_other_buffer_callback)(t_matglossOther*, uint32_t);
struct t_customWorkshop
{
uint32_t index;
char name[256];
};
DFHACK_EXPORT extern int (*alloc_t_customWorkshop_buffer_callback)(t_customWorkshop*, uint32_t);
DFHACK_EXPORT extern int (*alloc_t_material_buffer_callback)(t_material*, uint32_t);
struct c_colormodifier struct c_colormodifier
{ {
char part[128]; char part[128];
@ -112,6 +123,8 @@ DFHACK_EXPORT extern int DFHack_isStairTerrain(int in);
DFHACK_EXPORT extern int DFHack_isOpenTerrain(int in); DFHACK_EXPORT extern int DFHack_isOpenTerrain(int in);
DFHACK_EXPORT extern int DFHack_getVegetationType(int in); DFHACK_EXPORT extern int DFHack_getVegetationType(int in);
DFHACK_EXPORT extern int DFHack_getTileType(int index, TileRow* tPtr);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -0,0 +1,106 @@
=======================================
Introduction And Reasons For Existence
=======================================
C++ is not an easy language to access from other languages. There are several "features" that make interoperability considerably more painful when trying to write bindings for Python, Ruby, Lua, or whatever. To that end, dfhack has a C translation layer to ease the process of making bindings for other languages. A shadow API, if you will.
.. contents::
=================
Getting DFHack-C
=================
The C shim is a part of the standard dfhack package. If you've installed dfhack, you've already got it. The dfhack source and binaries are hosted on github_, at http://github.com/peterix/dfhack
.. _github: http://www.github.com/
Packages
=========
The library and tools are packaged for Archlinux and are available both
in AUR and the arch-games repository.
The package name is dfhack-git.
========
Layout
========
The structure of the C shim mimics, as far as possible, the normal dfhack structure. Of course, since C lacks things like classes, templates, and function overloading, there are a few places where deviations are unavoidable.
Return Values
=============
Unless otherwise specified, functions that return an int return one of the following values:
- 0: The operation failed.
- 1: The operation succeeded.
- -1: An invalid module pointer was supplied.
Types
=======
Module objects are passed around as void pointers with the typedef name 'DFHackObject'. Wherever possible, the structures and enumerations defined by dfhack are used without redefinition.
Allocator Callbacks
====================
Wherever possible, the C shim eschews the native allocation of memory, as this would require language bindings to remember to free the memory later, and would, in my opinion, make the shim less flexible. So a number of function pointers are exposed to allow memory to be allocated in the language being used to wrap dfhack. In general, the allocations relate to arrays of dfhack structures, but there are a couple of corner cases.
The buffer callback functions should take a pointer to an array of the particular type, and a 32-bit unsigned integer (uint32_t) defining the length of the array needed. If the buffer was successfully created, the callback function should return 1. In case of failure, set the buffer pointer to NULL (or 0) and return 0.
All of the allocators are defined in dfhack/library/include/dfhack-c/DFTypes_C.h.
Buffer Callback List
---------------------
- alloc_byte_buffer_callback(int8_t*, uint32_t)
- alloc_short_buffer_callback(int16_t*, uint32_t)
- alloc_int_buffer_callback(int32_t*, uint32_t)
- alloc_ubyte_buffer_callback(uint8_t*, uint32_t)
- alloc_ushort_buffer_callback(uint16_t*, uint32_t)
- alloc_uint_buffer_callback(uint32_t*, uint32_t)
- alloc_matgloss_buffer_callback(t_matgloss*, uint32_t)
- alloc_descriptor_buffer_callback(t_descriptor_color*, uint32_t)
- alloc_matgloss_other_buffer_callback(t_matglossOther*, uint32_t)
- alloc_vein_buffer_callback(t_vein*, uint32_t)
- alloc_frozenliquidvein_buffer_callback(t_frozenliquidvein*, uint32_t)
- alloc_spattervein_buffer_callback(t_spattervein*, uint32_t)
Templates Make My Life Harder
-------------------------------
Three dfhack structures (t_colormodifier, t_creaturecaste, and t_creaturetype) contain vectors, which (obviously) don't work in C. Therefore, these structures have C versions that replace the vector with a buffer and length, but are otherwise identical to their C++ counterparts. For each structure, there are three associated callbacks. One initializes an empty instance of the structure, one initializes an instance with values passed in, and one allocates a buffer in the same manner as the other allocators.
A Small Callback Example In Python
-------------------------------------
The Python bindings for dfhack implement the unsigned integer allocator callback like this:
.. admonition:: util.py
| from ctypes import \*
|
| def _allocate_array(t_type, count):
| arr_type = t_type * count
| arr = arr_type()
|
| ptr = c_void_p()
| ptr = addressof(arr)
|
| return (arr, ptr)
|
| def _alloc_uint_buffer(ptr, count):
| a = _allocate_array(c_uint, count)
|
| ptr = addressof(a[0])
|
| return 1
|
| _uint_functype = CFUNCTYPE(c_int, POINTER(c_uint), c_uint)
| alloc_uint_buffer = _uint_functype(_alloc_uint_buffer)
.. admonition:: dftypes.py
| from ctypes import \*
| from util import \*
|
| libdfhack = cdll.libdfhack
|
| libdfhack.alloc_uint_buffer_callback = alloc_uint_buffer
Modules
========
Every dfhack module has a corresponding set of C functions. The functions are named <MODULE>_<FUNCTION>, as in 'Maps_Start', 'Materials_ReadOthers', etc. The first argument to any module function is a void pointer that points to an instance of the module object in question.

@ -28,23 +28,18 @@ distribution.
#include "DFHack_C.h" #include "DFHack_C.h"
#include "dfhack/DFTypes.h" #include "dfhack/DFTypes.h"
#include "dfhack/modules/Buildings.h" #include "dfhack/modules/Buildings.h"
#include "dfhack-c/DFTypes_C.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct t_customWorkshop
{
uint32_t index;
char name[256];
};
DFHACK_EXPORT int Buildings_Start(DFHackObject* b_Ptr, uint32_t* numBuildings); DFHACK_EXPORT int Buildings_Start(DFHackObject* b_Ptr, uint32_t* numBuildings);
DFHACK_EXPORT int Buildings_Finish(DFHackObject* b_Ptr); DFHACK_EXPORT int Buildings_Finish(DFHackObject* b_Ptr);
DFHACK_EXPORT int Buildings_Read(DFHackObject* b_Ptr, const uint32_t index, t_building* building); DFHACK_EXPORT int Buildings_Read(DFHackObject* b_Ptr, const uint32_t index, t_building* building);
DFHACK_EXPORT int Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr, void* (*t_customWorkshop_buffer_create)(uint32_t)); DFHACK_EXPORT t_customWorkshop* Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr);
DFHACK_EXPORT int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building); DFHACK_EXPORT int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building);
#ifdef __cplusplus #ifdef __cplusplus

@ -27,6 +27,7 @@ distribution.
#include "DFHack_C.h" #include "DFHack_C.h"
#include "dfhack/DFTypes.h" #include "dfhack/DFTypes.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack/modules/Materials.h" #include "dfhack/modules/Materials.h"
#include "dfhack/modules/Creatures.h" #include "dfhack/modules/Creatures.h"
@ -42,12 +43,23 @@ DFHACK_EXPORT int32_t Creatures_ReadCreatureInBox(DFHackObject* cPtr, const int3
const uint16_t x2, const uint16_t y2, const uint16_t z2); const uint16_t x2, const uint16_t y2, const uint16_t z2);
DFHACK_EXPORT int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* furball); DFHACK_EXPORT int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* furball);
DFHACK_EXPORT int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); DFHACK_EXPORT t_material* Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball);
DFHACK_EXPORT uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr); DFHACK_EXPORT uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr);
DFHACK_EXPORT int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr); DFHACK_EXPORT int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr);
DFHACK_EXPORT int Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball, t_material* (*t_material_buffer_create)(int)); DFHACK_EXPORT int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
DFHACK_EXPORT int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value);
DFHACK_EXPORT int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2);
DFHACK_EXPORT int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul);
DFHACK_EXPORT int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature);
DFHACK_EXPORT int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex);
DFHACK_EXPORT int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul);
DFHACK_EXPORT int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood);
DFHACK_EXPORT int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill);
DFHACK_EXPORT int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count);
DFHACK_EXPORT int Creatures_WritePos(DFHackObject* cPtr, const uint32_t index, const t_creature* creature);
DFHACK_EXPORT int Creatures_WriteCiv(DFHackObject* cPtr, const uint32_t index, const int32_t civ);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -34,6 +34,9 @@ distribution.
extern "C" { extern "C" {
#endif #endif
DFHACK_EXPORT int Items_Start(DFHackObject* items);
DFHACK_EXPORT int Items_Finish(DFHackObject* items);
DFHACK_EXPORT char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats); DFHACK_EXPORT char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats);
DFHACK_EXPORT char* Items_getItemClass(DFHackObject* items, int32_t index); DFHACK_EXPORT char* Items_getItemClass(DFHackObject* items, int32_t index);
DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, t_item* item); DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, t_item* item);

@ -62,9 +62,9 @@ DFHACK_EXPORT t_matgloss* Materials_getPlant(DFHackObject* mat);
DFHACK_EXPORT t_matgloss* Materials_getRace(DFHackObject* mat); DFHACK_EXPORT t_matgloss* Materials_getRace(DFHackObject* mat);
DFHACK_EXPORT c_creaturetype* Materials_getRaceEx(DFHackObject* mat); DFHACK_EXPORT c_creaturetype* Materials_getRaceEx(DFHackObject* mat);
DFHACK_EXPORT t_descriptor_color* Materials_getColor(DFHackObject* mat); DFHACK_EXPORT t_descriptor_color* Materials_getColor(DFHackObject* mat);
DFHACK_EXPORT t_matglossOther* Materials_getOther(DFHackObject* mat); DFHACK_EXPORT t_matglossOther* Materials_getOther(DFHackObject* mat);
DFHACK_EXPORT t_matgloss* Materials_getAllDesc(DFHackObject* mat);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -27,6 +27,7 @@ distribution.
#include "DFHack_C.h" #include "DFHack_C.h"
#include "dfhack/DFTypes.h" #include "dfhack/DFTypes.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack/modules/Translation.h" #include "dfhack/modules/Translation.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -36,8 +37,8 @@ extern "C" {
DFHACK_EXPORT int Translation_Start(DFHackObject* trans); DFHACK_EXPORT int Translation_Start(DFHackObject* trans);
DFHACK_EXPORT int Translation_Finish(DFHackObject* trans); DFHACK_EXPORT int Translation_Finish(DFHackObject* trans);
DFHACK_EXPORT char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int)); DFHACK_EXPORT char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name);
DFHACK_EXPORT char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int)); DFHACK_EXPORT char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -96,7 +96,9 @@ namespace DFHack
TileVariant v; TileVariant v;
}; };
const TileRow tileTypeTable[520] = #define TILE_TYPE_ARRAY_LENGTH 520
const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] =
{ {
// 0 // 0
{"void",EMPTY, AIR, VAR_1}, {"void",EMPTY, AIR, VAR_1},

@ -24,6 +24,7 @@ distribution.
#include "dfhack-c/modules/Buildings_C.h" #include "dfhack-c/modules/Buildings_C.h"
using namespace std; using namespace std;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -68,7 +69,7 @@ int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building)
return -1; return -1;
} }
int Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr, void* (*t_customWorkshop_buffer_create)(uint32_t)) t_customWorkshop* Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr)
{ {
if(b_Ptr != NULL) if(b_Ptr != NULL)
{ {
@ -78,19 +79,24 @@ int Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr, void* (*t_customWorks
map<uint32_t, string>::iterator bIter; map<uint32_t, string>::iterator bIter;
if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes)) if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes))
return 0; return NULL;
(*alloc_t_customWorkshop_buffer_callback)(cw_Ptr, bTypes.size());
if(cw_Ptr == NULL)
return NULL;
cw_Ptr = (t_customWorkshop*)((*t_customWorkshop_buffer_create)(bTypes.size()));
for(i = 0, bIter = bTypes.begin(); bIter != bTypes.end(); bIter++, i++) for(i = 0, bIter = bTypes.begin(); bIter != bTypes.end(); bIter++, i++)
{ {
cw_Ptr[i].index = (*bIter).first; cw_Ptr[i].index = (*bIter).first;
size_t length = (*bIter).second.copy(cw_Ptr[i].name, 256); size_t length = (*bIter).second.copy(cw_Ptr[i].name, 256);
cw_Ptr[i].name[length] = '\0'; cw_Ptr[i].name[length] = '\0';
} }
return 1;
return cw_Ptr;
} }
return -1; return NULL;
} }
#ifdef __cplusplus #ifdef __cplusplus

@ -24,6 +24,11 @@ distribution.
#include "dfhack-c/modules/Creatures_C.h" #include "dfhack-c/modules/Creatures_C.h"
#include <vector>
#include <algorithm>
using namespace std;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -68,14 +73,35 @@ int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature*
return -1; return -1;
} }
int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) t_material* Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball)
{ {
if(cPtr != NULL) if(cPtr != NULL)
{ {
return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors); std::vector<t_material> mat;
if(((DFHack::Creatures*)cPtr)->ReadJob(furball, mat))
{
if(mat.size() <= 0)
return NULL;
t_material* buf;
(*alloc_t_material_buffer_callback)(buf, mat.size());
if(buf != NULL)
{
copy(mat.begin(), mat.end(), buf);
return buf;
}
else
return NULL;
}
else
return NULL;
} }
return -1; return NULL;
} }
uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr) uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr)
@ -98,27 +124,128 @@ int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr)
return -1; return -1;
} }
int Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball, t_material* (*t_material_buffer_create)(int)) int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{ {
if(cPtr != NULL) if(cPtr != NULL)
{ {
std::vector<t_material> mat; return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors);
}
if(((DFHack::Creatures*)cPtr)->ReadJob(furball, mat)) return -1;
}
int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value)
{
if(cPtr != NULL)
{ {
t_material* buf = (*t_material_buffer_create)(mat.size()); return ((DFHack::Creatures*)cPtr)->WriteHappiness(index, happiness_value);
}
if(buf != NULL) return -1;
}
int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2)
{ {
copy(mat.begin(), mat.end(), buf); if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteFlags(index, flags1, flags2);
}
return -1;
}
return 1; int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul)
{
if(cPtr != NULL && soul != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteSkills(index, *soul);
} }
else
return -1; return -1;
} }
else
int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature)
{
if(cPtr != NULL && creature != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteAttributes(index, *creature);
}
return -1;
}
int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteSex(index, sex);
}
return -1;
}
int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul)
{
if(cPtr != NULL && soul != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteTraits(index, *soul);
}
return -1;
}
int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteMood(index, mood);
}
return -1;
}
int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteMoodSkill(index, moodSkill);
}
return -1;
}
int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count)
{
if(cPtr != NULL && furball != NULL && mat != NULL)
{
if(mat_count == 0)
return 0; return 0;
std::vector<t_material> mat_vec;
copy(mat, mat + mat_count, mat_vec.begin());
return ((DFHack::Creatures*)cPtr)->WriteJob(furball, mat_vec);
}
return -1;
}
int Creatures_WritePos(DFHackObject* cPtr, const uint32_t index, const t_creature* creature)
{
if(cPtr != NULL && creature != NULL)
{
return ((DFHack::Creatures*)cPtr)->WritePos(index, *creature);
}
return -1;
}
int Creatures_WriteCiv(DFHackObject* cPtr, const uint32_t index, const int32_t civ)
{
if(cPtr != NULL)
{
return ((DFHack::Creatures*)cPtr)->WriteCiv(index, civ);
} }
return -1; return -1;

@ -28,6 +28,26 @@ distribution.
extern "C" { extern "C" {
#endif #endif
int Items_Start(DFHackObject* items)
{
if(items != NULL)
{
return ((DFHack::Items*)items)->Start();
}
return -1;
}
int Items_Finish(DFHackObject* items)
{
if(items != NULL)
{
return ((DFHack::Items*)items)->Finish();
}
return -1;
}
//FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings. //FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings.
char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats) char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats)

@ -407,6 +407,30 @@ t_matglossOther* Materials_getOther(DFHackObject* mat)
return NULL; return NULL;
} }
t_matgloss* Materials_getAllDesc(DFHackObject* mat)
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->alldesc.size() > 0)
{
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->alldesc.size()));
if(buf != NULL)
{
copy(materials->race.begin(), materials->alldesc.end(), buf);
return buf;
}
}
}
return NULL;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -58,7 +58,65 @@ int Translation_Finish(DFHackObject* trans)
return -1; return -1;
} }
char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int)) // char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int))
// {
// if(trans != NULL)
// {
// std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, true);
// if(nameTrans.size() > 0)
// {
// char* buf = (*char_buffer_create)(nameTrans.size());
// if(buf != NULL)
// {
// size_t len = nameTrans.copy(buf, nameTrans.size());
// if(len > 0)
// buf[len] = '\0';
// else
// buf[0] = '\0';
// }
// return buf;
// }
// else
// return NULL;
// }
// return NULL;
// }
// char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int))
// {
// if(trans != NULL)
// {
// std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, false);
// if(nameTrans.size() > 0)
// {
// char* buf = (*char_buffer_create)(nameTrans.size());
// if(buf != NULL)
// {
// size_t len = nameTrans.copy(buf, nameTrans.size());
// if(len > 0)
// buf[len] = '\0';
// else
// buf[0] = '\0';
// }
// return buf;
// }
// else
// return NULL;
// }
// return NULL;
// }
char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name)
{ {
if(trans != NULL) if(trans != NULL)
{ {
@ -66,7 +124,9 @@ char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name
if(nameTrans.size() > 0) if(nameTrans.size() > 0)
{ {
char* buf = (*char_buffer_create)(nameTrans.size()); char* buf;
(*alloc_char_buffer_callback)(buf, nameTrans.size());
if(buf != NULL) if(buf != NULL)
{ {
@ -87,7 +147,7 @@ char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name
return NULL; return NULL;
} }
char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name, char* (*char_buffer_create)(int)) char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name)
{ {
if(trans != NULL) if(trans != NULL)
{ {
@ -95,7 +155,9 @@ char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_n
if(nameTrans.size() > 0) if(nameTrans.size() > 0)
{ {
char* buf = (*char_buffer_create)(nameTrans.size()); char* buf;
(*alloc_char_buffer_callback)(buf, nameTrans.size());
if(buf != NULL) if(buf != NULL)
{ {

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import * from dftypes import *
import util import util
libdfhack.Buildings_GetCustomWorkshopType.argtypes = [ c_void_p, POINTER(CustomWorkshop) ] libdfhack.Buildings_GetCustomWorkshopType.argtypes = [ c_void_p, POINTER(CustomWorkshop) ]
@ -28,20 +28,7 @@ class Buildings(object):
return None return None
def read_custom_workshop_types(self): def read_custom_workshop_types(self):
def read_callback(count): return libdfhack.Buildings_ReadCustomWorkshopTypes(self._b_ptr)
allocated = util._allocate_array(CustomWorkshop, count)
workshop_types = allocated[0]
return allocated[1]
workshop_types = None
callback = _arr_create_func(read_callback)
if libdfhack.Buildings_ReadCustomWorkshopTypes(self._b_ptr, callback) > 0:
return workshop_types
else:
return None
def get_custom_workshop_type(self, custom_workshop): def get_custom_workshop_type(self, custom_workshop):
return libdfhack.Buildings_GetCustomWorkshopType(self._b_ptr, byref(custom_workshop)) return libdfhack.Buildings_GetCustomWorkshopType(self._b_ptr, byref(custom_workshop))

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import * from dftypes import *
class Constructions(object): class Constructions(object):
def __init__(self, ptr): def __init__(self, ptr):

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import * from dftypes import *
libdfhack.ContextManager_Alloc.restype = c_void_p libdfhack.ContextManager_Alloc.restype = c_void_p
libdfhack.ContextManager_Free.argtypes = [ c_void_p ] libdfhack.ContextManager_Free.argtypes = [ c_void_p ]

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import libdfhack, Creature, Material from dftypes import libdfhack, Creature, Material
import util import util
libdfhack.Creatures_WriteLabors.argtypes = [ c_void_p, c_uint, POINTER(c_ubyte) ] libdfhack.Creatures_WriteLabors.argtypes = [ c_void_p, c_uint, POINTER(c_ubyte) ]
@ -45,31 +45,18 @@ class Creatures(object):
return libdfhack.Creatures_WriteLabors(self._c_ptr, c_uint(index), labors) > 0 return libdfhack.Creatures_WriteLabors(self._c_ptr, c_uint(index), labors) > 0
def read_job(self, creature): def read_job(self, creature):
def read_callback(count): return libdfhack.Creatures_ReadJob(self._c_ptr, byref(creature))
allocated = util._allocate_array(Material, count)
jobs = allocated[0]
return allocated[1]
jobs = None
callback = _arr_create_func(read_callback)
if libdfhack.Creatures_ReadJob(self._c_ptr, byref(creature), callback) > 0:
return jobs
else:
return None
@property @property
def dwarf_race_index(self): def dwarf_race_index(self):
if self._d_race_index is None: if self._d_race_index is None:
self._d_race_index = int(libdfhack.Creatures_GetDwarfRaceIndex(self._c_ptr).value) self._d_race_index =libdfhack.Creatures_GetDwarfRaceIndex(self._c_ptr)
return self._d_race_index return self._d_race_index
@property @property
def dwarf_civ_id(self): def dwarf_civ_id(self):
if self._d_civ_id is None: if self._d_civ_id is None:
self._d_civ_id = int(libdfhack.Creatures_GetDwarfCivId(self._c_ptr).value) self._d_civ_id = libdfhack.Creatures_GetDwarfCivId(self._c_ptr)
return self._d_civ_id return self._d_civ_id

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydfhackflags import * from flags import *
from enum import * from enum import *
from util import * from util import *
@ -24,6 +24,24 @@ Temperatures = ((c_ushort * 16) * 16)
Designations40d = ((DesignationFlags * 16) * 16) Designations40d = ((DesignationFlags * 16) * 16)
Occupancies40d = ((OccupancyFlags * 16) * 16) Occupancies40d = ((OccupancyFlags * 16) * 16)
def wall_terrain_check(terrain):
return libdfhack.DFHack_isWallTerrain(terrain) > 0
def floor_terrain_check(terrain):
return libdfhack.DFHack_isFloorTerrain(terrain) > 0
def ramp_terrain_check(terrain):
return libdfhack.DFHack_isRampTerrain(terrain) > 0
def stair_terrain_check(terrain):
return libdfhack.DFHack_isStairTerrain(terrain) > 0
def open_terrain_check(terrain):
return libdfhack.DFHack_isOpenTerrain(terrain) > 0
def get_vegetation_type(terrain):
return libdfhack.DFHack_getVegetationType(terrain)
class Position2D(Structure): class Position2D(Structure):
_fields_ = [("x", c_ushort), _fields_ = [("x", c_ushort),
("y", c_ushort)] ("y", c_ushort)]
@ -52,11 +70,31 @@ class Vein(Structure):
("flags", c_uint), ("flags", c_uint),
("address_of", c_uint)] ("address_of", c_uint)]
def _alloc_vein_buffer_callback(ptr, count):
allocated = _allocate_array(Vein, count)
ptr = addressof(allocated[0])
return 1
_vein_functype = CFUNCTYPE(c_int, POINTER(Vein), c_uint)
libdfhack.alloc_vein_buffer_callback = _vein_functype(_alloc_vein_buffer_callback)
class FrozenLiquidVein(Structure): class FrozenLiquidVein(Structure):
_fields_ = [("vtable", c_uint), _fields_ = [("vtable", c_uint),
("tiles", TileTypes40d), ("tiles", TileTypes40d),
("address_of", c_uint)] ("address_of", c_uint)]
def _alloc_frozenliquidvein_buffer_callback(ptr, count):
allocated = _allocate_array(FrozenLiquidVein, count)
ptr = addressof(allocated[0])
return 1
_frozenliquidvein_functype = CFUNCTYPE(c_int, POINTER(FrozenLiquidVein), c_uint)
libdfhack.alloc_frozenliquidvein_buffer_callback = _frozenliquidvein_functype(_alloc_frozenliquidvein_buffer_callback)
class SpatterVein(Structure): class SpatterVein(Structure):
_fields_ = [("vtable", c_uint), _fields_ = [("vtable", c_uint),
("mat1", c_ushort), ("mat1", c_ushort),
@ -66,6 +104,16 @@ class SpatterVein(Structure):
("intensity", ((c_ubyte * 16) * 16)), ("intensity", ((c_ubyte * 16) * 16)),
("address_of", c_uint)] ("address_of", c_uint)]
def _alloc_spattervein_buffer_callback(ptr, count):
allocated = _allocate_array(SpatterVein, count)
ptr = addressof(allocated[0])
return 1
_spattervein_functype = CFUNCTYPE(c_int, POINTER(SpatterVein), c_uint)
libdfhack.alloc_spatter_buffer_callback = _spattervein_functype(_alloc_spattervein_buffer_callback)
class MapBlock40d(Structure): class MapBlock40d(Structure):
_fields_ = [("tiletypes", TileTypes40d), _fields_ = [("tiletypes", TileTypes40d),
("designation", Designations40d), ("designation", Designations40d),
@ -146,6 +194,16 @@ class CustomWorkshop(Structure):
_fields_ = [("index", c_uint), _fields_ = [("index", c_uint),
("name", c_char * 256)] ("name", c_char * 256)]
def _alloc_custom_workshop_buffer_callback(count):
allocated = _allocate_array(CustomWorkshop, count)
ptr = addressof(allocated[0])
return 1
_custom_workshop_functype = CFUNCTYPE(c_int, POINTER(CustomWorkshop), c_uint)
libdfhack.alloc_t_customWorkshop_buffer_callback = _custom_workshop_functype(_alloc_custom_workshop_buffer_callback)
class Construction(Structure): class Construction(Structure):
_fields_ = [("x", c_ushort), _fields_ = [("x", c_ushort),
("y", c_ushort), ("y", c_ushort),
@ -175,10 +233,20 @@ class Material(Structure):
("index", c_int), ("index", c_int),
("flags", c_uint)] ("flags", c_uint)]
def _alloc_material_buffer_callback(count):
allocated = _allocate_array(Material, count)
ptr = addressof(allocated[0])
return 1
_material_functype = CFUNCTYPE(c_int, POINTER(Material), c_uint)
libdfhack.alloc_t_material_buffer_callback = _material_functype(_alloc_material_buffer_callback)
class Skill(Structure): class Skill(Structure):
_fields_ = [("id", c_ushort), _fields_ = [("id", c_uint),
("experience", c_uint), ("experience", c_uint),
("rating", c_ushort)] ("rating", c_uint)]
class Job(Structure): class Job(Structure):
_fields_ = [("active", c_byte), _fields_ = [("active", c_byte),
@ -284,7 +352,9 @@ class Creature(Structure):
("has_default_soul", c_byte), ("has_default_soul", c_byte),
("defaultSoul", Soul), ("defaultSoul", Soul),
("nbcolors", c_uint), ("nbcolors", c_uint),
("color", (c_uint * _MAX_COLORS))] ("color", (c_uint * _MAX_COLORS)),
("birth_year", c_uint),
("birth_time", c_uint)]
class CreatureExtract(Structure): class CreatureExtract(Structure):
_fields_ = [("rawname", (c_char * 128))] _fields_ = [("rawname", (c_char * 128))]

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import * from dftypes import *
libdfhack.Items_getItemDescription.argtypes = [ c_void_p, c_uint, c_void_ptr, _arr_create_func ] libdfhack.Items_getItemDescription.argtypes = [ c_void_p, c_uint, c_void_ptr, _arr_create_func ]
libdfhack.Items_getItemDescription.restype = c_char_p libdfhack.Items_getItemDescription.restype = c_char_p

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import * from dftypes import *
from util import _uintify, uint_ptr from util import _uintify, uint_ptr
_MAX_DIM = 0x300 _MAX_DIM = 0x300
@ -15,6 +15,9 @@ libdfhack.Maps_WriteTemperatures.argtypes = [ c_void_p, c_uint, c_uint, c_uint,
libdfhack.Maps_ReadOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ] libdfhack.Maps_ReadOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ]
libdfhack.Maps_WriteOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ] libdfhack.Maps_WriteOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ]
libdfhack.Maps_ReadRegionOffsets.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(BiomeIndices40d) ] libdfhack.Maps_ReadRegionOffsets.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(BiomeIndices40d) ]
libdfhack.Maps_ReadStandardVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ]
libdfhack.Maps_ReadFrozenVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ]
libdfhack.Maps_ReadSpatterVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ]
class Maps(object): class Maps(object):
def __init__(self, ptr): def __init__(self, ptr):
@ -152,6 +155,21 @@ class Maps(object):
else: else:
return None return None
def read_veins(self, x, y, z):
ux, uy, uz = _uintify(x, y, z)
return libdfhack.Maps_ReadStandardVeins(self._map_ptr, ux, uy, uz)
def read_frozen_veins(self, x, y, z):
ux, uy, uz = _uintify(x, y, z)
return libdfhack.Maps_ReadFrozenVeins(self._map_ptr, ux, uy, uz)
def read_spatter_veins(self, x, y, z):
ux, uy, uz = _uintify(x, y, z)
return libdfhack.Maps_ReadSpatterVeins(self._map_ptr, ux, uy, uz)
@property @property
def size(self): def size(self):
x = c_uint() x = c_uint()

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import libdfhack from dftypes import libdfhack
from util import * from util import *
_get_arg_types = [ c_void_p, _arr_create_func ] _get_arg_types = [ c_void_p, _arr_create_func ]

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import libdfhack from dftypes import libdfhack
class Position(object): class Position(object):
def __init__(self, ptr): def __init__(self, ptr):

@ -1,5 +1,5 @@
from ctypes import * from ctypes import *
from pydftypes import libdfhack, Tree from dftypes import libdfhack, Tree
class Vegetation(object): class Vegetation(object):
def __init__(self, ptr): def __init__(self, ptr):