diff --git a/CMakeLists.txt b/CMakeLists.txt index 80aa7203f..f8458cb97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ INCLUDE(CPack) PROJECT (dfhack) cmake_minimum_required(VERSION 2.6) SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules) -SET ( DFHACK_VERSION "0.4.0.2" ) +SET ( DFHACK_VERSION "0.4.0.3-dev" ) # disable warning, autosearch if(COMMAND cmake_policy) @@ -30,6 +30,7 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/tinyxml/) include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/) add_subdirectory (library) +add_subdirectory (library/shm) #add_subdirectory (dfhack/python) add_subdirectory (tools/examples) add_subdirectory (tools/playground) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index b9f41fda2..f036a7a44 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -168,61 +168,3 @@ IF(UNIX) install(TARGETS dfhack LIBRARY DESTINATION lib) install(FILES ${CMAKE_SOURCE_DIR}/output/Memory.xml DESTINATION share/dfhack) ENDIF(UNIX) - -################################################################################ -# DFCONNECT -### - -SET(DFCONNECT_HDRS -shm/shms.h -shm/mod-core.h -shm/mod-maps.h -) - -SET(PROJECT_SRCS -shm/mod-core.cpp -shm/mod-maps.cpp -#mod-creature40d.cpp -) - -SET(PROJECT_HDRS_LINUX -) - -SET(PROJECT_HDRS_WINDOWS -) - -SET(PROJECT_SRCS_LINUX -shm/shms-linux.cpp -) - -SET(PROJECT_SRCS_WINDOWS -shm/shms-windows.cpp -) - -IF(UNIX) - LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_LINUX}) - LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_LINUX}) -ELSE(UNIX) - LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_WINDOWS}) - LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS}) -ENDIF(UNIX) - - -SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) - -LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) - -#IF(CMAKE_SIZEOF_VOID_P EQUAL 4) - IF(UNIX) - add_definitions(-DLINUX_BUILD) - SET(PROJECT_LIBS rt) - SET(CMAKE_CXX_FLAGS "-fvisibility=hidden") - ADD_LIBRARY(dfconnect SHARED ${PROJECT_SRCS}) - TARGET_LINK_LIBRARIES(dfconnect ${PROJECT_LIBS}) - ELSE(UNIX) - # SET(PROJECT_LIBS psapi) - ADD_LIBRARY(SDL SHARED ${PROJECT_SRCS}) - TARGET_LINK_LIBRARIES(SDL ${PROJECT_LIBS}) - ENDIF(UNIX) -#ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4) - diff --git a/library/ContextShared.cpp b/library/ContextShared.cpp index 7798cc85f..cf49a489b 100644 --- a/library/ContextShared.cpp +++ b/library/ContextShared.cpp @@ -24,33 +24,18 @@ using namespace DFHack; DFContextShared::DFContextShared() { // init modules - creatures = 0; - maps = 0; - position = 0; - gui = 0; - world = 0; - materials = 0; - translation = 0; - vegetation = 0; - buildings = 0; - constructions = 0; - items = 0; - windowio = 0; + allModules.clear(); + memset(&(s_mods), 0, sizeof(s_mods)); } DFContextShared::~DFContextShared() { - if(creatures) delete creatures; - if(maps) delete maps; - if(position) delete position; - if(gui) delete gui; - if(materials) delete materials; - if(translation) delete translation; - if(vegetation) delete vegetation; - if(buildings) delete buildings; - if(constructions) delete constructions; - if(world) delete world; - if(windowio) delete windowio; + // invalidate all modules + for(int i = 0 ; i < allModules.size(); i++) + { + delete allModules[i]; + } + allModules.clear(); } bool DFContextShared::InitReadNames() diff --git a/library/DFContext.cpp b/library/DFContext.cpp index fe2d5002e..41ac6e333 100644 --- a/library/DFContext.cpp +++ b/library/DFContext.cpp @@ -27,7 +27,6 @@ distribution. #include "dfhack/DFProcess.h" #include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFContext.h" -#include "dfhack/DFContext.h" #include "dfhack/DFError.h" #include @@ -93,6 +92,13 @@ bool Context::Detach() } d->shm_start = 0; // invalidate all modules + for(int i = 0 ; i < d->allModules.size(); i++) + { + delete d->allModules[i]; + } + d->allModules.clear(); + memset(&(d->s_mods), 0, sizeof(d->s_mods)); + /* if(d->creatures) { delete d->creatures; @@ -147,7 +153,7 @@ bool Context::Detach() { delete d->translation; d->translation = 0; - } + }*/ return true; } @@ -201,13 +207,39 @@ Process * Context::getProcess() /******************************************************************************* M O D U L E S *******************************************************************************/ + +#define MODULE_GETTER(TYPE) \ +TYPE * Context::get##TYPE() \ +{ \ + if(!d->s_mods.p##TYPE)\ + {\ + d->s_mods.p##TYPE = new TYPE(d);\ + d->allModules.push_back(d->s_mods.p##TYPE);\ + }\ + return d->s_mods.p##TYPE;\ +} + +MODULE_GETTER(Creatures); +MODULE_GETTER(Maps); +MODULE_GETTER(Gui); +MODULE_GETTER(WindowIO); +MODULE_GETTER(World); +MODULE_GETTER(Position); +MODULE_GETTER(Materials); +MODULE_GETTER(Items); +MODULE_GETTER(Translation); +MODULE_GETTER(Vegetation); +MODULE_GETTER(Buildings); +MODULE_GETTER(Constructions); +/* Creatures * Context::getCreatures() { if(!d->creatures) d->creatures = new Creatures(d); return d->creatures; } - +*/ +/* Maps * Context::getMaps() { if(!d->maps) @@ -284,7 +316,7 @@ Constructions * Context::getConstructions() d->constructions = new Constructions(d); return d->constructions; } - +*/ /* // returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name diff --git a/library/DFContext_C.cpp b/library/DFContext_C.cpp index 3de599df0..e6406c5be 100644 --- a/library/DFContext_C.cpp +++ b/library/DFContext_C.cpp @@ -240,7 +240,7 @@ DFHackObject* Context_getWindow(DFHackObject* context) { if(context != NULL) { - return (DFHackObject*)((DFHack::Context*)context)->getWindow(); + return (DFHackObject*)((DFHack::Context*)context)->getWindowIO(); } return NULL; diff --git a/library/include/DFHack.h b/library/include/DFHack.h index a5f40e896..3ccaf0b83 100644 --- a/library/include/DFHack.h +++ b/library/include/DFHack.h @@ -1,6 +1,16 @@ #ifndef DFHACK_API_H #define DFHACK_API_H +// Defines +#ifdef __GNUC__ +#define DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED(func) __declspec(deprecated) func +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED(func) func +#endif + // DFHack core classes and types #include "dfhack/DFIntegers.h" #include "dfhack/DFGlobal.h" diff --git a/library/include/dfhack/DFContext.h b/library/include/dfhack/DFContext.h index 04acc52d8..9c092cc38 100644 --- a/library/include/dfhack/DFContext.h +++ b/library/include/dfhack/DFContext.h @@ -113,7 +113,7 @@ namespace DFHack Constructions * getConstructions(); /// get the Window management and I/O module - WindowIO * getWindow(); + WindowIO * getWindowIO(); // DEAD CODE, WAITING TO BE UPDATED TO DF2010 /* diff --git a/library/include/dfhack/DFModule.h b/library/include/dfhack/DFModule.h new file mode 100644 index 000000000..95f8877a0 --- /dev/null +++ b/library/include/dfhack/DFModule.h @@ -0,0 +1,45 @@ + +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef MODULE_H_INCLUDED +#define MODULE_H_INCLUDED + +#include "DFExport.h" +namespace DFHack +{ + class Context; + class DFHACK_EXPORT Module + { + public: + ~Module(){}; + virtual bool Start(){return true;};// default start... + virtual bool Finish() = 0;// everything should have a Finish() + virtual bool doFinishOnResume(){return true;}; // should Context call Finish when Resume is called? + virtual bool doFinishOnMapChange(){return false;}; // Finish when map change is detected? + virtual bool doFinishOnDetach(){return false;}; // Finish in Context::Detach? + }; +} +#endif //MODULE_H_INCLUDED + diff --git a/library/include/dfhack/modules/Buildings.h b/library/include/dfhack/modules/Buildings.h index 4f8332ac6..f16f03953 100644 --- a/library/include/dfhack/modules/Buildings.h +++ b/library/include/dfhack/modules/Buildings.h @@ -4,6 +4,7 @@ * Buildings - also includes zones and stockpiles */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { struct t_building @@ -26,7 +27,7 @@ namespace DFHack }; class DFContextShared; - class DFHACK_EXPORT Buildings + class DFHACK_EXPORT Buildings : public Module { public: Buildings(DFContextShared * d); diff --git a/library/include/dfhack/modules/Constructions.h b/library/include/dfhack/modules/Constructions.h index e4f029591..76384fc7b 100644 --- a/library/include/dfhack/modules/Constructions.h +++ b/library/include/dfhack/modules/Constructions.h @@ -4,6 +4,7 @@ * DF constructions */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { // type of item the construction is made of @@ -40,7 +41,7 @@ namespace DFHack }; #pragma pack (pop) class DFContextShared; - class DFHACK_EXPORT Constructions + class DFHACK_EXPORT Constructions : public Module { public: Constructions(DFContextShared * d); diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h index 93a8fe23d..1ba4d36af 100644 --- a/library/include/dfhack/modules/Creatures.h +++ b/library/include/dfhack/modules/Creatures.h @@ -4,397 +4,398 @@ * Creatures */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { - /* - bits: - - 0 Can the dwarf move or are they waiting for their movement timer - 1 Dead (might also be set for incoming/leaving critters that are alive) - 2 Currently in mood - 3 Had a mood - 4 "marauder" -- wide class of invader/inside creature attackers - 5 Drowning - 6 Active merchant - 7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly) - 8 Left (left the map) - 9 Rider - 10 Incoming - 11 Diplomat - 12 Zombie - 13 Skeleton - 14 Can swap tiles during movement (prevents multiple swaps) - 15 On the ground (can be conscious) - 16 Projectile - 17 Active invader (for organized ones) - 18 Hidden in ambush - 19 Invader origin (could be inactive and fleeing) - 20 Will flee if invasion turns around - 21 Active marauder/invader moving inward - 22 Marauder resident/invader moving in all the way - 23 Check against flows next time you get a chance - 24 Ridden - 25 Caged - 26 Tame - 27 Chained - 28 Royal guard - 29 Fortress guard - 30 Suppress wield for beatings/etc - 31 Is an important historical figure - */ - - struct naked_creaturflags1 - { - unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer - unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive - unsigned int has_mood : 1; // Currently in mood - unsigned int had_mood : 1; // Had a mood - - unsigned int marauder : 1; // wide class of invader/inside creature attackers - unsigned int drowning : 1; - unsigned int merchant : 1; // active merchant - unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly - - unsigned int left : 1; // left the map - unsigned int rider : 1; - unsigned int incoming : 1; - unsigned int diplomat : 1; - - unsigned int zombie : 1; - unsigned int skeleton : 1; - unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps) - unsigned int on_ground : 1; // can be conscious - - unsigned int projectile : 1; - unsigned int active_invader : 1; // for organized ones - unsigned int hidden_in_ambush : 1; - unsigned int invader_origin : 1; // could be inactive and fleeing - - unsigned int coward : 1; // Will flee if invasion turns around - unsigned int hidden_ambusher : 1; // maybe - unsigned int invades : 1; // Active marauder/invader moving inward - unsigned int check_flows : 1; // Check against flows next time you get a chance - - // 0100 0000 - 8000 0000 - unsigned int ridden : 1; - unsigned int caged : 1; - unsigned int tame : 1; - unsigned int chained : 1; - - unsigned int royal_guard : 1; - unsigned int fortress_guard : 1; - unsigned int suppress_wield : 1; // Suppress wield for beatings/etc - unsigned int important_historical_figure : 1; // Is an important historical figure - }; - - union t_creaturflags1 - { - uint32_t whole; - naked_creaturflags1 bits; - }; - - /* - bits: - - 0 Swimming - 1 Play combat for sparring - 2 Do not notify about level gains (for embark etc) - 3 Unused - - 4 Nerves calculated - 5 Body part info calculated - 6 Is important historical figure (slight variation) - 7 Has been killed by kill function (slightly different from dead, not necessarily violent death) - - 8 Must be forgotten by forget function (just cleanup) - 9 Must be deleted (cleanup) - 10 Recently forgotten (cleanup) - 11 Offered for trade - - 12 Trade resolved - 13 Has breaks - 14 Gutted - 15 Circulatory spray - - 16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was) - 17 Marked for slaughter - 18 Underworld creature - 19 Current resident - - 20 Marked for special cleanup as unused load from unit block on disk - 21 Insulation from clothing calculated - 22 Uninvited guest - 23 Visitor - - 24 Inventory order calculated - 25 Vision -- have good part - 26 Vision -- have damaged part - 27 Vision -- have missing part - - 28 Breathing -- have good part - 29 Breathing -- having a problem - 30 Roaming wilderness population source - 31 Roaming wilderness population source -- not a map feature - */ - struct naked_creaturflags2 - { - unsigned int swimming : 1; - unsigned int sparring : 1; - unsigned int no_notify : 1; // Do not notify about level gains (for embark etc) - unsigned int unused : 1; - - unsigned int calculated_nerves : 1; - unsigned int calculated_bodyparts : 1; - unsigned int important_historical_figure : 1; // slight variation - unsigned int killed : 1; // killed by kill() function - - unsigned int cleanup_1 : 1; // Must be forgotten by forget function (just cleanup) - unsigned int cleanup_2 : 1; // Must be deleted (cleanup) - unsigned int cleanup_3 : 1; // Recently forgotten (cleanup) - unsigned int for_trade : 1; // Offered for trade - - unsigned int trade_resolved : 1; - unsigned int has_breaks : 1; - unsigned int gutted : 1; - unsigned int circulatory_spray : 1; - - unsigned int locked_in_for_trading : 1; - unsigned int slaughter : 1; // marked for slaughter - unsigned int underworld : 1; // Underworld creature - unsigned int resident : 1; // Current resident - - unsigned int cleanup_4 : 1; // Marked for special cleanup as unused load from unit block on disk - unsigned int calculated_insulation : 1; // Insulation from clothing calculated - unsigned int visitor_uninvited : 1; // Uninvited guest - unsigned int visitor : 1; // visitor - - unsigned int calculated_inventory : 1; // Inventory order calculated - unsigned int vision_good : 1; // Vision -- have good part - unsigned int vision_damaged : 1; // Vision -- have damaged part - unsigned int vision_missing : 1; // Vision -- have missing part - - unsigned int breathing_good : 1; // Breathing -- have good part - unsigned int breathing_problem : 1; // Breathing -- having a problem - unsigned int roaming_wilderness_population_source : 1; - unsigned int roaming_wilderness_population_source_not_a_map_feature : 1; - }; - - union t_creaturflags2 - { - uint32_t whole; - naked_creaturflags2 bits; - }; - - /* - struct t_labor - { - string name; - uint8_t value; - t_labor() { - value =0; - } - t_labor(const t_labor & b){ - name=b.name; - value=b.value; - } - t_labor & operator=(const t_labor &b){ - name=b.name; - value=b.value; - return *this; - } - }; - struct t_skill - { - string name; - uint16_t id; - uint32_t experience; - uint16_t rating; - t_skill(){ - id=rating=0; - experience=0; - } - t_skill(const t_skill & b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - } - t_skill & operator=(const t_skill &b) - { - name=b.name; - id=b.id; - experience=b.experience; - rating=b.rating; - return *this; - } - }; - - struct t_trait - { - uint16_t value; - string displayTxt; - string name; - t_trait(){ - value=0; - } - t_trait(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - } - t_trait & operator=(const t_trait &b) - { - name=b.name; - displayTxt=b.displayTxt; - value=b.value; - return *this; - } - }; - */ - - struct t_skill - { - uint32_t id; - uint32_t rating; - uint32_t experience; - }; - struct t_job - { - bool active; - uint32_t jobId; - uint8_t jobType; - uint32_t occupationPtr; - }; - struct t_like - { - int16_t type; - int16_t itemClass; - int16_t itemIndex; - t_matglossPair material; - bool active; - }; - - - // FIXME: define in Memory.xml instead? -#define NUM_CREATURE_TRAITS 30 -#define NUM_CREATURE_LABORS 102 -#define NUM_CREATURE_MENTAL_ATTRIBUTES 13 -#define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6 - - struct t_soul - { - uint8_t numSkills; - t_skill skills[256]; - /* - uint8_t numLikes; - t_like likes[32]; - */ - uint16_t traits[NUM_CREATURE_TRAITS]; - t_attrib analytical_ability; - t_attrib focus; - t_attrib willpower; - t_attrib creativity; - t_attrib intuition; - t_attrib patience; - t_attrib memory; - t_attrib linguistic_ability; - t_attrib spatial_sense; - t_attrib musicality; - t_attrib kinesthetic_sense; - t_attrib empathy; - t_attrib social_awareness; - }; - -#define MAX_COLORS 15 - - struct t_creature - { - uint32_t origin; - uint16_t x; - uint16_t y; - uint16_t z; - uint32_t race; - int32_t civ; - - t_creaturflags1 flags1; - t_creaturflags2 flags2; - - t_name name; - - int16_t mood; - int16_t mood_skill; - t_name artifact_name; - - uint8_t profession; - char custom_profession[128]; - - // enabled labors - uint8_t labors[NUM_CREATURE_LABORS]; - t_job current_job; - - uint32_t happiness; - uint32_t id; - t_attrib strength; - t_attrib agility; - t_attrib toughness; - t_attrib endurance; - t_attrib recuperation; - t_attrib disease_resistance; - int32_t squad_leader_id; - uint8_t sex; - uint16_t caste; - uint32_t pregnancy_timer; //Countdown timer to giving birth - bool has_default_soul; - t_soul defaultSoul; - uint32_t nbcolors; - uint32_t color[MAX_COLORS]; - - uint32_t birth_year; - uint32_t birth_time; - }; - - class DFContextShared; - struct t_creature; - class DFHACK_EXPORT Creatures - { - public: - Creatures(DFHack::DFContextShared * d); - ~Creatures(); - bool Start( uint32_t & numCreatures); - bool Finish(); - - /* Read Functions */ - // Read creatures in a box, starting with index. Returns -1 if no more creatures - // found. Call repeatedly do get all creatures in a specified box (uses tile coords) - int32_t ReadCreatureInBox(const int32_t index, t_creature & furball, - const uint16_t x1, const uint16_t y1,const uint16_t z1, - const uint16_t x2, const uint16_t y2,const uint16_t z2); - bool ReadCreature(const int32_t index, t_creature & furball); - bool ReadJob(const t_creature * furball, std::vector & mat); - - /* Getters */ - uint32_t GetDwarfRaceIndex ( void ); - int32_t GetDwarfCivId ( void ); - - /* Write Functions */ - // write labors of a creature (for Dwarf Therapist) - bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); - bool WriteHappiness(const uint32_t index, const uint32_t happinessValue); - bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2); - bool WriteSkills(const uint32_t index, const t_soul &soul); - bool WriteAttributes(const uint32_t index, const t_creature &creature); - bool WriteSex(const uint32_t index, const uint8_t sex); - bool WriteTraits(const uint32_t index, const t_soul &soul); - bool WriteMood(const uint32_t index, const uint16_t mood); - bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill); - bool WritePos(const uint32_t index, const t_creature &creature); - bool WriteCiv(const uint32_t index, const int32_t civ); - - private: - struct Private; - Private *d; - }; + /* + bits: + + 0 Can the dwarf move or are they waiting for their movement timer + 1 Dead (might also be set for incoming/leaving critters that are alive) + 2 Currently in mood + 3 Had a mood + 4 "marauder" -- wide class of invader/inside creature attackers + 5 Drowning + 6 Active merchant + 7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly) + 8 Left (left the map) + 9 Rider + 10 Incoming + 11 Diplomat + 12 Zombie + 13 Skeleton + 14 Can swap tiles during movement (prevents multiple swaps) + 15 On the ground (can be conscious) + 16 Projectile + 17 Active invader (for organized ones) + 18 Hidden in ambush + 19 Invader origin (could be inactive and fleeing) + 20 Will flee if invasion turns around + 21 Active marauder/invader moving inward + 22 Marauder resident/invader moving in all the way + 23 Check against flows next time you get a chance + 24 Ridden + 25 Caged + 26 Tame + 27 Chained + 28 Royal guard + 29 Fortress guard + 30 Suppress wield for beatings/etc + 31 Is an important historical figure + */ + + struct naked_creaturflags1 + { + unsigned int move_state : 1; // Can the dwarf move or are they waiting for their movement timer + unsigned int dead : 1; // might also be set for incoming/leaving critters that are alive + unsigned int has_mood : 1; // Currently in mood + unsigned int had_mood : 1; // Had a mood + + unsigned int marauder : 1; // wide class of invader/inside creature attackers + unsigned int drowning : 1; + unsigned int merchant : 1; // active merchant + unsigned int forest : 1; // used for units no longer linked to merchant/diplomacy, they just try to leave mostly + + unsigned int left : 1; // left the map + unsigned int rider : 1; + unsigned int incoming : 1; + unsigned int diplomat : 1; + + unsigned int zombie : 1; + unsigned int skeleton : 1; + unsigned int can_swap : 1; // Can swap tiles during movement (prevents multiple swaps) + unsigned int on_ground : 1; // can be conscious + + unsigned int projectile : 1; + unsigned int active_invader : 1; // for organized ones + unsigned int hidden_in_ambush : 1; + unsigned int invader_origin : 1; // could be inactive and fleeing + + unsigned int coward : 1; // Will flee if invasion turns around + unsigned int hidden_ambusher : 1; // maybe + unsigned int invades : 1; // Active marauder/invader moving inward + unsigned int check_flows : 1; // Check against flows next time you get a chance + + // 0100 0000 - 8000 0000 + unsigned int ridden : 1; + unsigned int caged : 1; + unsigned int tame : 1; + unsigned int chained : 1; + + unsigned int royal_guard : 1; + unsigned int fortress_guard : 1; + unsigned int suppress_wield : 1; // Suppress wield for beatings/etc + unsigned int important_historical_figure : 1; // Is an important historical figure + }; + + union t_creaturflags1 + { + uint32_t whole; + naked_creaturflags1 bits; + }; + + /* + bits: + + 0 Swimming + 1 Play combat for sparring + 2 Do not notify about level gains (for embark etc) + 3 Unused + + 4 Nerves calculated + 5 Body part info calculated + 6 Is important historical figure (slight variation) + 7 Has been killed by kill function (slightly different from dead, not necessarily violent death) + + 8 Must be forgotten by forget function (just cleanup) + 9 Must be deleted (cleanup) + 10 Recently forgotten (cleanup) + 11 Offered for trade + + 12 Trade resolved + 13 Has breaks + 14 Gutted + 15 Circulatory spray + + 16 Locked in for trading (it's a projectile on the other set of flags, might be what the flying was) + 17 Marked for slaughter + 18 Underworld creature + 19 Current resident + + 20 Marked for special cleanup as unused load from unit block on disk + 21 Insulation from clothing calculated + 22 Uninvited guest + 23 Visitor + + 24 Inventory order calculated + 25 Vision -- have good part + 26 Vision -- have damaged part + 27 Vision -- have missing part + + 28 Breathing -- have good part + 29 Breathing -- having a problem + 30 Roaming wilderness population source + 31 Roaming wilderness population source -- not a map feature + */ + struct naked_creaturflags2 + { + unsigned int swimming : 1; + unsigned int sparring : 1; + unsigned int no_notify : 1; // Do not notify about level gains (for embark etc) + unsigned int unused : 1; + + unsigned int calculated_nerves : 1; + unsigned int calculated_bodyparts : 1; + unsigned int important_historical_figure : 1; // slight variation + unsigned int killed : 1; // killed by kill() function + + unsigned int cleanup_1 : 1; // Must be forgotten by forget function (just cleanup) + unsigned int cleanup_2 : 1; // Must be deleted (cleanup) + unsigned int cleanup_3 : 1; // Recently forgotten (cleanup) + unsigned int for_trade : 1; // Offered for trade + + unsigned int trade_resolved : 1; + unsigned int has_breaks : 1; + unsigned int gutted : 1; + unsigned int circulatory_spray : 1; + + unsigned int locked_in_for_trading : 1; + unsigned int slaughter : 1; // marked for slaughter + unsigned int underworld : 1; // Underworld creature + unsigned int resident : 1; // Current resident + + unsigned int cleanup_4 : 1; // Marked for special cleanup as unused load from unit block on disk + unsigned int calculated_insulation : 1; // Insulation from clothing calculated + unsigned int visitor_uninvited : 1; // Uninvited guest + unsigned int visitor : 1; // visitor + + unsigned int calculated_inventory : 1; // Inventory order calculated + unsigned int vision_good : 1; // Vision -- have good part + unsigned int vision_damaged : 1; // Vision -- have damaged part + unsigned int vision_missing : 1; // Vision -- have missing part + + unsigned int breathing_good : 1; // Breathing -- have good part + unsigned int breathing_problem : 1; // Breathing -- having a problem + unsigned int roaming_wilderness_population_source : 1; + unsigned int roaming_wilderness_population_source_not_a_map_feature : 1; + }; + + union t_creaturflags2 + { + uint32_t whole; + naked_creaturflags2 bits; + }; + + /* + struct t_labor + { + string name; + uint8_t value; + t_labor() { + value =0; + } + t_labor(const t_labor & b){ + name=b.name; + value=b.value; + } + t_labor & operator=(const t_labor &b){ + name=b.name; + value=b.value; + return *this; + } + }; + struct t_skill + { + string name; + uint16_t id; + uint32_t experience; + uint16_t rating; + t_skill(){ + id=rating=0; + experience=0; + } + t_skill(const t_skill & b) + { + name=b.name; + id=b.id; + experience=b.experience; + rating=b.rating; + } + t_skill & operator=(const t_skill &b) + { + name=b.name; + id=b.id; + experience=b.experience; + rating=b.rating; + return *this; + } + }; + + struct t_trait + { + uint16_t value; + string displayTxt; + string name; + t_trait(){ + value=0; + } + t_trait(const t_trait &b) + { + name=b.name; + displayTxt=b.displayTxt; + value=b.value; + } + t_trait & operator=(const t_trait &b) + { + name=b.name; + displayTxt=b.displayTxt; + value=b.value; + return *this; + } + }; + */ + + struct t_skill + { + uint32_t id; + uint32_t rating; + uint32_t experience; + }; + struct t_job + { + bool active; + uint32_t jobId; + uint8_t jobType; + uint32_t occupationPtr; + }; + struct t_like + { + int16_t type; + int16_t itemClass; + int16_t itemIndex; + t_matglossPair material; + bool active; + }; + + + // FIXME: define in Memory.xml instead? + #define NUM_CREATURE_TRAITS 30 + #define NUM_CREATURE_LABORS 102 + #define NUM_CREATURE_MENTAL_ATTRIBUTES 13 + #define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6 + + struct t_soul + { + uint8_t numSkills; + t_skill skills[256]; + /* + uint8_t numLikes; + t_like likes[32]; + */ + uint16_t traits[NUM_CREATURE_TRAITS]; + t_attrib analytical_ability; + t_attrib focus; + t_attrib willpower; + t_attrib creativity; + t_attrib intuition; + t_attrib patience; + t_attrib memory; + t_attrib linguistic_ability; + t_attrib spatial_sense; + t_attrib musicality; + t_attrib kinesthetic_sense; + t_attrib empathy; + t_attrib social_awareness; + }; + + #define MAX_COLORS 15 + + struct t_creature + { + uint32_t origin; + uint16_t x; + uint16_t y; + uint16_t z; + uint32_t race; + int32_t civ; + + t_creaturflags1 flags1; + t_creaturflags2 flags2; + + t_name name; + + int16_t mood; + int16_t mood_skill; + t_name artifact_name; + + uint8_t profession; + char custom_profession[128]; + + // enabled labors + uint8_t labors[NUM_CREATURE_LABORS]; + t_job current_job; + + uint32_t happiness; + uint32_t id; + t_attrib strength; + t_attrib agility; + t_attrib toughness; + t_attrib endurance; + t_attrib recuperation; + t_attrib disease_resistance; + int32_t squad_leader_id; + uint8_t sex; + uint16_t caste; + uint32_t pregnancy_timer; //Countdown timer to giving birth + bool has_default_soul; + t_soul defaultSoul; + uint32_t nbcolors; + uint32_t color[MAX_COLORS]; + + uint32_t birth_year; + uint32_t birth_time; + }; + + class DFContextShared; + struct t_creature; + class DFHACK_EXPORT Creatures : public Module + { + public: + Creatures(DFHack::DFContextShared * d); + ~Creatures(); + bool Start( uint32_t & numCreatures ); + bool Finish(); + + /* Read Functions */ + // Read creatures in a box, starting with index. Returns -1 if no more creatures + // found. Call repeatedly do get all creatures in a specified box (uses tile coords) + int32_t ReadCreatureInBox(const int32_t index, t_creature & furball, + const uint16_t x1, const uint16_t y1,const uint16_t z1, + const uint16_t x2, const uint16_t y2,const uint16_t z2); + bool ReadCreature(const int32_t index, t_creature & furball); + bool ReadJob(const t_creature * furball, std::vector & mat); + + /* Getters */ + uint32_t GetDwarfRaceIndex ( void ); + int32_t GetDwarfCivId ( void ); + + /* Write Functions */ + // write labors of a creature (for Dwarf Therapist) + bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); + bool WriteHappiness(const uint32_t index, const uint32_t happinessValue); + bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2); + bool WriteSkills(const uint32_t index, const t_soul &soul); + bool WriteAttributes(const uint32_t index, const t_creature &creature); + bool WriteSex(const uint32_t index, const uint8_t sex); + bool WriteTraits(const uint32_t index, const t_soul &soul); + bool WriteMood(const uint32_t index, const uint16_t mood); + bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill); + bool WritePos(const uint32_t index, const t_creature &creature); + bool WriteCiv(const uint32_t index, const int32_t civ); + + private: + struct Private; + Private *d; + }; } #endif diff --git a/library/include/dfhack/modules/Gui.h b/library/include/dfhack/modules/Gui.h index abc33cff2..0ef170d3f 100644 --- a/library/include/dfhack/modules/Gui.h +++ b/library/include/dfhack/modules/Gui.h @@ -5,12 +5,13 @@ * Gui: Query the DF's GUI state */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { class DFContextShared; struct t_viewscreen; - class DFHACK_EXPORT Gui + class DFHACK_EXPORT Gui: public Module { public: diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index 90db2bbf6..9b2dba8fe 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -4,89 +4,39 @@ * Creatures */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { class Context; class DFContextShared; - -enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT}; - -/* this is used to store data about the way accessors work */ -class DFHACK_EXPORT Accessor -{ -private: - accessor_type type; - int32_t constant; - uint32_t offset1; - uint32_t offset2; - Process * p; - uint32_t dataWidth; -public: - Accessor(uint32_t function, Process * p); - Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p); - int32_t getValue(uint32_t objectPtr); - bool isConstant(); -}; - struct t_item { - t_material matdesc; - int32_t quantity; - int32_t quality; + t_material matdesc; + int32_t quantity; + int32_t quality; }; struct t_improvement { - t_material matdesc; - int32_t quality; -}; - -class DFHACK_EXPORT ItemImprovementDesc -{ -private: - Accessor * AType; - Process * p; -public: - ItemImprovementDesc(uint32_t VTable, Process * p); - bool getImprovement(uint32_t descptr, t_improvement & imp); - uint32_t vtable; - uint32_t maintype; -}; - -class DFHACK_EXPORT ItemDesc -{ -private: - Accessor * AMainType; - Accessor * ASubType; - Accessor * ASubIndex; - Accessor * AIndex; - Accessor * AQuality; - Process * p; - bool hasDecoration; -public: - ItemDesc(uint32_t VTable, Process * p); - bool getItem(uint32_t itemptr, t_item & item); - std::string className; - uint32_t vtable; - uint32_t mainType; - std::vector improvement; + t_material matdesc; + int32_t quality; }; -class DFHACK_EXPORT Items +class DFHACK_EXPORT Items : public Module { public: - Items(DFContextShared * _d); - ~Items(); - std::string getItemDescription(uint32_t itemptr, Materials * Materials); - std::string getItemClass(int32_t index); - bool getItemData(uint32_t itemptr, t_item & item); + Items(DFContextShared * _d); + ~Items(); + bool Start(); + bool Finish(); + std::string getItemDescription(uint32_t itemptr, Materials * Materials); + std::string getItemClass(int32_t index); + bool getItemData(uint32_t itemptr, t_item & item); private: - class Private; - Private* d; - std::map descType; - std::map descVTable; + class Private; + Private* d; }; } #endif diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index 6c4dd63a3..d1957c6b8 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -6,6 +6,7 @@ #define CL_MOD_MAPS #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { /*************************************************************************** @@ -304,10 +305,10 @@ namespace DFHack /*************************************************************************** C L I E N T M O D U L E ***************************************************************************/ - + #ifndef BUILD_SHM class DFContextShared; struct t_viewscreen; - class DFHACK_EXPORT Maps + class DFHACK_EXPORT Maps : public Module { public: @@ -422,5 +423,6 @@ namespace DFHack struct Private; Private *d; }; + #endif } #endif diff --git a/library/include/dfhack/modules/Materials.h b/library/include/dfhack/modules/Materials.h index 4cec9cecc..aac990751 100644 --- a/library/include/dfhack/modules/Materials.h +++ b/library/include/dfhack/modules/Materials.h @@ -1,13 +1,14 @@ #ifndef CL_MOD_MATERIALS #define CL_MOD_MATERIALS /* -* Creatures -*/ + * Materials + */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { class DFContextShared; - + struct t_matgloss { char id[128]; //the id in the raws @@ -53,7 +54,7 @@ namespace DFHack uint32_t startdate; /* in days */ uint32_t enddate; /* in days */ }; - + struct t_creaturecaste { char rawname[128]; @@ -115,12 +116,13 @@ namespace DFHack int32_t index; uint32_t flags; }; - - class DFHACK_EXPORT Materials + + class DFHACK_EXPORT Materials : public Module { public: Materials(DFHack::DFContextShared * _d); ~Materials(); + bool Finish(); std::vector inorganic; std::vector organic; diff --git a/library/include/dfhack/modules/Position.h b/library/include/dfhack/modules/Position.h index b70387e66..06fc23336 100644 --- a/library/include/dfhack/modules/Position.h +++ b/library/include/dfhack/modules/Position.h @@ -4,6 +4,7 @@ * View position and size and cursor position */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { #define NUM_HOTKEYS 16 @@ -15,33 +16,34 @@ namespace DFHack int32_t y; int32_t z; }; - + class DFContextShared; - class DFHACK_EXPORT Position + class DFHACK_EXPORT Position : public Module { public: - + Position(DFContextShared * d); ~Position(); + bool Finish(){return true;}; /* * Cursor and window coords */ bool getViewCoords (int32_t &x, int32_t &y, int32_t &z); bool setViewCoords (const int32_t x, const int32_t y, const int32_t z); - + bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z); bool setCursorCoords (const int32_t x, const int32_t y, const int32_t z); - + /* * Hotkeys (DF's zoom locations) */ bool ReadHotkeys(t_hotkey hotkeys[]); - + /* * Window size in tiles */ bool getWindowSize(int32_t & width, int32_t & height); - + private: struct Private; Private *d; diff --git a/library/include/dfhack/modules/Translation.h b/library/include/dfhack/modules/Translation.h index a7e186990..5b562bc77 100644 --- a/library/include/dfhack/modules/Translation.h +++ b/library/include/dfhack/modules/Translation.h @@ -4,6 +4,7 @@ * DF translation tables and name translation */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { class DFContextShared; @@ -13,8 +14,8 @@ namespace DFHack DFDict translations; DFDict foreign_languages; } Dicts; - - class DFHACK_EXPORT Translation + + class DFHACK_EXPORT Translation : public Module { public: Translation(DFContextShared * d); @@ -26,7 +27,7 @@ namespace DFHack Dicts * getDicts(); // translate a name using the loaded dictionaries std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true); - + private: struct Private; Private *d; diff --git a/library/include/dfhack/modules/Vegetation.h b/library/include/dfhack/modules/Vegetation.h index b81bb81c1..9ab390e7f 100644 --- a/library/include/dfhack/modules/Vegetation.h +++ b/library/include/dfhack/modules/Vegetation.h @@ -4,6 +4,7 @@ * DF vegetation - stuff that grows and gets cut down or trampled by dwarves */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { /* @@ -28,7 +29,7 @@ namespace DFHack }; class DFContextShared; - class DFHACK_EXPORT Vegetation + class DFHACK_EXPORT Vegetation : public Module { public: Vegetation(DFContextShared * d); diff --git a/library/include/dfhack/modules/WindowIO.h b/library/include/dfhack/modules/WindowIO.h index 146029ca0..6e1af9fcb 100644 --- a/library/include/dfhack/modules/WindowIO.h +++ b/library/include/dfhack/modules/WindowIO.h @@ -27,6 +27,7 @@ distribution. #include "dfhack/DFPragma.h" #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { @@ -88,12 +89,13 @@ enum t_special NUM_SPECIALS }; class DFContextShared; -class DFHACK_EXPORT WindowIO +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); diff --git a/library/include/dfhack/modules/World.h b/library/include/dfhack/modules/World.h index 21300bfd5..fdb08baf7 100644 --- a/library/include/dfhack/modules/World.h +++ b/library/include/dfhack/modules/World.h @@ -5,11 +5,12 @@ * World: all kind of stuff related to the current world state */ #include "dfhack/DFExport.h" +#include "dfhack/DFModule.h" namespace DFHack { class DFContextShared; - class DFHACK_EXPORT World + class DFHACK_EXPORT World : public Module { public: diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 66e2720ac..2419bbf40 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -33,235 +33,294 @@ distribution. using namespace DFHack; -class Items::Private +enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT}; + +/* this is used to store data about the way accessors work */ +class DFHACK_EXPORT Accessor { - public: - DFContextShared *d; - Process * owner; - /* - bool Inited; - bool Started; - */ +private: + accessor_type type; + int32_t constant; + uint32_t offset1; + uint32_t offset2; + Process * p; + uint32_t dataWidth; +public: + Accessor(uint32_t function, Process * p); + Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p); + int32_t getValue(uint32_t objectPtr); + bool isConstant(); }; - -Items::Items(DFContextShared * d_) +class DFHACK_EXPORT ItemImprovementDesc { - d = new Private; - d->d = d_; - d->owner = d_->p; -} -Items::~Items() +private: + Accessor * AType; + Process * p; +public: + ItemImprovementDesc(uint32_t VTable, Process * p); + bool getImprovement(uint32_t descptr, t_improvement & imp); + uint32_t vtable; + uint32_t maintype; +}; + +class DFHACK_EXPORT ItemDesc { - delete d; - /* TODO : delete all item descs */ -} +private: + Accessor * AMainType; + Accessor * ASubType; + Accessor * ASubIndex; + Accessor * AIndex; + Accessor * AQuality; + Process * p; + bool hasDecoration; +public: + ItemDesc(uint32_t VTable, Process * p); + bool getItem(uint32_t itemptr, t_item & item); + std::string className; + uint32_t vtable; + uint32_t mainType; + std::vector improvement; +}; + +// FIXME: this is crazy Accessor::Accessor(uint32_t function, Process *p) { - this->p = p; - this->constant = 0; - this->offset1 = 0; - this->offset2 = 0; - this->type = ACCESSOR_CONSTANT; - this->dataWidth = 2; - uint64_t funcText = p->readQuad(function); - if( funcText == 0xCCCCCCCCCCC3C033LL ) - { - return; - } - if( funcText == 0xCCCCCCCCC3FFC883LL ) - { - /* or eax,-1; ret; */ - this->constant = -1; - return; - } - if( (funcText&0xFFFFFFFFFF0000FFLL) == 0xCCCCC300000000B8LL ) - { - /* mov eax, xx; ret; */ - this->constant = (funcText>>8) & 0xffff; - return; - } - if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL ) - { - /* mov ax, [ecx+xx]; ret; */ - this->type = ACCESSOR_INDIRECT; - this->offset1 = (funcText>>24) & 0xffff; - return; - } - if( (funcText&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL ) - { - uint64_t funcText2 = p->readQuad(function+8); - if( (funcText2&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL ) + this->p = p; + this->constant = 0; + this->offset1 = 0; + this->offset2 = 0; + this->type = ACCESSOR_CONSTANT; + this->dataWidth = 2; + uint64_t funcText = p->readQuad(function); + if( funcText == 0xCCCCCCCCCCC3C033LL ) + { + return; + } + if( funcText == 0xCCCCCCCCC3FFC883LL ) + { + /* or eax,-1; ret; */ + this->constant = -1; + return; + } + if( (funcText&0xFFFFFFFFFF0000FFLL) == 0xCCCCC300000000B8LL ) + { + /* mov eax, xx; ret; */ + this->constant = (funcText>>8) & 0xffff; + return; + } + if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL ) + { + /* mov ax, [ecx+xx]; ret; */ + this->type = ACCESSOR_INDIRECT; + this->offset1 = (funcText>>24) & 0xffff; + return; + } + if( (funcText&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL ) + { + uint64_t funcText2 = p->readQuad(function+8); + if( (funcText2&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL ) { - this->type = ACCESSOR_DOUBLE_INDIRECT; - this->offset1 = (funcText>>16) & 0xffff; - this->offset2 = (funcText2>>8) & 0xff; - return; - } - } - if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC30000000081BF0FLL ) - { - /* movsx eax, word ptr [ecx+xx]; ret */ - this->type = ACCESSOR_INDIRECT; - this->offset1 = (funcText>>24) & 0xffff; - return; - } - if( (funcText&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL ) - { - /* mov eax, [ecx+xx]; ret; */ - this->type = ACCESSOR_INDIRECT; - this->offset1 = (funcText>>16) & 0xffff; - this->dataWidth = 4; - return; - } - printf("bad accessor @0x%x\n", function); + this->type = ACCESSOR_DOUBLE_INDIRECT; + this->offset1 = (funcText>>16) & 0xffff; + this->offset2 = (funcText2>>8) & 0xff; + return; + } + } + if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC30000000081BF0FLL ) + { + /* movsx eax, word ptr [ecx+xx]; ret */ + this->type = ACCESSOR_INDIRECT; + this->offset1 = (funcText>>24) & 0xffff; + return; + } + if( (funcText&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL ) + { + /* mov eax, [ecx+xx]; ret; */ + this->type = ACCESSOR_INDIRECT; + this->offset1 = (funcText>>16) & 0xffff; + this->dataWidth = 4; + return; + } + printf("bad accessor @0x%x\n", function); } bool Accessor::isConstant() { - if(this->type == ACCESSOR_CONSTANT) - return true; - else - return false; + if(this->type == ACCESSOR_CONSTANT) + return true; + else + return false; } int32_t Accessor::getValue(uint32_t objectPtr) { - switch(this->type) - { - case ACCESSOR_CONSTANT: - return this->constant; - break; - case ACCESSOR_INDIRECT: - switch(this->dataWidth) - { - case 2: - return (int16_t) p->readWord(objectPtr + this->offset1); - case 4: - return p->readDWord(objectPtr + this->offset1); - default: - return -1; - } - break; - case ACCESSOR_DOUBLE_INDIRECT: - switch(this->dataWidth) - { - case 2: - return (int16_t) p->readWord(p->readDWord(objectPtr + this->offset1) + this->offset2); - case 4: - return p->readDWord(p->readDWord(objectPtr + this->offset1) + this->offset2); - default: - return -1; - } - break; - default: - return -1; - } + switch(this->type) + { + case ACCESSOR_CONSTANT: + return this->constant; + break; + case ACCESSOR_INDIRECT: + switch(this->dataWidth) + { + case 2: + return (int16_t) p->readWord(objectPtr + this->offset1); + case 4: + return p->readDWord(objectPtr + this->offset1); + default: + return -1; + } + break; + case ACCESSOR_DOUBLE_INDIRECT: + switch(this->dataWidth) + { + case 2: + return (int16_t) p->readWord(p->readDWord(objectPtr + this->offset1) + this->offset2); + case 4: + return p->readDWord(p->readDWord(objectPtr + this->offset1) + this->offset2); + default: + return -1; + } + break; + default: + return -1; + } } ItemDesc::ItemDesc(uint32_t VTable, Process *p) { - uint32_t funcOffsetA = p->getDescriptor()->getOffset("item_type_accessor"); - uint32_t funcOffsetB = p->getDescriptor()->getOffset("item_subtype_accessor"); - uint32_t funcOffsetC = p->getDescriptor()->getOffset("item_subindex_accessor"); - uint32_t funcOffsetD = p->getDescriptor()->getOffset("item_index_accessor"); - uint32_t funcOffsetQuality = p->getDescriptor()->getOffset("item_quality_accessor"); - this->vtable = VTable; - this->p = p; - this->className = p->readClassName(VTable).substr(5); - this->className.resize(this->className.size()-2); - this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p); - this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p); - this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p); - this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p); - this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p); - this->hasDecoration = false; - if(this->AMainType->isConstant()) - this->mainType = this->AMainType->getValue(0); - else - { - fprintf(stderr, "Bad item main type at function %p\n", (void*) p->readDWord( VTable + funcOffsetA )); - this->mainType = 0; - } + uint32_t funcOffsetA = p->getDescriptor()->getOffset("item_type_accessor"); + uint32_t funcOffsetB = p->getDescriptor()->getOffset("item_subtype_accessor"); + uint32_t funcOffsetC = p->getDescriptor()->getOffset("item_subindex_accessor"); + uint32_t funcOffsetD = p->getDescriptor()->getOffset("item_index_accessor"); + uint32_t funcOffsetQuality = p->getDescriptor()->getOffset("item_quality_accessor"); + this->vtable = VTable; + this->p = p; + this->className = p->readClassName(VTable).substr(5); + this->className.resize(this->className.size()-2); + this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p); + this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p); + this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p); + this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p); + this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p); + this->hasDecoration = false; + if(this->AMainType->isConstant()) + this->mainType = this->AMainType->getValue(0); + else + { + fprintf(stderr, "Bad item main type at function %p\n", (void*) p->readDWord( VTable + funcOffsetA )); + this->mainType = 0; + } } bool ItemDesc::getItem(uint32_t itemptr, DFHack::t_item &item) { - item.matdesc.itemType = this->AMainType->getValue(itemptr); - item.matdesc.subType = this->ASubType->getValue(itemptr); - item.matdesc.subIndex = this->ASubIndex->getValue(itemptr); - item.matdesc.index = this->AIndex->getValue(itemptr); - item.quality = this->AQuality->getValue(itemptr); - item.quantity = 1; /* TODO */ - return true; + item.matdesc.itemType = this->AMainType->getValue(itemptr); + item.matdesc.subType = this->ASubType->getValue(itemptr); + item.matdesc.subIndex = this->ASubIndex->getValue(itemptr); + item.matdesc.index = this->AIndex->getValue(itemptr); + item.quality = this->AQuality->getValue(itemptr); + item.quantity = 1; /* TODO */ + return true; +} + +class Items::Private +{ + public: + DFContextShared *d; + Process * owner; + std::map descType; + std::map descVTable; +}; + +Items::Items(DFContextShared * d_) +{ + d = new Private; + d->d = d_; + d->owner = d_->p; +} +bool Items::Start(){return true;} +bool Items::Finish(){return true;} +Items::~Items() +{ + Finish(); + std::map::iterator it; + it = d->descVTable.begin(); + while (it != d->descVTable.end()) + { + delete (*it).second; + } + d->descType.clear(); + d->descVTable.clear(); + delete d; } bool Items::getItemData(uint32_t itemptr, DFHack::t_item &item) { - std::map::iterator it; - Process * p = d->owner; - ItemDesc * desc; + std::map::iterator it; + Process * p = d->owner; + ItemDesc * desc; - it = this->descVTable.find(itemptr); - if(it==descVTable.end()) - { - uint32_t vtable = p->readDWord(itemptr); - desc = new ItemDesc(vtable, p); - this->descVTable[vtable] = desc; - this->descType[desc->mainType] = desc; - } - else - desc = it->second; + it = d->descVTable.find(itemptr); + if(it==d->descVTable.end()) + { + uint32_t vtable = p->readDWord(itemptr); + desc = new ItemDesc(vtable, p); + d->descVTable[vtable] = desc; + d->descType[desc->mainType] = desc; + } + else + desc = it->second; - return desc->getItem(itemptr, item); + return desc->getItem(itemptr, item); } std::string Items::getItemClass(int32_t index) { - std::map::iterator it; - std::string out; + std::map::iterator it; + std::string out; - it = this->descType.find(index); - if(it==this->descType.end()) - { - /* these are dummy values for mood decoding */ - switch(index) - { - case 0: return "bar"; - case 1: return "cut gem"; - case 2: return "block"; - case 3: return "raw gem"; - case 4: return "raw stone"; - case 5: return "log"; - case 54: return "leather"; - case 57: return "cloth"; - case -1: return "probably bone or shell, but I really don't know"; - default: return "unknown"; - } - } - out = it->second->className; - return out; + it = d->descType.find(index); + if(it==d->descType.end()) + { + /* these are dummy values for mood decoding */ + switch(index) + { + case 0: return "bar"; + case 1: return "cut gem"; + case 2: return "block"; + case 3: return "raw gem"; + case 4: return "raw stone"; + case 5: return "log"; + case 54: return "leather"; + case 57: return "cloth"; + case -1: return "probably bone or shell, but I really don't know"; + default: return "unknown"; + } + } + out = it->second->className; + return out; } std::string Items::getItemDescription(uint32_t itemptr, Materials * Materials) { - DFHack::t_item item; - std::string out; + DFHack::t_item item; + std::string out; - if(!this->getItemData(itemptr, item)) - return "??"; - switch(item.quality) - { - case 0: break; - case 1: out.append("Well crafted "); break; - case 2: out.append("Finely crafted "); break; - case 3: out.append("Superior quality "); break; - case 4: out.append("Exceptionnal "); break; - case 5: out.append("Masterful "); break; - default: out.append("Crazy quality "); break; - } - out.append(Materials->getDescription(item.matdesc)); - out.append(" "); - out.append(this->getItemClass(item.matdesc.itemType)); - return out; + if(!this->getItemData(itemptr, item)) + return "??"; + switch(item.quality) + { + case 0: break; + case 1: out.append("Well crafted "); break; + case 2: out.append("Finely crafted "); break; + case 3: out.append("Superior quality "); break; + case 4: out.append("Exceptionnal "); break; + case 5: out.append("Masterful "); break; + default: out.append("Crazy quality "); break; + } + out.append(Materials->getDescription(item.matdesc)); + out.append(" "); + out.append(this->getItemClass(item.matdesc.itemType)); + return out; } diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index b14b7f062..e7d43a2a5 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -49,15 +49,15 @@ struct Maps::Private uint32_t maps_module; Server::Maps::maps_offsets offsets; - + DFContextShared *d; Process * owner; bool Inited; bool Started; - + // map between feature address and the read object map local_feature_store; - + vector v_geology[eBiomeCount]; }; @@ -67,10 +67,10 @@ Maps::Maps(DFContextShared* _d) d->d = _d; Process *p = d->owner = _d->p; d->Inited = d->Started = false; - + DFHack::memory_info * mem = p->getDescriptor(); Server::Maps::maps_offsets &off = d->offsets; - + // get the offsets once here off.map_offset = mem->getAddress ("map_data"); off.x_count_offset = mem->getAddress ("x_count_block"); @@ -83,24 +83,23 @@ Maps::Maps(DFContextShared* _d) off.veinvector = mem->getOffset ("map_data_vein_vector"); off.local_feature_offset = mem->getOffset ("map_data_feature_local"); off.global_feature_offset = mem->getOffset ("map_data_feature_global"); - + off.temperature1_offset = mem->getOffset ("map_data_temperature1_offset"); off.temperature2_offset = mem->getOffset ("map_data_temperature2_offset"); off.region_x_offset = mem->getAddress ("region_x"); off.region_y_offset = mem->getAddress ("region_y"); off.region_z_offset = mem->getAddress ("region_z"); - - + off.world_regions = mem->getAddress ("ptr2_region_array"); off.region_size = mem->getHexValue ("region_size"); off.region_geo_index_offset = mem->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = mem->getOffset ("geolayer_geoblock_offset"); off.world_geoblocks_vector = mem->getAddress ("geoblock_vector"); off.type_inside_geolayer = mem->getOffset ("type_inside_geolayer"); - + off.world_size_x = mem->getAddress ("world_size_x"); off.world_size_y = mem->getAddress ("world_size_y"); - + // these can fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; @@ -137,15 +136,17 @@ bool Maps::Start() return false; if(d->Started) Finish(); + Process *p = d->owner; Server::Maps::maps_offsets &off = d->offsets; + // get the map pointer uint32_t x_array_loc = p->readDWord (off.map_offset); if (!x_array_loc) { return false; } - + // get the size uint32_t mx, my, mz; mx = d->x_block_count = p->readDWord (off.x_count_offset); @@ -265,7 +266,7 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer /* * Tiletypes - */ + */ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) { @@ -292,8 +293,8 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf } /* - * Dirty flags - */ + * Dirty bit + */ bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit) { @@ -326,7 +327,9 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) return false; } -/// read/write the block flags +/* + * Block flags + */ bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags) { MAPS_GUARD @@ -356,8 +359,7 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc /* * Designations - */ - + */ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) { MAPS_GUARD @@ -384,8 +386,7 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40 /* * Occupancies - */ - + */ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) { MAPS_GUARD @@ -412,7 +413,7 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b /* * Temperatures - */ + */ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) { MAPS_GUARD @@ -717,7 +718,7 @@ bool Maps::ReadLocalFeatures( std::map > & // can't be used without a map! if(!d->block) return false; - + Process * p = d->owner; memory_info * mem = p->getDescriptor(); // deref pointer to the humongo-structure @@ -729,32 +730,26 @@ bool Maps::ReadLocalFeatures( std::map > & const uint32_t offset_elem = 4; const uint32_t main_mat_offset = mem->getOffset("local_feature_mat"); // 0x30 const uint32_t sub_mat_offset = mem->getOffset("local_feature_submat"); // 0x34 - + local_features.clear(); - + for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++) { - //uint64_t block48_x = blockX / 3 + d->regionX; - //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; - - // region X coord offset by 8 big blocks (48x48 tiles) - uint16_t region_x_plus8 = ( (blockX / 3 ) + d->regionX /*+ 8*/ ) / 16; - //((BYTE4(region_x_local) & 0xF) + (_DWORD)region_x_local) >> 4; - //int16_t region_x_local = (blockX / 3) + d->regionX; - //int16_t region_x_plus8 = ((region_x_local & 0xF) + region_x_local) >> 4; - // plain region Y coord + // region X coord (48x48 tiles) + uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16; + // region Y coord (48x48 tiles) uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16; - + // this is just a few pointers to arrays of 16B (4 DWORD) structs - uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4); - + uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4); + // 16B structs, second DWORD of the struct is a pointer uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem); if(wtf) { // wtf + sizeof(vector) * crap; - uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16)); + uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16)); DfVector p_features(p, feat_vector); uint32_t size = p_features.size(); planecoord pc; @@ -764,7 +759,7 @@ bool Maps::ReadLocalFeatures( std::map > & for(uint32_t i = 0; i < size; i++) { uint32_t cur_ptr = p_features[i]; - + map ::iterator it; it = d->local_feature_store.find(cur_ptr); // do we already have the feature? @@ -816,16 +811,16 @@ bool Maps::ReadGlobalFeatures( std::vector & features) // can't be used without a map! if(!d->block) return false; - + Process * p = d->owner; memory_info * mem = p->getDescriptor(); - + uint32_t global_feature_vector = mem->getAddress("global_feature_vector"); uint32_t global_feature_funcptr = mem->getOffset("global_feature_funcptr_"); const uint32_t main_mat_offset = mem->getOffset("global_feature_mat"); // 0x34 const uint32_t sub_mat_offset = mem->getOffset("global_feature_submat"); // 0x38 DfVector p_features (p,global_feature_vector); - + features.clear(); uint32_t size = p_features.size(); features.reserve(size); @@ -836,7 +831,7 @@ bool Maps::ReadGlobalFeatures( std::vector & features) temp.origin = feat_ptr; //temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder temp.discovered = false; - + // FIXME: use the memory_info cache mechanisms string name = p->readClassName(p->readDWord( feat_ptr)); if(name == "feature_init_underworld_from_layerst") diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index c3e358b69..481d23568 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -53,6 +53,21 @@ Materials::~Materials() { delete d; } + +bool Materials::Finish() +{ + inorganic.clear(); + organic.clear(); + tree.clear(); + plant.clear(); + race.clear(); + raceEx.clear(); + color.clear(); + other.clear(); + alldesc.clear(); + return true; +} + /* { LABEL_53: @@ -401,10 +416,10 @@ void Materials::ReadAllMaterials(void) std::string Materials::getDescription(t_material & mat) { - std::string out; - int32_t typeC; + std::string out; + int32_t typeC; - if ( (mat.subIndex<419) || (mat.subIndex>618) ) + if ( (mat.subIndex<419) || (mat.subIndex>618) ) { if ( (mat.subIndex<19) || (mat.subIndex>218) ) { @@ -414,13 +429,13 @@ std::string Materials::getDescription(t_material & mat) else { if (mat.subIndex>=this->other.size()) - { - if(mat.subIndex<0) - return "any"; - if(mat.subIndex>=this->raceEx.size()) - return "stuff"; - return this->raceEx[mat.subIndex].rawname; - } + { + if(mat.subIndex<0) + return "any"; + if(mat.subIndex>=this->raceEx.size()) + return "stuff"; + return this->raceEx[mat.subIndex].rawname; + } else { if (mat.index==-1) @@ -430,17 +445,17 @@ std::string Materials::getDescription(t_material & mat) } } else - if(mat.index<0) - return "any inorganic"; - else - return this->inorganic[mat.index].id; + if(mat.index<0) + return "any inorganic"; + else + return this->inorganic[mat.index].id; } else { if (mat.index>=this->raceEx.size()) return "unknown race"; typeC = mat.subIndex; - typeC -=19; + typeC -=19; if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size())) { return string(this->raceEx[mat.index].rawname).append(" extract"); @@ -452,6 +467,6 @@ std::string Materials::getDescription(t_material & mat) { return this->organic[mat.index].id; } - return out; + return out; } diff --git a/library/private/ContextShared.h b/library/private/ContextShared.h index f3c506880..361ccc45d 100644 --- a/library/private/ContextShared.h +++ b/library/private/ContextShared.h @@ -31,20 +31,23 @@ distribution. namespace DFHack { - class Materials; + class Module; + + class Creatures; + class Maps; + class Position; class Gui; class World; - class Position; - class Maps; - class Creatures; + class Materials; class Items; class Translation; + class Vegetation; class Buildings; + class Constructions; + class WindowIO; + class ProcessEnumerator; class Process; - class WindowIO; - class Vegetation; - class Constructions; class memory_info; struct t_name; class DFContextShared @@ -52,7 +55,7 @@ namespace DFHack public: DFContextShared(); ~DFContextShared(); - + // names, used by a few other modules. void readName(t_name & name, uint32_t address); // get the name offsets @@ -61,27 +64,30 @@ namespace DFHack uint32_t name_nickname_offset; uint32_t name_words_offset; bool namesInited; - + ProcessEnumerator* pm; Process* p; char * shm_start; memory_info* offset_descriptor; string xml; - - // Modules - Creatures * creatures; - Maps * maps; - Position * position; - Gui * gui; - World * world; - Materials * materials; - Items * items; - Translation * translation; - Vegetation * vegetation; - Buildings * buildings; - Constructions * constructions; - WindowIO * windowio; + // Modules + struct + { + Creatures * pCreatures; + Maps * pMaps; + Position * pPosition; + Gui * pGui; + World * pWorld; + Materials * pMaterials; + Items * pItems; + Translation * pTranslation; + Vegetation * pVegetation; + Buildings * pBuildings; + Constructions * pConstructions; + WindowIO * pWindowIO; + } s_mods; + std::vector allModules; /* uint32_t item_material_offset; @@ -93,7 +99,7 @@ namespace DFHack 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; diff --git a/library/shm/CMakeLists.txt b/library/shm/CMakeLists.txt new file mode 100644 index 000000000..0f712cad3 --- /dev/null +++ b/library/shm/CMakeLists.txt @@ -0,0 +1,56 @@ +################################################################################ +# DFCONNECT +### +SET(DFCONNECT_HDRS +shms.h +mod-core.h +mod-maps.h +) + +SET(PROJECT_SRCS +mod-core.cpp +mod-maps.cpp +#mod-creature40d.cpp +) + +SET(PROJECT_HDRS_LINUX +) + +SET(PROJECT_HDRS_WINDOWS +) + +SET(PROJECT_SRCS_LINUX +shms-linux.cpp +) + +SET(PROJECT_SRCS_WINDOWS +shms-windows.cpp +) + +IF(UNIX) + LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_LINUX}) + LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_LINUX}) +ELSE(UNIX) + LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_WINDOWS}) + LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS}) +ENDIF(UNIX) + + +SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) + +LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) + +#IF(CMAKE_SIZEOF_VOID_P EQUAL 4) + add_definitions(-DBUILD_SHM) + IF(UNIX) + add_definitions(-DLINUX_BUILD) + SET(PROJECT_LIBS rt) + SET(CMAKE_CXX_FLAGS "-fvisibility=hidden") + ADD_LIBRARY(dfconnect SHARED ${PROJECT_SRCS}) + TARGET_LINK_LIBRARIES(dfconnect ${PROJECT_LIBS}) + ELSE(UNIX) + # SET(PROJECT_LIBS psapi) + ADD_LIBRARY(SDL SHARED ${PROJECT_SRCS}) + TARGET_LINK_LIBRARIES(SDL ${PROJECT_LIBS}) + ENDIF(UNIX) +#ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)