Merge branch 'master' of git://github.com/peterix/dfhack into peterix

develop
simon 2010-08-17 13:59:54 +02:00
commit 4254190560
200 changed files with 12982 additions and 2807 deletions

@ -0,0 +1,28 @@
#=============================================================================
# Copyright 2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
# We use MSBuild as the build tool for VS 10
FIND_PROGRAM(CMAKE_MAKE_PROGRAM
NAMES MSBuild
HINTS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;ProductDir]
"$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
"c:/WINDOWS/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
"$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0;CLR Version]/"
)
MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
SET(MSVC10 1)
SET(MSVC_VERSION 1600)

@ -2,6 +2,7 @@
PROJECT (dfhack)
cmake_minimum_required(VERSION 2.6)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
SET ( DFHACK_VERSION "0.4.1.0-dev" )
# disable warning, autosearch
if(COMMAND cmake_policy)
@ -18,6 +19,13 @@ ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)
SET( LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack library" )
SET( EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack tools" )
SET( DATA_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/output CACHE PATH "Output directory for the dfhack data (offset files)" )
OPTION(BUILD_DFHACK_DOCUMENTATION "Create doxygen documentation for developers" OFF)
OPTION(BUILD_DFHACK_EXAMPLES "Build example tools" OFF)
OPTION(BUILD_DFHACK_PLAYGROUND "Build tools from the playground folder" OFF)
OPTION(BUILD_DFHACK_C_BINDIGS "Build the C portion of the library" ON)
OPTION(BUILD_OFFSET_EDITOR "Build the Offset GUI editor (not ready for use)." OFF)
include_directories (${CMAKE_SOURCE_DIR}/library/include/)
include_directories (${CMAKE_SOURCE_DIR}/library/shm/)
@ -26,7 +34,13 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/tinyxml/)
include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/)
add_subdirectory (library)
#add_subdirectory (dfhack/python)
IF(BUILD_OFFSET_EDITOR)
add_subdirectory (offsetedit)
ENDIF(BUILD_OFFSET_EDITOR)
add_subdirectory (library/shm)
add_subdirectory (tools/examples)
add_subdirectory (tools/playground)
add_subdirectory (tools/supported)
add_subdirectory (doc)

@ -1,159 +0,0 @@
Here's how you build dfhack!
----------------------------
Dependencies
============
You'll need cmake and 'a' compiler for building the main lib and the various tools.
(Linux only) Veinlook requires the wide-character ncurses library (libncursesw)
Building on Linux:
--------------------
* To run in the output folder (without installing):
building the library is simple. Enter the build folder, run the tools. Like this:
cd build
cmake .. -DCMAKE_BUILD_TYPE:string=Release
make
This will build the library and its tools and place them in /output.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI program.
* To be installed into the system or packaged
cd build
cmake -DCMAKE_BUILD_TYPE:string=Release -DCMAKE_INSTALL_PREFIX=/usr -DMEMXML_DATA_PATH:path=/usr/share/dfhack ..
make
make install
With this dfhack installs:
library to $CMAKE_INSTALL_PREFIX/lib
executables to $CMAKE_INSTALL_PREFIX/bin
The Memory.xml file to /usr/share/dfhack
See the section on the shared memory hook library (SHM).
Building on Windows:
--------------------
You need cmake. Get the win32 installer version from the official site:
http://www.cmake.org/cmake/resources/software.html
It has the usual installer wizard thing.
* Using mingw:
You also need a compiler. I build dfhack using mingw. You can get it from the mingw site:
Get the automated installer, it will download newest version of mingw and set things up nicely.
You'll have to add C:\MinGW\ to your PATH variable.
- Building:
open up cmd and navigate to the dfhack\build folder, run cmake and the mingw version of make:
cd build
cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Release
mingw32-make
* Using MSVC
open up cmd and navigate to the dfhack\build folder, run cmake:
cd build
cmake ..
This will generate MSVC solution and project files.
Note that: you are working in the /build folder. Files added to projects will
end up there! (and that's wrong). Any changes to the build system should
be done by changing cmake configs and running cmake on them!
Alo, you'll have to copy the Memory.xml file to the build output folders
MSVC generates. For example from 'output/' to 'output/Release/'
* Using some other compiler:
I'm afraid you are on your own. dfhack wasn't tested with any other compiler.
Try using a different cmake generator that's intended for your tools.
Build targets
-------------
dfhack has a few build targets.
If you're only after the library run 'make dfhack'.
'make' will build everything.
'make expbench' will build the expbench testing program and the library.
Build types
-----------
cmake allows you to pick a build type by changing this variable: CMAKE_BUILD_TYPE
cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
Without specifying a build type or 'None', cmake uses the CMAKE_CXX_FLAGS
variable for building.
Valid an useful build types include 'Release', 'Debug' and 'RelWithDebInfo'.
There are others, but they aren't really that useful.
Have fun.
--------------------------------------------------------------------------------
**Deprecated*Deprecated*Deprecated*Deprecated*Deprecated*Deprecated*Deprecated**
--------------------------------------------------------------------------------
Building the shared memory hook library (SHM)
---------------------------------------------
Unlike the rest of DFHack, The SHM needs special treatment when it comes to
compilation. Because it shares the memory space with DF itself, it has to be
built with the same tools as DF and use the same C and C++/STL libraries.
For DF 40d15 - 40d19_2 on Windows, use MSVC 2008. You can get the Express
edition for free from Microsoft.
Windows dependencies can be determined by a tool like depends.exe (google it).
Both the fake SDL.dll and DF have to use the same version of the C runtime
(MSVCRT).
The SHM can only be debugged using a RelWithDebInfo build!
Linux dependencies can be determined by setting the LD_DEBUG variable and
running ./df:
$export LD_DEBUG=versions
$./df
Example of (a part of a) relevant output from a working SHM installation:
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libpthread.so.0 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GCC_3.0' in file ./libs/libgcc_s.so.1 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file ./libs/libgcc_s.so.1 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.1' in file /opt/lib32/lib/libm.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libm.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.1.3' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.3.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBCXX_3.4.9' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `CXXABI_1.3' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBCXX_3.4' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `CXXABI_1.3' in file ./libs/libstdc++.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBCXX_3.4' in file ./libs/libstdc++.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.1.3' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.2' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.3.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
libdfconnect is the SHM. Both are compiled against the same C++ library and
share the same CXXABI version.
Precompiled SHM libraries are provided in binary releases.
* Checking strings support
Strings are one of the important C++ types and a great indicator that the SHM
works. Tools like Dwarf Therapist depend on string support. Reading of strings
can be checked by running any of the tools that deal with materials.
String writing is best tested with a fresh throw-away fort and dfrenamer.
Embark, give one dwarf a very long name using dfrenamer and save/exit.
If DF crashes during the save sequence, your SHM is not compatible with DF and
the throw-away fort is most probably lost.

@ -0,0 +1,147 @@
################
Compiling DFHACK
################
============================
Here's how you build dfhack!
============================
.. contents::
Dependencies
============
* ``cmake``
* A compiler for building the main lib and the various tools.
* (Linux only) Veinlook requires the wide-character ncurses library (libncursesw)
* (Linux only) You'll need X11 dev libraries.
Building on Linux
=================
To run in the output folder (without installing) building the library
is simple. Enter the build folder, run the tools. Like this::
cd build
cmake .. -DCMAKE_BUILD_TYPE:string=Release
make
This will build the library and its tools and place them in ``/output``.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI
program.
To be installed into the system or packaged::
cd build
cmake -DCMAKE_BUILD_TYPE:string=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DMEMXML_DATA_PATH:path=/usr/share/dfhack ..
make
make install
With this dfhack installs:
* library to ``$CMAKE_INSTALL_PREFIX/lib``
* executables to ``$CMAKE_INSTALL_PREFIX/bin``
* The ``Memory.xml`` file to ``/usr/share/dfhack``
See the section on the shared memory hook library (SHM).
Building on Windows
===================
You need ``cmake``. Get the win32 installer version from the official
site: http://www.cmake.org/cmake/resources/software.html
It has the usual installer wizard thing.
-----------
Using mingw
-----------
You also need a compiler. I build dfhack using mingw. You can get it
from the mingw site: http://www.mingw.org/
Get the automated installer, it will download newest version of mingw
and set things up nicely.
You'll have to add ``C:\MinGW\`` to your PATH variable.
Building
--------
open up cmd and navigate to the ``dfhack\build`` folder, run ``cmake``
and the mingw version of make::
cd build
cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Release
mingw32-make
----------
Using MSVC
----------
open up ``cmd`` and navigate to the ``dfhack\build`` folder, run
``cmake``::
cd build
cmake ..
This will generate MSVC solution and project files.
.. note::
You are working in the ``/build`` folder. Files added to
projects from within MSVC will end up there! (and that's
wrong). Any changes to the build system should be done
by changing cmake configs and running ``cmake`` on them!
-------------------------
Using some other compiler
-------------------------
I'm afraid you are on your own. dfhack wasn't tested with any other
compiler.
Try using a different cmake generator that's intended for your tools.
Build targets
=============
dfhack has a few build targets:
* If you're only after the library run ``make dfhack``.
* ``make`` will build everything.
* ``make expbench`` will build the expbench testing program and the
library.
* Some of the utilities and the doxygen documentation won't be
normally built. You can enable them by specifying some extra
CMake variables::
BUILD_DFHACK_DOCUMENTATION - generate the documentation (really bad)
BUILD_DFHACK_EXAMPLES - build tools from tools/examples
BUILD_DFHACK_PLAYGROUND - build tools from tools/playground
Example::
cmake .. -DBUILD_DFHACK_EXAMPLES=ON
Build types
===========
``cmake`` allows you to pick a build type by changing this
variable: ``CMAKE_BUILD_TYPE``
::
cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
Without specifying a build type or 'None', cmake uses the
``CMAKE_CXX_FLAGS`` variable for building.
Valid an useful build types include 'Release', 'Debug' and
'RelWithDebInfo'. There are others, but they aren't really that useful.
Have fun.
Building the shared memory hook library (SHM)
=============================================
Unlike the rest of DFHack, The SHM needs special treatment when it
comes to compilation. Because it shares the memory space with DF
itself, it has to be built with the same tools as DF and use the same C
and C++/STL libraries.
For DF 31.01 - 31.12 on Windows, use MSVC 2008. You can get the Express
edition for free from Microsoft.

@ -0,0 +1,471 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.7: http://docutils.sourceforge.net/" />
<title>Compiling DFHACK</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 6253 2010-03-02 00:24:53Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: left }
/* div.align-center * { */
/* text-align: left } */
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="compiling-dfhack">
<h1 class="title">Compiling DFHACK</h1>
<h2 class="subtitle" id="here-s-how-you-build-dfhack">Here's how you build dfhack!</h2>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#dependencies" id="id1">Dependencies</a></li>
<li><a class="reference internal" href="#building-on-linux" id="id2">Building on Linux</a></li>
<li><a class="reference internal" href="#building-on-windows" id="id3">Building on Windows</a><ul>
<li><a class="reference internal" href="#using-mingw" id="id4">Using mingw</a><ul>
<li><a class="reference internal" href="#building" id="id5">Building</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-msvc" id="id6">Using MSVC</a></li>
<li><a class="reference internal" href="#using-some-other-compiler" id="id7">Using some other compiler</a></li>
</ul>
</li>
<li><a class="reference internal" href="#build-targets" id="id8">Build targets</a></li>
<li><a class="reference internal" href="#build-types" id="id9">Build types</a></li>
<li><a class="reference internal" href="#building-the-shared-memory-hook-library-shm" id="id10">Building the shared memory hook library (SHM)</a></li>
</ul>
</div>
<div class="section" id="dependencies">
<h1><a class="toc-backref" href="#id1">Dependencies</a></h1>
<ul class="simple">
<li><tt class="docutils literal">cmake</tt></li>
<li>A compiler for building the main lib and the various tools.</li>
<li>(Linux only) Veinlook requires the wide-character ncurses library (libncursesw)</li>
<li>(Linux only) You'll need X11 dev libraries.</li>
</ul>
</div>
<div class="section" id="building-on-linux">
<h1><a class="toc-backref" href="#id2">Building on Linux</a></h1>
<p>To run in the output folder (without installing) building the library
is simple. Enter the build folder, run the tools. Like this:</p>
<pre class="literal-block">
cd build
cmake .. -DCMAKE_BUILD_TYPE:string=Release
make
</pre>
<p>This will build the library and its tools and place them in <tt class="docutils literal">/output</tt>.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI
program.</p>
<p>To be installed into the system or packaged:</p>
<pre class="literal-block">
cd build
cmake -DCMAKE_BUILD_TYPE:string=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DMEMXML_DATA_PATH:path=/usr/share/dfhack ..
make
make install
</pre>
<p>With this dfhack installs:</p>
<ul class="simple">
<li>library to <tt class="docutils literal">$CMAKE_INSTALL_PREFIX/lib</tt></li>
<li>executables to <tt class="docutils literal">$CMAKE_INSTALL_PREFIX/bin</tt></li>
<li>The <tt class="docutils literal">Memory.xml</tt> file to <tt class="docutils literal">/usr/share/dfhack</tt></li>
</ul>
<p>See the section on the shared memory hook library (SHM).</p>
</div>
<div class="section" id="building-on-windows">
<h1><a class="toc-backref" href="#id3">Building on Windows</a></h1>
<p>You need <tt class="docutils literal">cmake</tt>. Get the win32 installer version from the official
site: <a class="reference external" href="http://www.cmake.org/cmake/resources/software.html">http://www.cmake.org/cmake/resources/software.html</a></p>
<p>It has the usual installer wizard thing.</p>
<div class="section" id="using-mingw">
<h2><a class="toc-backref" href="#id4">Using mingw</a></h2>
<p>You also need a compiler. I build dfhack using mingw. You can get it
from the mingw site: <a class="reference external" href="http://www.mingw.org/">http://www.mingw.org/</a></p>
<p>Get the automated installer, it will download newest version of mingw
and set things up nicely.</p>
<p>You'll have to add <tt class="docutils literal"><span class="pre">C:\MinGW\</span></tt> to your PATH variable.</p>
<div class="section" id="building">
<h3><a class="toc-backref" href="#id5">Building</a></h3>
<p>open up cmd and navigate to the <tt class="docutils literal">dfhack\build</tt> folder, run <tt class="docutils literal">cmake</tt>
and the mingw version of make:</p>
<pre class="literal-block">
cd build
cmake .. -G&quot;MinGW Makefiles&quot; -DCMAKE_BUILD_TYPE:string=Release
mingw32-make
</pre>
</div>
</div>
<div class="section" id="using-msvc">
<h2><a class="toc-backref" href="#id6">Using MSVC</a></h2>
<p>open up <tt class="docutils literal">cmd</tt> and navigate to the <tt class="docutils literal">dfhack\build</tt> folder, run
<tt class="docutils literal">cmake</tt>:</p>
<pre class="literal-block">
cd build
cmake ..
</pre>
<p>This will generate MSVC solution and project files.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">You are working in the <tt class="docutils literal">/build</tt> folder. Files added to
projects from within MSVC will end up there! (and that's
wrong). Any changes to the build system should be done
by changing cmake configs and running <tt class="docutils literal">cmake</tt> on them!</p>
</div>
</div>
<div class="section" id="using-some-other-compiler">
<h2><a class="toc-backref" href="#id7">Using some other compiler</a></h2>
<p>I'm afraid you are on your own. dfhack wasn't tested with any other
compiler.</p>
<p>Try using a different cmake generator that's intended for your tools.</p>
</div>
</div>
<div class="section" id="build-targets">
<h1><a class="toc-backref" href="#id8">Build targets</a></h1>
<p>dfhack has a few build targets:</p>
<ul>
<li><p class="first">If you're only after the library run <tt class="docutils literal">make dfhack</tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal">make</tt> will build everything.</p>
</li>
<li><p class="first"><tt class="docutils literal">make expbench</tt> will build the expbench testing program and the
library.</p>
</li>
<li><p class="first">Some of the utilities and the doxygen documentation won't be
normally built. You can enable them by specifying some extra
CMake variables:</p>
<pre class="literal-block">
BUILD_DFHACK_DOCUMENTATION - generate the documentation (really bad)
BUILD_DFHACK_EXAMPLES - build tools from tools/examples
BUILD_DFHACK_PLAYGROUND - build tools from tools/playground
</pre>
<p>Example:</p>
<pre class="literal-block">
cmake .. -DBUILD_DFHACK_EXAMPLES=ON
</pre>
</li>
</ul>
</div>
<div class="section" id="build-types">
<h1><a class="toc-backref" href="#id9">Build types</a></h1>
<p><tt class="docutils literal">cmake</tt> allows you to pick a build type by changing this
variable: <tt class="docutils literal">CMAKE_BUILD_TYPE</tt></p>
<pre class="literal-block">
cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
</pre>
<p>Without specifying a build type or 'None', cmake uses the
<tt class="docutils literal">CMAKE_CXX_FLAGS</tt> variable for building.</p>
<p>Valid an useful build types include 'Release', 'Debug' and
'RelWithDebInfo'. There are others, but they aren't really that useful.</p>
<p>Have fun.</p>
</div>
<div class="section" id="building-the-shared-memory-hook-library-shm">
<h1><a class="toc-backref" href="#id10">Building the shared memory hook library (SHM)</a></h1>
<p>Unlike the rest of DFHack, The SHM needs special treatment when it
comes to compilation. Because it shares the memory space with DF
itself, it has to be built with the same tools as DF and use the same C
and C++/STL libraries.</p>
<p>For DF 31.01 - 31.12 on Windows, use MSVC 2008. You can get the Express
edition for free from Microsoft.</p>
</div>
</div>
</body>
</html>

174
README

@ -1,174 +0,0 @@
Introduction
------------
DFHack is a Dwarf Fortress memory access library and a set of basic tools using
this library. The library is a work in progress, so things might change as more
tools are written for it.
It is an attempt to unite the various ways tools access DF memory and allow for
easier development of new tools.
Getting DFHack
----------------
The project is currently hosted on github, for both source and binaries:
http://github.com/peterix/dfhack
* 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 :)
Compatibility
-------------
DFHack works on Windows XP, Vista, 7 or any modern Linux distribution.
Windows 2000 is currently *not supported* due to missing OS functionality.
If you know how to easily suspend processes, you can fix it :)
OSX is also not supported due to lack of developers with a Mac.
Currently supported Dwarf Fortress versions:
* Windows
0.31.01 - 0.31.03
* Linux
wine together with the Windows versions
Using the library as a developer
--------------------------------
The library is compilable under Linux with GCC and under Windows with MinGW32
and MSVC compilers. It is using the cmake build system. See COMPILE for details.
DFHack is using the zlib/libpng license. This makes it easy to link to it, use
it in-source or add your own extensions. Contributing back to the dfhack
repository is welcome and the right thing to do :)
At the time of writing there's no API reference or documentation. The code does
have a lot of comments though (and getting better all the time).
Contributing to DFHack
----------------------
Several things should be kept in mind when contributing to DFHack.
**** Coding style ****
DFhack uses ANSI formatting and four spaces as indentation. Line endings are
UNIX. The files use UTF-8 encoding. Code not following this won't make me happy,
because I'll have to fix it. There's a good chance I'll make *you* fix it ;)
**** How to get new code into DFHack ****
You can send patches or make a clone of the github repo and ask me on the
IRC channel to pull your code in. I'll review it and see if there are any
problems. I'll fix them if they are minor.
Fixes are higher in priority. If you want to work on something, but don't
know what, check out http://github.com/peterix/dfhack/issues -- this is also
a good place to dump new ideas and/or bugs that need fixing.
**** Layout for tools ****
Tools live in the tools/ folder. There, they are split into three categories:
distributed: these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.
examples : examples are tools that aren't very useful, but show how DF
and DFHack work. They should use only DFHack API functions.
No actual hacking or 'magic offsets' are allowed.
playground : This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools
should start here. They can contain actual hacking, magic values
and other nasty business.
**** Modules - what are they? ****
DFHack uses modules to partition sets of features into manageable chunks.
A module can have both client and server side.
Client side is the part that goes into the main library and is generally
written in C++. It is exposed to the users of DFHack.
Server side is used inside DF and serves to accelerate the client modules.
This is written mostly in C style.
There's a Core module that shouldn't be changed, because it defines
the basic commands like reading and writing raw data. The client parts
for the Core module are the various implementations of the Process
interface.
A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.
Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.
**** Dependencies ****
Internal : either part of the codebase or statically linked.
External : linked as dynamic loaded libraries (.dll, .so, etc.)
If you want to add dependencies, think twice about it. All internal dependencies
for core dfhack should be either public domain or require attribution at most.
Internal dependencies for tools can be either that, or any Free Software
licenses.
** Current internal dependencies **
tinyxml : used by core dfhack to read offset definitions from Memory.xml
md5 : an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.
argstream: Allows reading terminal application arguments. GPL!
** Current external dependencies **
wide-character ncurses : used for the veinlook tool on Linux.
python 2.6 : required for building and using the python bindings.
** Build-time dependencies **
cmake: you need cmake to generate the build system and some configuration
headers
Tools
-----
All the DFHack tools are terminal programs. This might seem strange to Windows
users, but these are meant mostly as examples for developers. Still, they can
be useful and are cross-platform just like the library itself.
- dfcleanmap : Cleans all the splatter that get scattered all over the map.
Only exception is mud. It leaves mud alone.
- dfexpbench : Just a simple benchmark of the data export speed.
- dfliquids : A command prompt for liquid creation and manipulation
(the Moses effect included!)
Also allows painting obsidian walls directly.
Note:
Spawning and deleting liquids can F up pathing data and
temperatures (creating heat traps). You've been warned.
- dfposition : Prints the current DF window properties and cursor position.
- dfprospector: Lists all available minerals on the map and how much
of them there is.
- dfreveal : Reveals the whole map, waits for input and hides it again.
If you close the tool while it waits, the map remains revealed.
- dfsuspend : Test of the process suspend/resume mechanism.
- dfunstuck : Use if you prematurely close any of the tools and DF
appears to be stuck.
- dfvdig : Designates a whole vein for digging. Point the cursor at a vein
and run this thing :)
- Your tool here: Write one ;)
Memory offset definitions
-------------------------
The file with memory offset definitions used by dfhack can be found in the
output folder.
~ EOF ~

@ -0,0 +1,260 @@
============
Introduction
============
DFHack is a Dwarf Fortress memory access library and a set of basic
tools using this library. The library is a work in progress, so things
might change as more tools are written for it.
It is an attempt to unite the various ways tools access DF memory and
allow for easier development of new tools.
.. contents::
==============
Getting DFHack
==============
The project is currently hosted on github_, for both source and
binaries 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 :)
=============
Compatibility
=============
DFHack works on Windows XP, Vista, 7 or any modern Linux distribution.
OSX is not supported due to lack of developers with a Mac.
Currently supported Dwarf Fortress versions are Windows and Linux.
Windows
=======
.. note::
Windows 2000 is currently *not supported* due to missing OS
functionality. If you know how to easily suspend processes, you can
fix it :)
0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.12 SDL
Linux
=====
0.31.05 - 0.31.12 native.
There are missing offsets but Map tools should be OK. Linux support is
a bit lacking, I'm working on it. All supported Windows versions
running in wine can be used with native DFHack binaries.
=====
Tools
=====
All the DFHack tools are terminal programs. This might seem strange to Windows
users, but these are meant mostly as examples for developers. Still, they can
be useful and are cross-platform just like the library itself.
dfcleanmap
==========
Cleans all the splatter that get scattered all over the map.
Only exception is mud. It leaves mud alone.
dfliquids
=========
A command prompt for liquid creation and manipulation (the Moses
effect included!) Also allows painting obsidian walls directly.
.. note::
Spawning and deleting liquids can F up pathing data and
temperatures (creating heat traps). You've been warned.
dfposition
==========
Prints the current DF window properties and cursor position.
dfprospector
============
Lists all available minerals on the map and how much of them there is.
dfprobe
============
Can be used to determine tile properties.
dfreveal
========
Reveals the whole map, waits for input and hides it again. If you close
the tool while it waits, the map remains revealed.
dfunstuck
=========
Use if you prematurely close any of the tools and DF appears to be
stuck.
dfvdig
======
Designates a whole vein for digging. Point the cursor at a vein and run
this thing :)
dfflows
=======
A tool for checking how many liquid tiles are actively checked for
flows.
dfattachtest
============
Test of the process attach/detach mechanism.
dfsuspend
=========
Test of the process suspend/resume mechanism.
dfexpbench
==========
Just a simple benchmark of the data export speed.
dfdoffsets
==========
Dumps the offsets for the currently running DF version into the terminal.
dfcleartask
===========
Solves the problem of unusable items after reclaim by clearing the 'in_job' bit of all items.
Your tool here
==============
Write one ;)
================================
Using the library as a developer
================================
The library is compilable under Linux with GCC and under Windows with
MinGW32 and MSVC compilers. It is using the cmake build system. See
COMPILE for details.
DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)
At the time of writing there's no API reference or documentation. The
code does have a lot of comments though (and getting better all the
time).
Contributing to DFHack
======================
Several things should be kept in mind when contributing to DFHack.
------------
Coding style
------------
DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make *you* fix it ;)
-------------------------------
How to get new code into DFHack
-------------------------------
You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.
Fixes are higher in priority. If you want to work on something, but
don't know what, check out http://github.com/peterix/dfhack/issues --
this is also a good place to dump new ideas and/or bugs that need
fixing.
----------------
Layout for tools
----------------
Tools live in the tools/ folder. There, they are split into three
categories.
distributed
these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.
examples
examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.
playground
This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.
------------------------
Modules - what are they?
------------------------
DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.
Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.
Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.
There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.
A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.
Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.
------------
Dependencies
------------
Internal
either part of the codebase or statically linked.
External
linked as dynamic loaded libraries (.dll, .so, etc.)
If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.
Current internal dependencies
-----------------------------
tinyxml
used by core dfhack to read offset definitions from Memory.xml
md5
an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.
argstream
Allows reading terminal application arguments. GPL!
Current external dependencies
-----------------------------
wide-character ncurses
used for the veinlook tool on Linux.
x11 libraries
used for sending key events on linux
Build-time dependencies
-----------------------
cmake
you need cmake to generate the build system and some configuration
headers
=========================
Memory offset definitions
=========================
The files with memory offset definitions used by dfhack can be found in the
data folder.

