SHM rework, stage 1
							parent
							
								
									b3424418e6
								
							
						
					
					
						commit
						0192520d43
					
				@ -1,138 +0,0 @@
 | 
			
		||||
Here's how you build dfhack!
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
First, there is one dependency, regardless of the OS you use:
 | 
			
		||||
  cmake - it's the build system
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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!
 | 
			
		||||
 | 
			
		||||
* 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 - 40d17 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't be debugged, because debug builds in MSVC use a different CRT!
 | 
			
		||||
 | 
			
		||||
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 lost.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 throughput 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 build types include 'Release' and 'Debug'. There are others, but they aren't really that useful.
 | 
			
		||||
 | 
			
		||||
Have fun.
 | 
			
		||||
@ -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:
 | 
			
		||||
  http://github.com/peterix/dfhack
 | 
			
		||||
 | 
			
		||||
There's an SVN repository at sourceforge, but will only be updated for major releases:
 | 
			
		||||
  https://sourceforge.net/projects/dfhack/
 | 
			
		||||
* subversion access: 
 | 
			
		||||
  svn co https://dfhack.svn.sourceforge.net/svnroot/dfhack/trunk dfhack 
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  40d
 | 
			
		||||
  40d9 - 40d18
 | 
			
		||||
 | 
			
		||||
* Linux
 | 
			
		||||
  40d9 - 40d18
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Using the library
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Using DFHack Tools
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
The project comes with a special extra library you should add to your DF
 | 
			
		||||
installation. It's used to boost the transfer speed between DF and DFHack, and
 | 
			
		||||
provide data consistency and synchronization. DFHack will work without the
 | 
			
		||||
library, but at suboptimal speeds and the consistency of data written back
 | 
			
		||||
to DF is questionable.
 | 
			
		||||
 | 
			
		||||
!!!     on Windows this currently only works with DF 40d15 - 40d18      !!!
 | 
			
		||||
     On Linux, it works with the whole range of supported DF versions.
 | 
			
		||||
 | 
			
		||||
!!! use the pre-compiled library intended for your OS and version of DF !!!
 | 
			
		||||
               You can find them in the 'precompiled' folder.
 | 
			
		||||
               
 | 
			
		||||
 | 
			
		||||
 ** Installing on Windows
 | 
			
		||||
 - Open your DF folder, locate SDL.dll and rename it to SDLreal.dll (making
 | 
			
		||||
   a backup of it is a good idea)
 | 
			
		||||
 - Copy the right DFHack SDL.dll into your DF folder.
 | 
			
		||||
 - Restart DF if it is running
 | 
			
		||||
 | 
			
		||||
 ** Unistalling on Windows
 | 
			
		||||
 - Open your DF folder, locate SDL.dll and delete it
 | 
			
		||||
 - Rename SDLreal.dll to SDL.dll
 | 
			
		||||
 - Restart DF if it is running
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 ** Installing on Linux
 | 
			
		||||
 - Open your DF folder and the libs folder within it
 | 
			
		||||
 - copy DFHack libdfconnect.so to the libs folder
 | 
			
		||||
 - copy the df startup script, name it dfhacked
 | 
			
		||||
 - open the new dfhacked startup script and add this line:
 | 
			
		||||
     export LD_PRELOAD="./libs/libdfconnect.so" # Hack DF!
 | 
			
		||||
   just before the line that launches DF
 | 
			
		||||
 | 
			
		||||
   Here's an example how the file can look after the change:
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
DF_DIR=$(dirname "$0")
 | 
			
		||||
cd "${DF_DIR}"
 | 
			
		||||
export SDL_DISABLE_LOCK_KEYS=1 # Work around for bug in Debian/Ubuntu SDL patch.
 | 
			
		||||
#export SDL_VIDEO_CENTERED=1 # Centre the screen.  Messes up resizing.
 | 
			
		||||
ldd dwarfort.exe | grep SDL_image | grep -qv "not found$"
 | 
			
		||||
if [ $? -eq 0 ]; then
 | 
			
		||||
 mkdir unused_libs
 | 
			
		||||
 mv libs/libSDL* unused_libs/
 | 
			
		||||
fi
 | 
			
		||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"./libs" # Update library search path.
 | 
			
		||||
export LD_PRELOAD="./libs/libdfconnect.so" # Hack DF!
 | 
			
		||||
