diff --git a/library/DFTypes_C.cpp b/library/DFTypes_C.cpp index dc7d946aa..9957ef0a1 100644 --- a/library/DFTypes_C.cpp +++ b/library/DFTypes_C.cpp @@ -33,6 +33,7 @@ using namespace std; #include "Internal.h" #include "dfhack/DFTypes.h" +#include "dfhack/DFTileTypes.h" #include "dfhack-c/DFTypes_C.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_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_colormodifier_callback)(c_colormodifier*, const char*, 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); } +int DFHack_getTileType(int index, TileRow* tPtr) +{ + if(index >= TILE_TYPE_ARRAY_LENGTH) + return 0; + + *tPtr = tileTypeTable[index]; + + return 1; +} + #ifdef __cplusplus } #endif diff --git a/library/include/dfhack-c/DFContext_C.h b/library/include/dfhack-c/DFContext_C.h index 365c235b9..9ae73e4ef 100644 --- a/library/include/dfhack-c/DFContext_C.h +++ b/library/include/dfhack-c/DFContext_C.h @@ -31,24 +31,102 @@ distribution. extern "C" { #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); + +/** +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 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_purge(DFHackObject* contextMgr); +DFHACK_EXPORT int ContextManager_purge(DFHackObject* contextMgr); DFHACK_EXPORT DFHackObject* ContextManager_getContext(DFHackObject* contextMgr, uint32_t index); 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); +/** +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); + +/** +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); + +/** +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); +/** +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); + +/** +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); + +/** +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_ForceResume(DFHackObject* context); DFHACK_EXPORT int Context_AsyncSuspend(DFHackObject* context); diff --git a/library/include/dfhack-c/DFTypes_C.h b/library/include/dfhack-c/DFTypes_C.h index fbd883ead..112e195d4 100644 --- a/library/include/dfhack-c/DFTypes_C.h +++ b/library/include/dfhack-c/DFTypes_C.h @@ -29,6 +29,7 @@ distribution. #include "dfhack/DFTypes.h" #include "dfhack/modules/Maps.h" #include "dfhack/modules/Materials.h" +#include "dfhack/DFTileTypes.h" #ifdef __cplusplus 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_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 { 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_getVegetationType(int in); +DFHACK_EXPORT extern int DFHack_getTileType(int index, TileRow* tPtr); + #ifdef __cplusplus } #endif diff --git a/library/include/dfhack-c/README_C.txt b/library/include/dfhack-c/README_C.txt new file mode 100644 index 000000000..3b785cf54 --- /dev/null +++ b/library/include/dfhack-c/README_C.txt @@ -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 _, 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. diff --git a/library/include/dfhack-c/modules/Buildings_C.h b/library/include/dfhack-c/modules/Buildings_C.h index 6b1632dd2..54c8d98d1 100644 --- a/library/include/dfhack-c/modules/Buildings_C.h +++ b/library/include/dfhack-c/modules/Buildings_C.h @@ -28,23 +28,18 @@ distribution. #include "DFHack_C.h" #include "dfhack/DFTypes.h" #include "dfhack/modules/Buildings.h" +#include "dfhack-c/DFTypes_C.h" #ifdef __cplusplus extern "C" { #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_Finish(DFHackObject* b_Ptr); 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); #ifdef __cplusplus diff --git a/library/include/dfhack-c/modules/Creatures_C.h b/library/include/dfhack-c/modules/Creatures_C.h index bbc9e6f54..16c357e58 100644 --- a/library/include/dfhack-c/modules/Creatures_C.h +++ b/library/include/dfhack-c/modules/Creatures_C.h @@ -27,6 +27,7 @@ distribution. #include "DFHack_C.h" #include "dfhack/DFTypes.h" +#include "dfhack-c/DFTypes_C.h" #include "dfhack/modules/Materials.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); 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 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 } diff --git a/library/include/dfhack-c/modules/Items_C.h b/library/include/dfhack-c/modules/Items_C.h index 5c1e08e48..5c61513f7 100644 --- a/library/include/dfhack-c/modules/Items_C.h +++ b/library/include/dfhack-c/modules/Items_C.h @@ -34,6 +34,9 @@ distribution. extern "C" { #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_getItemClass(DFHackObject* items, int32_t index); DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, t_item* item); diff --git a/library/include/dfhack-c/modules/Materials_C.h b/library/include/dfhack-c/modules/Materials_C.h index 25a9a7df3..888978a50 100644 --- a/library/include/dfhack-c/modules/Materials_C.h +++ b/library/include/dfhack-c/modules/Materials_C.h @@ -62,9 +62,9 @@ DFHACK_EXPORT t_matgloss* Materials_getPlant(DFHackObject* mat); DFHACK_EXPORT t_matgloss* Materials_getRace(DFHackObject* mat); DFHACK_EXPORT c_creaturetype* Materials_getRaceEx(DFHackObject* mat); - DFHACK_EXPORT t_descriptor_color* Materials_getColor(DFHackObject* mat); DFHACK_EXPORT t_matglossOther* Materials_getOther(DFHackObject* mat); +DFHACK_EXPORT t_matgloss* Materials_getAllDesc(DFHackObject* mat); #ifdef __cplusplus } diff --git a/library/include/dfhack-c/modules/Translation_C.h b/library/include/dfhack-c/modules/Translation_C.h index 8cbcf4e91..79a9fbd17 100644 --- a/library/include/dfhack-c/modules/Translation_C.h +++ b/library/include/dfhack-c/modules/Translation_C.h @@ -27,6 +27,7 @@ distribution. #include "DFHack_C.h" #include "dfhack/DFTypes.h" +#include "dfhack-c/DFTypes_C.h" #include "dfhack/modules/Translation.h" #ifdef __cplusplus @@ -36,8 +37,8 @@ extern "C" { DFHACK_EXPORT int Translation_Start(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_TranslateNameNonEnglish(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); #ifdef __cplusplus } diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/DFTileTypes.h index df0e3c873..e3b660711 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/DFTileTypes.h @@ -95,8 +95,10 @@ namespace DFHack TileMaterial m; TileVariant v; }; + + #define TILE_TYPE_ARRAY_LENGTH 520 - const TileRow tileTypeTable[520] = + const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] = { // 0 {"void",EMPTY, AIR, VAR_1}, diff --git a/library/modules/Buildings_C.cpp b/library/modules/Buildings_C.cpp index d7b7d940e..6017a75e5 100644 --- a/library/modules/Buildings_C.cpp +++ b/library/modules/Buildings_C.cpp @@ -24,6 +24,7 @@ distribution. #include "dfhack-c/modules/Buildings_C.h" using namespace std; + #ifdef __cplusplus extern "C" { #endif @@ -68,7 +69,7 @@ int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building) 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) { @@ -78,19 +79,24 @@ int Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr, void* (*t_customWorks map::iterator bIter; if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes)) - return 0; - - cw_Ptr = (t_customWorkshop*)((*t_customWorkshop_buffer_create)(bTypes.size())); + return NULL; + + (*alloc_t_customWorkshop_buffer_callback)(cw_Ptr, bTypes.size()); + + if(cw_Ptr == NULL) + return NULL; + for(i = 0, bIter = bTypes.begin(); bIter != bTypes.end(); bIter++, i++) { cw_Ptr[i].index = (*bIter).first; size_t length = (*bIter).second.copy(cw_Ptr[i].name, 256); cw_Ptr[i].name[length] = '\0'; } - return 1; + + return cw_Ptr; } - return -1; + return NULL; } #ifdef __cplusplus diff --git a/library/modules/Creatures_C.cpp b/library/modules/Creatures_C.cpp index 731ac8611..1370258b2 100644 --- a/library/modules/Creatures_C.cpp +++ b/library/modules/Creatures_C.cpp @@ -24,6 +24,11 @@ distribution. #include "dfhack-c/modules/Creatures_C.h" +#include +#include + +using namespace std; + #ifdef __cplusplus extern "C" { #endif @@ -68,14 +73,35 @@ int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* 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) { - return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors); + std::vector 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) @@ -98,27 +124,128 @@ int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr) 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) { - std::vector mat; - - if(((DFHack::Creatures*)cPtr)->ReadJob(furball, mat)) - { - t_material* buf = (*t_material_buffer_create)(mat.size()); - - if(buf != NULL) - { - copy(mat.begin(), mat.end(), buf); - - return 1; - } - else - return -1; - } - else + return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors); + } + + return -1; +} + +int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value) +{ + if(cPtr != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteHappiness(index, happiness_value); + } + + return -1; +} + +int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2) +{ + if(cPtr != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteFlags(index, flags1, flags2); + } + + return -1; +} + +int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul) +{ + if(cPtr != NULL && soul != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteSkills(index, *soul); + } + + return -1; +} + +int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature) +{ + if(cPtr != NULL && creature != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteAttributes(index, *creature); + } + + return -1; +} + +int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex) +{ + if(cPtr != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteSex(index, sex); + } + + return -1; +} + +int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul) +{ + if(cPtr != NULL && soul != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteTraits(index, *soul); + } + + return -1; +} + +int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood) +{ + if(cPtr != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteMood(index, mood); + } + + return -1; +} + +int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill) +{ + if(cPtr != NULL) + { + return ((DFHack::Creatures*)cPtr)->WriteMoodSkill(index, moodSkill); + } + + return -1; +} + +int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count) +{ + if(cPtr != NULL && furball != NULL && mat != NULL) + { + if(mat_count == 0) return 0; + + std::vector 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; diff --git a/library/modules/Items_C.cpp b/library/modules/Items_C.cpp index b9978f962..f0231617f 100644 --- a/library/modules/Items_C.cpp +++ b/library/modules/Items_C.cpp @@ -28,6 +28,26 @@ distribution. extern "C" { #endif +int Items_Start(DFHackObject* items) +{ + if(items != NULL) + { + return ((DFHack::Items*)items)->Start(); + } + + return -1; +} + +int Items_Finish(DFHackObject* items) +{ + if(items != NULL) + { + return ((DFHack::Items*)items)->Finish(); + } + + return -1; +} + //FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings. char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObject* mats) diff --git a/library/modules/Materials_C.cpp b/library/modules/Materials_C.cpp index 1d70f8716..f95c4e76c 100644 --- a/library/modules/Materials_C.cpp +++ b/library/modules/Materials_C.cpp @@ -407,6 +407,30 @@ t_matglossOther* Materials_getOther(DFHackObject* mat) 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 } #endif diff --git a/library/modules/Translation_C.cpp b/library/modules/Translation_C.cpp index e84e04c2a..2589e9640 100644 --- a/library/modules/Translation_C.cpp +++ b/library/modules/Translation_C.cpp @@ -58,7 +58,65 @@ int Translation_Finish(DFHackObject* trans) 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) { @@ -66,7 +124,9 @@ char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name if(nameTrans.size() > 0) { - char* buf = (*char_buffer_create)(nameTrans.size()); + char* buf; + + (*alloc_char_buffer_callback)(buf, nameTrans.size()); if(buf != NULL) { @@ -87,7 +147,7 @@ char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name 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) { @@ -95,7 +155,9 @@ char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_n if(nameTrans.size() > 0) { - char* buf = (*char_buffer_create)(nameTrans.size()); + char* buf; + + (*alloc_char_buffer_callback)(buf, nameTrans.size()); if(buf != NULL) { diff --git a/library/python/pydfhack/buildings.py b/library/python/pydfhack/buildings.py index 32c330201..d58b92840 100644 --- a/library/python/pydfhack/buildings.py +++ b/library/python/pydfhack/buildings.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import * +from dftypes import * import util libdfhack.Buildings_GetCustomWorkshopType.argtypes = [ c_void_p, POINTER(CustomWorkshop) ] @@ -28,20 +28,7 @@ class Buildings(object): return None def read_custom_workshop_types(self): - def read_callback(count): - 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 + return libdfhack.Buildings_ReadCustomWorkshopTypes(self._b_ptr) def get_custom_workshop_type(self, custom_workshop): return libdfhack.Buildings_GetCustomWorkshopType(self._b_ptr, byref(custom_workshop)) diff --git a/library/python/pydfhack/constructions.py b/library/python/pydfhack/constructions.py index e525d564e..fea93ee0b 100644 --- a/library/python/pydfhack/constructions.py +++ b/library/python/pydfhack/constructions.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import * +from dftypes import * class Constructions(object): def __init__(self, ptr): diff --git a/library/python/pydfhack/context.py b/library/python/pydfhack/context.py index 0afc2cf25..1f9f06c16 100644 --- a/library/python/pydfhack/context.py +++ b/library/python/pydfhack/context.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import * +from dftypes import * libdfhack.ContextManager_Alloc.restype = c_void_p libdfhack.ContextManager_Free.argtypes = [ c_void_p ] diff --git a/library/python/pydfhack/creatures.py b/library/python/pydfhack/creatures.py index d07cf2bdf..06bc52c36 100644 --- a/library/python/pydfhack/creatures.py +++ b/library/python/pydfhack/creatures.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import libdfhack, Creature, Material +from dftypes import libdfhack, Creature, Material import util 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 def read_job(self, creature): - def read_callback(count): - 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 + return libdfhack.Creatures_ReadJob(self._c_ptr, byref(creature)) @property def dwarf_race_index(self): 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 @property def dwarf_civ_id(self): 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 diff --git a/library/python/pydfhack/dftypes.py b/library/python/pydfhack/dftypes.py index 376d99238..86332ace4 100644 --- a/library/python/pydfhack/dftypes.py +++ b/library/python/pydfhack/dftypes.py @@ -1,5 +1,5 @@ from ctypes import * -from pydfhackflags import * +from flags import * from enum import * from util import * @@ -24,6 +24,24 @@ Temperatures = ((c_ushort * 16) * 16) Designations40d = ((DesignationFlags * 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): _fields_ = [("x", c_ushort), ("y", c_ushort)] @@ -52,11 +70,31 @@ class Vein(Structure): ("flags", 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): _fields_ = [("vtable", c_uint), ("tiles", TileTypes40d), ("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): _fields_ = [("vtable", c_uint), ("mat1", c_ushort), @@ -66,6 +104,16 @@ class SpatterVein(Structure): ("intensity", ((c_ubyte * 16) * 16)), ("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): _fields_ = [("tiletypes", TileTypes40d), ("designation", Designations40d), @@ -146,6 +194,16 @@ class CustomWorkshop(Structure): _fields_ = [("index", c_uint), ("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): _fields_ = [("x", c_ushort), ("y", c_ushort), @@ -175,10 +233,20 @@ class Material(Structure): ("index", c_int), ("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): - _fields_ = [("id", c_ushort), + _fields_ = [("id", c_uint), ("experience", c_uint), - ("rating", c_ushort)] + ("rating", c_uint)] class Job(Structure): _fields_ = [("active", c_byte), @@ -284,7 +352,9 @@ class Creature(Structure): ("has_default_soul", c_byte), ("defaultSoul", Soul), ("nbcolors", c_uint), - ("color", (c_uint * _MAX_COLORS))] + ("color", (c_uint * _MAX_COLORS)), + ("birth_year", c_uint), + ("birth_time", c_uint)] class CreatureExtract(Structure): _fields_ = [("rawname", (c_char * 128))] diff --git a/library/python/pydfhack/items.py b/library/python/pydfhack/items.py index 47ad42907..8c5d6625e 100644 --- a/library/python/pydfhack/items.py +++ b/library/python/pydfhack/items.py @@ -1,5 +1,5 @@ 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.restype = c_char_p diff --git a/library/python/pydfhack/maps.py b/library/python/pydfhack/maps.py index c889719e8..f92b75598 100644 --- a/library/python/pydfhack/maps.py +++ b/library/python/pydfhack/maps.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import * +from dftypes import * from util import _uintify, uint_ptr _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_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_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): def __init__(self, ptr): @@ -151,6 +154,21 @@ class Maps(object): return bi else: 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 def size(self): diff --git a/library/python/pydfhack/materials.py b/library/python/pydfhack/materials.py index 04d82fddb..354f4e59a 100644 --- a/library/python/pydfhack/materials.py +++ b/library/python/pydfhack/materials.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import libdfhack +from dftypes import libdfhack from util import * _get_arg_types = [ c_void_p, _arr_create_func ] diff --git a/library/python/pydfhack/position.py b/library/python/pydfhack/position.py index ffa758150..d302d4a6a 100644 --- a/library/python/pydfhack/position.py +++ b/library/python/pydfhack/position.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import libdfhack +from dftypes import libdfhack class Position(object): def __init__(self, ptr): diff --git a/library/python/pydfhack/vegetation.py b/library/python/pydfhack/vegetation.py index 0c22d26b5..ca1f12bd6 100644 --- a/library/python/pydfhack/vegetation.py +++ b/library/python/pydfhack/vegetation.py @@ -1,5 +1,5 @@ from ctypes import * -from pydftypes import libdfhack, Tree +from dftypes import libdfhack, Tree class Vegetation(object): def __init__(self, ptr):