@ -0,0 +1,601 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.7: http://docutils.sourceforge.net/" />
<title></title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 6253 2010-03-02 00:24:53Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: left }
/* div.align-center * { */
/* text-align: left } */
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
<p>DFHack is a Dwarf Fortress memory access library and a set of basic
tools using this library. The library is a work in progress, so things
might change as more tools are written for it.</p>
<p>It is an attempt to unite the various ways tools access DF memory and
allow for easier development of new tools.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
<li><a class="reference internal" href="#getting-dfhack" id="id2">Getting DFHack</a><ul>
<li><a class="reference internal" href="#packages" id="id3">Packages</a></li>
</ul>
</li>
<li><a class="reference internal" href="#compatibility" id="id4">Compatibility</a><ul>
<li><a class="reference internal" href="#windows" id="id5">Windows</a></li>
<li><a class="reference internal" href="#linux" id="id6">Linux</a></li>
</ul>
</li>
<li><a class="reference internal" href="#tools" id="id7">Tools</a><ul>
<li><a class="reference internal" href="#dfcleanmap" id="id8">dfcleanmap</a></li>
<li><a class="reference internal" href="#dfliquids" id="id9">dfliquids</a></li>
<li><a class="reference internal" href="#dfposition" id="id10">dfposition</a></li>
<li><a class="reference internal" href="#dfprospector" id="id11">dfprospector</a></li>
<li><a class="reference internal" href="#dfreveal" id="id12">dfreveal</a></li>
<li><a class="reference internal" href="#dfunstuck" id="id13">dfunstuck</a></li>
<li><a class="reference internal" href="#dfvdig" id="id14">dfvdig</a></li>
<li><a class="reference internal" href="#dfflows" id="id15">dfflows</a></li>
<li><a class="reference internal" href="#dfattachtest" id="id16">dfattachtest</a></li>
<li><a class="reference internal" href="#dfsuspend" id="id17">dfsuspend</a></li>
<li><a class="reference internal" href="#dfexpbench" id="id18">dfexpbench</a></li>
<li><a class="reference internal" href="#dfdoffsets" id="id19">dfdoffsets</a></li>
<li><a class="reference internal" href="#dfcleartask" id="id20">dfcleartask</a></li>
<li><a class="reference internal" href="#your-tool-here" id="id21">Your tool here</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-the-library-as-a-developer" id="id22">Using the library as a developer</a><ul>
<li><a class="reference internal" href="#contributing-to-dfhack" id="id23">Contributing to DFHack</a><ul>
<li><a class="reference internal" href="#coding-style" id="id24">Coding style</a></li>
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id25">How to get new code into DFHack</a></li>
<li><a class="reference internal" href="#layout-for-tools" id="id26">Layout for tools</a></li>
<li><a class="reference internal" href="#modules-what-are-they" id="id27">Modules - what are they?</a></li>
<li><a class="reference internal" href="#dependencies" id="id28">Dependencies</a><ul>
<li><a class="reference internal" href="#current-internal-dependencies" id="id29">Current internal dependencies</a></li>
<li><a class="reference internal" href="#current-external-dependencies" id="id30">Current external dependencies</a></li>
<li><a class="reference internal" href="#build-time-dependencies" id="id31">Build-time dependencies</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#memory-offset-definitions" id="id32">Memory offset definitions</a></li>
</ul>
</div>
</div>
<div class="section" id="getting-dfhack">
<h1><a class="toc-backref" href="#id2">Getting DFHack</a></h1>
<p>The project is currently hosted on <a class="reference external" href="http://www.github.com/">github</a>, for both source and
binaries at <a class="reference external" href="http://github.com/peterix/dfhack">http://github.com/peterix/dfhack</a></p>
<div class="section" id="packages">
<h2><a class="toc-backref" href="#id3">Packages</a></h2>
<p>The library and tools are packaged for Archlinux and are available both
in AUR and the arch-games repository.</p>
<p>The package name is dfhack-git :)</p>
</div>
</div>
<div class="section" id="compatibility">
<h1><a class="toc-backref" href="#id4">Compatibility</a></h1>
<p>DFHack works on Windows XP, Vista, 7 or any modern Linux distribution.</p>
<p>OSX is not supported due to lack of developers with a Mac.</p>
<p>Currently supported Dwarf Fortress versions are Windows and Linux.</p>
<div class="section" id="windows">
<h2><a class="toc-backref" href="#id5">Windows</a></h2>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">Windows 2000 is currently <em>not supported</em> due to missing OS
functionality. If you know how to easily suspend processes, you can
fix it :)</p>
</div>
<p>0.31.01 - 0.31.03 legacy
0.31.04 - 0.31.12 SDL</p>
</div>
<div class="section" id="linux">
<h2><a class="toc-backref" href="#id6">Linux</a></h2>
<p>0.31.05 - 0.31.12 native.
There are missing offsets but Map tools should be OK. Linux support is
a bit lacking, I'm working on it. All supported Windows versions
running in wine can be used with native DFHack binaries.</p>
</div>
</div>
<div class="section" id="tools">
<h1><a class="toc-backref" href="#id7">Tools</a></h1>
<p>All the DFHack tools are terminal programs. This might seem strange to Windows
users, but these are meant mostly as examples for developers. Still, they can
be useful and are cross-platform just like the library itself.</p>
<div class="section" id="dfcleanmap">
<h2><a class="toc-backref" href="#id8">dfcleanmap</a></h2>
<p>Cleans all the splatter that get scattered all over the map.
Only exception is mud. It leaves mud alone.</p>
</div>
<div class="section" id="dfliquids">
<h2><a class="toc-backref" href="#id9">dfliquids</a></h2>
<p>A command prompt for liquid creation and manipulation (the Moses
effect included!) Also allows painting obsidian walls directly.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">Spawning and deleting liquids can F up pathing data and
temperatures (creating heat traps). You've been warned.</p>
</div>
</div>
<div class="section" id="dfposition">
<h2><a class="toc-backref" href="#id10">dfposition</a></h2>
<p>Prints the current DF window properties and cursor position.</p>
</div>
<div class="section" id="dfprospector">
<h2><a class="toc-backref" href="#id11">dfprospector</a></h2>
<p>Lists all available minerals on the map and how much of them there is.</p>
</div>
<div class="section" id="dfreveal">
<h2><a class="toc-backref" href="#id12">dfreveal</a></h2>
<p>Reveals the whole map, waits for input and hides it again. If you close
the tool while it waits, the map remains revealed.</p>
</div>
<div class="section" id="dfunstuck">
<h2><a class="toc-backref" href="#id13">dfunstuck</a></h2>
<p>Use if you prematurely close any of the tools and DF appears to be
stuck.</p>
</div>
<div class="section" id="dfvdig">
<h2><a class="toc-backref" href="#id14">dfvdig</a></h2>
<p>Designates a whole vein for digging. Point the cursor at a vein and run
this thing :)</p>
</div>
<div class="section" id="dfflows">
<h2><a class="toc-backref" href="#id15">dfflows</a></h2>
<p>A tool for checking how many liquid tiles are actively checked for
flows.</p>
</div>
<div class="section" id="dfattachtest">
<h2><a class="toc-backref" href="#id16">dfattachtest</a></h2>
<p>Test of the process attach/detach mechanism.</p>
</div>
<div class="section" id="dfsuspend">
<h2><a class="toc-backref" href="#id17">dfsuspend</a></h2>
<p>Test of the process suspend/resume mechanism.</p>
</div>
<div class="section" id="dfexpbench">
<h2><a class="toc-backref" href="#id18">dfexpbench</a></h2>
<p>Just a simple benchmark of the data export speed.</p>
</div>
<div class="section" id="dfdoffsets">
<h2><a class="toc-backref" href="#id19">dfdoffsets</a></h2>
<p>Dumps the offsets for the currently running DF version into the terminal.</p>
</div>
<div class="section" id="dfcleartask">
<h2><a class="toc-backref" href="#id20">dfcleartask</a></h2>
<p>Solves the problem of unusable items after reclaim by clearing the 'in_job' bit of all items.</p>
</div>
<div class="section" id="your-tool-here">
<h2><a class="toc-backref" href="#id21">Your tool here</a></h2>
<p>Write one ;)</p>
</div>
</div>
<div class="section" id="using-the-library-as-a-developer">
<h1><a class="toc-backref" href="#id22">Using the library as a developer</a></h1>
<p>The library is compilable under Linux with GCC and under Windows with
MinGW32 and MSVC compilers. It is using the cmake build system. See
COMPILE for details.</p>
<p>DFHack is using the zlib/libpng license. This makes it easy to link to
it, use it in-source or add your own extensions. Contributing back to
the dfhack repository is welcome and the right thing to do :)</p>
<p>At the time of writing there's no API reference or documentation. The
code does have a lot of comments though (and getting better all the
time).</p>
<div class="section" id="contributing-to-dfhack">
<h2><a class="toc-backref" href="#id23">Contributing to DFHack</a></h2>
<p>Several things should be kept in mind when contributing to DFHack.</p>
<div class="section" id="coding-style">
<h3><a class="toc-backref" href="#id24">Coding style</a></h3>
<p>DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make <em>you</em> fix it ;)</p>
</div>
<div class="section" id="how-to-get-new-code-into-dfhack">
<h3><a class="toc-backref" href="#id25">How to get new code into DFHack</a></h3>
<p>You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.</p>
<p>Fixes are higher in priority. If you want to work on something, but
don't know what, check out <a class="reference external" href="http://github.com/peterix/dfhack/issues">http://github.com/peterix/dfhack/issues</a> --
this is also a good place to dump new ideas and/or bugs that need
fixing.</p>
</div>
<div class="section" id="layout-for-tools">
<h3><a class="toc-backref" href="#id26">Layout for tools</a></h3>
<p>Tools live in the tools/ folder. There, they are split into three
categories.</p>
<dl class="docutils">
<dt>distributed</dt>
<dd>these tools get distributed with binary releases and are installed
by doing 'make install' on linux. They are supposed to be stable
and supported. Experimental, useless, buggy or untested stuff
doesn't belong here.</dd>
<dt>examples</dt>
<dd>examples are tools that aren't very useful, but show how DF and
DFHack work. They should use only DFHack API functions. No actual
hacking or 'magic offsets' are allowed.</dd>
<dt>playground</dt>
<dd>This is a catch-all folder for tools that aren't ready to be
examples or be distributed in binary releases. All new tools should
start here. They can contain actual hacking, magic values and other
nasty business.</dd>
</dl>
</div>
<div class="section" id="modules-what-are-they">
<h3><a class="toc-backref" href="#id27">Modules - what are they?</a></h3>
<p>DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.</p>
<p>Client side is the part that goes into the main library and is
generally written in C++. It is exposed to the users of DFHack.</p>
<p>Server side is used inside DF and serves to accelerate the client
modules. This is written mostly in C style.</p>
<p>There's a Core module that shouldn't be changed, because it defines the
basic commands like reading and writing raw data. The client parts for
the Core module are the various implementations of the Process
interface.</p>
<p>A good example of a module is Maps. Named the same in both client and
server, it allows accelerating the reading of map blocks.</p>
<p>Communication between modules happens by using shared memory. This is
pretty fast, but needs quite a bit of care to not break.</p>
</div>
<div class="section" id="dependencies">
<h3><a class="toc-backref" href="#id28">Dependencies</a></h3>
<dl class="docutils">
<dt>Internal</dt>
<dd>either part of the codebase or statically linked.</dd>
<dt>External</dt>
<dd>linked as dynamic loaded libraries (.dll, .so, etc.)</dd>
</dl>
<p>If you want to add dependencies, think twice about it. All internal
dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.</p>
<div class="section" id="current-internal-dependencies">
<h4><a class="toc-backref" href="#id29">Current internal dependencies</a></h4>
<dl class="docutils">
<dt>tinyxml</dt>
<dd>used by core dfhack to read offset definitions from Memory.xml</dd>
<dt>md5</dt>
<dd>an implementation of the MD5 hash algorithm. Used for identifying
DF binaries on Linux.</dd>
<dt>argstream</dt>
<dd>Allows reading terminal application arguments. GPL!</dd>
</dl>
</div>
<div class="section" id="current-external-dependencies">
<h4><a class="toc-backref" href="#id30">Current external dependencies</a></h4>
<dl class="docutils">
<dt>wide-character ncurses</dt>
<dd>used for the veinlook tool on Linux.</dd>
<dt>x11 libraries</dt>
<dd>used for sending key events on linux</dd>
</dl>
</div>
<div class="section" id="build-time-dependencies">
<h4><a class="toc-backref" href="#id31">Build-time dependencies</a></h4>
<dl class="docutils">
<dt>cmake</dt>
<dd>you need cmake to generate the build system and some configuration
headers</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="section" id="memory-offset-definitions">
<h1><a class="toc-backref" href="#id32">Memory offset definitions</a></h1>
<p>The files with memory offset definitions used by dfhack can be found in the
data folder.</p>
</div>
</div>
</body>
</html>

@ -1,4 +0,0 @@
mkdir build-real
cd build-real
cmake ..\.. -G"Visual Studio 7"
pause

@ -1,4 +0,0 @@
mkdir build-real
cd build-real
cmake ..\.. -G"Visual Studio 7 .NET 2003"
pause

File diff suppressed because it is too large Load Diff