./dwarfort.exe $* # Go, go, go! :)
 | 
			
		||||
 | 
			
		||||
 - Use this new startup script to start DF
 | 
			
		||||
 | 
			
		||||
 ** Uninstalling on Linux
 | 
			
		||||
 - Open your DF and DF/libs folders
 | 
			
		||||
 - Delete libdfconnect.so and the dfhacked startup script
 | 
			
		||||
 - Go back to using the df startup script
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
If the tool writes back to DF's memory, make sure you are using the shared
 | 
			
		||||
memory interface mentioned in the previous section!
 | 
			
		||||
 | 
			
		||||
* reveal     - plain old reveal tool. It reveals all the map blocks already
 | 
			
		||||
               initialized by DF.
 | 
			
		||||
 | 
			
		||||
* prospector - scans the map for minerals. by default it only scans only visible
 | 
			
		||||
               veins. You can make it show hidden things with '-a' and base rock
 | 
			
		||||
               and soil layers with '-b'. These can be combined ('-ab')
 | 
			
		||||
 | 
			
		||||
* cleanmap   - cleans mud, vomit, snow and all kinds of mess from the map.
 | 
			
		||||
               It will clean your irrigated farms too, so consider yourself
 | 
			
		||||
               warned.
 | 
			
		||||
 | 
			
		||||
* incremental - incremental search utility.
 | 
			
		||||
 | 
			
		||||
* bauxite - converts all mechanisms into bauxite mechanisms.
 | 
			
		||||
 | 
			
		||||
* itemdesignator - Allows mass-designating items by type and material - dump,
 | 
			
		||||
                   forbid, melt and set on fire ;)
 | 
			
		||||
* digger         - allows designating tiles for digging/cutting/ramp removal
 | 
			
		||||
 | 
			
		||||
  A list of accepted tile classes:
 | 
			
		||||
        1  = WALL
 | 
			
		||||
        2  = PILLAR
 | 
			
		||||
        3  = FORTIFICATION
 | 
			
		||||
        
 | 
			
		||||
        4  = STAIR_UP
 | 
			
		||||
        5  = STAIR_DOWN
 | 
			
		||||
        6  = STAIR_UPDOWN
 | 
			
		||||
        
 | 
			
		||||
        7  = RAMP
 | 
			
		||||
        
 | 
			
		||||
        8  = FLOOR
 | 
			
		||||
        9  = TREE_DEAD
 | 
			
		||||
        10 = TREE_OK
 | 
			
		||||
        11 = SAPLING_DEAD
 | 
			
		||||
        12 = SAPLING_OK
 | 
			
		||||
        13 = SHRUB_DEAD
 | 
			
		||||
        14 = SHRUB_OK
 | 
			
		||||
        15 = BOULDER
 | 
			
		||||
        16 = PEBBLES
 | 
			
		||||
  
 | 
			
		||||
  Example : dfdigger -o 100,100,15 -t 9,10 -m 10
 | 
			
		||||
  This will start looking for trees at coords 100,100,15 and designate ten of them for cutting.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Memory offset definitions
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
The file with memory offset definitions used by dfhack can be found in the
 | 
			
		||||
output folder. 
 | 
			
		||||
 | 
			
		||||
~ EOF ~
 | 
			
		||||
@ -0,0 +1,274 @@
 | 
			
		||||