@ -4,6 +4,7 @@
<MemoryDescriptors>
<Entry version="meta-2010" os="all" id="meta-2010">
<Offset name="keep_me_happy">0x0</Offset>
====================================================================
T R A I T S
====================================================================
@ -217,6 +218,17 @@
level_2="Often does the first thing that comes to mind"
level_1="Acts impulsively"
level_0="Always acts without considering alternatives or thinking through possibilities">29</Trait>
====================================================================
M O O D S
====================================================================
<Mood id="0" name="Fey"/>
<Mood id="1" name="Secretive"/>
<Mood id="2" name="Possesed"/>
<Mood id="3" name="Macabre"/>
<Mood id="4" name="Fell"/>
<Mood id="5" name="Melancholy"/>
====================================================================
P R O F E S S I O N S
====================================================================
@ -322,6 +334,7 @@
<Profession can_assign_labors="true" is_military="true" name="LASHER">88</Profession>
<Profession can_assign_labors="true" is_military="true" name="MASTER_LASHER">89</Profession>
<Profession can_assign_labors="true" is_military="false" name="None">90</Profession>
====================================================================
J O B S
====================================================================
@ -792,7 +805,32 @@ size=212
<Skill name="Bone Setting">62</Skill>
<Skill name="Suturing">63</Skill>
<Skill name="Crutch-walking">64</Skill>
====================================================================
L E V E L S
====================================================================
<Level id="0" name="Dabbling" xpNxtLvl="500"/>
<Level id="1" name="Novice" xpNxtLvl="600"/>
<Level id="2" name="Adequate" xpNxtLvl="700"/>
<Level id="3" name="Competent" xpNxtLvl="800"/>
<Level id="4" name="Skilled" xpNxtLvl="900"/>
<Level id="5" name="Proficient" xpNxtLvl="1000"/>
<Level id="6" name="Talented" xpNxtLvl="1100"/>
<Level id="7" name="Adept" xpNxtLvl="1200"/>
<Level id="8" name="Expert" xpNxtLvl="1300"/>
<Level id="9" name="Professional" xpNxtLvl="1400"/>
<Level id="10" name="Accomplished" xpNxtLvl="1500"/>
<Level id="11" name="Great" xpNxtLvl="1600"/>
<Level id="12" name="Master" xpNxtLvl="1700"/>
<Level id="13" name="High Master" xpNxtLvl="1800"/>
<Level id="14" name="Grand Master" xpNxtLvl="1900"/>
<Level id="15" name="Legendary" xpNxtLvl="2000"/>
<Level id="16" name="Legendary+1" xpNxtLvl="2100"/> TODO verify level 16 and up's existence in DF2010
<Level id="17" name="Legendary+2" xpNxtLvl="2200"/>
<Level id="18" name="Legendary+3" xpNxtLvl="2300"/>
<Level id="19" name="Legendary+4" xpNxtLvl="2400"/>
<Level id="20" name="Legendary+5" xpNxtLvl="-1"/> -1 for no cap
====================================================================
L A B O R S
====================================================================
@ -1427,6 +1465,8 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_mood">0x288</Offset>
<Offset name="creature_birth_year">0x298</Offset>
<Offset name="creature_birth_time">0x29C</Offset>
<Offset name="creature_current_job">0x390</Offset> <!-- from chmod -->
<Offset name="creature_mood_skill">0x394</Offset> the skill that will be increased at the end of the mood (or not)
<Offset name="creature_physical">0x464</Offset>
<!--
<Offset name="creature_strength">0x464</Offset>
@ -1436,8 +1476,6 @@ map_data_1b60_offset 0x1B9c
<Offset name="creature_recuperation">0x4D4</Offset>
<Offset name="creature_disease_resistance">0x4F0</Offset>
-->
<Offset name="creature_current_job">0x390</Offset> <!-- from chmod -->
<Offset name="creature_mood_skill">0x394</Offset> the skill that will be increased at the end of the mood (or not)
<Offset name="creature_appearance_vector">0x604</Offset>
<Offset name="creature_artifact_name">0x6D4</Offset>
<Offset name="creature_labors">0x774</Offset>
@ -1447,20 +1485,23 @@ map_data_1b60_offset 0x1B9c
Castes
======
<Offset name="color_modifier_part">0x70</Offset>
<Offset name="color_modifier_startdate">0x64</Offset>
<Offset name="color_modifier_enddate">0x68</Offset>
<Offset name="caste_bodypart_vector">0x51C</Offset>
<Offset name="caste_color_modifiers">0xACC</Offset>
<Offset name="caste_attributes">0x654</Offset>
<Offset name="caste_color_modifiers">0xACC</Offset>
Body Parts
==========
<Offset name="bodypart_id">0x0</Offset>
<Offset name="bodypart_category">0x1C</Offset>
<Offset name="bodypart_layers_vector">0x44</Offset>
<Offset name="bodypart_singular_vector">0x78</Offset>
<Offset name="bodypart_plural_vector">0x90</Offset>
Color Mods
==========
<Offset name="color_modifier_part">0x70</Offset>
<Offset name="color_modifier_startdate">0x64</Offset>
<Offset name="color_modifier_enddate">0x68</Offset>
Body Parts
==========
<Offset name="bodypart_id">0x0</Offset>
<Offset name="bodypart_category">0x1C</Offset>
<Offset name="bodypart_layers_vector">0x44</Offset>
<Offset name="bodypart_singular_vector">0x78</Offset>
<Offset name="bodypart_plural_vector">0x90</Offset>
Materials
=========
@ -1597,7 +1638,90 @@ map_data_1b60_offset 0x1B9c
<Offset name="item_type_accessor">0x0</Offset> Why do i have to redefine this ???
</Entry>
<Entry version="v0.31.05" os="windows" id="0.31.05" base="0.31.04" rebase="0x8010">
<String name="md5">394ff63fc00fedd5df0b36e4beb589bc</String>
<HexValue name="pe_timestamp">0x4c091569</HexValue>
<Address name="dwarf_race_index">0x014abee4</Address> CHMOD
<Address name="dwarf_civ_id">0x1471FB0</Address> BOGUS!
<Address name="window_dims">0x180b10c</Address> LOOKS O.K.
<Address name="window_x">0xe6c0dc</Address> VERIFIED
<Address name="window_y">0xe9a1b0</Address> VERIFIED
<Address name="window_z">0xe9a18c</Address> VERIFIED
<Address name="cursor_xyz">0xaf12cc</Address> VERIFIED
<Address name="current_tick">0xE80780</Address> LOOKS O.K.
<Address name="current_year">0xEB2878</Address> LOOKS O.K.
<Offset name="item_type_accessor">0x0</Offset> Why do i have to redefine this ???
... what?
</Entry>
<Entry version="v0.31.06" os="windows" id="0.31.06" base="0.31.05" rebase="0x10">
<String name="md5">c4b7e37dafa2716e31d29110968ac64e</String>
<HexValue name="pe_timestamp">0x4c0f83d5</HexValue>
<Address name="cursor_xyz">0xaf12d0</Address>
</Entry>
<Entry version="v0.31.07" os="windows" id="0.31.07" base="0.31.06" rebase="0x2000">
<String name="md5">1c0b5254af1b8ff9a34b51c3f6609da3</String>
<HexValue name="pe_timestamp">0x4c1cbe4b</HexValue>
<Address name="cursor_xyz">0xaf32d8</Address>0xaf12d0
<Address name="window_dims">0x180d11c</Address> 0x180b10c
<Address name="window_x">0xe6e0ec</Address>
<Address name="window_y">0xe9c1c0</Address>
<Address name="window_z">0xe9c19c</Address>
map size X: 0x16c4b10
map size Y: 0x16c4b14
</Entry>
<Entry version="v0.31.08" os="windows" id="0.31.08" base="0.31.07" rebase="-0x1000">
<String name="md5">a83e6b21307cf41fb54c315fa40dec86</String>
<HexValue name="pe_timestamp">0x4c1d69fe</HexValue>
<Address name="dwarf_civ_id">0x14acee8</Address>
<!--
<Address name="cursor_xyz">0xaf32d8</Address>0xaf12d0
<Address name="window_dims">0x180d11c</Address> 0x180b10c
<Address name="window_x">0xe6e0ec</Address>
<Address name="window_y">0xe9c1c0</Address>
<Address name="window_z">0xe9c19c</Address>
map size X: 0x16c4b10
map size Y: 0x16c4b14
-->
</Entry>
<Entry version="v0.31.09" os="windows" id="0.31.09" base="0.31.08" rebase="0xD028" > rebase="0xD030"
<!-- TODO: fix creature offsets -->
<!-- TODO: small offsets added all over the place, investigate -->
<String name="md5">1a85839ab03df082974dc5629d3fbc26</String>
<HexValue name="pe_timestamp">0x4C3897C0</HexValue>
<Address name="cursor_xyz">0xaff2d8</Address>
<Address name="language_vector">0x16D33CC</Address>
<Address name="translation_vector">0x16D33FC</Address>
<Offset name="word_table">0x4c</Offset>
Creatures
=========
<Address name="creature_vector">0x168E73C</Address>
<Address name="dwarf_race_index">0x014b9f1c</Address>
<Offset name="creature_soulskill_vector">0X1F4</Offset>
<Offset name="creature_physical">0x4AC</Offset>
<Offset name="creature_appearance_vector">0x64c</Offset> <!-- Maybe slightly wrong -->
<Offset name="creature_artifact_name">0x71c</Offset>
<Offset name="creature_labors">0x7Bc</Offset>
<Offset name="creature_soul_vector">0x0788</Offset>
<Offset name="creature_default_soul">0x07A0</Offset>
<Offset name="creature_happiness">0x87c</Offset>
</Entry>
<Entry version="v0.31.10" os="windows" id="0.31.10" base="0.31.09">
<String name="md5">349d1ad6eda7b6c5e87f8e4726a0999a</String>
<HexValue name="pe_timestamp">0x4C398089</HexValue>
</Entry>
<Entry version="v0.31.11" os="windows" id="0.31.11" base="0.31.10" rebase="0x7018">
<String name="md5">552cfa417fd131204ebfee66aefc4adb</String>
<HexValue name="pe_timestamp">0x4C496D93</HexValue>
<Address name="cursor_xyz">0xB062D8</Address>
<Address name="window_x">0xe81114</Address> VERIFIED
<Address name="window_y">0xeAF1E8</Address> VERIFIED
<Address name="window_z">0xeAF1C4</Address> VERIFIED
</Entry>
<Entry version="v0.31.12" os="windows" id="0.31.12" base="0.31.11">
<String name="md5">f0459165a426a9f2dd8d957e9fa7f01d</String>
<HexValue name="pe_timestamp">0x4C4C32E7</HexValue>
</Entry>
.-"""-.
' \
|,. ,-. | _________________________
@ -1615,185 +1739,229 @@ map_data_1b60_offset 0x1B9c
| `.`, | `.
| `. __.j )
|__ |--""___| ,-'
`"--...,+"""" `._,.-'
`"--...,+"""" `._,.-'
<!-- Windows logo by Microsoft -->
<!-- Tux logo by the Linux guys :) -->
<Entry version="v0.30_04" os="linux" id="30_04lin" base="meta-2010">
<String name="md5">1d759a11af258263ef5c139d6d9a3e15</String>
<Entry version="linux-offsets-2010" os="all" id="linux-offsets-2010" base="meta-2010">
Basic things
============
<HexValue name="sizeof_vector">0xC</HexValue>
<Offset name="vector_triplet">0x0</Offset>
<HexValue name="sizeof_string">0x4</HexValue>
<!-- MAYBE
<HexValue name="sizeof_string">0x4</HexValue>
<HexValue name="sizeof_vector">0x10</HexValue>
<Offset name="vector_triplet">0x4</Offset>
-->
<HexValue name="sizeof_vector">0xC</HexValue> VERIFIED
<Offset name="vector_triplet">0x0</Offset> VERIFIED
<HexValue name="sizeof_string">0x4</HexValue> VERIFIED
MAP BLOCK OFFSETS
=================
<Offset name="map_data_vein_vector">0x08</Offset> VERIFIED
<Offset name="map_data_feature_local">0x20</Offset> VERIFIED
<Offset name="map_data_feature_global">0x24</Offset> VERIFIED
<Offset name="map_data_type">0x006A</Offset> VERIFIED
<Offset name="map_data_designation">0x026C</Offset> VERIFIED
<Offset name="map_data_occupancy">0x066c</Offset> VERIFIED
<Offset name="map_data_temperature1_offset">0x156c</Offset> VERIFIED
<Offset name="map_data_temperature2_offset">0x176c</Offset> VERIFIED
<Offset name="map_data_biome_stuffs">0x1D6C</Offset> VERIFIED
<Offset name="map_data_pathfinding_offset">0x0D6c</Offset> VERIFIED
MAP FEATURE OFFSETS
===================
<Offset name= "global_feature_funcptr_">0x94</Offset> VERIFIED
<Offset name="global_feature_mat">0x28</Offset> VERIFIED
<Offset name="global_feature_submat">0x2C</Offset> VERIFIED
<Offset name="local_feature_mat">0x24</Offset> VERIFIED
<Offset name="local_feature_submat">0x28</Offset> VERIFIED
values for the region structure
===============================
<HexValue name="region_size">0x58</HexValue> VERIFIED
<Offset name="region_geo_index_off">0x54</Offset> VERIFIED
geoblock offsets
================
<Offset name="geolayer_geoblock_offset">0x4</Offset> VERIFIED
<Offset name="type_inside_geolayer">0x4</Offset> VERIFIED
Name struct
===========
<Offset name="name_firstname">0x0</Offset> VERIFIED
<Offset name="name_nickname">0x4</Offset> VERIFIED
<Offset name="name_words">0x8</Offset> VERIFIED
Creature offsets
================
<Offset name="creature_name">0x0</Offset> VERIFIED
<Offset name="creature_custom_profession">0x3c</Offset> CHMOD
<Offset name="creature_profession">0x40</Offset> CHMOD
<Offset name="creature_race">0x44</Offset> CHMOD
<Offset name="creature_position">0x90</Offset> BAD!!
<Offset name="creature_flags1">0x8C</Offset> CHMOD
<Offset name="creature_flags2">0x90</Offset> CHMOD
<Offset name="creature_caste">0xA4</Offset> VERIFY
<Offset name="creature_sex">0xA6</Offset> CHMOD
<Offset name="creature_id">0xA8</Offset> CHMOD
<Offset name="creature_civ">0xB4</Offset> VERIFY!
<Offset name="creature_pickup_equipment_bit">0X144</Offset> CHMOD
<Offset name="creature_mood">0x18C</Offset> VERIFY!
<Offset name="creature_birth_year">0x19C</Offset> VERIFY!
<Offset name="creature_birth_time">0x1A0</Offset> VERIFY!
<Offset name="creature_physical">0x464</Offset> BAD!
<Offset name="creature_current_job">0x258</Offset> CHMOD
<Offset name="creature_mood_skill">0x394</Offset> VERIFY!
the skill that will be increased at the end of the mood (or not)
<Offset name="creature_appearance_vector">0x604</Offset> BAD!
<Offset name="creature_artifact_name">0x6D4</Offset> BAD!
<Offset name="creature_labors">0x51C</Offset> CHMOD
<Offset name="creature_soul_vector">0x0500</Offset> CHMOD
<Offset name="creature_default_soul">0x0758</Offset> BAD!
<Offset name="creature_happiness">0x5AC</Offset> CHMOD
Souls
=====
<Offset name="soul_name">0x0</Offset>
<Offset name="soul_skills_vector">0x1C4</Offset> CHMOD
<Offset name="soul_traits">0x1DC</Offset> CHMOD
<Offset name="soul_mental">0x88</Offset> BAD!
Body Parts
==========
<Offset name="bodypart_id">0x0</Offset>
<Offset name="bodypart_category">0x1C</Offset>
<Offset name="bodypart_layers_vector">0x44</Offset>
<Offset name="bodypart_singular_vector">0x78</Offset>
<Offset name="bodypart_plural_vector">0x90</Offset>
Job structure
=============
<Offset name="job_id">0x0</Offset> Incrementaly assigned
<Offset name="job_type">0x8</Offset> seems to be just like the old occupations
<Offset name="job_materials_vector">0xa4</Offset>
Job materials
=============
<Offset name="job_material_maintype">0x0</Offset> like mood materials, 0=bars, 4=stone, 5=wood, 57=cloth, 54=leather ...
<Offset name="job_material_sectype1">0x2</Offset> subsubtype ?
<Offset name="job_material_sectype2">0x4</Offset> subtype ?
<Offset name="job_material_sectype3">0x8</Offset> index of material (for example, 2 is for silver)
<Offset name="job_material_flags">0x18</Offset> set only for shell / bone mood requirements ?
Creature type offsets
=====================
<Offset name="creature_type_caste_vector">0x60</Offset> VERIFIED
from 0.31.08
Toad: 0xaf75b68
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x18f4
Toad: colors = 0x36
<Offset name="creature_type_extract_vector">0x18f4</Offset> VERIFIED
<Offset name="creature_tile">0x20</Offset> VERIFIED
<Offset name="creature_tile_color">0x36</Offset> LOOKS OK
Castes
======
<Offset name="color_modifier_part">0x70</Offset>
<Offset name="color_modifier_startdate">0x64</Offset>
<Offset name="color_modifier_enddate">0x68</Offset>
<Offset name="caste_bodypart_vector">0x51C</Offset>
<Offset name="caste_color_modifiers">0xACC</Offset>
<Offset name="caste_attributes">0x654</Offset>
<!--
<Offset name="creature_type_caste_vector">0x138</Offset>
<Offset name="creature_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset>
-->
<!--
struct CreatureType
{
Vector<CreatureCasteType*> creature_type_caste_vector (0x138);
Vector<CreatureExtractType*> creature_type_extract_vector (0x1A14);
Offset creature_tile (0xE0);
Offset creature_tile_color (0xF6);
}
-->
Color descriptors
=================
<Offset name="descriptor_rawname">0x0</Offset> VERIFIED
<Offset name="descriptor_name">0x1C</Offset> VERIFIED
<Offset name="descriptor_color_r">0x24</Offset> VERIFIED
<Offset name="descriptor_color_v">0x28</Offset> VERIFIED
<Offset name="descriptor_color_b">0x2C</Offset> VERIFIED
Language tables
===============
<Offset name="word_table">0x1C</Offset> VERIFIED
Constructions
=============
<Offset name="sizeof_construction">0x14</Offset>
</Entry>
<Entry version="v0.30_04" os="linux" id="30_04lin" base="linux-offsets-2010">
<String name="md5">1d759a11af258263ef5c139d6d9a3e15</String>
<!-- most probably a static object, because its parts are often
referenced as offset to this address *and* as addresses -->
<Address name="WORLD">0x92D00C0</Address> 0x0165B188
<Address name="WORLD">0x92D00C0</Address>
Position and window dimensions
==============================
<Address name="window_x">0x8cd3b18</Address> 0xe32798
<Address name="window_y">0x8cd3b1c</Address> 0xe60838
<Address name="window_z">0x8cd3b20</Address> 0xe60814
<Address name="cursor_xyz">0x8b17370</Address> 0xae82cc
<Address name="window_x">0x8cd3b18</Address>
<Address name="window_y">0x8cd3b1c</Address>
<Address name="window_z">0x8cd3b20</Address>
<Address name="cursor_xyz">0x8b17370</Address>
<Address name="window_dims">0x9464d6c</Address>
<Address name="window_dims">0x9464d6c</Address> 0x17f5ab8
GUI State
=========
<Address name="pause_state">0x92c971c</Address> 0x146e45f
<!--
Bogus: <Address name="current_cursor_creature">0xae82cc</Address>
<Address name="pause_state">0x92c971c</Address>
<Address name="current_menu_state">0x017f6f38</Address>
Bogus: <Address name="view_screen">0xae82cc</Address>
-->
Map stuff
Map data
=========
<Address name="map_data">0x9322d20</Address> WORLD + 0x52C60
<Offset name="map_data_vein_vector">0x08</Offset>
<Offset name="map_data_feature_local">0x20</Offset>
<Offset name="map_data_feature_global">0x24</Offset>
<Offset name="map_data_type">0x006A</Offset>
<Offset name="map_data_designation">0x026C</Offset>
<Offset name="map_data_occupancy">0x066c</Offset>
<Offset name="map_data_temperature1_offset">0x156c</Offset>
<Offset name="map_data_temperature2_offset">0x176c</Offset>
<Offset name="map_data_biome_stuffs">0x1D6C</Offset>
<Offset name="map_data_pathfinding_offset">0x0D6c</Offset>
Map Features
============
WORLD + 0x5487C
<Address name="global_feature_vector">0x932493C</Address>
<Offset name= "global_feature_funcptr_">0x94</Offset>
<Offset name="global_feature_mat">0x28</Offset>
<Offset name="global_feature_submat">0x2C</Offset>
WORLD + 0x548F4
<Address name="local_feature_start_ptr">0x93249B4</Address>
<Offset name="local_feature_mat">0x24</Offset>
<Offset name="local_feature_submat">0x28</Offset>
* map size in blocks *
<Address name="x_count_block">0x9322d34</Address> 0x016ad738
<Address name="y_count_block">0x9322d38</Address>0x016ad73C
<Address name="z_count_block">0x9322d3C</Address>0x016ad740
<Address name="x_count_block">0x9322d34</Address>
<Address name="y_count_block">0x9322d38</Address>
<Address name="z_count_block">0x9322d3C</Address>
* map size in tiles *
<Address name="x_count">0x9322d40</Address> 0x016ad744
<Address name="y_count">0x9322d44</Address> 0x016ad748
<Address name="z_count">0x9322d48</Address> 0x016ad74C
<Address name="x_count">0x9322d40</Address>
<Address name="y_count">0x9322d44</Address>
<Address name="z_count">0x9322d48</Address>
* region coords *
WORLD + 0x525C8
<Address name="region_x">0x9322d4C</Address> 0x016ad750
<Address name="region_x">0x9322d4C</Address>
WORLD + 0x525CC
<Address name="region_y">0x9322d50</Address> 0x016ad754
<Address name="region_y">0x9322d50</Address>
WORLD + 0x525D0
<Address name="region_z">0x9322d54</Address> 0x016ad758
<Address name="region_z">0x9322d54</Address>
* World size * (WORDs)
WORLD + 0x542E0
<Address name="world_size_x">0x93243A0</Address> 0x016AEDD4
<Address name="world_size_x">0x93243A0</Address>
WORLD + 0x542E2
<Address name="world_size_y">0x93243A2</Address> 0x016AEDD6
<Address name="world_size_y">0x93243A2</Address>
WORLD + 0x54894
<Address name="geoblock_vector">0x9324954</Address> FIX 0x16AF52C
<Address name="geoblock_vector">0x9324954</Address>
WORLD + 0x548B8
<Address name="ptr2_region_array">0x9324978</Address> FIX 0x16AF574
values for the region structure
===============================
<HexValue name="region_size">0x58</HexValue> 0x64 FIX
<Offset name="region_geo_index_off">0x54</Offset> 0x60 FIX
geoblock offsets
================
<Offset name="geolayer_geoblock_offset">0x4</Offset> vector
<Offset name="type_inside_geolayer">0x4</Offset> vector
Name struct
===========
<Offset name="name_firstname">0x0</Offset>
<Offset name="name_nickname">0x4</Offset>
<Offset name="name_words">0x8</Offset>
<Address name="ptr2_region_array">0x9324978</Address>
Creatures
=========
<Address name="creature_vector">0x092E3AA0</Address>
<Address name="dwarf_race_index">0x092CB608</Address>
<Address name="dwarf_civ_id">0x092CB5FC</Address>
<Offset name="creature_name">0x0</Offset>
<Offset name="creature_custom_profession">0x6c</Offset>
<Offset name="creature_profession">0x3c</Offset> *
<Offset name="creature_race">0x44</Offset> *
<Offset name="creature_position">0x90</Offset>
<Offset name="creature_flags1">0x8C</Offset> *
<Offset name="creature_flags2">0x90</Offset> *
<Offset name="creature_caste">0x110</Offset>
<Offset name="creature_sex">0xA6</Offset> *
<Offset name="creature_id">0x114</Offset>
<Offset name="creature_civ">0XB4</Offset> *
<Offset name="creature_soulskill_vector">0X1F4</Offset>
<Offset name="creature_pickup_equipment_bit">0X21C</Offset>
<Offset name="creature_mood">0x18C</Offset> *
<Offset name="creature_birth_year">0x19C</Offset> *
<Offset name="creature_birth_time">0x1A0</Offset> *
<Offset name="creature_physical">0x464</Offset>
<Offset name="creature_current_job">0x390</Offset> from chmod
<Offset name="creature_mood_skill">0x394</Offset> the skill that will be increased at the end of the mood (or not)
<Offset name="creature_appearance_vector">0x604</Offset>
<Offset name="creature_artifact_name">0x6D4</Offset>
<Offset name="creature_labors">0x774</Offset>
<Offset name="creature_soul_vector">0x0740</Offset>
<Offset name="creature_default_soul">0x0758</Offset>
<Offset name="creature_happiness">0x834</Offset>
Souls
=====
<Offset name="soul_name">0x0</Offset>
<Offset name="soul_skills_vector">0x1F4</Offset>
<Offset name="soul_traits">0x224</Offset>
<Offset name="soul_mental">0x88</Offset>
Castes
======
<Offset name="color_modifier_part">0x70</Offset>
<Offset name="color_modifier_startdate">0x64</Offset>
<Offset name="color_modifier_enddate">0x68</Offset>
<Offset name="caste_bodypart_vector">0x51C</Offset>
<Offset name="caste_color_modifiers">0xACC</Offset>
<Offset name="caste_attributes">0x654</Offset>
Body Parts
==========
<Offset name="bodypart_id">0x0</Offset>
<Offset name="bodypart_category">0x1C</Offset>
<Offset name="bodypart_layers_vector">0x44</Offset>
<Offset name="bodypart_singular_vector">0x78</Offset>
<Offset name="bodypart_plural_vector">0x90</Offset>
Job structure
=============
<Offset name="job_id">0x0</Offset> Incrementaly assigned
<Offset name="job_type">0x8</Offset> seems to be just like the old occupations
<Offset name="job_materials_vector">0xa4</Offset>
Job materials
=============
<Offset name="job_material_maintype">0x0</Offset> like mood materials, 0=bars, 4=stone, 5=wood, 57=cloth, 54=leather ...
<Offset name="job_material_sectype1">0x2</Offset> subsubtype ?
<Offset name="job_material_sectype2">0x4</Offset> subtype ?
<Offset name="job_material_sectype3">0x8</Offset> index of material (for example, 2 is for silver)
<Offset name="job_material_flags">0x18</Offset> set only for shell / bone mood requirements ?
Materials
=========
@ -1812,32 +1980,29 @@ map_data_1b60_offset 0x1B9c
creature types actually used for creatures,
<Address name="creature_type_vector">0x09324F14</Address>
<Offset name="creature_type_caste_vector">0x138</Offset>
<Offset name="creature_type_extract_vector">0x1A14</Offset>
<Offset name="creature_tile">0xE0</Offset>
<Offset name="creature_tile_color">0xF6</Offset>
Color descriptors
=================
<Address name="descriptor_colors_vector">0x9329378</Address> VERIFIED
<Address name="descriptor_all_colors">0x9329390</Address> VERIFIED
Translations
============
WORLD + 0x54E50
<Address name="language_vector">23</Address>
<Address name="language_vector">0x9324fd4</Address>
WORLD + 0x54E80
<Address name="translation_vector">24</Address>
<Offset name="word_table">0x4C</Offset>
<Address name="translation_vector">0x9324fec</Address>
Constructions
=============
WORLD + 0x84
<Address name="construction_vector">0x92D0144</Address> 0x165b290
<Offset name="sizeof_construction">0x14</Offset>
Time
====
<Address name="current_year">0x92C9680</Address>
<Address name="current_tick">0x92C9688</Address>
<!--
Translations
============
WORLD + 0x54E50
<Address name="language_vector">0x016AFFD8</Address>
WORLD + 0x54E80
<Address name="translation_vector">0x016B0008</Address>
<Offset name="word_table">0x4C</Offset>
Vegetation
==========
@ -1940,10 +2105,260 @@ map_data_1b60_offset 0x1B9c
<Offset name="item_improvement_quality">0x14</Offset>
<Offset name="item_type_accessor">0x14</Offset> (in the vtable)
-->
</Entry>
<Entry version="v0.31.05" os="linux" id="30_05lin" base="linux-offsets-2010">
<String name="md5">fea3801a26538b1741f3cc9294139fca</String>
<!-- most probably a static object, because its parts are often
referenced as offset to this address *and* as addresses -->
<Address name="WORLD">0x92C60E0</Address> MOST PROBABLY BOGUS!
Position and window dimensions
==============================
<Address name="window_x">0x8cc9b38</Address> VERIFIED
<Address name="window_y">0x8cc9b3c</Address> VERIFIED
<Address name="window_z">0x8cc9b40</Address> VERIFIED
<Address name="cursor_xyz">0x8b0d36c</Address> VERIFIED
<Address name="window_dims">0x945ad8c</Address> VERIFIED
GUI State
=========
<Address name="pause_state">0x92bf73c</Address> VERIFIED
Map data
========
WORLD + 0x52C60?
<Address name="map_data">0x9318D40</Address> VERIFIED
Map Features
============
WORLD + 0x5487C?
<Address name="global_feature_vector">0x931A95C</Address> VERIFIED
WORLD + 0x548F4?
<Address name="local_feature_start_ptr">0x931A9D4</Address> VERIFIED
* map size in blocks *
<Address name="x_count_block">0x9318D54</Address> VERIFIED
<Address name="y_count_block">0x9318D58</Address> VERIFIED
<Address name="z_count_block">0x9318D5C</Address> VERIFIED
* map size in tiles *
<Address name="x_count">0x9318D60</Address> VERIFIED
<Address name="y_count">0x9318D64</Address> VERIFIED
<Address name="z_count">0x9318D68</Address> VERIFIED
* region coords *
WORLD + 0x525C8
<Address name="region_x">0x9318D6C</Address> VERIFIED
WORLD + 0x525CC
<Address name="region_y">0x9318D70</Address> VERIFIED
WORLD + 0x525D0
<Address name="region_z">0x9318D74</Address> VERIFIED (old = 0x9322d54)
* World size * (WORDs)
WORLD + 0x542E0
<Address name="world_size_x">0x931A3C0</Address> VERIFIED
WORLD + 0x542E2
<Address name="world_size_y">0x931A3C2</Address> VERIFIED
WORLD + 0x54894
<Address name="geoblock_vector">0x931A974</Address> VERIFIED
WORLD + 0x548B8
<Address name="ptr2_region_array">0x931A998</Address> VERIFIED
Materials
=========
soil, stone, metal
inorganics vector
<Address name="mat_inorganics">0x931ae88</Address> VERIFIED
wood and plant matter
<Address name="mat_organics_all">0x931ae94</Address> VERIFIED
plant matter
<Address name="mat_organics_plants">0x931aea0</Address> VERIFIED
just wood
<Address name="mat_organics_trees">0x931aeb8</Address> VERIFIED
creature types actually used for creatures,
<Address name="creature_type_vector">0x931af34</Address> VERIFIED
Color descriptors
=================
<Address name="descriptor_colors_vector">0x931f398</Address> VERIFIED
<Address name="descriptor_all_colors">0x931f3b0</Address> VERIFIED
Translations
============
WORLD + 0x54E50
<Address name="language_vector">0x931aff4</Address>
WORLD + 0x54E80
<Address name="translation_vector">0x931b00c</Address>
Creatures
=========
<Address name="creature_vector">0x92D9AC0</Address>
<Address name="dwarf_race_index">0x92C1628</Address>0x092CB608
<Address name="dwarf_civ_id">0x92C161C</Address>0x092CB5FC
Time
====
<Address name="current_tick">0x92C9688</Address>
<Address name="current_year">0x92C9680</Address>
<Address name="current_year">0x92BF6A0</Address>
<Address name="current_tick">0x92BF6A8</Address>
YEAR 0x92BF6A0, WORLD - 0x6A40
TICKS 0x92BF6A8, WORLD - 0x6A40 + 0x08
</Entry>
<Entry version="v0.31.06" os="linux" id="30_06lin" base="30_05lin" rebase="-0x20E0">
<String name="md5">13a1c19e8f59b74e307e094e2a0f28c3</String>
<Address name="cursor_xyz">0x8b0b328</Address> VERIFIED
WORLD = 0x92C4000
Creatures
=========
WORLD + 0x139E0
0x92d79d4
0x92d79e0 = real one? seems like it
0x92d7a10
</Entry>
<Entry version="v0.31.07" os="linux" id="30_07lin" base="30_06lin" rebase="0x2000">
<String name="md5">b31979551782e89c049b11db8d2d86d7</String>
</Entry>
<Entry version="v0.31.08" os="linux" id="30_08lin" base="30_07lin">
<String name="md5">e37750890350d7b9d8203879aff8fa5c</String>
</Entry>
<Entry version="v0.31.09" os="linux" id="30_09lin" base="30_08lin" rebase="0x11000">
<!-- TODO: fix creature offsets -->
<!-- TODO: small offsets added all over the place, investigate -->
<String name="md5">4f1f988bc1b425d4193d3d8b7b0579a5</String>
stealing memory...
looking for vectors...
-------------------
!!LANGUAGE TABLES!!
-------------------
translation vector: 0x932bf2c
lang vector: 0x932bf14
word table offset: 0x1c
-------------
!!MATERIALS!!
-------------
inorganics:
0x932bda8
organics:
0x932bdb4
trees:
0x932bdd8
plants:
0x932bdc0
color descriptors:
0x93302b8
Amber color:0xaf842e0
all descriptors:
0x93302d0
toad-first creature types:
0x932be54
all creature types:
0x932be2c
0x932be54
Toad: 0xb076f88
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x18f4
Toad: colors = 0x36
</Entry>
<Entry version="v0.31.10" os="linux" id="30_10lin" base="30_09lin">
<String name="md5">3e7bea269018a6fb88ef53715685aa64</String>
-------------------
!!LANGUAGE TABLES!!
-------------------
translation vector: 0x932bf2c
lang vector: 0x932bf14
word table offset: 0x1c
-------------
!!MATERIALS!!
-------------
inorganics:
0x932bda8
organics:
0x932bdb4
trees:
0x932bdd8
plants:
0x932bdc0
color descriptors:
0x93302b8
Amber color:0xcc3a770
all descriptors:
0x93302d0
toad-first creature types:
0x932be54
elephant-first creature types:
all creature types:
0x932be2c
0x932be54
Toad: 0xc77d798
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x18f4
Toad: colors = 0x36
Buildings
=========
<Address name="buildings_vector">0x92eb068</Address>
<Offset name="building_custom_workshop_type">0xE0</Offset>
<Address name="custom_workshop_vector">0x93302e8</Address>
<Offset name="custom_workshop_name">0x4</Offset>
<Offset name="custom_workshop_type">0x8</Offset>
<VTable name="building_vtable">
<multiclass name="building_trapst" typeoffset="0xC0" />
<multiclass name="building_workshopst" typeoffset="0xC0" />
<multiclass name="building_furnacest" typeoffset="0xCE" />
<multiclass name="building_siegeenginest" typeoffset="0xC0" />
</VTable>
</Entry>
<Entry version="v0.31.11" os="linux" id="30_11lin" base="30_10lin" rebase="0x1D020">
<!-- BIG rebase, possible broken stuff -->
<String name="md5">7b04ad536b8b657588ac209a7f95e1d1</String>
<Address name="window_x">0x8cf7a58</Address> VERIFIED
<Address name="window_y">0x8cf7a5C</Address> VERIFIED
<Address name="window_z">0x8cf7a60</Address> VERIFIED
<Address name="cursor_xyz">0x8b3b328</Address> VERIFIED
-------------------
!!LANGUAGE TABLES!!
-------------------
translation vector: 0x9348f4c
lang vector: 0x9348f34
word table offset: 0x1c
-------------
!!MATERIALS!!
-------------
inorganics:
0x9348dc8
organics:
0x9348dd4
trees:
0x9348df8
plants:
0x9348de0
color descriptors:
0x934d2d8
Amber color:0xac014c0
all descriptors:
0x934d2f0
toad-first creature types:
0x9348e74
all creature types:
0x9348e4c
0x9348e74
Toad: 0xadae390
Toad: rawname = 0x0
Toad: character (not reliable) = 0x20
Toad: caste vector = 0x60
Toad: extract? vector = 0x18f4
Toad: colors = 0x36
</Entry>
<Entry version="v0.31.12" os="linux" id="30_12lin" base="30_11lin" rebase="-0x1000">
<String name="md5">e79cead03187ecb692961b316b7cdcd4</String>
</Entry>
</MemoryDescriptors>
</DFExtractor>

@ -0,0 +1,68 @@
# repurposed from libnoise: http://github.com/qknight/libnoise/tree/master/doc/
# following code and comments is by the original author, with some changes by
# me (peterix)
# ------------------------------------------------------------------------------
#
# many thanks go to Philippe Poilbarbe for writing the code this file is based on
# http://www.cmake.org/pipermail/cmake/2006-August/010794.html
#
# much later i also found this:
# http://tobias.rautenkranz.ch/cmake/doxygen/
# but it is hard to understand...
IF (BUILD_DFHACK_DOCUMENTATION)
FIND_PACKAGE(Doxygen)
IF(DOXYGEN_FOUND)
SET(DOXYGEN_LANGUAGE "English" CACHE STRING "Language used by doxygen")
MARK_AS_ADVANCED(DOXYGEN_LANGUAGE)
# you could also set the version with this, see Doxygen.in
# there you will find a line like this:
# PROJECT_NUMBER = @DFHACK_VERSION@
# @DFHACK_VERSION@ is then replaced by our global DFHACK_VERSION
#
# for instance you could uncomment the next 3 lines and change the version for testing
# SET(DFHACK_VERSION
# "1.2.3-foo500"
# )
# doxygen can reference external images with IMAGE_PATH, this is how we set it dynamically
SET( CMAKE_DOXYGEN_IMAGE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/img"
)
# doxygen searches for source code (defined in FILE_PATTERNS, for example: *.cpp *.h)
# with DOXYGEN_SOURCE_DIR we fill a list of directories and later we write it into
# the Doxyfile with a REGEX REPLACE (see below)
SET( DOXYGEN_SOURCE_DIR
# "${CMAKE_SOURCE_DIR}/library"
"${CMAKE_SOURCE_DIR}/doc/index.dxgen"
"${CMAKE_SOURCE_DIR}/library/include"
"${CMAKE_SOURCE_DIR}/library/include/dfhack"
"${CMAKE_SOURCE_DIR}/library/include/dfhack/modules"
"${CMAKE_SOURCE_DIR}/library/include/dfhack-c"
"${CMAKE_SOURCE_DIR}/library/include/dfhack-c/modules"
# "${CMAKE_SOURCE_DIR}/library/modules"
# "${CMAKE_SOURCE_DIR}/library/shm"
# "${CMAKE_SOURCE_DIR}/library/private"
)
SET(DOXYGEN_OUTPUT_DIR html)
STRING(REGEX REPLACE ";" " " CMAKE_DOXYGEN_INPUT_LIST "${DOXYGEN_SOURCE_DIR}")
CONFIGURE_FILE(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
SET(HTML_TARGET "html" )
ADD_CUSTOM_TARGET(${HTML_TARGET} ALL
/usr/bin/doxygen ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
INSTALL( DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html/" DESTINATION "/usr/share/doc/dfhack-${DFHACK_VERSION}" )
ELSE(DOXYGEN_FOUND)
MESSAGE (FATAL_ERROR "doxygen binary couldn't be found")
ENDIF(DOXYGEN_FOUND)
ENDIF (BUILD_DFHACK_DOCUMENTATION)

@ -0,0 +1,212 @@
# Doxyfile 1.3.9.1
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = dfhack
PROJECT_NUMBER = @DFHACK_VERSION@
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @CMAKE_DOXYGEN_INPUT_LIST@
FILE_PATTERNS = *.cpp *.h *.dxgen
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH = @CMAKE_DOXYGEN_IMAGE_PATH@
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 8
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = NO
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 0
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

@ -0,0 +1,73 @@
/*******************************************************************************
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/*! \page index
<center>
\htmlonly
<h1>DFHack</h1>
<!--<img src="logo.png" alt="DFHack"/><br/>-->
\endhtmlonly
</center>
<h2>Introduction</h2>
DFHack is a Dwarf Fortress memory access library and a set of basic tools using
this library. The library is a work in progress, so things might change as more
tools are written for it.
It is an attempt to unite the various ways tools access DF memory and allow for
easier development of new tools. In general, you can use it to move memory
objects in and out of Dwarf Fortress really fast, regardless of DF version or OS.
First part of the manual deals with the basic of using DFHack as a library:
<ul>
PLACEHOLDER TERRITORY!
<li>Section \ref blah discusses some weird stuff
<a href="target">this is a link</a>
<li>Section \ref starting tells you how to cromulate at a distance!
</ul>
Second part has some details on DFHack development:
<ul>
<li>Section \ref starting tells you how to cromulate at a distance!
</ul>
The third part describes how to use the supported DFHack utilities
<ul>
<li>Section \ref dfattachtest shows how to use the \c dfattachtest program
<li>Section \ref dfcleanmap shows how to use the \c dfcleanmap program
<li>Section \ref dfexpbench shows how to use the \c dfexpbench program
<li>Section \ref dfflows shows how to use the \c dfflows program
<li>Section \ref dfliquids shows how to use the \c dfliquids program
<li>Section \ref dfprobe shows how to use the \c dfprobe program
<li>Section \ref dfprospector shows how to use the \c dfprospector program
<li>Section \ref dfreveal shows how to use the \c dfreveal program
<li>Section \ref dfsuspend shows how to use the \c dfsuspend program
<li>Section \ref dfunstuck shows how to use the \c dfunstuck program
<li>Section \ref dfvdig shows how to use the \c dfvdig program
</ul>
*/

@ -0,0 +1,3 @@
#!/bin/bash
rst2html README.rst > Readme.html
rst2html COMPILE.rst > Compile.html

@ -27,9 +27,11 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/)
include_directories (${CMAKE_SOURCE_DIR}/library/private/)
SET(PROJECT_HDRS
private/DFMemInfoManager.h
private/ContextShared.h
private/Internal.h
include/dfhack/DFError.h
include/dfhack/DFMemInfo.h
include/dfhack/DFMemInfoManager.h
include/dfhack/DFProcessEnumerator.h
include/dfhack/DFProcess.h
include/dfhack/DFTileTypes.h
@ -52,14 +54,18 @@ include/dfhack/modules/WindowIO.h
include/dfhack/modules/World.h
)
SET(PROJECT_C_HDRS
include/dfhack-c/DFTypes_C.h
include/dfhack-c/DFContext_C.h
)
SET(PROJECT_SRCS
DFMemInfo.cpp
DFMemInfoManager.cpp
DFContextManager.cpp
DFContext.cpp
DFProcessEnumerator.cpp
ContextShared.cpp
DFContext_C.cpp
DFTypes_C.cpp
depends/md5/md5.cpp
depends/md5/md5wrapper.cpp
@ -80,6 +86,11 @@ modules/Position.cpp
modules/Translation.cpp
modules/Vegetation.cpp
modules/World.cpp
)
SET(PROJECT_C_SRCS
DFContext_C.cpp
DFTypes_C.cpp
modules/Buildings_C.cpp
modules/Constructions_C.cpp
@ -91,6 +102,8 @@ modules/Position_C.cpp
modules/Materials_C.cpp
modules/Translation_C.cpp
modules/Vegetation_C.cpp
modules/WindowIO_C.cpp
modules/World_C.cpp
)
SET(PROJECT_HDRS_LINUX
@ -105,14 +118,12 @@ DFProcess-linux.cpp
DFProcess-linux-SHM.cpp
DFProcess-linux-wine.cpp
modules/WindowIO-linux.cpp
DFProcessEnumerator-linux.cpp
)
SET(PROJECT_SRCS_WINDOWS
DFProcess-windows.cpp
DFProcess-windows-SHM.cpp
modules/WindowIO-windows.cpp
DFProcessEnumerator-windows.cpp
)
IF(UNIX)
@ -123,6 +134,11 @@ ELSE(UNIX)
LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS})
ENDIF(UNIX)
IF(BUILD_DFHACK_C_BINDIGS)
LIST(APPEND PROJECT_HDRS ${PROJECT_C_HDRS})
LIST(APPEND PROJECT_SRCS ${PROJECT_C_SRCS})
ENDIF(BUILD_DFHACK_C_BINDIGS)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE )
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
@ -161,65 +177,29 @@ SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" )
TARGET_LINK_LIBRARIES(dfhack ${PROJECT_LIBS})
if(MSVC)
# This is a MSVC hack used for copying files into the target directory
# of build target set in MSVC.
# It exploits the fact that MSVC has some variables in .vcproj files, much like cmake does here.
#
# So, $(TargetDir) is ignored by cmake, and replaced with the actual output directory by MSVC
ADD_CUSTOM_COMMAND(TARGET dfhack POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/data/Memory.xml $(TargetDir)/Memory.xml
)
ADD_CUSTOM_COMMAND(TARGET dfhack POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Compile.html $(TargetDir)/Compile.html
)
ADD_CUSTOM_COMMAND(TARGET dfhack POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Readme.html $(TargetDir)/Readme.html
)
else(MSVC)
# Just put the file in the output directory on Linux and Mac
configure_file(${CMAKE_SOURCE_DIR}/data/Memory.xml ${DATA_OUTPUT_PATH}/Memory.xml COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/Compile.html ${DATA_OUTPUT_PATH}/Compile.html COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/Readme.html ${DATA_OUTPUT_PATH}/Readme.html COPYONLY)
endif(MSVC)
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)

@ -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()

@ -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 <shms.h>
@ -89,10 +88,18 @@ bool Context::Detach()
{
if (!d->p->detach())
{
cerr << "Context::Detach failed!" << endl;
return false;
}
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 +154,7 @@ bool Context::Detach()
{
delete d->translation;
d->translation = 0;
}
}*/
return true;
}
@ -167,6 +174,10 @@ bool Context::AsyncSuspend()
bool Context::Resume()
{
for(int i = 0 ; i < d->allModules.size(); i++)
{
d->allModules[i]->OnResume();
}
return d->p->resume();
}
bool Context::ForceResume()
@ -201,13 +212,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 +321,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

@ -23,10 +23,10 @@ distribution.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h"
#include "dfhack/DFContext.h"
@ -41,61 +41,186 @@ distribution.
using namespace DFHack;
namespace DFHack
{
class DFContextMgrPrivate
class ContextManager::Private
{
public:
DFContextMgrPrivate(){};
~DFContextMgrPrivate(){};
Private(){};
~Private(){};
string xml; // path to xml
vector <Context *> contexts;
ProcessEnumerator * pEnum;
};
}
class DFHack::BadContexts::Private
{
public:
Private(){};
vector <Context *> bad;
};
BadContexts::BadContexts():d(new Private()){}
BadContexts::~BadContexts()
{
clear();
delete d;
}
bool BadContexts::Contains(Process* p)
{
for(int i = 0; i < d->bad.size(); i++)
{
if((d->bad[i])->getProcess() == p)
return true;
}
return false;
}
ContextManager::ContextManager (const string path_to_xml) : d (new DFContextMgrPrivate())
bool BadContexts::Contains(Context* c)
{
for(int i = 0; i < d->bad.size(); i++)
{
if(d->bad[i] == c)
return true;
}
return false;
}
uint32_t BadContexts::size()
{
return d->bad.size();
}
void BadContexts::clear()
{
for(int i = 0; i < d->bad.size(); i++)
{
// delete both Process and Context!
// process has to be deleted after context, because Context does some
// cleanup on delete (detach, etc.)
Process * to_kill = d->bad[i]->getProcess();
delete d->bad[i];
delete to_kill;
}
d->bad.clear();
}
void BadContexts::push_back(Context* c)
{
if(c)
d->bad.push_back(c);
}
Context * BadContexts::operator[](uint32_t index)
{
if(index < d->bad.size())
return d->bad[index];
return 0;
}
ContextManager::ContextManager (const string path_to_xml) : d (new Private())
{
d->pEnum = 0;
d->xml = QUOT (MEMXML_DATA_PATH);
d->xml += "/";
d->xml += path_to_xml;
d->pEnum = new ProcessEnumerator(d->xml);
}
ContextManager::~ContextManager()
{
purge();
// process enumerator has to be destroyed after we detach from processes
// because it tracks and destroys them
if(d->pEnum)
{
delete d->pEnum;
d->pEnum = 0;
}
delete d;
}
uint32_t ContextManager::Refresh()
uint32_t ContextManager::Refresh( BadContexts* bad_contexts )
{
purge();
if(d->pEnum != 0)
d->pEnum = new ProcessEnumerator(d->xml);
else
// handle expired processes, remove stale Contexts
{
delete d->pEnum;
d->pEnum = new ProcessEnumerator(d->xml);
BadProcesses expired;
// get new list od living and expired Process objects
d->pEnum->Refresh(&expired);
// scan expired, kill contexts if necessary
vector <Context*>::iterator it = d->contexts.begin();;
while(it != d->contexts.end())
{
Process * test = (*it)->getProcess();
if(expired.Contains(test))
{
// ok. we have an expired context here.
if(!bad_contexts)
{
// with nowhere to put the context, we have to destroy it
delete *it;
// stop tracking it and advance the iterator
it = d->contexts.erase(it);
continue;
}
else
{
// we stuff the context into bad_contexts
bad_contexts->push_back(*it);
// stop tracking it and advance the iterator
it = d->contexts.erase(it);
// remove process from the 'expired' container, it is tracked by bad_contexts now
// (which is responsible for freeing it).
expired.excise(test);
continue;
}
}
else it++; // not expired, just advance to next one
}
// no expired contexts are in the d->contexts vector now
// all processes remaining in 'expired' are now destroyed along with it
}
d->pEnum->purge();
d->pEnum->findProcessess();
int numProcesses = d->pEnum->size();
int numContexts = d->contexts.size();
vector <Context *> newContexts;
// enumerate valid processes
for(int i = 0; i < numProcesses; i++)
{
Context * c = new Context(d->pEnum->operator[](i));
d->contexts.push_back(c);
Process * test = d->pEnum->operator[](i);
bool exists = false;
// scan context vector for this process
for(int j = 0; j < numContexts; j++)
{
if((d->contexts[j])->getProcess() == test)
{
// already have that one, skip
exists = true;
}
}
if(!exists)
{
// new process needs a new context
Context * c = new Context(d->pEnum->operator[](i));
newContexts.push_back(c);
}
}
d->contexts.insert(d->contexts.end(), newContexts.begin(), newContexts.end());
return d->contexts.size();
}
uint32_t ContextManager::size()
{
return d->contexts.size();
}
Context * ContextManager::operator[](uint32_t index)
{
if (index < d->contexts.size())
return d->contexts[index];
return 0;
}
Context * ContextManager::getSingleContext()
{
if(!d->contexts.size())
@ -111,16 +236,11 @@ Context * ContextManager::getSingleContext()
}
throw DFHack::Error::NoProcess();
}
void ContextManager::purge(void)
{
for(int i = 0; i < d->contexts.size();i++)
delete d->contexts[i];
d->contexts.clear();
// process enumerator has to be destroyed after we detach from processes
// because it tracks and destroys them
if(d->pEnum)
{
delete d->pEnum;
d->pEnum = 0;
}
d->pEnum->purge();
}

@ -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;

@ -27,8 +27,60 @@ distribution.
#include "dfhack/DFError.h"
#include "dfhack/DFProcess.h"
//Inital amount of space in levels vector (since we usually know the number, efficent!)
#define NUM_RESERVE_LVLS 20
#define NUM_RESERVE_MOODS 6
using namespace DFHack;
/*
* Common data types
*/
namespace DFHack
{
struct t_type
{
t_type(uint32_t assign, uint32_t type, std::string classname)
:classname(classname),assign(assign),type(type){};
std::string classname;
uint32_t assign;
uint32_t type;
};
struct t_class
{
t_class(const t_class &old)
{
classname = old.classname;
vtable = old.vtable;
assign = old.assign;
type_offset = old.type_offset;
for(uint32_t i = 0; i < old.subs.size();i++)
{
t_type * t = new t_type (*old.subs[i]);
subs.push_back(t);
}
}
t_class ()
{
vtable = 0;
assign = 0;
type_offset = 0;
}
~t_class()
{
for(uint32_t i = 0; i < subs.size();i++)
{
delete subs[i];
}
subs.clear();
}
std::string classname;
uint32_t vtable;
uint32_t assign;// index to typeclass array if multiclass. return value if not.
uint32_t type_offset; // offset of type data for multiclass
std::vector<t_type *> subs;
};
}
/*
* Private data
*/
@ -43,7 +95,9 @@ class memory_info::Private
vector<string> professions;
vector<string> jobs;
vector<string> skills;
vector<DFHack::t_level> levels;
vector< vector<string> > traits;
vector<string> moods;
map <uint32_t, string> labors;
// storage for class and multiclass
@ -71,6 +125,8 @@ memory_info::memory_info()
d->base = 0;
d->p = 0;
d->classindex = 0;
d->levels.reserve(NUM_RESERVE_LVLS);
d->moods.reserve(NUM_RESERVE_MOODS);
}
// copy constructor
@ -97,6 +153,8 @@ memory_info::memory_info(const memory_info &old)
d->skills = old.d->skills;
d->traits = old.d->traits;
d->labors = old.d->labors;
d->levels = old.d->levels;
d->moods = old.d->moods;
}
void memory_info::setParentProcess(Process * _p)
{
@ -251,6 +309,30 @@ void memory_info::setSkill (const string & key, const string & value)
d->skills[keyInt] = value;
}
void memory_info::setLevel(const std::string &nLevel,
const std::string &nName,
const std::string &nXp)
{
uint32_t keyInt = strtol(nLevel.c_str(), NULL, 10);
if(d->levels.size() <= keyInt)
d->levels.resize(keyInt+1);
d->levels[keyInt].level = keyInt;
d->levels[keyInt].name = nName;
d->levels[keyInt].xpNxtLvl = strtol(nXp.c_str(), NULL, 10);
}
void memory_info::setMood(const std::string &id, const std::string &mood)
{
uint32_t keyInt = strtol(id.c_str(), NULL, 10);
if(d->moods.size() <= keyInt)
d->moods.resize(keyInt+1);
d->moods[keyInt] = mood;
}
void memory_info::setTrait(const string & key,
const string & value,
const string & zero,
@ -564,6 +646,7 @@ string memory_info::getProfession (const uint32_t key) const
string memory_info::getJob (const uint32_t key) const
{
if(d->jobs.size() > key)
{
return d->jobs[key];
}
@ -579,6 +662,15 @@ string memory_info::getSkill (const uint32_t key) const
throw Error::MissingMemoryDefinition("skill", key);
}
DFHack::t_level memory_info::getLevelInfo(const uint32_t level) const
{
if(d->levels.size() > level)
{
return d->levels[level];
}
throw Error::MissingMemoryDefinition("Level", level);
}
// FIXME: ugly hack that needs to die
int absolute (int number)
{
@ -621,6 +713,11 @@ string memory_info::getTraitName(const uint32_t traitIdx) const
throw Error::MissingMemoryDefinition("traitname", traitIdx);
}
std::vector< std::vector<std::string> > const& memory_info::getAllTraits()
{
return d->traits;
}
string memory_info::getLabor (const uint32_t laborIdx)
{
if(d->labors.count(laborIdx))
@ -630,3 +727,52 @@ string memory_info::getLabor (const uint32_t laborIdx)
throw Error::MissingMemoryDefinition("labor", laborIdx);
}
std::string memory_info::getMood(const uint32_t moodID)
{
if(d->moods.size() > moodID)
{
return d->moods[moodID];
}
throw Error::MissingMemoryDefinition("Mood", moodID);
}
std::string memory_info::PrintOffsets()
{
ostringstream ss;
ss << "<Version name=\"" << getVersion() << "\">" << endl;
switch (getOS())
{
case OS_LINUX:
ss << "<MD5 value=\"" << getString("md5") << "\" />" << endl;
break;
case OS_WINDOWS:
ss << "<PETimeStamp value=\"" << hex << "0x" << getHexValue("pe_timestamp") << "\" />" << endl;
ss << "<MD5 value=\"" << getString("md5") << "\" />" << endl;
break;
default:
ss << " UNKNOWN" << endl;
}
ss << "<Offsets>" << endl;
map<string,uint32_t>::const_iterator iter;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
{
ss << " <Address name=\"" << (*iter).first << "\" value=\"" << hex << "0x" << (*iter).second << "\" />" << endl;
}
map<string,int32_t>::const_iterator iter2;
for(iter2 = d->offsets.begin(); iter2 != d->offsets.end(); iter2++)
{
ss << " <Offset name=\"" << (*iter2).first << "\" value=\"" << hex << "0x" << (*iter2).second <<"\" />" << endl;
}
for(iter = d->hexvals.begin(); iter != d->hexvals.end(); iter++)
{
ss << " <HexValue name=\"" << (*iter).first << "\" value=\"" << hex << "0x" << (*iter).second <<"\" />" << endl;
}
map<string,string>::const_iterator iter3;
for(iter3 = d->strings.begin(); iter3 != d->strings.end(); iter3++)
{
ss << " <String name=\"" << (*iter3).first << "\" value=\"" << (*iter3).second <<"\" />" << endl;
}
ss << "</Offsets>" << endl;
ss << "</Version>" << endl;
return ss.str();
}

@ -23,8 +23,9 @@ distribution.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h"
using namespace DFHack;
@ -151,8 +152,12 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
{
// only elements get processed
const char *cstr_type = pMemEntry->Value();
const char *cstr_name = pMemEntry->Attribute("name");
const char *cstr_name = pMemEntry->Attribute("name");
const char *cstr_value = pMemEntry->GetText();
if(!cstr_value)
cstr_value = pMemEntry->Attribute("id");
// check for missing parts
string type, name, value;
type = cstr_type;
@ -203,6 +208,14 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
{
mem->setLabor(value,name);
}
else if (type == "Level")
{
mem->setLevel(value, name, pMemEntry->Attribute("xpNxtLvl"));
}
else if (type == "Mood")
{
mem->setMood(value, name);
}
else
{
throw Error::MemoryXmlUnknownType(type.c_str());

@ -569,10 +569,7 @@ bool SHMProcess::attach()
bool SHMProcess::detach()
{
if(!d->attached)
{
return false;
}
if(!d->attached) return true;
if(d->locked)
{
resume();
@ -714,7 +711,7 @@ float SHMProcess::readFloat (const uint32_t offset)
D_SHMHDR->address = offset;
gcc_barrier
d->SetAndWait(CORE_READ_DWORD);
return D_SHMHDR->value;
return reinterpret_cast<float&> (D_SHMHDR->value);
}
void SHMProcess::readFloat (const uint32_t offset, float &val)
{
@ -723,7 +720,7 @@ void SHMProcess::readFloat (const uint32_t offset, float &val)
D_SHMHDR->address = offset;
gcc_barrier
d->SetAndWait(CORE_READ_DWORD);
val = D_SHMHDR->value;
val = reinterpret_cast<float&> (D_SHMHDR->value);
}
/*

@ -331,7 +331,7 @@ bool WineProcess::attach()
bool WineProcess::detach()
{
if(!d->attached) return false;
if(!d->attached) return true;
if(!d->suspended) suspend();
int result = 0;
// close /proc/PID/mem
@ -367,9 +367,11 @@ void WineProcess::read (const uint32_t offset, const uint32_t size, uint8_t *tar
if(size == 0) return;
ssize_t result;
result = pread(d->memFileHandle, target,size,offset);
if(result != size)
ssize_t total = 0;
ssize_t remaining = size;
while (total != size)
{
result = pread(d->memFileHandle, target + total ,remaining,offset + total);
if(result == -1)
{
cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl;
@ -379,7 +381,8 @@ void WineProcess::read (const uint32_t offset, const uint32_t size, uint8_t *tar
}
else
{
read(offset + result, size - result, target + result);
total += result;
remaining -= result;
}
}
}

@ -86,7 +86,7 @@ NormalProcess::NormalProcess(uint32_t pid, vector< memory_info* >& known_version
target_name[target_result] = 0;
// is this the regular linux DF?
if (strstr(target_name, "dwarfort.exe") != NULL)
if (strstr(target_name, "dwarfort.exe") != 0 || strstr(target_name,"Dwarf_Fortress") != 0)
{
// create linux process, add it to the vector
d->identified = d->validate(target_name,pid,mem_name,known_versions );
@ -318,7 +318,7 @@ bool NormalProcess::attach()
bool NormalProcess::detach()
{
if(!d->attached) return false;
if(!d->attached) return true;
if(!d->suspended) suspend();
int result = 0;
// close /proc/PID/mem

@ -632,10 +632,7 @@ bool SHMProcess::attach()
bool SHMProcess::detach()
{
if(!d->attached)
{
return false;
}
if(!d->attached) return true;
//cerr << "detach" << endl;// FIXME: throw
if(d->locked)
{
@ -756,7 +753,7 @@ float SHMProcess::readFloat (const uint32_t offset)
D_SHMHDR->address = offset;
full_barrier
d->SetAndWait(CORE_READ_DWORD);
return (float) D_SHMHDR->value;
return reinterpret_cast<float&> (D_SHMHDR->value);
}
void SHMProcess::readFloat (const uint32_t offset, float &val)
{
@ -765,7 +762,7 @@ void SHMProcess::readFloat (const uint32_t offset, float &val)
D_SHMHDR->address = offset;
full_barrier
d->SetAndWait(CORE_READ_DWORD);
val = (float) D_SHMHDR->value;
val = reinterpret_cast<float&> (D_SHMHDR->value);
}
uint64_t SHMProcess::readQuad (const uint32_t offset)
{

@ -249,10 +249,7 @@ bool NormalProcess::attach()
bool NormalProcess::detach()
{
if(!d->attached)
{
return false;
}
if(!d->attached) return true;
resume();
d->attached = false;
return true;

@ -1,135 +0,0 @@
/*
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.
*/
#include "Internal.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <time.h>
#include "shms.h"
using namespace DFHack;
class DFHack::ProcessEnumerator::Private
{
public:
Private(){};
MemInfoManager *meminfo;
std::vector<Process *> processes;
};
bool ProcessEnumerator::findProcessess()
{
DIR *dir_p;
struct dirent *dir_entry_p;
// Open /proc/ directory
dir_p = opendir("/proc/");
// Reading /proc/ entries
while(NULL != (dir_entry_p = readdir(dir_p)))
{
// Only PID folders (numbers)
if (strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
{
continue;
}
Process *p1 = new SHMProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
if(p1->isIdentified())
{
d->processes.push_back(p1);
continue;
}
else
{
delete p1;
}
Process *p2 = new NormalProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
if(p2->isIdentified())
{
d->processes.push_back(p2);
continue;
}
else
{
delete p2;
}
Process *p3 = new WineProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
if(p3->isIdentified())
{
d->processes.push_back(p3);
continue;
}
else
{
delete p3;
}
}
closedir(dir_p);
// return value depends on if we found some DF processes
if(d->processes.size())
{
return true;
}
return false;
}
uint32_t ProcessEnumerator::size()
{
return d->processes.size();
}
Process * ProcessEnumerator::operator[](uint32_t index)
{
assert(index < d->processes.size());
return d->processes[index];
}
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
: d(new Private())
{
d->meminfo = new MemInfoManager(path_to_xml);
}
void ProcessEnumerator::purge()
{
for(uint32_t i = 0;i < d->processes.size();i++)
{
delete d->processes[i];
}
d->processes.clear();
}
ProcessEnumerator::~ProcessEnumerator()
{
// delete all processes
purge();
delete d->meminfo;
delete d;
}

@ -1,147 +0,0 @@
/*
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.
*/
#include "Internal.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
using namespace DFHack;
class DFHack::ProcessEnumerator::Private
{
public:
Private(){};
MemInfoManager *meminfo;
std::vector<Process *> processes;
};
// some magic - will come in handy when we start doing debugger stuff on Windows
bool EnableDebugPriv()
{
bool bRET = FALSE;
TOKEN_PRIVILEGES tp;
HANDLE hToken;
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
{
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
if (hToken != INVALID_HANDLE_VALUE)
{
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.PrivilegeCount = 1;
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0))
{
bRET = TRUE;
}
CloseHandle(hToken);
}
}
}
return bRET;
}
// WINDOWS version of the process finder
bool ProcessEnumerator::findProcessess()
{
// Get the list of process identifiers.
DWORD ProcArray[2048], memoryNeeded, numProccesses;
//EnableDebugPriv();
if ( !EnumProcesses( ProcArray, sizeof(ProcArray), &memoryNeeded ) )
{
cout << "EnumProcesses fail'd" << endl;
return false;
}
// Calculate how many process identifiers were returned.
numProccesses = memoryNeeded / sizeof(DWORD);
EnableDebugPriv();
// iterate through processes
for ( int i = 0; i < (int)numProccesses; i++ )
{
Process *p = new SHMProcess(ProcArray[i],d->meminfo->meminfo);
if(p->isIdentified())
{
d->processes.push_back(p);
continue;
}
else
{
delete p;
p = 0;
}
p = new NormalProcess(ProcArray[i],d->meminfo->meminfo);
if(p->isIdentified())
{
d->processes.push_back(p);
continue;
}
else
{
delete p;
p = 0;
}
}
if(d->processes.size())
return true;
return false;
}
uint32_t ProcessEnumerator::size()
{
return d->processes.size();
};
Process * ProcessEnumerator::operator[](uint32_t index)
{
assert(index < d->processes.size());
return d->processes[index];
};
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
: d(new Private())
{
d->meminfo = new MemInfoManager(path_to_xml);
}
void ProcessEnumerator::purge()
{
for(uint32_t i = 0;i < d->processes.size();i++)
{
delete d->processes[i];
}
d->processes.clear();
}
ProcessEnumerator::~ProcessEnumerator()
{
// delete all processes
purge();
delete d->meminfo;
delete d;
}

@ -0,0 +1,380 @@
/*
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.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFMemInfo.h"
using namespace DFHack;
typedef std::vector<Process *> PROC_V;
typedef std::map<ProcessID, Process*> PID2PROC;
class DFHack::ProcessEnumerator::Private
{
public:
Private(){};
MemInfoManager *meminfo;
PROC_V Processes;
PID2PROC ProcMap;
Process *GetProcessObject(ProcessID ID);
void EnumPIDs (vector <ProcessID> &PIDs);
};
class DFHack::BadProcesses::Private
{
public:
Private(){};
PROC_V bad;
};
BadProcesses::BadProcesses():d(new Private()){}
BadProcesses::~BadProcesses()
{
clear();
delete d;
}
bool BadProcesses::Contains(Process* p)
{
for(int i = 0; i < d->bad.size(); i++)
{
if(d->bad[i] == p)
return true;
}
return false;
}
bool BadProcesses::excise(Process* p)
{
vector<Process*>::iterator it = d->bad.begin();
while(it != d->bad.end())
{
if((*it) == p)
{
d->bad.erase(it);
return true;
}
else
{
it++;
}
}
return false;
}
uint32_t BadProcesses::size()
{
return d->bad.size();
}
void BadProcesses::clear()
{
for(int i = 0; i < d->bad.size(); i++)
{
delete d->bad[i];
}
d->bad.clear();
}
void BadProcesses::push_back(Process* p)
{
if(p)
d->bad.push_back(p);
}
Process * BadProcesses::operator[](uint32_t index)
{
if(index < d->bad.size())
return d->bad[index];
return 0;
}
//FIXME: wasteful
Process *ProcessEnumerator::Private::GetProcessObject(ProcessID ID)
{
Process *p1 = new SHMProcess(ID.pid,meminfo->meminfo);
if(p1->isIdentified())
return p1;
else
delete p1;
Process *p2 = new NormalProcess(ID.pid,meminfo->meminfo);
if(p2->isIdentified())
return p2;
else
delete p2;
#ifdef LINUX_BUILD
Process *p3 = new WineProcess(ID.pid,meminfo->meminfo);
if(p3->isIdentified())
return p3;
else
delete p3;
#endif
return 0;
}
#ifdef LINUX_BUILD
void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
{
DIR *dir_p;
struct dirent *dir_entry_p;
struct stat st;
char fullname[512];
fullname[0] = 0;
PIDs.clear(); // make sure the vector is clear
// Open /proc/ directory
dir_p = opendir("/proc/");
// Reading /proc/ entries
while(NULL != (dir_entry_p = readdir(dir_p)))
{
// Only PID folders (numbers)
if (strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
{
continue;
}
sprintf(fullname, "/proc/%s", dir_entry_p->d_name);
int ierr = stat (fullname, &st);
if (ierr != 0)
{
printf("Cannot stat %s: ierr= %d\n", fullname, ierr);
continue;
}
uint64_t Pnum = atoi(dir_entry_p->d_name);
uint64_t ctime = st.st_ctime;
PIDs.push_back(ProcessID(ctime,Pnum));
}
closedir(dir_p);
}
#endif
#ifndef LINUX_BUILD
// some magic - will come in handy when we start doing debugger stuff on Windows
bool EnableDebugPriv()
{
bool bRET = FALSE;
TOKEN_PRIVILEGES tp;
HANDLE hToken;
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
{
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
if (hToken != INVALID_HANDLE_VALUE)
{
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.PrivilegeCount = 1;
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0))
{
bRET = TRUE;
}
CloseHandle(hToken);
}
}
}
return bRET;
}
typedef union
{
struct
{
uint32_t LowDword;
uint32_t HighDword;
};
uint64_t Quad;
} TWO_DWORDS;
// Convert Windows FileTime structs to POSIX timestamp
// from http://frenk.wordpress.com/2009/12/14/convert-filetime-to-unix-timestamp/
uint64_t FileTime_to_POSIX(FILETIME ft)
{
// takes the last modified date
TWO_DWORDS date, adjust;
date.HighDword = ft.dwHighDateTime;
date.LowDword = ft.dwLowDateTime;
// 100-nanoseconds = milliseconds * 10000
adjust.Quad = 11644473600000LL * 10000LL;
// removes the diff between 1970 and 1601
date.Quad -= adjust.Quad;
// converts back from 100-nanoseconds to seconds
return date.Quad / 10000000LL;
}
void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
{
FILETIME ftCreate, ftExit, ftKernel, ftUser;
PIDs.clear(); // make sure the vector is clear
// Get the list of process identifiers.
DWORD ProcArray[2048], memoryNeeded, numProccesses;
//EnableDebugPriv();
if ( !EnumProcesses( ProcArray, sizeof(ProcArray), &memoryNeeded ) )
{
cout << "EnumProcesses fail'd" << endl;
return;
}
// Calculate how many process identifiers were returned.
numProccesses = memoryNeeded / sizeof(DWORD);
EnableDebugPriv();
// iterate through processes
for ( int i = 0; i < (int)numProccesses; i++ )
{
HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION, false, ProcArray[i]);
if(!proc)
continue;
if(GetProcessTimes(proc, &ftCreate, &ftExit, &ftKernel, &ftUser))
{
uint64_t ctime = FileTime_to_POSIX(ftCreate);
uint64_t Pnum = ProcArray[i];
PIDs.push_back(ProcessID(ctime,Pnum));
}
CloseHandle(proc);
}
}
#endif
bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes )
{
// PIDs to process
vector <ProcessID> PIDs;
// this will be the new process map
PID2PROC temporary;
// clear the vector
d->Processes.clear();
if(invalidated_processes)
invalidated_processes->clear();
d->EnumPIDs(PIDs);
for(uint64_t i = 0; i < PIDs.size();i++)
{
ProcessID & PID = PIDs[i];
// check if we know about the OS process already
PID2PROC::iterator found= d->ProcMap.find(PID);
if( found != d->ProcMap.end())
{
// we do
// check if it does have a DFHack Process object associated with it
Process * p = (*found).second;
if(p)
{
// add it back to the vector we export
d->Processes.push_back(p);
}
// remove the OS Process from ProcMap
d->ProcMap.erase(found);
// add the OS Process to what will be the new ProcMap
temporary[PID] = p;
}
else
{
// an OS process we don't know yet!
// try to make a DFHack Process object for it
if(Process*p = d->GetProcessObject(PID))
{
// allright. this is something that can be used
d->Processes.push_back(p);
temporary[PID] = p;
}
else
{
// just a process. we track it anyway. Why not.
temporary[PID] = 0;
}
}
}
// now the vector we export is filled again and a temporary map with valid processes is created.
// we iterate over the old Process map and destroy all the processes that are dead.
for(PID2PROC::const_iterator idx = d->ProcMap.begin(); idx != d->ProcMap.end();++idx)
{
Process * p = (*idx).second;
if(p)
{
if(invalidated_processes)
{
invalidated_processes->push_back(p);
}
else
{
delete p;
}
}
}
d->ProcMap.swap(temporary);
// return value depends on if we found some DF processes
if(d->Processes.size())
{
return true;
}
return false;
}
uint32_t ProcessEnumerator::size()
{
return d->Processes.size();
}
Process * ProcessEnumerator::operator[](uint32_t index)
{
assert(index < d->Processes.size());
return d->Processes[index];
}
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
: d(new Private())
{
d->meminfo = new MemInfoManager(path_to_xml);
}
void ProcessEnumerator::purge()
{
for(uint32_t i = 0;i < d->Processes.size();i++)
{
delete d->Processes[i];
}
d->ProcMap.clear();
d->Processes.clear();
}
ProcessEnumerator::~ProcessEnumerator()
{
// delete all processes
purge();
delete d->meminfo;
delete d;
}

@ -23,6 +23,7 @@ distribution.
*/
#include "dfhack/DFIntegers.h"
#include "dfhack/DFTileTypes.h"
#include <stdlib.h>
#include "string.h"
#include <vector>
@ -41,31 +42,65 @@ using namespace DFHack;
extern "C" {
#endif
int8_t* (*alloc_byte_buffer_callback)(uint32_t) = NULL;
int16_t* (*alloc_short_buffer_callback)(uint32_t) = NULL;
int32_t* (*alloc_int_buffer_callback)(uint32_t) = NULL;
int (*alloc_byte_buffer_callback)(int8_t*, uint32_t) = NULL;
int (*alloc_short_buffer_callback)(int16_t*, uint32_t) = NULL;
int (*alloc_int_buffer_callback)(int32_t*, uint32_t) = NULL;
uint8_t* (*alloc_ubyte_buffer_callback)(uint32_t) = NULL;
uint16_t* (*alloc_ushort_buffer_callback)(uint32_t) = NULL;
uint32_t* (*alloc_uint_buffer_callback)(uint32_t) = NULL;
int (*alloc_ubyte_buffer_callback)(uint8_t*, uint32_t) = NULL;
int (*alloc_ushort_buffer_callback)(uint16_t*, uint32_t) = NULL;
int (*alloc_uint_buffer_callback)(uint32_t*, uint32_t) = NULL;
char* (*alloc_char_buffer_callback)(uint32_t) = NULL;
int (*alloc_char_buffer_callback)(char*, uint32_t) = NULL;
t_matgloss* (*alloc_matgloss_buffer_callback)(int) = NULL;
t_descriptor_color* (*alloc_descriptor_buffer_callback)(int) = NULL;
t_matglossOther* (*alloc_matgloss_other_buffer_callback)(int) = NULL;
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;
c_colormodifier* (*alloc_empty_colormodifier_callback)(void) = NULL;
c_colormodifier* (*alloc_colormodifier_callback)(const char*, uint32_t) = NULL;
c_colormodifier* (*alloc_colormodifier_buffer_callback)(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;
c_creaturecaste* (*alloc_empty_creaturecaste_callback)(void) = NULL;
c_creaturecaste* (*alloc_creaturecaste_callback)(const char*, const char*, const char*, const char*, uint32_t, uint32_t) = NULL;
c_creaturecaste* (*alloc_creaturecaste_buffer_callback)(uint32_t) = NULL;
int (*alloc_empty_creaturecaste_callback)(c_creaturecaste*)= NULL;
int (*alloc_creaturecaste_callback)(c_creaturecaste*, const char*, const char*, const char*, const char*, uint32_t, uint32_t) = NULL;
int (*alloc_creaturecaste_buffer_callback)(c_creaturecaste*, uint32_t) = NULL;
c_creaturetype* (*alloc_empty_creaturetype_callback)(void) = NULL;
c_creaturetype* (*alloc_creaturetype_callback)(const char*, uint32_t, uint32_t, uint8_t, uint16_t, uint16_t, uint16_t) = NULL;
c_creaturetype* (*alloc_creaturetype_buffer_callback)(uint32_t) = NULL;
int (*alloc_empty_creaturetype_callback)(c_creaturetype*) = NULL;
int (*alloc_creaturetype_callback)(c_creaturetype*, const char*, uint32_t, uint32_t, uint8_t, uint16_t, uint16_t, uint16_t) = NULL;
int (*alloc_creaturetype_buffer_callback)(c_creaturetype*, uint32_t) = NULL;
int (*alloc_vein_buffer_callback)(t_vein*, uint32_t) = NULL;
int (*alloc_frozenliquidvein_buffer_callback)(t_frozenliquidvein*, uint32_t) = NULL;
int (*alloc_spattervein_buffer_callback)(t_spattervein*, uint32_t) = NULL;
int DFHack_isWallTerrain(int in)
{
return DFHack::isWallTerrain(in);
}
int DFHack_isFloorTerrain(int in)
{
return DFHack::isFloorTerrain(in);
}
int DFHack_isRampTerrain(int in)
{
return DFHack::isRampTerrain(in);
}
int DFHack_isStairTerrain(int in)
{
return DFHack::isStairTerrain(in);
}
int DFHack_isOpenTerrain(int in)
{
return DFHack::isOpenTerrain(in);
}
int DFHack_getVegetationType(int in)
{
return DFHack::getVegetationType(in);
}
#ifdef __cplusplus
}
@ -76,7 +111,7 @@ int ColorListConvert(t_colormodifier* src, c_colormodifier* dest)
if(src == NULL)
return -1;
dest = ((*alloc_colormodifier_callback)(src->part, src->colorlist.size()));
((*alloc_colormodifier_callback)(dest, src->part, src->colorlist.size()));
copy(src->colorlist.begin(), src->colorlist.end(), dest->colorlist);
@ -88,7 +123,7 @@ int CreatureCasteConvert(t_creaturecaste* src, c_creaturecaste* dest)
if(src == NULL)
return -1;
dest = ((*alloc_creaturecaste_callback)(src->rawname, src->singular, src->plural, src->adjective, src->ColorModifier.size(), src->bodypart.size()));
((*alloc_creaturecaste_callback)(dest, src->rawname, src->singular, src->plural, src->adjective, src->ColorModifier.size(), src->bodypart.size()));
for(int i = 0; i < dest->colorModifierLength; i++)
ColorListConvert(&src->ColorModifier[i], &dest->ColorModifier[i]);
@ -103,7 +138,7 @@ int CreatureTypeConvert(t_creaturetype* src, c_creaturetype* dest)
if(src == NULL)
return -1;
dest = ((*alloc_creaturetype_callback)(src->rawname, src->castes.size(), src->extract.size(), src->tile_character, src->tilecolor.fore, src->tilecolor.back, src->tilecolor.bright));
((*alloc_creaturetype_callback)(dest, src->rawname, src->castes.size(), src->extract.size(), src->tile_character, src->tilecolor.fore, src->tilecolor.back, src->tilecolor.bright));
for(int i = 0; i < dest->castesCount; i++)
CreatureCasteConvert(&src->castes[i], &dest->castes[i]);

@ -1,6 +1,17 @@
#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"
#include "dfhack/DFError.h"
@ -10,7 +21,7 @@
#include "dfhack/DFProcess.h"
#include "dfhack/DFTypes.h"
// DFHack modules
#include "dfhack/modules/Buildings.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Position.h"
@ -22,5 +33,16 @@
#include "dfhack/modules/Vegetation.h"
#include "dfhack/modules/Maps.h"
#include "dfhack/DFMiscUtils.h"
#endif
/*
* This is a header full of ugly, volatile things.
* Only for use of official DFHack tools!
*/
#ifdef DFHACK_WANT_MISCUTILS
#include "dfhack/DFMiscUtils.h"
#endif
// define this to get the static tiletype->properties mapping
#ifdef DFHACK_WANT_TILETYPES
#include "dfhack/DFTileTypes.h"
#endif
#endif

@ -25,12 +25,20 @@ distribution.
#ifndef DFHACK_C_API
#define DFHACK_C_API
typedef void DFHackObject;
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include "dfhack/DFGlobal.h"
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "dfhack-c/DFContext_C.h"
#include "dfhack-c/DFTypes_C.h"
using namespace DFHack;
typedef void DFHackObject;
#ifdef __cplusplus
extern "C" {

@ -25,10 +25,7 @@ distribution.
#ifndef DFHACK_C_CONTEXT
#define DFHACK_C_CONTEXT
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
typedef void DFHackObject;
#include "DFHack_C.h"
#ifdef __cplusplus
extern "C" {

@ -25,30 +25,28 @@ distribution.
#ifndef TYPES_C_API
#define TYPES_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Maps.h"
#include "dfhack/modules/Materials.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
DFHACK_EXPORT extern int8_t* (*alloc_byte_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int16_t* (*alloc_short_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int32_t* (*alloc_int_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_byte_buffer_callback)(int8_t*, uint32_t);
DFHACK_EXPORT extern int (*alloc_short_buffer_callback)(int16_t*, uint32_t);
DFHACK_EXPORT extern int (*alloc_int_buffer_callback)(int32_t*, uint32_t);
DFHACK_EXPORT extern uint8_t* (*alloc_ubyte_buffer_callback)(uint32_t);
DFHACK_EXPORT extern uint16_t* (*alloc_ushort_buffer_callback)(uint32_t);
DFHACK_EXPORT extern uint32_t* (*alloc_uint_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_ubyte_buffer_callback)(uint8_t*, uint32_t);
DFHACK_EXPORT extern int (*alloc_ushort_buffer_callback)(uint16_t*, uint32_t);
DFHACK_EXPORT extern int (*alloc_uint_buffer_callback)(uint32_t*, uint32_t);
DFHACK_EXPORT extern char* (*alloc_char_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_char_buffer_callback)(char*, uint32_t);
DFHACK_EXPORT extern t_matgloss* (*alloc_matgloss_buffer_callback)(int);
DFHACK_EXPORT extern t_descriptor_color* (*alloc_descriptor_buffer_callback)(int);
DFHACK_EXPORT extern t_matglossOther* (*alloc_matgloss_other_buffer_callback)(int);
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 c_colormodifier
{
@ -57,9 +55,9 @@ struct c_colormodifier
uint32_t colorlistLength;
};
DFHACK_EXPORT extern c_colormodifier* (*alloc_empty_colormodifier_callback)(void);
DFHACK_EXPORT extern c_colormodifier* (*alloc_colormodifier_callback)(const char*, uint32_t);
DFHACK_EXPORT extern c_colormodifier* (*alloc_colormodifier_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_empty_colormodifier_callback)(c_colormodifier*);
DFHACK_EXPORT extern int (*alloc_colormodifier_callback)(c_colormodifier*, const char*, uint32_t);
DFHACK_EXPORT extern int (*alloc_colormodifier_buffer_callback)(c_colormodifier*, uint32_t);
struct c_creaturecaste
{
@ -75,9 +73,9 @@ struct c_creaturecaste
uint32_t bodypartLength;
};
DFHACK_EXPORT extern c_creaturecaste* (*alloc_empty_creaturecaste_callback)(void);
DFHACK_EXPORT extern c_creaturecaste* (*alloc_creaturecaste_callback)(const char*, const char*, const char*, const char*, uint32_t, uint32_t);
DFHACK_EXPORT extern c_creaturecaste* (*alloc_creaturecaste_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_empty_creaturecaste_callback)(c_creaturecaste*);
DFHACK_EXPORT extern int (*alloc_creaturecaste_callback)(c_creaturecaste*, const char*, const char*, const char*, const char*, uint32_t, uint32_t);
DFHACK_EXPORT extern int (*alloc_creaturecaste_buffer_callback)(c_creaturecaste*, uint32_t);
struct c_creaturetype
{
@ -99,9 +97,20 @@ struct c_creaturetype
} tilecolor;
};
DFHACK_EXPORT extern c_creaturetype* (*alloc_empty_creaturetype_callback)(void);
DFHACK_EXPORT extern c_creaturetype* (*alloc_creaturetype_callback)(const char*, uint32_t, uint32_t, uint8_t, uint16_t, uint16_t, uint16_t);
DFHACK_EXPORT extern c_creaturetype* (*alloc_creaturetype_buffer_callback)(uint32_t);
DFHACK_EXPORT extern int (*alloc_empty_creaturetype_callback)(c_creaturetype*);
DFHACK_EXPORT extern int (*alloc_creaturetype_callback)(c_creaturetype*, const char*, uint32_t, uint32_t, uint8_t, uint16_t, uint16_t, uint16_t);
DFHACK_EXPORT extern int (*alloc_creaturetype_buffer_callback)(c_creaturetype*, uint32_t);
DFHACK_EXPORT extern int (*alloc_vein_buffer_callback)(t_vein*, uint32_t);
DFHACK_EXPORT extern int (*alloc_frozenliquidvein_buffer_callback)(t_frozenliquidvein*, uint32_t);
DFHACK_EXPORT extern int (*alloc_spattervein_buffer_callback)(t_spattervein*, uint32_t);
DFHACK_EXPORT extern int DFHack_isWallTerrain(int in);
DFHACK_EXPORT extern int DFHack_isFloorTerrain(int in);
DFHACK_EXPORT extern int DFHack_isRampTerrain(int in);
DFHACK_EXPORT extern int DFHack_isStairTerrain(int in);
DFHACK_EXPORT extern int DFHack_isOpenTerrain(int in);
DFHACK_EXPORT extern int DFHack_getVegetationType(int in);
#ifdef __cplusplus
}

@ -25,13 +25,9 @@ distribution.
#ifndef BUILDINGS_C_API
#define BUILDINGS_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Buildings.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -25,13 +25,9 @@ distribution.
#ifndef CONSTRUCTIONS_C_API
#define CONSTRUCTIONS_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Constructions.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -25,15 +25,11 @@ distribution.
#ifndef CREATURES_C_API
#define CREATURES_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Creatures.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif

@ -25,11 +25,9 @@ distribution.
#ifndef GUI_C_API
#define GUI_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
using namespace DFHack;
#include "dfhack/modules/Gui.h"
#ifdef __cplusplus
extern "C" {

@ -25,15 +25,10 @@ distribution.
#ifndef ITEMS_C_API
#define ITEMS_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "Internal.h"
using namespace DFHack;
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Items.h"
#include "DFHack_C.h"
#include "dfhack/DFProcess.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack/modules/Items.h"
#ifdef __cplusplus
extern "C" {

@ -25,19 +25,9 @@ distribution.
#ifndef MAPS_C_API
#define MAPS_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include <vector>
#include <map>
#include <string>
using namespace std;
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Maps.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
@ -79,6 +69,10 @@ DFHACK_EXPORT int Maps_WriteBlockFlags(DFHackObject* maps, uint32_t x, uint32_t
DFHACK_EXPORT int Maps_ReadRegionOffsets(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, biome_indices40d* buffer);
DFHACK_EXPORT t_vein* Maps_ReadStandardVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z);
DFHACK_EXPORT t_frozenliquidvein* Maps_ReadFrozenVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z);
DFHACK_EXPORT t_spattervein* Maps_ReadSpatterVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z);
#ifdef __cplusplus
}
#endif

@ -25,14 +25,9 @@ distribution.
#ifndef MATERIALS_C_API
#define MATERIALS_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Materials.h"
#include "DFHack_C.h"
#include "dfhack-c/DFTypes_C.h"
using namespace DFHack;
#include "dfhack/modules/Materials.h"
#ifdef __cplusplus
extern "C" {

@ -25,8 +25,8 @@ distribution.
#ifndef POSITION_C_API
#define POSITION_C_API
#include "dfhack/DFExport.h"
#include "DFHack_C.h"
#include "dfhack/modules/Position.h"
#ifdef __cplusplus
extern "C" {

@ -25,13 +25,9 @@ distribution.
#ifndef TRANSLATION_C_API
#define TRANSLATION_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Translation.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -25,13 +25,9 @@ distribution.
#ifndef VEGETATION_C_API
#define VEGETATION_C_API
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Vegetation.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -0,0 +1,43 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
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 WINDOWIO_C_API
#define WINDOWIO_C_API
#include "DFHack_C.h"
#include "dfhack/modules/WindowIO.h"
#ifdef __cplusplus
extern "C" {
#endif
DFHACK_EXPORT int WindowIO_TypeStr(DFHackObject* window, const char* input, int delay, bool useShift);
DFHACK_EXPORT int WindowIO_TypeSpecial(DFHackObject* window, t_special command, int count, int delay);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,47 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
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 WORLD_C_API
#define WORLD_C_API
#include "DFHack_C.h"
#include "dfhack/modules/World.h"
#ifdef __cplusplus
extern "C" {
#endif
DFHACK_EXPORT int World_Start(DFHackObject* world);
DFHACK_EXPORT int World_Finish(DFHackObject* world);
DFHACK_EXPORT int World_ReadCurrentTick(DFHackObject* world, uint32_t* tick);
DFHACK_EXPORT int World_ReadCurrentYear(DFHackObject* world, uint32_t* year);
DFHACK_EXPORT int World_ReadCurrentMonth(DFHackObject* world, uint32_t* month);
DFHACK_EXPORT int World_ReadCurrentDay(DFHackObject* world, uint32_t* day);
#ifdef __cplusplus
}
#endif
#endif

@ -44,74 +44,78 @@ namespace DFHack
class DFContextShared;
class WindowIO;
class Process;
class DFHACK_EXPORT Context
{
public:
Context(Process * p);
~Context();
bool isValid();
bool Attach();
bool Detach();
bool isAttached();
/// stop the tracked process
bool Suspend();
/// @return true if the process is stopped
bool isSuspended();
/// stop the tracked process, asynchronous
bool AsyncSuspend();
/// resume the tracked process
bool Resume();
/// forces resume on Windows. This can be a bad thing with multiple tools running!
bool ForceResume();
memory_info *getMemoryInfo();
Process* getProcess();
void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target);
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
// FIXME: this is crap.
// get the creatures module
/// get the creatures module
Creatures * getCreatures();
// get the maps module
/// get the maps module
Maps * getMaps();
// get the gui module
/// get the gui module
Gui * getGui();
// get the world module
/// get the world module
World * getWorld();
// get the position module
/// get the position module
Position * getPosition();
// get the materials module
/// get the materials module
Materials * getMaterials();
// get the items module
/// get the items module
Items * getItems();
// get the translation module
/// get the translation module
Translation * getTranslation();
// get the vegetation module
/// get the vegetation module
Vegetation * getVegetation();
// get the buildings module
/// get the buildings module
Buildings * getBuildings();
// get the constructions module
/// get the constructions module
Constructions * getConstructions();
// get the Window management and I/O module
WindowIO * getWindow();
/// get the Window management and I/O module
WindowIO * getWindowIO();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/*
* Effects like mist, dragonfire or dust
*/

@ -35,18 +35,111 @@ distribution.
namespace DFHack
{
class Context;
class DFContextMgrPrivate;
class BadContexts;
class Process;
/**
* Used to enumerate, create and destroy Contexts. The very base of DFHack.
* @see DFHack::Context
*/
class DFHACK_EXPORT ContextManager
{
DFContextMgrPrivate * const d;
class Private;
Private * const d;
public:
/**
* Constructs the ContextManager.
* @param path_to_xml the path to the file that defines memory offsets. (Memory.xml)
*/
ContextManager(const std::string path_to_xml);
/**
* Destroys the ContextManager.
*/
~ContextManager();
uint32_t Refresh();
/**
* Refresh the internal list of valid Context objects.
* @param bad_contexts pointer to a BadContexts object. Not required. All contexts are automatically destroyed if the object is not provided.
* @see DFHack::BadContexts
* @return Number of tracked contexts
*/
uint32_t Refresh(BadContexts* bad_contexts = 0);
/**
* Get the number of tracked contexts.
* @return Number of tracked contexts
*/
uint32_t size();
/**
* Get a context by index
* @param index index of the context to be returned
* @return pointer to a Context. 0 if the index is out of range.
*/
Context * operator[](uint32_t index);
/**
* Convenience method to return a single valid Context
* @return pointer to a Context
*/
Context * getSingleContext();
/**
* Destroy all tracked Context objects
* Normally called during object destruction. Calling this from outside ContextManager is nasty.
*/
void purge(void);
};
/**
* Class used for holding a set of invalidated Context AND Process objects temporarily and destroy them safely.
* @see DFHack::Context
* @see DFHack::Process
*/
class DFHACK_EXPORT BadContexts
{
class Private;
Private * const d;
void push_back(Context * c);
friend class ContextManager;
void clear();
public:
BadContexts();
/**
* Destructor.
* All Processes and Contexts tracked by the BadContexts object will be destroyed also.
*/
~BadContexts();
/**
* Test if a Context is among the invalidated Contexts
* @param c pointer to a Context to be checked
* @return true if the Context is among the invalidated. false otherwise.
*/
bool Contains(Context* c);
/**
* Test if a Process is among the invalidated Processes/Contexts
* @param p pointer to a Process to be checked
* @see DFHack::Process
* @return true if the Process is among the invalidated. false otherwise.
*/
bool Contains(Process* p);
// TODO: Add excise(Context *) method
/**
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
uint32_t size();
/**
* Get an invalid Context by index
* @param index index of the invalid Context to be returned
* @return pointer to an invalid Context
*/
Context * operator[](uint32_t index);
};
} // namespace DFHack
#endif // CONTEXTMANAGER_H_INCLUDED

@ -297,6 +297,16 @@ namespace DFHack
return "SHM ATTACH FAILURE";
}
};
class DFHACK_EXPORT ModuleNotInitialized : public std::exception
{
public:
ModuleNotInitialized() {}
virtual ~ModuleNotInitialized() throw(){};
virtual const char* what() const throw()
{
return "Programmer error: module not initialized!";
}
};
}
}

@ -27,70 +27,21 @@ distribution.
#include "DFPragma.h"
#include "DFExport.h"
#include <map>
#include <vector>
#include <string>
#include "dfhack/DFTypes.h"
namespace DFHack
{
/*
* Stubs
*/
class Process;
/*
* Common data types
*/
struct t_type
{
t_type(uint32_t assign, uint32_t type, std::string classname)
:classname(classname),assign(assign),type(type){};
std::string classname;
uint32_t assign;
uint32_t type;
};
struct t_class;
struct t_class
{
t_class(const t_class &old)
{
classname = old.classname;
vtable = old.vtable;
assign = old.assign;
type_offset = old.type_offset;
for(uint32_t i = 0; i < old.subs.size();i++)
{
t_type * t = new t_type (*old.subs[i]);
subs.push_back(t);
}
}
t_class ()
{
vtable = 0;
assign = 0;
type_offset = 0;
}
~t_class()
{
for(uint32_t i = 0; i < subs.size();i++)
{
delete subs[i];
}
subs.clear();
}
std::string classname;
uint32_t vtable;
uint32_t assign;// index to typeclass array if multiclass. return value if not.
uint32_t type_offset; // offset of type data for multiclass
vector<t_type *> subs;
};
class DFHACK_EXPORT memory_info
{
private:
class Private;
Private * d;
Private * d;
public:
enum OSType
{
@ -114,7 +65,8 @@ namespace DFHack
int32_t getOffset (const char *);
uint32_t getAddress (const char *);
uint32_t getHexValue (const char *);
std::string getMood(const uint32_t moodID);
std::string getString (const std::string&);
std::string getProfession(const uint32_t) const;
std::string getJob(const uint32_t) const;
@ -122,6 +74,9 @@ namespace DFHack
std::string getTrait (const uint32_t, const uint32_t) const;
std::string getTraitName(const uint32_t) const;
std::string getLabor (const uint32_t);
std::vector< std::vector<std::string> > const& getAllTraits();
DFHack::t_level getLevelInfo(const uint32_t level) const;
void setVersion(const char *);
void setVersion(const std::string&);
@ -149,42 +104,52 @@ namespace DFHack
void setProfession(const std::string &, const std::string &);
void setJob(const std::string &, const std::string &);
void setSkill(const std::string &, const std::string &);
void setTrait(const std::string &,const std::string &,const std::string &,const std::string &,const std::string &,const std::string &,const std::string &,const std::string &);
void setTrait(const std::string &, const std::string &, const std::string &,
const std::string &, const std::string &,
const std::string &, const std::string &, const std::string &);
void setLabor(const std::string &, const std::string &);
void setLevel(const std::string &nLevel, const std::string &nName,
const std::string &nXp);
void setMood(const std::string &id, const std::string &mood);
void RebaseVTable(const int32_t offset);
void setParentProcess(Process * _p);
t_class * setClass (const char * classname, uint32_t vptr = 0, uint32_t typeoffset = 0);
void setClassChild (t_class * parent, const char * classname, const char * type);
/*
/**
* Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class)
* uses memory reading directly, needs suspend. input = address of the object
* fails if it's unable to read from memory
*/
bool resolveObjectToClassID (const uint32_t address, int32_t & classID);
/*
/**
* Get a ClassID when you know the classname. can fail if the class is not in the cache
*/
bool resolveClassnameToClassID (const std::string classname, int32_t & classID);
/*
/**
* Get a vptr from a classname. Can fail if the type is not in the cache
* limited to normal classes, variable-dependent types will resolve to the base class
*/
bool resolveClassnameToVPtr ( const std::string classname, uint32_t & vptr );
/*
/**
* Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID)
*/
bool resolveClassIDToClassname (const int32_t classID, std::string & classname);
/*
/**
* Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR!
*/
const vector<std::string> * getClassIDMapping();
const std::vector<std::string> * getClassIDMapping();
/**
* Get a string with all addresses and offsets
*/
std::string PrintOffsets();
};
}
#endif // MEMINFO_H_INCLUDED

@ -8,17 +8,13 @@
#include <sstream>
#include <ctime>
#include <cstdio>
using namespace std;
#include <dfhack/DFProcess.h>
#include <dfhack/DFMemInfo.h>
#include <dfhack/DFVector.h>
/*
* This is a header full of ugly, volatile things.
* Only for use of official DFHack tools!
*/
void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;

@ -0,0 +1,54 @@
/*
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:
virtual ~Module(){};
virtual bool Start(){return true;};// default start...
virtual bool Finish() = 0;// everything should have a Finish()
// should Context call Finish when Resume is called?
virtual bool OnResume()
{
Finish();
return true;
};
// Finish when map change is detected?
// TODO: implement
virtual bool OnMapChange()
{
return false;
};
};
}
#endif //MODULE_H_INCLUDED

@ -35,6 +35,25 @@ namespace DFHack
class Process;
class Window;
struct ProcessID
{
ProcessID(const uint64_t _time, const uint64_t _pid): time(_time), pid(_pid){};
bool operator==(const ProcessID &other) const
{
return (other.time == time && other.pid == pid);
}
bool operator< (const ProcessID& ms) const
{
if (time < ms.time)
return true;
else if(time == ms.time)
return pid < ms.pid ;
return false;
}
uint64_t time;
uint64_t pid;
};
// structure describing a memory range
struct DFHACK_EXPORT t_memrange
{
@ -53,100 +72,117 @@ namespace DFHack
if (address >= start && address <= end) return true;
return false;
}
inline void print()
{
std::cout << std::hex << start << " - " << end << "|" << (read ? "r" : "-") << (write ? "w" : "-") << (execute ? "x" : "-") << "|" << name << std::endl;
}
uint8_t * buffer;
};
class DFHACK_EXPORT Process
{
public:
// this is the single most important destructor ever. ~px
/// this is the single most important destructor ever. ~px
virtual ~Process(){};
// Set up stuff so we can read memory, suspends synchronously
/// Set up stuff so we can read memory, suspends synchronously
virtual bool attach() = 0;
// detach from DF, resume its execution if it's suspended
/// detach from DF, resume its execution if it's suspended
virtual bool detach() = 0;
// synchronous suspend
// waits for DF to be actually suspended,
// this might take a while depending on implementation
/**
* synchronous suspend
* waits for DF to be actually suspended,
* this might take a while depending on implementation
*/
virtual bool suspend() = 0;
// asynchronous suspend to use together with polling and timers
/// asynchronous suspend to use together with polling and timers
virtual bool asyncSuspend() = 0;
// resume DF execution
/// resume DF execution
virtual bool resume() = 0;
// force-resume DF execution
/// force-resume DF execution
virtual bool forceresume() = 0;
/// read a 8-byte integer
virtual uint64_t readQuad(const uint32_t address) = 0;
/// read a 8-byte integer
virtual void readQuad(const uint32_t address, uint64_t & value) = 0;
/// write a 8-byte integer
virtual void writeQuad(const uint32_t address, const uint64_t value) = 0;
/// read a 4-byte integer
virtual uint32_t readDWord(const uint32_t address) = 0;
/// read a 4-byte integer
virtual void readDWord(const uint32_t address, uint32_t & value) = 0;
/// write a 4-byte integer
virtual void writeDWord(const uint32_t address, const uint32_t value) = 0;
/// read a float
virtual float readFloat(const uint32_t address) = 0;
/// write a float
virtual void readFloat(const uint32_t address, float & value) = 0;
/// read a 2-byte integer
virtual uint16_t readWord(const uint32_t address) = 0;
/// read a 2-byte integer
virtual void readWord(const uint32_t address, uint16_t & value) = 0;
/// write a 2-byte integer
virtual void writeWord(const uint32_t address, const uint16_t value) = 0;
/// read a byte
virtual uint8_t readByte(const uint32_t address) = 0;
/// read a byte
virtual void readByte(const uint32_t address, uint8_t & value) = 0;
/// write a byte
virtual void writeByte(const uint32_t address, const uint8_t value) = 0;
/// read an arbitrary amount of bytes
virtual void read( uint32_t address, uint32_t length, uint8_t* buffer) = 0;
/// write an arbitrary amount of bytes
virtual void write(uint32_t address, uint32_t length, uint8_t* buffer) = 0;
// read a string
virtual const string readSTLString (uint32_t offset) = 0;
/// read an STL string
virtual const std::string readSTLString (uint32_t offset) = 0;
/// read an STL string
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string
virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0;
// get class name of an object with rtti/type info
virtual string readClassName(uint32_t vptr) = 0;
/// get class name of an object with rtti/type info
virtual std::string readClassName(uint32_t vptr) = 0;
/// read a null-terminated C string
virtual const std::string readCString (uint32_t offset) = 0;
/// @return true if the process is suspended
virtual bool isSuspended() = 0;
/// @return true if the process is attached
virtual bool isAttached() = 0;
/// @return true if the process is identified -- has a Memory.xml entry
virtual bool isIdentified() = 0;
// find the thread IDs of the process
virtual bool getThreadIDs(vector<uint32_t> & threads ) = 0;
// get virtual memory ranges of the process (what is mapped where)
virtual void getMemRanges( vector<t_memrange> & ranges ) = 0;
// get the flattened Memory.xml entry of this process
/// find the thread IDs of the process
virtual bool getThreadIDs(std::vector<uint32_t> & threads ) = 0;
/// get virtual memory ranges of the process (what is mapped where)
virtual void getMemRanges(std::vector<t_memrange> & ranges ) = 0;
/// get the flattened Memory.xml entry of this process
virtual memory_info *getDescriptor() = 0;
// get the DF Process ID
/// get the DF Process ID
virtual int getPID() = 0;
// get module index by name and version. bool 1 = error
/// get module index by name and version. bool 1 = error
virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0;
// get the SHM start if available
/// get the SHM start if available
virtual char * getSHMStart (void) = 0;
// set a SHM command and wait for a response, return 0 on error or throw exception
/// set a SHM command and wait for a response, return 0 on error or throw exception
virtual bool SetAndWait (uint32_t state) = 0;
/*
// wait while SHM command == state. returns 0 without the SHM
virtual bool waitWhile (uint32_t state) = 0;
// set SHM command.
virtual void setCmd (uint32_t newstate) = 0;
*/
};
////////////////////////////////////////////////////////////////////////////
// Compiler appeasement area. Not worth a look really... //
////////////////////////////////////////////////////////////////////////////
class DFHACK_EXPORT NormalProcess : virtual public Process
{
friend class ProcessEnumerator;
class Private;
private:
Private * const d;
public:
NormalProcess(uint32_t pid, vector <memory_info *> & known_versions);
NormalProcess(uint32_t pid, std::vector <memory_info *> & known_versions);
~NormalProcess();
bool attach();
bool detach();
@ -178,11 +214,11 @@ namespace DFHack
void read( uint32_t address, uint32_t length, uint8_t* buffer);
void write(uint32_t address, uint32_t length, uint8_t* buffer);
const string readSTLString (uint32_t offset);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
// get class name of an object with rtti/type info
string readClassName(uint32_t vptr);
std::string readClassName(uint32_t vptr);
const std::string readCString (uint32_t offset);
@ -190,8 +226,8 @@ namespace DFHack
bool isAttached();
bool isIdentified();
bool getThreadIDs(vector<uint32_t> & threads );
void getMemRanges( vector<t_memrange> & ranges );
bool getThreadIDs(std::vector<uint32_t> & threads );
void getMemRanges(std::vector<t_memrange> & ranges );
memory_info *getDescriptor();
int getPID();
// get module index by name and version. bool 1 = error
@ -200,12 +236,6 @@ namespace DFHack
char * getSHMStart (void){return 0;};
// set a SHM command and wait for a response
bool SetAndWait (uint32_t state){return false;};
/*
// wait for a SHM state. returns 0 without the SHM
bool waitWhile (uint32_t state){return false;};
// set SHM command.
void setCmd (uint32_t newstate){};
*/
};
class DFHACK_EXPORT SHMProcess : virtual public Process
@ -216,7 +246,7 @@ namespace DFHack
Private * const d;
public:
SHMProcess(uint32_t PID, vector <memory_info *> & known_versions);
SHMProcess(uint32_t PID, std::vector <memory_info *> & known_versions);
~SHMProcess();
// Set up stuff so we can read memory
bool attach();
@ -249,11 +279,11 @@ namespace DFHack
void read( uint32_t address, uint32_t length, uint8_t* buffer);
void write(uint32_t address, uint32_t length, uint8_t* buffer);
const string readSTLString (uint32_t offset);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info
string readClassName(uint32_t vptr);
std::string readClassName(uint32_t vptr);
const std::string readCString (uint32_t offset);
@ -261,8 +291,8 @@ namespace DFHack
bool isAttached();
bool isIdentified();
bool getThreadIDs(vector<uint32_t> & threads );
void getMemRanges( vector<t_memrange> & ranges );
bool getThreadIDs(std::vector<uint32_t> & threads );
void getMemRanges(std::vector<t_memrange> & ranges );
memory_info *getDescriptor();
int getPID();
// get module index by name and version. bool 1 = error
@ -270,12 +300,6 @@ namespace DFHack
// get the SHM start if available
char * getSHMStart (void);
bool SetAndWait (uint32_t state);
/*
// wait for a SHM state. returns 0 without the SHM
bool waitWhile (uint32_t state);
// set SHM command.
void setCmd (uint32_t newstate);
*/
};
#ifdef LINUX_BUILD
@ -287,7 +311,7 @@ namespace DFHack
Private * const d;
public:
WineProcess(uint32_t pid, vector <memory_info *> & known_versions);
WineProcess(uint32_t pid, std::vector <memory_info *> & known_versions);
~WineProcess();
bool attach();
bool detach();
@ -319,11 +343,11 @@ namespace DFHack
void read( uint32_t address, uint32_t length, uint8_t* buffer);
void write(uint32_t address, uint32_t length, uint8_t* buffer);
const string readSTLString (uint32_t offset);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
// get class name of an object with rtti/type info
string readClassName(uint32_t vptr);
std::string readClassName(uint32_t vptr);
const std::string readCString (uint32_t offset);
@ -331,8 +355,8 @@ namespace DFHack
bool isAttached();
bool isIdentified();
bool getThreadIDs(vector<uint32_t> & threads );
void getMemRanges( vector<t_memrange> & ranges );
bool getThreadIDs(std::vector<uint32_t> & threads );
void getMemRanges(std::vector<t_memrange> & ranges );
memory_info *getDescriptor();
int getPID();
// get module index by name and version. bool 1 = error
@ -340,12 +364,6 @@ namespace DFHack
// get the SHM start if available
char * getSHMStart (void){return 0;};
bool SetAndWait (uint32_t state){return false;};
/*
// wait for a SHM state. returns 0 without the SHM
bool waitWhile (uint32_t state){return false;};
// set SHM command.
void setCmd (uint32_t newstate){};
*/
};
#endif
}

@ -28,27 +28,105 @@ distribution.
#include "DFPragma.h"
#include "DFExport.h"
class TiXmlElement;
namespace DFHack
{
class memory_info;
class Process;
/*
* Process manager
class BadProcesses;
/**
* Process enumerator
* Used to enumerate, create and destroy Processes.
* @see DFHack::Process
*/
class DFHACK_EXPORT ProcessEnumerator
{
class Private;
Private * const d;
public:
ProcessEnumerator( string path_to_xml);
/**
* Constructs the ProcessEnumerator.
* @param path_to_xml the path to the file that defines memory offsets. (Memory.xml)
*/
ProcessEnumerator( string path_to_xml );
/**
* Destroys the ProcessEnumerator.
*/
~ProcessEnumerator();
bool findProcessess();
/**
* Refresh the internal list of valid Process objects.
* @param invalidated_processes pointer to a BadProcesses object. Not required. All processes are automatically destroyed if the object is not provided.
* @see DFHack::BadProcesses
* @return true if there's at least one valit Process
*/
bool Refresh(BadProcesses * invalidated_processes = 0);
/**
* @return Number of tracked processes
*/
uint32_t size();
/**
* Get a Process by index
* @param index index of the Process to be returned
* @return pointer to a Process. 0 if the index is out of range.
*/
Process * operator[](uint32_t index);
/**
* Destroy all tracked Process objects
* Normally called during object destruction. Calling this from outside ProcessManager is nasty.
*/
void purge(void);
};
/**
* Class used for holding a set of invalidated Process objects temporarily and destroy them safely.
* @see DFHack::Process
*/
class DFHACK_EXPORT BadProcesses
{
class Private;
Private * const d;
void push_back(Process * p);
friend class ProcessEnumerator;
void clear();
public:
BadProcesses();
/**
* Destructor.
* All Processes tracked by the BadProcesses object will be destroyed also.
*/
~BadProcesses();
/**
* Test if a Process is among the invalidated Processes
* @param p pointer to a Process to be checked
* @return true if the Process is among the invalidated. false otherwise.
*/
bool Contains(Process* p);
/**
* Remove a Process from the tracked invalidated Processes. Used by BadContexts.
* @param p pointer to a Process to be excised
* @see DFHack::BadContexts
* @return true if the Process was among the invalidated. false otherwise.
*/
bool excise (Process* p);
/**
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
uint32_t size();
/**
* Get an invalid Process by index
* @param index index of the invalid Process to be returned
* @return pointer to an invalid Process
*/
Process * operator[](uint32_t index);
};
}
#endif // PROCESSMANAGER_H_INCLUDED

@ -29,9 +29,10 @@ distribution.
namespace DFHack
{
// tile class -- determines the general shape of the tile
enum TileClass
{
EMPTY,
EMPTY,// empty
WALL,
PILLAR,
@ -41,10 +42,10 @@ namespace DFHack
STAIR_DOWN,
STAIR_UPDOWN,
RAMP,
RAMP_TOP,
RAMP,// ramps have no direction
RAMP_TOP,// the top of a ramp. I assume it's used for path finding.
FLOOR,
FLOOR,// generic floor
TREE_DEAD,
TREE_OK,
SAPLING_DEAD,
@ -54,29 +55,31 @@ namespace DFHack
BOULDER,
PEBBLES
};
// material -- what material the tile is made of
enum TileMaterial
{
AIR,
SOIL,
STONE,
FEATSTONE, // whatever it is
OBSIDIAN,
VEIN,
ICE,
GRASS,
GRASS2,
GRASS_DEAD,
GRASS_DRY,
DRIFTWOOD,
HFS,
MAGMA,
CAMPFIRE,
FIRE,
ASHES,
CONSTRUCTED,
CYAN_GLOW
AIR,// empty
SOIL,// ordinary soil. material depends on geology
STONE,// ordinary layer stone. material depends on geology
FEATSTONE,// map feature stone. used for things like hell, the hell temple or adamantine tubes. material depends on local/global feature
OBSIDIAN,// cast obsidian
VEIN,// vein stone. material depends on mineral veins present
ICE,// frozen water... not much to say. you can determine what was on the tile before it froze by looking into the 'ice vein' objects
GRASS,// grass (has 4 variants)
GRASS2,// grass (has 4 variants)
GRASS_DEAD,// dead grass (has 4 variants)
GRASS_DRY,// dry grass (has 4 variants)
DRIFTWOOD,// non-specified wood - normally on top of the local layer stone/soil.
HFS,// the stuff demon pits are made of - this makes them different from ordinary pits.
MAGMA,// material for semi-molten rock and 'magma flow' tiles
CAMPFIRE,// human armies make them when they siege. The original tile may be lost?
FIRE,// burning grass
ASHES,// what remains from a FIRE
CONSTRUCTED,// tile material depends on the construction present
CYAN_GLOW// the glowy stuff that disappears from the demon temple when you take the sword.
};
// variants are used for tiles, where there are multiple variants of the same - like grass floors
enum TileVariant
{
VAR_1,

@ -203,7 +203,7 @@ struct t_settlement
struct t_attrib
{
uint32_t level;
uint32_t field_4;
uint32_t field_4; // offset from beginning, purpose unknown
uint32_t field_8;
uint32_t field_C;
uint32_t leveldiff;
@ -211,5 +211,12 @@ struct t_attrib
uint32_t field_18;
};
struct t_level
{
uint32_t level;
std::string name;
uint32_t xpNxtLvl;
};
}// namespace DFHack
#endif // TYPES_H_INCLUDED

@ -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);
@ -37,7 +38,7 @@ namespace DFHack
bool Finish();
// read a vector of names
bool ReadCustomWorkshopTypes(map <uint32_t, string> & btypes);
bool ReadCustomWorkshopTypes(std::map <uint32_t, std::string> & btypes);
// returns -1 on error, >= 0 for real value
int32_t GetCustomWorkshopType(t_building & building);

@ -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);

@ -4,6 +4,7 @@
* Creatures
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
/*
@ -49,12 +50,12 @@ namespace DFHack
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;
@ -64,12 +65,12 @@ namespace DFHack
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
@ -80,7 +81,7 @@ namespace DFHack
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
@ -142,43 +143,43 @@ namespace DFHack
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;
@ -188,84 +189,84 @@ namespace DFHack
/*
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;
}
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;
}
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;
}
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
{
uint16_t id;
uint32_t id;
uint32_t rating;
uint32_t experience;
uint16_t rating;
};
struct t_job
{
bool active;
uint32_t jobId;
uint8_t jobType;
uint32_t occupationPtr;
uint32_t occupationPtr;
};
struct t_like
{
@ -280,7 +281,9 @@ namespace DFHack
// 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;
@ -305,7 +308,7 @@ namespace DFHack
t_attrib social_awareness;
};
#define MAX_COLORS 15
#define MAX_COLORS 15
struct t_creature
{
@ -315,23 +318,23 @@ namespace DFHack
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;
@ -352,29 +355,45 @@ namespace DFHack
uint32_t birth_year;
uint32_t birth_time;
};
class DFContextShared;
struct t_creature;
class DFHACK_EXPORT Creatures
class DFHACK_EXPORT Creatures : public Module
{
public:
public:
Creatures(DFHack::DFContextShared * d);
~Creatures();
bool Start( uint32_t & numCreatures);
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);
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);
/// write labors of a creature (for Dwarf Therapist)
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
/* Getters */
uint32_t GetDwarfRaceIndex ( void );
int32_t GetDwarfCivId ( void );
bool ReadJob(const t_creature * furball, std::vector<t_material> & mat);
private:
/* Write Functions */
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 WriteJob(const t_creature * furball, std::vector<t_material> const& mat);
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;
};

@ -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:

@ -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<ItemImprovementDesc> 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<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> descVTable;
class Private;
Private* d;
};
}
#endif

@ -6,12 +6,13 @@
#define CL_MOD_MAPS
#include "dfhack/DFExport.h"
#include "dfhack/DFModule.h"
namespace DFHack
{
/***************************************************************************
T Y P E S
***************************************************************************/
enum e_feature
{
feature_Other,
@ -19,6 +20,7 @@ namespace DFHack
feature_Underworld,
feature_Hell_Temple
};
static const char * sa_feature[]=
{
(char*)"Other",
@ -26,6 +28,8 @@ namespace DFHack
(char*)"Underworld",
(char*)"Hell Temple"
};
/// used as a key for the local feature map. combines X an Y coords.
union planecoord
{
uint32_t xy;
@ -40,40 +44,60 @@ namespace DFHack
return false;
}
};
struct t_feature
{
e_feature type;
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc.
int16_t main_material;
/// generally some index to a vector of material types.
int32_t sub_material;
bool discovered; // placeholder.
/// placeholder
bool discovered;
/// this is NOT part of the DF feature, but an address of the feature as seen by DFhack.
uint32_t origin;
};
/// mineral vein object
struct t_vein
{
uint32_t vtable;
/// index into the inorganic material vector
int32_t type;
int16_t assignment[16];
/// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16];
uint32_t flags;
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
// stores what tiles should appear when the ice melts
/// stores what tiles should appear when the ice melts
struct t_frozenliquidvein
{
uint32_t vtable;
/// a 16x16 array of the original tile types
int16_t tiles[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
/// a 'spattervein' defines what coverings the individual map tiles have (snow, blood, etc)
/// @see PrintSplatterType in DFMiscUtils.h -- incomplete, but illustrative
struct t_spattervein
{
uint32_t vtable;
/// generic material.
uint16_t mat1;
uint16_t unk1;
/// material vector index
uint32_t mat2;
/// something even more specific?
uint16_t mat3;
/// 16x16 array of covering 'intensity'
uint8_t intensity[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
enum BiomeOffset
@ -98,16 +122,25 @@ namespace DFHack
traffic_restricted
};
/// type of a designation for a tile
enum e_designation
{
/// no designation
designation_no,
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees
designation_ud_stair, // dig up/down stairs
designation_channel, // dig a channel
designation_ramp, // dig ramp out of a wall
designation_d_stair, // dig a stair down
designation_u_stair, // dig a stair up
designation_7 // whatever
/// dig walls, remove stairs and ramps, gather plants, fell trees. depends on tile type
designation_default,
/// dig up/down stairs
designation_ud_stair,
/// dig a channel
designation_channel,
/// dig ramp out of a wall
designation_ramp,
/// dig a stair down
designation_d_stair,
/// dig a stair up
designation_u_stair,
/// whatever. for completenes I guess
designation_7
};
enum e_liquidtype
@ -120,41 +153,43 @@ namespace DFHack
{
unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile?
/*
* All the different dig designations... needs more info, probably an enum
*/
/// All the different dig designations
e_designation dig : 3;
unsigned int smooth : 2;
unsigned int hidden : 1;
/*
/**
* This one is rather involved, but necessary to retrieve the base layer matgloss index
* see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details
* @see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284
*/
unsigned int geolayer_index :4;
unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/*
/**
* Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet
*/
unsigned int biome : 4;
/*
/**
* 0 = water
* 1 = magma
*/
e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2; // needs enum
unsigned int flow_forbid : 1; // what?
e_traffic traffic : 2;
/// the tile is not evaluated when calculating flows?
unsigned int flow_forbid : 1;
/// no liquid spreading
unsigned int liquid_static : 1;
unsigned int feature_local : 1; // this tile is a part of a feature
unsigned int feature_global : 1; // this tile is a part of a feature
unsigned int liquid_character : 2; // those ripples on streams?
/// this tile is a part of a local feature. can be combined with 'featstone' tiles
unsigned int feature_local : 1;
/// this tile is a part of a global feature. can be combined with 'featstone' tiles
unsigned int feature_global : 1;
/// those ripples on streams?
unsigned int liquid_character : 2;
};
union t_designation
@ -166,12 +201,16 @@ namespace DFHack
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
struct naked_occupancy
{
unsigned int building : 3;// building type... should be an enum?
// building type... should be an enum?
// 7 = door
unsigned int building : 3;
/// the tile contains a standing? creature
unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1;
// splatter. everyone loves splatter.
/// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int mud : 1;
unsigned int vomit :1;
unsigned int broken_arrows_color :4;
@ -199,12 +238,14 @@ namespace DFHack
struct naked_occupancy_grouped
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int building : 3;
/// the tile contains a standing? creature
unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1;
// splatter. everyone loves splatter.
/// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int splatter : 26;
};
@ -218,12 +259,15 @@ namespace DFHack
// map block flags
struct naked_blockflags
{
unsigned int designated : 1;// designated for jobs (digging and stuff like that)
unsigned int unk_1 : 1; // possibly related to the designated flag
// two flags required for liquid flow. no idea why
/// designated for jobs (digging and stuff like that)
unsigned int designated : 1;
/// possibly related to the designated flag
unsigned int unk_1 : 1;
/// two flags required for liquid flow.
unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1;
unsigned int unk_2: 28; // rest of the flags is completely unknown
/// rest of the flags is completely unknown
unsigned int unk_2: 28;
// there's a possibility that this flags field is shorter than 32 bits
};
@ -241,23 +285,30 @@ namespace DFHack
typedef struct
{
/// type of the tiles
tiletypes40d tiletypes;
/// flags determining the state of the tiles
designations40d designation;
/// flags determining what's on the tiles
occupancies40d occupancy;
/// values used for geology/biome assignment
biome_indices40d biome_indices;
uint32_t origin; // the address where it came from
/// the address where the block came from
uint32_t origin;
t_blockflags blockflags;
/// index into the global feature vector
int16_t global_feature;
/// index into the local feature vector... complicated
int16_t local_feature;
} mapblock40d;
/***************************************************************************
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:
@ -321,6 +372,7 @@ namespace DFHack
* Return false/0 on failure, buffer allocated by client app, 256 items long
*/
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
/**
* Get the address of a block or 0 if block is not valid
*/
@ -340,7 +392,7 @@ namespace DFHack
/// read/write temperatures
bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
/// read/write block occupancies
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
@ -350,10 +402,8 @@ namespace DFHack
bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
/// read/write the block flags
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
t_blockflags blockflags);
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
/// read/write features
bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global);
bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
@ -368,10 +418,11 @@ namespace DFHack
std::vector<t_vein>* veins,
std::vector<t_frozenliquidvein>* ices = 0,
std::vector<t_spattervein>* splatter = 0);
private:
struct Private;
Private *d;
};
#endif
}
#endif

@ -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];
@ -84,81 +85,72 @@ namespace DFHack
struct t_matglossOther
{
char rawname[128];
char rawname[128];
};
struct t_creatureextract
{
char rawname[128];
char rawname[128];
};
// this doesn't transfer well across the shm gap...
struct t_creaturetype
{
char rawname[128];
std::vector <t_creaturecaste> castes;
std::vector <t_creatureextract> extract;
uint8_t tile_character;
struct
{
uint16_t fore;
uint16_t back;
uint16_t bright;
} tilecolor;
std::vector <t_creaturecaste> castes;
std::vector <t_creatureextract> extract;
uint8_t tile_character;
struct
{
uint16_t fore;
uint16_t back;
uint16_t bright;
} tilecolor;
};
// this structure describes what are things made of in the DF world
struct t_material
{
int16_t itemType;
int16_t subType;
int16_t subIndex;
int32_t index;
uint32_t flags;
int16_t itemType;
int16_t subType;
int16_t subIndex;
int32_t index;
uint32_t flags;
};
class DFHACK_EXPORT Materials
class DFHACK_EXPORT Materials : public Module
{
public:
Materials(DFHack::DFContextShared * _d);
~Materials();
std::vector<t_matgloss> inorganic;
std::vector<t_matgloss> organic;
std::vector<t_matgloss> tree;
std::vector<t_matgloss> plant;
std::vector<t_matgloss> race;
std::vector<t_creaturetype> raceEx;
std::vector<t_descriptor_color> color;
std::vector<t_matglossOther> other;
std::vector<t_matgloss> alldesc;
bool ReadInorganicMaterials (void);
bool ReadOrganicMaterials (void);
bool ReadWoodMaterials (void);
bool ReadPlantMaterials (void);
bool ReadCreatureTypes (void);
bool ReadCreatureTypesEx (void);
bool ReadDescriptorColors(void);
bool ReadOthers (void);
void ReadAllMaterials(void);
std::string getDescription(t_material & mat);
/*
bool ReadInorganicMaterials (std::vector<t_matgloss> & output);
bool ReadOrganicMaterials (std::vector<t_matgloss> & output);
bool ReadWoodMaterials (std::vector<t_matgloss> & output);
bool ReadPlantMaterials (std::vector<t_matgloss> & output);
// TODO: maybe move to creatures?
bool ReadCreatureTypes (std::vector<t_matgloss> & output);
bool ReadCreatureTypesEx (vector<t_creaturetype> & creatures);
bool ReadDescriptorColors(std::vector<t_descriptor_color> & output);
*/
private:
class Private;
Private* d;
};
public:
Materials(DFHack::DFContextShared * _d);
~Materials();
bool Finish();
std::vector<t_matgloss> inorganic;
std::vector<t_matgloss> organic;
std::vector<t_matgloss> tree;
std::vector<t_matgloss> plant;
std::vector<t_matgloss> race;
std::vector<t_creaturetype> raceEx;
std::vector<t_descriptor_color> color;
std::vector<t_matglossOther> other;
std::vector<t_matgloss> alldesc;
bool ReadInorganicMaterials (void);
bool ReadOrganicMaterials (void);
bool ReadWoodMaterials (void);
bool ReadPlantMaterials (void);
bool ReadCreatureTypes (void);
bool ReadCreatureTypesEx (void);
bool ReadDescriptorColors(void);
bool ReadOthers (void);
void ReadAllMaterials(void);
std::string getType(t_material & mat);
std::string getDescription(t_material & mat);
private:
class Private;
Private* d;
};
}
#endif

@ -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,49 @@ namespace DFHack
int32_t y;
int32_t z;
};
struct t_screen
{
uint8_t symbol;
uint8_t foreground;
uint8_t background;
uint8_t bright;
uint8_t gtile;
uint8_t grayscale;
};
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);
/*
* Screen tiles
*/
bool getScreenTiles(int32_t width, int32_t height, t_screen screen[]);
private:
struct Private;
Private *d;

@ -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;

@ -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);

@ -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);

@ -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:

@ -22,20 +22,8 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "dfhack/DFIntegers.h"
#include <string>
#include <map>
#include "stdio.h"
using namespace std;
#include "Internal.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Buildings.h"
#include "dfhack-c/modules/Buildings_C.h"
using namespace DFHack;
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
@ -82,33 +70,27 @@ int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building)
int Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr, void* (*t_customWorkshop_buffer_create)(uint32_t))
{
if(b_Ptr != NULL)
{
int i;
t_customWorkshop* cw_Ptr;
map<uint32_t, string> bTypes;
map<uint32_t, string>::iterator bIter;
bool result = ((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes);
if(!result)
return 0;
cw_Ptr = (t_customWorkshop*)((*t_customWorkshop_buffer_create)(bTypes.size()));
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 -1;
if(b_Ptr != NULL)
{
int i;
t_customWorkshop* cw_Ptr;
std::map<uint32_t, string> bTypes;
map<uint32_t, string>::iterator bIter;
if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes))
return 0;
cw_Ptr = (t_customWorkshop*)((*t_customWorkshop_buffer_create)(bTypes.size()));
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 -1;
}
#ifdef __cplusplus

@ -22,15 +22,8 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "dfhack/DFIntegers.h"
#include "Internal.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Constructions.h"
#include "dfhack-c/modules/Constructions_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif

@ -92,19 +92,19 @@ Creatures::Creatures(DFContextShared* _d)
creatures.mood_offset = minfo->getOffset("creature_mood");
creatures.mood_skill_offset = minfo->getOffset("creature_mood_skill");
creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit");
creatures.current_job_offset = minfo->getOffset("creature_current_job");
creatures.current_job_offset = minfo->getOffset("creature_current_job");
// soul offsets
creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector");
creatures.soul_mental_offset = minfo->getOffset("soul_mental");
creatures.soul_traits_offset = minfo->getOffset("soul_traits");
// appearance
creatures.appearance_vector_offset = minfo->getOffset("creature_appearance_vector");
//birth
creatures.birth_year_offset = minfo->getOffset("creature_birth_year");
creatures.birth_time_offset = minfo->getOffset("creature_birth_time");
// name offsets for the creature module
creatures.name_firstname_offset = minfo->getOffset("name_firstname");
creatures.name_nickname_offset = minfo->getOffset("name_nickname");
@ -172,17 +172,17 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
*/
// non-SHM slow path
memory_info * minfo = d->d->offset_descriptor;
// read pointer from vector at position
uint32_t temp = d->p_cre->at (index);
furball.origin = temp;
Creatures2010::creature_offsets &offs = d->creatures;
//read creature from memory
// name
d->d->readName(furball.name,temp + offs.name_offset);
// basic stuff
p->readDWord (temp + offs.happiness_offset, furball.happiness);
p->readDWord (temp + offs.id_offset, furball.id);
@ -193,22 +193,24 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
p->readWord (temp + offs.caste_offset, furball.caste);
p->readDWord (temp + offs.flags1_offset, furball.flags1.whole);
p->readDWord (temp + offs.flags2_offset, furball.flags2.whole);
// physical attributes
p->read(temp + offs.physical_offset, sizeof(t_attrib) * 6, (uint8_t *)&furball.strength);
p->read(temp + offs.physical_offset,
sizeof(t_attrib) * NUM_CREATURE_PHYSICAL_ATTRIBUTES,
(uint8_t *)&furball.strength);
// mood stuff
furball.mood = (int16_t) p->readWord (temp + offs.mood_offset);
furball.mood_skill = p->readWord (temp + offs.mood_skill_offset);
d->d->readName(furball.artifact_name, temp + offs.artifact_name_offset);
d->d->readName(furball.artifact_name, temp + offs.artifact_name_offset);
// custom profession
p->readSTLString(temp + offs.custom_profession_offset, furball.custom_profession, sizeof(furball.custom_profession));
//fill_char_buf (furball.custom_profession, p->readSTLString (temp + offs.custom_profession_offset));
// labors
p->read (temp + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors);
// profession
furball.profession = p->readByte (temp + offs.profession_offset);
@ -252,25 +254,34 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball)
*/
uint32_t soul = p->readDWord(temp + offs.default_soul_offset);
furball.has_default_soul = false;
if(soul)
{
furball.has_default_soul = true;
// get first soul's skills
DfVector <uint32_t> skills(p, soul + offs.soul_skills_vector_offset);
furball.defaultSoul.numSkills = skills.size();
for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++)
{
uint32_t temp2 = skills[i];
// a byte: this gives us 256 skills maximum.
furball.defaultSoul.skills[i].id = p->readByte (temp2);
furball.defaultSoul.skills[i].rating = p->readByte (temp2 + 4);
furball.defaultSoul.skills[i].experience = p->readWord (temp2 + 8);
furball.defaultSoul.skills[i].rating =
p->readByte (temp2 + offsetof(t_skill, rating));
furball.defaultSoul.skills[i].experience =
p->readWord (temp2 + offsetof(t_skill, experience));
}
// mental attributes are part of the soul
p->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability);
p->read(soul + offs.soul_mental_offset,
sizeof(t_attrib) * NUM_CREATURE_MENTAL_ATTRIBUTES,
(uint8_t *)&furball.defaultSoul.analytical_ability);
// traits as well
p->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits);
p->read(soul + offs.soul_traits_offset,
sizeof (uint16_t) * NUM_CREATURE_TRAITS,
(uint8_t *) &furball.defaultSoul.traits);
}
DfVector <uint32_t> app(p, temp + offs.appearance_vector_offset);
@ -301,7 +312,7 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
{
if (!d->Started)
return -1;
Process *p = d->owner;
/*
if(d->creature_module)
@ -346,14 +357,15 @@ int32_t Creatures::ReadCreatureInBox (int32_t index, t_creature & furball,
}
}
bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(!d->Started) return false;
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->write(temp + d->creatures.labors_offset, NUM_CREATURE_LABORS, labors);
uint32_t pickup_equip;
p->readDWord(temp + d->creatures.pickup_equipment_bit, pickup_equip);
@ -362,6 +374,198 @@ bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LA
return true;
}
bool Creatures::WriteHappiness(const uint32_t index, const uint32_t happinessValue)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.happiness_offset, happinessValue);
return true;
}
bool Creatures::WriteFlags(const uint32_t index,
const uint32_t flags1,
const uint32_t flags2)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord (temp + d->creatures.flags1_offset, flags1);
p->writeDWord (temp + d->creatures.flags2_offset, flags2);
return true;
}
bool Creatures::WriteSkills(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
DfVector<uint32_t> skills(p, souloff + d->creatures.soul_skills_vector_offset);
for (uint32_t i=0; i<soul.numSkills; i++)
{
uint32_t temp2 = skills[i];
p->writeByte(temp2 + offsetof(t_skill, rating), soul.skills[i].rating);
p->writeWord(temp2 + offsetof(t_skill, experience), soul.skills[i].experience);
}
return true;
}
bool Creatures::WriteAttributes(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
// physical attributes
p->write(temp + d->creatures.physical_offset,
sizeof(t_attrib) * NUM_CREATURE_PHYSICAL_ATTRIBUTES,
(uint8_t *)&creature.strength);
// mental attributes are part of the soul
p->write(souloff + d->creatures.soul_mental_offset,
sizeof(t_attrib) * NUM_CREATURE_MENTAL_ATTRIBUTES,
(uint8_t *)&creature.defaultSoul.analytical_ability);
return true;
}
bool Creatures::WriteSex(const uint32_t index, const uint8_t sex)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeByte (temp + d->creatures.sex_offset, sex);
}
bool Creatures::WriteTraits(const uint32_t index, const t_soul &soul)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
uint32_t souloff = p->readDWord(temp + d->creatures.default_soul_offset);
if(!souloff)
{
return false;
}
p->write(souloff + d->creatures.soul_traits_offset,
sizeof (uint16_t) * NUM_CREATURE_TRAITS,
(uint8_t *) &soul.traits);
return true;
}
bool Creatures::WriteMood(const uint32_t index, const uint16_t mood)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeWord(temp + d->creatures.mood_offset, mood);
return true;
}
bool Creatures::WriteMoodSkill(const uint32_t index, const uint16_t moodSkill)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeWord(temp + d->creatures.mood_skill_offset, moodSkill);
return true;
}
bool Creatures::WriteJob(const t_creature * furball, std::vector<t_material> const& mat)
{
unsigned int i;
if(!d->Inited) return false;
if(!furball->current_job.active) return false;
Process * p = d->owner;
memory_info * minfo = d->d->offset_descriptor;
DfVector <uint32_t> cmats(p, furball->current_job.occupationPtr + minfo->getOffset("job_materials_vector"));
for(i=0;i<cmats.size();i++)
{
p->writeWord(cmats[i] + minfo->getOffset("job_material_maintype"), mat[i].itemType);
p->writeWord(cmats[i] + minfo->getOffset("job_material_sectype1"), mat[i].subType);
p->writeWord(cmats[i] + minfo->getOffset("job_material_sectype2"), mat[i].subIndex);
p->writeDWord(cmats[i] + minfo->getOffset("job_material_sectype3"), mat[i].index);
p->writeDWord(cmats[i] + minfo->getOffset("job_material_flags"), mat[i].flags);
}
return true;
}
bool Creatures::WritePos(const uint32_t index, const t_creature &creature)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->write (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (creature.x));
return true;
}
bool Creatures::WriteCiv(const uint32_t index, const int32_t civ)
{
if(!d->Started)
{
return false;
}
uint32_t temp = d->p_cre->at (index);
Process * p = d->owner;
p->writeDWord(temp + d->creatures.civ_offset, civ);
return true;
}
uint32_t Creatures::GetDwarfRaceIndex()
{
if(!d->Inited) return 0;

@ -22,21 +22,7 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Creatures.h"
#include "dfhack-c/modules/Creatures_C.h"
#include "DFHack_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -21,16 +21,8 @@ must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <vector>
#include <string>
#include "DFHack_C.h"
#include "dfhack-c/modules/Gui_C.h"
#include "dfhack/DFIntegers.h"
#include "Internal.h"
#include "dfhack/modules/Gui.h"
using namespace DFHack;
#include "dfhack-c/modules/Gui_C.h"
#ifdef __cplusplus
extern "C" {

@ -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<ItemImprovementDesc> 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<int32_t, ItemDesc *> descType;
std::map<uint32_t, ItemDesc *> 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<uint32_t, ItemDesc *>::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<uint32_t, ItemDesc *>::iterator it;
Process * p = d->owner;
ItemDesc * desc;
std::map<uint32_t, ItemDesc *>::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<int32_t, ItemDesc *>::iterator it;
std::string out;
std::map<int32_t, ItemDesc *>::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;
}

@ -22,29 +22,14 @@ must not be misrepresented as being the original software.
distribution.
*/
#include <map>
#include <vector>
#include <string>
#include "dfhack/DFExport.h"
#include "dfhack/DFIntegers.h"
#include "DFHack_C.h"
#include "dfhack/DFTypes.h"
using namespace std;
using namespace DFHack;
#include "dfhack/DFProcess.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Items.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack-c/modules/Items_C.h"
#ifdef __cplusplus
extern "C" {
#endif
//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)
{
if(items != NULL && mats != NULL)
@ -53,7 +38,8 @@ char* Items_getItemDescription(DFHackObject* items, uint32_t itemptr, DFHackObje
if(desc.size() > 0)
{
char* buf = (*alloc_char_buffer_callback)(desc.size());
char* buf;
(*alloc_char_buffer_callback)(buf,desc.size());
if(buf != NULL)
{
@ -80,8 +66,8 @@ char* Items_getItemClass(DFHackObject* items, int32_t index)
if(iclass.size() > 0)
{
char* buf = (*alloc_char_buffer_callback)(iclass.size());
char* buf;
(*alloc_char_buffer_callback)(buf, iclass.size());
if(buf != NULL)
{
size_t len = iclass.copy(buf, iclass.size());

@ -37,7 +37,7 @@ distribution.
#define SHMCMD(num) ((shm_cmd *)d->d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->d->shm_start)
#define SHMDATA(type) ((type *)(d->d->shm_start + SHM_HEADER))
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack;
struct Maps::Private
@ -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 <uint32_t, t_feature> local_feature_store;
vector<uint16_t> 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,27 +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;
@ -129,6 +125,7 @@ Maps::~Maps()
{
if(d->Started)
Finish();
delete d;
}
/*-----------------------------------*
@ -140,15 +137,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);
@ -193,6 +192,7 @@ bool Maps::Start()
// getter for map size
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{
MAPS_GUARD
x = d->x_block_count;
y = d->y_block_count;
z = d->z_block_count;
@ -216,6 +216,7 @@ bool Maps::Finish()
bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{
MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return false;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0;
@ -223,6 +224,7 @@ bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
uint32_t Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
{
MAPS_GUARD
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return 0;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
@ -230,6 +232,7 @@ uint32_t Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{
MAPS_GUARD
Process *p = d->owner;
if(d->d->shm_start && d->maps_module) // ACCELERATE!
{
@ -264,10 +267,11 @@ 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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -279,6 +283,7 @@ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buff
bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -289,11 +294,12 @@ 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)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
@ -307,6 +313,7 @@ bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -321,9 +328,12 @@ 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
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
@ -336,6 +346,7 @@ bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &bloc
}
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -349,10 +360,10 @@ 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
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -364,6 +375,7 @@ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d
bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -375,10 +387,10 @@ 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
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -390,6 +402,7 @@ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *bu
bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -401,9 +414,10 @@ 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
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -417,6 +431,7 @@ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *
}
bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -434,6 +449,7 @@ bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures
*/
bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -445,6 +461,7 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -458,6 +475,7 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -470,6 +488,7 @@ bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
@ -485,6 +504,7 @@ bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global
*/
bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins, vector <t_frozenliquidvein>* ices, vector <t_spattervein> *splatter)
{
MAPS_GUARD
t_vein v;
t_frozenliquidvein fv;
t_spattervein sv;
@ -625,6 +645,7 @@ __int16 __userpurge GetGeologicalRegion<ax>(__int16 block_X<cx>, int X<ebx>, __i
*/
bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
{
MAPS_GUARD
memory_info * minfo = d->d->offset_descriptor;
Process *p = d->owner;
// get needed addresses and offsets. Now this is what I call crazy.
@ -694,10 +715,11 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features )
{
MAPS_GUARD
// 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
@ -709,32 +731,26 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
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<ptr>) * 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<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size();
planecoord pc;
@ -744,7 +760,7 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
for(uint32_t i = 0; i < size; i++)
{
uint32_t cur_ptr = p_features[i];
map <uint32_t, t_feature>::iterator it;
it = d->local_feature_store.find(cur_ptr);
// do we already have the feature?
@ -792,19 +808,20 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
{
MAPS_GUARD
// 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<uint32_t> p_features (p,global_feature_vector);
features.clear();
uint32_t size = p_features.size();
features.reserve(size);
@ -815,7 +832,7 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & 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")

@ -22,20 +22,14 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "dfhack/DFIntegers.h"
#include <vector>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
#include "Internal.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Maps.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack-c/modules/Maps_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
@ -280,6 +274,98 @@ int Maps_ReadRegionOffsets(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t
return -1;
}
t_vein* Maps_ReadStandardVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_vein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins);
if(result)
{
t_vein* v_buf = NULL;
if(veins.size() > 0)
{
((*alloc_vein_buffer_callback)(v_buf, veins.size()));
copy(veins.begin(), veins.end(), v_buf);
}
return v_buf;
}
else
return NULL;
}
return NULL;
}
t_frozenliquidvein* Maps_ReadFrozenVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_frozenliquidvein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_frozenliquidvein> frozen_veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, &frozen_veins);
if(result)
{
t_frozenliquidvein* fv_buf = NULL;
if(frozen_veins.size() > 0)
{
((*alloc_frozenliquidvein_buffer_callback)(fv_buf, frozen_veins.size()));
copy(frozen_veins.begin(), frozen_veins.end(), fv_buf);
}
return fv_buf;
}
else
return NULL;
}
return NULL;
}
t_spattervein* Maps_ReadSpatterVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{
if(maps != NULL)
{
if(alloc_spattervein_buffer_callback == NULL)
return NULL;
vector<t_vein> veins;
vector<t_spattervein> spatter_veins;
bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, &spatter_veins);
if(result)
{
t_spattervein* sv_buf = NULL;
if(spatter_veins.size() > 0)
{
((*alloc_spattervein_buffer_callback)(sv_buf, spatter_veins.size()));
copy(spatter_veins.begin(), spatter_veins.end(), sv_buf);
}
return sv_buf;
}
else
return NULL;
}
return NULL;
}
#ifdef __cplusplus
}
#endif

@ -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:
@ -243,24 +258,24 @@ bool Materials::ReadCreatureTypes (void)
bool Materials::ReadOthers(void)
{
Process * p = d->owner;
uint32_t matBase = p->getDescriptor()->getAddress ("mat_other");
uint32_t i = 0;
uint32_t ptr;
Process * p = d->owner;
uint32_t matBase = p->getDescriptor()->getAddress ("mat_other");
uint32_t i = 0;
uint32_t ptr;
other.clear();
other.clear();
while(1)
{
t_matglossOther mat;
ptr = p->readDWord(matBase + i*4);
if(ptr==0)
break;
p->readSTLString(ptr, mat.rawname, sizeof(mat.rawname));
other.push_back(mat);
i++;
}
return true;
while(1)
{
t_matglossOther mat;
ptr = p->readDWord(matBase + i*4);
if(ptr==0)
break;
p->readSTLString(ptr, mat.rawname, sizeof(mat.rawname));
other.push_back(mat);
i++;
}
return true;
}
bool Materials::ReadDescriptorColors (void)
@ -301,8 +316,8 @@ bool Materials::ReadCreatureTypesEx (void)
uint32_t bodypart_id_offset = mem->getOffset ("bodypart_id");
uint32_t bodypart_category_offset = mem->getOffset ("bodypart_category");
uint32_t bodypart_layers_offset = mem->getOffset ("bodypart_layers_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector");
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector");
uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); // unused
uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector"); // unused
uint32_t color_modifier_part_offset = mem->getOffset ("color_modifier_part");
uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate");
uint32_t color_modifier_enddate_offset = mem->getOffset ("color_modifier_enddate");
@ -318,7 +333,18 @@ bool Materials::ReadCreatureTypesEx (void)
for (uint32_t i = 0; i < size;i++)
{
t_creaturetype mat;
// FROM race READ
// std::string rawname AT 0,
// char tile_character AT tile_offset,
// word tilecolor.fore : tile_color_offset,
// word tilecolor.back : tile_color_offset + 2,
// word tilecolor.bright : tile_color_offset + 4
p->readSTLString (p_races[i], mat.rawname, sizeof(mat.rawname));
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_castes(p, p_races[i] + castes_vector_offset);
sizecas = p_castes.size();
for (uint32_t j = 0; j < sizecas;j++)
@ -364,11 +390,6 @@ bool Materials::ReadCreatureTypesEx (void)
mat.castes.push_back(caste);
}
mat.tile_character = p->readByte( p_races[i] + tile_offset );
mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset );
mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 );
mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 );
DfVector <uint32_t> p_extract(p, p_races[i] + extract_vector_offset);
for(uint32_t j = 0; j < p_extract.size(); j++)
{
@ -395,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) )
{
@ -408,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)
@ -424,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");
@ -446,6 +467,56 @@ std::string Materials::getDescription(t_material & mat)
{
return this->organic[mat.index].id;
}
return out;
return out;
}
//type of material only so we know which vector to retrieve
std::string Materials::getType(t_material & mat)
{
if((mat.subIndex<419) || (mat.subIndex>618))
{
if((mat.subIndex<19) || (mat.subIndex>218))
{
if(mat.subIndex)
{
if(mat.subIndex>0x292)
{
return "unknown";
}
else
{
if(mat.subIndex>=this->other.size())
{
if(mat.subIndex<0)
return "any";
if(mat.subIndex>=this->raceEx.size())
return "unknown";
return "racex";
}
else
{
if (mat.index==-1)
return "other";
else
return "other derivate";
}
}
}
else
return "inorganic";
}
else
{
if (mat.index>=this->raceEx.size())
return "unknown";
return "racex extract";
}
}
else
{
return "organic";
}
}

@ -22,21 +22,8 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "dfhack/DFIntegers.h"
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include "Internal.h"
#include "dfhack/DFTypes.h"
#include "dfhack/modules/Materials.h"
#include "dfhack-c/DFTypes_C.h"
#include "dfhack-c/modules/Materials_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
@ -233,7 +220,9 @@ t_matgloss* Materials_getInorganic(DFHackObject* mat)
if(materials->inorganic.size() > 0)
{
t_matgloss* buf = ((*alloc_matgloss_buffer_callback)(materials->inorganic.size()));
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->inorganic.size()));
if(buf != NULL)
{
@ -255,7 +244,9 @@ t_matgloss* Materials_getOrganic(DFHackObject* mat)
if(materials->organic.size() > 0)
{
t_matgloss* buf = ((*alloc_matgloss_buffer_callback)(materials->organic.size()));
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->organic.size()));
if(buf != NULL)
{
@ -277,7 +268,9 @@ t_matgloss* Materials_getTree(DFHackObject* mat)
if(materials->tree.size() > 0)
{
t_matgloss* buf = ((*alloc_matgloss_buffer_callback)(materials->tree.size()));
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->tree.size()));
if(buf != NULL)
{
@ -299,7 +292,9 @@ t_matgloss* Materials_getPlant(DFHackObject* mat)
if(materials->plant.size() > 0)
{
t_matgloss* buf = ((*alloc_matgloss_buffer_callback)(materials->plant.size()));
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->plant.size()));
if(buf != NULL)
{
@ -321,7 +316,9 @@ t_matgloss* Materials_getRace(DFHackObject* mat)
if(materials->race.size() > 0)
{
t_matgloss* buf = ((*alloc_matgloss_buffer_callback)(materials->race.size()));
t_matgloss* buf;
((*alloc_matgloss_buffer_callback)(buf, materials->race.size()));
if(buf != NULL)
{
@ -345,7 +342,9 @@ c_creaturetype* Materials_getRaceEx(DFHackObject* mat)
if(matSize > 0)
{
c_creaturetype* buf = ((*alloc_creaturetype_buffer_callback)(matSize));
c_creaturetype* buf;
((*alloc_creaturetype_buffer_callback)(buf, matSize));
if(buf != NULL)
{
@ -368,7 +367,9 @@ t_descriptor_color* Materials_getColor(DFHackObject* mat)
if(materials->color.size() > 0)
{
t_descriptor_color* buf = ((*alloc_descriptor_buffer_callback)(materials->color.size()));
t_descriptor_color* buf;
((*alloc_descriptor_buffer_callback)(buf, materials->color.size()));
if(buf != NULL)
{
@ -390,7 +391,9 @@ t_matglossOther* Materials_getOther(DFHackObject* mat)
if(materials->other.size() > 0)
{
t_matglossOther* buf = ((*alloc_matgloss_other_buffer_callback)(materials->other.size()));
t_matglossOther* buf;
((*alloc_matgloss_other_buffer_callback)(buf, materials->other.size()));
if(buf != NULL)
{

@ -41,12 +41,15 @@ struct Position::Private
uint32_t hotkey_mode_offset;
uint32_t hotkey_xyz_offset;
uint32_t hotkey_size;
uint32_t screen_tiles_ptr_offset;
DFContextShared *d;
Process * owner;
bool Inited;
bool Started;
bool StartedHotkeys;
bool StartedScreen;
};
Position::Position(DFContextShared * d_)
@ -55,7 +58,7 @@ Position::Position(DFContextShared * d_)
d->d = d_;
d->owner = d_->p;
d->Inited = true;
d->StartedHotkeys = d->Started = false;
d->StartedHotkeys = d->Started = d->StartedScreen = false;
memory_info * mem;
try
{
@ -66,7 +69,10 @@ Position::Position(DFContextShared * d_)
d->cursor_xyz_offset = mem->getAddress ("cursor_xyz");
d->window_dims_offset = mem->getAddress ("window_dims");
d->Started = true;
}
catch(exception &){};
try
{
d->hotkey_start = mem->getAddress("hotkey_start");
d->hotkey_mode_offset = mem->getOffset ("hotkey_mode");
d->hotkey_xyz_offset = mem->getOffset("hotkey_xyz");
@ -74,6 +80,12 @@ Position::Position(DFContextShared * d_)
d->StartedHotkeys = true;
}
catch(exception &){};
try
{
d->screen_tiles_ptr_offset = mem->getAddress ("screen_tiles_pointer");
d->StartedScreen = true;
}
catch(exception &){};
}
Position::~Position()
@ -158,3 +170,33 @@ bool Position::getWindowSize (int32_t &width, int32_t &height)
return true;
}
bool Position::getScreenTiles (int32_t width, int32_t height, t_screen screen[])
{
if(!d->Inited) return false;
if(!d->StartedScreen) return false;
uint32_t screen_addr;
d->owner->read (d->screen_tiles_ptr_offset, sizeof(uint32_t), (uint8_t *) screen_addr);
uint8_t* tiles = new uint8_t[width*height*4/* + 80 + width*height*4*/];
d->owner->read (screen_addr, (width*height*4/* + 80 + width*height*4*/), (uint8_t *) tiles);
for(int32_t iy=0; iy<height; iy++)
{
for(int32_t ix=0; ix<width; ix++)
{
screen[ix + iy*width].symbol = tiles[iy + ix*height*4 +0];
screen[ix + iy*width].foreground = tiles[iy + ix*height*4 +1];
screen[ix + iy*width].background = tiles[iy + ix*height*4 +2];
screen[ix + iy*width].bright = tiles[iy + ix*height*4 +3];
//screen[ix + iy*width].gtile = tiles[width*height*4 + 80 + iy + ix*height +0];
//screen[ix + iy*width].grayscale = tiles[width*height*4 + 80 + iy + ix*height +1];
}
}
delete [] tiles;
return true;
}

@ -22,15 +22,7 @@ must not be misrepresented as being the original software.
distribution.
*/
#include <vector>
#include <string>
#include "dfhack-c/modules/Position_C.h"
#include "dfhack/DFIntegers.h"
#include "Internal.h"
#include "dfhack/modules/Position.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {

@ -72,6 +72,7 @@ bool Translation::Start()
if(!d->Inited)
return false;
Process * p = d->d->p;
Finish();
DfVector <uint32_t> genericVec (p, d->genericAddress);
DfVector <uint32_t> transVec (p, d->transAddress);
DFDict & translations = d->dicts.translations;
@ -92,7 +93,6 @@ bool Translation::Start()
for (uint32_t i = 0; i < transVec.size();i++)
{
uint32_t transPtr = transVec.at(i);
DfVector <uint32_t> trans_names_vec (p, transPtr + d->word_table_offset);
for (uint32_t j = 0;j < trans_names_vec.size();j++)
{

@ -0,0 +1,67 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <vector>
#include <map>
#include <string>
using namespace std;
#include "dfhack/DFIntegers.h"
#include "DFHack.h"
#include "DFHack_C.h"
#include "dfhack/modules/WindowIO.h"
#include "dfhack-c/modules/WindowIO_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int WindowIO_TypeStr(DFHackObject* window, const char* input, int delay, bool useShift)
{
if(window != NULL)
{
((DFHack::WindowIO*)window)->TypeStr(input, delay, useShift);
return 1;
}
return -1;
}
int WindowIO_TypeSpecial(DFHackObject* window, t_special command, int count, int delay)
{
if(window != NULL)
{
((DFHack::WindowIO*)window)->TypeSpecial(command, count, delay);
return 1;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -95,12 +95,22 @@ uint32_t World::ReadCurrentTick()
return 0;
}
// FIX'D according to this:
/*
World::ReadCurrentMonth and World::ReadCurrentDay
« Sent to: peterix on: June 04, 2010, 04:44:30 »
« You have forwarded or responded to this message. »
ReplyQuoteRemove
Shouldn't these be /28 and %28 instead of 24? There're 28 days in a DF month.
Using 28 and doing the calculation on the value stored at the memory location
specified by memory.xml gets me the current month/date.
*/
uint32_t World::ReadCurrentMonth()
{
return this->ReadCurrentTick() / 1200 / 24;
return this->ReadCurrentTick() / 1200 / 28;
}
uint32_t World::ReadCurrentDay()
{
return ((this->ReadCurrentTick() / 1200) % 24) + 1;
return ((this->ReadCurrentTick() / 1200) % 28) + 1;
}

@ -0,0 +1,105 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "DFHack_C.h"
#include "dfhack/modules/World.h"
#include "dfhack-c/modules/World_C.h"
#ifdef __cplusplus
extern "C" {
#endif
int World_Start(DFHackObject* world)
{
if(world != NULL)
{
if(((DFHack::World*)world)->Start())
return 1;
else
return 0;
}
return -1;
}
int World_Finish(DFHackObject* world)
{
if(world != NULL)
{
if(((DFHack::World*)world)->Finish())
return 1;
else
return 0;
}
return -1;
}
int World_ReadCurrentTick(DFHackObject* world, uint32_t* tick)
{
if(world != NULL)
{
*tick = ((DFHack::World*)world)->ReadCurrentTick();
return 1;
}
return -1;
}
int World_ReadCurrentYear(DFHackObject* world, uint32_t* year)
{
if(world != NULL)
{
*year = ((DFHack::World*)world)->ReadCurrentYear();
return 1;
}
return -1;
}
int World_ReadCurrentMonth(DFHackObject* world, uint32_t* month)
{
if(world != NULL)
{
*month = ((DFHack::World*)world)->ReadCurrentMonth();
return 1;
}
return -1;
}
int World_ReadCurrentDay(DFHackObject* world, uint32_t* day)
{
if(world != NULL)
{
*day = ((DFHack::World*)world)->ReadCurrentDay();
return 1;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -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 <Module *> 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;

@ -25,10 +25,12 @@ distribution.
#ifndef MEMINFO_MANAGER_H_INCLUDED
#define MEMINFO_MANAGER_H_INCLUDED
#include "DFPragma.h"
#include "dfhack/DFPragma.h"
class TiXmlElement;
namespace DFHack
{
class memory_info;
class MemInfoManager
{
friend class ProcessEnumerator;
@ -38,8 +40,8 @@ namespace DFHack
// memory info entries loaded from a file
bool loadFile( string path_to_xml);
bool isInErrorState() const {return error;};
private:
std::vector<memory_info*> meminfo;
private:
void ParseVTable(TiXmlElement* vtable, memory_info* mem);
void ParseEntry (TiXmlElement* entry, memory_info* mem, map <string ,TiXmlElement *>& knownEntries);
bool error;

@ -1,25 +0,0 @@
from ctypes import *
from pydfhack import libdfhack, ViewScreen
libdfhack.Gui_ReadViewScreen.argtypes = [ c_void_p, c_void_p ]
class Gui(object):
def __init__(self, ptr):
self._gui_ptr = ptr
def start(self):
return libdfhack.Gui_Start(self._gui_ptr)
def finish(self):
return libdfhack.Gui_Finish(self._gui_ptr)
def read_pause_state(self):
return libdfhack.Gui_ReadPauseState(self._pos_ptr) > 0
def read_view_screen(self):
s = ViewScreen()
if libdfhack.Gui_ReadViewScreen(self._gui_ptr, byref(s)) > 0:
return s
else:
return None

@ -1,141 +0,0 @@
from ctypes import *
from pydftypes import libdfhack
from util import *
_get_arg_types = [ c_void_p, _arr_create_func ]
libdfhack.Materials_getInorganic.argtypes = _get_arg_types
libdfhack.Materials_getOrganic.argtypes = _get_arg_types
libdfhack.Materials_getTree.argtypes = _get_arg_types
libdfhack.Materials_getPlant.argtypes = _get_arg_types
libdfhack.Materials_getRace.argtypes = _get_arg_types
#libdfhack.Materials_getRaceEx.argtypes = _get_arg_types
libdfhack.Materials_getColor.argtypes = _get_arg_types
libdfhack.Materials_getOther.argtypes = _get_arg_types
class Materials(object):
def __init__(self, ptr):
self._mat_ptr = ptr
self.inorganic = None
self.organic = None
self.tree = None
self.plant = None
self.race = None
self.race_ex = None
self.color = None
self.other = None
def read_inorganic(self):
return libdfhack.Materials_ReadInorganicMaterials(self._mat_ptr)
def read_organic(self):
return libdfhack.Materials_ReadOrganicMaterials(self._mat_ptr)
def read_wood(self):
return libdfhack.Materials_ReadWoodMaterials(self._mat_ptr)
def read_plant(self):
return libdfhack.Materials_ReadPlantMaterials(self._mat_ptr)
def read_creature_types(self):
return libdfhack.Materials_ReadCreatureTypes(self._mat_ptr)
def read_creature_types_ex(self):
return libdfhack.Materials_ReadCreatureTypesEx(self._mat_ptr)
def read_descriptor_colors(self):
return libdfhack.Materials_ReadDescriptorColors(self._mat_ptr)
def read_others(self):
return libdfhack.Materials_ReadOthers(self._mat_ptr)
def read_all(self):
libdfhack.Materials_ReadAllMaterials(self._mat_ptr)
def get_description(self, material):
return libdfhack.Materials_getDescription(self._mat_ptr, byref(material))
def update_inorganic_cache(self):
def update_callback(count):
allocated = _allocate_array(Matgloss, count)
self.inorganic = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getInorganic(self._mat_ptr, callback)
def update_organic_cache(self):
def update_callback(count):
allocated = _allocate_array(Matgloss, count)
self.organic = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getOrganic(self._mat_ptr, callback)
def update_tree_cache(self):
def update_callback(count):
allocated = _allocate_array(Matgloss, count)
self.tree = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getTree(self._mat_ptr, callback)
def update_plant_cache(self):
def update_callback(count):
allocated = _allocate_array(Matgloss, count)
self.plant = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getPlant(self._mat_ptr, callback)
def update_race_cache(self):
def update_callback(count):
allocated = _allocate_array(Matgloss, count)
self.race = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getRace(self._mat_ptr, callback)
def update_color_cache(self):
def update_callback(count):
allocated = _allocate_array(DescriptorColor, count)
self.color = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getColor(self._mat_ptr, callback)
def update_other_cache(self):
def update_callback(count):
allocated = _allocate_array(MatglossOther, count)
self.other = allocated[0]
return allocated[1]
callback = _arr_create_func(update_callback)
return libdfhack.Materials_getOther(self._mat_ptr, callback)

@ -1,43 +0,0 @@
from ctypes import *
from pydftypes import libdfhack
class Position(object):
def __init__(self, ptr):
self._pos_ptr = ptr
self._vx, self._vy, self._vz = c_int(), c_int(), c_int()
self._cx, self._cy, self._cz = c_int(), c_int(), c_int()
self._ww, self._wh = c_int(), c_int()
def get_view_coords(self):
if libdfhack.Position_getViewCoords(self._pos_ptr, byref(self._vx), byref(self._vy), byref(self._vz)) > 0:
return (self._vx.value, self._vy.value, self._vz.value)
else:
return (-1, -1, -1)
def set_view_coords(self, v_coords):
self._vx.value, self._vy.value, self._vz.value = v_coords
libdfhack.Position_setViewCoords(self._pos_ptr, self._vx, self._vy, self._vz)
view_coords = property(get_view_coords, set_view_coords)
def get_cursor_coords(self):
if libdfhack.Position_getCursorCoords(self._pos_ptr, byref(self._cx), byref(self._cy), byref(self._cz)) > 0:
return (self._cx.value, self._cy.value, self._cz.value)
else:
return (-1, -1, -1)
def set_cursor_coords(self, c_coords):
self._cx.value, self._cy.value, self_cz.value = c_coords
libdfhack.Position_setCursorCoords(self._pos_ptr, self._cx, self._cy, self._cz)
cursor_coords = property(get_cursor_coords, set_cursor_coords)
@property
def window_size(self):
if libdfhack.Position_getWindowSize(self._pos_ptr, byref(self._ww), byref(self._wh)) > 0:
return (self._ww.value, self._wh.value)
else:
return (-1, -1)

@ -1,66 +0,0 @@
from ctypes import *
def _uintify(x, y, z):
return (c_uint(x), c_uint(y), c_uint(z))
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_int_buffer(count):
a = _allocate_array(c_int, count)
return a[1]
alloc_int_buffer = CFUNCTYPE(POINTER(c_int), c_uint)(_alloc_int_buffer)
def _alloc_uint_buffer(count):
a = _allocate_array(c_uint, count)
return a[1]
alloc_uint_buffer = CFUNCTYPE(POINTER(c_uint), c_uint)(_alloc_uint_buffer)
def _alloc_short_buffer(count):
a = _allocate_array(c_short, count)
return a[1]
alloc_short_buffer = CFUNCTYPE(POINTER(c_short), c_uint)(_alloc_short_buffer)
def _alloc_ushort_buffer(count):
a = _allocate_array(c_ushort, count)
return a[1]
alloc_ushort_buffer = CFUNCTYPE(POINTER(c_ushort), c_uint)(_alloc_ushort_buffer)
def _alloc_byte_buffer(count):
a = _allocate_array(c_byte, count)
return a[1]
alloc_byte_buffer = CFUNCTYPE(POINTER(c_byte), c_uint)(_alloc_byte_buffer)
def _alloc_ubyte_buffer(count):
a = _allocate_array(c_ubyte, count)
return a[1]
alloc_ubyte_buffer = CFUNCTYPE(POINTER(c_ubyte), c_uint)(_alloc_ubyte_buffer)
def _alloc_char_buffer(count):
c = create_string_buffer(count)
ptr = c_void_p()
ptr = addressof(c)
return ptr
alloc_char_buffer = CFUNCTYPE(POINTER(c_char), c_uint)(_alloc_char_buffer)

@ -1,25 +0,0 @@
from ctypes import *
from pydftypes import libdfhack, Tree
class Vegetation(object):
def __init__(self, ptr):
self._v_ptr = ptr
def start(self):
n = c_uint(0)
if libdfhack.Vegetation_Start(self._v_ptr, byref(n)) > 0:
return int(n.value)
else:
return -1
def finish(self):
return libdfhack.Vegetation_Finish(self._v_ptr) > 0
def read(self, index):
t = Tree()
if libdfhack.Vegetation_Read(self._v_ptr, c_uint(index), byref(t)) > 0:
return t
else:
return None

Some files were not shown because too many files have changed in this diff Show More