/*
 | 
			
		||||
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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the source for the DF <-> dfhack shm bridge's core module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "../library/integers.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "shms.h"
 | 
			
		||||
 | 
			
		||||
enum DFPP_CmdType
 | 
			
		||||
{
 | 
			
		||||
    CANCELLATION, // we should jump out of the Act()
 | 
			
		||||
    CLIENT_WAIT, // we are waiting for the client
 | 
			
		||||
    FUNCTION, // we call a function as a result of the command
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct DFPP_command
 | 
			
		||||
{
 | 
			
		||||
    DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons
 | 
			
		||||
    std::string name;
 | 
			
		||||
    void (*_function)(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct DFPP_module
 | 
			
		||||
{
 | 
			
		||||
    inline void push_command(DFPP_CmdType type, const char * name, void (*_function)(void))
 | 
			
		||||
    {
 | 
			
		||||
        DFPP_command cmd;
 | 
			
		||||
        cmd.type = type;
 | 
			
		||||
        cmd.name = name;
 | 
			
		||||
        cmd._function = _function;
 | 
			
		||||
        commands.push_back(cmd);
 | 
			
		||||
    }
 | 
			
		||||
    inline void set_command(unsigned int index, DFPP_CmdType type, const char * name, void (*_function)(void))
 | 
			
		||||
    {
 | 
			
		||||
        DFPP_command cmd;
 | 
			
		||||
        cmd.type = type;
 | 
			
		||||
        cmd.name = name;
 | 
			
		||||
        cmd._function = _function;
 | 
			
		||||
        commands[index] = cmd;
 | 
			
		||||
    }
 | 
			
		||||
    inline void reserve (unsigned int numcommands)
 | 
			
		||||
    {
 | 
			
		||||
        commands.clear();
 | 
			
		||||
        DFPP_command cmd = {CANCELLATION,"",0};
 | 
			
		||||
        commands.resize(numcommands,cmd);
 | 
			
		||||
    }
 | 
			
		||||
    std::string name;
 | 
			
		||||
    uint32_t version; // version
 | 
			
		||||
    std::vector <DFPP_command> commands;
 | 
			
		||||
    void * modulestate;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::vector <DFPP_module> module_registry;
 | 
			
		||||
 | 
			
		||||
// various crud
 | 
			
		||||
extern int errorstate;
 | 
			
		||||
extern char *shm;
 | 
			
		||||
extern int shmid;
 | 
			
		||||
 | 
			
		||||
#define SHMHDR ((shm_header *)shm)
 | 
			
		||||
#define SHMCMD ((shm_cmd *)shm)->pingpong
 | 
			
		||||
 | 
			
		||||
void GetCoreVersion (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMHDR->value = module_registry[0].version;
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_VERSION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GetPID (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMHDR->value = OS_getPID();
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_PID;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReadRaw (void)
 | 
			
		||||
{
 | 
			
		||||
    memcpy(shm + SHM_HEADER, (void *) SHMHDR->address,SHMHDR->length);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_DATA;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReadDWord (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMHDR->value = *((uint32_t*) SHMHDR->address);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_DWORD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReadWord (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMHDR->value = *((uint16_t*) SHMHDR->address);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_WORD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReadByte (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMHDR->value = *((uint8_t*) SHMHDR->address);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_BYTE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteRaw (void)
 | 
			
		||||
{
 | 
			
		||||
    memcpy((void *)SHMHDR->address, shm + SHM_HEADER,SHMHDR->length);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteDWord (void)
 | 
			
		||||
{
 | 
			
		||||
    (*(uint32_t*)SHMHDR->address) = SHMHDR->value;
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteWord (void)
 | 
			
		||||
{
 | 
			
		||||
    (*(uint16_t*)SHMHDR->address) = SHMHDR->value;
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteByte (void)
 | 
			
		||||
{
 | 
			
		||||
    (*(uint8_t*)SHMHDR->address) = SHMHDR->value;
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReadSTLString (void)
 | 
			
		||||
{
 | 
			
		||||
    std::string * myStringPtr = (std::string *) SHMHDR->address;
 | 
			
		||||
    unsigned int l = myStringPtr->length();
 | 
			
		||||
    SHMHDR->value = l;
 | 
			
		||||
    // there doesn't have to be a null terminator!
 | 
			
		||||
    strncpy(shm+SHM_HEADER,myStringPtr->c_str(),l+1);
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_RET_STRING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteSTLString (void)
 | 
			
		||||
{
 | 
			
		||||
    std::string * myStringPtr = (std::string *) SHMHDR->address;
 | 
			
		||||
    // here we DO expect a 0 terminator
 | 
			
		||||
    myStringPtr->assign((const char *) (shm + SHM_HEADER));
 | 
			
		||||
    full_barrier
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Suspend (void)
 | 
			
		||||
{
 | 
			
		||||
    SHMCMD = CORE_SUSPENDED;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InitCore(void)
 | 
			
		||||
{
 | 
			
		||||
    DFPP_module core;
 | 
			
		||||
    core.name = "Core";
 | 
			
		||||
    core.version = CORE_VERSION;
 | 
			
		||||
    core.modulestate = 0; // this one is dumb and has no real state
 | 
			
		||||
    
 | 
			
		||||
    core.reserve(NUM_CORE_CMDS);
 | 
			
		||||
    core.set_command(CORE_RUNNING, CANCELLATION, "Running", NULL);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_GET_VERSION, FUNCTION,"Get core version",GetCoreVersion);
 | 
			
		||||
    core.set_command(CORE_RET_VERSION, CLIENT_WAIT,"Core version return",0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_GET_PID, FUNCTION, "Get PID", GetPID);
 | 
			
		||||
    core.set_command(CORE_RET_PID, CLIENT_WAIT, "PID return", 0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_DFPP_READ, FUNCTION,"Raw read",ReadRaw);
 | 
			
		||||
    core.set_command(CORE_RET_DATA, CLIENT_WAIT,"Raw read return",0);
 | 
			
		||||
 | 
			
		||||
    core.set_command(CORE_READ_DWORD, FUNCTION,"Read DWORD",ReadDWord);
 | 
			
		||||
    core.set_command(CORE_RET_DWORD, CLIENT_WAIT,"Read DWORD return",0);
 | 
			
		||||
 | 
			
		||||
    core.set_command(CORE_READ_WORD, FUNCTION,"Read WORD",ReadWord);
 | 
			
		||||
    core.set_command(CORE_RET_WORD, CLIENT_WAIT,"Read WORD return",0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_READ_BYTE, FUNCTION,"Read BYTE",ReadByte);
 | 
			
		||||
    core.set_command(CORE_RET_BYTE, CLIENT_WAIT,"Read BYTE return",0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_SV_ERROR, CANCELLATION, "Server error", 0);
 | 
			
		||||
    core.set_command(CORE_CL_ERROR, CANCELLATION, "Client error", 0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_WRITE, FUNCTION, "Raw write", WriteRaw);
 | 
			
		||||
    core.set_command(CORE_WRITE_DWORD, FUNCTION, "Write DWORD", WriteDWord);
 | 
			
		||||
    core.set_command(CORE_WRITE_WORD, FUNCTION, "Write WORD", WriteWord);
 | 
			
		||||
    core.set_command(CORE_WRITE_BYTE, FUNCTION, "Write BYTE", WriteByte);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_SUSPEND, FUNCTION, "Suspend", Suspend);
 | 
			
		||||
    core.set_command(CORE_SUSPENDED, CLIENT_WAIT, "Suspended", 0);
 | 
			
		||||
    
 | 
			
		||||
    core.set_command(CORE_READ_STL_STRING, FUNCTION, "Read STL string", ReadSTLString);
 | 
			
		||||
    core.set_command(CORE_READ_C_STRING, CLIENT_WAIT, "RESERVED", 0);
 | 
			
		||||
    core.set_command(CORE_RET_STRING, CLIENT_WAIT, "Return string", 0);
 | 
			
		||||
    core.set_command(CORE_WRITE_STL_STRING, FUNCTION, "Write STL string", WriteSTLString);
 | 
			
		||||
    module_registry.push_back(core);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InitModules (void)
 | 
			
		||||
{
 | 
			
		||||
    // create the core module
 | 
			
		||||
    InitCore();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SHM_Act (void)
 | 
			
		||||
{
 | 
			
		||||
    if(errorstate)
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    uint32_t numwaits = 0;
 | 
			
		||||
    check_again: // goto target!!!
 | 
			
		||||
    if(numwaits == 10000)
 | 
			
		||||
    {
 | 
			
		||||
        // this tests if there's a process on the other side
 | 
			
		||||
        if(isValidSHM())
 | 
			
		||||
        {
 | 
			
		||||
            numwaits = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            full_barrier
 | 
			
		||||
            SHMCMD = CORE_RUNNING;
 | 
			
		||||
            fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    DFPP_module & mod = module_registry[((shm_cmd *)shm)->parts.module];
 | 
			
		||||
    DFPP_command & cmd = mod.commands[((shm_cmd *)shm)->parts.command];
 | 
			
		||||
    //fprintf(stderr, "Client invoked  %s\n", cmd.name.c_str() );
 | 
			
		||||
    if(cmd._function)
 | 
			
		||||
    {
 | 
			
		||||
        cmd._function();
 | 
			
		||||
    }
 | 
			
		||||
    if(cmd.type != CANCELLATION)
 | 
			
		||||
    {
 | 
			
		||||
        SCHED_YIELD
 | 
			
		||||
        numwaits ++; // watchdog timeout
 | 
			
		||||
        goto check_again;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,187 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the source for the DF <-> dfhack shm bridge, server protocol part
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "../library/integers.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
//#include <unistd.h>
 | 
			
		||||
#include "shms.h"
 | 
			
		||||
// various crud
 | 
			
		||||
extern int errorstate;
 | 
			
		||||
extern char *shm;
 | 
			
		||||
extern int shmid;
 | 
			
		||||
 | 
			
		||||
void SHM_Act (void)
 | 
			
		||||
{
 | 
			
		||||
    if(errorstate)
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    uint32_t numwaits = 0;
 | 
			
		||||
    uint32_t length;
 | 
			
		||||
    uint32_t address;
 | 
			
		||||
    std::string * myStringPtr;
 | 
			
		||||
    check_again: // goto target!!!
 | 
			
		||||
    SCHED_YIELD // yield the CPU, valid only on single-core CPUs
 | 
			
		||||
    if(numwaits == 10000)
 | 
			
		||||
    {
 | 
			
		||||
        // this tests if there's a process on the other side
 | 
			
		||||
        if(isValidSHM())
 | 
			
		||||
        {
 | 
			
		||||
            numwaits = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_RUNNING;
 | 
			
		||||
            fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
 | 
			
		||||
            //MessageBox(0,"Broke out of loop, other process disappeared.","FUN", MB_OK);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    switch (((shm_cmd *)shm)->pingpong)
 | 
			
		||||
    {
 | 
			
		||||
        case DFPP_RET_VERSION:
 | 
			
		||||
        case DFPP_RET_DATA:
 | 
			
		||||
        case DFPP_RET_DWORD:
 | 
			
		||||
        case DFPP_RET_WORD:
 | 
			
		||||
        case DFPP_RET_BYTE:
 | 
			
		||||
        case DFPP_RET_STRING:
 | 
			
		||||
        case DFPP_SUSPENDED:
 | 
			
		||||
        case DFPP_RET_PID:
 | 
			
		||||
        case DFPP_SV_ERROR:
 | 
			
		||||
            numwaits++;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
        case DFPP_SUSPEND:
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            /*
 | 
			
		||||
        case DFPP_BOUNCE:
 | 
			
		||||
            length = ((shm_bounce *)shm)->length;
 | 
			
		||||
            memcpy(BigFat,shm + SHM_HEADER,length);
 | 
			
		||||
            memcpy(shm + SHM_HEADER,BigFat,length);
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            */
 | 
			
		||||
        case DFPP_PID:
 | 
			
		||||
            ((shm_retval *)shm)->value = getPID();
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_PID;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_VERSION:
 | 
			
		||||
            ((shm_retval *)shm)->value = PINGPONG_VERSION;
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_VERSION;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_READ:
 | 
			
		||||
            length = ((shm_read *)shm)->length;
 | 
			
		||||
            address = ((shm_read *)shm)->address;
 | 
			
		||||
            memcpy(shm + SHM_HEADER, (void *) address,length);
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_READ_DWORD:
 | 
			
		||||
            address = ((shm_read_small *)shm)->address;
 | 
			
		||||
            ((shm_retval *)shm)->value = *((uint32_t*) address);
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_DWORD;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
 | 
			
		||||
        case DFPP_READ_WORD:
 | 
			
		||||
            address = ((shm_read_small *)shm)->address;
 | 
			
		||||
            ((shm_retval *)shm)->value = *((uint16_t*) address);
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_WORD;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_READ_BYTE:
 | 
			
		||||
            address = ((shm_read_small *)shm)->address;
 | 
			
		||||
            ((shm_retval *)shm)->value = *((uint8_t*) address);
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_BYTE;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_WRITE:
 | 
			
		||||
            address = ((shm_write *)shm)->address;
 | 
			
		||||
            length = ((shm_write *)shm)->length;
 | 
			
		||||
            memcpy((void *)address, shm + SHM_HEADER,length);
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_WRITE_DWORD:
 | 
			
		||||
            (*(uint32_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
 | 
			
		||||
        case DFPP_WRITE_WORD:
 | 
			
		||||
            (*(uint16_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
        
 | 
			
		||||
        case DFPP_WRITE_BYTE:
 | 
			
		||||
            (*(uint8_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
            
 | 
			
		||||
        case DFPP_CL_ERROR:
 | 
			
		||||
        case DFPP_RUNNING:
 | 
			
		||||
            //fprintf(stderr, "no. of waits: %d\n", numwaits);
 | 
			
		||||
            //MessageBox(0,"Broke out of loop properly","FUN", MB_OK);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case DFPP_READ_STL_STRING:
 | 
			
		||||
            myStringPtr = (std::string *) ((shm_read_small *)shm)->address;
 | 
			
		||||
            ((shm_retval *)shm)->value = myStringPtr->length();
 | 
			
		||||
            strncpy(shm+SHM_HEADER,myStringPtr->c_str(),myStringPtr->length()+1);// length + 1 for the null terminator
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_RET_STRING;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
 | 
			
		||||
        case DFPP_WRITE_STL_STRING:
 | 
			
		||||
            myStringPtr = (std::string *) ((shm_write *)shm)->address;
 | 
			
		||||
            myStringPtr->assign((const char *) (shm + SHM_HEADER));
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
 | 
			
		||||
            goto check_again;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            ((shm_retval *)shm)->value = DFEE_INVALID_COMMAND;
 | 
			
		||||
            full_barrier
 | 
			
		||||
            ((shm_retval *)shm)->pingpong = DFPP_SV_ERROR;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue