diff --git a/.gitignore b/.gitignore index 5bcab6110..702a6490c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # linux backup files *~ +#Kdevelop project file +*.kdev4 + # compiled binaries output/* @@ -13,6 +16,9 @@ library/private/config.h # any build folders build*/ +nix +buntu +build/VC2010 #except for the real one !build/ @@ -26,6 +32,7 @@ build/doc build/bin build/library build/tools +build/plugins #ignore Kdevelop stuff .kdev4 @@ -40,4 +47,7 @@ dfhack/python/PyDFHack.egg-info dfhack/python/build dfhack/python/dist +# CPack stuff +build/CPack*Config.cmake + /cmakeall.bat diff --git a/CMakeLists.txt b/CMakeLists.txt index 97c1aedff..f463cf0a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,287 +1,97 @@ # main project file. use it from a build sub-folder, see COMPILE for details ## some generic CMake magic -cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) -PROJECT (dfhack) +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +project(dfhack) SET(CMAKE_MODULE_PATH ${dfhack_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH} ) -if("${dfhack_SOURCE_DIR}" STREQUAL "${dfhack_BINARY_DIR}") +if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR "In-source builds are not allowed.") endif() -SET(DFHACK_CONSISTENCY 1) - -set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "5") -set(CPACK_PACKAGE_VERSION_PATCH "15") +set(DFHACK_VERSION_MAJOR "0") +set(DFHACK_VERSION_MINOR "31") +set(DFHACK_VERSION_PATCH "25") set(DFHACK_REVISION "1") -set(DFHACK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") -set(CPACK_PACKAGE_VERSION ${DFHACK_VERSION}) - -set(CPACK_PACKAGE_NAME "dfhack") -SET(CPACK_PACKAGE_VENDOR "dethware.org") -SET(CPACK_PACKAGE_CONTACT "peterix@dethware.org") -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Memory hacks for Dwarf Fortress") -SET(CPACK_PACKAGE_DESCRIPTION -"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.") - +set(DFHACK_VERSION "${DFHACK_VERSION_MAJOR}.${DFHACK_VERSION_MINOR}.${DFHACK_VERSION_PATCH}") ## setting the build type IF(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") - SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.") + SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Release RelWithDebInfo.") ENDIF() -## put everything in one big ugly directory to make MSVC and KDevelop debuggers happy -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dfhack_BINARY_DIR}/bin") -SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${dfhack_BINARY_DIR}/bin") -SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${dfhack_BINARY_DIR}/bin") - +SET(DFHACK_OUTPUT_DIR "${dfhack_BINARY_DIR}/bin" CACHE STRING "Where should be the produced libraries and binaries stored.") +SET(DFHACK_PLUGIN_OUTPUT_DIR "${DFHACK_OUTPUT_DIR}/plugins") + +## where to put things during the build (force MSVC to behave) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${DFHACK_OUTPUT_DIR}) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${DFHACK_OUTPUT_DIR}) + +## where to install things (after the build is done, classic 'make install' or package structure) +# the dfhack libraries will be installed here: +SET(DFHACK_LIBRARY_DESTINATION .) +# the dfhack tools will be installed here: +SET(DFHACK_BINARY_DESTINATION .) +# Memory.xml goes here: +SET(DFHACK_DATA_DESTINATION .) +# Plugins go here +SET(DFHACK_PLUGIN_DESTINATION plugins) +# Includes go here: +SET(DFHACK_INCLUDES_DESTINATION dev/include) +# the Windows .lib files go here: IF(WIN32) - set (DFHACK_INST_DEFAULT "portable") -ELSE() - set (DFHACK_INST_DEFAULT "linux") -ENDIF() - -SET( DFHACK_INSTALL ${DFHACK_INST_DEFAULT} CACHE STRING -"Choose the install type: -'portable' for a portable zip or tar.gz package (windows default) -'linux' for generic packaging and system installs on linux (linux default) -'ubuntu-10.10' for ubuntu maverick package.") - -SET( MEMXML_DATA_PATH . CACHE PATH -"Path to a valid Memory.xml file. -This is baked into the library, so when you package DFHack for linux, set it to the right path.") - -IF(${DFHACK_INSTALL} STREQUAL "portable") - # the dfhack libraries will be installed here: - SET(DFHACK_LIBRARY_DESTINATION .) - # the dfhack tools will be installed here: - SET(DFHACK_BINARY_DESTINATION .) - # Memory.xml goes here: - SET(DFHACK_DATA_DESTINATION .) - # Includes go here: - SET(DFHACK_INCLUDES_DESTINATION dev/include) - # the Windows .lib files go here: - IF(WIN32) - SET(DFHACK_DEVLIB_DESTINATION dev) - SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) - ENDIF() - IF(UNIX) - SET(CMAKE_INSTALL_RPATH "$ORIGIN") - ENDIF() - # documentation goes here: - SET(DFHACK_USERDOC_DESTINATION .) - SET(DFHACK_DEVDOC_DESTINATION dev) - SET(DFHACK_DOXYGEN_DESTINATION dev/doxygen) -ENDIF() - -# generic linux package in a .tar.gz -IF(${DFHACK_INSTALL} STREQUAL "linux") - if(WIN32) - MESSAGE(FATAL_ERROR "WTF are you doing?") - endif() - # set RPATH to always point at the dfhack lib using relative path. - SET(CMAKE_INSTALL_RPATH "$ORIGIN/../lib/") - # the dfhack libraries will be installed here: - SET(DFHACK_LIBRARY_DESTINATION lib) - # the dfhack tools will be installed here: - SET(DFHACK_BINARY_DESTINATION bin) - # Memory.xml goes here: - SET(DFHACK_DATA_DESTINATION share/dfhack) - # Includes go here: - SET(DFHACK_INCLUDES_DESTINATION include) - # documentation goes here: - SET(DFHACK_USERDOC_DESTINATION share/dfhack/doc) - SET(DFHACK_DEVDOC_DESTINATION share/dfhack/doc) - SET(DFHACK_DOXYGEN_DESTINATION share/dfhack/doc/doxygen) -ENDIF() - -IF(${DFHACK_INSTALL} STREQUAL "ubuntu-10.10" OR ${DFHACK_INSTALL} STREQUAL "debian") - if(WIN32) - MESSAGE(FATAL_ERROR "WTF are you doing?") - endif() - # set RPATH to always point at the dfhack lib using relative path. - SET(CMAKE_INSTALL_RPATH "$ORIGIN/../lib/") - # the dfhack libraries will be installed here: - SET(DFHACK_LIBRARY_DESTINATION usr/lib) - # the dfhack tools will be installed here: - SET(DFHACK_BINARY_DESTINATION usr/bin) - # Memory.xml goes here: - SET(DFHACK_DATA_DESTINATION usr/share/dfhack) - # Includes go here: - SET(DFHACK_INCLUDES_DESTINATION usr/include) - # documentation goes here: - SET(DFHACK_USERDOC_DESTINATION usr/share/dfhack/doc) - SET(DFHACK_DEVDOC_DESTINATION usr/share/dfhack/doc) - SET(DFHACK_DOXYGEN_DESTINATION usr/share/dfhack/doc/doxygen) - INSTALL(FILES - "${CMAKE_CURRENT_SOURCE_DIR}/package/${DFHACK_INSTALL}/99-dfhack.conf" - DESTINATION etc/sysctl.d) -ENDIF() - - - -## some options for the user/developer to play with -OPTION(BUILD_DFHACK_LIBRARY "Build the library. Needed for all the tools." ON) -OPTION(BUILD_DFHACK_C_BINDINGS "Build the C portion of the library." ON) -OPTION(BUILD_DFHACK_PYTHON_BINDINGS "Build/install the python wrapper." ON) -IF(WIN32) - OPTION(BUILD_DFHACK_DEVEL "Build the developer stuff." OFF) + SET(DFHACK_DEVLIB_DESTINATION dev) + SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) ENDIF() IF(UNIX) - OPTION(BUILD_DFHACK_DEVEL "Build the developer stuff." ON) + SET(CMAKE_INSTALL_RPATH "$ORIGIN") ENDIF() -OPTION(BUILD_DFHACK_DOXYGEN "Create doxygen documentation for developers" ON) -OPTION(BUILD_DFHACK_SUPPORTED "Build the supported tools." ON) -OPTION(BUILD_DFHACK_EXAMPLES "Build example tools" OFF) -OPTION(BUILD_DFHACK_PLAYGROUND "Build tools from the playground folder" OFF) -OPTION(BUILD_NO_CURSES "Don't build tools requiring curses" OFF) - -include_directories (${dfhack_SOURCE_DIR}/library/include/) -include_directories (${dfhack_SOURCE_DIR}/library/shm/) -include_directories (${dfhack_SOURCE_DIR}/library/depends/argstream/) -include_directories (${dfhack_SOURCE_DIR}/library/depends/xgetopt/) -# handle curses library bull**** on multiple platforms. -IF(UNIX) - find_package(Curses QUIET) - if(Curses_FOUND) - add_library(curses SHARED IMPORTED) - set_property(TARGET curses PROPERTY IMPORTED_LOCATION ${Curses_LIBRARY}) - include_directories (${Curses_INCLUDE_PATH}) - endif() -ELSE() - add_library(curses SHARED IMPORTED) - set_property(TARGET curses PROPERTY IMPORTED_LOCATION ${dfhack_SOURCE_DIR}/pdcurses/pdcurses.dll) - set_property(TARGET curses PROPERTY IMPORTED_IMPLIB ${dfhack_SOURCE_DIR}/pdcurses/pdcurses.lib) - include_directories (${dfhack_SOURCE_DIR}/pdcurses) - add_custom_target( curses-copy - COMMAND "${CMAKE_COMMAND}" -E make_directory ${dfhack_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/ - COMMAND "${CMAKE_COMMAND}" -E copy "${dfhack_SOURCE_DIR}/pdcurses/pdcurses.dll" ${dfhack_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/ - DEPENDS "${dfhack_SOURCE_DIR}/pdcurses/pdcurses.dll") - SET(Curses_FOUND TRUE) - INSTALL(FILES "${dfhack_SOURCE_DIR}/pdcurses/pdcurses.dll" DESTINATION ${DFHACK_BINARY_DESTINATION}) -ENDIF() +# documentation goes here: +SET(DFHACK_USERDOC_DESTINATION .) +SET(DFHACK_DEVDOC_DESTINATION dev) +SET(DFHACK_DOXYGEN_DESTINATION dev/doxygen) -# macro to save on typing in the tool subdirs -# builds a tool, links it to the dfhack lib and makes sure the dependency -# LOCAL_DEPNAME is built first, in case there is one -MACRO(DFHACK_TOOL TOOL_NAME TOOL_SOURCES) - ADD_EXECUTABLE(${TOOL_NAME} ${TOOL_SOURCES}) - TARGET_LINK_LIBRARIES(${TOOL_NAME} dfhack) - if(DEFINED LOCAL_DEPNAME) - ADD_DEPENDENCIES(${TOOL_NAME} ${LOCAL_DEPNAME}) - endif() - install(TARGETS - ${TOOL_NAME} - RUNTIME DESTINATION ${DFHACK_BINARY_DESTINATION}) -ENDMACRO() - -# same as above builds a curses tool instead of plain terminal one. -MACRO(DFHACK_CURSES_TOOL TOOL_NAME TOOL_SOURCES) - IF(Curses_FOUND AND NOT BUILD_NO_CURSES) - ADD_EXECUTABLE(${TOOL_NAME} ${TOOL_SOURCES}) - TARGET_LINK_LIBRARIES(${TOOL_NAME} dfhack curses) - if(DEFINED LOCAL_DEPNAME) - ADD_DEPENDENCIES(${TOOL_NAME} ${LOCAL_DEPNAME}) - endif() - if(WIN32) - ADD_DEPENDENCIES(${TOOL_NAME} curses-copy) - ENDIF() - install(TARGETS - ${TOOL_NAME} - RUNTIME DESTINATION ${DFHACK_BINARY_DESTINATION}) - ELSE() - MESSAGE(STATUS "Wide-character ncurses library not found - " ${TOOL_NAME} "can't be built") - ENDIF() -ENDMACRO() - - -IF(BUILD_DFHACK_LIBRARY) +## some options for the user/developer to play with +OPTION(BUILD_LIBRARY "Build the library that goes into DF." ON) +OPTION(BUILD_PLUGINS "Build the plugins." ON) +IF(BUILD_LIBRARY) add_subdirectory (library) - - IF(BUILD_DFHACK_PYTHON_BINDINGS) - MESSAGE("TODO: write CMakeLists.txt for the python things.") - ENDIF() - IF(BUILD_DFHACK_SUPPORTED) - add_subdirectory (tools/supported) - ENDIF() - - IF(BUILD_DFHACK_EXAMPLES) - add_subdirectory (tools/examples) - ENDIF() - - IF(BUILD_DFHACK_PLAYGROUND) - add_subdirectory (tools/playground) - ENDIF() - ## install the default documentation files install(FILES LICENSE Readme.html DESTINATION ${DFHACK_USERDOC_DESTINATION}) endif() -IF(BUILD_DFHACK_DOXYGEN AND BUILD_DFHACK_DEVEL) - add_subdirectory (doc) -ENDIF() +IF(BUILD_PLUGINS) + add_subdirectory (plugins) +endif() -IF(${DFHACK_INSTALL} STREQUAL "portable") - IF(UNIX) - SET(CPACK_GENERATOR "TGZ") - ENDIF() - IF(WIN32) - SET(CPACK_GENERATOR "ZIP") - # this includes the MSVC C++ DLLs in the package. Doesn't work with Express versions in general. - INCLUDE(InstallRequiredSystemLibraries) - ENDIF() - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${DFHACK_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") - INCLUDE(CPack) +# Packaging with CPack! +IF(UNIX) + SET(CPACK_GENERATOR "TGZ") ENDIF() +IF(WIN32) + SET(CPACK_GENERATOR "ZIP") + # this includes the MSVC C++ DLLs in the package. Doesn't work with Express versions in general. + # we should be fine with the stuff DF already has packaged... so, commenting out + # INCLUDE(InstallRequiredSystemLibraries) +ENDIF() +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${DFHACK_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") +INCLUDE(CPack) -#------------------------------------------------------------------------------- -# Figure out debian architecture -#------------------------------------------------------------------------------- - -FUNCTION(GET_DEBIAN_ARCHITECTURE arch) - SET(dpkgarch) - - FIND_PROGRAM(DPKG_CMD dpkg) - IF(NOT DPKG_CMD) - MESSAGE(STATUS "Can not find dpkg in your path, default to i386.") - SET(${arch} i386 PARENT_SCOPE) - ENDIF() - EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture - OUTPUT_VARIABLE dpkgarch - OUTPUT_STRIP_TRAILING_WHITESPACE ) - SET(${arch} ${dpkgarch} PARENT_SCOPE) -ENDFUNCTION() - -IF(${DFHACK_INSTALL} STREQUAL "ubuntu-10.10" OR ${DFHACK_INSTALL} STREQUAL "debian") - SET(CPACK_GENERATOR "DEB") - - #wtf, wtf, wtf. force them to be empty - set(CMAKE_INSTALL_PREFIX "" FORCE) - set(CPACK_INSTALL_PREFIX "") - SET(CPACK_PACKAGING_INSTALL_PREFIX "") - set(CPACK_SET_DESTDIR true) - - SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") # yep. magma. - SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") # very. - SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) # find deps automatically! hopefully... maybe... - SET(INSTSCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/package/${DFHACK_INSTALL}") - SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${INSTSCRIPT}/postinst;${INSTSCRIPT}/preinst;${INSTSCRIPT}/postrm") - - GET_DEBIAN_ARCHITECTURE(PKG_ARCHITECTURE) - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${DFHACK_VERSION}-${DFHACK_REVISION}_${DFHACK_INSTALL}-${PKG_ARCHITECTURE}") - INCLUDE(CPack) -ENDIF() diff --git a/LICENSE b/LICENSE index d9943bf5a..68b70dcf3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,8 @@ ---------------------------------------------------------------------- License of dfhack -github.com/peterix/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,62 +23,6 @@ must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ----------------------------------------------------------------------- -License of library/include/dfhack/DFstdint_win.h - -ISO C9x compliant stdint.h for Microsoft Visual Studio -Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 - - Copyright (c) 2006-2008 Alexander Chemeris - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of the author may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------------- -License of argstream (used by some utilities for parsing command line params) - -Copyright (C) 2004 Xavier Decoret - -argsteam is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Foobar is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This library is used by: -tools/playground/catsplosion.cpp -tools/playground/digger.cpp -tools/supported/vdig.cpp - ---------------------------------------------------------------------------- License of "RSA Data Security, Inc. MD5 Message-Digest Algorithm" Used to identify DF binaries. @@ -171,3 +116,69 @@ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------ + * dirent.h - dirent API for Microsoft Visual Studio + * + * Copyright (C) 2006 Toni Ronkko + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------ +Parts of dfhack are based on linenoise: +linenoise.c -- guerrilla line editing library against the idea that a +line editing lib needs to be 20,000 lines of C code. + +You can find the latest source code at: + + http://github.com/antirez/linenoise + +Does a number of crazy assumptions that happen to be true in 99.9999% of +the 2010 UNIX computers around. + +------------------------------------------------------------------------ + +Copyright (c) 2010, Salvatore Sanfilippo +Copyright (c) 2010, Pieter Noordhuis + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Memory-40d.xml b/Memory-40d.xml deleted file mode 100644 index b6d5ce1f5..000000000 --- a/Memory-40d.xml +++ /dev/null @@ -1,2129 +0,0 @@ - - - - - - - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56 - 57 - 58 - 59 - 60 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 80 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 90 - 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - 99 - 100 - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 - 111 - 112 - 113 - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56 - 57 - 58 - 59 - 60 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 80 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 90 - 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - 99 - 100 - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 - 111 - 112 - 113 - 114 - 115 - 116 - 117 - 118 - 119 - 120 - 121 - 122 - 123 - 124 - 125 - 126 - 127 - 128 - 129 - 130 - 131 - 132 - 133 - 134 - 135 - 136 - 137 - 138 - 139 - 140 - 141 - 142 - 143 - 144 - 145 - 146 - 147 - 148 - 149 - 150 - 151 - 152 - 153 - 154 - 155 - 156 - 157 - 158 - 159 - 160 - 161 - 162 - 163 - 164 - 165 - 166 - 167 - 168 - 169 - 170 - 171 - 172 - 173 - 174 - 175 - 176 - 177 - 178 - 179 - 180 - 181 - 182 - 183 - 184 - 185 - 186 - 187 - 188 - 189 - 190 - 191 - 192 - 193 - 194 - 195 - 196 - 197 - 198 - 199 - 200 - 201 - 202 - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56 - 57 - 58 - 59 - 60 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 0 - 66 - 11 - 10 - 13 - 12 - 14 - 15 - 16 - 20 - 38 - 19 - 41 - 39 - 43 - 42 - 40 - 44 - 45 - 48 - 27 - 49 - 21 - 47 - 26 - 46 - 50 - 23 - 18 - 30 - 32 - 71 - 33 - 34 - 70 - 31 - 28 - 69 - 25 - 22 - 29 - 72 - 35 - 36 - 37 - 67 - 73 - 64 - 65 - 17 - 8 - 2 - 6 - 4 - 1 - 5 - 7 - 9 - 3 - 24 - 51 - 52 - 53 - 54 - 55 - 57 - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .,:rsr, - :2;,;r2A@@5 - @2::s5A#@@@ @r. . - sd;:riXA#@@ :@@@Gir;;AS9 - Bs::sS3A#@2 @@#AhXirsS#; - iHrLr5d#@@@ .@#95sr;;rie - i*' `*@3 @@A2sr;:;r#5 - :..:rll: @@A5sr::r3@ - @Hr;iZ#@@@@ `:rr;;;;: - S@r.;i2#@@@ @s. .. - @2::ri2A@@# B@G2ir:...5i - :@r,r3X##@@ @G5sr:..,:A - .@Ar;;rSB@@# H#2sr;,..,is - .' `* ,@ASs;:..,:B - ;rr;:,..,:. - `''' - W I N D O W S - and - W I N E - - - 0x47b6fac2 - 48c831b6f3950913b8e1aeada563d2db - 0x0 - 0x4 -
0x014639f4
-
0x01463288
-
0x01463388
-
0x00c7bc00
-
0x01287d14
-
0x00941288
-
0x01287a9c
-
0x01463358
-
0x014a6994
-
0x014a4eac
-
0x014a6834
-
0xffffffff
-
0x8b010127
-
0x014a4edc
-
0x014a4ee0
-
0x014a4ee4
-
0x014a6680
-
0x014a671c
-
0x014a69b4
-
0x01467b78
-
0x01295d58
-
0x01284184
-
0x00941288
-
0x00c2358c
-
0x00c68350
-
0x014a64dc
-
0x014a4ec4
-
0x014a4ec8
-
0x014a4ecc
- - 0x08 - - 0x08 - 0x2C - 0x0062 - 0x0264 - 0x0664 - 0x1D64 - - 0x0 - 0x1C - 0x38 - 0x1C - - 0x00 - 0x6c - 0x88 - 0x8C - 0x94 - 0xE4 - 0xE8 - 0xF2 - 0xF4 - 0x158 - 0x1F8 - 0x1FC - 0x228 - 0x2F8 - 0x2AC - 0x328 - 0x32C - 0x330 - 0x3CC - 0x438 - 0x43C - 0x440 - 0x444 - 0x454 - 0x474 - 0x520 - 0x5D0 - - 0x70 - - 0x84 - 0x86 - 0x684 - 0x6B4 - - 0x5C - 0x58 - - 0x4 - - 0x10 - - 0x84 - 0x60 - 0x08 - 0x2C - 0x0062 - 0x0264 - 0x0664 - 0x1D64 - 0x3C - 0x2 - 0x4 - 0x8 - 0x24 - 0x1C - 0x20 - 0x00 - 0x7a - 0xD8 - 0x68 - 0x24 - 0x1C - 0x28 - 0x24 - 0x24 - 0x24 - 0x5C - 0x94 - 0xB0 -
- - 0x47c12f36 - 8bd90fb6db8388f129fde224a35459de -
0x01463bec
-
0x01463480
-
0x01463580
-
0x00c7bc04
-
0x01287d14
-
0x0094128c
-
0x01287a9c
-
0x01463550
-
0x014a6c60
-
0x014a50a4
-
0x014a6b00
-
0xffffffff
-
0x8b010127
-
0x014a50d4
-
0x014a50d8
-
0x014a50dc
-
0x014a694c
-
0x014a69e8
-
0x014a6c80
-
0x01467d70
-
0x01295d58
-
0x01284184
-
0x00c3fb40
-
0x00c23594
-
0x00c68354
-
0x014a66d4
-
0x014a50bc
-
0x014a50c0
-
0x014a50c4
-
- - 0x47c29583 - 9147b5e922a30873fd1a742b1dea1724 -
0xffffffff
-
0x8b010127
-
- - 0x487b4e8b - 4b3857a05590b9d9488900e575079e9d -
0x01512b70
-
0x014feb80
-
0x01512504
-
0x00d16c20
-
0x01322d58
-
0x009d6284
-
0x01322adc
-
0x014fec50
-
0x01555f88
-
0x01554028
-
0x01555e28
-
0xffffffff
-
0x8b010131
-
0x01554058
-
0x0155405c
-
0x01554060
-
0x01555ce8
-
0x01555c6c
-
0x01555fa8
-
0x01516cf4
-
0x01330d98
-
0x0131f1b4
-
0x00cd5398
-
0x00cb8dec
-
0x00d03370
-
0x01555658
-
0x01554040
-
0x01554044
-
0x01554048
-
- - 0x487c9338 - 52155dea390c2080fc16e4bbeb077164 -
0xffffffff
-
0x8b010131
-
- - 0x487f2f30 - 8f8cf06b1cd5ea102881a7cced767d4f -
0x01513b90
-
0x014ffba0
-
0x01513524
-
0x00d17c44
-
0x01323d78
-
0x009d7284
-
0xffffffff
- -
0x014ffc70
-
0x01556fa8
-
0x01555048
-
0x01556e48
-
0xffffffff
- -
0x8b010131
-
0x01555078
-
0x0155507c
-
0x01555080
-
0x01556d08
-
0x01556c8c
-
0x01556fc8
-
0x01517d14
-
0x01331db8
-
0x013201d4
-
0x00cd63bc
-
0x00cb9dec
-
0x00d04394
-
0x01556678
-
0x01555060
-
0x01555064
-
0x01555068
-
- - 0x48873bc3 - 8614a01593baef6e4a341e2f1a92ba06 -
0x0151ffb8
-
0x0150bfc8
-
0x0151f94c
-
0x00d23c4c
-
0x0132fdb0
-
0x009e3284
-
0x0132fb34
-
0x0150c098
-
0x015635cc
-
0x01561470
-
0x0156346c
-
0x0132faac
-
0x8b010131
-
0x015614a0
-
0x015614a4
-
0x015614a8
-
0x01563154
-
0x015630d8
-
0x015635ec
-
0x0152413c
-
0x0133ddf0
-
0x0132c1dc
-
0x00ce23c4
-
0x00cc5df4
-
0x00d1039c
-
0x01562aa0
-
0x01561488
-
0x0156148c
-
0x01561490
-
- - 0x4888672c - 32f68422f5b4d938549eed0565bcfb92 - - - 0x489d8c7f - 33db0401081058fb54252210bf371344 -
0x01576468
-
0x01562478
-
0x01575dfc
-
0x00d7a0fc
-
0x01386260
-
0x009ef294
-
0x01385fe4
-
0x01562548
-
0x015b9a7c
-
0x015b7920
-
0x015b991c
-
0x01385f5c
-
0x5f010137
-
0x015b7950
-
0x015b7954
-
0x015b7958
-
0x015b9604
-
0x015b9588
-
0x015b9a9c
-
0x0157a5ec
-
0x013942a0
-
0x0138268c
-
0x00d387fc
-
0x00d66870
-
0x00d6684c
-
0x015b8f50
-
0x015b7938
-
0x015b793c
-
0x015b7940
-
- - 0x48a9727f - 441c76f45cfffc6abc6548e41c7e2218 -
0x015828a8
-
0x0156e8b8
-
0x0158223c
-
0x00d860fc
-
0x01392268
-
0x009fb294
-
0x01391fc0
-
0x0156e988
-
0x015c5ecc
-
0x015c3d60
-
0x015c5d6c
-
0x01391f64
-
0x5f010138
-
0x015c3d90
-
0x015c3d94
-
0x015c3d98
-
0x015c5a54
-
0x015c59c8
-
0x015c5eec
-
0x01586a2c
-
0x013a02a8
-
0x0138e694
-
0x00d447fc
-
0x00d72870
-
0x00d7284c
-
0x015c5390
-
0x015c3d78
-
0x015c3d7c
-
0x015c3d80
-
- - 0x48ad547a - 65b4fa339d4081e934c1297d2a22234a - - - 0x48ad802b - 15e95727019e76aa653538618c7e0cfd - - - 0x48c330df - 2c686c26307dcccd7c36cc79737ebe4f -
0x015838a0
-
0x0156f8b0
-
0x01583234
-
0x00D870F4
-
0x01393260
-
0x009fc294
-
0x1583234
-
0x01392fb8
-
0x0156f980
-
0x015c6ed0
-
0x015c4d58
-
0x015c6d70
-
0x01392f5c
-
0x0138147f
-
0x015c4d88
-
0x015c4d8c
-
0x015c4d90
-
0x015c6a58
-
0x015c69cc
-
0x015c6ef0
-
0x01587a24
-
0x013a12a0
-
0x0138f68c
-
0x00d457f4
-
0x00d73868
-
0x00d73844
-
0x015c6388
-
0x015c4d70
-
0x015c4d74
-
0x015c4d78
-
- - - 0x4953556c - b1a8ca1f91734eb492b7f54f6823cddb - -0x8 - 0x4 -
0x014d1db0
-
0x014bda18
-
0x014D141C
-
0x00cd4c3c
-
0x0165b5a8
-
0x0094b27c
-
0x165b410
-
0x012e101c
-
0x014d14f8
-
0x01517678
-
0x015152f8
-
0x01517468
-
0x012e0fe4
-
0x012cefbf
-
0x01515330
-
0x01515334
-
0x01515338
-
0x015170f8
-
0x0151702c
-
0x015176a8
-
0x014d7f84
-
0x012ef340
-
0x0165a34c
-
0x00c9333c
-
0x00cc13b0
-
0x00cc138c
-
0x01516930
-
0x01515318
-
0x0151531c
-
0x01515320
- 0x54 - - 0x0 - 0x1C - 0x38 - 0x1C - - - 0xFC - 0x100 - 0x10A - 0x10C - 0x198 - 0x238 - 0x23C - 0x268 - 0x2F8 - 0x314 - 0x3C0 - 0x3C4 - 0x3C8 - 0x484 - 0x4F0 - 0x4F4 - 0x4F8 - 0x504 - 0x51C - 0x544 - 0x610 - 0x700 - - 0x70 - - 0x10 - 0x2C - 0x0082 - 0x0284 - 0x0684 - 0x1D84 - 0x84 - 0x86 - 0x75C - 0x79C - - 0x64 - 0x60 - - 0xC - 0x2 - 0x4 - 0x8 - 0x24 - 0x1C - 0x20 - 0x2C - 0x0 - 0x7a - 0x100 - 0x68 - 0x24 - - 0x18 - 0x1C - 0x28 - 0x24 - 0x24 - 0x24 - 0x5C - 0x94 - 0xB0 - - - - - - - -
- - 0x4957716f - 9b6da355562a4cdd345ea3046290499b -
0x00cd6c3c
-
0x0094d27c
-
0x012d0fbf
-
0x00c9533c
-
0x00cc33b0
-
0x00cc338c
-
- - 0x4957a0a2 - b77759db7a6dd787bf98953fc5749d81 - - - 0x495991c3 - a0792b81e5b8ec1dbdd627643e93b40d -
0xcd8c34
-
0x0094f27c
-
0x012d2fbb
-
0x00c97334
-
0x00cc53a8
-
0x00cc5384
-
- - 0x495cafd2 - d09e88a32fe57de5973f78ef213271b6 -
0xcefc68
-
0x009662a4
-
0x012e9fef
-
0x00cae368
-
0x00cdc3dc
-
0x00cdc3b8
-
- - 0x495fcfef - 8e8e2a83d421e356a8047dc8830a7426 -
0xcefc68
-
0x009662a4
-
0x012e9fef
-
0x00cae368
-
0x00cdc3dc
-
0x00cdc3b8
-
- - 0x4963c928 - 32253bee114dd25ebbaa50d90b5c0a2a - - - 0x4967c2e0 - aea5a207b8b1cda942502f97a429f6c3 - - - 0x49c59b94 - 193193d8624f2f3f6d9d556fab09b122 -
0x0151bd00
-
0x01507968
-
0x0151b36c
-
0x00d20ed8
-
0x016a54f8
-
0x009652a4
-
0x16a5360
-
0x0132e574
-
0x0151b448
-
0x015615c8
-
0x0155f248
-
0x015613b8
-
0x0132e53c
-
0x0131b25f
-
0x0155f280
-
0x0155f284
-
0x0155f288
-
0x01561048
-
0x01560f7c
-
0x015615f8
-
0x01521ed4
-
0x0133c898
-
0x016a429c
-
0x00cdf5a0
-
0x00d0d64c
-
0x00d0d628
-
0x01560880
-
0x0155f268
-
0x0155f26c
-
0x0155f270
-
- - 0x49c82d3f - 6f81231b845e9c9dc29aaf57705ccc7c - - - 0x4a3ccb7f - 6ea1de36af8e1666bd6478736e298c4c -
0x015b7750
-
0x015a33b8
-
0x015b6dbc
-
0x00ddaed8
-
0x0095f410
-
0x0095f2b4
-
0x1740e60
-
0x013e8574
-
0x015b6e98
-
0x015fd04c
-
0x015faccc
-
0x015fce3c
-
0x013e853c
-
0x013d525f
-
0x015fad04
-
0x015fad08
-
0x015fad0c
-
0x015fcacc
-
0x015fca00
-
0x015fd07c
-
0x015bd924
-
0x015b6dc4
-
0x0173fde0
-
0x00d995a0
-
0x00dc764c
-
0x00dc7628
-
0x015fc304
-
0x015facec
-
0x015facf0
-
0x015facf4
-
- - 0x4a51c26e - 04a8d8ce311d8ac75e4241bef68d3147 -
0x00ddff38
-
0x00964430
-
0x009642b4
-
0x013da2bf
-
0x00d9e600
-
0x00dcc6ac
-
0x00dcc688
-
- - 0x4a8623d2 - 781a2e51be4056a7320108f8f0df8a13 -
0x00de1f44
-
0x00966430
-
0x009662b4
-
0x013dc2c7
-
0x00da060c
-
0x00dce6b8
-
0x00dce694
-
- - 0x4a9a6090 - 12cc4a3dbb6e6dfd7bc7aee458b9471a -
0x015be808
-
0x015aa470
-
0x015bde74
-
0x00de1f54
-
0x00966430
-
0x009662b4
-
0x1747f20
-
0x013ef62c
-
0x015bdf50
-
0x01604104
-
0x01601d84
-
0x01603ef4
-
0x013ef5f4
-
0x013dc2eb
-
0x01601dbc
-
0x01601dc0
-
0x01601dc4
-
0x01603b84
-
0x01603ab8
-
0x01604134
-
0x015c49dc
-
0x015bde7c
-
0x01746e98
-
0x00da061c
-
0x00dce6c8
-
0x00dce6a4
-
0x016033bc
-
0x01601da4
-
0x01601da8
-
0x01601dac
-
- - 0x4a9b1a72 - 59ab29021aca9f3c66b1ab102fb3ceea - - - 0x4b6b7879 - de66405f54d98297303d439b3b7aa30e -
0x015f3260
-
0x015deec8
-
0x015f28cc
-
0x00e16924
-
0x0099ae08
-
0x0099ac88
-
0x177c978
-
0x014240dc
-
0x015f29a8
-
0x01638b5c
-
0x016367dc
-
0x0163894c
-
0x014240a4
-
0x01410cc1
-
0x01636814
-
0x01636818
-
0x0163681c
-
0x016385dc
-
0x01638510
-
0x01638b8c
-
0x015f9434
-
0x014243c4
-
0x0177b8f0
-
0x00dd4fec
-
0x00e03098
-
0x00e03074
-
0x01637e14
-
0x016367fc
-
0x01636800
-
0x01636804
-
0x0177c978
-
- - - - 0x4b81b00d - 5cdc6f4804809f4d5cacdb66785e8cda - -
0x00df2ebc
-
0x00977438
-
0x009772b8
-
0x014ad278
-
0x00db1584
-
0x00ddf630
-
0x00ddf60c
-
- - 0x4b90268a - 13640a273d90af39425b798ae9823757 -
0x01512898
-
0x014fe500
-
0x01511f04
-
0x00d35b68
-
0x016ac1a0
-
0x0097a2b8
-
0x169bfb0
-
0x01343714
-
0x01511fe0
-
0x01558194
-
0x01555e14
-
0x01557f84
-
0x013436dc
-
0x0132ff1e
-
0x01555e4c
-
0x01555e50
-
0x01555e54
-
0x01557c14
-
0x01557b48
-
0x015581c4
-
0x01518a6c
-
0x013439fc
-
0x0169af28
-
0x00cf4230
-
0x00d222dc
-
0x00d222b8
-
0x0155744c
-
0x01555e34
-
0x01555e38
-
0x01555e3c
-
- - 0x4B918BB9 - af29004e1763bb3460faa11907c3ac90 - - .-"""-. - ' \ - |,. ,-. | - |()L( ()| | - |,' `".| | - |.___.',| ` - .j `--"' ` `. - / ' ' \ - / / ` `. - / / ` . - / / l | - . , L I N U X | | - ,"`. .| | - _.' ``. | `..-'l - | `.`, | `. - | `. __.j ) - |__ |--""___| ,-' - `"--...,+"""" `._,.-' - - - - 7a0859795e972574e80fa3cebc9fcf85 - 0x0 - 0x0 -
0x093154e0
-
0x093016b8
-
0x09355940
-
0x09314ffc
-
0x09301560
-
0x08859fc0
-
0x08cfa060
-
0x0930140c
-
0x09356fd0
-
0x09314ffc
-
0x09355964
-
0x09357808
-
0x093013e4
-
0x092f0580
-
0x0935596c
-
0x09355970
-
0x09355974
-
0x0935754c
-
0x093574e0
-
0x09357928
-
0x09318630
-
0x08b36c80
-
0x09355968
-
0x08b36c84
-
0x08cfa978
-
0x08cfa97c
-
0x09356f6c
-
0x09355954
-
0x09355958
-
0x0935595c
- 0x1C - - 0x0 - 0x4 - 0x8 - 0x4 - - 0x08 - - 0x00 - 0x4C - 0x44 - 0x90 - 0x94 - 0x003c - 0x0040 - 0x009E - 0x00A0 - 0x00F0 - 0x160 - 0x164 - 0x190 - 0x02F8 - 0x0200 - 0x264 - 0x268 - 0x26C - 0x02F8 - 0x0334 - 0x0338 - 0x033C - 0x0340 - 0x034C - 0x0364 - 0x0400 - 0x0490 - - 0x40 - - 0x08 - 0x2C - 0x0052 - 0x0254 - 0x0654 - 0x1D54 - - 0x54 - 0x56 - 0x5A4 - 0x5C8 - - 0x58 - 0x54 - - 0x4 - - 0xC - 0x24 - 0x18 - 0x2 - 0x4 - 0x8 - 0xC - 0x4 - 0x8 - 0x14 - 0x00 - 0x4a - 0x94 - 0x50 - 0x0C - - 0x20 - - 0xC - 0x4 - 0x10 - 0xC - 0xC - 0xC - 0x14 - 0x1C - 0x20 - - - - - - -
- - 51c73ff46b2688aafaee0204efe91a94 -
0x09315f00
-
0x093020d8
-
0x09356360
-
0x09315a1c
-
0x09301f80
-
0x0885a9e4
-
0x08cfaa80
-
0x09301e2c
-
0x093579f0
-
0x09315a1c
-
0x09356384
-
0x09358228
-
0x09301e04
-
0x092f0fa0
-
0x0935638c
-
0x09356390
-
0x09356394
-
0x09357f6c
-
0x09357f00
-
0x09358348
-
0x09319050
-
0x08b376a0
-
0x09356388
-
0x08b376a4
-
0x08cfb398
-
0x08cfb39c
-
0x0935798c
-
0x09356374
-
0x09356378
-
0x0935637c
-
- - c1eb408868c80fd1c726d2a917cd1b9a -
0x0885ad54
-
- - 59d497bfc3a523f0f40f34283ad59796 -
0x0885bbf0
-
- - f756194db073f05b98fc6ce872c8757d -
0x09333e00
-
0x0931ffd8
-
0x09374260
-
0x0933391c
-
0x0931fe80
-
0x088788e4
-
0x08d18980
-
0x0931fd2c
-
0x093758f0
-
0x0933391c
-
0x09374284
-
0x09376128
-
0x0931fd04
-
0x0930eea0
-
0x0937428c
-
0x09374290
-
0x09374294
-
0x09375e6c
-
0x09375e00
-
0x09376248
-
0x09336f50
-
0x08b555a0
-
0x09374288
-
0x08b555a4
-
0x08d19298
-
0x08d1929c
-
0x0937588c
-
0x09374274
-
0x09374278
-
0x0937427c
-
- - b004b3876193633875956af752663f26 - - - c8616fc74d79b3c8c40bbc1182fbd61c -
0x088786a0
-
- - 992afd73855e787860277f53d18afcbb -
0x08877630
-
- - cba6354000ec54865a161627605c3837 -
0x092bf340
-
0x092ab518
-
0x092bee5c
-
0x0929a3c8
-
0x092ab3c0
-
0x088073d4
-
0x08ca3eb8
-
0x092ab26c
-
0x092beecc
-
0x09301770
-
0x092ff7a0
-
0x09301668
-
0x092ab244
-
0x0929a3e0
-
0x092ff7cc
-
0x092ff7d0
-
0x092ff7d4
-
0x093013ac
-
0x09301340
-
0x09301788
-
0x092c2490
-
0x08ae40a0
-
0x09510050
-
0x08ca47d4
-
0x08ca47d8
-
0x08ca47dc
-
0x09300dcc
-
0x092ff7b4
-
0x092ff7b8
-
0x092ff7bc
-
- - fb8ecac8a12af5d0d7b1707078985d0d - - - 4367c59934cbcf14f43fd3af6444c455 -
0x08f55740
-
0x08f41918
-
0x08f5525c
-
0x08f307c8
-
0x08f417c0
-
0x0877b33c
-
0x0893a2ac
-
0x08f4166c
-
0x08f552cc
-
0x08f97b8c
-
0x08f95bbc
-
0x08f97a84
-
0x08f41644
-
0x08f307e0
-
0x08f95be8
-
0x08f95bec
-
0x08f95bf0
-
0x08f977c8
-
0x08f9775c
-
0x08f97ba4
-
0x08f58890
-
0x0877f8e0
-
0x091a647c
-
0x0893abd4
-
0x0893abd8
-
0x0893abdc
-
0x08f971e8
-
0x08f95bd0
-
0x08f95bd4
-
0x08f95bd8
-
- - 2f3cb9d720e9fe8844c02c72a2b20bbd -
0x08780344
-
0x0893f2d0
-
- - dab3ce6bc074529706a1e5fe1273108c -
0x08f5a760
-
0x08f46938
-
0x08f5a27c
-
0x08f357e8
-
0x08f467e0
-
0x08780354
-
0x0893f2d0
-
0x08f4668c
-
0x08f5a2ec
-
0x08f9cbac
-
0x08f9abdc
-
0x08f9caa4
-
0x08f46664
-
0x08f35800
-
0x08f9ac08
-
0x08f9ac0c
-
0x08f9ac10
-
0x08f9c7e8
-
0x08f9c77c
-
0x08f9cbc4
-
0x08f5d8b0
-
0x08784900
-
0x091ab49c
-
0x0893fbf4
-
0x0893fbf8
-
0x0893fbfc
-
0x08f9c208
-
0x08f9abf0
-
0x08f9abf4
-
0x08f9abf8
-
- - 4f55a1dcc326786271f221de23c425b5 - - - 022b933926e08da49c6df8649295f2b7 - - - 8f55a6250f2550e28535b79db43d5f1a -
0x08f628c0
-
0x08f4ea98
-
0x08f623dc
-
0x08f3d948
-
0x08f4e940
-
0x0878c340
-
0x08947438
-
0x08f4e7ec
-
0x08f6244c
-
0x08fa4d0c
-
0x08fa2d3c
-
0x08fa4c04
-
0x08f4e7c4
-
0x660008f3
-
0x08fa2d68
-
0x08fa2d6c
-
0x08fa2d70
-
0x08fa4948
-
0x08fa48dc
-
0x08fa4d24
-
0x08f65a10
-
0x0878caa0
-
0x091b35fc
-
0x08947d54
-
0x08947d58
-
0x08947d5c
-
0x08fa4368
-
0x08fa2d50
-
0x08fa2d54
-
0x08fa2d58
-
- - 777e7d674d8908042307994cb75250ff -
0x09009860
-
0x08ff5a38
-
0x0900937C
-
0x08fe48e8
-
0x08ff58e0
-
0x08833324
-
0x089ee3d8
-
0x08FF578C
-
0x090093ec
-
0x0904bcac
-
0x09049cdc
-
0x0904bba4
-
0x08ff5764
-
0x08fe4900
-
0x09049d08
-
0x09049d0c
-
0x09049d10
-
0x0904b8e8
-
0x0904b87c
-
0x0904bcc4
-
0x0900c9b0
-
0x08833a40
-
0x0925a59c
-
0x089eecf4
-
0x089eecf8
-
0x089eecfc
-
0x0904b308
-
0x09049cf0
-
0x09049cf4
-
0x09049cf8
-
- - 04c3ad13c657f59ba6fc135e156d721d -
0x09008880
-
0x08ff4a58
-
0x0900839C
-
0x08fe3908
-
0x08ff4900
-
0x08832328
-
0x089ed3f8
-
0x08ff47ac
-
0x0900840c
-
0x0904accc
-
0x09048cfc
-
0x0904abc4
-
0x08ff4784
-
0xc60008fe
-
0x09048d28
-
0x09048d2c
-
0x09048d30
-
0x0904a908
-
0x0904a89c
-
0x0904ace4
-
0x0900b9d0
-
0x08832a60
-
0x091995fc
-
0x089edd14
-
0x089edd18
-
0x089edd1c
-
0x0904a328
-
0x09048d10
-
0x09048d14
-
0x09048d18
-
- - - 851c1190b6a7b42f2463967623d18575 - 0x4BB45F99 - - - 0x18 - 0x0 - 0xC - 0x1C - - -
0xe32798
-
0xe60838
-
0xe60814
-
0xae82cc
- -
0x17f5ab8
- Found addresses: (next to each other!) - 0x17f5ab8 - 0x17f5ac0 - 0x17f5ac8 - 0x17f5ad0 - -
0x146e45f
- Found addresses: - 0x146e45f - 0x185b677 - - Bogus:
0xae82cc
- -
0x017f6f38
- - Bogus:
0xae82cc
- - - -
0x016ad738
-
0x016ad73C
-
0x016ad740
- -
0x016ad744
-
0x016ad748
-
0x016ad74C
- -
0x016ad750
-
0x016ad754
-
0x016ad758
- -
0x016AD718
- 0x10 - 0x0092 - 0x029C - - - 0x0 - 0x1C - 0x38 - - - 0x0 - 0x90 - 0xF8 - 0xFC - 0x110 - 0x114 - 0x6D0 - 0x770 - - - - -
-
-
diff --git a/Memory.xml b/Memory.xml index c61576bcf..b662e7676 100644 --- a/Memory.xml +++ b/Memory.xml @@ -803,8 +803,9 @@
+
-
+
@@ -927,6 +928,15 @@
+ + + + + + + + +
@@ -989,11 +999,16 @@ - -
- - - + + +
+ + + + + + to what??? + @@ -1022,6 +1037,7 @@
+
@@ -1057,6 +1073,9 @@ + +
+ @@ -1132,8 +1151,7 @@
-
-
+
@@ -1305,18 +1323,12 @@ - -
- - - - + +
@@ -2244,21 +2256,37 @@ + +
+
+
+ - -
- - - - - 0x194 TEST - - - + + + + + + + + + + + + +
+ + + + + 0x194 TEST + + + cmake item vector: @@ -3022,6 +3050,12 @@ WORLD: 0x93f77a0 + + +
+
+
+ Maybe, possibly.
@@ -3031,6 +3065,28 @@ + + + + + + + + + + + + + +
+ + + + + + + +
@@ -3038,6 +3094,7 @@
+
@@ -3088,6 +3145,9 @@
+ +
+ diff --git a/ReleaseText.txt b/ReleaseText.txt deleted file mode 100644 index 83b538a63..000000000 --- a/ReleaseText.txt +++ /dev/null @@ -1 +0,0 @@ -DFHack tools for DF 31.21 \ No newline at end of file diff --git a/build/build-MinGW32-debug.bat b/build/build-MinGW32-debug.bat deleted file mode 100644 index a20cb905c..000000000 --- a/build/build-MinGW32-debug.bat +++ /dev/null @@ -1,6 +0,0 @@ -mkdir MINGW32-debug -cd MINGW32-debug -cmake ..\.. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Debug -cmake-gui . -mingw32-make 2> ..\mingw-build-log.txt -pause \ No newline at end of file diff --git a/build/build-MinGW32-release.bat b/build/build-MinGW32-release.bat deleted file mode 100644 index af1dd060b..000000000 --- a/build/build-MinGW32-release.bat +++ /dev/null @@ -1,7 +0,0 @@ -mkdir MINGW32-release -cd MINGW32-release -cmake ..\.. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Release - -cmake-gui . -mingw32-make 2> ..\mingw-build-log.txt -pause \ No newline at end of file diff --git a/build/generate-MSVC-2005.bat b/build/generate-MSVC-2005.bat deleted file mode 100644 index 40aca9e01..000000000 --- a/build/generate-MSVC-2005.bat +++ /dev/null @@ -1,5 +0,0 @@ -mkdir VC2005 -cd VC2005 -echo Pre-generating a build folder -cmake ..\.. -G"Visual Studio 8 2005" -cmake-gui . \ No newline at end of file diff --git a/build/generate-MSVC-2008.bat b/build/generate-MSVC-2008.bat deleted file mode 100644 index f8b0fd040..000000000 --- a/build/generate-MSVC-2008.bat +++ /dev/null @@ -1,5 +0,0 @@ -mkdir VC2008 -cd VC2008 -echo Pre-generating a build folder -cmake ..\.. -G"Visual Studio 9 2008" -cmake-gui . \ No newline at end of file diff --git a/build/linux-remote.expect b/build/linux-remote.expect deleted file mode 100644 index 18fcdc8b9..000000000 --- a/build/linux-remote.expect +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/expect -# procedure to attempt connecting; result 0 if OK, 1 otherwise -proc connect {} { - expect "login:" - send "kitteh\r" - expect "password:" - send "a\r" -expect { - kitteh {return 0} - failed return 1 - "invalid password" return 1 - timeout return 1 - connected -} - # timed out - return 1 -} - -# procedure to do build stuff; result 0 if OK, 1 otherwise -proc dobuild {} { - set timeout -1 - send "pkg-win32.bat\r\n" - puts "\nBuilding...\n" -expect { - "BUILD OK" {return 0} - "MSVC ERROR" {return 1} - "CMAKE ERROR" {return 1} - "ENV ERROR" {return 1} -} -} - -spawn telnet win7 - -set rez [connect] -if { $rez == 1 } { -puts "\nError connecting to server!\n" -exit 1 -} - -send "net use X: \\\\vboxsvr\\projects\r\n" -expect "The command completed successfully." -send "X:\r\n" -expect "X:" -send "cd X:\\dfhack\\build\r\n" -expect "build" - -set buildrez [dobuild] -if { $buildrez == 1 } { - puts "\nThere was an error during build.\n" -} else { - puts "\nAll OK.\n" -} -send "exit\r" -expect eof -exit $buildrez diff --git a/build/pkg-debian.sh b/build/pkg-debian.sh deleted file mode 100644 index 6d3bce5da..000000000 --- a/build/pkg-debian.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -rm -r debian -mkdir debian -cd debian -cmake ../.. -DCMAKE_BUILD_TYPE="Release" -DDFHACK_INSTALL="debian" -DMEMXML_DATA_PATH="/usr/share/dfhack" -DBUILD_DFHACK_C_BINDINGS=ON -DBUILD_DFHACK_DEVEL=ON -DBUILD_DFHACK_DOXYGEN=OFF -DBUILD_DFHACK_EXAMPLES=OFF -DBUILD_DFHACK_PLAYGROUND=OFF -DBUILD_DFHACK_PYTHON_BINDINGS=ON -make package -mv *.deb ../ \ No newline at end of file diff --git a/build/pkg-ubuntu-10.10-x64.sh b/build/pkg-ubuntu-10.10-x64.sh deleted file mode 100644 index 5f4e17b3f..000000000 --- a/build/pkg-ubuntu-10.10-x64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -rm -r ubuntu64 -mkdir ubuntu64 -cd ubuntu64 -cmake ../.. -DCMAKE_BUILD_TYPE="Release" -DDFHACK_INSTALL="ubuntu-10.10" -DMEMXML_DATA_PATH="/usr/share/dfhack" -DDFHACK_PACKAGE_DIR=".." -DBUILD_DFHACK_C_BINDINGS=ON -DBUILD_DFHACK_DEVEL=ON -DBUILD_DFHACK_DOXYGEN=OFF -DBUILD_DFHACK_EXAMPLES=OFF -DBUILD_DFHACK_PLAYGROUND=OFF -DBUILD_DFHACK_PYTHON_BINDINGS=ON -make package -mv *.deb ../ \ No newline at end of file diff --git a/build/pkg-ubuntu-10.10.sh b/build/pkg-ubuntu-10.10.sh deleted file mode 100644 index 01baab90e..000000000 --- a/build/pkg-ubuntu-10.10.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -rm -r ubuntu -mkdir ubuntu -cd ubuntu -cmake ../.. -DCMAKE_BUILD_TYPE="Release" -DDFHACK_INSTALL="ubuntu-10.10" -DMEMXML_DATA_PATH="/usr/share/dfhack" -DDFHACK_PACKAGE_DIR=".." -DBUILD_DFHACK_C_BINDINGS=ON -DBUILD_DFHACK_DEVEL=ON -DBUILD_DFHACK_DOXYGEN=OFF -DBUILD_DFHACK_EXAMPLES=OFF -DBUILD_DFHACK_PLAYGROUND=OFF -DBUILD_DFHACK_PYTHON_BINDINGS=ON -make package -mv *.deb ../ diff --git a/build/pkg-win32.bat b/build/pkg-win32.bat deleted file mode 100644 index ff71e9744..000000000 --- a/build/pkg-win32.bat +++ /dev/null @@ -1,37 +0,0 @@ -@ECHO OFF -rd /S /Q MSVC10 -mkdir MSVC10 -cd MSVC10 -echo CLEANUP DONE - -cmake ..\.. -G"Visual Studio 10" -DDFHACK_INSTALL="portable" -DMEMXML_DATA_PATH="." -DBUILD_DFHACK_C_BINDINGS=OFF -DBUILD_DFHACK_DEVEL=OFF -DBUILD_DFHACK_DOXYGEN=OFF -DBUILD_DFHACK_EXAMPLES=OFF -DBUILD_DFHACK_PLAYGROUND=OFF -DBUILD_DFHACK_PYTHON_BINDINGS=OFF > ..\pkg-win32-cmake.log -if errorlevel 1 goto cmakeerror -echo CMAKE OK - -call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" > ..\pkg-win32-env.log -if errorlevel 1 goto enverror -echo ENV OK - -msbuild PACKAGE.vcxproj /p:Configuration=Release /l:FileLogger,Microsoft.Build.Engine;logfile=..\pkg-win32-msbuild.log;encoding=utf-8 -noconsolelogger > NUL -if errorlevel 1 goto msvcerror -move /Y *.zip .. -echo BUILD OK -set errorlevel=0 -goto end - -:cmakeerror -echo CMAKE ERROR -set errorlevel=1 -goto end - -:enverror -echo ENV ERROR -set errorlevel=1 -goto end - -:msvcerror -echo MSVC ERROR -set errorlevel=1 -goto end - -:end \ No newline at end of file diff --git a/build/pkg-win32.sh b/build/pkg-win32.sh deleted file mode 100755 index 6e81264f2..000000000 --- a/build/pkg-win32.sh +++ /dev/null @@ -1,14 +0,0 @@ -#/bin/sh -# Remote into a virtualbox VM to build with MSVC. -# Very specific to my own local setup. ~px - -# VARS. TODO: parametrize -export DFHACK_VER=0.5.7 -export PKG=dfhack-bin-$DFHACK_VER -export TARGET=Release - -# let's build it all -VBoxManage startvm "7 Prof" -sleep 20 -expect linux-remote.expect $TARGET - diff --git a/dfhack-python/CMakeLists.txt b/dfhack-python/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/dfhack-python/__init__.py b/dfhack-python/__init__.py deleted file mode 100644 index f6d2a2d31..000000000 --- a/dfhack-python/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -import context - -__all__ = [ "buildings", - "constructions", - "context", - "creatures", - "dftypes", - "flags", - "gui", - "items", - "maps", - "materials", - "vegetation" ] \ No newline at end of file diff --git a/dfhack-python/buildings.py b/dfhack-python/buildings.py deleted file mode 100644 index d58b92840..000000000 --- a/dfhack-python/buildings.py +++ /dev/null @@ -1,34 +0,0 @@ -from ctypes import * -from dftypes import * -import util - -libdfhack.Buildings_GetCustomWorkshopType.argtypes = [ c_void_p, POINTER(CustomWorkshop) ] - -class Buildings(object): - def __init__(self, ptr): - self._b_ptr = ptr - - def start(self): - num = c_uint() - - if libdfhack.Buildings_Start(self._b_ptr, byref(num)) > 0: - return int(num.value) - else: - return -1 - - def finish(self): - return libdfhack.Buildings_Finish(self._b_ptr) > 0 - - def read(self, index): - b = Building() - - if libdfhack.Buildings_Read(self._b_ptr, c_uint(index), byref(b)) > 0: - return b - else: - return None - - def read_custom_workshop_types(self): - return libdfhack.Buildings_ReadCustomWorkshopTypes(self._b_ptr) - - def get_custom_workshop_type(self, custom_workshop): - return libdfhack.Buildings_GetCustomWorkshopType(self._b_ptr, byref(custom_workshop)) diff --git a/dfhack-python/constructions.py b/dfhack-python/constructions.py deleted file mode 100644 index f822a54fa..000000000 --- a/dfhack-python/constructions.py +++ /dev/null @@ -1,25 +0,0 @@ -from ctypes import c_uint, byref -from dftypes import libdfhack, Construction - -class Constructions(object): - def __init__(self, ptr): - self._c_ptr = ptr - - def start(self): - num = c_uint() - - if libdfhack.Constructions_Start(self._c_ptr, byref(num)) > 0: - return int(num.value) - else: - return -1 - - def finish(self): - return libdfhack.Constructions_Finish(self._c_ptr) > 0 - - def read(self, index): - c = Construction() - - if libdfhack.Constructions_Read(self._c_ptr, c_uint(index), byref(c)) > 0: - return c - else: - return None diff --git a/dfhack-python/context.py b/dfhack-python/context.py deleted file mode 100644 index b2459af46..000000000 --- a/dfhack-python/context.py +++ /dev/null @@ -1,191 +0,0 @@ -from ctypes import * -from dftypes import * - -libdfhack.ContextManager_Alloc.restype = c_void_p -libdfhack.ContextManager_Free.argtypes = [ c_void_p ] - -libdfhack.ContextManager_getContext.restype = c_void_p -libdfhack.ContextManager_getSingleContext.restype = c_void_p - -libdfhack.Context_Free.argtypes = [ c_void_p ] - -libdfhack.Context_getMemoryInfo.restype = c_void_p -libdfhack.Context_getProcess.restype = c_void_p - -libdfhack.Context_getCreatures.restype = c_void_p -libdfhack.Context_getMaps.restype = c_void_p -libdfhack.Context_getGui.restype = c_void_p -libdfhack.Context_getMaterials.restype = c_void_p -libdfhack.Context_getTranslation.restype = c_void_p -libdfhack.Context_getVegetation.restype = c_void_p -libdfhack.Context_getBuildings.restype = c_void_p -libdfhack.Context_getConstructions.restype = c_void_p -libdfhack.Context_getItems.restype = c_void_p -libdfhack.Context_getWorld.restype = c_void_p -libdfhack.Context_getWindowIO.restype = c_void_p - -class ContextManager(object): - def __init__(self, memory_path): - self._cm_ptr = libdfhack.ContextManager_Alloc(create_string_buffer(memory_path)) - - def __del__(self): - libdfhack.ContextManager_Free(self._cm_ptr) - - def refresh(self): - return libdfhack.ContextManager_Refresh(self._cm_ptr) > 0 - - def purge(self): - libdfhack.ContextManager_purge(self._cm_ptr) - - def get_context(self, index): - p = libdfhack.ContextManager_getContext(self._cm_ptr, index) - - if p: - return Context(p) - else: - return None - - def get_single_context(self): - p = libdfhack.ContextManager_getSingleContext(self._cm_ptr) - - if p: - return Context(p) - else: - return None - -class Context(object): - def __init__(self, ptr): - self._c_ptr = ptr - - self._mat_obj = None - self._map_obj = None - self._veg_obj = None - self._build_obj = None - self._con_obj = None - self._gui_obj = None - self._tran_obj = None - self._item_obj = None - self._creature_obj = None - self._world_obj = None - self._window_io_obj = None - - def __del__(self): - libdfhack.Context_Free(self._c_ptr) - - def attach(self): - return libdfhack.Context_Attach(self._c_ptr) > 0 - - def detach(self): - self._mat_obj = None - self._map_obj = None - self._veg_obj = None - self._build_obj = None - self._con_obj = None - self._gui_obj = None - self._tran_obj = None - self._item_obj = None - self._creature_obj = None - self._world_obj = None - self._window_io_obj = None - - return libdfhack.Context_Detach(self._c_ptr) > 0 - - def suspend(self): - return libdfhack.Context_Suspend(self._c_ptr) > 0 - - def resume(self): - return libdfhack.Context_Resume(self._c_ptr) > 0 - - def force_resume(self): - return libdfhack.Context_ForceResume(self._c_ptr) > 0 - - def async_suspend(self): - return libdfhack.Context_AsyncSuspend(self._c_ptr) > 0 - - @property - def is_attached(self): - return libdfhack.Context_isAttached(self._c_ptr) > 0 - - @property - def is_suspended(self): - return libdfhack.Context_isSuspended(self._c_ptr) > 0 - - @property - def materials(self): - import materials - if self._mat_obj is None: - self._mat_obj = materials.Materials(libdfhack.Context_getMaterials(self._c_ptr)) - - return self._mat_obj - - @property - def maps(self): - import maps - if self._map_obj is None: - self._map_obj = maps.Maps(libdfhack.Context_getMaps(self._c_ptr)) - - return self._map_obj - - @property - def vegetation(self): - import vegetation - if self._veg_obj is None: - self._veg_obj = vegetation.Vegetation(libdfhack.Context_getVegetation(self._c_ptr)) - - return self._veg_obj - - @property - def buildings(self): - import buildings - if self._build_obj is None: - self._build_obj = buildings.Buildings(libdfhack.Context_getBuildings(self._c_ptr)) - - return self._build_obj - - @property - def creatures(self): - import creatures - if self._creature_obj is None: - self._creature_obj = creatures.Creatures(libdfhack.Context_getCreatures(self._c_ptr)) - - return self._creature_obj - - @property - def gui(self): - import gui - if self._gui_obj is None: - self._gui_obj = gui.Gui(libdfhack.Context_getGui(self._c_ptr)) - - return self._gui_obj - - @property - def items(self): - import items - if self._item_obj is None: - self._item_obj = items.Items(libdfhack.Context_getItems(self._c_ptr)) - - return self._item_obj - - @property - def translation(self): - import translation - if self._tran_obj is None: - self._tran_obj = translation.Translation(libdfhack.Context_getTranslation(self._c_ptr)) - - return self._tran_obj - - @property - def world(self): - import world - if self._world_obj is None: - self._world_obj = world.World(libdfhack.Context_getWorld(self._c_ptr)) - - return self._world_obj - - @property - def window_io(self): - import window_io - if self._window_io_obj is None: - self._window_io_obj = window_io.WindowIO(libdfhack.Context_getWindowIO(self._c_ptr)) - - return self._window_io_obj \ No newline at end of file diff --git a/dfhack-python/creatures.py b/dfhack-python/creatures.py deleted file mode 100644 index b4a51a4b5..000000000 --- a/dfhack-python/creatures.py +++ /dev/null @@ -1,73 +0,0 @@ -from ctypes import * -from dftypes import libdfhack, Creature, Material -import util - -libdfhack.Creatures_WriteLabors.argtypes = [ c_void_p, c_uint, POINTER(c_ubyte) ] - -libdfhack.Creatures_ReadJob.restype = POINTER(Material) -libdfhack.Creatures_ReadInventoryIdx.restype = POINTER(c_uint) -libdfhack.Creatures_ReadInventoryPtr.restype = POINTER(c_uint) - -class Creatures(object): - def __init__(self, ptr): - print ptr - self._c_ptr = ptr - - self._d_race_index = None - self._d_civ_id = None - - def start(self): - n = c_uint(0) - - if libdfhack.Creatures_Start(self._c_ptr, byref(n)) > 0: - return int(n.value) - else: - return -1 - - def finish(self): - return libdfhack.Creatures_Finish(self._c_ptr) > 0 - - def read_creature(self, index): - c = Creature() - - if libdfhack.Creatures_ReadCreature(self._c_ptr, c_int(index), byref(c)) > 0: - return c - else: - return None - - def read_creature_in_box(self, index, pos1, pos2): - c = Creature() - - x1, y1, z1 = c_uint(pos1[0]), c_uint(pos1[1]), c_uint(pos1[2]) - x2, y2, z2 = c_uint(pos2[0]), c_uint(pos2[1]), c_uint(pos2[2]) - - retval = libdfhack.Creatures_ReadCreatureInBox(self._c_ptr, byref(c), x1, y1, z1, x2, y2, z2) - - return (retval, c) - - def write_labors(self, index, labors): - return libdfhack.Creatures_WriteLabors(self._c_ptr, c_uint(index), labors) > 0 - - def read_job(self, creature): - job_ptr = libdfhack.Creatures_ReadJob(self._c_ptr, byref(creature)) - jobs = None - - if id(job_ptr) in dftypes.pointer_dict: - jobs = dftypes.pointer_dict[id(job_ptr)][1] - del dftypes.pointer_dict[id(job_ptr)] - - return jobs - - @property - def dwarf_race_index(self): - if self._d_race_index is None: - self._d_race_index =libdfhack.Creatures_GetDwarfRaceIndex(self._c_ptr) - - return self._d_race_index - - @property - def dwarf_civ_id(self): - if self._d_civ_id is None: - self._d_civ_id = libdfhack.Creatures_GetDwarfCivId(self._c_ptr) - - return self._d_civ_id diff --git a/dfhack-python/dfhack_api_ctypes.py b/dfhack-python/dfhack_api_ctypes.py deleted file mode 100644 index 185746e3b..000000000 --- a/dfhack-python/dfhack_api_ctypes.py +++ /dev/null @@ -1,152 +0,0 @@ -from ctypes import * -from pydftypes import * - - -libdfhack.API_Alloc.restype = c_void_p -libdfhack.API_Free.argtypes = [ c_void_p ] - -libdfhack.API_getMemoryInfo.restype = c_void_p -libdfhack.API_getProcess.restype = c_void_p -libdfhack.API_getWindow.restype = c_void_p - -libdfhack.API_getCreatures.restype = c_void_p -libdfhack.API_getMaps.restype = c_void_p -libdfhack.API_getGui.restype = c_void_p -libdfhack.API_getMaterials.restype = c_void_p -libdfhack.API_getTranslation.restype = c_void_p -libdfhack.API_getVegetation.restype = c_void_p -libdfhack.API_getBuildings.restype = c_void_p -libdfhack.API_getConstructions.restype = c_void_p -libdfhack.API_getItems.restype = c_void_p - -class API(object): - def __init__(self, memory_path): - self._api_ptr = libdfhack.API_Alloc(create_string_buffer(memory_path)) - - self._mat_obj = None - self._map_obj = None - self._veg_obj = None - self._build_obj = None - self._con_obj = None - self._gui_obj = None - self._tran_obj = None - self._item_obj = None - self._creature_obj = None - - def __del__(self): - libdfhack.API_Free(self._api_ptr) - - def attach(self): - return libdfhack.API_Attach(self._api_ptr) > 0 - - def detach(self): - return libdfhack.API_Detach(self._api_ptr) > 0 - - def suspend(self): - return libdfhack.API_Suspend(self._api_ptr) > 0 - - def resume(self): - return libdfhack.API_Resume(self._api_ptr) > 0 - - def force_resume(self): - return libdfhack.API_ForceResume(self._api_ptr) > 0 - - def async_suspend(self): - return libdfhack.API_AsyncSuspend(self._api_ptr) > 0 - - @property - def is_attached(self): - return libdfhack.API_isAttached(self._api_ptr) > 0 - - @property - def is_suspended(self): - return libdfhack.API_isSuspended(self._api_ptr) > 0 - - @property - def materials(self): - import materials - if self._mat_obj is None: - self._mat_obj = materials.Materials(libdfhack.API_getMaterials(self._api_ptr)) - - return self._mat_obj - - @property - def maps(self): - import maps - if self._map_obj is None: - self._map_obj = maps.Maps(libdfhack.API_getMaps(self._api_ptr)) - - return self._map_obj - - @property - def vegetation(self): - import vegetation - if self._veg_obj is None: - self._veg_obj = vegetation.Vegetation(libdfhack.API_getVegetation(self._api_ptr)) - - return self._veg_obj - - @property - def buildings(self): - import buildings - if self._build_obj is None: - self._build_obj = buildings.Buildings(libdfhack.API_getBuildings(self._api_ptr)) - - return self._build_obj - - @property - def creatures(self): - import creatures - if self._creature_obj is None: - self._creature_obj = creatures.Creatures(libdfhack.API_getCreatures(self._api_ptr)) - - return self._creature_obj - - @property - def gui(self): - import gui - if self._gui_obj is None: - self._gui_obj = gui.Gui(libdfhack.API_getGui(self._api_ptr)) - - return self._gui_obj - - @property - def items(self): - import items - if self._item_obj is None: - self._item_obj = items.Items(libdfhack.API_getItems(self._api_ptr)) - - return self._item_obj - - @property - def translation(self): - import translation - if self._tran_obj is None: - self._tran_obj = translation.Translation(libdfhack.API_getTranslation(self._api_ptr)) - - return self._tran_obj - -def reveal(): - df = API("Memory.xml") - df.attach() - - m = df.maps - - m.start() - - m_x, m_y, m_z = m.size - - for x in xrange(m_x): - for y in xrange(m_y): - for z in xrange(m_z): - if m.is_valid_block(x, y, z): - d = m.read_designations(x, y, z) - - for i in d: - for j in i: - j.bits.hidden = 0 - - m.write_designations(x, y, z, d) - - m.finish() - df.detach() diff --git a/dfhack-python/dftypes.py b/dfhack-python/dftypes.py deleted file mode 100644 index 729f7cdff..000000000 --- a/dfhack-python/dftypes.py +++ /dev/null @@ -1,637 +0,0 @@ -from ctypes import * -from flags import * -from enum import * -import util -from util import * - -libdfhack = cdll.libdfhack - -def _register_callback(name, func): - ptr = c_void_p.in_dll(libdfhack, name) - ptr.value = cast(func, c_void_p).value - -_register_callback("alloc_byte_buffer_callback", alloc_byte_buffer) -_register_callback("alloc_ubyte_buffer_callback", alloc_ubyte_buffer) -_register_callback("alloc_short_buffer_callback", alloc_short_buffer) -_register_callback("alloc_ushort_buffer_callback", alloc_ushort_buffer) -_register_callback("alloc_int_buffer_callback", alloc_int_buffer) -_register_callback("alloc_uint_buffer_callback", alloc_uint_buffer) -_register_callback("alloc_char_buffer_callback", alloc_char_buffer) - -_arr_create_func = CFUNCTYPE(c_void_p, c_int) -_dfhack_string = (c_char * 128) - -TileTypes40d = ((c_int * 16) * 16) -BiomeIndices40d = c_ubyte * 16 -Temperatures = ((c_ushort * 16) * 16) -Designations40d = ((DesignationFlags * 16) * 16) -Occupancies40d = ((OccupancyFlags * 16) * 16) - -def wall_terrain_check(terrain): - return libdfhack.DFHack_isWallTerrain(terrain) > 0 - -def floor_terrain_check(terrain): - return libdfhack.DFHack_isFloorTerrain(terrain) > 0 - -def ramp_terrain_check(terrain): - return libdfhack.DFHack_isRampTerrain(terrain) > 0 - -def stair_terrain_check(terrain): - return libdfhack.DFHack_isStairTerrain(terrain) > 0 - -def open_terrain_check(terrain): - return libdfhack.DFHack_isOpenTerrain(terrain) > 0 - -def get_vegetation_type(terrain): - return libdfhack.DFHack_getVegetationType(terrain) - -class Position2D(Structure): - _fields_ = [("x", c_ushort), - ("y", c_ushort)] - -class Position3D(Structure): - _fields_ = [("x", c_ushort), - ("y", c_ushort), - ("z", c_uint)] - -class PlaneCoord(Union): - _fields_ = [("xyz", Position3D), - ("dim", Position2D), - ("comparate", c_ulong)] - - def __cmp__(self, other): - if isinstance(other, PlaneCoord): - return self.comparate - other.comparate - else: - raise TypeError("argument must be of type %s" % type(self)) - -class Feature(Structure): - _fields_ = [("type", FeatureType), - ("main_material", c_short), - ("sub_material", c_short), - ("discovered", c_byte), - ("origin", c_uint)] - -class FeatureMapNode(Structure): - _fields_ = [("coordinate", PlaneCoord), - ("features", POINTER(Feature)), - ("feature_length", c_uint)] - -def _alloc_featuremap_buffer_callback(ptr, fmap_list, count): - arr_list = [] - arr = (FeatureMapNode * count)() - - for i, v in enumerate(arr): - f_count = int(fmap_list[i]) - f_arr = (Feature * f_count)() - - f_p = cast(f_arr, POINTER(Feature)) - v.features = f_p - - arr_list.extend((f_arr, f_p)) - - p = cast(arr, POINTER(FeatureMapNode)) - ptr[0] = p - - pointer_dict[addressof(arr)] = (ptr, arr, p, arr_list) - - return 1 - -_alloc_featuremap_buffer_functype = CFUNCTYPE(c_int, POINTER(POINTER(FeatureMapNode)), uint_ptr, c_uint) -_alloc_featuremap_buffer_func = _alloc_featuremap_buffer_functype(_alloc_featuremap_buffer_callback) -_register_callback("alloc_featuremap_buffer_callback", _alloc_featuremap_buffer_func) - -class Vein(Structure): - _fields_ = [("vtable", c_uint), - ("type", c_int), - ("assignment", c_short * 16), - ("flags", c_uint), - ("address_of", c_uint)] - -_vein_ptr = POINTER(Vein) - -def _alloc_vein_buffer_callback(ptr, count): - return util._allocate_array(ptr, Vein, count) - -_vein_functype = CFUNCTYPE(c_int, POINTER(_vein_ptr), c_uint) -_vein_func = _vein_functype(_alloc_vein_buffer_callback) -_register_callback("alloc_vein_buffer_callback", _vein_func) - -class FrozenLiquidVein(Structure): - _fields_ = [("vtable", c_uint), - ("tiles", TileTypes40d), - ("address_of", c_uint)] - -_frozenvein_ptr = POINTER(FrozenLiquidVein) - -def _alloc_frozenliquidvein_buffer_callback(ptr, count): - return util._allocate_array(ptr, FrozenLiquidVein, count) - -_frozenliquidvein_functype = CFUNCTYPE(c_int, POINTER(_frozenvein_ptr), c_uint) -_frozenliquidvein_func = _frozenliquidvein_functype(_alloc_frozenliquidvein_buffer_callback) -_register_callback("alloc_frozenliquidvein_buffer_callback", _frozenliquidvein_func) - -class SpatterVein(Structure): - _fields_ = [("vtable", c_uint), - ("mat1", c_ushort), - ("unk1", c_ushort), - ("mat2", c_uint), - ("mat3", c_ushort), - ("intensity", ((c_ubyte * 16) * 16)), - ("address_of", c_uint)] - -_spattervein_ptr = POINTER(SpatterVein) - -def _alloc_spattervein_buffer_callback(ptr, count): - return util._allocate_array(ptr, SpatterVein, count) - -_spattervein_functype = CFUNCTYPE(c_int, POINTER(_spattervein_ptr), c_uint) -_spattervein_func = _spattervein_functype(_alloc_spattervein_buffer_callback) -_register_callback("alloc_spattervein_buffer_callback", _spattervein_func) - -class GrassVein(Structure): - _fields_ = [("vtable", c_uint), - ("material", c_uint), - ("intensity", ((c_ubyte * 16) * 16)), - ("address_of", c_uint)] - -_grassvein_ptr = POINTER(GrassVein) - -def _alloc_grassvein_buffer_callback(ptr, count): - return util._allocate_array(ptr, GrassVein, count) - -_grassvein_functype = CFUNCTYPE(c_int, POINTER(_grassvein_ptr), c_uint) -_grassvein_func = _grassvein_functype(_alloc_grassvein_buffer_callback) -_register_callback("alloc_grassvein_buffer_callback", _grassvein_func) - -class WorldConstruction(Structure): - _fields_ = [("vtable", c_uint), - ("material", c_uint), - ("assignment", c_ushort * 16), - ("address_of", c_uint)] - -_worldconstruction_ptr = POINTER(WorldConstruction) - -def _alloc_worldconstruction_buffer_callback(ptr, count): - return util._allocate_array(ptr, WorldConstruction, count) - -_worldconstruction_functype = CFUNCTYPE(c_int, POINTER(_worldconstruction_ptr), c_uint) -_worldconstruction_func = _worldconstruction_functype(_alloc_worldconstruction_buffer_callback) -_register_callback("alloc_worldconstruction_buffer_callback", _worldconstruction_func) - -class MapBlock40d(Structure): - _fields_ = [("tiletypes", TileTypes40d), - ("designation", Designations40d), - ("occupancy", Occupancies40d), - ("biome_indices", BiomeIndices40d), - ("origin", c_uint), - ("blockflags", BlockFlags), - ("global_feature", c_short), - ("local_feature", c_short)] - - -class ViewScreen(Structure): - _fields_ = [("type", c_int)] - -class Matgloss(Structure): - _fields_ = [("id", _dfhack_string), - ("fore", c_byte), - ("back", c_byte), - ("bright", c_byte), - ("name", _dfhack_string)] - -_matgloss_ptr = POINTER(Matgloss) - -def _alloc_matgloss_buffer_callback(ptr, count): - return util._allocate_array(ptr, Matgloss, count) - -_matgloss_functype = CFUNCTYPE(c_int, POINTER(_matgloss_ptr), c_uint) -_matgloss_func = _matgloss_functype(_alloc_matgloss_buffer_callback) -_register_callback("alloc_matgloss_buffer_callback", _matgloss_func) - -class MatglossPair(Structure): - _fields_ = [("type", c_short), - ("index", c_int)] - -class DescriptorColor(Structure): - _fields_ = [("id", _dfhack_string), - ("r", c_float), - ("v", c_float), - ("b", c_float), - ("name", _dfhack_string)] - -def _alloc_descriptor_buffer_callback(ptr, count): - return util._allocate_array(ptr, DescriptorColor, count) - -_descriptor_functype = CFUNCTYPE(c_int, POINTER(POINTER(DescriptorColor)), c_uint) -_descriptor_func = _descriptor_functype(_alloc_descriptor_buffer_callback) -_register_callback("alloc_descriptor_buffer_callback", _descriptor_func) - -class MatglossPlant(Structure): - _fields_ = [("id", _dfhack_string), - ("fore", c_ubyte), - ("back", c_ubyte), - ("bright", c_ubyte), - ("name", _dfhack_string), - ("drink_name", _dfhack_string), - ("food_name", _dfhack_string), - ("extract_name", _dfhack_string)] - -class MatglossOther(Structure): - _fields_ = [("rawname", c_char * 128)] - -def _alloc_matgloss_other_buffer_callback(ptr, count): - return util._allocate_array(ptr, MatglossOther, count) - -_matgloss_other_functype = CFUNCTYPE(c_int, POINTER(POINTER(MatglossOther)), c_uint) -_matgloss_other_func = _matgloss_other_functype(_alloc_matgloss_other_buffer_callback) -_register_callback("alloc_matgloss_other_buffer_callback", _matgloss_other_func) - -class Building(Structure): - _fields_ = [("origin", c_uint), - ("vtable", c_uint), - ("x1", c_uint), - ("y1", c_uint), - ("x2", c_uint), - ("y2", c_uint), - ("z", c_uint), - ("material", MatglossPair), - ("type", c_uint)] - -class CustomWorkshop(Structure): - _fields_ = [("index", c_uint), - ("name", c_char * 256)] - -def _alloc_custom_workshop_buffer_callback(ptr, count): - return util._allocate_array(ptr, CustomWorkshop, count) - -_custom_workshop_functype = CFUNCTYPE(c_int, POINTER(POINTER(CustomWorkshop)), c_uint) -_custom_workshop_func = _custom_workshop_functype(_alloc_custom_workshop_buffer_callback) -_register_callback("alloc_customWorkshop_buffer_callback", _custom_workshop_func) - -class Construction(Structure): - _fields_ = [("x", c_ushort), - ("y", c_ushort), - ("z", c_ushort), - ("form", c_ushort), - ("unk_8", c_ushort), - ("mat_type", c_ushort), - ("mat_idx", c_uint), - ("unk3", c_ushort), - ("unk4", c_ushort), - ("unk5", c_ushort), - ("unk6", c_uint), - ("origin", c_uint)] - -class Tree(Structure): - _fields_ = [("type", c_ushort), - ("material", c_ushort), - ("x", c_ushort), - ("y", c_ushort), - ("z", c_ushort), - ("address", c_uint)] - - def __str__(self): - water = "" - tree_type = "tree" - - if self.type == 1 or self.type == 3: - water = "near-water" - if self.type == 2 or self.type == 3: - tree_type = "shrub" - - s = "%d:%d = %s %s\nAddress: 0x%x\n" % (self.type, self.material, water, tree_type, self.address) - - return s - -def _alloc_tree_buffer_callback(ptr, count): - return util._allocate_array(ptr, Tree, count) - -_alloc_tree_buffer_functype = CFUNCTYPE(c_int, POINTER(POINTER(Tree)), c_uint) -_alloc_tree_buffer_func = _alloc_tree_buffer_functype(_alloc_tree_buffer_callback) -_register_callback("alloc_tree_buffer_callback", _alloc_tree_buffer_func) - -class Material(Structure): - _fields_ = [("itemType", c_short), - ("subType", c_short), - ("subIndex", c_short), - ("index", c_int), - ("flags", c_uint)] - -def _alloc_material_buffer_callback(ptr, count): - return util._allocate_array(ptr, Material, count) - -_material_functype = CFUNCTYPE(c_int, POINTER(POINTER(Material)), c_uint) -_material_func = _material_functype(_alloc_material_buffer_callback) -_register_callback("alloc_material_buffer_callback", _material_func) - -class Skill(Structure): - _fields_ = [("id", c_uint), - ("experience", c_uint), - ("rating", c_uint)] - -class Job(Structure): - _fields_ = [("active", c_byte), - ("jobId", c_uint), - ("jobType", c_ubyte), - ("occupationPtr", c_uint)] - -class Like(Structure): - _fields_ = [("type", c_short), - ("itemClass", c_short), - ("itemIndex", c_short), - ("material", MatglossPair), - ("active", c_byte)] - -class Attribute(Structure): - _fields_ = [("level", c_uint), - ("field_4", c_uint), - ("field_8", c_uint), - ("field_C", c_uint), - ("leveldiff", c_uint), - ("field_14", c_uint), - ("field_18", c_uint)] - -class Name(Structure): - _fields_ = [("first_name", _dfhack_string), - ("nickname", _dfhack_string), - ("words", (c_int * 7)), - ("parts_of_speech", (c_ushort * 7)), - ("language", c_uint), - ("has_name", c_byte)] - -class Note(Structure): - _fields_ = [("symbol", c_char), - ("foreground", c_ushort), - ("background", c_ushort), - ("name", _dfhack_string), - ("x", c_ushort), - ("y", c_ushort), - ("z", c_ushort)] - -class Settlement(Structure): - _fields_ = [("origin", c_uint), - ("name", Name), - ("world_x", c_short), - ("world_y", c_short), - ("local_x1", c_short), - ("local_x2", c_short), - ("local_y1", c_short), - ("local_y2", c_short)] - -_NUM_CREATURE_TRAITS = 30 -_NUM_CREATURE_LABORS = 102 - -class Soul(Structure): - _fields_ = [("numSkills", c_ubyte), - ("skills", (Skill * 256)), - ("traits", (c_ushort * _NUM_CREATURE_TRAITS)), - ("analytical_ability", Attribute), - ("focus", Attribute), - ("willpower", Attribute), - ("creativity", Attribute), - ("intuition", Attribute), - ("patience", Attribute), - ("memory", Attribute), - ("linguistic_ability", Attribute), - ("spatial_sense", Attribute), - ("musicality", Attribute), - ("kinesthetic_sense", Attribute), - ("empathy", Attribute), - ("social_awareness", Attribute)] - -_MAX_COLORS = 15 - -class Creature(Structure): - _fields_ = [("origin", c_uint), - ("x", c_ushort), - ("y", c_ushort), - ("z", c_ushort), - ("race", c_uint), - ("civ", c_int), - ("flags1", CreatureFlags1), - ("flags2", CreatureFlags2), - ("name", Name), - ("mood", c_short), - ("mood_skill", c_short), - ("artifact_name", Name), - ("profession", c_ubyte), - ("custom_profession", _dfhack_string), - ("labors", (c_ubyte * _NUM_CREATURE_LABORS)), - ("current_job", Job), - ("happiness", c_uint), - ("id", c_uint), - ("strength", Attribute), - ("agility", Attribute), - ("toughness", Attribute), - ("endurance", Attribute), - ("recuperation", Attribute), - ("disease_resistance", Attribute), - ("squad_leader_id", c_int), - ("sex", c_ubyte), - ("caste", c_ushort), - ("pregnancy_timer", c_uint), - ("has_default_soul", c_byte), - ("defaultSoul", Soul), - ("nbcolors", c_uint), - ("color", (c_uint * _MAX_COLORS)), - ("birth_year", c_int), - ("birth_time", c_uint)] - -class CreatureExtract(Structure): - _fields_ = [("rawname", _dfhack_string)] - -class BodyPart(Structure): - _fields_ = [("id", _dfhack_string), - ("category", _dfhack_string), - ("single", _dfhack_string), - ("plural", _dfhack_string)] - -_bodypart_ptr = POINTER(BodyPart) - -class ColorModifier(Structure): - _fields_ = [("part", _dfhack_string), - ("colorlist", POINTER(c_uint)), - ("colorlistLength", c_uint), - ("startdate", c_uint), - ("enddate", c_uint)] - - def __init__(self): - self.colorlistLength = 0 - -_colormodifier_ptr = POINTER(ColorModifier) - -class CreatureCaste(Structure): - _fields_ = [("rawname", _dfhack_string), - ("singular", _dfhack_string), - ("plural", _dfhack_string), - ("adjective", _dfhack_string), - ("color_modifier", _colormodifier_ptr), - ("color_modifier_length", c_uint), - ("bodypart", _bodypart_ptr), - ("bodypart_length", c_uint), - ("strength", Attribute), - ("agility", Attribute), - ("toughness", Attribute), - ("endurance", Attribute), - ("recuperation", Attribute), - ("disease_resistance", Attribute), - ("analytical_ability", Attribute), - ("focus", Attribute), - ("willpower", Attribute), - ("creativity", Attribute), - ("intuition", Attribute), - ("patience", Attribute), - ("memory", Attribute), - ("linguistic_ability", Attribute), - ("spatial_sense", Attribute), - ("musicality", Attribute), - ("kinesthetic_sense", Attribute)] - -_creaturecaste_ptr = POINTER(CreatureCaste) - -class TileColor(Structure): - _fields_ = [("fore", c_ushort), - ("back", c_ushort), - ("bright", c_ushort)] - -class ColorDescriptor(Structure): - _fields_ = [("colorlistLength", c_uint)] - -class CasteDescriptor(Structure): - _fields_ = [("color_descriptors", POINTER(ColorDescriptor)), - ("colorModifierLength", c_uint), - ("bodypartLength", c_uint)] - -class CreatureTypeDescriptor(Structure): - _fields_ = [("caste_descriptors", POINTER(CasteDescriptor)), - ("castesCount", c_uint), - ("extractCount", c_uint)] - -class CreatureType(Structure): - _fields_ = [("rawname", _dfhack_string), - ("castes", _creaturecaste_ptr), - ("castes_count", c_uint), - ("extract", POINTER(CreatureExtract)), - ("extract_count", c_uint), - ("tile_character", c_ubyte), - ("tilecolor", TileColor)] - -_creaturetype_ptr = POINTER(CreatureType) - -def _alloc_creaturetype_buffer(ptr, descriptors, count): - arr_list = [] - c_arr = (CreatureType * count)() - - for i, v in enumerate(c_arr): - v.castesCount = descriptors[i].castesCount - v_caste_arr = (CreatureCaste * v.castesCount)() - - for j, v_c in enumerate(v_caste_arr): - caste_descriptor = descriptors[i].caste_descriptors[j] - - v_c.colorModifierLength = caste_descriptor.colorModifierLength - c_color_arr = (ColorModifier * v_c.colorModifierLength)() - - for k, c_c in enumerate(c_color_arr): - color_descriptor = caste_descriptor.color_descriptors[k] - - c_c.colorlistLength = color_descriptor.colorlistLength - - c_color_list_arr = (c_uint * c_c.colorlistLength)() - - p = cast(c_color_list_arr, POINTER(c_uint)) - - c_c.colorlist = p - - arr_list.extend((c_color_list_arr, p)) - - c_p = cast(c_color_arr, POINTER(ColorModifier)) - v_c.colorModifier = c_p - - v_c.bodypartLength = caste_descriptor.bodypartLength - c_bodypart_arr = (BodyPart * v_c.bodypartLength)() - - b_p = cast(c_bodypart_arr, POINTER(BodyPart)) - v_c.bodypart = b_p - - arr_list.extend((c_color_arr, c_p, c_bodypart_arr, b_p)) - - v.extractCount = descriptors[i].extractCount - v_extract_arr = (CreatureExtract * v.extractCount)() - - caste_p = cast(v_caste_arr, POINTER(CreatureCaste)) - v.castes = caste_p - - extract_p = cast(v_extract_arr, POINTER(CreatureExtract)) - v.extract = extract_p - - arr_list.extend((v_caste_arr, caste_p, v_extract_arr, extract_p)) - - p = cast(c_arr, _creaturetype_ptr) - ptr[0] = p - - pointer_dict[addressof(c_arr)] = (ptr, c_arr, p, arr_list) - - return 1 - -_alloc_creaturetype_buffer_functype = CFUNCTYPE(c_int, POINTER(_creaturetype_ptr), POINTER(CreatureTypeDescriptor), c_uint) -_alloc_creaturetype_buffer_func = _alloc_creaturetype_buffer_functype(_alloc_creaturetype_buffer) -_register_callback("alloc_creaturetype_buffer_callback", _alloc_creaturetype_buffer_func) - -class GameModes(Structure): - _fields_ = [("control_mode", c_ubyte), - ("game_mode", c_ubyte)] - -class Hotkey(Structure): - _fields_ = [("name", (c_char * 10)), - ("mode", c_short), - ("x", c_int), - ("y", c_int), - ("z", c_int)] - -_hotkey_ptr = POINTER(Hotkey) - -def _alloc_hotkey_buffer_callback(ptr, count): - print "hotkey alloc: %d" % count - return util._allocate_array(ptr, Hotkey, count) - -_hotkey_functype = CFUNCTYPE(c_int, POINTER(_hotkey_ptr), c_uint) -_hotkey_func = _hotkey_functype(_alloc_hotkey_buffer_callback) -_register_callback("alloc_hotkey_buffer_callback", _hotkey_func) - -class MemRange(Structure): - _fields_ = [("start", c_ulong), - ("end", c_ulong), - ("name", (c_char * 1024)), - ("read", c_uint, 1), - ("write", c_uint, 1), - ("execute", c_uint, 1), - ("shared", c_uint, 1), - ("valid", c_ubyte), - ("buffer", POINTER(c_ubyte))] - -_memrange_ptr = POINTER(MemRange) - -def _alloc_memrange_buffer(ptr, descriptors, count): - arr_list = [] - m_arr = (MemRange * count)() - - for i, v in enumerate(m_arr): - buf_arr = (c_ubyte * int(descriptors[i]))() - buf_ptr = cast(buf_arr, POINTER(c_ubyte)) - - v.buffer = buf_ptr - - arr_list.extend((buf_arr, buf_ptr)) - - p = cast(m_arr, _memrange_ptr) - ptr[0] = p - - pointer_dict[addressof(m_arr)] = (ptr, m_arr, p, arr_list) - - return 1 - -_alloc_memrange_buffer_functype = CFUNCTYPE(c_int, POINTER(_memrange_ptr), POINTER(c_uint), c_uint) -_alloc_memrange_buffer_func = _alloc_memrange_buffer_functype(_alloc_memrange_buffer) -_register_callback("alloc_memrange_buffer_callback", _alloc_memrange_buffer_func) \ No newline at end of file diff --git a/dfhack-python/enum.py b/dfhack-python/enum.py deleted file mode 100644 index bc123a8c9..000000000 --- a/dfhack-python/enum.py +++ /dev/null @@ -1,156 +0,0 @@ -#found this in the cookbook: http://code.activestate.com/recipes/576415/ - -from ctypes import c_uint - -class C_EnumerationType(type(c_uint)): - def __new__(metacls, name, bases, dictionary): - if not "_members_" in dictionary: - _members_ = {} - - for key, value in dictionary.iteritems(): - if not key.startswith("_"): - _members_[key] = value - - dictionary["_members_"] = _members_ - - cls = type(c_uint).__new__(metacls, name, bases, dictionary) - - for key, value in cls._members_.iteritems(): - globals()[key] = value - - return cls - - def __contains__(self, value): - return value in self._members_.values() - - def __repr__(self): - return "" % self.__name__ - -class C_Enumeration(c_uint): - __metaclass__ = C_EnumerationType - _members_ = {} - - def __init__(self, value): - for key, value in self._members_.iteritems(): - if v == value: - self.name = key - break - else: - raise ValueError("No enumeration member with value %r" % value) - - c_uint.__init__(self, value) - - def __repr__(self): - return "" % (self.name, self.value, self.__class__) - - @classmethod - def from_param(cls, param): - if isinstance(param, C_Enumeration): - if param.__class__ != cls: - raise ValueError("Cannot mix enumeration members") - else: - return param - else: - return cls(param) - -FeatureType = C_EnumerationType("FeatureType", - (c_uint,), - {"Other" : 0, - "Adamantine_Tube" : 1, - "Underworld" : 2, - "Hell_Temple" : 3}) - -BiomeOffset = C_EnumerationType("BiomeOffset", - (c_uint,), - {"NorthWest" : 0, - "North" : 1, - "NorthEast" : 2, - "West" : 3, - "Here" : 4, - "East" : 5, - "SouthWest" : 6, - "South" : 7, - "SouthEast" : 8, - "BiomeCount" : 9}) - -TrafficType = C_EnumerationType("TrafficType", - (c_uint,), - {"Normal" : 0, - "Low" : 1, - "High" : 2, - "Restricted" : 3}) - -DesignationType = C_EnumerationType("DesignationType", - (c_uint,), - {"No" : 0, - "Default" : 1, - "UD_Stair" : 2, - "Channel" : 3, - "Ramp" : 4, - "D_Stair" : 5, - "U_Stair" : 6, - "Whatever" : 7}) - -LiquidType = C_EnumerationType("LiquidType", - (c_uint,), - {"Water" : 0, - "Magma" : 1}) - -#this list must stay in the same order as the one in dfhack/library/include/dfhack/modules/WindowIO.h! -_keys = ["ENTER", - "SPACE", - "BACK_SPACE", - "TAB", - "CAPS_LOCK", - "LEFT_SHIFT", - "RIGHT_SHIFT", - "LEFT_CONTROL", - "RIGHT_CONTROL", - "ALT", - "WAIT", - "ESCAPE", - "UP", - "DOWN", - "LEFT", - "RIGHT", - "F1", - "F2", - "F3", - "F4", - "F5", - "F6", - "F7", - "F8", - "F9", - "F10", - "F11", - "F12", - "PAGE_UP", - "PAGE_DOWN", - "INSERT", - "DFK_DELETE", - "HOME", - "END", - "KEYPAD_DIVIDE", - "KEYPAD_MULTIPLY", - "KEYPAD_SUBTRACT", - "KEYPAD_ADD," - "KEYPAD_ENTER", - "KEYPAD_0", - "KEYPAD_1", - "KEYPAD_2", - "KEYPAD_3", - "KEYPAD_4", - "KEYPAD_5", - "KEYPAD_6", - "KEYPAD_7", - "KEYPAD_8", - "KEYPAD_9", - "KEYPAD_DECIMAL_POINT", - "NUM_SPECIALS"] - -_key_dict = dict([(k, i) for i, k in enumerate(_keys)]) - -KeyType = C_EnumerationType("KeyType", - (c_uint,), - _key_dict) diff --git a/dfhack-python/flags.py b/dfhack-python/flags.py deleted file mode 100644 index e058ab511..000000000 --- a/dfhack-python/flags.py +++ /dev/null @@ -1,201 +0,0 @@ -# -*- coding: utf-8 -*- -from ctypes import Structure, Union, c_uint -from enum import * - -class DesignationStruct(Structure): - _fields_ = [("flow_size", c_uint, 3), - ("pile", c_uint, 1), - ("dig", DesignationType, 3), - ("smooth", c_uint, 2), - ("hidden", c_uint, 1), - ("geolayer_index", c_uint, 4), - ("light", c_uint, 1), - ("subterranean", c_uint, 1), - ("skyview", c_uint, 1), - ("biome", c_uint, 4), - ("liquid_type", c_uint, 1), - ("water_table", c_uint, 1), - ("rained", c_uint, 1), - ("traffic", c_uint, 2), - ("flow_forbid", c_uint, 1), - ("liquid_static", c_uint, 1), - ("feature_local", c_uint, 1), - ("feature_global", c_uint, 1), - ("water_stagnant", c_uint, 1), - ("water_salt", c_uint, 1)] - -class DesignationFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", DesignationStruct)] - - def __init__(self, initial = 0): - self.whole = initial - - def __int__(self): - return self.whole - -class OccupancyStruct(Structure): - _fields_ = [("building", c_uint, 3), - ("unit", c_uint, 1), - ("unit_grounded", c_uint, 1), - ("item", c_uint, 1), - ("splatter", c_uint, 26)] - -class OccupancyFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", OccupancyStruct)] - - def __init__(self, initial = 0): - self.whole = initial - - def __int__(self): - return self.whole - -class CreatureStruct1(Structure): - _fields_ = [("move_state", c_uint, 1), - ("dead", c_uint, 1), - ("has_mood", c_uint, 1), - ("had_mood", c_uint, 1), - ("marauder", c_uint, 1), - ("drowning", c_uint, 1), - ("merchant", c_uint, 1), - ("forest", c_uint, 1), - ("left", c_uint, 1), - ("rider", c_uint, 1), - ("incoming", c_uint, 1), - ("diplomat", c_uint, 1), - ("zombie", c_uint, 1), - ("skeleton", c_uint, 1), - ("can_swap", c_uint, 1), - ("on_ground", c_uint, 1), - ("projectile", c_uint, 1), - ("active_invader", c_uint, 1), - ("hidden_in_ambush", c_uint, 1), - ("invader_origin", c_uint, 1), - ("coward", c_uint, 1), - ("hidden_ambusher", c_uint, 1), - ("invades", c_uint, 1), - ("check_flows", c_uint, 1), - ("ridden", c_uint, 1), - ("caged", c_uint, 1), - ("tame", c_uint, 1), - ("chained", c_uint, 1), - ("royal_guard", c_uint, 1), - ("fortress_guard", c_uint, 1), - ("suppress_wield", c_uint, 1), - ("important_historical_figure", c_uint, 1)] - -class CreatureFlags1(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", CreatureStruct1)] - - def __init__(self, initial = 0): - self.whole = initial - - def __int__(self): - return self.whole - -class CreatureStruct2(Structure): - _fields_ = [("swimming", c_uint, 1), - ("sparring", c_uint, 1), - ("no_notify", c_uint, 1), - ("unused", c_uint, 1), - ("calculated_nerves", c_uint, 1), - ("calculated_bodyparts", c_uint, 1), - ("important_historical_figure", c_uint, 1), - ("killed", c_uint, 1), - ("cleanup_1", c_uint, 1), - ("cleanup_2", c_uint, 1), - ("cleanup_3", c_uint, 1), - ("for_trade", c_uint, 1), - ("trade_resolved", c_uint, 1), - ("has_breaks", c_uint, 1), - ("gutted", c_uint, 1), - ("circulatory_spray", c_uint, 1), - ("locked_in_for_trading", c_uint, 1), - ("slaughter", c_uint, 1), - ("underworld", c_uint, 1), - ("resident", c_uint, 1), - ("cleanup_4", c_uint, 1), - ("calculated_insulation", c_uint, 1), - ("visitor_uninvited", c_uint, 1), - ("visitor", c_uint, 1), - ("calculated_inventory", c_uint, 1), - ("vision_good", c_uint, 1), - ("vision_damaged", c_uint, 1), - ("vision_missing", c_uint, 1), - ("breathing_good", c_uint, 1), - ("breathing_problem", c_uint, 1), - ("roaming_wilderness_population_source", c_uint, 1), - ("roaming_wilderness_population_source_not_a_map_feature", c_uint, 1)] - -class CreatureFlags2(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", CreatureStruct2)] - - def __init__(self, initial = 0): - self.whole = initial - - def __int__(self): - return self.whole - -class ItemStruct(Structure): - _fields_ = [("on_ground", c_uint, 1), - ("in_job", c_uint, 1), - ("in_inventory", c_uint, 1), - ("u_ngrd1", c_uint, 1), - ("in_workshop", c_uint, 1), - ("u_ngrd2", c_uint, 1), - ("u_ngrd3", c_uint, 1), - ("rotten", c_uint, 1), - ("unk1", c_uint, 1), - ("u_ngrd4", c_uint, 1), - ("unk2", c_uint, 1), - ("u_ngrd5", c_uint, 1), - ("unk3", c_uint, 1), - ("u_ngrd6", c_uint, 1), - ("narrow", c_uint, 1), - ("u_ngrd7", c_uint, 1), - ("worn", c_uint, 1), - ("unk4", c_uint, 1), - ("u_ngrd8", c_uint, 1), - ("forbid", c_uint, 1), - ("unk5", c_uint, 1), - ("dump", c_uint, 1), - ("on_fire", c_uint, 1), - ("melt", c_uint, 1), - ("hidden", c_uint, 1), - ("u_ngrd9", c_uint, 1), - ("unk6", c_uint, 1), - ("unk7", c_uint, 1), - ("unk8", c_uint, 1), - ("unk9", c_uint, 1), - ("unk10", c_uint, 1), - ("unk11", c_uint, 1)] - -class ItemFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", ItemStruct)] - - def __init__(self, initial = 0): - self.whole = initial - - def __int__(self): - return self.whole - -class BlockFlagStruct(Structure): - _fields_ = [("designated", c_uint, 1), - ("unk_1", c_uint, 1), - ("liquid_1", c_uint, 1), - ("liquid_2", c_uint, 1), - ("unk_2", c_uint, 28)] - -class BlockFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", BlockFlagStruct)] - - def __init__(self, inital = 0): - self.whole = initial - - def __int__(self): - return self.whole diff --git a/dfhack-python/gui.py b/dfhack-python/gui.py deleted file mode 100644 index 2a050d782..000000000 --- a/dfhack-python/gui.py +++ /dev/null @@ -1,73 +0,0 @@ -from ctypes import c_void_p, c_int, c_uint, byref -from dftypes import libdfhack, ViewScreen, Hotkey -from util import check_pointer_cache - -libdfhack.Gui_getViewCoords.argtypes = [ c_void_p, POINTER(c_int), POINTER(c_int), POINTER(c_int) ] -libdfhack.Gui_setViewCoords.argtypes = [ c_void_p, c_int, c_int, c_int ] - -libdfhack.Gui_getCursorCoords.argtypes = [ c_void_p, POINTER(c_int), POINTER(c_int), POINTER(c_int) ] -libdfhack.Gui_setCursorCoords.argtypes = [ c_void_p, c_int, c_int, c_int ] - -libdfhack.Gui_getWindowSize.argtypes = [ c_void_p, POINTER(c_int), POINTER(c_int) ] - -libdfhack.Gui_ReadViewScreen.argtypes = [ c_void_p, c_void_p ] - -libdfhack.Gui_ReadHotkeys.restype = c_void_p - -libdfhack.Gui_getScreenTiles.argtypes = [ c_void_p, c_int, c_int ] -libdfhack.Gui_getScreenTiles.restype = c_void_p - -class Gui(object): - def __init__(self, ptr): - self._gui_ptr = ptr - - def start(self): - return libdfhack.Gui_Start(self._gui_ptr) > 0 - - def finish(self): - return libdfhack.Gui_Finish(self._gui_ptr) > 0 - - def read_view_screen(self): - s = ViewScreen() - - if libdfhack.Gui_ReadViewScreen(self._gui_ptr, byref(s)) > 0: - return s - else: - return None - - def get_view_coords(self): - x, y, z = (0, 0, 0) - - if libdfhack.Gui_getViewCoords(self._gui_ptr, byref(x), byref(y), byref(z)) > 0: - return (x, y, z) - else: - return (-1, -1, -1) - - def set_view_coords(self, x, y, z): - libdfhack.Gui_setViewCoords(self._gui_ptr, x, y, z) - - def get_cursor_coords(self): - x, y, z = (0, 0, 0) - - if libdfhack.Gui_getCursorCoords(self._gui_ptr, byref(x), byref(y), byref(z)) > 0: - return (x, y, z) - else: - return (-1, -1, -1) - - def set_cursor_coords(self, x, y, z): - libdfhack.Gui_setCursorCoords(self._gui_ptr, x, y, z) - - def read_hotkeys(self): - return check_pointer_cache(libdfhack.Gui_ReadHotkeys(self._gui_ptr)) - - def get_screen_tiles(self, width, height): - return check_pointer_cache(libdfhack.Gui_getScreenTiles(self._gui_ptr, width, height)) - - @property - def window_size(self): - width, height = (0, 0) - - if libdfhack.Gui_getWindowSize(self._gui_ptr, byref(width), byref(height)) > 0: - return (width, height) - else: - return (-1, -1) diff --git a/dfhack-python/items.py b/dfhack-python/items.py deleted file mode 100644 index 8c5d6625e..000000000 --- a/dfhack-python/items.py +++ /dev/null @@ -1,33 +0,0 @@ -from ctypes import * -from dftypes import * - -libdfhack.Items_getItemDescription.argtypes = [ c_void_p, c_uint, c_void_ptr, _arr_create_func ] -libdfhack.Items_getItemDescription.restype = c_char_p -libdfhack.Items_getItemClass.argtypes = [ c_void_p, c_int, _arr_create_func ] -libdfhack.Item_getItemClass.restype = c_char_p - -class Items(object): - def __init__(self, ptr): - self._i_ptr = ptr - - def get_item_description(self, itemptr, materials): - def get_callback(count): - item_string = create_string_buffer(count) - - return byref(item_string) - - item_string = None - callback = _arr_create_func(get_callback) - - return libdfhack.Items_getItemDescription(self._i_ptr, itemptr, materials, callback) - - def get_item_class(self, index): - def get_callback(count): - item_string = create_string_buffer(count) - - return byref(item_string) - - item_string = None - callback = _arr_create_func(get_callback) - - return libdfhack.Items_getItemClass(self._i_ptr, index, callback) diff --git a/dfhack-python/maps.py b/dfhack-python/maps.py deleted file mode 100644 index 616eda056..000000000 --- a/dfhack-python/maps.py +++ /dev/null @@ -1,291 +0,0 @@ -from ctypes import * -from dftypes import * -from util import _uintify, int_ptr, uint_ptr, check_pointer_cache - -_MAX_DIM = 0x300 -_MAX_DIM_SQR = _MAX_DIM * _MAX_DIM - -libdfhack.Maps_getSize.argtypes = [ c_void_p, uint_ptr, uint_ptr, uint_ptr ] -libdfhack.Maps_getPosition.argtypes = [ c_void_p, int_ptr, int_ptr, int_ptr ] - -libdfhack.Maps_ReadTileTypes.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(TileTypes40d) ] -libdfhack.Maps_WriteTileTypes.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(TileTypes40d) ] -libdfhack.Maps_ReadDesignations.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Designations40d) ] -libdfhack.Maps_WriteDesignations.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Designations40d) ] -libdfhack.Maps_ReadTemperatures.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Temperatures) ] -libdfhack.Maps_WriteTemperatures.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Temperatures) ] -libdfhack.Maps_ReadOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ] -libdfhack.Maps_WriteOccupancy.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(Occupancies40d) ] -libdfhack.Maps_ReadRegionOffsets.argtypes = [ c_void_p, c_uint, c_uint, c_uint, POINTER(BiomeIndices40d) ] - -libdfhack.Maps_ReadVegetation.restype = c_void_p - -libdfhack.Maps_ReadStandardVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ] -libdfhack.Maps_ReadFrozenVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ] -libdfhack.Maps_ReadSpatterVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ] -libdfhack.Maps_ReadGrassVeins.argtypes = [ c_void_p, c_uint, c_uint, c_uint ] -libdfhack.Maps_ReadWorldConstructions.argtypes = [ c_void_p, c_uint, c_uint, c_uint ] - -libdfhack.Maps_ReadStandardVeins.restype = c_void_p -libdfhack.Maps_ReadFrozenVeins.restype = c_void_p -libdfhack.Maps_ReadSpatterVeins.restype = c_void_p -libdfhack.Maps_ReadGrassVeins.restype = c_void_p -libdfhack.Maps_ReadWorldConstructions.restype = c_void_p - -libdfhack.Maps_ReadLocalFeatures.restype = c_void_p - -class Maps(object): - def __init__(self, ptr): - self._map_ptr = ptr - - def start(self): - return libdfhack.Maps_Start(self._map_ptr) > 0 - - def finish(self): - return libdfhack.Maps_Finish(self._map_ptr) > 0 - - def is_valid_block(self, x, y, z): - return libdfhack.Maps_isValidBlock(self._map_ptr, *_uintify(x, y, z)) > 0 - - def read_tile_types(self, x, y, z): - tt = TileTypes40d() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadTileTypes(self._map_ptr, ux, uy, uz, tt) > 0: - return tt - else: - return None - - def write_tile_types(self, x, y, z, tt): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteTileTypes(self._map_ptr, ux, uy, uz, tt) > 0 - - def read_designations(self, x, y, z): - d = Designations40d() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadDesignations(self._map_ptr, ux, uy, uz, byref(d)) > 0: - return d - else: - return None - - def write_designations(self, x, y, z, d): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteDesignations(self._map_ptr, ux, uy, uz, byref(d)) > 0 - - def read_temperatures(self, x, y, z): - t = Temperatures() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadDesignations(self._map_ptr, ux, uy, uz, t) > 0: - return t - else: - return None - - def write_temperatures(self, x, y, z, t): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteDesignations(self._map_ptr, ux, uy, uz, t) > 0 - - def read_occupancy(self, x, y, z): - o = Occupancies40d() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadDesignations(self._map_ptr, ux, uy, uz, o) > 0: - return o - else: - return None - - def write_occupancy(self, x, y, z, o): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteDesignations(self._map_ptr, ux, uy, uz, byref(o)) > 0 - - def read_dirty_bit(self, x, y, z): - bit = c_int(0) - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadDirtyBit(self._map_ptr, ux, uy, uz, byref(bit)) > 0: - if bit > 0: - return True - else: - return False - else: - return None - - def write_dirty_bit(self, x, y, z, dirty): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteDirtyBit(self._map_ptr, ux, uy, uz, c_int(dirty)) > 0 - - def read_features(self, x, y, z): - lf = c_short() - gf = c_short() - - ux, uy, uz = _uintify(x, y, z) - - libdfhack.Maps_ReadFeatures(self._map_ptr, ux, uy, uz, byref(lf), byref(fg)) - - return (lf, gf) - - def write_local_feature(self, x, y, z, local_feature = -1): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteLocalFeature(self._map_ptr, ux, uy, uz, c_short(local_feature)) > 0 - - def write_global_feature(self, x, y, z, global_feature = -1): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteGlobalFeature(self._map_ptr, ux, uy, uz, c_short(global_feature)) > 0 - - def read_block_flags(self, x, y, z): - bf = BlockFlags() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadBlockFlags(self._map_ptr, ux, uy, uz, byref(bf)) > 0: - return bf - else: - return None - - def write_block_flags(self, x, y, z, block_flags): - ux, uy, uz = _uintify(x, y, z) - - return libdfhack.Maps_WriteBlockFlags(self._map_ptr, ux, uy, uz, block_flags) > 0 - - def read_region_offsets(self, x, y, z): - bi = BiomeIndices40d() - - ux, uy, uz = _uintify(x, y, z) - - if libdfhack.Maps_ReadRegionOffsets(self._map_ptr, ux, uy, uz, byref(bi)) > 0: - return bi - else: - return None - - def read_veins(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadStandardVeins(self._map_ptr, ux, uy, uz)) - - def read_frozen_veins(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadFrozenVeins(self._map_ptr, ux, uy, uz)) - - def read_spatter_veins(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadSpatterVeins(self._map_ptr, ux, uy, uz)) - - def read_grass_veins(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadGrassVeins(self._map_ptr, ux, uy, uz)) - - def read_world_constructions(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadWorldConstructions(self._map_ptr, ux, uy, uz)) - - def read_vegetation(self, x, y, z): - ux, uy, uz = _uintify(x, y, z) - - return check_pointer_cache(libdfhack.Maps_ReadVegetation(self._map_ptr, ux, uy, uz)) - - def read_local_features(self): - f = libdfhack.Maps_ReadLocalFeatures(self._map_ptr) - feature_dict = {} - f_arr = check_pointer_cache(f, False) - - if f_arr is not None: - for node in f_arr: - c = node.coordinate.xyz - coord = MapPoint(c.x, c.y, c.z) - f_list = [node.features[i] for i in xrange(node.feature_length)] - feature_dict[coord] = f_list - - return feature_dict - - @property - def size(self): - x, y, z = (c_uint(0), c_uint(0), c_uint(0)) - - retval = libdfhack.Maps_getSize(self._map_ptr, byref(x), byref(y), byref(z)) - - return (int(x.value), int(y.value), int(z.value)) - - @property - def position(self): - x, y, z = (c_int(0), c_int(0), c_int(0)) - - libdfhack.Maps_getPosition(self._map_ptr, byref(x), byref(y), byref(z)) - - return (int(x.value), int(y.value), int(z.value)) - -class MapPoint(object): - __slots__ = ["_x", "_y", "_z", "_cmp_val"] - - def __init__(self, x = 0, y = 0, z = 0): - self._x, self._y, self._z = x, y, z - - self._cmp_val = self._get_cmp_value() - - def _val_set(self, which, val): - if which == 0: - self._x = val - elif which == 1: - self._y = val - elif which == 2: - self._z = val - - self._cmp_val = self._get_cmp_value() - - x = property(fget = lambda self: self._x, fset = lambda self, v: self._val_set(0, v)) - y = property(fget = lambda self: self._y, fset = lambda self, v: self._val_set(1, v)) - z = property(fget = lambda self: self._z, fset = lambda self, v: self._val_set(2, v)) - - def _get_cmp_value(self): - return (self.z * _MAX_DIM_SQR) + (self.y * _MAX_DIM) + self.x - - #comparison operators - def __eq__(self, other): - return self.x == other.x and self.y == other.y and self.z == other.z - - def __ne__(self, other): - return not self == other - - def __lt__(self, other): - return self._cmp_val < other._cmp_val - - def __le__(self, other): - return self < other or self == other - - def __gt__(self, other): - return self._cmp_val > other._cmp_val - - def __ge__(self, other): - return self > other or self == other - - #arithmetic operators - def __add__(self, num): - return MapPoint(self.x, self.y, self.z + num) - - def __sub__(self, num): - return MapPoint(self.x, self.y, self.z - num) - - def __div__(self, num): - return MapPoint(self.x / num, self.y / num, self.z) - - def __mul__(self, num): - return MapPoint(self.x * num, self.y * num, self.z) - - def __mod__(self, num): - return MapPoint(self.x % num, self.y % num, self.z) \ No newline at end of file diff --git a/dfhack-python/materials.py b/dfhack-python/materials.py deleted file mode 100644 index 37bfcf2ff..000000000 --- a/dfhack-python/materials.py +++ /dev/null @@ -1,166 +0,0 @@ -from ctypes import * -import dftypes -from dftypes import libdfhack, Matgloss, CreatureType, DescriptorColor, MatglossOther -from util import check_pointer_cache - -libdfhack.Materials_getInorganic.restype = c_void_p -libdfhack.Materials_getOrganic.restype = c_void_p -libdfhack.Materials_getTree.restype = c_void_p -libdfhack.Materials_getPlant.restype = c_void_p -libdfhack.Materials_getRace.restype = c_void_p -libdfhack.Materials_getRaceEx.restype = c_void_p -libdfhack.Materials_getColor.restype = c_void_p -libdfhack.Materials_getOther.restype = c_void_p -libdfhack.Materials_getAllDesc.restype = c_void_p - -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 _get_inorganic(self): - self.inorganic = check_pointer_cache(libdfhack.Materials_getInorganic(self._mat_ptr)) - - def _get_organic(self): - self.organic = check_pointer_cache(libdfhack.Materials_getOrganic(self._mat_ptr)) - - def _get_tree(self): - self.tree = check_pointer_cache(libdfhack.Materials_getTree(self._mat_ptr)) - - def _get_plant(self): - self.plant = check_pointer_cache(libdfhack.Materials_getPlant(self._mat_ptr)) - - def _get_race(self): - self.race = check_pointer_cache(libdfhack.Materials_getRace(self._mat_ptr)) - - def _get_race_ex(self): - self.race_ex = check_pointer_cache(libdfhack.Materials_getRaceEx(self._mat_ptr)) - - def _get_color(self): - self.color = check_pointer_cache(libdfhack.Materials_getColor(self._mat_ptr)) - - def _get_other(self): - self.other = check_pointer_cache(libdfhack.Materials_getOther(self._mat_ptr)) - - def _get_all(self): - self._get_inorganic() - self._get_organic() - self._get_tree() - self._get_plant() - self._get_race() - self._get_race_ex() - self._get_color() - self._get_other() - def _clear_all(self): - 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): - result = libdfhack.Materials_ReadInorganicMaterials(self._mat_ptr) > 0 - - if result == True: - self._get_inorganic() - else: - self.inorganic = None - - return result - - def read_organic(self): - result = libdfhack.Materials_ReadOrganicMaterials(self._mat_ptr) > 0 - - if result == True: - self._get_organic() - else: - self.organic = None - - return result - - def read_tree(self): - result = libdfhack.Materials_ReadWoodMaterials(self._mat_ptr) > 0 - - if result == True: - self._get_tree() - else: - self.tree = None - - return result - - def read_plant(self): - result = libdfhack.Materials_ReadPlantMaterials(self._mat_ptr) > 0 - - if result == True: - self._get_plant() - else: - self.plant = None - - return result - - def read_creature_types(self): - result = libdfhack.Materials_ReadCreatureTypes(self._mat_ptr) > 0 - - if result == True: - self._get_race() - else: - self.race = None - - return result - - def read_creature_types_ex(self): - result = libdfhack.Materials_ReadCreatureTypesEx(self._mat_ptr) > 0 - - if result == True: - self._get_race_ex() - else: - self.race_ex = None - - return result - - def read_descriptor_colors(self): - result = libdfhack.Materials_ReadDescriptorColors(self._mat_ptr) > 0 - - if result == True: - self._get_color() - else: - self.color = None - - return result - - def read_others(self): - result = libdfhack.Materials_ReadOthers(self._mat_ptr) > 0 - - if result == True: - self._get_other() - else: - self.other = None - - return result - - def read_all(self): - result = libdfhack.Materials_ReadAllMaterials(self._mat_ptr) > 0 - - if result == True: - self._get_all() - else: - self._clear_all() - - return result - - def get_type(self, material): - return libdfhack.Materials_getType(self._mat_ptr, byref(material)) - - def get_description(self, material): - return libdfhack.Materials_getDescription(self._mat_ptr, byref(material)) \ No newline at end of file diff --git a/dfhack-python/process.py b/dfhack-python/process.py deleted file mode 100644 index b9ac200b6..000000000 --- a/dfhack-python/process.py +++ /dev/null @@ -1,135 +0,0 @@ -from ctypes import * -from dftypes import libdfhack -from util import check_pointer_cache - -libdfhack.Process_readQuad.argtypes = [ c_void_p, c_uint, POINTER(c_ulong) ] -libdfhack.Process_writeQuad.argtypes = [ c_void_p, c_uint, c_ulong ] - -libdfhack.Process_readDWord.argtypes = [ c_void_p, c_uint, POINTER(c_uint) ] -libdfhack.Process_writeDWord.argtypes = [ c_void_p, c_uint, c_uint ] - -libdfhack.Process_readWord.argtypes = [ c_void_p, c_uint, POINTER(c_ushort) ] -libdfhack.Process_writeWord.argtypes = [ c_void_p, c_uint, c_ushort ] - -libdfhack.Process_readByte.argtypes = [ c_void_p, c_uint, POINTER(c_ubyte) ] -libdfhack.Process_writeByte.argtypes = [ c_void_p, c_uint, c_ubyte ] - -libdfhack.Process_readFloat.argtypes = [ c_void_p, c_uint, POINTER(c_float) ] - -libdfhack.Process_read.argtypes = [ c_void_p, c_uint, c_uint ] -libdfhack.Process_read.restype = c_void_p - -libdfhack.Process_write.argtypes = [ c_void_p, c_uint, c_uint, POINTER(c_ubyte) ] - -libdfhack.Process_getThreadIDs.restype = c_void_p - -class Process(object): - def __init__(self, ptr): - self._p_ptr = ptr - - def attach(self): - return libdfhack.Process_attach(self._p_ptr) > 0 - - def detach(self): - return libdfhack.Process_detach(self._p_ptr) > 0 - - def suspend(self): - return libdfhack.Process_suspend(self._p_ptr) > 0 - - def async_suspend(self): - return libdfhack.Process_asyncSuspend(self._p_ptr) > 0 - - def resume(self): - return libdfhack.Process_resume(self._p_ptr) > 0 - - def force_resume(self): - return libdfhack.Process_forceresume(self._p_ptr) > 0 - - def read_quad(self, address): - q = c_ulong(0) - - if libdfhack.Process_readQuad(self._p_ptr, address, byref(q)) > 0: - return long(q.value) - else: - return -1 - - def write_quad(self, address, value): - return libdfhack.Process_writeQuad(self._p_ptr, address, value) > 0 - - def read_dword(self, address): - d = c_uint(0) - - if libdfhack.Process_readDWord(self._p_ptr, address, byref(d)) > 0: - return int(d.value) - else: - return -1 - - def write_dword(self, address, value): - return libdfhack.Process_writeDWord(self._p_ptr, address, value) > 0 - - def read_word(self, address): - s = c_ushort(0) - - if libdfhack.Process_readWord(self._p_ptr, address, byref(s)) > 0: - return int(s.value) - else: - return -1 - - def write_word(self, address, value): - return libdfhack.Process_writeWord(self._p_ptr, address, value) > 0 - - def read_byte(self, address): - b = c_ubyte(0) - - if libdfhack.Process_readByte(self._p_ptr, address, byref(b)) > 0: - return int(b.value) - else: - return -1 - - def write_byte(self, address, value): - return libdfhack.Process_writeByte(self._p_ptr, address, value) > 0 - - def read_float(self, address): - f = c_float(0) - - if libdfhack.Process_readFloat(self._p_ptr, address, byref(f)) > 0: - return float(f.value) - else: - return -1 - - def read(self, address, length): - return check_pointer_cache(libdfhack.Process_read(self._p_ptr, address, length)) - - def write(self, address, length, buffer): - libdfhack.Process_write(self._p_ptr, address, length, byref(buffer)) - - def get_thread_ids(self): - return check_pointer_cache(libdfhack.Process_getThreadIDs(self._p_ptr)) - - def set_and_wait(self, state): - return libdfhack.Process_SetAndWait(self._p_ptr, state) > 0 - - @property - def is_suspended(self): - return libdfhack.Process_isSuspended(self._p_ptr) > 0 - - @property - def is_attached(self): - return libdfhack.Process_isAttached(self._p_ptr) > 0 - - @property - def is_identified(self): - return libdfhack.Process_isIdentified(self._p_ptr) > 0 - - @property - def is_snapshot(self): - return libdfhack.Process_isSnapshot(self._p_ptr) > 0 - - @property - def pid(self): - p = c_int(0) - - if libdfhack.Process_getPID(self._p_ptr, byref(p)) > 0: - return int(p.value) - else: - return -1 \ No newline at end of file diff --git a/dfhack-python/util.py b/dfhack-python/util.py deleted file mode 100644 index 40fd990a1..000000000 --- a/dfhack-python/util.py +++ /dev/null @@ -1,88 +0,0 @@ -from ctypes import * - -int_ptr = POINTER(c_int) -uint_ptr = POINTER(c_uint) - -short_ptr = POINTER(c_short) -ushort_ptr = POINTER(c_ushort) - -byte_ptr = POINTER(c_byte) -ubyte_ptr = POINTER(c_ubyte) - -pointer_dict = {} - -def check_pointer_cache(address, return_as_list = True): - arr = None - - if address in pointer_dict: - arr = pointer_dict[address][1] - del pointer_dict[address] - - if return_as_list == True: - arr = [i for i in arr] - - return arr - -def _uintify(x, y, z): - return (c_uint(x), c_uint(y), c_uint(z)) - -def _allocate_array(ptr, t_type, count): - arr = (t_type * count)() - - p = cast(arr, POINTER(t_type)) - - ptr[0] = p - - pointer_dict[addressof(arr)] = (ptr, arr, p) - - return 1 - -def _alloc_int_buffer(ptr, count): - return _allocate_array(ptr, c_int, count) - -_int_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_int)), c_uint) -alloc_int_buffer = _int_functype(_alloc_int_buffer) - -def _alloc_uint_buffer(ptr, count): - return _allocate_array(ptr, c_uint, count) - -_uint_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_uint)), c_uint) -alloc_uint_buffer = _uint_functype(_alloc_uint_buffer) - -def _alloc_short_buffer(ptr, count): - return _allocate_array(ptr, c_short, count) - -_short_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_short)), c_uint) -alloc_short_buffer = _short_functype(_alloc_short_buffer) - -def _alloc_ushort_buffer(ptr, count): - return _allocate_array(ptr, c_ushort, count) - -_ushort_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_ushort)), c_uint) -alloc_ushort_buffer = _ushort_functype(_alloc_ushort_buffer) - -def _alloc_byte_buffer(ptr, count): - return _allocate_array(ptr, c_byte, count) - -_byte_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_byte)), c_uint) -alloc_byte_buffer = _byte_functype(_alloc_byte_buffer) - -def _alloc_ubyte_buffer(ptr, count): - return _allocate_array(ptr, c_ubyte, count) - -_ubyte_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_ubyte)), c_uint) -alloc_ubyte_buffer = _ubyte_functype(_alloc_ubyte_buffer) - -def _alloc_char_buffer(ptr, count): - c = create_string_buffer(count) - - p = cast(c, POINTER(c_char)) - - ptr[0] = p - - pointer_dict[id(ptr[0])] = (ptr, c, p) - - return 1 - -_char_functype = CFUNCTYPE(c_int, POINTER(POINTER(c_char)), c_uint) -alloc_char_buffer = _char_functype(_alloc_char_buffer) diff --git a/dfhack-python/vegetation.py b/dfhack-python/vegetation.py deleted file mode 100644 index ca1f12bd6..000000000 --- a/dfhack-python/vegetation.py +++ /dev/null @@ -1,25 +0,0 @@ -from ctypes import * -from dftypes 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 diff --git a/dfhack-python/window_io.py b/dfhack-python/window_io.py deleted file mode 100644 index 0e29b86fc..000000000 --- a/dfhack-python/window_io.py +++ /dev/null @@ -1,26 +0,0 @@ -from ctypes import * -from dftypes import libdfhack - -libdfhack.WindowIO_TypeStr.argtypes = [ c_void_p, c_char_p, c_uint, c_byte ] -libdfhack.WindowIO_TypeSpecial.argtypes = [ c_void_p, c_uint, c_uint, c_uint, c_uint ] - -class WindowIO(object): - def __init__(self, ptr): - self._window_io_ptr = ptr - - def type_str(self, s, delay = 0, use_shift = False): - c_shift = c_byte(0) - c_delay = c_uint(delay) - c_s = c_char_p(s) - - if use_shift is True: - c_shift = c_byte(1) - - return libdfhack.WindowIO_TypeStr(self._window_io_ptr, c_s, c_delay, c_shift) > 0 - - def type_special(self, command, count = 1, delay = 0): - c_command = c_uint(command) - c_count = c_uint(count) - c_delay = c_uint(delay) - - return libdfhack.WindowIO_TypeSpecial(self._window_io_ptr, c_command, c_count, c_delay) > 0 \ No newline at end of file diff --git a/dfhack-python/world.py b/dfhack-python/world.py deleted file mode 100644 index 5a6e798b0..000000000 --- a/dfhack-python/world.py +++ /dev/null @@ -1,80 +0,0 @@ -from ctypes import * -from dftypes import libdfhack, GameModes -from util import _uintify, uint_ptr - -libdfhack.World_ReadGameMode.argtypes = [ c_void_p, POINTER(GameModes) ] - -class World(object): - def __init__(self, ptr): - self._world_ptr = ptr - - def start(self): - return libdfhack.World_Start(self._world_ptr) > 0 - - def finish(self): - return libdfhack.World_Finish(self._world_ptr) > 0 - - def read_pause_state(self): - return libdfhack.World_ReadPauseState(self._world_ptr) > 0 - - def set_pause_state(self, pause_state): - p = c_byte(0) - - if pause_state is not None and pause_state is not False: - p.value = 1 - - return libdfhack.World_SetPauseState(self._world_ptr, p) > 0 - - def read_current_tick(self): - tick = c_uint(0) - - if libdfhack.World_ReadCurrentTick(self._world_ptr, byref(tick)) > 0: - return int(tick) - else: - return -1 - - def read_current_year(self): - year = c_uint(0) - - if libdfhack.World_ReadCurrentYear(self._world_ptr, byref(year)) > 0: - return int(year) - else: - return -1 - - def read_current_month(self): - month = c_uint(0) - - if libdfhack.World_ReadCurrentMonth(self._world_ptr, byref(month)) > 0: - return int(month) - else: - return -1 - - def read_current_day(self): - day = c_uint(0) - - if libdfhack.World_ReadCurrentDay(self._world_ptr, byref(day)) > 0: - return int(day) - else: - return -1 - - def read_current_weather(self): - weather = c_ubyte(0) - - if libdfhack.World_ReadCurrentWeather(self._world_ptr, byref(weather)) > 0: - return int(weather) - else: - return -1 - - def write_current_weather(self, weather): - return libdfhack.World_WriteCurrentWeather(self._world_ptr, c_ubyte(weather)) - - def read_game_mode(self): - game_modes = GameModes() - - if libdfhack.World_ReadGameMode(self._world_ptr, byref(game_modes)) > 0: - return game_modes - else: - return None - - def write_game_mode(self, game_mode): - return libdfhack.World_WriteGameMode(self._world_ptr, game_modes) > 0 \ No newline at end of file diff --git a/dfhack.kdev4 b/dfhack.kdev4 deleted file mode 100644 index 771cc037c..000000000 --- a/dfhack.kdev4 +++ /dev/null @@ -1,3 +0,0 @@ -[Project] -Manager=KDevCMakeManager -Name=dfhack diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 83198f305..b890715e8 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -1,45 +1,42 @@ -if(NOT DEFINED DFHACK_CONSISTENCY) - MESSAGE(FATAL_ERROR "Please build the whole thing, not parts. You can turn parts on/off using options.") -ENDIF() - -PROJECT (dfhack-library) +PROJECT (dfapi) cmake_minimum_required(VERSION 2.8) +## build options +OPTION(BUILD_DEVEL "Install/package files required for development (For SDK)." OFF) +OPTION(BUILD_DOXYGEN "Create/install/package doxygen documentation for DFHack (For SDK)." OFF) + include_directories (include) include_directories (depends/md5) +include_directories (depends/libnoise) include_directories (depends/tinyxml) -include_directories (depends/argstream) include_directories (private) SET(PROJECT_HDRS_INTERNAL private/ContextShared.h private/Internal.h - private/SHMProcess.h - private/LinuxProcess.h - private/ProcessFactory.h - private/MicrosoftSTL.h + private/wdirent.h ) SET(PROJECT_HDRS include/DFHack.h -include/dfhack/DFContext.h -include/dfhack/DFContextManager.h -include/dfhack/DFError.h -include/dfhack/DFExport.h -include/dfhack/DFIntegers.h -include/dfhack/DFMiscUtils.h -include/dfhack/DFModule.h -include/dfhack/DFPragma.h -include/dfhack/DFProcess.h -include/dfhack/DFProcessEnumerator.h -include/dfhack/DFTileTypes.h -include/dfhack/DFTypes.h -include/dfhack/DFVector.h -include/dfhack/VersionInfoFactory.h +include/dfhack/Console.h +include/dfhack/Core.h +include/dfhack/Error.h +include/dfhack/Export.h +include/dfhack/FakeSDL.h +include/dfhack/MiscUtils.h +include/dfhack/Module.h +include/dfhack/Pragma.h +include/dfhack/Process.h +include/dfhack/TileTypes.h +include/dfhack/Types.h +include/dfhack/Vector.h include/dfhack/VersionInfo.h +include/dfhack/VersionInfoFactory.h +include/dfhack/Virtual.h include/dfhack/extra/MapExtras.h -include/dfhack/extra/termutil.h include/dfhack/extra/stopwatch.h +include/dfhack/extra/termutil.h include/dfhack/modules/Buildings.h include/dfhack/modules/Constructions.h include/dfhack/modules/Creatures.h @@ -48,41 +45,20 @@ include/dfhack/modules/Gui.h include/dfhack/modules/Items.h include/dfhack/modules/Maps.h include/dfhack/modules/Materials.h +include/dfhack/modules/Notes.h include/dfhack/modules/Translation.h include/dfhack/modules/Vegetation.h -include/dfhack/modules/WindowIO.h +include/dfhack/modules/Vermin.h include/dfhack/modules/World.h ) -SET(PROJECT_C_HDRS -include/DFHack_C.h -include/dfhack-c/DFProcess_C.h -include/dfhack-c/DFTypes_C.h -include/dfhack-c/DFTileTypes_C.h -include/dfhack-c/DFContext_C.h -include/dfhack-c/modules/Buildings_C.h -include/dfhack-c/modules/Constructions_C.h -include/dfhack-c/modules/Creatures_C.h -include/dfhack-c/modules/Gui_C.h -include/dfhack-c/modules/Items_C.h -include/dfhack-c/modules/Maps_C.h -include/dfhack-c/modules/Materials_C.h -include/dfhack-c/modules/Translation_C.h -include/dfhack-c/modules/Vegetation_C.h -include/dfhack-c/modules/WindowIO_C.h -include/dfhack-c/modules/World_C.h -) - SET(PROJECT_SRCS +Core.cpp +PluginManager.cpp +TileTypes.cpp VersionInfo.cpp VersionInfoFactory.cpp -DFContextManager.cpp -DFContext.cpp -DFTileTypes.cpp -DFProcessEnumerator.cpp -ContextShared.cpp -DFProcess-SHM.cpp -MicrosoftSTL.cpp +Virtual.cpp depends/md5/md5.cpp depends/md5/md5wrapper.cpp @@ -100,49 +76,29 @@ modules/Gui.cpp modules/Items.cpp modules/Maps.cpp modules/Materials.cpp +modules/Notes.cpp modules/Translation.cpp modules/Vegetation.cpp +modules/Vermin.cpp modules/World.cpp ) -SET(PROJECT_C_SRCS -DFContext_C.cpp -DFProcess_C.cpp -DFTypes_C.cpp -DFTileTypes_C.cpp - -modules/Buildings_C.cpp -modules/Constructions_C.cpp -modules/Creatures_C.cpp -modules/Gui_C.cpp -modules/Items_C.cpp -modules/Maps_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 ) SET(PROJECT_HDRS_WINDOWS -include/dfhack/DFstdint_win.h ) SET(PROJECT_SRCS_LINUX -DFProcess-linux.cpp -DFProcess-linux-base.cpp -DFProcess-linux-SHM.cpp -DFProcess-linux-wine.cpp -modules/WindowIO-linux.cpp +Console-linux.cpp +FakeSDL-linux.cpp +Process-linux.cpp ) SET(PROJECT_SRCS_WINDOWS -DFProcess-windows.cpp -DFProcess-windows-SHM.cpp -modules/WindowIO-windows.cpp +Console-windows.cpp +FakeSDL-windows.cpp +Process-windows.cpp ) IF(UNIX) @@ -153,30 +109,19 @@ ELSE() LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS}) ENDIF() -IF(BUILD_DFHACK_C_BINDINGS) - LIST(APPEND PROJECT_HDRS ${PROJECT_C_HDRS}) - LIST(APPEND PROJECT_SRCS ${PROJECT_C_SRCS}) -ENDIF() - SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) -# Are we 64bit? (Damn you, ptrace()!) -IF( CMAKE_SIZEOF_VOID_P MATCHES 8 ) - ADD_DEFINITIONS(-DHAVE_64_BIT) -ENDIF() - -ADD_DEFINITIONS(-DMEMXML_DATA_PATH="${MEMXML_DATA_PATH}") ADD_DEFINITIONS(-DBUILD_DFHACK_LIB) IF(UNIX) add_definitions(-DLINUX_BUILD) - find_library(X11_LIBRARY X11) SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall") - SET(CMAKE_CXX_FLAGS "-fvisibility=hidden") + SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -m32") + SET(CMAKE_C_FLAGS "-fvisibility=hidden -m32") - SET(PROJECT_LIBS ${X11_LIBRARY} rt ) + SET(PROJECT_LIBS rt ) ELSE() IF(MSVC) SET(PROJECT_LIBS psapi ${dfhack_SOURCE_DIR}/library/depends/ntdll/ntdll.lib) @@ -187,30 +132,59 @@ ENDIF() ADD_LIBRARY(dfhack SHARED ${PROJECT_SRCS}) +IF(WIN32) + SET_TARGET_PROPERTIES(dfhack PROPERTIES OUTPUT_NAME "SDL" ) +ENDIF() + SET_TARGET_PROPERTIES(dfhack PROPERTIES DEBUG_POSTFIX "-debug" ) TARGET_LINK_LIBRARIES(dfhack ${PROJECT_LIBS}) -ADD_CUSTOM_TARGET( memxmlcopy +ADD_CUSTOM_TARGET( prepare DEPENDS ${dfhack_SOURCE_DIR}/Memory.xml -COMMAND ${CMAKE_COMMAND} -E make_directory ${dfhack_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/ -COMMAND ${CMAKE_COMMAND} -E copy ${dfhack_SOURCE_DIR}/Memory.xml ${dfhack_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/) -ADD_DEPENDENCIES(dfhack memxmlcopy) +COMMAND ${CMAKE_COMMAND} -E make_directory ${DFHACK_OUTPUT_DIR} +COMMAND ${CMAKE_COMMAND} -E make_directory ${DFHACK_PLUGIN_OUTPUT_DIR} +COMMAND ${CMAKE_COMMAND} -E copy ${dfhack_SOURCE_DIR}/Memory.xml ${DFHACK_OUTPUT_DIR}) +ADD_DEPENDENCIES(dfhack prepare) +# On linux, copy our version of the df launch script which sets LD_PRELOAD +IF(UNIX) + ADD_CUSTOM_TARGET( prepare_UNIX + DEPENDS ${dfhack_SOURCE_DIR}/package/linux/dfhack + COMMAND ${CMAKE_COMMAND} -E make_directory ${DFHACK_OUTPUT_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${dfhack_SOURCE_DIR}/package/linux/dfhack ${DFHACK_OUTPUT_DIR}) + ADD_DEPENDENCIES(dfhack prepare_UNIX) + install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack + DESTINATION ${DFHACK_LIBRARY_DESTINATION}) +ELSE() +# On windows, copy the renamed SDL so DF can still run. + ADD_CUSTOM_TARGET( prepare_WINDOWS + DEPENDS ${dfhack_SOURCE_DIR}/package/windows/SDLreal.dll + COMMAND ${CMAKE_COMMAND} -E make_directory ${DFHACK_OUTPUT_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${dfhack_SOURCE_DIR}/package/windows/SDLreal.dll ${DFHACK_OUTPUT_DIR}) + ADD_DEPENDENCIES(dfhack prepare_WINDOWS) + install(PROGRAMS ${dfhack_SOURCE_DIR}/package/windows/SDLreal.dll + DESTINATION ${DFHACK_LIBRARY_DESTINATION}) +ENDIF() + install(TARGETS dfhack LIBRARY DESTINATION ${DFHACK_LIBRARY_DESTINATION} RUNTIME DESTINATION ${DFHACK_LIBRARY_DESTINATION}) #linux: lib install(FILES ${dfhack_SOURCE_DIR}/Memory.xml DESTINATION ${DFHACK_DATA_DESTINATION}) #linux: share/dfhack -if(BUILD_DFHACK_DEVEL) +if(BUILD_DEVEL) if(WIN32) install(TARGETS dfhack ARCHIVE DESTINATION ${DFHACK_DEVLIB_DESTINATION}) endif() - # note the ending '/'. This means *constents* of the directory are installed + # note the ending '/'. This means *contents* of the directory are installed # without the '/', the directory itself is installed install(DIRECTORY include/ DESTINATION ${DFHACK_INCLUDES_DESTINATION} FILES_MATCHING PATTERN "*.h" ) #linux: include + # Building the docs + IF(BUILD_DOXYGEN) + add_subdirectory (doc) + ENDIF() endif() diff --git a/library/Console-linux.cpp b/library/Console-linux.cpp new file mode 100644 index 000000000..f96972a90 --- /dev/null +++ b/library/Console-linux.cpp @@ -0,0 +1,751 @@ +/* +https://github.com/peterix/dfhack + +A thread-safe logging console with a line editor. + +Based on linenoise: +linenoise -- guerrilla line editing library against the idea that a +line editing lib needs to be 20,000 lines of C code. + +You can find the latest source code at: + + http://github.com/antirez/linenoise + +Does a number of crazy assumptions that happen to be true in 99.9999% of +the 2010 UNIX computers around. + +------------------------------------------------------------------------ + +Copyright (c) 2010, Salvatore Sanfilippo +Copyright (c) 2010, Pieter Noordhuis +Copyright (c) 2011, Petr Mrázek + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "dfhack/Console.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace DFHack; + +static int isUnsupportedTerm(void) +{ + static const char *unsupported_term[] = {"dumb","cons25",NULL}; + char *term = getenv("TERM"); + int j; + + if (term == NULL) return 0; + for (j = 0; unsupported_term[j]; j++) + if (!strcasecmp(term,unsupported_term[j])) return 1; + return 0; +} + +const char * ANSI_CLS = "\033[2J"; +const char * ANSI_BLACK = "\033[22;30m"; +const char * ANSI_RED = "\033[22;31m"; +const char * ANSI_GREEN = "\033[22;32m"; +const char * ANSI_BROWN = "\033[22;33m"; +const char * ANSI_BLUE = "\033[22;34m"; +const char * ANSI_MAGENTA = "\033[22;35m"; +const char * ANSI_CYAN = "\033[22;36m"; +const char * ANSI_GREY = "\033[22;37m"; +const char * ANSI_DARKGREY = "\033[01;30m"; +const char * ANSI_LIGHTRED = "\033[01;31m"; +const char * ANSI_LIGHTGREEN = "\033[01;32m"; +const char * ANSI_YELLOW = "\033[01;33m"; +const char * ANSI_LIGHTBLUE = "\033[01;34m"; +const char * ANSI_LIGHTMAGENTA = "\033[01;35m"; +const char * ANSI_LIGHTCYAN = "\033[01;36m"; +const char * ANSI_WHITE = "\033[01;37m"; +const char * RESETCOLOR = "\033[0m"; + +const char * getANSIColor(const int c) +{ + switch (c) + { + case -1: return RESETCOLOR; // HACK! :P + case 0 : return ANSI_BLACK; + case 1 : return ANSI_BLUE; // non-ANSI + case 2 : return ANSI_GREEN; + case 3 : return ANSI_CYAN; // non-ANSI + case 4 : return ANSI_RED; // non-ANSI + case 5 : return ANSI_MAGENTA; + case 6 : return ANSI_BROWN; + case 7 : return ANSI_GREY; + case 8 : return ANSI_DARKGREY; + case 9 : return ANSI_LIGHTBLUE; // non-ANSI + case 10: return ANSI_LIGHTGREEN; + case 11: return ANSI_LIGHTCYAN; // non-ANSI; + case 12: return ANSI_LIGHTRED; // non-ANSI; + case 13: return ANSI_LIGHTMAGENTA; + case 14: return ANSI_YELLOW; // non-ANSI + case 15: return ANSI_WHITE; + default: return ""; + } +} + +namespace DFHack +{ + class Private : public std::stringbuf + { + public: + Private() + { + dfout_C = NULL; + rawmode = false; + supported_terminal = false; + state = con_unclaimed; + }; + virtual ~Private() + { + //sync(); + } + protected: + int sync() + { + print(str().c_str()); + str(std::string()); // Clear the string buffer + return 0; + } + public: + /// Print a formatted string, like printf + int print(const char * format, ...) + { + va_list args; + va_start( args, format ); + int ret = vprint( format, args ); + va_end( args ); + return ret; + } + int vprint(const char * format, va_list vl) + { + if(state == con_lineedit) + { + disable_raw(); + fprintf(dfout_C,"\x1b[1G"); + fprintf(dfout_C,"\x1b[0K"); + int ret = vfprintf( dfout_C, format, vl ); + enable_raw(); + prompt_refresh(); + return ret; + } + else return vfprintf( dfout_C, format, vl ); + } + int vprinterr(const char * format, va_list vl) + { + if(state == con_lineedit) + { + disable_raw(); + color(Console::COLOR_LIGHTRED); + fprintf(dfout_C,"\x1b[1G"); + fprintf(dfout_C,"\x1b[0K"); + int ret = vfprintf( dfout_C, format, vl ); + reset_color(); + enable_raw(); + prompt_refresh(); + return ret; + } + else + { + color(Console::COLOR_LIGHTRED); + int ret = vfprintf( dfout_C, format, vl ); + reset_color(); + return ret; + } + } + /// Print a formatted string, like printf, in red + int printerr(const char * format, ...) + { + va_list args; + va_start( args, format ); + int ret = vprinterr( format, args ); + va_end( args ); + return ret; + } + /// Clear the console, along with its scrollback + void clear() + { + if(rawmode) + { + const char * clr = "\033c\033[3J\033[H"; + ::write(STDIN_FILENO,clr,strlen(clr)); + } + else + { + print("\033c\033[3J\033[H"); + fflush(dfout_C); + } + } + /// Position cursor at x,y. 1,1 = top left corner + void gotoxy(int x, int y) + { + print("\033[%d;%dH", y,x); + } + /// Set color (ANSI color number) + void color(Console::color_value index) + { + if(!rawmode) + fprintf(dfout_C,getANSIColor(index)); + else + { + const char * colstr = getANSIColor(index); + int lstr = strlen(colstr); + ::write(STDIN_FILENO,colstr,lstr); + } + } + /// Reset color to default + void reset_color(void) + { + color(Console::COLOR_RESET); + if(!rawmode) + fflush(dfout_C); + } + /// Enable or disable the caret/cursor + void cursor(bool enable = true) + { + if(enable) + print("\033[?25h"); + else + print("\033[?25l"); + } + /// Waits given number of milliseconds before continuing. + void msleep(unsigned int msec); + /// get the current number of columns + int get_columns(void) + { + winsize ws; + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 80; + return ws.ws_col; + } + /// get the current number of rows + int get_rows(void) + { + winsize ws; + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) return 25; + return ws.ws_row; + } + /// beep. maybe? + //void beep (void); + /// A simple line edit (raw mode) + int lineedit(const std::string& prompt, std::string& output, SDL::Mutex * lock) + { + output.clear(); + this->prompt = prompt; + if (!supported_terminal) + { + print(prompt.c_str()); + fflush(dfout_C); + // FIXME: what do we do here??? + //SDL_mutexV(lock); + std::getline(std::cin, output); + //SDL_mutexP(lock); + return output.size(); + } + else + { + int count; + if (enable_raw() == -1) return 0; + if(state == con_lineedit) + return -1; + state = con_lineedit; + count = prompt_loop(lock); + state = con_unclaimed; + disable_raw(); + print("\n"); + if(count != -1) + { + output = raw_buffer; + } + return count; + } + } + /// add a command to the history + void history_add(const std::string& command) + { + // if current command = last in history -> do not add. Always add if history is empty. + if(!history.empty() && history.front() == command) + return; + history.push_front(command); + if(history.size() > 100) + history.pop_back(); + } + /// clear the command history + void history_clear(); + + int enable_raw() + { + struct termios raw; + + if (!supported_terminal) + return -1; + if (tcgetattr(STDIN_FILENO,&orig_termios) == -1) + return -1; + + raw = orig_termios; //modify the original mode + // input modes: no break, no CR to NL, no parity check, no strip char, + // no start/stop output control. + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + // output modes - disable post processing + raw.c_oflag &= ~(OPOST); + // control modes - set 8 bit chars + raw.c_cflag |= (CS8); + // local modes - choing off, canonical off, no extended functions, + // no signal chars (^Z,^C) + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + // control chars - set return condition: min number of bytes and timer. + // We want read to return every single byte, without timeout. + raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0;// 1 byte, no timer + // put terminal in raw mode after flushing + if (tcsetattr(STDIN_FILENO,TCSAFLUSH,&raw) < 0) + return -1; + rawmode = 1; + return 0; + } + + void disable_raw() + { + /* Don't even check the return value as it's too late. */ + if (rawmode && tcsetattr(STDIN_FILENO,TCSAFLUSH,&orig_termios) != -1) + rawmode = 0; + } + void prompt_refresh() + { + char seq[64]; + int cols = get_columns(); + int plen = prompt.size(); + const char * buf = raw_buffer.c_str(); + int len = raw_buffer.size(); + int cooked_cursor = raw_cursor; + // Use math! This is silly. + while((plen+cooked_cursor) >= cols) + { + buf++; + len--; + cooked_cursor--; + } + while (plen+len > cols) + { + len--; + } + /* Cursor to left edge */ + snprintf(seq,64,"\x1b[1G"); + if (::write(STDIN_FILENO,seq,strlen(seq)) == -1) return; + /* Write the prompt and the current buffer content */ + if (::write(STDIN_FILENO,prompt.c_str(),plen) == -1) return; + if (::write(STDIN_FILENO,buf,len) == -1) return; + /* Erase to right */ + snprintf(seq,64,"\x1b[0K"); + if (::write(STDIN_FILENO,seq,strlen(seq)) == -1) return; + /* Move cursor to original position. */ + snprintf(seq,64,"\x1b[1G\x1b[%dC", (int)(cooked_cursor+plen)); + if (::write(STDIN_FILENO,seq,strlen(seq)) == -1) return; + } + + int prompt_loop(SDL::Mutex * lock) + { + int fd = STDIN_FILENO; + size_t plen = prompt.size(); + int history_index = 0; + raw_buffer.clear(); + raw_cursor = 0; + /* The latest history entry is always our current buffer, that + * initially is just an empty string. */ + const std::string empty; + history_add(empty); + if (::write(fd,prompt.c_str(),prompt.size()) == -1) return -1; + while(1) + { + char c; + int nread; + char seq[2], seq2; + SDL_mutexV(lock); + nread = ::read(fd,&c,1); + SDL_mutexP(lock); + if (nread <= 0) return raw_buffer.size(); + + /* Only autocomplete when the callback is set. It returns < 0 when + * there was an error reading from fd. Otherwise it will return the + * character that should be handled next. */ + if (c == 9) + { + /* + if( completionCallback != NULL) { + c = completeLine(fd,prompt,buf,buflen,&len,&pos,cols); + // Return on errors + if (c < 0) return len; + // Read next character when 0 + if (c == 0) continue; + } + else + { + // ignore tab + continue; + } + */ + // just ignore tabs + continue; + } + + switch(c) + { + case 13: // enter + history.pop_front(); + return raw_buffer.size(); + case 3: // ctrl-c + errno = EAGAIN; + return -1; + case 127: // backspace + case 8: // ctrl-h + if (raw_cursor > 0 && raw_buffer.size() > 0) + { + raw_buffer.erase(raw_cursor-1,1); + raw_cursor--; + prompt_refresh(); + } + break; + case 27: // escape sequence + SDL_mutexV(lock); + if (::read(fd,seq,2) == -1) + { + SDL_mutexP(lock); + break; + } + SDL_mutexP(lock); + if(seq[0] == '[') + { + if (seq[1] == 'D') + { + left_arrow: + if (raw_cursor > 0) + { + raw_cursor--; + prompt_refresh(); + } + } + else if ( seq[1] == 'C') + { + right_arrow: + /* right arrow */ + if (raw_cursor != raw_buffer.size()) + { + raw_cursor++; + prompt_refresh(); + } + } + else if (seq[1] == 'A' || seq[1] == 'B') + { + /* up and down arrow: history */ + if (history.size() > 1) + { + /* Update the current history entry before to + * overwrite it with tne next one. */ + history[history_index] = raw_buffer; + /* Show the new entry */ + history_index += (seq[1] == 'A') ? 1 : -1; + if (history_index < 0) + { + history_index = 0; + break; + } + else if (history_index >= history.size()) + { + history_index = history.size()-1; + break; + } + raw_buffer = history[history_index]; + raw_cursor = raw_buffer.size(); + prompt_refresh(); + } + } + else if(seq[1] == 'H') + { + // home + raw_cursor = 0; + prompt_refresh(); + } + else if(seq[1] == 'F') + { + // end + raw_cursor = raw_buffer.size(); + prompt_refresh(); + } + else if (seq[1] > '0' && seq[1] < '7') + { + // extended escape + SDL_mutexV(lock); + if (::read(fd,&seq2,1) == -1) + { + SDL_mutexP(lock); + break; + } + SDL_mutexP(lock); + if (seq[1] == '3' && seq2 == '~' ) + { + // delete + if (raw_buffer.size() > 0 && raw_cursor < raw_buffer.size()) + { + raw_buffer.erase(raw_cursor,1); + prompt_refresh(); + } + } + } + } + break; + default: + if (raw_buffer.size() == raw_cursor) + { + raw_buffer.append(1,c); + raw_cursor++; + if (plen+raw_buffer.size() < get_columns()) + { + /* Avoid a full update of the line in the + * trivial case. */ + if (::write(fd,&c,1) == -1) return -1; + } + else + { + prompt_refresh(); + } + } + else + { + raw_buffer.insert(raw_cursor,1,c); + raw_cursor++; + prompt_refresh(); + } + break; + case 21: // Ctrl+u, delete the whole line. + raw_buffer.clear(); + raw_cursor = 0; + prompt_refresh(); + break; + case 11: // Ctrl+k, delete from current to end of line. + raw_buffer.erase(raw_cursor); + prompt_refresh(); + break; + case 1: // Ctrl+a, go to the start of the line + raw_cursor = 0; + prompt_refresh(); + break; + case 5: // ctrl+e, go to the end of the line + raw_cursor = raw_buffer.size(); + prompt_refresh(); + break; + case 12: // ctrl+l, clear screen + clear(); + prompt_refresh(); + } + } + return raw_buffer.size(); + } + FILE * dfout_C; + std::deque history; + bool supported_terminal; + // state variables + bool rawmode; // is raw mode active? + termios orig_termios; // saved/restored by raw mode + // current state + enum console_state + { + con_unclaimed, + con_lineedit + } state; + std::string prompt; // current prompt string + std::string raw_buffer; // current raw mode buffer + int raw_cursor; // cursor position in the buffer + }; +} + +Console::Console():std::ostream(0), std::ios(0) +{ + d = 0; + inited = false; + // we can't create the mutex at this time. the SDL functions aren't hooked yet. + wlock = 0; +} +Console::~Console() +{ + if(inited) + shutdown(); + if(wlock) + SDL_DestroyMutex(wlock); + if(d) + delete d; +} + +bool Console::init(void) +{ + d = new Private(); + // make our own weird streams so our IO isn't redirected + d->dfout_C = fopen("/dev/tty", "w"); + wlock = SDL_CreateMutex(); + rdbuf(d); + std::cin.tie(this); + clear(); + d->supported_terminal = !isUnsupportedTerm() && isatty(STDIN_FILENO); + inited = true; +} + +bool Console::shutdown(void) +{ + SDL_mutexP(wlock); + if(d->rawmode) + d->disable_raw(); + print("\n"); + inited = false; + SDL_mutexV(wlock); + return true; +} + +int Console::print( const char* format, ... ) +{ + va_list args; + SDL_mutexP(wlock); + int ret; + if(!inited) ret = -1; + else + { + va_start( args, format ); + ret = d->vprint(format, args); + va_end(args); + } + SDL_mutexV(wlock); + return ret; +} + +int Console::printerr( const char* format, ... ) +{ + va_list args; + SDL_mutexP(wlock); + int ret; + if(!inited) ret = -1; + else + { + va_start( args, format ); + ret = d->vprinterr(format, args); + va_end(args); + } + SDL_mutexV(wlock); + return ret; +} + +int Console::get_columns(void) +{ + SDL_mutexP(wlock); + int ret = -1; + if(inited) + ret = d->get_columns(); + SDL_mutexV(wlock); + return ret; +} + +int Console::get_rows(void) +{ + SDL_mutexP(wlock); + int ret = -1; + if(inited) + ret = d->get_rows(); + SDL_mutexV(wlock); + return ret; +} + +void Console::clear() +{ + SDL_mutexP(wlock); + if(inited) + d->clear(); + SDL_mutexV(wlock); +} + +void Console::gotoxy(int x, int y) +{ + SDL_mutexP(wlock); + if(inited) + d->gotoxy(x,y); + SDL_mutexV(wlock); +} + +void Console::color(color_value index) +{ + SDL_mutexP(wlock); + if(inited) + d->color(index); + SDL_mutexV(wlock); +} + +void Console::reset_color( void ) +{ + SDL_mutexP(wlock); + if(inited) + d->reset_color(); + SDL_mutexV(wlock); +} + +void Console::cursor(bool enable) +{ + SDL_mutexP(wlock); + if(inited) + d->cursor(enable); + SDL_mutexV(wlock); +} + +// push to front, remove from back if we are above maximum. ignore immediate duplicates +void Console::history_add(const std::string & command) +{ + SDL_mutexP(wlock); + if(inited) + d->history_add(command); + SDL_mutexV(wlock); +} + +int Console::lineedit(const std::string & prompt, std::string & output) +{ + SDL_mutexP(wlock); + int ret = -2; + if(inited) + ret = d->lineedit(prompt,output,wlock); + SDL_mutexV(wlock); + return ret; +} + +void Console::msleep (unsigned int msec) +{ + if (msec > 1000) sleep(msec/1000000); + usleep((msec % 1000000) * 1000); +} \ No newline at end of file diff --git a/library/Console-windows.cpp b/library/Console-windows.cpp new file mode 100644 index 000000000..64b6b4f95 --- /dev/null +++ b/library/Console-windows.cpp @@ -0,0 +1,588 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2011 Petr Mrázek + +A thread-safe logging console with a line editor for windows. + +Based on linenoise win32 port, +copyright 2010, Jon Griffiths . +All rights reserved. +Based on linenoise, copyright 2010, Salvatore Sanfilippo . +The original linenoise can be found at: http://github.com/antirez/linenoise + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Redis nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dfhack/Console.h" +#include "dfhack/FakeSDL.h" +#include +#include +#include +#include +using namespace DFHack; + +// FIXME: maybe make configurable with an ini option? +#define MAX_CONSOLE_LINES 999; + +namespace DFHack +{ + class Private : public std::stringbuf + { + public: + Private() : basic_stringbuf::basic_stringbuf() + { + dfout_C = 0; + rawmode = 0; + console_in = 0; + console_out = 0; + ConsoleWindow = 0; + default_attributes = 0; + state = con_unclaimed; + raw_cursor = 0; + }; + virtual ~Private() + { + //sync(); + } + protected: + int sync() + { + print (str().c_str()); + // Clear the string buffer + str(std::string()); + return 0; + } + public: + /// Print a formatted string, like printf + int print(const char * format, ...) + { + va_list args; + va_start( args, format ); + int ret = vprint( format, args ); + va_end( args ); + return ret; + } + int vprint(const char * format, va_list vl) + { + if(state == con_lineedit) + { + clearline(); + int ret = vfprintf( dfout_C, format, vl ); + prompt_refresh(); + return ret; + } + else return vfprintf( dfout_C, format, vl ); + } + int vprinterr(const char * format, va_list vl) + { + if(state == con_lineedit) + { + color(Console::COLOR_LIGHTRED); + clearline(); + int ret = vfprintf( dfout_C, format, vl ); + reset_color(); + prompt_refresh(); + return ret; + } + else + { + color(Console::COLOR_LIGHTRED); + int ret = vfprintf( dfout_C, format, vl ); + reset_color(); + return ret; + } + } + /// Print a formatted string, like printf, in red + int printerr(const char * format, ...) + { + va_list args; + va_start( args, format ); + int ret = vprinterr( format, args ); + va_end( args ); + return ret; + } + int get_columns(void) + { + CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; + GetConsoleScreenBufferInfo(console_out, &inf); + return (size_t)inf.dwSize.X; + } + int get_rows(void) + { + CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; + GetConsoleScreenBufferInfo(console_out, &inf); + return (size_t)inf.dwSize.Y; + } + void clear() + { + system("cls"); + } + void clearline() + { + CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; + GetConsoleScreenBufferInfo(console_out, &inf); + // Blank to EOL + char* tmp = (char*)malloc(inf.dwSize.X); + memset(tmp, ' ', inf.dwSize.X); + output(tmp, inf.dwSize.X, 0, inf.dwCursorPosition.Y); + free(tmp); + COORD coord = {0, inf.dwCursorPosition.Y}; // Windows uses 0-based coordinates + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); + } + void gotoxy(int x, int y) + { + COORD coord = {x-1, y-1}; // Windows uses 0-based coordinates + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); + } + + void color(int index) + { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, index); + } + + void reset_color( void ) + { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, default_attributes); + } + + void cursor(bool enable) + { + if(enable) + { + HANDLE hConsoleOutput; + CONSOLE_CURSOR_INFO structCursorInfo; + hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE ); + GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size + structCursorInfo.bVisible = TRUE; + SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); + } + else + { + HANDLE hConsoleOutput; + CONSOLE_CURSOR_INFO structCursorInfo; + hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE ); + GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size + structCursorInfo.bVisible = FALSE; + SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); + } + } + + void output(const char* str, size_t len, int x, int y) + { + COORD pos = { (SHORT)x, (SHORT)y }; + DWORD count = 0; + WriteConsoleOutputCharacterA(console_out, str, len, pos, &count); + } + + void prompt_refresh() + { + size_t cols = get_columns(); + size_t plen = prompt.size(); + const char * buf = raw_buffer.c_str(); + size_t len = raw_buffer.size(); + + while ((plen + raw_cursor) >= cols) + { + buf++; + len--; + raw_cursor--; + } + while (plen + len > cols) + { + len--; + } + + CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; + GetConsoleScreenBufferInfo(console_out, &inf); + output(prompt.c_str(), plen, 0, inf.dwCursorPosition.Y); + output(buf, len, plen, inf.dwCursorPosition.Y); + if (plen + len < (size_t)inf.dwSize.X) + { + // Blank to EOL + char* tmp = (char*)malloc(inf.dwSize.X - (plen + len)); + memset(tmp, ' ', inf.dwSize.X - (plen + len)); + output(tmp, inf.dwSize.X - (plen + len), len + plen, inf.dwCursorPosition.Y); + free(tmp); + } + inf.dwCursorPosition.X = (SHORT)(raw_cursor + plen); + SetConsoleCursorPosition(console_out, inf.dwCursorPosition); + } + + int prompt_loop(SDL::Mutex * lock) + { + raw_buffer.clear(); // make sure the buffer is empty! + size_t plen = prompt.size(); + raw_cursor = 0; + int history_index = 0; + // The latest history entry is always our current buffer, that + // initially is just an empty string. + const std::string empty; + history_add(empty); + + CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; + GetConsoleScreenBufferInfo(console_out, &inf); + size_t cols = inf.dwSize.X; + output(prompt.c_str(), plen, 0, inf.dwCursorPosition.Y); + inf.dwCursorPosition.X = (SHORT)plen; + SetConsoleCursorPosition(console_out, inf.dwCursorPosition); + + while (1) + { + INPUT_RECORD rec; + DWORD count; + SDL_mutexV(lock); + ReadConsoleInputA(console_in, &rec, 1, &count); + SDL_mutexP(lock); + if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown) + continue; + switch (rec.Event.KeyEvent.wVirtualKeyCode) + { + case VK_RETURN: // enter + history.pop_front(); + return raw_buffer.size(); + case VK_BACK: // backspace + if (raw_cursor > 0 && raw_buffer.size() > 0) + { + raw_buffer.erase(raw_cursor-1,1); + raw_cursor--; + prompt_refresh(); + } + break; + case VK_LEFT: // left arrow + if (raw_cursor > 0) + { + raw_cursor--; + prompt_refresh(); + } + break; + case VK_RIGHT: // right arrow + if (raw_cursor != raw_buffer.size()) + { + raw_cursor++; + prompt_refresh(); + } + break; + case VK_UP: + case VK_DOWN: + // up and down arrow: history + if (history.size() > 1) + { + // Update the current history entry before to + // overwrite it with tne next one. + history[history_index] = raw_buffer; + // Show the new entry + history_index += (rec.Event.KeyEvent.wVirtualKeyCode == VK_UP) ? 1 : -1; + if (history_index < 0) + { + history_index = 0; + break; + } + else if (history_index >= history.size()) + { + history_index = history.size()-1; + break; + } + raw_buffer = history[history_index]; + raw_cursor = raw_buffer.size(); + prompt_refresh(); + } + break; + case VK_DELETE: + // delete + if (raw_buffer.size() > 0 && raw_cursor < raw_buffer.size()) + { + raw_buffer.erase(raw_cursor,1); + prompt_refresh(); + } + break; + case VK_HOME: + raw_cursor = 0; + prompt_refresh(); + break; + case VK_END: + raw_cursor = raw_buffer.size(); + prompt_refresh(); + break; + default: + if (rec.Event.KeyEvent.uChar.AsciiChar < ' ' || + rec.Event.KeyEvent.uChar.AsciiChar > '~') + continue; + if (raw_buffer.size() == raw_cursor) + raw_buffer.append(1,rec.Event.KeyEvent.uChar.AsciiChar); + else + raw_buffer.insert(raw_cursor,1,rec.Event.KeyEvent.uChar.AsciiChar); + raw_cursor++; + prompt_refresh(); + break; + } + } + } + int lineedit(const std::string & prompt, std::string & output, SDL::Mutex*lock) + { + output.clear(); + int count; + state = con_lineedit; + this->prompt = prompt; + count = prompt_loop(lock); + if(count != -1) + output = raw_buffer; + state = con_unclaimed; + print("\n"); + return count; + } + + // push to front, remove from back if we are above maximum. ignore immediate duplicates + void history_add(const std::string & command) + { + // if current command = last in history -> do not add. Always add if history is empty. + if(!history.empty() && history.front() == command) + return; + history.push_front(command); + if(history.size() > 100) + history.pop_back(); + } + + FILE * dfout_C; + int rawmode; /* for atexit() function to check if restore is needed*/ + std::deque history; + + HANDLE console_in; + HANDLE console_out; + HWND ConsoleWindow; + WORD default_attributes; + // current state + enum console_state + { + con_unclaimed, + con_lineedit + } state; + std::string prompt; // current prompt string + std::string raw_buffer; // current raw mode buffer + int raw_cursor; // cursor position in the buffer + }; +} + + +Console::Console():std::ostream(0), std::ios(0) +{ + d = 0; + wlock = 0; + inited = false; +} + +Console::~Console() +{ +} + +bool Console::init(void) +{ + d = new Private(); + int hConHandle; + long lStdHandle; + CONSOLE_SCREEN_BUFFER_INFO coninfo; + FILE *fp; + DWORD oldMode, newMode; + + // Allocate a console! + AllocConsole(); + d->ConsoleWindow = GetConsoleWindow(); + wlock = SDL_CreateMutex(); + HMENU hm = GetSystemMenu(d->ConsoleWindow,false); + DeleteMenu(hm, SC_CLOSE, MF_BYCOMMAND); + + // set the screen buffer to be big enough to let us scroll text + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); + d->default_attributes = coninfo.wAttributes; + coninfo.dwSize.Y = MAX_CONSOLE_LINES; // How many lines do you want to have in the console buffer + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); + + // redirect unbuffered STDOUT to the console + d->console_out = GetStdHandle(STD_OUTPUT_HANDLE); + lStdHandle = (long)d->console_out; + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + d->dfout_C = _fdopen( hConHandle, "w" ); + setvbuf( d->dfout_C, NULL, _IONBF, 0 ); + + // redirect unbuffered STDIN to the console + d->console_in = GetStdHandle(STD_INPUT_HANDLE); + lStdHandle = (long)d->console_in; + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "r" ); + *stdin = *fp; + setvbuf( stdin, NULL, _IONBF, 0 ); + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),&oldMode); + newMode = oldMode | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT; + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),newMode); + SetConsoleCtrlHandler(NULL,true); + std::ios::sync_with_stdio(); + + // make our own weird streams so our IO isn't redirected + rdbuf(d); + std::cin.tie(this); + clear(); + inited = true; + return true; +} +// FIXME: looks awfully empty, doesn't it? +bool Console::shutdown(void) +{ + SDL_mutexP(wlock); + FreeConsole(); + inited = false; + SDL_mutexV(wlock); + return true; +} +int Console::print( const char* format, ... ) +{ + va_list args; + SDL_mutexP(wlock); + int ret; + if(!inited) ret = -1; + else + { + va_start( args, format ); + ret = d->vprint(format, args); + va_end(args); + } + SDL_mutexV(wlock); + return ret; +} + +int Console::printerr( const char* format, ... ) +{ + va_list args; + SDL_mutexP(wlock); + int ret; + if(!inited) ret = -1; + else + { + va_start( args, format ); + ret = d->vprinterr(format, args); + va_end(args); + } + SDL_mutexV(wlock); + return ret; +} + +int Console::get_columns(void) +{ + SDL_mutexP(wlock); + int ret = -1; + if(inited) + ret = d->get_columns(); + SDL_mutexV(wlock); + return ret; +} + +int Console::get_rows(void) +{ + SDL_mutexP(wlock); + int ret = -1; + if(inited) + ret = d->get_rows(); + SDL_mutexV(wlock); + return ret; +} + +void Console::clear() +{ + SDL_mutexP(wlock); + if(inited) + d->clear(); + SDL_mutexV(wlock); +} + +void Console::gotoxy(int x, int y) +{ + SDL_mutexP(wlock); + if(inited) + d->gotoxy(x,y); + SDL_mutexV(wlock); +} + +void Console::color(color_value index) +{ + SDL_mutexP(wlock); + if(inited) + d->color(index); + SDL_mutexV(wlock); +} + +void Console::reset_color( void ) +{ + SDL_mutexP(wlock); + if(inited) + d->reset_color(); + SDL_mutexV(wlock); +} + +void Console::cursor(bool enable) +{ + SDL_mutexP(wlock); + if(inited) + d->cursor(enable); + SDL_mutexV(wlock); +} + +// push to front, remove from back if we are above maximum. ignore immediate duplicates +void Console::history_add(const std::string & command) +{ + SDL_mutexP(wlock); + if(inited) + d->history_add(command); + SDL_mutexV(wlock); +} + +int Console::lineedit(const std::string & prompt, std::string & output) +{ + SDL_mutexP(wlock); + int ret = -2; + if(inited) + ret = d->lineedit(prompt,output,wlock); + SDL_mutexV(wlock); + return ret; +} + +void Console::msleep (unsigned int msec) +{ + Sleep(msec); +} diff --git a/library/ContextShared.cpp b/library/ContextShared.cpp deleted file mode 100644 index 1aaed1d1c..000000000 --- a/library/ContextShared.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "Internal.h" - -#include -#include -#include -#include -using namespace std; - -#include "private/ContextShared.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFModule.h" -using namespace DFHack; - -DFContextShared::DFContextShared() -{ - // init modules - allModules.clear(); - memset(&(s_mods), 0, sizeof(s_mods)); - namesInited = false; - namesFailed = false; -} - -DFContextShared::~DFContextShared() -{ - // invalidate all modules - for(unsigned int i = 0 ; i < allModules.size(); i++) - { - delete allModules[i]; - } - allModules.clear(); -} - -bool DFContextShared::InitReadNames() -{ - try - { - OffsetGroup * OG = offset_descriptor->getGroup("name"); - name_firstname_offset = OG->getOffset("first"); - name_nickname_offset = OG->getOffset("nick"); - name_words_offset = OG->getOffset("second_words"); - name_parts_offset = OG->getOffset("parts_of_speech"); - name_language_offset = OG->getOffset("language"); - name_set_offset = OG->getOffset("has_name"); - } - catch(exception &) - { - namesFailed = true; - return false; - } - namesInited = true; - return true; -} - -void DFContextShared::readName(t_name & name, uint32_t address) -{ - if(namesFailed) - { - return; - } - if(!namesInited) - { - if(!InitReadNames()) return; - } - p->readSTLString(address + name_firstname_offset , name.first_name, 128); - p->readSTLString(address + name_nickname_offset , name.nickname, 128); - p->read(address + name_words_offset, 7*4, (uint8_t *)name.words); - p->read(address + name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech); - name.language = p->readDWord(address + name_language_offset); - name.has_name = p->readByte(address + name_set_offset); -} - -void DFContextShared::copyName(uint32_t address, uint32_t target) -{ - uint8_t buf[28]; - - if (address == target) - return; - - p->copySTLString(address + name_firstname_offset, target + name_firstname_offset); - p->copySTLString(address + name_nickname_offset, target + name_nickname_offset); - p->read(address + name_words_offset, 7*4, buf); - p->write(target + name_words_offset, 7*4, buf); - p->read(address + name_parts_offset, 7*2, buf); - p->write(target + name_parts_offset, 7*2, buf); - p->writeDWord(target + name_language_offset, p->readDWord(address + name_language_offset)); - p->writeByte(target + name_set_offset, p->readByte(address + name_set_offset)); -} diff --git a/library/Core.cpp b/library/Core.cpp new file mode 100644 index 000000000..33ee910d4 --- /dev/null +++ b/library/Core.cpp @@ -0,0 +1,599 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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 +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "dfhack/Error.h" +#include "dfhack/Process.h" +#include "dfhack/Core.h" +#include "dfhack/Console.h" +#include "dfhack/Module.h" +#include "dfhack/VersionInfoFactory.h" +#include "dfhack/PluginManager.h" +#include "ModuleFactory.h" +#include "dfhack/modules/Gui.h" +#include "dfhack/modules/World.h" + +#include "dfhack/SDL_fakes/events.h" + +#include +#include +#include +using namespace DFHack; + + struct Core::Cond + { + Cond() + { + predicate = false; + wakeup = SDL_CreateCond(); + } + ~Cond() + { + SDL_DestroyCond(wakeup); + } + bool Lock(SDL::Mutex * m) + { + while(!predicate) + { + SDL_CondWait(wakeup,m); + } + predicate = false; + return true; + } + bool Unlock() + { + predicate = true; + SDL_CondSignal(wakeup); + return true; + } + SDL::Cond * wakeup; + bool predicate; + }; + +void cheap_tokenise(string const& input, vector &output) +{ + istringstream str(input); + istream_iterator cur(str), end; + output.assign(cur, end); +} + +struct IODATA +{ + Core * core; + PluginManager * plug_mgr; +}; + +// A thread function... for handling hotkeys. This is needed because +// all the plugin commands are expected to be run from foreign threads. +// Running them from one of the main DF threads will result in deadlock! +int fHKthread(void * iodata) +{ + Core * core = ((IODATA*) iodata)->core; + PluginManager * plug_mgr = ((IODATA*) iodata)->plug_mgr; + if(plug_mgr == 0 || core == 0) + { + cerr << "Hotkey thread has croaked." << endl; + return 0; + } + while(1) + { + std::string stuff = core->getHotkeyCmd(); // waits on mutex! + if(!stuff.empty()) + { + vector crap; + plug_mgr->InvokeCommand(stuff, crap); + } + } +} + +// A thread function... for the interactive console. +int fIOthread(void * iodata) +{ + IODATA * iod = ((IODATA*) iodata); + Core * core = iod->core; + PluginManager * plug_mgr = ((IODATA*) iodata)->plug_mgr; + Console & con = core->con; + if(plug_mgr == 0 || core == 0) + { + con.printerr("Something horrible happened in Core's constructor...\n"); + return 0; + } + con.print("DFHack is ready. Have a nice day!\n" + "Type in '?' or 'help' for general help, 'ls' to see all commands.\n"); + int clueless_counter = 0; + while (true) + { + string command = ""; + int ret = con.lineedit("[DFHack]# ",command); + if(ret == -2) + { + cerr << "Console is shutting down properly." << endl; + return 0; + } + else if(ret == -1) + { + cerr << "Console caught an unspecified error." << endl; + continue; + } + else if(ret) + { + // a proper, non-empty command was entered + con.history_add(command); + } + // cut the input into parts + vector parts; + cheap_tokenise(command,parts); + if(parts.size() == 0) + { + clueless_counter ++; + continue; + } + string first = parts[0]; + parts.erase(parts.begin()); + // let's see what we actually got + if(first=="help" || first == "?") + { + if(!parts.size()) + { + con.print("This is the DFHack console. You can type commands in and manage DFHack plugins from it.\n" + "Some basic editing capabilities are included (single-line text editing).\n" + "The console also has a command history - you can navigate it with Up and Down keys.\n" + "On Windows, you may have to resize your console window. The appropriate menu is accessible\n" + "by clicking on the program icon in the top bar of the window.\n\n" + "Basic commands:\n" + " help|? - This text.\n" + " ls|dir [PLUGIN] - List available commands. Optionally for single plugin.\n" + " cls - Clear the console.\n" + " fpause - Force DF to pause.\n" + " die - Force DF to close immediately\n" + "Plugin management (useful for developers):\n" + //" belongs COMMAND - Tell which plugin a command belongs to.\n" + " plug [PLUGIN|v] - List plugin state and description.\n" + " load PLUGIN|all - Load a plugin by name or load all possible plugins.\n" + " unload PLUGIN|all - Unload a plugin or all loaded plugins.\n" + " reload PLUGIN|all - Reload a plugin or all loaded plugins.\n" + ); + } + else + { + con.printerr("not implemented yet\n"); + } + } + else if( first == "load" ) + { + if(parts.size()) + { + string & plugname = parts[0]; + if(plugname == "all") + { + for(int i = 0; i < plug_mgr->size();i++) + { + Plugin * plug = (plug_mgr->operator[](i)); + plug->load(); + } + } + else + { + Plugin * plug = plug_mgr->getPluginByName(plugname); + if(!plug) con.printerr("No such plugin\n"); + plug->load(); + } + } + } + else if( first == "reload" ) + { + if(parts.size()) + { + string & plugname = parts[0]; + if(plugname == "all") + { + for(int i = 0; i < plug_mgr->size();i++) + { + Plugin * plug = (plug_mgr->operator[](i)); + plug->reload(); + } + } + else + { + Plugin * plug = plug_mgr->getPluginByName(plugname); + if(!plug) con.printerr("No such plugin\n"); + plug->reload(); + } + } + } + else if( first == "unload" ) + { + if(parts.size()) + { + string & plugname = parts[0]; + if(plugname == "all") + { + for(int i = 0; i < plug_mgr->size();i++) + { + Plugin * plug = (plug_mgr->operator[](i)); + plug->unload(); + } + } + else + { + Plugin * plug = plug_mgr->getPluginByName(plugname); + if(!plug) con.printerr("No such plugin\n"); + plug->unload(); + } + } + } + else if(first == "ls" || first == "dir") + { + if(parts.size()) + { + string & plugname = parts[0]; + const Plugin * plug = plug_mgr->getPluginByName(plugname); + if(!plug) + { + con.printerr("There's no plugin called %s!\n",plugname.c_str()); + } + else for (int j = 0; j < plug->size();j++) + { + const PluginCommand & pcmd = (plug->operator[](j)); + con.print(" %-22s - %s\n",pcmd.name.c_str(), pcmd.description.c_str()); + } + } + else + { + con.print( + "builtin:\n" + " help|? - This text or help specific to a plugin.\n" + " ls [PLUGIN] - List available commands. Optionally for single plugin.\n" + " cls - Clear the console.\n" + " fpause - Force DF to pause.\n" + " die - Force DF to close immediately\n" + " belongs COMMAND - Tell which plugin a command belongs to.\n" + " plug [PLUGIN|v] - List plugin state and detailed description.\n" + " load PLUGIN|all - Load a plugin by name or load all possible plugins.\n" + " unload PLUGIN|all - Unload a plugin or all loaded plugins.\n" + " reload PLUGIN|all - Reload a plugin or all loaded plugins.\n" + "\n" + "plugins:\n" + ); + for(int i = 0; i < plug_mgr->size();i++) + { + const Plugin * plug = (plug_mgr->operator[](i)); + if(!plug->size()) + continue; + for (int j = 0; j < plug->size();j++) + { + const PluginCommand & pcmd = (plug->operator[](j)); + con.print(" %-22s- %s\n",pcmd.name.c_str(), pcmd.description.c_str()); + } + } + } + } + else if(first == "plug") + { + for(int i = 0; i < plug_mgr->size();i++) + { + const Plugin * plug = (plug_mgr->operator[](i)); + if(!plug->size()) + continue; + con.print("%s\n", plug->getName().c_str()); + } + } + else if(first == "fpause") + { + World * w = core->getWorld(); + w->SetPauseState(true); + con.print("The game was forced to pause!"); + } + else if(first == "cls") + { + con.clear(); + } + else if(first == "die") + { + _exit(666); + } + else + { + vector parts; + cheap_tokenise(command,parts); + if(parts.size() == 0) + { + clueless_counter++; + } + else + { + string first = parts[0]; + parts.erase(parts.begin()); + command_result res = plug_mgr->InvokeCommand(first, parts); + if(res == CR_NOT_IMPLEMENTED) + { + con.printerr("Invalid command.\n"); + clueless_counter ++; + } + /* + else if(res == CR_FAILURE) + { + con.printerr("ERROR!\n"); + } + */ + } + } + if(clueless_counter == 3) + { + con.print("Do 'help' or '?' for the list of available commands.\n"); + clueless_counter = 0; + } + } +} + +Core::Core() +{ + // init the console. This must be always the first step! + plug_mgr = 0; + vif = 0; + p = 0; + errorstate = false; + vinfo = 0; + started = false; + memset(&(s_mods), 0, sizeof(s_mods)); + + // create mutex for syncing with interactive tasks + AccessMutex = 0; + core_cond = 0; + // set up hotkey capture + memset(hotkey_states,0,sizeof(hotkey_states)); + hotkey_set = false; + HotkeyMutex = 0; + HotkeyCond = 0; +}; + +bool Core::Init() +{ + // init the console. This must be always the first step! + con.init(); + // find out what we are... + vif = new DFHack::VersionInfoFactory("Memory.xml"); + p = new DFHack::Process(vif); + if (!p->isIdentified()) + { + con.printerr("Couldn't identify this version of DF.\n"); + errorstate = true; + delete p; + p = NULL; + return false; + } + vinfo = p->getDescriptor(); + + // create mutex for syncing with interactive tasks + AccessMutex = SDL_CreateMutex(); + if(!AccessMutex) + { + con.printerr("Mutex creation failed\n"); + errorstate = true; + return false; + } + core_cond = new Core::Cond(); + // create plugin manager + plug_mgr = new PluginManager(this); + if(!plug_mgr) + { + con.printerr("Failed to create the Plugin Manager.\n"); + errorstate = true; + return false; + } + // look for all plugins, + // create IO thread + IODATA *temp = new IODATA; + temp->core = this; + temp->plug_mgr = plug_mgr; + SDL::Thread * IO = SDL_CreateThread(fIOthread, (void *) temp); + // set up hotkey capture + HotkeyMutex = SDL_CreateMutex(); + HotkeyCond = SDL_CreateCond(); + SDL::Thread * HK = SDL_CreateThread(fHKthread, (void *) temp); + started = true; + return true; +} +/// sets the current hotkey command +bool Core::setHotkeyCmd( std::string cmd ) +{ + // access command + SDL_mutexP(HotkeyMutex); + { + hotkey_set = true; + hotkey_cmd = cmd; + SDL_CondSignal(HotkeyCond); + } + SDL_mutexV(HotkeyMutex); + return true; +} +/// removes the hotkey command and gives it to the caller thread +std::string Core::getHotkeyCmd( void ) +{ + string returner; + SDL_mutexP(HotkeyMutex); + while ( ! hotkey_set ) + { + SDL_CondWait(HotkeyCond, HotkeyMutex); + } + hotkey_set = false; + returner = hotkey_cmd; + hotkey_cmd.clear(); + SDL_mutexV(HotkeyMutex); + return returner; +} + + +void Core::Suspend() +{ + Core::Cond * nc = new Core::Cond(); + // put the condition on a stack + SDL_mutexP(StackMutex); + suspended_tools.push(nc); + SDL_mutexV(StackMutex); + // wait until Core::Update() wakes up the tool + SDL_mutexP(AccessMutex); + nc->Lock(AccessMutex); + SDL_mutexV(AccessMutex); +} + +void Core::Resume() +{ + SDL_mutexP(AccessMutex); + core_cond->Unlock(); + SDL_mutexV(AccessMutex); +} + +// should always be from simulation thread! +int Core::Update() +{ + if(!started) Init(); + if(errorstate) + return -1; + + // notify all the plugins that a game tick is finished + plug_mgr->OnUpdate(); + // wake waiting tools + // do not allow more tools to join in while we process stuff here + SDL_mutexP(StackMutex); + while (!suspended_tools.empty()) + { + Core::Cond * nc = suspended_tools.top(); + suspended_tools.pop(); + SDL_mutexP(AccessMutex); + // wake tool + nc->Unlock(); + // wait for tool to wake us + core_cond->Lock(AccessMutex); + SDL_mutexV(AccessMutex); + // destroy condition + delete nc; + } + SDL_mutexV(StackMutex); + return 0; +}; + +// FIXME: needs to terminate the IO threads and properly dismantle all the machinery involved. +int Core::Shutdown ( void ) +{ + errorstate = 1; + if(plug_mgr) + { + delete plug_mgr; + plug_mgr = 0; + } + // invalidate all modules + for(unsigned int i = 0 ; i < allModules.size(); i++) + { + delete allModules[i]; + } + allModules.clear(); + memset(&(s_mods), 0, sizeof(s_mods)); + con.shutdown(); + return -1; +} + +int Core::SDL_Event(SDL::Event* ev, int orig_return) +{ + // do NOT process events before we are ready. + if(!started) return orig_return; + if(!ev) + return orig_return; + if(ev && ev->type == SDL::ET_KEYDOWN || ev->type == SDL::ET_KEYUP) + { + SDL::KeyboardEvent * ke = (SDL::KeyboardEvent *)ev; + bool shift = ke->ksym.mod & SDL::KMOD_SHIFT; + // consuming F1 .. F8 + int idx = ke->ksym.sym - SDL::K_F1; + if(idx < 0 || idx > 7) + return orig_return; + idx += 8*shift; + // now we have the real index... + if(ke->state == SDL::BTN_PRESSED && !hotkey_states[idx]) + { + hotkey_states[idx] = 1; + Gui * g = getGui(); + if(g->hotkeys && g->df_interface && g->df_menu_state) + { + t_viewscreen * ws = g->GetCurrentScreen(); + // FIXME: put hardcoded values into memory.xml + if(ws->getClassName() == "viewscreen_dwarfmodest" && *g->df_menu_state == 0x23) + return orig_return; + else + { + t_hotkey & hotkey = (*g->hotkeys)[idx]; + setHotkeyCmd(hotkey.name); + } + } + } + else if(ke->state == SDL::BTN_RELEASED) + { + hotkey_states[idx] = 0; + } + } + return orig_return; + // do stuff with the events... +} + +/******************************************************************************* + M O D U L E S +*******************************************************************************/ + +#define MODULE_GETTER(TYPE) \ +TYPE * Core::get##TYPE() \ +{ \ + if(errorstate) return NULL;\ + if(!s_mods.p##TYPE)\ + {\ + Module * mod = create##TYPE();\ + s_mods.p##TYPE = (TYPE *) mod;\ + allModules.push_back(mod);\ + }\ + return s_mods.p##TYPE;\ +} + +MODULE_GETTER(Creatures); +MODULE_GETTER(Engravings); +MODULE_GETTER(Maps); +MODULE_GETTER(Gui); +MODULE_GETTER(World); +MODULE_GETTER(Materials); +MODULE_GETTER(Items); +MODULE_GETTER(Translation); +MODULE_GETTER(Vegetation); +MODULE_GETTER(Buildings); +MODULE_GETTER(Constructions); +MODULE_GETTER(Vermin); +MODULE_GETTER(Notes); diff --git a/library/DFContext.cpp b/library/DFContext.cpp deleted file mode 100644 index ca633f786..000000000 --- a/library/DFContext.cpp +++ /dev/null @@ -1,177 +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 -#include -#include -using namespace std; - -#include "dfhack/DFProcess.h" -#include "dfhack/DFProcessEnumerator.h" -#include "dfhack/DFContext.h" -#include "dfhack/DFError.h" -#include "dfhack/DFModule.h" - -#include "private/ContextShared.h" -#include "private/ModuleFactory.h" - -using namespace DFHack; - -Context::Context (Process* p) : d (new DFContextShared()) -{ - d->p = p; - d->offset_descriptor = p->getDescriptor(); - d->shm_start = 0; -} - -Context::~Context() -{ - Detach(); - delete d; -} - -bool Context::isValid() -{ - //FIXME: check for error states here - if(d->p->isIdentified()) - return true; - return false; -} - -bool Context::Attach() -{ - if (!d->p->attach()) - { - //throw Error::CantAttach(); - return false; - } - d->shm_start = d->p->getSHMStart(); - // process is attached, everything went just fine... hopefully - return true; -} - - -bool Context::Detach() -{ - if (!d->p->detach()) - { - cerr << "Context::Detach failed!" << endl; - return false; - } - d->shm_start = 0; - // invalidate all modules - for(unsigned int i = 0 ; i < d->allModules.size(); i++) - { - delete d->allModules[i]; - } - d->allModules.clear(); - memset(&(d->s_mods), 0, sizeof(d->s_mods)); - return true; -} - -bool Context::isAttached() -{ - return d->p->isAttached(); -} - -bool Context::Suspend() -{ - return d->p->suspend(); -} -bool Context::AsyncSuspend() -{ - return d->p->asyncSuspend(); -} - -bool Context::Resume() -{ - for(unsigned int i = 0 ; i < d->allModules.size(); i++) - { - d->allModules[i]->OnResume(); - } - return d->p->resume(); -} -bool Context::ForceResume() -{ - for(unsigned int i = 0 ; i < d->allModules.size(); i++) - { - d->allModules[i]->OnResume(); - } - return d->p->forceresume(); -} -bool Context::isSuspended() -{ - return d->p->isSuspended(); -} - -void Context::ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target) -{ - d->p->read (offset, size, target); -} - -void Context::WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source) -{ - d->p->write (offset, size, source); -} - -VersionInfo *Context::getMemoryInfo() -{ - return d->offset_descriptor; -} - -Process * Context::getProcess() -{ - return d->p; -} - -/******************************************************************************* - M O D U L E S -*******************************************************************************/ - -#define MODULE_GETTER(TYPE) \ -TYPE * Context::get##TYPE() \ -{ \ - if(!d->s_mods.p##TYPE)\ - {\ - Module * mod = create##TYPE(d);\ - d->s_mods.p##TYPE = (TYPE *) mod;\ - d->allModules.push_back(mod);\ - }\ - return d->s_mods.p##TYPE;\ -} - -MODULE_GETTER(Creatures); -MODULE_GETTER(Engravings); -MODULE_GETTER(Maps); -MODULE_GETTER(Gui); -MODULE_GETTER(WindowIO); -MODULE_GETTER(World); -MODULE_GETTER(Materials); -MODULE_GETTER(Items); -MODULE_GETTER(Translation); -MODULE_GETTER(Vegetation); -MODULE_GETTER(Buildings); -MODULE_GETTER(Constructions); diff --git a/library/DFContextManager.cpp b/library/DFContextManager.cpp deleted file mode 100644 index 5ee5e3904..000000000 --- a/library/DFContextManager.cpp +++ /dev/null @@ -1,246 +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 -#include -#include -using namespace std; - -#include "dfhack/VersionInfoFactory.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFProcessEnumerator.h" -#include "dfhack/DFError.h" - -#include "dfhack/DFContext.h" -#include "dfhack/DFContextManager.h" -#include "private/ContextShared.h" - -using namespace DFHack; -namespace DFHack -{ - class ContextManager::Private - { - public: - Private(){}; - ~Private(){}; - string xml; // path to xml - vector contexts; - ProcessEnumerator * pEnum; - }; -} -class DFHack::BadContexts::Private -{ - public: - Private(){}; - vector bad; -}; - - -BadContexts::BadContexts():d(new Private()){} - -BadContexts::~BadContexts() -{ - clear(); - delete d; -} - -bool BadContexts::Contains(Process* p) -{ - for(unsigned int i = 0; i < d->bad.size(); i++) - { - if((d->bad[i])->getProcess() == p) - return true; - } - return false; -} - -bool BadContexts::Contains(Context* c) -{ - for(unsigned 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(unsigned 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->xml = 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( BadContexts* bad_contexts ) -{ - // handle expired processes, remove stale Contexts - { - BadProcesses expired; - // get new list od living and expired Process objects - d->pEnum->Refresh(&expired); - - // scan expired, kill contexts if necessary - vector ::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 - } - int numProcesses = d->pEnum->size(); - int numContexts = d->contexts.size(); - vector newContexts; - // enumerate valid processes - for(int i = 0; i < numProcesses; i++) - { - 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()) - { - Refresh(); - } - for(unsigned int i = 0; i < d->contexts.size();i++) - { - if(d->contexts[i]->isValid()) - { - return d->contexts[i]; - } - } - throw DFHack::Error::NoProcess(); -} - -void ContextManager::purge(void) -{ - for(unsigned int i = 0; i < d->contexts.size();i++) - delete d->contexts[i]; - d->contexts.clear(); - d->pEnum->purge(); -} diff --git a/library/DFContext_C.cpp b/library/DFContext_C.cpp deleted file mode 100644 index cfe24ad00..000000000 --- a/library/DFContext_C.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* -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/DFPragma.h" -#include "dfhack/DFExport.h" -#include -#include -#include -using namespace std; - -#include "dfhack/DFIntegers.h" -#include "dfhack/DFContextManager.h" -#include "dfhack/DFContext.h" - - -using namespace DFHack; - -#include "dfhack-c/DFContext_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHackObject* ContextManager_Alloc(const char* path_to_xml) -{ - DFHack::ContextManager* contextMgr = new DFHack::ContextManager(std::string(path_to_xml)); - return (DFHackObject*)contextMgr; -} - -//FIXME: X:\dfhack\DFHackContext_C.cpp:56: warning: deleting `DFHackObject* ' is undefined -//DC: Yeah, I forgot that trying to delete a void pointer might be a bad idea. This works now. -void ContextManager_Free(DFHackObject* contextMgr) -{ - if(contextMgr != NULL) - { - DFHack::ContextManager* a = (DFHack::ContextManager*)contextMgr; - delete a; - - contextMgr = NULL; - } -} - -int ContextManager_Refresh(DFHackObject* contextMgr) -{ - if(contextMgr != NULL) - { - return ((DFHack::ContextManager*)contextMgr)->Refresh(); - } - - return -1; -} - -int ContextManager_size(DFHackObject* contextMgr, uint32_t* size) -{ - if(contextMgr != NULL) - { - uint32_t result = ((DFHack::ContextManager*)contextMgr)->size(); - - *size = result; - - return 1; - } - - return -1; -} - -int ContextManager_purge(DFHackObject* contextMgr) -{ - if(contextMgr != NULL) - { - ((DFHack::ContextManager*)contextMgr)->purge(); - - return 1; - } - - return -1; -} - -DFHackObject* ContextManager_getContext(DFHackObject* contextMgr, uint32_t index) -{ - if(contextMgr != NULL) - { - DFHack::ContextManager* mgr = ((DFHack::ContextManager*)contextMgr); - - if(index >= mgr->size()) - return NULL; - - return (DFHackObject*)((DFHack::Context*)((*mgr)[index])); - } - - return NULL; -} - -DFHackObject* ContextManager_getSingleContext(DFHackObject* contextMgr) -{ - if(contextMgr != NULL) - { - return (DFHackObject*)((DFHack::ContextManager*)contextMgr)->getSingleContext(); - } - - return NULL; -} - -void Context_Free(DFHackObject* context) -{ - if(context != NULL) - { - DFHack::Context* c = (DFHack::Context*)context; - delete c; - - context = NULL; - } -} - -int Context_Attach(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->Attach(); - } - - return -1; -} - -int Context_Detach(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->Detach(); - } - - return -1; -} - -int Context_isAttached(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->isAttached(); - } - - return -1; -} - -int Context_Suspend(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->Suspend(); - } - - return -1; -} - -int Context_Resume(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->Resume(); - } - - return -1; -} - -int Context_isSuspended(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->isSuspended(); - } - - return -1; -} - -int Context_ForceResume(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->ForceResume(); - } - - return -1; -} - -int Context_AsyncSuspend(DFHackObject* context) -{ - if(context != NULL) - { - return ((DFHack::Context*)context)->AsyncSuspend(); - } - - return -1; -} - -//module getters - -DFHackObject* Context_getMemoryInfo(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getMemoryInfo(); - } - - return NULL; -} - -DFHackObject* Context_getProcess(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getProcess(); - } - - return NULL; -} - -DFHackObject* Context_getCreatures(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getCreatures(); - } - - return NULL; -} - -DFHackObject* Context_getMaps(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getMaps(); - } - - return NULL; -} - -DFHackObject* Context_getGui(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getGui(); - } - - return NULL; -} - -DFHackObject* Context_getMaterials(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getMaterials(); - } - - return NULL; -} - -DFHackObject* Context_getTranslation(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getTranslation(); - } - - return NULL; -} - -DFHackObject* Context_getVegetation(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getVegetation(); - } - - return NULL; -} - -DFHackObject* Context_getBuildings(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getBuildings(); - } - - return NULL; -} - -DFHackObject* Context_getConstructions(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getConstructions(); - } - - return NULL; -} - -DFHackObject* Context_getItems(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getItems(); - } - - return NULL; -} - -DFHackObject* Context_getWorld(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getWorld(); - } - - return NULL; -} - -DFHackObject* Context_getWindowIO(DFHackObject* context) -{ - if(context != NULL) - { - return (DFHackObject*)((DFHack::Context*)context)->getWindowIO(); - } - - return NULL; -} - -void Context_ReadRaw(DFHackObject* context, const uint32_t offset, const uint32_t size, uint8_t* target) -{ - if(context != NULL) - { - ((DFHack::Context*)context)->ReadRaw(offset, size, target); - } -} - -void Context_WriteRaw(DFHackObject* context, const uint32_t offset, const uint32_t size, uint8_t* source) -{ - if(context != NULL) - { - ((DFHack::Context*)context)->WriteRaw(offset, size, source); - } -} - -#ifdef __cplusplus -} -#endif diff --git a/library/DFProcess-SHM.cpp b/library/DFProcess-SHM.cpp deleted file mode 100644 index 44622da51..000000000 --- a/library/DFProcess-SHM.cpp +++ /dev/null @@ -1,488 +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 "PlatformInternal.h" -#include -#include -#include -#include -using namespace std; - -#include "SHMProcess.h" -#include "ProcessFactory.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -#include "shms.h" -#include "mod-core.h" - -using namespace DFHack; - -Process* DFHack::createSHMProcess(uint32_t pid, VersionInfoFactory * factory) -{ - return new SHMProcess(pid, factory); -} - -SHMProcess::SHMProcess(uint32_t PID, VersionInfoFactory * factory) -: d(new Private(this)) -{ - d->process_ID = PID; - // attach the SHM - if(!attach()) - { - return; - } - // Test bridge version, get PID, sync Yield - bool bridgeOK; - if(!d->Aux_Core_Attach(bridgeOK,d->process_ID)) - { - detach(); - throw Error::SHMAttachFailure(); - } - else if(!bridgeOK) - { - detach(); - throw Error::SHMVersionMismatch(); - } - - // try to identify the DF version (md5 the binary, compare with known versions) - d->validate(factory); - // at this point, DF is attached and suspended, make it run - detach(); -} - -SHMProcess::~SHMProcess() -{ - if(d->attached) - { - detach(); - } - // destroy data model. this is assigned by processmanager - if(d->memdescriptor) - delete d->memdescriptor; - delete d; -} - -VersionInfo * SHMProcess::getDescriptor() -{ - return d->memdescriptor; -} - -int SHMProcess::getPID() -{ - return d->process_ID; -} - - -bool SHMProcess::isSuspended() -{ - return d->locked; -} -bool SHMProcess::isAttached() -{ - return d->attached; -} - -bool SHMProcess::isIdentified() -{ - return d->identified; -} - -bool SHMProcess::suspend() -{ - if(!d->attached) - { - return false; - } - if(d->locked) - { - return true; - } - //cerr << "suspend" << endl;// FIXME: throw - // FIXME: this should be controlled on the server side - // FIXME: IF server got CORE_RUN in this frame, interpret CORE_SUSPEND as CORE_STEP - // did we just resume a moment ago? - if(D_SHMCMD == CORE_RUN) - { - //fprintf(stderr,"%d invokes step\n",attachmentIdx); - // wait for the next window - /* - if(!d->SetAndWait(CORE_STEP)) - { - throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))"); - } - */ - D_SHMCMD = CORE_STEP; - } - else - { - //fprintf(stderr,"%d invokes suspend\n",attachmentIdx); - // lock now - /* - if(!d->SetAndWait(CORE_SUSPEND)) - { - throw Error::SHMLockingError("if(!d->SetAndWait(CORE_SUSPEND))"); - } - */ - D_SHMCMD = CORE_SUSPEND; - } - //fprintf(stderr,"waiting for lock\n"); - // we wait for the server to give up our suspend lock (held by default) - if(acquireSuspendLock()) - { - d->locked = true; - return true; - } - return false; -} - -// FIXME: needs a good think-through -bool SHMProcess::asyncSuspend() -{ - if(!d->attached) - { - return false; - } - if(d->locked) - { - return true; - } - //cerr << "async suspend" << endl;// FIXME: throw - uint32_t cmd = D_SHMCMD; - if(cmd == CORE_SUSPENDED) - { - // we have to hold the lock to be really suspended - if(acquireSuspendLock()) - { - d->locked = true; - return true; - } - return false; - } - else - { - // did we just resume a moment ago? - if(cmd == CORE_STEP) - { - return false; - } - else if(cmd == CORE_RUN) - { - D_SHMCMD = CORE_STEP; - } - else - { - D_SHMCMD = CORE_SUSPEND; - } - return false; - } -} - -bool SHMProcess::forceresume() -{ - return resume(); -} - -// FIXME: wait for the server to advance a step! -bool SHMProcess::resume() -{ - if(!d->attached) - return false; - if(!d->locked) - return true; - //cerr << "resume" << endl;// FIXME: throw - // unlock the suspend lock - if(releaseSuspendLock()) - { - d->locked = false; - if(d->SetAndWait(CORE_RUN)) // we have to make sure the server responds! - { - return true; - } - throw Error::SHMLockingError("if(d->SetAndWait(CORE_RUN))"); - } - throw Error::SHMLockingError("if(releaseSuspendLock())"); - return false; -} - -// get module index by name and version. bool 0 = error -bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) -{ - if(!d->locked) throw Error::MemoryAccessDenied(0xdeadbeef); - - modulelookup * payload = D_SHMDATA(modulelookup); - payload->version = version; - - strncpy(payload->name,name,255); - payload->name[255] = 0; - - if(!SetAndWait(CORE_ACQUIRE_MODULE)) - { - return false; // FIXME: throw a fatal exception instead - } - if(D_SHMHDR->error) - { - return false; - } - //fprintf(stderr,"%s v%d : %d\n", name, version, D_SHMHDR->value); - OUTPUT = D_SHMHDR->value; - return true; -} - -bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) -{ - if(!locked) throw Error::MemoryAccessDenied(0xdeadbeef); - - SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); - if(!SetAndWait(CORE_ATTACH)) return false; - /* - cerr <<"CORE_VERSION" << CORE_VERSION << endl; - cerr <<"server CORE_VERSION" << SHMDATA(coreattach)->sv_version << endl; - */ - versionOK =( SHMDATA(coreattach)->sv_version == CORE_VERSION ); - PID = SHMDATA(coreattach)->sv_PID; - useYield = SHMDATA(coreattach)->sv_useYield; - #ifdef DEBUG - if(useYield) cerr << "Using Yield!" << endl; - #endif - return true; -} - -void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) -{ - if(!d->locked) throw Error::MemoryAccessDenied(src_address); - - // normal read under 1MB - if(size <= SHM_BODY) - { - D_SHMHDR->address = src_address; - D_SHMHDR->length = size; - full_barrier - d->SetAndWait(CORE_READ); - memcpy (target_buffer, D_SHMDATA(void),size); - } - // a big read, we pull data over the shm in iterations - else - { - // first read equals the size of the SHM window - uint32_t to_read = SHM_BODY; - while (size) - { - // read to_read bytes from src_cursor - D_SHMHDR->address = src_address; - D_SHMHDR->length = to_read; - full_barrier - d->SetAndWait(CORE_READ); - memcpy (target_buffer, D_SHMDATA(void) ,to_read); - // decrease size by bytes read - size -= to_read; - // move the cursors - src_address += to_read; - target_buffer += to_read; - // check how much to write in the next iteration - to_read = min(size, (uint32_t) SHM_BODY); - } - } -} - -void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_BYTE); - val = D_SHMHDR->value; -} - -void SHMProcess::readWord (const uint32_t offset, uint16_t &val) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_WORD); - val = D_SHMHDR->value; -} - -void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_DWORD); - val = D_SHMHDR->value; -} - -void SHMProcess::readQuad (const uint32_t offset, uint64_t &val) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_QUAD); - val = D_SHMHDR->Qvalue; -} - -void SHMProcess::readFloat (const uint32_t offset, float &val) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_DWORD); - val = reinterpret_cast (D_SHMHDR->value); -} - -/* - * WRITING - */ - -void SHMProcess::writeQuad (uint32_t offset, uint64_t data) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - D_SHMHDR->Qvalue = data; - full_barrier - d->SetAndWait(CORE_WRITE_QUAD); -} - -void SHMProcess::writeDWord (uint32_t offset, uint32_t data) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - D_SHMHDR->value = data; - full_barrier - d->SetAndWait(CORE_WRITE_DWORD); -} - -// using these is expensive. -void SHMProcess::writeWord (uint32_t offset, uint16_t data) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - D_SHMHDR->value = data; - full_barrier - d->SetAndWait(CORE_WRITE_WORD); -} - -void SHMProcess::writeByte (uint32_t offset, uint8_t data) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - D_SHMHDR->value = data; - full_barrier - d->SetAndWait(CORE_WRITE_BYTE); -} - -void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) -{ - if(!d->locked) throw Error::MemoryAccessDenied(dst_address); - - // normal write under 1MB - if(size <= SHM_BODY) - { - D_SHMHDR->address = dst_address; - D_SHMHDR->length = size; - memcpy(D_SHMDATA(void),source_buffer, size); - full_barrier - d->SetAndWait(CORE_WRITE); - } - // a big write, we push this over the shm in iterations - else - { - // first write equals the size of the SHM window - uint32_t to_write = SHM_BODY; - while (size) - { - // write to_write bytes to dst_cursor - D_SHMHDR->address = dst_address; - D_SHMHDR->length = to_write; - memcpy(D_SHMDATA(void),source_buffer, to_write); - full_barrier - d->SetAndWait(CORE_WRITE); - // decrease size by bytes written - size -= to_write; - // move the cursors - source_buffer += to_write; - dst_address += to_write; - // check how much to write in the next iteration - to_write = min(size, (uint32_t) SHM_BODY); - } - } -} - -const std::string SHMProcess::readCString (uint32_t offset) -{ - std::string temp; - int counter = 0; - char r; - while (1) - { - r = Process::readByte(offset+counter); - if(!r) break; - counter++; - temp.append(1,r); - } - return temp; -} - -const std::string SHMProcess::readSTLString(uint32_t offset) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_STL_STRING); - return(string( D_SHMDATA(char) )); -} - -size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) -{ - if(!d->locked) throw Error::MemoryAccessDenied(offset); - - D_SHMHDR->address = offset; - full_barrier - d->SetAndWait(CORE_READ_STL_STRING); - size_t length = D_SHMHDR->value; - size_t fit = min(bufcapacity - 1, length); - strncpy(buffer,D_SHMDATA(char),fit); - buffer[fit] = 0; - return fit; -} - -size_t SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) -{ - if(!d->locked) throw Error::MemoryAccessDenied(address); - - D_SHMHDR->address = address; - strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator - full_barrier - d->SetAndWait(CORE_WRITE_STL_STRING); - return writeString.length(); -} diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp deleted file mode 100644 index 3d13f0397..000000000 --- a/library/DFProcess-linux-SHM.cpp +++ /dev/null @@ -1,421 +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 "PlatformInternal.h" - -#include -#include -#include -#include -using namespace std; - -#include "SHMProcess.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace DFHack; - -SHMProcess::Private::Private(SHMProcess * self_) -{ - memdescriptor = NULL; - process_ID = 0; - shm_ID = -1; - attached = false; - identified = false; - useYield = false; - server_lock = -1; - client_lock = -1; - suspend_lock = -1; - locked = false; - self = self_; -} - -bool SHMProcess::Private::SetAndWait (uint32_t state) -{ - uint32_t cnt = 0; - if(!attached) return false; - SHMCMD = state; - - while (SHMCMD == state) - { - // yield the CPU, only on single-core CPUs - if(useYield) - { - SCHED_YIELD - } - if(cnt == 10000) - { - if(!AreLocksOk())// DF not there anymore? - { - //detach the shared memory - shmdt(shm_addr); - FreeLocks(); - attached = locked = identified = false; - // we aren't the current process anymore - throw Error::SHMServerDisappeared(); - } - else - { - cnt = 0; - } - } - cnt++; - } - // server returned a generic error - if(SHMCMD == CORE_ERROR) - { - return false; - } - return true; -} - -/* -Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us -enough control over scheduling) -we end up with this silly thing -*/ -bool SHMProcess::SetAndWait (uint32_t state) -{ - return d->SetAndWait(state); -} - -uint32_t OS_getAffinity() -{ - cpu_set_t mask; - sched_getaffinity(0,sizeof(cpu_set_t),&mask); - // FIXME: truncation - uint32_t affinity = *(uint32_t *) &mask; - return affinity; -} - -void SHMProcess::Private::FreeLocks() -{ - attachmentIdx = -1; - if(client_lock != -1) - { - lockf(client_lock,F_ULOCK,0); - close(client_lock); - client_lock = -1; - } - if(server_lock != -1) - { - close(server_lock); - server_lock = -1; - } - if(suspend_lock != -1) - { - close(suspend_lock); - locked = false; - suspend_lock = -1; - } -} - -bool SHMProcess::Private::GetLocks() -{ - char name[256]; - // try to acquire locks - // look at the server lock, if it's locked, the server is present - sprintf(name, "/tmp/DFHack/%d/SVlock",process_ID); - server_lock = open(name,O_WRONLY); - if(server_lock == -1) - { - // cerr << "can't open sv lock" << endl; - return false; - } - - if(lockf( server_lock, F_TEST, 0 ) != -1) - { - cerr << "sv lock not locked" << endl; - close(server_lock); - server_lock = -1; - return false; - } - - for(int i = 0; i < SHM_MAX_CLIENTS; i++) - { - // open the client suspend locked - sprintf(name, "/tmp/DFHack/%d/CLSlock%d",process_ID,i); - suspend_lock = open(name,O_WRONLY); - if(suspend_lock == -1) - { - cerr << "can't open cl S-lock " << i << endl; - // couldn't open lock - continue; - } - - // open the client lock, try to lock it - sprintf(name, "/tmp/DFHack/%d/CLlock%d",process_ID,i); - client_lock = open(name,O_WRONLY); - if(client_lock == -1) - { - cerr << "can't open cl lock " << i << endl; - close(suspend_lock); - locked = false; - suspend_lock = -1; - // couldn't open lock - continue; - } - if(lockf(client_lock,F_TLOCK, 0) == -1) - { - // couldn't acquire lock - cerr << "can't acquire cl lock " << i << endl; - close(suspend_lock); - locked = false; - suspend_lock = -1; - close(client_lock); - client_lock = -1; - continue; - } - // ok, we have all the locks we need! - attachmentIdx = i; - return true; - } - close(server_lock); - server_lock = -1; - cerr << "can't get any client locks" << endl; - return false; -} - -// test if we have client and server locks and the server is present -bool SHMProcess::Private::AreLocksOk() -{ - // both locks are inited (we hold our lock) - if(client_lock != -1 && server_lock != -1) - { - if(lockf(server_lock,F_TEST,0) == -1) // and server holds its lock - { - return true; // OK, locks are good - } - } - // locks are bad - return false; -} - - -bool SHMProcess::Private::validate(VersionInfoFactory * factory) -{ - char exe_link_name [256]; - char target_name[1024]; - int target_result; - // find the binary - sprintf(exe_link_name,"/proc/%d/exe", process_ID); - target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); - if (target_result == -1) - { - perror("readlink"); - return false; - } - // make sure we have a null terminated string... - // see http://www.opengroup.org/onlinepubs/000095399/functions/readlink.html - target_name[target_result] = 0; - - // get hash of the running DF process - md5wrapper md5; - string hash = md5.getHashFromFile(target_name); - - // create linux process, add it to the vector - VersionInfo * vinfo = factory->getVersionInfoByMD5(hash); - if(vinfo) - { - memdescriptor = vinfo; - // FIXME: BIG BAD BUG RIGHT HERE!!!! - memdescriptor->setParentProcess(self); - identified = true; - vector_start = memdescriptor->getGroup("vector")->getOffset("start"); - return true; - } - return false; -} - -// there is only one we care about. -bool SHMProcess::getThreadIDs(vector & threads ) -{ - if(d->attached) - { - threads.clear(); - threads.push_back(d->process_ID); - return true; - } - return false; -} - -//FIXME: cross-reference with ELF segment entries? -void SHMProcess::getMemRanges( vector & ranges ) -{ - char buffer[1024]; - char permissions[5]; // r/-, w/-, x/-, p/s, 0 - - sprintf(buffer, "/proc/%lu/maps", (long unsigned)d->process_ID); - FILE *mapFile = ::fopen(buffer, "r"); - uint64_t offset, device1, device2, node; - - while (fgets(buffer, 1024, mapFile)) - { - t_memrange temp; - temp.name[0] = 0; - sscanf(buffer, "%zx-%zx %s %zx %2zu:%2zu %zu %s", - &temp.start, - &temp.end, - (char*)&permissions, - &offset, &device1, &device2, &node, - (char*)&temp.name); - temp.read = permissions[0] == 'r'; - temp.write = permissions[1] == 'w'; - temp.execute = permissions[2] == 'x'; - temp.valid = true; - ranges.push_back(temp); - } -} - -bool SHMProcess::acquireSuspendLock() -{ - return (lockf(d->suspend_lock,F_LOCK,0) == 0); -} - -bool SHMProcess::releaseSuspendLock() -{ - return (lockf(d->suspend_lock,F_ULOCK,0) == 0); -} - - -bool SHMProcess::attach() -{ - if(d->attached) - { - if(!d->locked) - return suspend(); - return true; - } - //cerr << "attach" << endl;// FIXME: throw - if(!d->GetLocks()) - { - //cerr << "server is full or not really there!" << endl; - return false; - } - - /* - * Locate the segment. - */ - if ((d->shm_ID = shmget(SHM_KEY + d->process_ID, SHM_SIZE, 0666)) < 0) - { - d->FreeLocks(); - cerr << "can't find segment" << endl; // FIXME: throw - return false; - } - - /* - * Attach the segment - */ - if ((d->shm_addr = (char *) shmat(d->shm_ID, NULL, 0)) == (char *) -1) - { - d->FreeLocks(); - cerr << "can't attach segment" << endl; // FIXME: throw - return false; - } - d->attached = true; - if(!suspend()) - { - shmdt(d->shm_addr); - d->FreeLocks(); - cerr << "unable to suspend" << endl; - return false; - } - return true; -} - -bool SHMProcess::detach() -{ - if(!d->attached) return true; - if(d->locked) - { - resume(); - } - // detach segment - if(shmdt(d->shm_addr) != -1) - { - d->FreeLocks(); - d->locked = false; - d->attached = false; - d->shm_addr = 0; - return true; - } - // fail if we can't detach - // FIXME: throw exception here?? - perror("failed to detach shared segment"); - return false; -} - -void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -void SHMProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - write(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - - -string SHMProcess::doReadClassName (uint32_t vptr) -{ - if(!d->locked) throw Error::MemoryAccessDenied(vptr); - - int typeinfo = Process::readDWord(vptr - 0x4); - int typestring = Process::readDWord(typeinfo + 0x4); - string raw = readCString(typestring); - size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers - size_t end = raw.length(); - return raw.substr(start,end-start); -} - -string SHMProcess::getPath() -{ - char cwd_name[256]; - char target_name[1024]; - int target_result; - - sprintf(cwd_name,"/proc/%d/cwd", getPID()); - // resolve /proc/PID/exe link - target_result = readlink(cwd_name, target_name, sizeof(target_name)); - target_name[target_result] = '\0'; - return(string(target_name)); -} - -char * SHMProcess::getSHMStart (void) -{ - if(!d->locked) return 0; //THROW HERE! - - return d->shm_addr; -} diff --git a/library/DFProcess-linux-base.cpp b/library/DFProcess-linux-base.cpp deleted file mode 100644 index ed4da316a..000000000 --- a/library/DFProcess-linux-base.cpp +++ /dev/null @@ -1,326 +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 "PlatformInternal.h" - -#include -#include -#include -#include -#include -using namespace std; - -#include "LinuxProcess.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -#include -#include -using namespace DFHack; - -LinuxProcessBase::LinuxProcessBase(uint32_t pid) -: my_pid(pid) -{ - my_descriptor = NULL; - attached = false; - suspended = false; - memFileHandle = 0; -} - -bool LinuxProcessBase::isSuspended() -{ - return suspended; -} -bool LinuxProcessBase::isAttached() -{ - return attached; -} - -bool LinuxProcessBase::isIdentified() -{ - return identified; -} - -LinuxProcessBase::~LinuxProcessBase() -{ - // destroy our copy of the memory descriptor - if(my_descriptor) - delete my_descriptor; -} - -VersionInfo * LinuxProcessBase::getDescriptor() -{ - return my_descriptor; -} - -int LinuxProcessBase::getPID() -{ - return my_pid; -} - -int getdir (string dir, vector &files) -{ - DIR *dp; - struct dirent *dirp; - if((dp = opendir(dir.c_str())) == NULL) { - cout << "Error(" << errno << ") opening " << dir << endl; - return errno; - } - - while ((dirp = readdir(dp)) != NULL) { - files.push_back(string(dirp->d_name)); - } - closedir(dp); - return 0; -} - -bool LinuxProcessBase::getThreadIDs(vector & threads ) -{ - stringstream ss; - vector subdirs; - ss << "/proc/" << my_pid << "/task/"; - if(getdir(ss.str(),subdirs) != 0) - { - //FIXME: needs exceptions. this is a fatal error - cerr << "unable to enumerate threads. This is BAD!" << endl; - return false; - } - threads.clear(); - for(size_t i = 0; i < subdirs.size();i++) - { - uint32_t tid; - if(sscanf(subdirs[i].c_str(),"%d", &tid)) - { - threads.push_back(tid); - } - } - return true; -} - -//FIXME: cross-reference with ELF segment entries? -void LinuxProcessBase::getMemRanges( vector & ranges ) -{ - char buffer[1024]; - char permissions[5]; // r/-, w/-, x/-, p/s, 0 - - sprintf(buffer, "/proc/%lu/maps", (long unsigned)my_pid); - FILE *mapFile = ::fopen(buffer, "r"); - size_t start, end, offset, device1, device2, node; - - while (fgets(buffer, 1024, mapFile)) - { - t_memrange temp; - temp.name[0] = 0; - sscanf(buffer, "%zx-%zx %s %zx %2zu:%2zu %zu %[^\n]s", - &start, - &end, - (char*)&permissions, - &offset, &device1, &device2, &node, - (char*)&temp.name); - temp.start = start; - temp.end = end; - temp.read = permissions[0] == 'r'; - temp.write = permissions[1] == 'w'; - temp.execute = permissions[2] == 'x'; - temp.shared = permissions[3] == 's'; - temp.valid = true; - ranges.push_back(temp); - } -} - -void LinuxProcessBase::read (const uint32_t offset, const uint32_t size, uint8_t *target) -{ - if(size == 0) return; - - ssize_t result; - ssize_t total = 0; - ssize_t remaining = size; - while (total != size) - { - result = pread(memFileHandle, target + total ,remaining,offset + total); - if(result == -1) - { - cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; - cerr << "errno: " << errno << endl; - errno = 0; - throw Error::MemoryAccessDenied(offset); - } - else - { - total += result; - remaining -= result; - } - } -} - -void LinuxProcessBase::readByte (const uint32_t offset, uint8_t &val ) -{ - read(offset, 1, &val); -} - -void LinuxProcessBase::readWord (const uint32_t offset, uint16_t &val) -{ - read(offset, 2, (uint8_t *) &val); -} - -void LinuxProcessBase::readDWord (const uint32_t offset, uint32_t &val) -{ - read(offset, 4, (uint8_t *) &val); -} - -void LinuxProcessBase::readFloat (const uint32_t offset, float &val) -{ - read(offset, 4, (uint8_t *) &val); -} - -void LinuxProcessBase::readQuad (const uint32_t offset, uint64_t &val) -{ - read(offset, 8, (uint8_t *) &val); -} - -/* - * WRITING - */ - -void LinuxProcessBase::writeQuad (uint32_t offset, const uint64_t data) -{ - #ifdef HAVE_64_BIT - ptrace(PTRACE_POKEDATA,my_pid, offset, data); - #else - ptrace(PTRACE_POKEDATA,my_pid, offset, (uint32_t) data); - ptrace(PTRACE_POKEDATA,my_pid, offset+4, (uint32_t) (data >> 32)); - #endif -} - -void LinuxProcessBase::writeDWord (uint32_t offset, uint32_t data) -{ - #ifdef HAVE_64_BIT - uint64_t orig = Process::readQuad(offset); - orig &= 0xFFFFFFFF00000000; - orig |= data; - ptrace(PTRACE_POKEDATA,my_pid, offset, orig); - #else - ptrace(PTRACE_POKEDATA,my_pid, offset, data); - #endif -} - -// using these is expensive. -void LinuxProcessBase::writeWord (uint32_t offset, uint16_t data) -{ - #ifdef HAVE_64_BIT - uint64_t orig = Process::readQuad(offset); - orig &= 0xFFFFFFFFFFFF0000; - orig |= data; - ptrace(PTRACE_POKEDATA,my_pid, offset, orig); - #else - uint32_t orig = Process::readDWord(offset); - orig &= 0xFFFF0000; - orig |= data; - ptrace(PTRACE_POKEDATA,my_pid, offset, orig); - #endif -} - -void LinuxProcessBase::writeByte (uint32_t offset, uint8_t data) -{ - #ifdef HAVE_64_BIT - uint64_t orig = Process::readQuad(offset); - orig &= 0xFFFFFFFFFFFFFF00; - orig |= data; - ptrace(PTRACE_POKEDATA,my_pid, offset, orig); - #else - uint32_t orig = Process::readDWord(offset); - orig &= 0xFFFFFF00; - orig |= data; - ptrace(PTRACE_POKEDATA,my_pid, offset, orig); - #endif -} - -// blah. THIS IS RIDICULOUS -void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source) -{ - uint32_t indexptr = 0; - while (size > 0) - { - #ifdef HAVE_64_BIT - // quad! - if(size >= 8) - { - writeQuad(offset, *(uint64_t *) (source + indexptr)); - offset +=8; - indexptr +=8; - size -=8; - } - else - #endif - // default: we push 4 bytes - if(size >= 4) - { - writeDWord(offset, *(uint32_t *) (source + indexptr)); - offset +=4; - indexptr +=4; - size -=4; - } - // last is either three or 2 bytes - else if(size >= 2) - { - writeWord(offset, *(uint16_t *) (source + indexptr)); - offset +=2; - indexptr +=2; - size -=2; - } - // finishing move - else if(size == 1) - { - writeByte(offset, *(uint8_t *) (source + indexptr)); - return; - } - } -} - -const std::string LinuxProcessBase::readCString (uint32_t offset) -{ - std::string temp; - int counter = 0; - char r; - while (1) - { - r = Process::readByte(offset+counter); - if(!r) break; - counter++; - temp.append(1,r); - } - return temp; -} - -string LinuxProcessBase::getPath() -{ - char cwd_name[256]; - char target_name[1024]; - int target_result; - - sprintf(cwd_name,"/proc/%d/cwd", getPID()); - // resolve /proc/PID/exe link - target_result = readlink(cwd_name, target_name, sizeof(target_name)); - target_name[target_result] = '\0'; - return(string(target_name)); -} diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp deleted file mode 100644 index 0fb56d88f..000000000 --- a/library/DFProcess-linux-wine.cpp +++ /dev/null @@ -1,280 +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 "PlatformInternal.h" - -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "LinuxProcess.h" -#include "ProcessFactory.h" -#include "MicrosoftSTL.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -using namespace DFHack; - -#include -#include - -#include - - -namespace { - class WineProcess : public LinuxProcessBase - { - private: - uint8_t vector_start; - MicrosoftSTL stl; - public: - WineProcess(uint32_t pid, VersionInfoFactory * factory); - ~WineProcess() - { - if(attached) - { - detach(); - } - } - bool attach(); - bool detach(); - - bool suspend(); - bool asyncSuspend(); - bool resume(); - bool forceresume(); - - void readSTLVector(const uint32_t address, t_vecTriplet & triplet); - void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); - const std::string readSTLString (uint32_t offset); - size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - size_t writeSTLString(const uint32_t address, const std::string writeString); - // get class name of an object with rtti/type info - std::string doReadClassName(uint32_t vptr); - }; -} - -Process* DFHack::createWineProcess(uint32_t pid, VersionInfoFactory * factory) -{ - return new WineProcess(pid, factory); -} - -WineProcess::WineProcess(uint32_t pid, VersionInfoFactory * factory) : LinuxProcessBase(pid) -{ - char dir_name [256]; - char exe_link_name [256]; - char mem_name [256]; - char cwd_name [256]; - char cmdline_name [256]; - char target_name[1024]; - int target_result; - - identified = false; - my_descriptor = 0; - - sprintf(dir_name,"/proc/%d/", pid); - sprintf(exe_link_name,"/proc/%d/exe", pid); - sprintf(mem_name,"/proc/%d/mem", pid); - memFile = mem_name; - sprintf(cwd_name,"/proc/%d/cwd", pid); - sprintf(cmdline_name,"/proc/%d/cmdline", pid); - - // resolve /proc/PID/exe link - target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); - if (target_result == -1) - { - return; - } - // make sure we have a null terminated string... - target_name[target_result] = 0; - - // FIXME: this fails when the wine process isn't started from the 'current working directory'. strip path data from cmdline - // is this windows version of Df running in wine? - if(strstr(target_name, "wine-preloader")!= NULL) - { - // get working directory - target_result = readlink(cwd_name, target_name, sizeof(target_name)-1); - target_name[target_result] = 0; - - // got path to executable, do the same for its name - ifstream ifs ( cmdline_name , ifstream::in ); - string cmdline; - getline(ifs,cmdline); - if (cmdline.find("dwarfort-w.exe") != string::npos || cmdline.find("dwarfort.exe") != string::npos || cmdline.find("Dwarf Fortress.exe") != string::npos) - { - char exe_link[1024]; - // put executable name and path together - sprintf(exe_link,"%s/%s",target_name,cmdline.c_str()); - - md5wrapper md5; - // get hash of the running DF process - string hash = md5.getHashFromFile(exe_link); - // create linux process, add it to the vector - VersionInfo * vinfo = factory->getVersionInfoByMD5(hash); - if(vinfo) - { - my_descriptor = new VersionInfo(*vinfo); - my_descriptor->setParentProcess(this); - vector_start = my_descriptor->getGroup("vector")->getOffset("start"); - stl.init(this); - identified = true; - } - return; - } - } -} - -void WineProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -void WineProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) -{ - return stl.readSTLString(offset, buffer, bufcapacity); -} - -size_t WineProcess::writeSTLString(const uint32_t address, const std::string writeString) -{ - return stl.writeSTLString(address,writeString); -} - - -const string WineProcess::readSTLString (uint32_t offset) -{ - return stl.readSTLString(offset); -} - -string WineProcess::doReadClassName (uint32_t vptr) -{ - return stl.readClassName(vptr); -} - -bool WineProcess::asyncSuspend() -{ - return suspend(); -} - -bool WineProcess::suspend() -{ - int status; - if(suspended) - return true; - // can we attach? - if (ptrace(PTRACE_ATTACH , my_pid, NULL, NULL) == -1) - { - // no, we got an error - perror("ptrace attach error"); - cerr << "attach failed on pid " << my_pid << endl; - return false; - } - while(true) - { - // we wait on the pid - pid_t w = waitpid(my_pid, &status, 0); - if (w == -1) - { - // child died - perror("wait inside attach()"); - return false; - } - // stopped -> let's continue - if (WIFSTOPPED(status)) - { - break; - } - } - int proc_pid_mem = open(memFile.c_str(),O_RDONLY); - if(proc_pid_mem == -1) - { - ptrace(PTRACE_DETACH, my_pid, NULL, NULL); - cerr << memFile << endl; - cerr << "couldn't open /proc/" << my_pid << "/mem" << endl; - perror("open(memFile.c_str(),O_RDONLY)"); - return false; - } - else - { - attached = suspended = true; - memFileHandle = proc_pid_mem; - return true; // we are attached - } -} - -bool WineProcess::forceresume() -{ - return resume(); -} - -bool WineProcess::resume() -{ - if(!suspended) - return true; - int result = 0; - // close /proc/PID/mem - result = close(memFileHandle); - if(result == -1) - { - cerr << "couldn't close /proc/"<< my_pid <<"/mem" << endl; - perror("mem file close"); - return false; - } - else - { - // detach - result = ptrace(PTRACE_DETACH, my_pid, NULL, NULL); - if(result == -1) - { - cerr << "couldn't detach from process pid" << my_pid << endl; - perror("ptrace detach"); - return false; - } - else - { - attached = suspended = false; - return true; - } - } -} - - -bool WineProcess::attach() -{ - if(suspended) return true; - return suspend(); -} - -bool WineProcess::detach() -{ - if(!suspended) return true; - return resume(); -} diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp deleted file mode 100644 index e4d8ab4ae..000000000 --- a/library/DFProcess-linux.cpp +++ /dev/null @@ -1,410 +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 "PlatformInternal.h" - -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "LinuxProcess.h" -#include "ProcessFactory.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -#include -#include -#include -#include -using namespace DFHack; - -namespace { - class NormalProcess : public LinuxProcessBase - { - private: - uint8_t vector_start; - set thread_ids; - - void waitForSuspend(set &threads); - public: - NormalProcess(uint32_t pid, VersionInfoFactory * known_versions); - ~NormalProcess() - { - if(attached) - { - detach(); - } - } - bool attach(); - bool detach(); - - bool suspend(); - bool asyncSuspend(); - bool resume(); - bool forceresume(); - - void readSTLVector(const uint32_t address, t_vecTriplet & triplet); - void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); - const std::string readSTLString (uint32_t offset); - size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - size_t writeSTLString(const uint32_t address, const std::string writeString); - size_t copySTLString(const uint32_t address, const uint32_t target); - // get class name of an object with rtti/type info - std::string doReadClassName(uint32_t vptr); - }; -} - -Process* DFHack::createNormalProcess(uint32_t pid, VersionInfoFactory * known_versions) -{ - return new NormalProcess(pid, known_versions); -} - -NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions) : LinuxProcessBase(pid) -{ - char dir_name [256]; - char exe_link_name [256]; - char mem_name [256]; - char cwd_name [256]; - char cmdline_name [256]; - char target_name[1024]; - int target_result; - - identified = false; - my_descriptor = 0; - - sprintf(dir_name,"/proc/%d/", pid); - sprintf(exe_link_name,"/proc/%d/exe", pid); - sprintf(mem_name,"/proc/%d/mem", pid); - memFile = mem_name; - sprintf(cwd_name,"/proc/%d/cwd", pid); - sprintf(cmdline_name,"/proc/%d/cmdline", pid); - - // resolve /proc/PID/exe link - target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); - if (target_result == -1) - { - return; - } - // make sure we have a null terminated string... - target_name[target_result] = 0; - - // is this the regular linux DF? - if (strstr(target_name, "dwarfort.exe") != 0 || strstr(target_name,"Dwarf_Fortress") != 0) - { - md5wrapper md5; - // get hash of the running DF process - string hash = md5.getHashFromFile(target_name); - // create linux process, add it to the vector - VersionInfo * vinfo = known_versions->getVersionInfoByMD5(hash); - if(vinfo) - { - my_descriptor = new VersionInfo(*vinfo); - my_descriptor->setParentProcess(this); - vector_start = my_descriptor->getGroup("vector")->getOffset("start"); - identified = true; - } - } -} - -struct _Rep_base -{ - uint32_t _M_length; // length of text stored, not including zero termination - uint32_t _M_capacity; // capacity, not including zero termination - int32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply) -}; - -size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) -{ - _Rep_base header; - offset = Process::readDWord(offset); - read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - size_t read_real = min((size_t)header._M_length, bufcapacity-1);// keep space for null termination - read(offset,read_real,(uint8_t * )buffer); - buffer[read_real] = 0; - return read_real; -} - -size_t NormalProcess::writeSTLString(const uint32_t address, const std::string writeString) -{ - _Rep_base header; - // get buffer location - uint32_t start = Process::readDWord(address); - // read the header - read(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - - // the buffer has actual size = 1. no space for storing anything more than a zero byte - if(header._M_capacity == 0) - return 0; - if(header._M_refcount > 0 ) // one ref or one non-shareable (-1) ref - return 0; - - // get writeable length (lesser of our string length and capacity of the target) - uint32_t lstr = writeString.length(); - uint32_t allowed_copy = min(lstr, header._M_capacity); - // write header with new length. - header._M_length = allowed_copy; - write(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - // write string, add a zero terminator, return bytes written - write(start, allowed_copy, (uint8_t *) writeString.c_str()); - writeByte(start + allowed_copy, 0); - return allowed_copy; -} - -void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -void NormalProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -const string NormalProcess::readSTLString (uint32_t offset) -{ - _Rep_base header; - - offset = Process::readDWord(offset); - read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - - // FIXME: use char* everywhere, avoid string - char * temp = new char[header._M_length+1]; - read(offset,header._M_length+1,(uint8_t * )temp); - string ret(temp); - delete[] temp; - return ret; -} - -size_t NormalProcess::copySTLString (uint32_t offset, uint32_t target) -{ - _Rep_base header; - - offset = Process::readDWord(offset); - uint32_t old_target = Process::readDWord(target); - - if (offset == old_target) - return 0; - - read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - - // destroying the leaked state - if (header._M_refcount == -1) - header._M_refcount = 1; - else - header._M_refcount++; - - write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); - - writeDWord(target, offset); - return header._M_length; -} - -string NormalProcess::doReadClassName (uint32_t vptr) -{ - int typeinfo = Process::readDWord(vptr - 0x4); - int typestring = Process::readDWord(typeinfo + 0x4); - string raw = readCString(typestring); - size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers - size_t end = raw.length(); - return raw.substr(start,end-start); -} - -bool NormalProcess::asyncSuspend() -{ - return suspend(); -} - -bool NormalProcess::suspend() -{ - if(!attached) - return false; - if(suspended) - return true; - - set threads; - - for (set::iterator it = thread_ids.begin(); it != thread_ids.end(); ++it) { - if (syscall(SYS_tgkill, my_pid, *it, SIGSTOP) == -1) { - cerr << "couldn't stop thread " << *it << endl; - perror("kill SIGSTOP error"); - } else { - threads.insert(*it); - } - } - - if (threads.empty()) { - cerr << "couldn't suspend any of the threads"; - return false; - } - - waitForSuspend(threads); - - if (!threads.empty()) - cerr << "couldn't suspend some of the threads"; - - suspended = true; - return true; -} - -bool NormalProcess::forceresume() -{ - return resume(); -} - -bool NormalProcess::resume() -{ - if(!attached) - return false; - if(!suspended) - return true; - - bool ok = true; - for (set::iterator it = thread_ids.begin(); it != thread_ids.end(); ++it) { - int result = ptrace(PTRACE_CONT, *it, NULL, NULL); - if(result == -1) - { - cerr << "couldn't resume thread " << *it << endl; - perror("ptrace resume error"); - ok = false; - } - } - - if (ok) - suspended = false; - return ok; -} - -void NormalProcess::waitForSuspend(set &threads) -{ - int status; - while (!threads.empty()) { - pid_t w = waitpid(-1, &status, __WALL); - if (w == -1) { - perror("waitpid"); - return; - } - if (threads.find(w) == threads.end() - && thread_ids.find(w) == thread_ids.end()) - continue; - if (WIFSTOPPED(status)) { - threads.erase(w); - thread_ids.insert(w); - } else if (WIFEXITED(status) || WIFSIGNALED(status)) { - threads.erase(w); - thread_ids.erase(w); - } - } -} - -bool NormalProcess::attach() -{ - if(attached) - { - if(!suspended) - return suspend(); - return true; - } - - set threads; - vector thread_vec; - - if (!getThreadIDs(thread_vec)) - return false; - - for (vector::iterator it = thread_vec.begin(); it != thread_vec.end(); ++it) { - if (ptrace(PTRACE_ATTACH, *it, NULL, NULL) == -1) - { - // no, we got an error - perror("ptrace attach error"); - cerr << "attach failed on pid " << *it << endl; - continue; - } - threads.insert(*it); - } - - thread_ids.clear(); - waitForSuspend(threads); - - if (thread_ids.empty()) { - cerr << "couldn't attach to any threads" << endl; - return false; - } - - if (!threads.empty()) - cerr << "couldn't attach to some threads" << endl; - - suspended = true; - - int proc_pid_mem = open(memFile.c_str(),O_RDONLY); - if(proc_pid_mem == -1) - { - ptrace(PTRACE_DETACH, my_pid, NULL, NULL); - cerr << memFile << endl; - cerr << "couldn't open /proc/" << my_pid << "/mem" << endl; - perror("open(memFile.c_str(),O_RDONLY)"); - return false; - } - else - { - attached = true; - - memFileHandle = proc_pid_mem; - return true; // we are attached - } -} - -bool NormalProcess::detach() -{ - if(!attached) return true; - if(!suspended) suspend(); - int result = 0; - // close /proc/PID/mem - result = close(memFileHandle); - if(result == -1) - { - cerr << "couldn't close /proc/"<< my_pid <<"/mem" << endl; - perror("mem file close"); - return false; - } - else - { - for (set::iterator it = thread_ids.begin(); it != thread_ids.end();) { - // detach - result = ptrace(PTRACE_DETACH, *it, NULL, NULL); - if(result == -1) - { - cerr << "couldn't detach from process pid" << *it << endl; - perror("ptrace detach"); - return false;; - } - thread_ids.erase(it++); - } - - attached = false; - return true; - } -} diff --git a/library/DFProcess-windows-SHM.cpp b/library/DFProcess-windows-SHM.cpp deleted file mode 100644 index ae5b71e77..000000000 --- a/library/DFProcess-windows-SHM.cpp +++ /dev/null @@ -1,428 +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 "PlatformInternal.h" -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "SHMProcess.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -#include "shms.h" -#include "mod-core.h" -using namespace DFHack; - -SHMProcess::Private::Private(SHMProcess * self_) -{ - memdescriptor = NULL; - process_ID = 0; - attached = false; - locked = false; - identified = false; - useYield = 0; - DFSVMutex = 0; - DFCLMutex = 0; - DFCLSuspendMutex = 0; - self = self_; -} - -bool SHMProcess::Private::SetAndWait (uint32_t state) -{ - uint32_t cnt = 0; - if(!attached) return false; - SHMCMD = state; - - while (SHMCMD == state) - { - // yield the CPU, only on single-core CPUs - if(useYield) - { - SCHED_YIELD - } - if(cnt == 10000) - { - if(!AreLocksOk())// DF not there anymore? - { - UnmapViewOfFile(shm_addr); - FreeLocks(); - attached = locked = identified = false; - // we aren't the current process anymore - throw Error::SHMServerDisappeared(); - } - else - { - cnt = 0; - } - } - cnt++; - } - // server returned a generic error - if(SHMCMD == CORE_ERROR) - { - return false; - } - return true; -} - -bool SHMProcess::SetAndWait (uint32_t state) -{ - return d->SetAndWait(state); -} - -uint32_t OS_getAffinity() -{ - HANDLE hProcess = GetCurrentProcess(); - DWORD dwProcessAffinityMask, dwSystemAffinityMask; - GetProcessAffinityMask( hProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ); - return dwProcessAffinityMask; -} - -void SHMProcess::Private::FreeLocks() -{ - attachmentIdx = -1; - if(DFCLMutex != 0) - { - ReleaseMutex(DFCLMutex); - CloseHandle(DFCLMutex); - DFCLMutex = 0; - } - if(DFSVMutex != 0) - { - CloseHandle(DFSVMutex); - DFSVMutex = 0; - } - if(DFCLSuspendMutex != 0) - { - ReleaseMutex(DFCLSuspendMutex); - CloseHandle(DFCLSuspendMutex); - // FIXME: maybe also needs ReleaseMutex! - DFCLSuspendMutex = 0; - locked = false; - } -} - -bool SHMProcess::Private::GetLocks() -{ - char name[256]; - // try to acquire locks - // look at the server lock, if it's locked, the server is present - sprintf(name,"DFSVMutex-%d",process_ID); - DFSVMutex = OpenMutex(SYNCHRONIZE,0, name); - if(DFSVMutex == 0) - { - // cerr << "can't open sv lock" << endl; - return false; - } - // unlike the F_TEST of lockf, this one actually locks. we have to release - if(WaitForSingleObject(DFSVMutex,0) == 0) - { - ReleaseMutex(DFSVMutex); - // cerr << "sv lock not locked" << endl; - CloseHandle(DFSVMutex); - DFSVMutex = 0; - return false; - } - - for(int i = 0; i < SHM_MAX_CLIENTS; i++) - { - // open the client suspend locked - sprintf(name, "DFCLSuspendMutex-%d-%d",process_ID,i); - DFCLSuspendMutex = OpenMutex(SYNCHRONIZE,0, name); - if(DFCLSuspendMutex == 0) - { - //cerr << "can't open cl S-lock " << i << endl; - // couldn't open lock - continue; - } - - // open the client lock, try to lock it - - sprintf(name,"DFCLMutex-%d-%d",process_ID,i); - DFCLMutex = OpenMutex(SYNCHRONIZE,0,name); - if(DFCLMutex == 0) - { - //cerr << "can't open cl lock " << i << endl; - CloseHandle(DFCLSuspendMutex); - locked = false; - DFCLSuspendMutex = 0; - continue; - } - uint32_t waitstate = WaitForSingleObject(DFCLMutex,0); - if(waitstate == WAIT_FAILED || waitstate == WAIT_TIMEOUT ) - { - //cerr << "can't acquire cl lock " << i << endl; - CloseHandle(DFCLSuspendMutex); - locked = false; - DFCLSuspendMutex = 0; - CloseHandle(DFCLMutex); - DFCLMutex = 0; - continue; - } - // ok, we have all the locks we need! - attachmentIdx = i; - return true; - } - CloseHandle(DFSVMutex); - DFSVMutex = 0; - // cerr << "can't get any client locks" << endl; - return false; -} - -// is the other side still there? -bool SHMProcess::Private::AreLocksOk() -{ - // both locks are inited (we hold our lock) - if(DFCLMutex != 0 && DFSVMutex != 0) - { - // try if CL mutex is free - switch (WaitForSingleObject(DFSVMutex,0)) - { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - { - ReleaseMutex(DFSVMutex); - return false; - } - case WAIT_TIMEOUT: - { - // mutex is held by DF - return true; - } - default: - case WAIT_FAILED: - { - // TODO: now how do I respond to this? - return false; - } - } - } - return false; -} - -bool SHMProcess::Private::validate(VersionInfoFactory * factory) -{ - // try to identify the DF version - IMAGE_NT_HEADERS pe_header; - IMAGE_SECTION_HEADER sections[16]; - HMODULE hmod = NULL; - DWORD junk; - HANDLE hProcess; - bool found = false; - identified = false; - // open process, we only need the process open - hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, process_ID ); - if (NULL == hProcess) - return false; - - // try getting the first module of the process - if(EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk) == 0) - { - CloseHandle(hProcess); - // cout << "EnumProcessModules fail'd" << endl; - return false; - } - // got base ;) - uint32_t base = (uint32_t)hmod; - - // read from this process - uint32_t pe_offset = self->Process::readDWord(base+0x3C); - self->read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); - self->read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); - - VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp); - if(vinfo) - { - VersionInfo *m = new VersionInfo(*vinfo); - m->RebaseAll(base); - memdescriptor = m; - m->setParentProcess(self); - identified = true; - vector_start = memdescriptor->getGroup("vector")->getOffset("start"); - CloseHandle(hProcess); - return true; - } - return false; -} - -bool SHMProcess::getThreadIDs(vector & threads ) -{ - HANDLE AllThreads = INVALID_HANDLE_VALUE; - THREADENTRY32 te32; - - AllThreads = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); - if( AllThreads == INVALID_HANDLE_VALUE ) - { - return false; - } - te32.dwSize = sizeof(THREADENTRY32 ); - - if( !Thread32First( AllThreads, &te32 ) ) - { - CloseHandle( AllThreads ); - return false; - } - - do - { - if( te32.th32OwnerProcessID == d->process_ID ) - { - threads.push_back(te32.th32ThreadID); - } - } while( Thread32Next(AllThreads, &te32 ) ); - - CloseHandle( AllThreads ); - return true; -} - -//FIXME: use VirtualQuery to probe for memory ranges, cross-reference with base-corrected PE segment entries -void SHMProcess::getMemRanges( vector & ranges ) -{ - // BLAH - ranges.clear(); -} - -bool SHMProcess::acquireSuspendLock() -{ - return ( WaitForSingleObject(d->DFCLSuspendMutex,INFINITE) == 0 ); -} - -bool SHMProcess::releaseSuspendLock() -{ - return ( ReleaseMutex(d->DFCLSuspendMutex) != 0); -} - - -bool SHMProcess::attach() -{ - if(d->attached) - { - if(!d->locked) - return suspend(); - return true; - } - //cerr << "attach" << endl;// FIXME: throw - if(!d->GetLocks()) - { - //cerr << "server is full or not really there!" << endl; - return false; - } - - /* - * Locate the segment. - */ - char shmname [256]; - sprintf(shmname,"DFShm-%d",d->process_ID); - HANDLE shmHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS,false,shmname); - if(!shmHandle) - { - d->FreeLocks(); - //ReleaseMutex(d->DFCLMutex); - return false; // we couldn't lock it - } - - /* - * Attach the segment - */ - d->shm_addr = (char *) MapViewOfFile(shmHandle,FILE_MAP_ALL_ACCESS, 0,0, SHM_SIZE); - if(!d->shm_addr) - { - CloseHandle(shmHandle); - //ReleaseMutex(d->DFCLMutex); - d->FreeLocks(); - return false; // we couldn't attach the mapping // FIXME: throw - } - // we close the handle right here - it's not needed anymore - CloseHandle(shmHandle); - - d->attached = true; - if(!suspend()) - { - UnmapViewOfFile(d->shm_addr); - d->FreeLocks(); - //cerr << "unable to suspend" << endl;// FIXME: throw - return false; - } - return true; -} - -bool SHMProcess::detach() -{ - if(!d->attached) return true; - if(d->locked) - { - resume(); - } - // detach segment - UnmapViewOfFile(d->shm_addr); - // release it for some other client - //ReleaseMutex(d->DFCLMutex); // we keep the mutex handles - d->FreeLocks(); - d->attached = false; - d->locked = false; - d->shm_addr = false; - return true; -} - -void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -void SHMProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - write(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -string SHMProcess::doReadClassName (uint32_t vptr) -{ - int rtti = Process::readDWord(vptr - 0x4); - int typeinfo = Process::readDWord(rtti + 0xC); - string raw = readCString(typeinfo + 0xC); // skips the .?AV - raw.resize(raw.length() - 2);// trim @@ from end - return raw; -} - -string SHMProcess::getPath() -{ - HMODULE hmod; - DWORD junk; - char String[255]; - HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, d->process_ID ); //get the handle from the process ID - EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle - GetModuleFileNameEx(hProcess,hmod,String,sizeof(String)); //get the filename from the module - string out(String); - return(out.substr(0,out.find_last_of("\\"))); -} - -char * SHMProcess::getSHMStart (void) -{ - if(!d->locked) throw Error::MemoryAccessDenied(0xdeadbeef); - - return d->shm_addr; -} diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp deleted file mode 100644 index 8a8cd45fa..000000000 --- a/library/DFProcess-windows.cpp +++ /dev/null @@ -1,611 +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 "PlatformInternal.h" -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "ProcessFactory.h" -#include "MicrosoftSTL.h" -#include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -using namespace DFHack; - -namespace -{ - class NormalProcess : public Process - { - private: - VersionInfo * my_descriptor; - HANDLE my_handle; - vector threads; - vector stoppedthreads; - uint32_t my_pid; - string memFile; - bool attached; - bool suspended; - bool identified; - uint8_t vector_start; - IMAGE_NT_HEADERS pe_header; - IMAGE_SECTION_HEADER * sections; - uint32_t base; - MicrosoftSTL stl; - public: - NormalProcess(uint32_t pid, VersionInfoFactory * factory); - ~NormalProcess(); - bool attach(); - bool detach(); - - bool suspend(); - bool asyncSuspend(); - bool resume(); - bool forceresume(); - - void readQuad(const uint32_t address, uint64_t & value); - void writeQuad(const uint32_t address, const uint64_t value); - - void readDWord(const uint32_t address, uint32_t & value); - void writeDWord(const uint32_t address, const uint32_t value); - - void readFloat(const uint32_t address, float & value); - - void readWord(const uint32_t address, uint16_t & value); - void writeWord(const uint32_t address, const uint16_t value); - - void readByte(const uint32_t address, uint8_t & value); - void writeByte(const uint32_t address, const uint8_t value); - - void read( uint32_t address, uint32_t length, uint8_t* buffer); - void write(uint32_t address, uint32_t length, uint8_t* buffer); - - void readSTLVector(const uint32_t address, t_vecTriplet & triplet); - void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); - const std::string readSTLString (uint32_t offset); - size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - size_t writeSTLString(const uint32_t address, const std::string writeString); - // get class name of an object with rtti/type info - std::string doReadClassName(uint32_t vptr); - - const std::string readCString (uint32_t offset); - - bool isSuspended(); - bool isAttached(); - bool isIdentified(); - - bool getThreadIDs(std::vector & threads ); - void getMemRanges(std::vector & ranges ); - VersionInfo *getDescriptor(); - int getPID(); - std::string getPath(); - // get module index by name and version. bool 1 = error - bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { OUTPUT=0; return false;}; - // get the SHM start if available - char * getSHMStart (void){return 0;}; - // set a SHM command and wait for a response - bool SetAndWait (uint32_t state){return false;}; - }; - -} - -Process* DFHack::createNormalProcess(uint32_t pid, VersionInfoFactory * factory) -{ - return new NormalProcess(pid, factory); -} - -NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory) -: my_pid(pid) -{ - my_descriptor = NULL; - attached = false; - suspended = false; - base = 0; - sections = 0; - - HMODULE hmod = NULL; - DWORD needed; - bool found = false; - - identified = false; - // open process - my_handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, my_pid ); - if (NULL == my_handle) - return; - - // try getting the first module of the process - if(EnumProcessModules(my_handle, &hmod, sizeof(hmod), &needed) == 0) - { - CloseHandle(my_handle); - my_handle=0; - // cout << "EnumProcessModules fail'd" << endl; - return; //if enumprocessModules fails, give up - } - - // got base ;) - base = (uint32_t)hmod; - - // read from this process - try - { - uint32_t pe_offset = Process::readDWord(base+0x3C); - read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); - const size_t sectionsSize = sizeof(IMAGE_SECTION_HEADER) * pe_header.FileHeader.NumberOfSections; - sections = (IMAGE_SECTION_HEADER *) malloc(sectionsSize); - read(base + pe_offset + sizeof(pe_header), sectionsSize, (uint8_t *)sections); - } - catch (exception &) - { - CloseHandle(my_handle); - my_handle = 0; - return; - } - //cout << "PE Timestamp: " << hex << pe_header.FileHeader.TimeDateStamp << dec << endl; - VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp); - if(vinfo) - { - /* - cout << "Using version " << vinfo->getName() << ". Offsets follow:" << endl; - cout << "--------------------------------------------------------------" << endl; - cout << vinfo->PrintOffsets(); - cout << "--------------------------------------------------------------" << endl; - */ - // only enumerate threads if this is a valid DF process. the enumeration is costly. - vector threads_ids; - if(!getThreadIDs( threads_ids )) - { - // thread enumeration failed. - CloseHandle(my_handle); - my_handle = 0; - return; - } - identified = true; - // give the process a data model and memory layout fixed for the base of first module - my_descriptor = new VersionInfo(*vinfo); - my_descriptor->RebaseAll(base); - // keep track of created memory_info object so we can destroy it later - my_descriptor->setParentProcess(this); - try - { - vector_start = my_descriptor->getGroup("vector")->getOffset("start"); - stl.init(this); - } - catch (DFHack::Error::UnsetMemoryDefinition &) - { - CloseHandle(my_handle); - my_handle = 0; - identified = false; - return; - } - for(size_t i = 0; i < threads_ids.size();i++) - { - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]); - if(hThread) - threads.push_back(hThread); - else - cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl; - } - } - else - { - // close handles of processes that aren't DF - //cout << "ABOUT TO FREE HANDLE" << endl; - CloseHandle(my_handle); - //cout << "FREE'D HANDLE" << endl; - my_handle = 0; - } -} - -NormalProcess::~NormalProcess() -{ - if(attached) - { - detach(); - } - // destroy our rebased copy of the memory descriptor - delete my_descriptor; - if(my_handle != NULL) - { - CloseHandle(my_handle); - } - for(size_t i = 0; i < threads.size(); i++) - CloseHandle(threads[i]); - if(sections != NULL) - free(sections); -} - -VersionInfo * NormalProcess::getDescriptor() -{ - return my_descriptor; -} - -int NormalProcess::getPID() -{ - return my_pid; -} - -bool NormalProcess::isSuspended() -{ - return suspended; -} -bool NormalProcess::isAttached() -{ - return attached; -} - -bool NormalProcess::isIdentified() -{ - return identified; -} - -bool NormalProcess::asyncSuspend() -{ - return suspend(); -} - -bool NormalProcess::suspend() -{ - if(!attached) - return false; - if(suspended) - { - return true; - } - for(size_t i = 0; i < threads.size(); i++) - { - stoppedthreads.push_back(threads[i]); - SuspendThread(threads[i]); - } - suspended = true; - return true; -} - -bool NormalProcess::forceresume() -{ - if(!attached) - return false; - for(size_t i = 0; i < threads.size(); i++) - while (ResumeThread(threads[i]) > 1); - suspended = false; - return true; -} - - -bool NormalProcess::resume() -{ - if(!attached) - return false; - if(!suspended) - { - return true; - } - for(size_t i = 0; i < stoppedthreads.size(); i++) - ResumeThread(stoppedthreads[i]); - stoppedthreads.clear(); - suspended = false; - return true; -} - -bool NormalProcess::attach() -{ - if(attached) - { - if(!suspended) - return suspend(); - return true; - } - attached = true; - suspend(); - - return true; -} - - -bool NormalProcess::detach() -{ - if(!attached) return true; - resume(); - attached = false; - return true; -} - -bool NormalProcess::getThreadIDs(vector & threads ) -{ - HANDLE AllThreads = INVALID_HANDLE_VALUE; - THREADENTRY32 te32; - - AllThreads = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); - if( AllThreads == INVALID_HANDLE_VALUE ) - { - return false; - } - te32.dwSize = sizeof(THREADENTRY32 ); - - if( !Thread32First( AllThreads, &te32 ) ) - { - CloseHandle( AllThreads ); - return false; - } - - do - { - if( te32.th32OwnerProcessID == my_pid ) - { - threads.push_back(te32.th32ThreadID); - } - } while( Thread32Next(AllThreads, &te32 ) ); - - CloseHandle( AllThreads ); - return true; -} -/* -typedef struct _MEMORY_BASIC_INFORMATION -{ - void * BaseAddress; - void * AllocationBase; - uint32_t AllocationProtect; - size_t RegionSize; - uint32_t State; - uint32_t Protect; - uint32_t Type; -} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; -*/ -/* -//Internal structure used to store heap block information. -struct HeapBlock -{ - PVOID dwAddress; - DWORD dwSize; - DWORD dwFlags; - ULONG reserved; -}; -*/ -void HeapNodes(DWORD pid, map & heaps) -{ - // Create debug buffer - PDEBUG_BUFFER db = RtlCreateQueryDebugBuffer(0, FALSE); - // Get process heap data - RtlQueryProcessDebugInformation( pid, PDI_HEAPS/* | PDI_HEAP_BLOCKS*/, db); - ULONG heapNodeCount = db->HeapInformation ? *PULONG(db->HeapInformation):0; - PDEBUG_HEAP_INFORMATION heapInfo = PDEBUG_HEAP_INFORMATION(PULONG(db-> HeapInformation) + 1); - // Go through each of the heap nodes and dispaly the information - for (unsigned int i = 0; i < heapNodeCount; i++) - { - heaps[heapInfo[i].Base] = i; - } - // Clean up the buffer - RtlDestroyQueryDebugBuffer( db ); -} - -// FIXME: NEEDS TESTING! -void NormalProcess::getMemRanges( vector & ranges ) -{ - MEMORY_BASIC_INFORMATION MBI; - map heaps; - uint64_t movingStart = 0; - map nameMap; - - // get page size - SYSTEM_INFO si; - GetSystemInfo(&si); - uint64_t PageSize = si.dwPageSize; - // enumerate heaps - HeapNodes(my_pid, heaps); - // go through all the VM regions, convert them to our internal format - while (VirtualQueryEx(this->my_handle, (const void*) (movingStart), &MBI, sizeof(MBI)) == sizeof(MBI)) - { - movingStart = ((uint64_t)MBI.BaseAddress + MBI.RegionSize); - if(movingStart % PageSize != 0) - movingStart = (movingStart / PageSize + 1) * PageSize; - // skip empty regions and regions we share with other processes (DLLs) - if( !(MBI.State & MEM_COMMIT) /*|| !(MBI.Type & MEM_PRIVATE)*/ ) - continue; - t_memrange temp; - temp.start = (uint64_t) MBI.BaseAddress; - temp.end = ((uint64_t)MBI.BaseAddress + (uint64_t)MBI.RegionSize); - temp.read = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READONLY || MBI.Protect & PAGE_READWRITE; - temp.write = MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READWRITE; - temp.execute = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_EXECUTE; - temp.valid = true; - if(!GetModuleBaseName(this->my_handle, (HMODULE) temp.start, temp.name, 1024)) - { - if(nameMap.count(temp.start)) - { - // potential buffer overflow... - strcpy(temp.name, nameMap[temp.start].c_str()); - } - else - { - // filter away shared segments without a name. - if( !(MBI.Type & MEM_PRIVATE) ) - continue; - else - { - // could be a heap? - if(heaps.count(temp.start)) - { - sprintf(temp.name,"HEAP %d",heaps[temp.start]); - } - else temp.name[0]=0; - } - - - - } - } - else - { - // this is our executable! (could be generalized to pull segments from libs, but whatever) - if(base == temp.start) - { - for(int i = 0; i < pe_header.FileHeader.NumberOfSections; i++) - { - char sectionName[9]; - memcpy(sectionName,sections[i].Name,8); - sectionName[8] = 0; - string nm; - nm.append(temp.name); - nm.append(" : "); - nm.append(sectionName); - nameMap[temp.start + sections[i].VirtualAddress] = nm; - } - } - else - continue; - } - ranges.push_back(temp); - } -} - -void NormalProcess::readByte (const uint32_t offset,uint8_t &result) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint8_t), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::readWord (const uint32_t offset, uint16_t &result) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint16_t), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::readDWord (const uint32_t offset, uint32_t &result) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint32_t), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::readQuad (const uint32_t offset, uint64_t &result) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(uint64_t), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::readFloat (const uint32_t offset, float &result) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, &result, sizeof(float), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::read (const uint32_t offset, uint32_t size, uint8_t *target) -{ - if(!ReadProcessMemory(my_handle, (int*) offset, target, size, NULL)) - throw Error::MemoryAccessDenied(offset); -} - -// WRITING -void NormalProcess::writeQuad (const uint32_t offset, uint64_t data) -{ - if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::writeDWord (const uint32_t offset, uint32_t data) -{ - if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -// using these is expensive. -void NormalProcess::writeWord (uint32_t offset, uint16_t data) -{ - if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::writeByte (uint32_t offset, uint8_t data) -{ - if(!WriteProcessMemory(my_handle, (int*) offset, &data, sizeof(data), NULL)) - throw Error::MemoryAccessDenied(offset); -} - -void NormalProcess::write (uint32_t offset, uint32_t size, uint8_t *source) -{ - if(!WriteProcessMemory(my_handle, (int*) offset, source, size, NULL)) - throw Error::MemoryAccessDenied(offset); -} - -// FIXME: could exploit the fact we can read more than one byte... but still, this is almost unused. -const std::string NormalProcess::readCString (const uint32_t offset) -{ - std::string temp; - int counter = 0; - char r; - while (1) - { - if(!ReadProcessMemory(my_handle, (int*) (offset + counter), &r, sizeof(uint8_t), NULL)) break; - r = Process::readByte(offset+counter); - // order is important. even if the first character is \0, we cound that as a success. It's an empty string. - counter++; - if(!r) break; - temp.append(1,r); - } - if(!counter) - throw Error::MemoryAccessDenied(offset); - return temp; -} - -void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -void NormalProcess::writeSTLVector(const uint32_t address, t_vecTriplet & triplet) -{ - write(address + vector_start, sizeof(triplet), (uint8_t *) &triplet); -} - -size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) -{ - return stl.readSTLString(offset, buffer, bufcapacity); -} - -const string NormalProcess::readSTLString (uint32_t offset) -{ - return stl.readSTLString(offset); -} - -size_t NormalProcess::writeSTLString (uint32_t address, string str) -{ - return stl.writeSTLString(address, str); -} - -string NormalProcess::doReadClassName (uint32_t vptr) -{ - return stl.readClassName(vptr); -} - -string NormalProcess::getPath() -{ - HMODULE hmod; - DWORD junk; - char String[255]; - EnumProcessModules(my_handle, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle - GetModuleFileNameEx(my_handle,hmod,String,sizeof(String)); //get the filename from the module - string out(String); - return(out.substr(0,out.find_last_of("\\"))); -} diff --git a/library/DFProcessEnumerator.cpp b/library/DFProcessEnumerator.cpp deleted file mode 100644 index 25e790bbb..000000000 --- a/library/DFProcessEnumerator.cpp +++ /dev/null @@ -1,391 +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 "PlatformInternal.h" - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "ProcessFactory.h" - -#include "dfhack/VersionInfoFactory.h" -#include "dfhack/DFProcessEnumerator.h" -#include "dfhack/VersionInfo.h" - - -using namespace DFHack; - -typedef std::vector PROC_V; -typedef std::map PID2PROC; - -class DFHack::ProcessEnumerator::Private -{ - public: - Private(){}; - VersionInfoFactory *meminfo; - PROC_V Processes; - PID2PROC ProcMap; - Process *GetProcessObject(ProcessID ID); - void EnumPIDs (vector &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(unsigned int i = 0; i < d->bad.size(); i++) - { - if(d->bad[i] == p) - return true; - } - return false; -} - -bool BadProcesses::excise(Process* p) -{ - vector::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(unsigned 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 *p2 = createNormalProcess(ID.pid, meminfo); - if(p2->isIdentified()) - { - return p2; - } - else - { - delete p2; - } -#ifdef LINUX_BUILD - Process *p3 = createWineProcess(ID.pid, meminfo); - if(p3->isIdentified()) - return p3; - else - delete p3; -#endif - return 0; -} - -#ifdef LINUX_BUILD -void ProcessEnumerator::Private::EnumPIDs (vector &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 &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; - if(!EnableDebugPriv()) - { - cerr << "Failed to acquire debug privileges." << endl; - } - if ( !EnumProcesses( ProcArray, sizeof(ProcArray), &memoryNeeded ) ) - { - cerr << "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 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 VersionInfoFactory(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; -} diff --git a/library/DFProcess_C.cpp b/library/DFProcess_C.cpp deleted file mode 100644 index ed9bcc285..000000000 --- a/library/DFProcess_C.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* -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 -#include -#include -#include -#include - -using namespace std; - -#include "dfhack/DFIntegers.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack-c/DFProcess_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PTR_CHECK if(p_Ptr == NULL) return -1; - -int C_ProcessID_Compare(c_processID* left, c_processID* right) -{ - if(left == NULL || right == NULL) - return PROCESSID_C_NULL; - else - { - if(left->time == right->time && left->pid == right->pid) - return PROCESSID_C_EQ; - else if(left->time < right->time || left->pid < right->pid) - return PROCESSID_C_LT; - else - return PROCESSID_C_GT; - } -} - -#define FUNCTION_FORWARD(func_name) \ -int Process_##func_name (DFHackObject* p_Ptr) \ -{ \ - if(p_Ptr == NULL) \ - return -1; \ - if(((DFHack::Process*)p_Ptr)->func_name()) \ - return 1; \ - else \ - return 0; \ -} - -FUNCTION_FORWARD(attach) -FUNCTION_FORWARD(detach) -FUNCTION_FORWARD(suspend) -FUNCTION_FORWARD(asyncSuspend) -FUNCTION_FORWARD(resume) -FUNCTION_FORWARD(forceresume) -FUNCTION_FORWARD(isSuspended) -FUNCTION_FORWARD(isAttached) -FUNCTION_FORWARD(isIdentified) -FUNCTION_FORWARD(isSnapshot) - -#define MEMREAD_FUNC_FORWARD(func_name, type) \ -int Process_##func_name(DFHackObject* p_Ptr, uint32_t address, type* value) \ -{ \ - PTR_CHECK \ - ((DFHack::Process*)p_Ptr)->func_name(address, *value); \ - return 1; \ -} - -#define MEMWRITE_FUNC_FORWARD(func_name, type) \ -int Process_##func_name(DFHackObject* p_Ptr, uint32_t address, type value) \ -{ \ - PTR_CHECK \ - ((DFHack::Process*)p_Ptr)->func_name(address, value); \ - return 1; \ -} - -MEMREAD_FUNC_FORWARD(readQuad, uint64_t) -MEMWRITE_FUNC_FORWARD(writeQuad, uint64_t) - -MEMREAD_FUNC_FORWARD(readDWord, uint32_t) -MEMWRITE_FUNC_FORWARD(writeDWord, uint32_t) - -MEMREAD_FUNC_FORWARD(readWord, uint16_t) -MEMWRITE_FUNC_FORWARD(writeWord, uint16_t) - -MEMREAD_FUNC_FORWARD(readFloat, float) - -MEMREAD_FUNC_FORWARD(readByte, uint8_t) -MEMWRITE_FUNC_FORWARD(writeByte, uint8_t) - -MEMREAD_FUNC_FORWARD(readSTLVector, t_vecTriplet); - -uint8_t* Process_read(DFHackObject* p_Ptr, uint32_t address, uint32_t length) -{ - if(p_Ptr == NULL || alloc_ubyte_buffer_callback == NULL) - return NULL; - - uint8_t* buf; - - ((*alloc_ubyte_buffer_callback)(&buf, length)); - - if(buf == NULL) - return NULL; - - ((DFHack::Process*)p_Ptr)->read(address, length, buf); - - return buf; -} - -void Process_write(DFHackObject* p_Ptr, uint32_t address, uint32_t length, uint8_t* buffer) -{ - if(p_Ptr == NULL || buffer == NULL) - return; - - ((DFHack::Process*)p_Ptr)->write(address, length, buffer); -} - -const char* Process_readString(DFHackObject* p_Ptr, uint32_t offset) -{ - if(p_Ptr == NULL || alloc_char_buffer_callback == NULL) - return NULL; - - std::string pString = ((DFHack::Process*)p_Ptr)->readSTLString(offset); - - if(pString.length() > 0) - { - size_t length = pString.length(); - - char* buf; - - //add 1 for the null terminator - ((*alloc_char_buffer_callback)(&buf, length + 1)); - - if(buf == NULL) - return NULL; - - memset(buf, '\n', length + 1); - - pString.copy(buf, length); - - return buf; - } - else - return ""; -} - -const char* Process_getPath(DFHackObject* p_Ptr) -{ - if(p_Ptr == NULL || alloc_char_buffer_callback == NULL) - return NULL; - - std::string pString = ((DFHack::Process*)p_Ptr)->getPath(); - - if(pString.length() > 0) - { - size_t length = pString.length(); - - char* buf; - - //add 1 for the null terminator - ((*alloc_char_buffer_callback)(&buf, length + 1)); - - if(buf == NULL) - return NULL; - - memset(buf, '\0', length + 1); - - pString.copy(buf, length); - - return buf; - } - else - return ""; -} - -const char* Process_readClassName(DFHackObject* p_Ptr, uint32_t vptr) -{ - if(p_Ptr == NULL || alloc_char_buffer_callback == NULL) - return NULL; - - std::string cString = ((DFHack::Process*)p_Ptr)->readClassName(vptr); - - if(cString.length() > 0) - { - size_t length = cString.length(); - - char* buf; - - //add 1 for the null terminator - ((*alloc_char_buffer_callback)(&buf, length + 1)); - - if(buf == NULL) - return NULL; - - memset(buf, '\0', length + 1); - - cString.copy(buf, length); - - return buf; - } - else - return ""; -} - -uint32_t* Process_getThreadIDs(DFHackObject* p_Ptr) -{ - if(p_Ptr == NULL || alloc_uint_buffer_callback == NULL) - return NULL; - - std::vector threads; - - if(((DFHack::Process*)p_Ptr)->getThreadIDs(threads)) - { - uint32_t* buf; - if(threads.size() > 0) - { - ((*alloc_uint_buffer_callback)(&buf, threads.size())); - if(buf == NULL) - return NULL; - copy(threads.begin(), threads.end(), buf); - return buf; - } - } - return NULL; -} - -t_memrange* Process_getMemRanges(DFHackObject* p_Ptr) -{ - if(p_Ptr == NULL || alloc_memrange_buffer_callback == NULL) - return NULL; - - std::vector ranges; - - ((DFHack::Process*)p_Ptr)->getMemRanges(ranges); - - if(ranges.size() > 0) - { - t_memrange* buf; - uint32_t* rangeDescriptorBuf = (uint32_t*)calloc(ranges.size(), sizeof(uint32_t)); - - for(uint32_t i = 0; i < ranges.size(); i++) - { - t_memrange* r = &ranges[i]; - rangeDescriptorBuf[i] = (uint32_t)(r->end - r->start); - } - - ((*alloc_memrange_buffer_callback)(&buf, rangeDescriptorBuf, ranges.size())); - free(rangeDescriptorBuf); - if(buf == NULL) - return NULL; - - for(uint32_t i = 0; i < ranges.size(); i++) - { - t_memrange* r = &ranges[i]; - buf[i].start = r->start; - buf[i].end = r->end; - memset(buf[i].name, '\0', 1024); - strncpy(buf[i].name, r->name, 1024); - buf[i].read = r->read; - buf[i].write = r->write; - buf[i].execute = r->execute; - buf[i].shared = r->shared; - buf[i].valid = r->valid; - memcpy(buf[i].buffer, r->buffer, r->end - r->start); - } - return buf; - } - return NULL; -} - -int Process_getPID(DFHackObject* p_Ptr, int32_t* pid) -{ - if(p_Ptr == NULL) - { - *pid = -1; - return -1; - } - else - { - *pid = ((DFHack::Process*)p_Ptr)->getPID(); - return 1; - } -} - -int Process_getModuleIndex(DFHackObject* p_Ptr, char* name, uint32_t version, uint32_t* output) -{ - PTR_CHECK - - if(((DFHack::Process*)p_Ptr)->getModuleIndex(name, version, *output)) - return 1; - else - return 0; -} - -int Process_SetAndWait(DFHackObject* p_Ptr, uint32_t state) -{ - PTR_CHECK - - if(((DFHack::Process*)p_Ptr)->SetAndWait(state)) - return 1; - else - return 0; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/DFTileTypes_C.cpp b/library/DFTileTypes_C.cpp deleted file mode 100644 index 2832d36b0..000000000 --- a/library/DFTileTypes_C.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -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 "Internal.h" -#include "dfhack/DFTileTypes.h" -#include "dfhack-c/DFTileTypes_C.h" - -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::tileShape(in); -} - -int DFHack_getTileType(int index, TileRow* tPtr) -{ - if(index >= TILE_TYPE_ARRAY_LENGTH) - return 0; - - *tPtr = tileTypeTable[index]; - return 1; -} diff --git a/library/DFTypes_C.cpp b/library/DFTypes_C.cpp deleted file mode 100644 index 22ee57089..000000000 --- a/library/DFTypes_C.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* -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 "Internal.h" - -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "dfhack/DFTypes.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack/modules/Materials.h" -using namespace DFHack; - -/* -I believe this is what they call "the bad kind of clever", but writing out registration functions for each callback just feels *so* wrong... - -The output of this macro is something like this... - -void RegisterByteBufferCallback(int(*fptr)(int8_t*, uint32_t)) -{ - alloc_byte_buffer_callback = fptr; -} - -*/ -#define BUILD(a) a ## BufferCallback -#define REG_MACRO(type_name, type, callback) void BUILD(Register ## type_name) (int (*fptr)(type, uint32_t)) { callback = fptr; } - -/* -The output of this macro is something like this... - -void UnregisterByteBufferCallback() -{ - alloc_byte_buffer_callback = NULL; -} - -*/ -#define UNREG_MACRO(type_name, callback) void BUILD(Unregister ## type_name) () { callback = NULL; } - -#ifdef __cplusplus -extern "C" { -#endif - -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; - -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; - -int (*alloc_char_buffer_callback)(char**, uint32_t) = 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; - -int (*alloc_feature_buffer_callback)(t_feature**, uint32_t) = NULL; -int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t) = NULL; -int (*alloc_screen_buffer_callback)(t_screen**, uint32_t) = NULL; - -int (*alloc_tree_buffer_callback)(dfh_plant**, uint32_t) = NULL; - -int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t) = NULL; - -int (*alloc_customWorkshop_buffer_callback)(t_customWorkshop**, uint32_t) = NULL; -int (*alloc_material_buffer_callback)(t_material**, uint32_t) = NULL; - -int (*alloc_creaturetype_buffer_callback)(c_creaturetype**, c_creaturetype_descriptor*, 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 (*alloc_grassvein_buffer_callback)(t_grassvein**, uint32_t) = NULL; -int (*alloc_worldconstruction_buffer_callback)(t_worldconstruction**, uint32_t) = NULL; - -int (*alloc_featuremap_buffer_callback)(c_featuremap_node**, uint32_t*, uint32_t) = NULL; - -//int (*alloc_bodypart_buffer_callback)(t_bodypart**, uint32_t) = NULL; -REG_MACRO(Byte, int8_t**, alloc_byte_buffer_callback) -REG_MACRO(Short, int16_t**, alloc_short_buffer_callback) -REG_MACRO(Int, int32_t**, alloc_int_buffer_callback) -REG_MACRO(UByte, uint8_t**, alloc_ubyte_buffer_callback) -REG_MACRO(UShort, uint16_t**, alloc_ushort_buffer_callback) -REG_MACRO(UInt, uint32_t**, alloc_uint_buffer_callback) -REG_MACRO(Char, char**, alloc_char_buffer_callback) -REG_MACRO(Matgloss, t_matgloss**, alloc_matgloss_buffer_callback) -REG_MACRO(DescriptorColor, t_descriptor_color**, alloc_descriptor_buffer_callback) -REG_MACRO(MatglossOther, t_matglossOther**, alloc_matgloss_other_buffer_callback) -REG_MACRO(Feature, t_feature**, alloc_feature_buffer_callback) -REG_MACRO(Hotkey, t_hotkey**, alloc_hotkey_buffer_callback) -REG_MACRO(Screen, t_screen**, alloc_screen_buffer_callback) -REG_MACRO(Tree, dfh_plant**, alloc_tree_buffer_callback) -REG_MACRO(CustomWorkshop, t_customWorkshop**, alloc_customWorkshop_buffer_callback) -REG_MACRO(Material, t_material**, alloc_material_buffer_callback) - -void RegisterMemRangeBufferCallback(int (*funcptr)(t_memrange**, uint32_t*, uint32_t)) -{ - alloc_memrange_buffer_callback = funcptr; -} - -UNREG_MACRO(Byte, alloc_byte_buffer_callback) -UNREG_MACRO(Short, alloc_short_buffer_callback) -UNREG_MACRO(Int, alloc_int_buffer_callback) -UNREG_MACRO(UByte, alloc_ubyte_buffer_callback) -UNREG_MACRO(UShort, alloc_ushort_buffer_callback) -UNREG_MACRO(UInt, alloc_uint_buffer_callback) -UNREG_MACRO(Char, alloc_char_buffer_callback) -UNREG_MACRO(Matgloss, alloc_matgloss_buffer_callback) -UNREG_MACRO(DescriptorColor, alloc_descriptor_buffer_callback) -UNREG_MACRO(MatglossOther, alloc_matgloss_other_buffer_callback) -UNREG_MACRO(Feature, alloc_feature_buffer_callback) -UNREG_MACRO(Hotkey, alloc_hotkey_buffer_callback) -UNREG_MACRO(Screen, alloc_screen_buffer_callback) -UNREG_MACRO(Tree, alloc_tree_buffer_callback) -UNREG_MACRO(MemRange, alloc_memrange_buffer_callback) -UNREG_MACRO(CustomWorkshop, alloc_customWorkshop_buffer_callback) -UNREG_MACRO(Material, alloc_material_buffer_callback) - -void RegisterCreatureTypeBufferCallback(int (*funcptr)(c_creaturetype**, c_creaturetype_descriptor*, uint32_t)) -{ - alloc_creaturetype_buffer_callback = funcptr; -} - -UNREG_MACRO(CreatureType, alloc_creaturetype_buffer_callback) - -REG_MACRO(Vein, t_vein**, alloc_vein_buffer_callback) -REG_MACRO(FrozenLiquidVein, t_frozenliquidvein**, alloc_frozenliquidvein_buffer_callback) -REG_MACRO(SpatterVein, t_spattervein**, alloc_spattervein_buffer_callback) -REG_MACRO(GrassVein, t_grassvein**, alloc_grassvein_buffer_callback) -REG_MACRO(WorldConstruction, t_worldconstruction**, alloc_worldconstruction_buffer_callback) - -UNREG_MACRO(Vein, alloc_vein_buffer_callback) -UNREG_MACRO(FrozenLiquidVein, alloc_frozenliquidvein_buffer_callback) -UNREG_MACRO(SpatterVein, alloc_spattervein_buffer_callback) -UNREG_MACRO(GrassVein, alloc_grassvein_buffer_callback) -UNREG_MACRO(WorldConstruction, alloc_worldconstruction_buffer_callback) - -void RegisterFeatureMapBufferCallback(int (*funcptr)(c_featuremap_node**, uint32_t*, uint32_t)) -{ - alloc_featuremap_buffer_callback = funcptr; -} - -UNREG_MACRO(FeatureMap, alloc_featuremap_buffer_callback) - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/library/FakeSDL-linux.cpp b/library/FakeSDL-linux.cpp new file mode 100644 index 000000000..5a26aec4b --- /dev/null +++ b/library/FakeSDL-linux.cpp @@ -0,0 +1,247 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DFHack.h" +#include "dfhack/Core.h" +#include "dfhack/FakeSDL.h" +#include + +/* + * Plugin loading functions + */ +namespace DFHack +{ + DFLibrary * OpenPlugin (const char * filename) + { + dlerror(); + DFLibrary * ret = (DFLibrary *) dlopen(filename, RTLD_NOW); + if(!ret) + { + std::cerr << dlerror() << std::endl; + } + return ret; + } + void * LookupPlugin (DFLibrary * plugin ,const char * function) + { + return (DFLibrary *) dlsym((void *)plugin, function); + } + void ClosePlugin (DFLibrary * plugin) + { + dlclose((void *) plugin); + } +} + +/******************************************************************************* +* SDL part starts here * +*******************************************************************************/ +bool FirstCall(void); +bool inited = false; + +DFhackCExport int SDL_NumJoysticks(void) +{ + DFHack::Core & c = DFHack::Core::getInstance(); + // the 'inited' variable should be normally protected by a lock. It isn't + // this is harmless enough. only thing this can cause is a slight delay before + // DF input events start to be processed by Core + int ret = c.Update(); + if(ret == 0) + inited = true; + return ret; +} + +// ptr to the real functions +//static void (*_SDL_GL_SwapBuffers)(void) = 0; +static void (*_SDL_Quit)(void) = 0; +static int (*_SDL_Init)(uint32_t flags) = 0; +static SDL::Thread * (*_SDL_CreateThread)(int (*fn)(void *), void *data) = 0; +//static int (*_SDL_Flip)(void * some_ptr) = 0; +/* +// hook - called every tick in OpenGL mode of DF +DFhackCExport void SDL_GL_SwapBuffers(void) +{ + if(_SDL_GL_SwapBuffers) + { + if(!errorstate) + { + SHM_Act(); + } + counter ++; + _SDL_GL_SwapBuffers(); + } +} +*/ +/* +// hook - called every tick in the 2D mode of DF +DFhackCExport int SDL_Flip(void * some_ptr) +{ + if(_SDL_Flip) + { + if(!errorstate) + { + SHM_Act(); + } + counter ++; + return _SDL_Flip(some_ptr); + } + return 0; +} +*/ + +static SDL::Mutex * (*_SDL_CreateMutex)(void) = 0; +DFhackCExport SDL::Mutex * SDL_CreateMutex(void) +{ + return _SDL_CreateMutex(); +} + +static int (*_SDL_mutexP)(SDL::Mutex * mutex) = 0; +DFhackCExport int SDL_mutexP(SDL::Mutex * mutex) +{ + return _SDL_mutexP(mutex); +} + +static int (*_SDL_mutexV)(SDL::Mutex * mutex) = 0; +DFhackCExport int SDL_mutexV(SDL::Mutex * mutex) +{ + return _SDL_mutexV(mutex); +} + +static void (*_SDL_DestroyMutex)(SDL::Mutex * mutex) = 0; +DFhackCExport void SDL_DestroyMutex(SDL::Mutex * mutex) +{ + _SDL_DestroyMutex(mutex); +} + +// hook - called at program exit +DFhackCExport void SDL_Quit(void) +{ + DFHack::Core & c = DFHack::Core::getInstance(); + c.Shutdown(); + if(_SDL_Quit) + { + _SDL_Quit(); + } +} + +// called by DF to check input events +static int (*_SDL_PollEvent)(SDL::Event* event) = 0; +DFhackCExport int SDL_PollEvent(SDL::Event* event) +{ + int orig_return = _SDL_PollEvent(event); + // only send events to Core after we get first SDL_NumJoysticks call + // DF event loop is possibly polling for SDL events before things get inited properly + // SDL handles it. We don't, because we use some other parts of SDL too. + + // possible data race. whatever. it's a flag, we don't mind all that much + if(inited && event != 0) + { + DFHack::Core & c = DFHack::Core::getInstance(); + return c.SDL_Event(event, orig_return); + } + return orig_return; +} + +static uint32_t (*_SDL_ThreadID)(void) = 0; +DFhackCExport uint32_t SDL_ThreadID() +{ + return _SDL_ThreadID(); +} + +static SDL::Cond * (*_SDL_CreateCond)(void) = 0; +DFhackCExport SDL::Cond *SDL_CreateCond(void) +{ + return _SDL_CreateCond(); +} +static void (*_SDL_DestroyCond)(SDL::Cond *) = 0; +DFhackCExport void SDL_DestroyCond(SDL::Cond *cond) +{ + _SDL_DestroyCond(cond); +} +static int (*_SDL_CondSignal)(SDL::Cond *) = 0; +DFhackCExport int SDL_CondSignal(SDL::Cond *cond) +{ + return _SDL_CondSignal(cond); +} +static int (*_SDL_CondWait)(SDL::Cond *, SDL::Mutex *) = 0; +DFhackCExport int SDL_CondWait(SDL::Cond *cond, SDL::Mutex * mut) +{ + return _SDL_CondWait(cond, mut); +} + +// hook - called at program start, initialize some stuffs we'll use later +DFhackCExport int SDL_Init(uint32_t flags) +{ + freopen("stdout.log", "w", stdout); + freopen("stderr.log", "w", stderr); + // horrible casts not supported by the C or C++ standards. Only POSIX. Damn you, POSIX. + // find real functions + //_SDL_GL_SwapBuffers = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_GL_SwapBuffers"); + _SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init"); + //_SDL_Flip = (int (*)( void * )) dlsym(RTLD_NEXT, "SDL_Flip"); + _SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit"); + _SDL_CreateThread = (SDL::Thread* (*)(int (*fn)(void *), void *data))dlsym(RTLD_NEXT, "SDL_CreateThread"); + _SDL_CreateMutex = (SDL::Mutex*(*)())dlsym(RTLD_NEXT,"SDL_CreateMutex"); + _SDL_DestroyMutex = (void (*)(SDL::Mutex*))dlsym(RTLD_NEXT,"SDL_DestroyMutex"); + _SDL_mutexP = (int (*)(SDL::Mutex*))dlsym(RTLD_NEXT,"SDL_mutexP"); + _SDL_mutexV = (int (*)(SDL::Mutex*))dlsym(RTLD_NEXT,"SDL_mutexV"); + _SDL_PollEvent = (int (*)(SDL::Event*))dlsym(RTLD_NEXT,"SDL_PollEvent"); + _SDL_ThreadID = (uint32_t (*)())dlsym(RTLD_NEXT,"SDL_ThreadID"); + + _SDL_CreateCond = (SDL::Cond * (*)())dlsym(RTLD_NEXT,"SDL_CreateCond"); + _SDL_DestroyCond = (void(*)(SDL::Cond *))dlsym(RTLD_NEXT,"SDL_DestroyCond"); + _SDL_CondSignal = (int (*)(SDL::Cond *))dlsym(RTLD_NEXT,"SDL_CondSignal"); + _SDL_CondWait = (int (*)(SDL::Cond *, SDL::Mutex *))dlsym(RTLD_NEXT,"SDL_CondWait"); + + // check if we got them + if(_SDL_Init && _SDL_Quit && _SDL_CreateThread + && _SDL_CreateMutex && _SDL_DestroyMutex && _SDL_mutexP + && _SDL_mutexV && _SDL_PollEvent && _SDL_ThreadID + && _SDL_CondSignal && _SDL_CondWait && _SDL_CreateCond && _SDL_DestroyCond) + { + fprintf(stderr,"dfhack: hooking successful\n"); + } + else + { + // bail, this would be a disaster otherwise + fprintf(stderr,"dfhack: something went horribly wrong\n"); + exit(1); + } + int ret = _SDL_Init(flags); + return ret; +} diff --git a/library/shm/shms-windows.cpp b/library/FakeSDL-windows.cpp similarity index 70% rename from library/shm/shms-windows.cpp rename to library/FakeSDL-windows.cpp index 1173de74a..7c2e58343 100644 --- a/library/shm/shms-windows.cpp +++ b/library/FakeSDL-windows.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix) +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,239 +22,42 @@ must not be misrepresented as being the original software. distribution. */ -/** - * This is the source for the DF <-> dfhack shm bridge, - * to be used with SDL 1.2 and DF 40d16. Windows sucks - * using hacks like this sucks even more - */ - -#include -#include - #define DFhackCExport extern "C" __declspec(dllexport) -#include "dfhack/DFIntegers.h" +#include +#include #include #include -#include "shms.h" -#include "mod-core.h" +#include "dfhack/Core.h" +#include "dfhack/FakeSDL.h" #include -int errorstate = 0; -char *shm = 0; -int shmid = 0; -bool inited = 0; -HANDLE shmHandle = 0; - -HANDLE DFSVMutex = 0; -HANDLE DFCLMutex[SHM_MAX_CLIENTS]; -HANDLE DFCLSuspendMutex[SHM_MAX_CLIENTS]; -int held_DFCLSuspendMutex[SHM_MAX_CLIENTS]; -int numheld = SHM_MAX_CLIENTS; -bool FirstCall(); - -void OS_lockSuspendLock(int which) -{ - if(numheld == SHM_MAX_CLIENTS) - return; - // lock not held by server and can be picked up. OK. - if(held_DFCLSuspendMutex[which] == 0) - { - uint32_t state = WaitForSingleObject(DFCLSuspendMutex[which],INFINITE); - if(state == WAIT_ABANDONED || state == WAIT_OBJECT_0) - { - held_DFCLSuspendMutex[which] = 1; - numheld++; - return; - } - // lock couldn't be picked up! - errorstate = 1; - MessageBox(0,"Suspend lock locking failed. Further communication disabled!","Error", MB_OK); - return; - } - errorstate = 1; - MessageBox(0,"Server tried to lock already locked suspend lock? Further communication disabled!","Error", MB_OK); - return; -} - -void OS_releaseSuspendLock(int which) -{ - /* - if(which >=0 && which < SHM_MAX_CLIENTS) - return; - */ - if(numheld != SHM_MAX_CLIENTS) - { - MessageBox(0,"Locking system failure. Further communication disabled!","Error", MB_OK); - errorstate = 1; - return; - } - // lock hel by server and can be released -> OK - if(held_DFCLSuspendMutex[which] == 1 && ReleaseMutex(DFCLSuspendMutex[which])) - { - numheld--; - held_DFCLSuspendMutex[which] = 0; - } - // locked and not can't be released? FAIL! - else if (held_DFCLSuspendMutex[which] == 1) - { - MessageBox(0,"Suspend lock failed to unlock. Further communication disabled!","Error", MB_OK); - return; - } -} - -void SHM_Init ( void ) +/* + * Plugin loading functions + */ +namespace DFHack { - // check that we do this only once per process - if(inited) - { - MessageBox(0,"SHM_Init was called twice or more!","FUN", MB_OK); - return; - } - inited = true; - - - char clmutexname [256]; - char clsmutexname [256]; - char shmname [256]; - sprintf(shmname,"DFShm-%d",OS_getPID()); - - // create a locked server mutex - char svmutexname [256]; - sprintf(svmutexname,"DFSVMutex-%d",OS_getPID()); - DFSVMutex = CreateMutex( 0, 1, svmutexname); - if(DFSVMutex == 0) - { - MessageBox(0,"Server mutex creation failed. Further communication disabled!","Error", MB_OK); - errorstate = 1; - return; - } - // the mutex already existed. we don't want to know. - if(GetLastError() == ERROR_ALREADY_EXISTS) - { - MessageBox(0,"Server mutex already existed. Further communication disabled!","Error", MB_OK); - errorstate = 1; - return; - } - - // create client and suspend mutexes - for(int i = 0; i < SHM_MAX_CLIENTS; i++) - { - sprintf(clmutexname,"DFCLMutex-%d-%d",OS_getPID(),i); - sprintf(clsmutexname,"DFCLSuspendMutex-%d-%d",OS_getPID(),i); - - DFCLMutex[i] = CreateMutex( 0, 0, clmutexname); // client mutex, not held - DFCLSuspendMutex[i] = CreateMutex( 0, 1, clsmutexname); // suspend mutexes held on start - held_DFCLSuspendMutex[i] = 1; - - if(DFCLMutex[i] == 0 || DFCLSuspendMutex[i] == 0 || GetLastError() == ERROR_ALREADY_EXISTS) - { - MessageBox(0,"Client mutex creation failed. Close all tools before starting DF.","Error", MB_OK); - errorstate = 1; - return; - } - } - - // create virtual memory mapping - shmHandle = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,SHM_SIZE,shmname); - // if can't create or already exists -> nothing happens - if(GetLastError() == ERROR_ALREADY_EXISTS) + DFLibrary * OpenPlugin (const char * filename) { - MessageBox(0,"SHM bridge already in use","Error", MB_OK); - errorstate = 1; - return; + return (DFLibrary *) LoadLibrary(filename); } - if(!shmHandle) + void * LookupPlugin (DFLibrary * plugin ,const char * function) { - MessageBox(0,"Couldn't create SHM bridge","Error", MB_OK); - errorstate = 1; - return; + return (DFLibrary *) GetProcAddress((HMODULE)plugin, function); } - // attempt to attach the created mapping - shm = (char *) MapViewOfFile(shmHandle,FILE_MAP_ALL_ACCESS, 0,0, SHM_SIZE); - if(shm) + void ClosePlugin (DFLibrary * plugin) { - // make sure we don't stall or do crazy stuff - for(int i = 0; i < SHM_MAX_CLIENTS;i++) - { - ((uint32_t *)shm)[i] = CORE_RUNNING; - } - // init modules :) - InitModules(); - } - else - { - MessageBox(0,"Couldn't attach SHM bridge","Error", MB_OK); - errorstate = 1; - return; - } -} - -void SHM_Destroy ( void ) -{ - if(errorstate) - return; - KillModules(); - // get rid of all the locks - CloseHandle(DFSVMutex); - for(int i=0; i < SHM_MAX_CLIENTS; i++) - { - CloseHandle(DFCLSuspendMutex[i]); - CloseHandle(DFCLMutex[i]); - } -} - -uint32_t OS_getPID() -{ - return GetCurrentProcessId(); -} - -// TODO: move to some utils file -uint32_t OS_getAffinity() -{ - HANDLE hProcess = GetCurrentProcess(); - DWORD dwProcessAffinityMask, dwSystemAffinityMask; - GetProcessAffinityMask( hProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ); - return dwProcessAffinityMask; -} - - - -// is the other side still there? -bool isValidSHM(int which) -{ - // try if CL mutex is free (by locking client mutex) - uint32_t result = WaitForSingleObject(DFCLMutex[which],0); - - switch (result) - { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - { - OS_lockSuspendLock(which); - ReleaseMutex(DFCLMutex[which]); - return false; - } - case WAIT_TIMEOUT: - { - // mutex is held by a process already - return true; - } - default: - case WAIT_FAILED: - { - // TODO: now how do I respond to this? - return false; - } + FreeLibrary((HMODULE) plugin); } } - /*************************************************************************/ -// boring wrappers beyond this point. Only fix when broken +// extremely boring wrappers beyond this point. Only fix when broken -// function and variable pointer... we don't try to understand what SDL does here -typedef void * fPtr; -typedef void * vPtr; +// we don't know which of the SDL functions will be called first... so we +// just catch the first one and init all our function pointers at that time +bool FirstCall(void); +bool inited = false; +bool started_joysticks = false; /// wrappers for SDL 1.2 functions used in 40d16 /***** Condition variables @@ -268,26 +71,26 @@ SDL_CondWait SDL_DestroyCond void SDLCALL SDL_DestroyCond(SDL_cond *cond); */ -static vPtr (*_SDL_CreateCond)() = 0; -DFhackCExport vPtr SDL_CreateCond() +static SDL::Cond * (*_SDL_CreateCond)() = 0; +DFhackCExport SDL::Cond * SDL_CreateCond() { return _SDL_CreateCond(); } -static int (*_SDL_CondSignal)(vPtr cond) = 0; -DFhackCExport int SDL_CondSignal(vPtr cond) +static int (*_SDL_CondSignal)(SDL::Cond *) = 0; +DFhackCExport int SDL_CondSignal(SDL::Cond * cond) { return _SDL_CondSignal(cond); } -static int (*_SDL_CondWait)(vPtr cond, vPtr mutex) = 0; -DFhackCExport int SDL_CondWait(vPtr cond, vPtr mutex) +static int (*_SDL_CondWait)(SDL::Cond *,SDL::Mutex *) = 0; +DFhackCExport int SDL_CondWait(SDL::Cond * cond, SDL::Mutex * mutex) { return _SDL_CondWait(cond, mutex); } -static void (*_SDL_DestroyCond)(vPtr cond) = 0; -DFhackCExport void SDL_DestroyCond(vPtr cond) +static void (*_SDL_DestroyCond)(SDL::Cond * ) = 0; +DFhackCExport void SDL_DestroyCond(SDL::Cond * cond) { _SDL_DestroyCond(cond); } @@ -301,20 +104,26 @@ SDL_mutexP SDL_DestroyMutex void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex); */ -static vPtr (*_SDL_CreateMutex)(void) = 0; -DFhackCExport vPtr SDL_CreateMutex(void) +static SDL::Mutex * (*_SDL_CreateMutex)(void) = 0; +DFhackCExport SDL::Mutex * SDL_CreateMutex(void) { return _SDL_CreateMutex(); } -static int (*_SDL_mutexP)(vPtr mutex) = 0; -DFhackCExport int SDL_mutexP(vPtr mutex) +static int (*_SDL_mutexP)(SDL::Mutex * mutex) = 0; +DFhackCExport int SDL_mutexP(SDL::Mutex * mutex) { return _SDL_mutexP(mutex); } -static void (*_SDL_DestroyMutex)(vPtr mutex) = 0; -DFhackCExport void SDL_DestroyMutex(vPtr mutex) +static int (*_SDL_mutexV)(SDL::Mutex * mutex) = 0; +DFhackCExport int SDL_mutexV(SDL::Mutex * mutex) +{ + return _SDL_mutexV(mutex); +} + +static void (*_SDL_DestroyMutex)(SDL::Mutex * mutex) = 0; +DFhackCExport void SDL_DestroyMutex(SDL::Mutex * mutex) { _SDL_DestroyMutex(mutex); } @@ -585,10 +394,19 @@ DFhackCExport uint8_t * SDL_GetKeyState(int* numkeys) return _SDL_GetKeyState(numkeys); } -static int (*_SDL_PollEvent)(vPtr event) = 0; -DFhackCExport int SDL_PollEvent(vPtr event) +static int (*_SDL_PollEvent)(SDL::Event *) = 0; +DFhackCExport int SDL_PollEvent(SDL::Event * event) { - return _SDL_PollEvent(event); + int orig_return = _SDL_PollEvent(event); + // only send events to Core after we get first SDL_NumJoysticks call + // DF event loop is possibly polling for SDL events before things get inited properly + // SDL handles it. We don't, because we use some other parts of SDL too. + if(started_joysticks && event != 0) + { + DFHack::Core & c = DFHack::Core::getInstance(); + return c.SDL_Event(event, orig_return); + } + return orig_return; } /***** error handling @@ -640,20 +458,20 @@ SDL_UnloadObject extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); */ -static vPtr (*_SDL_LoadFunction)(void *handle, const char *name) = 0; -DFhackCExport vPtr SDL_LoadFunction(void *handle, const char *name) +static void * (*_SDL_LoadFunction)(SDL::Library *handle, const char *name) = 0; +DFhackCExport void * SDL_LoadFunction(SDL::Library *handle, const char *name) { return _SDL_LoadFunction(handle, name); } -static vPtr (*_SDL_LoadObject)(const char *sofile) = 0; -DFhackCExport vPtr SDL_LoadObject(const char *sofile) +extern "C" static SDL::Library * (*_SDL_LoadObject)(const char *sofile) = 0; +DFhackCExport SDL::Library * SDL_LoadObject(const char *sofile) { return _SDL_LoadObject(sofile); } -static void (*_SDL_UnloadObject)(vPtr handle) = 0; -DFhackCExport void SDL_UnloadObject(vPtr handle) +static void (*_SDL_UnloadObject)(SDL::Library * handle) = 0; +DFhackCExport void SDL_UnloadObject(SDL::Library * handle) { _SDL_UnloadObject(handle); } @@ -720,6 +538,10 @@ DFhackCExport size_t SDL_strlcpy(char *dst, const char *src, size_t maxlen) if(!_SDL_strlcpy) { HMODULE realSDLlib = LoadLibrary("SDLreal.dll"); + if(!realSDLlib) + { + exit(-111); + } _SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy"); } return _SDL_strlcpy(dst,src,maxlen); @@ -737,12 +559,8 @@ SDL_GL_SwapBuffers static void (*_SDL_Quit)(void) = 0; DFhackCExport void SDL_Quit(void) { - fprintf(stderr,"Quitting!\n"); - if(!errorstate) - { - SHM_Destroy(); - errorstate = true; - } + DFHack::Core & c = DFHack::Core::getInstance(); + c.Shutdown(); if(_SDL_Quit) { _SDL_Quit(); @@ -751,15 +569,10 @@ DFhackCExport void SDL_Quit(void) // this is supported from 0.31.04 forward DFhackCExport int SDL_NumJoysticks(void) { - if(errorstate) - return -1; - if(!inited) - { - SHM_Init(); - return -2; - } - SHM_Act(); - return -3; + DFHack::Core & c = DFHack::Core::getInstance(); + int ret = c.Update(); + started_joysticks = true; + return ret; } static void (*_SDL_GL_SwapBuffers)(void) = 0; @@ -798,8 +611,8 @@ DFhackCExport void *SDL_CreateSemaphore(uint32_t initial_value) return _SDL_CreateSemaphore(initial_value); } -static void * (*_SDL_CreateThread)(int (*fn)(void *), void *data) = 0; -DFhackCExport void *SDL_CreateThread(int (*fn)(void *), void *data) +static SDL::Thread * (*_SDL_CreateThread)(int (*fn)(void *), void *data) = 0; +DFhackCExport SDL::Thread *SDL_CreateThread(int (*fn)(void *), void *data) { if(!inited) FirstCall(); @@ -879,7 +692,7 @@ DFhackCExport uint32_t SDL_ThreadID(void) return _SDL_ThreadID(); } -// this has to be thread-safe. Let's hope it is. +// FIXME: this has to be thread-safe. bool FirstCall() { HMODULE realSDLlib = LoadLibrary("SDLreal.dll"); @@ -889,17 +702,18 @@ bool FirstCall() fprintf(stderr, "Can't load SDLreal.dll\n"); return 0; } + fprintf(stderr, "FirstCall()\n"); // stuff for DF _SDL_AddTimer = (void*(*)(uint32_t, void*, void*)) GetProcAddress(realSDLlib,"SDL_AddTimer"); - _SDL_CondSignal = (int (*)(void*))GetProcAddress(realSDLlib,"SDL_CondSignal"); - _SDL_CondWait = (int (*)(void*, void*))GetProcAddress(realSDLlib,"SDL_CondWait"); + _SDL_CondSignal = (int (*)(SDL::Cond*))GetProcAddress(realSDLlib,"SDL_CondSignal"); + _SDL_CondWait = (int (*)(SDL::Cond*, SDL::Mutex*))GetProcAddress(realSDLlib,"SDL_CondWait"); _SDL_ConvertSurface = (void*(*)(void*, void*, uint32_t))GetProcAddress(realSDLlib,"SDL_ConvertSurface"); - _SDL_CreateCond = (void*(*)())GetProcAddress(realSDLlib,"SDL_CreateCond"); - _SDL_CreateMutex = (void*(*)())GetProcAddress(realSDLlib,"SDL_CreateMutex"); + _SDL_CreateCond = (SDL::Cond*(*)())GetProcAddress(realSDLlib,"SDL_CreateCond"); + _SDL_CreateMutex = (SDL::Mutex*(*)())GetProcAddress(realSDLlib,"SDL_CreateMutex"); _SDL_CreateRGBSurface = (void*(*)(uint32_t, int, int, int, uint32_t, uint32_t, uint32_t, uint32_t))GetProcAddress(realSDLlib,"SDL_CreateRGBSurface"); _SDL_CreateRGBSurfaceFrom = (void*(*)(void*, int, int, int, int, uint32_t, uint32_t, uint32_t, uint32_t))GetProcAddress(realSDLlib,"SDL_CreateRGBSurfaceFrom"); - _SDL_DestroyCond = (void (*)(void*))GetProcAddress(realSDLlib,"SDL_DestroyCond"); - _SDL_DestroyMutex = (void (*)(void*))GetProcAddress(realSDLlib,"SDL_DestroyMutex"); + _SDL_DestroyCond = (void (*)(SDL::Cond*))GetProcAddress(realSDLlib,"SDL_DestroyCond"); + _SDL_DestroyMutex = (void (*)(SDL::Mutex*))GetProcAddress(realSDLlib,"SDL_DestroyMutex"); _SDL_EnableKeyRepeat = (int (*)(int, int))GetProcAddress(realSDLlib,"SDL_EnableKeyRepeat"); _SDL_EnableUNICODE = (int (*)(int))GetProcAddress(realSDLlib,"SDL_EnableUNICODE"); _SDL_GetVideoSurface = (void*(*)())GetProcAddress(realSDLlib,"SDL_GetVideoSurface"); @@ -918,7 +732,7 @@ bool FirstCall() _SDL_Flip = (int (*)( void * )) GetProcAddress(realSDLlib, "SDL_Flip"); _SDL_LockSurface = (int (*)(void*))GetProcAddress(realSDLlib,"SDL_LockSurface"); _SDL_MapRGB = (uint32_t (*)(void*, uint8_t, uint8_t, uint8_t))GetProcAddress(realSDLlib,"SDL_MapRGB"); - _SDL_PollEvent = (int (*)(void*))GetProcAddress(realSDLlib,"SDL_PollEvent"); + _SDL_PollEvent = (int (*)(SDL::Event*))GetProcAddress(realSDLlib,"SDL_PollEvent"); _SDL_Quit = (void (*)())GetProcAddress(realSDLlib,"SDL_Quit"); _SDL_RWFromFile = (void*(*)(const char*, const char*))GetProcAddress(realSDLlib,"SDL_RWFromFile"); _SDL_RemoveTimer = (bool (*)(void*))GetProcAddress(realSDLlib,"SDL_RemoveTimer"); @@ -932,24 +746,25 @@ bool FirstCall() _SDL_UpperBlit = (int (*)(void*, void*, void*, void*))GetProcAddress(realSDLlib,"SDL_UpperBlit"); _SDL_WM_SetCaption = (void (*)(const char*, const char*))GetProcAddress(realSDLlib,"SDL_WM_SetCaption"); _SDL_WM_SetIcon = (void (*)(void*, uint8_t*))GetProcAddress(realSDLlib,"SDL_WM_SetIcon"); - _SDL_mutexP = (int (*)(void*))GetProcAddress(realSDLlib,"SDL_mutexP"); + _SDL_mutexP = (int (*)(SDL::Mutex*))GetProcAddress(realSDLlib,"SDL_mutexP"); + _SDL_mutexV = (int (*)(SDL::Mutex*))GetProcAddress(realSDLlib,"SDL_mutexV"); _SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy"); // stuff for SDL_Image _SDL_ClearError = (void (*)())GetProcAddress(realSDLlib,"SDL_ClearError"); _SDL_Error = (void (*)(int))GetProcAddress(realSDLlib,"SDL_Error"); - _SDL_LoadFunction = (void*(*)(void*, const char*))GetProcAddress(realSDLlib,"SDL_LoadFunction"); - _SDL_LoadObject = (void*(*)(const char*))GetProcAddress(realSDLlib,"SDL_LoadObject"); + _SDL_LoadFunction = (void*(*)(SDL::Library*, const char*))GetProcAddress(realSDLlib,"SDL_LoadFunction"); + _SDL_LoadObject = (SDL::Library*(*)(const char*))GetProcAddress(realSDLlib,"SDL_LoadObject"); _SDL_ReadBE32 = (uint32_t (*)(void*))GetProcAddress(realSDLlib,"SDL_ReadBE32"); _SDL_ReadLE16 = (uint16_t (*)(void*))GetProcAddress(realSDLlib,"SDL_ReadLE16"); _SDL_ReadLE32 = (uint32_t (*)(void*))GetProcAddress(realSDLlib,"SDL_ReadLE32"); _SDL_SetError = (void (*)(const char*, ...))GetProcAddress(realSDLlib,"SDL_SetError"); - _SDL_UnloadObject = (void (*)(void*))GetProcAddress(realSDLlib,"SDL_UnloadObject"); + _SDL_UnloadObject = (void (*)(SDL::Library*))GetProcAddress(realSDLlib,"SDL_UnloadObject"); _SDL_FillRect = (int (*)(void*,void*,uint32_t))GetProcAddress(realSDLlib,"SDL_FillRect"); // new in DF 0.31.04 _SDL_CreateSemaphore = (void* (*)(uint32_t))GetProcAddress(realSDLlib,"SDL_CreateSemaphore"); - _SDL_CreateThread = (void* (*)(int (*fn)(void *), void *data))GetProcAddress(realSDLlib,"SDL_CreateThread"); + _SDL_CreateThread = (SDL::Thread* (*)(int (*fn)(void *), void *data))GetProcAddress(realSDLlib,"SDL_CreateThread"); _SDL_Delay = (void (*)(uint32_t))GetProcAddress(realSDLlib,"SDL_Delay"); _SDL_DestroySemaphore = (void (*)(void *))GetProcAddress(realSDLlib,"SDL_DestroySemaphore"); _SDL_GetAppState = (uint8_t (*)(void))GetProcAddress(realSDLlib,"SDL_GetAppState"); @@ -961,5 +776,7 @@ bool FirstCall() _SDL_ThreadID = (uint32_t (*)(void))GetProcAddress(realSDLlib,"SDL_ThreadID"); fprintf(stderr,"Initized HOOKS!\n"); + inited = true; return 1; } + diff --git a/library/MicrosoftSTL.cpp b/library/MicrosoftSTL.cpp deleted file mode 100644 index b19aded87..000000000 --- a/library/MicrosoftSTL.cpp +++ /dev/null @@ -1,108 +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 -#include -#include -using namespace std; - -#include "MicrosoftSTL.h" -#include "dfhack/DFProcess.h" -#include "dfhack/VersionInfo.h" - -using namespace DFHack; - -void MicrosoftSTL::init(Process* self) -{ - p = self; - OffsetGroup * strGrp = p->getDescriptor()->getGroup("string")->getGroup("MSVC"); - STLSTR_buf_off = strGrp->getOffset("buffer"); - STLSTR_size_off = strGrp->getOffset("size"); - STLSTR_cap_off = strGrp->getOffset("capacity"); -} - -size_t MicrosoftSTL::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) -{ - uint32_t start_offset = offset + STLSTR_buf_off; - size_t length = p->readDWord(offset + STLSTR_size_off); - size_t capacity = p->readDWord(offset + STLSTR_cap_off); - - size_t read_real = min(length, bufcapacity-1);// keep space for null termination - - // read data from inside the string structure - if(capacity < 16) - { - p->read(start_offset, read_real , (uint8_t *)buffer); - } - else // read data from what the offset + 4 dword points to - { - start_offset = p->readDWord(start_offset);// dereference the start offset - p->read(start_offset, read_real, (uint8_t *)buffer); - } - - buffer[read_real] = 0; - return read_real; -} - -const string MicrosoftSTL::readSTLString (uint32_t offset) -{ - uint32_t start_offset = offset + STLSTR_buf_off; - size_t length = p->readDWord(offset + STLSTR_size_off); - size_t capacity = p->readDWord(offset + STLSTR_cap_off); - - char * temp = new char[capacity+1]; - - // read data from inside the string structure - if(capacity < 16) - { - p->read(start_offset, capacity, (uint8_t *)temp); - } - else // read data from what the offset + 4 dword points to - { - start_offset = p->readDWord(start_offset);// dereference the start offset - p->read(start_offset, capacity, (uint8_t *)temp); - } - - temp[length] = 0; - string ret = temp; - delete temp; - return ret; -} - -string MicrosoftSTL::readClassName (uint32_t vptr) -{ - int rtti = p->readDWord(vptr - 0x4); - int typeinfo = p->readDWord(rtti + 0xC); - string raw = p->readCString(typeinfo + 0xC); // skips the .?AV - raw.resize(raw.length() - 2);// trim @@ from end - return raw; -} - -// FIXME: really, fix this. -size_t MicrosoftSTL::writeSTLString(const uint32_t address, const std::string writeString) -{ - return 0; -} \ No newline at end of file diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp new file mode 100644 index 000000000..99a01ea25 --- /dev/null +++ b/library/PluginManager.cpp @@ -0,0 +1,395 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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/Core.h" +#include "dfhack/Process.h" +#include "dfhack/PluginManager.h" +#include "dfhack/Console.h" +using namespace DFHack; + +#include +#include +#include +using namespace std; + +#ifdef LINUX_BUILD + #include + #include +#else + #include "wdirent.h" +#endif + +static int getdir (string dir, vector &files) +{ + DIR *dp; + struct dirent *dirp; + if((dp = opendir(dir.c_str())) == NULL) + { + return errno; + } + while ((dirp = readdir(dp)) != NULL) { + files.push_back(string(dirp->d_name)); + } + closedir(dp); + return 0; +} + +bool hasEnding (std::string const &fullString, std::string const &ending) +{ + if (fullString.length() > ending.length()) + { + return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); + } + else + { + return false; + } +} +struct Plugin::RefLock +{ + RefLock() + { + refcount = 0; + wakeup = SDL_CreateCond(); + mut = SDL_CreateMutex(); + } + ~RefLock() + { + SDL_DestroyCond(wakeup); + SDL_DestroyMutex(mut); + } + void lock() + { + SDL_mutexP(mut); + } + void unlock() + { + SDL_mutexV(mut); + } + void lock_add() + { + SDL_mutexP(mut); + refcount ++; + SDL_mutexV(mut); + } + void lock_sub() + { + SDL_mutexP(mut); + refcount --; + SDL_CondSignal(wakeup); + SDL_mutexV(mut); + } + void operator++() + { + refcount ++; + } + void operator--() + { + refcount --; + SDL_CondSignal(wakeup); + } + void wait() + { + while(refcount) + { + SDL_CondWait(wakeup, mut); + } + } + SDL::Cond * wakeup; + SDL::Mutex * mut; + int refcount; +}; +Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _filename, PluginManager * pm) +{ + filename = filepath; + parent = pm; + name.reserve(_filename.size()); + for(int i = 0; i < _filename.size();i++) + { + char ch = _filename[i]; + if(ch == '.') + break; + name.append(1,ch); + } + Console & con = core->con; + plugin_lib = 0; + plugin_init = 0; + plugin_shutdown = 0; + plugin_status = 0; + plugin_onupdate = 0; + state = PS_UNLOADED; + access = new RefLock(); +} + +Plugin::~Plugin() +{ + if(state == PS_LOADED) + { + unload(); + } + delete access; +} + +bool Plugin::load() +{ + access->lock(); + if(state == PS_BROKEN) + { + access->unlock(); + return false; + } + else if(state == PS_LOADED) + { + access->unlock(); + return true; + } + Core & c = Core::getInstance(); + Console & con = c.con; + DFLibrary * plug = OpenPlugin(filename.c_str()); + if(!plug) + { + con.printerr("Can't load plugin %s\n", filename.c_str()); + state = PS_BROKEN; + access->unlock(); + return false; + } + const char * (*_PlugName)() =(const char * (*)()) LookupPlugin(plug, "plugin_name"); + if(!_PlugName) + { + con.printerr("Plugin %s has no name.\n", filename.c_str()); + ClosePlugin(plug); + state = PS_BROKEN; + access->unlock(); + return false; + } + plugin_init = (command_result (*)(Core *, std::vector &)) LookupPlugin(plug, "plugin_init"); + if(!plugin_init) + { + con.printerr("Plugin %s has no init function.\n", filename.c_str()); + ClosePlugin(plug); + state = PS_BROKEN; + access->unlock(); + return false; + } + plugin_status = (command_result (*)(Core *, std::string &)) LookupPlugin(plug, "plugin_status"); + plugin_onupdate = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_onupdate"); + plugin_shutdown = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_shutdown"); + //name = _PlugName(); + plugin_lib = plug; + if(plugin_init(&c,commands) == CR_OK) + { + state = PS_LOADED; + parent->registerCommands(this); + access->unlock(); + return true; + } + else + { + con.printerr("Plugin %s has failed to initialize properly.\n", filename.c_str()); + ClosePlugin(plugin_lib); + state = PS_BROKEN; + access->unlock(); + return false; + } + // not reachable +} + +bool Plugin::unload() +{ + Core & c = Core::getInstance(); + Console & con = c.con; + // get the mutex + access->lock(); + // if we are actually loaded + if(state == PS_LOADED) + { + // notify plugin about shutdown + command_result cr = plugin_shutdown(&Core::getInstance()); + // wait for all calls to finish + access->wait(); + // cleanup... + parent->unregisterCommands(this); + if(cr == CR_OK) + { + ClosePlugin(plugin_lib); + state = PS_UNLOADED; + access->unlock(); + return false; + } + else + { + con.printerr("Plugin %s has failed to shutdown!\n",name.c_str()); + state = PS_BROKEN; + access->unlock(); + return false; + } + } + else if(state == PS_UNLOADED) + { + access->unlock(); + return true; + } + access->unlock(); + return false; +} + +bool Plugin::reload() +{ + if(state != PS_LOADED) + return false; + if(!unload()) + return false; + if(!load()) + return false; + return true; +} + +command_result Plugin::invoke( std::string & command, std::vector & parameters) +{ + Core & c = Core::getInstance(); + command_result cr = CR_NOT_IMPLEMENTED; + access->lock_add(); + if(state == PS_LOADED) + { + for (int i = 0; i < commands.size();i++) + { + if(commands[i].name == command) + { + cr = commands[i].function(&c, parameters); + break; + } + } + } + access->lock_sub(); + return cr; +} + +command_result Plugin::on_update() +{ + Core & c = Core::getInstance(); + command_result cr = CR_NOT_IMPLEMENTED; + access->lock_add(); + if(state == PS_LOADED && plugin_onupdate) + { + cr = plugin_onupdate(&c); + } + access->lock_sub(); + return cr; +} + +Plugin::plugin_state Plugin::getState() const +{ + return state; +} + +PluginManager::PluginManager(Core * core) +{ +#ifdef LINUX_BUILD + string path = core->p->getPath() + "/plugins/"; + const string searchstr = ".plug.so"; +#else + string path = core->p->getPath() + "\\plugins\\"; + const string searchstr = ".plug.dll"; +#endif + cmdlist_mutex = SDL_CreateMutex(); + vector filez; + getdir(path, filez); + for(int i = 0; i < filez.size();i++) + { + if(hasEnding(filez[i],searchstr)) + { + Plugin * p = new Plugin(core, path + filez[i], filez[i], this); + all_plugins.push_back(p); + // make all plugins load by default (until a proper design emerges). + p->load(); + } + } +} + +PluginManager::~PluginManager() +{ + for(int i = 0; i < all_plugins.size();i++) + { + delete all_plugins[i]; + } + all_plugins.clear(); + SDL_DestroyMutex(cmdlist_mutex); +} + +Plugin *PluginManager::getPluginByName (const std::string & name) +{ + for(int i = 0; i < all_plugins.size(); i++) + { + if(name == all_plugins[i]->name) + return all_plugins[i]; + } + return 0; +} + +// FIXME: handle name collisions... +command_result PluginManager::InvokeCommand( std::string & command, std::vector & parameters) +{ + command_result cr = CR_NOT_IMPLEMENTED; + Core * c = &Core::getInstance(); + SDL_mutexP(cmdlist_mutex); + map ::iterator iter = belongs.find(command); + if(iter != belongs.end()) + { + cr = iter->second->invoke(command, parameters); + } + SDL_mutexV(cmdlist_mutex); + return cr; +} + +void PluginManager::OnUpdate( void ) +{ + for(int i = 0; i < all_plugins.size(); i++) + { + all_plugins[i]->on_update(); + } +} +// FIXME: doesn't check name collisions! +void PluginManager::registerCommands( Plugin * p ) +{ + SDL_mutexP(cmdlist_mutex); + vector & cmds = p->commands; + for(int i = 0; i < cmds.size();i++) + { + belongs[cmds[i].name] = p; + } + SDL_mutexV(cmdlist_mutex); +} + +// FIXME: doesn't check name collisions! +void PluginManager::unregisterCommands( Plugin * p ) +{ + SDL_mutexP(cmdlist_mutex); + vector & cmds = p->commands; + for(int i = 0; i < cmds.size();i++) + { + belongs.erase(cmds[i].name); + } + SDL_mutexV(cmdlist_mutex); +} \ No newline at end of file diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp new file mode 100644 index 000000000..23d8baf12 --- /dev/null +++ b/library/Process-linux.cpp @@ -0,0 +1,179 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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 +#include + +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include "dfhack/Process.h" +#include "dfhack/VersionInfoFactory.h" +#include "dfhack/VersionInfo.h" +#include "dfhack/Error.h" +using namespace DFHack; + +Process::Process(VersionInfoFactory * known_versions) +{ + const char * dir_name = "/proc/self/"; + const char * exe_link_name = "/proc/self/exe"; + const char * cwd_name = "/proc/self/cwd"; + const char * cmdline_name = "/proc/self/cmdline"; + char target_name[1024]; + int target_result; + + identified = false; + my_descriptor = 0; + + // resolve /proc/self/exe link + target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); + if (target_result == -1) + { + return; + } + // make sure we have a null terminated string... + target_name[target_result] = 0; + + // is this the regular linux DF? + if (strstr(target_name, "dwarfort.exe") != 0 || strstr(target_name,"Dwarf_Fortress") != 0) + { + md5wrapper md5; + // get hash of the running DF process + string hash = md5.getHashFromFile(target_name); + // create linux process, add it to the vector + VersionInfo * vinfo = known_versions->getVersionInfoByMD5(hash); + if(vinfo) + { + my_descriptor = new VersionInfo(*vinfo); + my_descriptor->setParentProcess(this); + identified = true; + } + } +} + +string Process::doReadClassName (void * vptr) +{ + //FIXME: BAD!!!!! + int typeinfo = Process::readDWord((uint32_t)vptr - 0x4); + int typestring = Process::readDWord(typeinfo + 0x4); + string raw = readCString(typestring); + size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers + size_t end = raw.length(); + return raw.substr(start,end-start); +} + +//FIXME: cross-reference with ELF segment entries? +void Process::getMemRanges( vector & ranges ) +{ + char buffer[1024]; + char permissions[5]; // r/-, w/-, x/-, p/s, 0 + + FILE *mapFile = ::fopen("/proc/self/maps", "r"); + size_t start, end, offset, device1, device2, node; + + while (fgets(buffer, 1024, mapFile)) + { + t_memrange temp; + temp.name[0] = 0; + sscanf(buffer, "%zx-%zx %s %zx %2zu:%2zu %zu %[^\n]s", + &start, + &end, + (char*)&permissions, + &offset, &device1, &device2, &node, + (char*)&temp.name); + temp.start = start; + temp.end = end; + temp.read = permissions[0] == 'r'; + temp.write = permissions[1] == 'w'; + temp.execute = permissions[2] == 'x'; + temp.shared = permissions[3] == 's'; + temp.valid = true; + ranges.push_back(temp); + } +} + +uint32_t Process::getBase() +{ + return 0; +} + +static int getdir (string dir, vector &files) +{ + DIR *dp; + struct dirent *dirp; + if((dp = opendir(dir.c_str())) == NULL) + { + cout << "Error(" << errno << ") opening " << dir << endl; + return errno; + } + while ((dirp = readdir(dp)) != NULL) { + files.push_back(string(dirp->d_name)); + } + closedir(dp); + return 0; +} + +bool Process::getThreadIDs(vector & threads ) +{ + stringstream ss; + vector subdirs; + if(getdir("/proc/self/task/",subdirs) != 0) + { + //FIXME: needs exceptions. this is a fatal error + cerr << "unable to enumerate threads. This is BAD!" << endl; + return false; + } + threads.clear(); + for(size_t i = 0; i < subdirs.size();i++) + { + uint32_t tid; + if(sscanf(subdirs[i].c_str(),"%d", &tid)) + { + threads.push_back(tid); + } + } + return true; +} + +string Process::getPath() +{ + const char * cwd_name = "/proc/self/cwd"; + char target_name[1024]; + int target_result; + target_result = readlink(cwd_name, target_name, sizeof(target_name)); + target_name[target_result] = '\0'; + return(string(target_name)); +} + +int Process::getPID() +{ + return getpid(); +} \ No newline at end of file diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp new file mode 100644 index 000000000..2edfc6325 --- /dev/null +++ b/library/Process-windows.cpp @@ -0,0 +1,358 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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" + +#define _WIN32_WINNT 0x0501 // needed for INPUT struct +#define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +typedef LONG NTSTATUS; +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) + +// FIXME: it is uncertain how these map to 64bit +typedef struct _DEBUG_BUFFER +{ + HANDLE SectionHandle; + PVOID SectionBase; + PVOID RemoteSectionBase; + ULONG SectionBaseDelta; + HANDLE EventPairHandle; + ULONG Unknown[2]; + HANDLE RemoteThreadHandle; + ULONG InfoClassMask; + ULONG SizeOfInfo; + ULONG AllocatedSize; + ULONG SectionSize; + PVOID ModuleInformation; + PVOID BackTraceInformation; + PVOID HeapInformation; + PVOID LockInformation; + PVOID Reserved[8]; +} DEBUG_BUFFER, *PDEBUG_BUFFER; + +typedef struct _DEBUG_HEAP_INFORMATION +{ + ULONG Base; // 0×00 + ULONG Flags; // 0×04 + USHORT Granularity; // 0×08 + USHORT Unknown; // 0x0A + ULONG Allocated; // 0x0C + ULONG Committed; // 0×10 + ULONG TagCount; // 0×14 + ULONG BlockCount; // 0×18 + ULONG Reserved[7]; // 0x1C + PVOID Tags; // 0×38 + PVOID Blocks; // 0x3C +} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; + +// RtlQueryProcessDebugInformation.DebugInfoClassMask constants +#define PDI_MODULES 0x01 +#define PDI_BACKTRACE 0x02 +#define PDI_HEAPS 0x04 +#define PDI_HEAP_TAGS 0x08 +#define PDI_HEAP_BLOCKS 0x10 +#define PDI_LOCKS 0x20 + +extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlQueryProcessDebugInformation( IN ULONG ProcessId, IN ULONG DebugInfoClassMask, IN OUT PDEBUG_BUFFER DebugBuffer); +extern "C" __declspec(dllimport) PDEBUG_BUFFER __stdcall RtlCreateQueryDebugBuffer( IN ULONG Size, IN BOOLEAN EventPair); +extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlDestroyQueryDebugBuffer( IN PDEBUG_BUFFER DebugBuffer); + +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "dfhack/VersionInfo.h" +#include "dfhack/VersionInfoFactory.h" +#include "dfhack/Error.h" +#include "dfhack/Process.h" +using namespace DFHack; +namespace DFHack +{ + class PlatformSpecific + { + public: + PlatformSpecific() + { + base = 0; + sections = 0; + }; + HANDLE my_handle; + vector threads; + vector stoppedthreads; + uint32_t my_pid; + IMAGE_NT_HEADERS pe_header; + IMAGE_SECTION_HEADER * sections; + uint32_t base; + }; +} +Process::Process(VersionInfoFactory * factory) +{ + HMODULE hmod = NULL; + DWORD needed; + bool found = false; + identified = false; + my_descriptor = NULL; + + d = new PlatformSpecific(); + // open process + d->my_pid = GetCurrentProcessId(); + d->my_handle = GetCurrentProcess(); + // try getting the first module of the process + if(EnumProcessModules(d->my_handle, &hmod, sizeof(hmod), &needed) == 0) + { + return; //if enumprocessModules fails, give up + } + + // got base ;) + d->base = (uint32_t)hmod; + + // read from this process + try + { + uint32_t pe_offset = Process::readDWord(d->base+0x3C); + read(d->base + pe_offset, sizeof(d->pe_header), (uint8_t *)&(d->pe_header)); + const size_t sectionsSize = sizeof(IMAGE_SECTION_HEADER) * d->pe_header.FileHeader.NumberOfSections; + d->sections = (IMAGE_SECTION_HEADER *) malloc(sectionsSize); + read(d->base + pe_offset + sizeof(d->pe_header), sectionsSize, (uint8_t *)(d->sections)); + } + catch (exception &) + { + return; + } + VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(d->pe_header.FileHeader.TimeDateStamp); + if(vinfo) + { + vector threads_ids; + if(!getThreadIDs( threads_ids )) + { + // thread enumeration failed. + return; + } + identified = true; + // give the process a data model and memory layout fixed for the base of first module + my_descriptor = new VersionInfo(*vinfo); + my_descriptor->RebaseAll(d->base); + // keep track of created memory_info object so we can destroy it later + my_descriptor->setParentProcess(this); + for(size_t i = 0; i < threads_ids.size();i++) + { + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]); + if(hThread) + d->threads.push_back(hThread); + else + cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl; + } + } +} + +Process::~Process() +{ + // destroy our rebased copy of the memory descriptor + delete my_descriptor; + for(size_t i = 0; i < d->threads.size(); i++) + CloseHandle(d->threads[i]); + if(d->sections != NULL) + free(d->sections); +} + +bool Process::getThreadIDs(vector & threads ) +{ + HANDLE AllThreads = INVALID_HANDLE_VALUE; + THREADENTRY32 te32; + + AllThreads = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); + if( AllThreads == INVALID_HANDLE_VALUE ) + { + return false; + } + te32.dwSize = sizeof(THREADENTRY32 ); + + if( !Thread32First( AllThreads, &te32 ) ) + { + CloseHandle( AllThreads ); + return false; + } + + do + { + if( te32.th32OwnerProcessID == d->my_pid ) + { + threads.push_back(te32.th32ThreadID); + } + } while( Thread32Next(AllThreads, &te32 ) ); + + CloseHandle( AllThreads ); + return true; +} +/* +typedef struct _MEMORY_BASIC_INFORMATION +{ + void * BaseAddress; + void * AllocationBase; + uint32_t AllocationProtect; + size_t RegionSize; + uint32_t State; + uint32_t Protect; + uint32_t Type; +} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; +*/ +/* +//Internal structure used to store heap block information. +struct HeapBlock +{ + PVOID dwAddress; + DWORD dwSize; + DWORD dwFlags; + ULONG reserved; +}; +*/ +void HeapNodes(DWORD pid, map & heaps) +{ + // Create debug buffer + PDEBUG_BUFFER db = RtlCreateQueryDebugBuffer(0, FALSE); + // Get process heap data + RtlQueryProcessDebugInformation( pid, PDI_HEAPS/* | PDI_HEAP_BLOCKS*/, db); + ULONG heapNodeCount = db->HeapInformation ? *PULONG(db->HeapInformation):0; + PDEBUG_HEAP_INFORMATION heapInfo = PDEBUG_HEAP_INFORMATION(PULONG(db-> HeapInformation) + 1); + // Go through each of the heap nodes and dispaly the information + for (unsigned int i = 0; i < heapNodeCount; i++) + { + heaps[heapInfo[i].Base] = i; + } + // Clean up the buffer + RtlDestroyQueryDebugBuffer( db ); +} + +// FIXME: NEEDS TESTING! +void Process::getMemRanges( vector & ranges ) +{ + MEMORY_BASIC_INFORMATION MBI; + map heaps; + uint64_t movingStart = 0; + map nameMap; + + // get page size + SYSTEM_INFO si; + GetSystemInfo(&si); + uint64_t PageSize = si.dwPageSize; + // enumerate heaps + HeapNodes(d->my_pid, heaps); + // go through all the VM regions, convert them to our internal format + while (VirtualQueryEx(d->my_handle, (const void*) (movingStart), &MBI, sizeof(MBI)) == sizeof(MBI)) + { + movingStart = ((uint64_t)MBI.BaseAddress + MBI.RegionSize); + if(movingStart % PageSize != 0) + movingStart = (movingStart / PageSize + 1) * PageSize; + // skip empty regions and regions we share with other processes (DLLs) + if( !(MBI.State & MEM_COMMIT) /*|| !(MBI.Type & MEM_PRIVATE)*/ ) + continue; + t_memrange temp; + temp.start = (uint64_t) MBI.BaseAddress; + temp.end = ((uint64_t)MBI.BaseAddress + (uint64_t)MBI.RegionSize); + temp.read = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READONLY || MBI.Protect & PAGE_READWRITE; + temp.write = MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READWRITE; + temp.execute = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_EXECUTE; + temp.valid = true; + if(!GetModuleBaseName(d->my_handle, (HMODULE) temp.start, temp.name, 1024)) + { + if(nameMap.count(temp.start)) + { + // potential buffer overflow... + strcpy(temp.name, nameMap[temp.start].c_str()); + } + else + { + // filter away shared segments without a name. + if( !(MBI.Type & MEM_PRIVATE) ) + continue; + else + { + // could be a heap? + if(heaps.count(temp.start)) + { + sprintf(temp.name,"HEAP %d",heaps[temp.start]); + } + else temp.name[0]=0; + } + } + } + else + { + // this is our executable! (could be generalized to pull segments from libs, but whatever) + if(d->base == temp.start) + { + for(int i = 0; i < d->pe_header.FileHeader.NumberOfSections; i++) + { + char sectionName[9]; + memcpy(sectionName,d->sections[i].Name,8); + sectionName[8] = 0; + string nm; + nm.append(temp.name); + nm.append(" : "); + nm.append(sectionName); + nameMap[temp.start + d->sections[i].VirtualAddress] = nm; + } + } + else + continue; + } + ranges.push_back(temp); + } +} + +uint32_t Process::getBase() +{ + if(d) + return d->base; + return 0x400000; +} + +string Process::doReadClassName (void * vptr) +{ + int rtti = readDWord((uint32_t)vptr - 0x4); + int typeinfo = readDWord(rtti + 0xC); + string raw = readCString(typeinfo + 0xC); // skips the .?AV + raw.resize(raw.length() - 2);// trim @@ from end + return raw; +} + +string Process::getPath() +{ + HMODULE hmod; + DWORD junk; + char String[255]; + EnumProcessModules(d->my_handle, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle + GetModuleFileNameEx(d->my_handle,hmod,String,sizeof(String)); //get the filename from the module + string out(String); + return(out.substr(0,out.find_last_of("\\"))); +} diff --git a/library/DFTileTypes.cpp b/library/TileTypes.cpp similarity index 96% rename from library/DFTileTypes.cpp rename to library/TileTypes.cpp index 5ca3c4aa7..40b7768f9 100644 --- a/library/DFTileTypes.cpp +++ b/library/TileTypes.cpp @@ -1,7 +1,30 @@ -// vim: sts=4 sta et shiftwidth=4: -#include "dfhack/DFIntegers.h" -#include "dfhack/DFTileTypes.h" -#include "dfhack/DFExport.h" +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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/TileTypes.h" +#include "dfhack/Export.h" namespace DFHack { diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index 7e6f52abc..e0da4ca96 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -31,8 +32,8 @@ distribution. using namespace std; #include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" -#include "dfhack/DFProcess.h" +#include "dfhack/Error.h" +#include "dfhack/Process.h" using namespace DFHack; //Inital amount of space in levels vector (since we usually know the number, efficient!) @@ -972,7 +973,7 @@ void VersionInfo::setClassChild (t_class * parent, const char * name, const char } -// FIXME: stupid. we need a better container +// FIXME: This in now DEPRECATED! bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & classid) { uint32_t vtable = d->p->readDWord(address); @@ -989,7 +990,8 @@ bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & class else// couldn't find? { // we set up the class for the first time - string classname = d->p->readClassName(vtable); + //FIXME: use actual pointers everywhere. + string classname = d->p->readClassName((void*)vtable); d->classIDs[vtable] = cl = setClass(classname.c_str(),vtable); } // and isn't a multi-class @@ -1026,7 +1028,7 @@ bool VersionInfo::resolveObjectToClassID(const uint32_t address, int32_t & class //ALERT: doesn't care about multiclasses -bool VersionInfo::resolveClassnameToVPtr(const string classname, uint32_t & vptr) +bool VersionInfo::resolveClassnameToVPtr(const string classname, void * & vptr) { // FIXME: another stupid search. for(uint32_t i = 0;i< d->classes.size();i++) @@ -1034,7 +1036,7 @@ bool VersionInfo::resolveClassnameToVPtr(const string classname, uint32_t & vptr //if(classes[i].) if(d->classes[i]->classname == classname) // got class { - vptr = d->classes[i]->vtable; + vptr = (void *) d->classes[i]->vtable; return true; } } diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 0c7b29554..15f3f8a6a 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -32,7 +32,7 @@ using namespace std; #include "dfhack/VersionInfoFactory.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFError.h" +#include "dfhack/Error.h" using namespace DFHack; #include @@ -168,13 +168,13 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem) string type = pClassEntry->Value(); const char *cstr_name = pClassEntry->Attribute("name"); const char *cstr_vtable = pClassEntry->Attribute("vtable"); - uint32_t vtable = 0; + uint32_t vtable_num = 0; if(cstr_vtable) - vtable = strtol(cstr_vtable, NULL, 16); + vtable_num = strtol(cstr_vtable, NULL, 16); // it's a simple class if(type== "class") { - mem->setClass(cstr_name, vtable); + mem->setClass(cstr_name, vtable_num); } // it's a multi-type class else if (type == "multiclass") @@ -184,7 +184,7 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem) uint32_t typeoffset = 0; if(cstr_typeoffset) typeoffset = strtol(cstr_typeoffset, NULL, 16); - t_class * mclass = mem->setClass(cstr_name, vtable, typeoffset); + t_class * mclass = mem->setClass(cstr_name, vtable_num, typeoffset); // parse class sub-entries pClassSubEntry = pClassEntry->FirstChildElement(); for(;pClassSubEntry;pClassSubEntry=pClassSubEntry->NextSiblingElement()) diff --git a/library/Virtual.cpp b/library/Virtual.cpp new file mode 100644 index 000000000..37598e32d --- /dev/null +++ b/library/Virtual.cpp @@ -0,0 +1,16 @@ +#include "Internal.h" + +#include +#include +#include + +#include "dfhack/Process.h" +#include "dfhack/Core.h" +#include "dfhack/Virtual.h" +using namespace DFHack; + +std::string t_virtual::getClassName() +{ + Core & c = Core::getInstance(); + return c.p->readClassName(vptr); +} \ No newline at end of file diff --git a/library/depends/argstream/argstream.h b/library/depends/argstream/argstream.h deleted file mode 100644 index 0abf55808..000000000 --- a/library/depends/argstream/argstream.h +++ /dev/null @@ -1,819 +0,0 @@ -/* Copyright (C) 2004 Xavier Decoret -* -* argsteam is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* Foobar is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with Foobar; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef ARGSTREAM_H -#define ARGSTREAM_H - - -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - class argstream; - - template - class ValueHolder; - - template - argstream& operator>> (argstream&, const ValueHolder&); - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueHolder - { - public: - ValueHolder(char s, - const char* l, - T& b, - const char* desc, - bool mandatory); - ValueHolder(const char* l, - T& b, - const char* desc, - bool mandatory); - ValueHolder(char s, - T& b, - const char* desc, - bool mandatory); - friend argstream& operator>><>(argstream& s,const ValueHolder& v); - std::string name() const; - std::string description() const; - private: - std::string shortName_; - std::string longName_; - T* value_; - T initialValue_; - std::string description_; - bool mandatory_; - }; - template - inline ValueHolder - parameter(char s, - const char* l, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,l,b,desc,mandatory); - } - template - inline ValueHolder - parameter(char s, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,b,desc,mandatory); - } - template - inline ValueHolder - parameter(const char* l, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(l,b,desc,mandatory); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of OptionHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class OptionHolder - { - public: - inline OptionHolder(char s, - const char* l, - bool& b, - const char* desc); - inline OptionHolder(const char* l, - bool& b, - const char* desc); - inline OptionHolder(char s, - bool& b, - const char* desc); - friend argstream& operator>>(argstream& s,const OptionHolder& v); - inline std::string name() const; - inline std::string description() const; - protected: - inline OptionHolder(char s, - const char* l, - const char* desc); - friend OptionHolder help(char s='h', - const char* l="help", - const char* desc="Display this help"); - private: - std::string shortName_; - std::string longName_; - bool* value_; - std::string description_; - }; - inline OptionHolder - option(char s, - const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(s,l,b,desc); - } - inline OptionHolder - option(char s, - bool& b, - const char* desc="") - { - return OptionHolder(s,b,desc); - } - inline OptionHolder - option(const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(l,b,desc); - } - inline OptionHolder - help(char s, - const char* l, - const char* desc) - { - return OptionHolder(s,l,desc); - } - template - class ValuesHolder; - template - argstream& operator>> (argstream&, const ValuesHolder&); - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValuesHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValuesHolder - { - public: - ValuesHolder(const O& o, - const char* desc, - int len); - friend argstream& operator>><>(argstream& s,const ValuesHolder& v); - std::string name() const; - std::string description() const; - typedef T value_type; - private: - mutable O value_; - std::string description_; - int len_; - char letter_; - }; - template - inline ValuesHolder - values(const O& o, - const char* desc="", - int len=-1) - { - return ValuesHolder(o,desc,len); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueParser - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueParser - { - public: - inline T operator()(const std::string& s) const - { - std::istringstream is(s); - T t; - is>>t; - return t; - } - }; - // We need to specialize for string otherwise parsing of a value that - // contains space (for example a string with space passed in quotes on the - // command line) would parse only the first element of the value!!! - template <> - class ValueParser - { - public: - inline std::string operator()(const std::string& s) const - { - return s; - } - }; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of argstream - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class argstream - { - public: - inline argstream(int argc,char** argv); - //inline argstream(const char* c); - template - friend argstream& operator>>(argstream& s,const ValueHolder& v); - friend inline argstream& operator>>(argstream& s,const OptionHolder& v); - template - friend argstream& operator>>(argstream& s,const ValuesHolder& v); - - inline bool helpRequested() const; - inline bool isOk() const; - inline std::string errorLog() const; - inline std::string usage() const; - inline void defaultErrorHandling(bool ignoreUnused=false) const; - static inline char uniqueLetter(); - protected: - void parse(int argc,char** argv); - private: - typedef std::list::iterator value_iterator; - typedef std::pair help_entry; - std::string progName_; - std::map options_; - std::list values_; - bool minusActive_; - bool isOk_; - std::deque argHelps_; - std::string cmdLine_; - std::deque errors_; - bool helpRequested_; - }; - //************************************************************ - // Implementation of ValueHolder - //************************************************************ - template - ValueHolder::ValueHolder(char s, - const char* l, - T& v, - const char* desc, - bool mandatory) - : shortName_(1,s), - longName_(l), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(const char* l, - T& v, - const char* desc, - bool mandatory) - : longName_(l), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(char s, - T& v, - const char* desc, - bool mandatory) - : shortName_(1,s), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - std::string - ValueHolder::name() const - { - std::ostringstream os; - if (!shortName_.empty()) os<<'-'< - std::string - ValueHolder::description() const - { - std::ostringstream os; - os< - //************************************************************ - template - ValuesHolder::ValuesHolder(const O& o, - const char* desc, - int len) - : value_(o), - description_(desc), - len_(len) - { - letter_ = argstream::uniqueLetter(); - } - template - std::string - ValuesHolder::name() const - { - std::ostringstream os; - os< - std::string - ValuesHolder::description() const - { - return description_; - } - //************************************************************ - // Implementation of argstream - //************************************************************ - inline - argstream::argstream(int argc,char** argv) - : progName_(argv[0]), - minusActive_(true), - isOk_(true) - { - parse(argc,argv); - } - //inline - // argstream::argstream(const char* c) - // : progName_(""), - // minusActive_(true), - // isOk_(true) - //{ - // std::string s(c); - // // Build argc, argv from s. We must add a dummy first element for - // // progName because parse() expects it!! - // std::deque args; - // args.push_back(""); - // std::istringstream is(s); - // while (is.good()) - // { - // std::string t; - // is>>t; - // args.push_back(t); - // } - // char* pargs[args.size()]; - // char** p = pargs; - // for (std::deque::const_iterator - // iter = args.begin(); - // iter != args.end();++iter) - // { - // *p++ = const_cast(iter->c_str()); - // } - // parse(args.size(),pargs); - //} - inline void - argstream::parse(int argc,char** argv) - { - // Run thru all arguments. - // * it has -- in front : it is a long name option, if remainder is empty, - // it is an error - // * it has - in front : it is a sequence of short name options, if - // remainder is empty, deactivates option (- will - // now be considered a char). - // * if any other char, or if option was deactivated - // : it is a value. Values are split in parameters - // (immediately follow an option) and pure values. - // Each time a value is parsed, if the previously parsed argument was an - // option, then the option is linked to the value in case of it is a - // option with parameter. The subtle point is that when several options - // are given with short names (ex: -abc equivalent to -a -b -c), the last - // parsed option is -c). - // Since we use map for option, any successive call overides the previous - // one: foo -a -b -a hello is equivalent to foo -b -a hello - // For values it is not true since we might have several times the same - // value. - value_iterator* lastOption = NULL; - for (char** a = argv,**astop=a+argc;++a!=astop;) - { - std::string s(*a); - if (minusActive_ && s[0] == '-') - { - if (s.size() > 1 && s[1] == '-') - { - if (s.size() == 2) - { - minusActive_ = false; - continue; - } - lastOption = &(options_[s.substr(2)] = values_.end()); - } - else - { - if (s.size() > 1) - { - // Parse all chars, if it is a minus we have an error - for (std::string::const_iterator cter = s.begin(); - ++cter != s.end();) - { - if (*cter == '-') - { - isOk_ = false; - std::ostringstream os; - os<<"- in the middle of a switch "<::const_iterator - iter = options_.begin();iter != options_.end();++iter) - { - std::cout<<"DEBUG: option "<first; - if (iter->second != values_.end()) - { - std::cout<<" -> "<<*(iter->second); - } - std::cout<::const_iterator - iter = values_.begin();iter != values_.end();++iter) - { - std::cout<<"DEBUG: value "<<*iter<::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - if (lmaxfirst.size()) lmax = iter->first.size(); - } - for (std::deque::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - os<<'\t'<first<first.size(),' ') - <<" : "<second<<'\n'; - } - return os.str(); - } - inline std::string - argstream::errorLog() const - { - std::string s; - for(std::deque::const_iterator iter = errors_.begin(); - iter != errors_.end();++iter) - { - s += *iter; - s += '\n'; - } - return s; - } - inline char - argstream::uniqueLetter() - { - static unsigned int c = 'a'; - return c++; - } - template - argstream& - operator>>(argstream& s,const ValueHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line, either it - // has an associated value in which case we assign it, or it has not, in - // which case we have an error. - if (iter->second != s.values_.end()) - { -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: found value "<<*(iter->second)< p; - *(v.value_) = p(*(iter->second)); - // The option and its associated value are removed, the subtle thing - // is that someother options might have this associated value too, - // which we must invalidate. - s.values_.erase(iter->second); - - // FIXME this loop seems to crash if a std::string is used as the value - //for (std::map::iterator - // jter = s.options_.begin();jter != s.options_.end();++jter) - //{ - // if (jter->second == iter->second) - // { - // jter->second = s.values_.end(); - // } - //} - s.options_.erase(iter); - } - else - { - s.isOk_ = false; - std::ostringstream os; - os<<"No value following switch "<first - <<" on command line"; - s.errors_.push_back(os.str()); - } - } - else - { - if (v.mandatory_) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Mandatory parameter "; - if (!v.shortName_.empty()) os<<'-'<>(argstream& s,const OptionHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line then the - // option is true and if an associated value was found, it is ignored - if (v.value_ != NULL) - { - *(v.value_) = true; - } - else - { - s.helpRequested_ = true; - } - // The option only is removed - s.options_.erase(iter); - } - else - { - if (v.value_ != NULL) - { - *(v.value_) = false; - } - else - { - s.helpRequested_ = false; - } - } - return s; - } - template - argstream& - operator>>(argstream& s,const ValuesHolder& v) - { - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - { - std::ostringstream os; - os<<' '<::iterator first = s.values_.begin(); - // We add to the iterator as much values as we can, limited to the length - // specified (if different of -1) - int n = v.len_ != -1?v.len_:s.values_.size(); - while (first != s.values_.end() && n-->0) - { - // Read the value from the string *first - ValueParser p; - *(v.value_++) = p(*first ); - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - // The value we just removed was maybe "remembered" by an option so we - // remove it now. - for (std::map::iterator - jter = s.options_.begin();jter != s.options_.end();++jter) - { - if (jter->second == first) - { - jter->second = s.values_.end(); - } - } - ++first; - } - // Check if we have enough values - if (n != 0) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Expecting "< -#include +#include //---------------------------------------------------------------------- //typedefs typedef unsigned char *POINTER; diff --git a/doc/CMakeLists.txt b/library/doc/CMakeLists.txt similarity index 87% rename from doc/CMakeLists.txt rename to library/doc/CMakeLists.txt index aad02a203..0a4e5bd2d 100644 --- a/doc/CMakeLists.txt +++ b/library/doc/CMakeLists.txt @@ -35,12 +35,7 @@ IF(DOXYGEN_FOUND) # 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 - "${dfhack_SOURCE_DIR}/doc/index.dxgen" - "${dfhack_SOURCE_DIR}/library/include" - "${dfhack_SOURCE_DIR}/library/include/dfhack" - "${dfhack_SOURCE_DIR}/library/include/dfhack/modules" - "${dfhack_SOURCE_DIR}/library/include/dfhack-c" - "${dfhack_SOURCE_DIR}/library/include/dfhack-c/modules" + "${dfhack_SOURCE_DIR}/library" ) STRING(REGEX REPLACE ";" " " CMAKE_DOXYGEN_INPUT_LIST "${DOXYGEN_SOURCE_DIR}") diff --git a/doc/Doxyfile.in b/library/doc/Doxyfile.in similarity index 99% rename from doc/Doxyfile.in rename to library/doc/Doxyfile.in index a08f3f355..5ee8f500e 100644 --- a/doc/Doxyfile.in +++ b/library/doc/Doxyfile.in @@ -600,7 +600,7 @@ FILE_PATTERNS = *.cpp \ # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a @@ -628,7 +628,7 @@ EXCLUDE_PATTERNS = # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = Private # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see diff --git a/doc/Doxygen.html b/library/doc/Doxygen.html similarity index 100% rename from doc/Doxygen.html rename to library/doc/Doxygen.html diff --git a/doc/img/.dot b/library/doc/img/.dot similarity index 100% rename from doc/img/.dot rename to library/doc/img/.dot diff --git a/doc/index.dxgen b/library/doc/index.dxgen similarity index 100% rename from doc/index.dxgen rename to library/doc/index.dxgen diff --git a/library/include/DFHack.h b/library/include/DFHack.h index 07db7af0c..7a9c8c0ad 100644 --- a/library/include/DFHack.h +++ b/library/include/DFHack.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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 DFHACK_API_H #define DFHACK_API_H @@ -19,14 +43,14 @@ #define DEPRECATED(func) func #endif +// C99 integer types (used everywhere) +#include + // DFHack core classes and types -#include "dfhack/DFIntegers.h" -#include "dfhack/DFError.h" -#include "dfhack/DFContextManager.h" -#include "dfhack/DFContext.h" +#include "dfhack/Error.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Types.h" // DFHack modules #include "dfhack/modules/Buildings.h" @@ -46,11 +70,11 @@ * Only for use of official DFHack tools! */ #ifdef DFHACK_WANT_MISCUTILS - #include "dfhack/DFMiscUtils.h" + #include "dfhack/MiscUtils.h" #endif // define this to get the static tiletype->properties mapping #ifdef DFHACK_WANT_TILETYPES - #include "dfhack/DFTileTypes.h" + #include "dfhack/TileTypes.h" #endif #endif diff --git a/library/include/dfhack-c/Common.h b/library/include/dfhack-c/Common.h deleted file mode 100644 index 49e38fd02..000000000 --- a/library/include/dfhack-c/Common.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 DFHACK_C_API -#define DFHACK_C_API - -#define HBUILD(a) a ## BufferCallback -#define HREG_MACRO(type_name, type) DFHACK_EXPORT void HBUILD(Register ## type_name) (int (*funcptr)(type, uint32_t)); - -#define HUNREG_MACRO(type_name) DFHACK_EXPORT void HBUILD(Unregister ## type_name) (); - -#include "dfhack/DFPragma.h" - -#include "dfhack/DFExport.h" -#include "dfhack/DFIntegers.h" - -typedef void DFHackObject; - -#ifdef __cplusplus - -namespace DFHack {}; -using namespace DFHack; -extern "C" { - #endif - // some global stuff here - #ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/DFContext_C.h b/library/include/dfhack-c/DFContext_C.h deleted file mode 100644 index 9f33b885b..000000000 --- a/library/include/dfhack-c/DFContext_C.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -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 DFHACK_C_CONTEXT -#define DFHACK_C_CONTEXT - -#include "dfhack-c/Common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** -Allocates a new ContextManager. -@param path_to_xml A const string pointer containing the path to the Memory.xml file. -@return A DFHackObject pointer that points to the allocated ContextManager. -*/ -DFHACK_EXPORT DFHackObject* ContextManager_Alloc(const char* path_to_xml); - -/** -Frees a previously allocated ContextManager. -@param contextMgr A DFHackObject pointer that points to a previously allocated ContextManager. -@return None. -*/ -DFHACK_EXPORT void ContextManager_Free(DFHackObject* contextMgr); - -DFHACK_EXPORT int ContextManager_Refresh(DFHackObject* contextMgr); - -/** -Gets the number of active DF processes. -@param contextMgr A pointer to an active ContextManager. -@param size A pointer to an unsigned 32-bit integer that will contain the count of active DF processes. -@return - - 0: Failure. - - 1: Success. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int ContextManager_size(DFHackObject* contextMgr, uint32_t* size); - -DFHACK_EXPORT int ContextManager_purge(DFHackObject* contextMgr); -DFHACK_EXPORT DFHackObject* ContextManager_getContext(DFHackObject* contextMgr, uint32_t index); -DFHACK_EXPORT DFHackObject* ContextManager_getSingleContext(DFHackObject* contextMgr); - -/** -Frees a previously allocated Context. -@param context A DFHackObject pointer that points to a previously allocated Context. -@return None. -*/ -DFHACK_EXPORT void Context_Free(DFHackObject* context); - -/** -Attaches to a running DF process. -@param context A pointer to an unattached Context. -@return - - 0: Failure. - - 1: Success. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_Attach(DFHackObject* context); - -/** -Detaches from a tracked DF process. -@param context A pointer to an attached Context. -@return - - 0: Failure. - - 1: Success. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_Detach(DFHackObject* context); - -/** -Determines whether or not the given Context is attached to a running DF process. -@param context A pointer to an attached Context. -@return - - 0: The supplied Context is not attached. - - 1: The supplied Context is attached. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_isAttached(DFHackObject* context); - -/** -Suspends a running DF process. -@param context A pointer to an attached Context. -@return - - 0: The tracked process was not suspended. - - 1: The tracked process was suspended. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_Suspend(DFHackObject* context); - -/** -Resume a running DF process. -@param context A pointer to an attached Context. -@return - - 0: The tracked process was not resumed. - - 1: The tracked process was resumed. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_Resume(DFHackObject* context); - -/** -Determines whether or not the given Context's tracked process is suspended. -@param context A pointer to an attached Context. -@return - - 0: The tracked process is not suspended. - - 1: The tracked process is suspended. - - -1: An invalid pointer was supplied. -*/ -DFHACK_EXPORT int Context_isSuspended(DFHackObject* context); -DFHACK_EXPORT int Context_ForceResume(DFHackObject* context); -DFHACK_EXPORT int Context_AsyncSuspend(DFHackObject* context); - -DFHACK_EXPORT DFHackObject* Context_getMemoryInfo(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getProcess(DFHackObject* context); - -DFHACK_EXPORT DFHackObject* Context_getCreatures(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getMaps(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getGui(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getMaterials(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getTranslation(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getVegetation(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getBuildings(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getConstructions(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getItems(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getWorld(DFHackObject* context); -DFHACK_EXPORT DFHackObject* Context_getWindowIO(DFHackObject* context); - -//these are DANGEROUS...can crash/segfault DF, turn the seas to blood, call up the Antichrist, etc -DFHACK_EXPORT void Context_ReadRaw(DFHackObject* context, const uint32_t offset, const uint32_t size, uint8_t* target); -DFHACK_EXPORT void Context_WriteRaw(DFHackObject* context, const uint32_t offset, const uint32_t size, uint8_t* source); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/DFProcess_C.h b/library/include/dfhack-c/DFProcess_C.h deleted file mode 100644 index 13d31aea3..000000000 --- a/library/include/dfhack-c/DFProcess_C.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -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 PROCESS_C_API -#define PROCESS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFProcess.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct c_processID -{ - uint64_t time; - uint64_t pid; -}; - -#define PROCESSID_C_NULL -2 -#define PROCESSID_C_LT -1 -#define PROCESSID_C_EQ 0 -#define PROCESSID_C_GT 1 - -DFHACK_EXPORT extern int C_ProcessID_Compare(c_processID* left, c_processID* right); - -DFHACK_EXPORT int Process_attach(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_detach(DFHackObject* p_Ptr); - -DFHACK_EXPORT int Process_suspend(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_asyncSuspend(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_resume(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_forceresume(DFHackObject* p_Ptr); - -DFHACK_EXPORT int Process_readQuad(DFHackObject* p_Ptr, uint32_t address, uint64_t* value); -DFHACK_EXPORT int Process_writeQuad(DFHackObject* p_Ptr, uint32_t address, uint64_t value); - -DFHACK_EXPORT int Process_readDWord(DFHackObject* p_Ptr, uint32_t address, uint32_t* value); -DFHACK_EXPORT int Process_writeDWord(DFHackObject* p_Ptr, uint32_t address, uint32_t value); - -DFHACK_EXPORT int Process_readWord(DFHackObject* p_Ptr, uint32_t address, uint16_t* value); -DFHACK_EXPORT int Process_writeWord(DFHackObject* p_Ptr, uint32_t address, uint16_t value); - -DFHACK_EXPORT int Process_readFloat(DFHackObject* p_Ptr, uint32_t address, float* value); - -DFHACK_EXPORT int Process_readByte(DFHackObject* p_Ptr, uint32_t address, uint8_t* value); -DFHACK_EXPORT int Process_writeByte(DFHackObject* p_Ptr, uint32_t address, uint8_t value); - -DFHACK_EXPORT uint8_t* Process_read(DFHackObject* p_Ptr, uint32_t address, uint32_t length); -DFHACK_EXPORT void Process_write(DFHackObject* p_Ptr, uint32_t address, uint32_t length, uint8_t* buffer); - -DFHACK_EXPORT int Process_readSTLVector(DFHackObject* p_Ptr, uint32_t address, t_vecTriplet* vector); - -DFHACK_EXPORT const char* Process_readString(DFHackObject* p_Ptr, uint32_t offset); -DFHACK_EXPORT const char* Process_getPath(DFHackObject* p_Ptr); -DFHACK_EXPORT const char* Process_readClassName(DFHackObject* p_Ptr, uint32_t vptr); - -DFHACK_EXPORT int Process_isSuspended(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_isAttached(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_isIdentified(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_isSnapshot(DFHackObject* p_Ptr); - -DFHACK_EXPORT uint32_t* Process_getThreadIDs(DFHackObject* p_Ptr); -DFHACK_EXPORT t_memrange* Process_getMemRanges(DFHackObject* p_Ptr); -DFHACK_EXPORT int Process_getPID(DFHackObject* p_Ptr, int32_t* pid); - -DFHACK_EXPORT int Process_getModuleIndex(DFHackObject* p_Ptr, char* name, uint32_t version, uint32_t* output); - -DFHACK_EXPORT int Process_SetAndWait(DFHackObject* p_Ptr, uint32_t state); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/DFTileTypes_C.h b/library/include/dfhack-c/DFTileTypes_C.h deleted file mode 100644 index 3d23dccb0..000000000 --- a/library/include/dfhack-c/DFTileTypes_C.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -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 TILETYPES_C_API -#define TILETYPES_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTileTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int DFHack_isWallTerrain(int in); -DFHACK_EXPORT int DFHack_isFloorTerrain(int in); -DFHACK_EXPORT int DFHack_isRampTerrain(int in); -DFHACK_EXPORT int DFHack_isStairTerrain(int in); -DFHACK_EXPORT int DFHack_isOpenTerrain(int in); -DFHACK_EXPORT int DFHack_getVegetationType(int in); - -DFHACK_EXPORT int DFHack_getTileType(int index, TileRow* tPtr); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/library/include/dfhack-c/DFTypes_C.h b/library/include/dfhack-c/DFTypes_C.h deleted file mode 100644 index 4cff7a6b3..000000000 --- a/library/include/dfhack-c/DFTypes_C.h +++ /dev/null @@ -1,262 +0,0 @@ -/* -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 TYPES_C_API -#define TYPES_C_API - -#include "dfhack-c/Common.h" -#include "DFProcess_C.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Maps.h" -#include "dfhack/modules/Materials.h" -#include "dfhack/modules/Gui.h" - -#define HBUILD(a) a ## BufferCallback -#define HREG_MACRO(type_name, type) DFHACK_EXPORT void HBUILD(Register ## type_name) (int (*funcptr)(type, uint32_t)); - -#define HUNREG_MACRO(type_name) DFHACK_EXPORT void HBUILD(Unregister ## type_name) (); - -#ifdef __cplusplus -extern "C" { -#endif - -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 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 int (*alloc_char_buffer_callback)(char**, uint32_t); - -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); - -DFHACK_EXPORT extern int (*alloc_feature_buffer_callback)(t_feature**, uint32_t); -DFHACK_EXPORT extern int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t); -DFHACK_EXPORT extern int (*alloc_screen_buffer_callback)(t_screen**, uint32_t); - -DFHACK_EXPORT extern int (*alloc_tree_buffer_callback)(dfh_plant**, uint32_t); - -DFHACK_EXPORT extern int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t); - -DFHACK_EXPORT void RegisterByteBufferCallback(int (*funcptr)(int8_t**, uint32_t)); -DFHACK_EXPORT void RegisterShortBufferCallback(int (*funcptr)(int16_t**, uint32_t)); -DFHACK_EXPORT void RegisterIntBufferCallback(int (*funcptr)(int32_t**, uint32_t)); - -DFHACK_EXPORT void RegisterUByteBufferCallback(int (*funcptr)(uint8_t**, uint32_t)); -DFHACK_EXPORT void RegisterUShortBufferCallback(int (*funcptr)(uint16_t**, uint32_t)); -DFHACK_EXPORT void RegisterUIntBufferCallback(int (*funcptr)(uint32_t**, uint32_t)); - -DFHACK_EXPORT void RegisterCharBufferCallback(int (*funcptr)(char**, uint32_t)); - -DFHACK_EXPORT void RegisterMatglossBufferCallback(int (*funcptr)(t_matgloss**, uint32_t)); -DFHACK_EXPORT void RegisterDescriptorColorBufferCallback(int (*funcptr)(t_descriptor_color**, uint32_t)); -DFHACK_EXPORT void RegisterMatglossOtherBufferCallback(int (*funcptr)(t_matglossOther**, uint32_t)); - -DFHACK_EXPORT void RegisterFeatureBufferCallback(int (*funcptr)(t_feature**, uint32_t)); -DFHACK_EXPORT void RegisterHotkeyBufferCallback(int (*funcptr)(t_hotkey**, uint32_t)); -DFHACK_EXPORT void RegisterScreenBufferCallback(int (*funcptr)(t_screen**, uint32_t)); - -DFHACK_EXPORT void RegisterTreeBufferCallback(int (*funcptr)(dfh_plant**, uint32_t)); - -DFHACK_EXPORT void RegisterMemRangeBufferCallback(int (*funcptr)(t_memrange**, uint32_t*, uint32_t)); - -HUNREG_MACRO(Byte) -HUNREG_MACRO(Short) -HUNREG_MACRO(Int) -HUNREG_MACRO(UByte) -HUNREG_MACRO(UShort) -HUNREG_MACRO(UInt) - -HUNREG_MACRO(Char) - -HUNREG_MACRO(Matgloss) -HUNREG_MACRO(DescriptorColor) -HUNREG_MACRO(MatglossOther) - -HUNREG_MACRO(Feature) -HUNREG_MACRO(Hotkey) -HUNREG_MACRO(Screen) - -HUNREG_MACRO(Tree) -HUNREG_MACRO(MemRange) - -struct t_customWorkshop -{ - uint32_t index; - char name[256]; -}; - -DFHACK_EXPORT extern int (*alloc_customWorkshop_buffer_callback)(t_customWorkshop**, uint32_t); -DFHACK_EXPORT extern int (*alloc_material_buffer_callback)(t_material**, uint32_t); - -DFHACK_EXPORT void RegisterCustomWorkshopBufferCallback(int (*funcptr)(t_customWorkshop**, uint32_t)); -DFHACK_EXPORT void RegisterMaterialBufferCallback(int (*funcptr)(t_material**, uint32_t)); - -HUNREG_MACRO(CustomWorkshop) -HUNREG_MACRO(Material) - -struct c_colormodifier -{ - char part[128]; - uint32_t* colorlist; - uint32_t colorlistLength; - uint32_t startdate; - uint32_t enddate; -}; - -struct c_colormodifier_descriptor -{ - uint32_t colorlistLength; -}; - -struct c_creaturecaste -{ - char rawname[128]; - char singular[128]; - char plural[128]; - char adjective[128]; - - c_colormodifier* colorModifier; - uint32_t colorModifierLength; - - t_bodypart* bodypart; - uint32_t bodypartLength; - - t_attrib strength; - t_attrib agility; - t_attrib toughness; - t_attrib endurance; - t_attrib recuperation; - t_attrib disease_resistance; - t_attrib analytical_ability; - t_attrib focus; - t_attrib willpower; - t_attrib creativity; - t_attrib intuition; - t_attrib patience; - t_attrib memory; - t_attrib linguistic_ability; - t_attrib spatial_sense; - t_attrib musicality; - t_attrib kinesthetic_sense; -}; - -struct c_creaturecaste_descriptor -{ - c_colormodifier_descriptor* color_descriptors; - uint32_t colorModifierLength; - uint32_t bodypartLength; -}; - -struct c_creaturetype -{ - char rawname[128]; - - c_creaturecaste* castes; - uint32_t castesCount; - - t_creatureextract* extract; - uint32_t extractCount; - - uint8_t tile_character; - - struct - { - uint16_t fore; - uint16_t back; - uint16_t bright; - } tilecolor; -}; - -struct c_creaturetype_descriptor -{ - c_creaturecaste_descriptor* caste_descriptors; - uint32_t castesCount; - uint32_t extractCount; -}; - -DFHACK_EXPORT extern int (*alloc_creaturetype_buffer_callback)(c_creaturetype**, c_creaturetype_descriptor*, 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 (*alloc_grassvein_buffer_callback)(t_grassvein**, uint32_t); -DFHACK_EXPORT extern int (*alloc_worldconstruction_buffer_callback)(t_worldconstruction**, uint32_t); - -DFHACK_EXPORT void RegisterCreatureTypeBufferCallback(int (*funcptr)(c_creaturetype**, c_creaturetype_descriptor*, uint32_t)); - -DFHACK_EXPORT void RegisterVeinBufferCallback(int (*funcptr)(t_vein**, uint32_t)); -DFHACK_EXPORT void RegisterFrozenLiquidVeinBufferCallback(int (*funcptr)(t_frozenliquidvein**, uint32_t)); -DFHACK_EXPORT void RegisterSpatterVeinBufferCallback(int (*funcptr)(t_spattervein**, uint32_t)); -DFHACK_EXPORT void RegisterGrassVeinBufferCallback(int (*funcptr)(t_grassvein**, uint32_t)); -DFHACK_EXPORT void RegisterWorldConstructionBufferCallback(int (*funcptr)(t_worldconstruction**, uint32_t)); - -HUNREG_MACRO(CreatureType) - -HUNREG_MACRO(Vein) -HUNREG_MACRO(FrozenLiquidVein) -HUNREG_MACRO(SpatterVein) -HUNREG_MACRO(GrassVein) -HUNREG_MACRO(WorldConstruction) - -struct c_mapcoord -{ - union - { - struct - { - uint16_t x; - uint16_t y; - uint32_t z; - }; - struct - { - uint16_t x; - uint16_t y; - } dim; - - uint64_t comparate; - }; -}; - -struct c_featuremap_node -{ - c_mapcoord coordinate; - t_feature* features; - uint32_t feature_length; -}; - -DFHACK_EXPORT extern int (*alloc_featuremap_buffer_callback)(c_featuremap_node**, uint32_t*, uint32_t); - -DFHACK_EXPORT void RegisterFeatureMapBufferCallback(int (*funcptr)(c_featuremap_node**, uint32_t*, uint32_t)); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/library/include/dfhack-c/README_C.rst b/library/include/dfhack-c/README_C.rst deleted file mode 100644 index 875903357..000000000 --- a/library/include/dfhack-c/README_C.rst +++ /dev/null @@ -1,133 +0,0 @@ -======================================= -Introduction And Reasons For Existence -======================================= - -C++ is not an easy language to access from other languages. There are several "features" that make interoperability considerably more painful when trying to write bindings for Python, Ruby, Lua, or whatever. To that end, dfhack has a C translation layer to ease the process of making bindings for other languages. A shadow API, if you will. - -.. contents:: - - -================= -Getting DFHack-C -================= -The C shim is a part of the standard dfhack package. If you've installed dfhack, you've already got it. The dfhack source and binaries are hosted on github_, at http://github.com/peterix/dfhack - -.. _github: http://www.github.com/ - -Packages -========= -The library and tools are packaged for Archlinux and are available both -in AUR and the arch-games repository. - -The package name is dfhack-git. - -======== -Layout -======== -The structure of the C shim mimics, as far as possible, the normal dfhack structure. Of course, since C lacks things like classes, templates, and function overloading, there are a few places where deviations are unavoidable. - -Return Values -============= -Unless otherwise specified, functions that return an int return one of the following values: - -- 0: The operation failed. -- 1: The operation succeeded. -- -1: An invalid module pointer was supplied. - -Types -======= -Module objects are passed around as void pointers with the typedef name 'DFHackObject'. Wherever possible, the structures and enumerations defined by dfhack are used without redefinition. - -Allocator Callbacks -==================== -Wherever possible, the C shim eschews the native allocation of memory, as this would require language bindings to remember to free the memory later, and would, in my opinion, make the shim less flexible. So a number of function pointers are exposed to allow memory to be allocated in the language being used to wrap dfhack. In general, the allocations relate to arrays of dfhack structures, but there are a couple of corner cases. - -The buffer callback functions should take a pointer to an array of the particular type, and a 32-bit unsigned integer (uint32_t) defining the length of the array needed. If the buffer was successfully created, the callback function should return 1. In case of failure, set the buffer pointer to NULL (or 0) and return 0. - -All of the allocators are defined in dfhack/library/include/dfhack-c/DFTypes_C.h. - -Buffer Callback List ---------------------- -- alloc_byte_buffer_callback(int8_t**, uint32_t) -- alloc_short_buffer_callback(int16_t**, uint32_t) -- alloc_int_buffer_callback(int32_t**, uint32_t) -- alloc_ubyte_buffer_callback(uint8_t**, uint32_t) -- alloc_ushort_buffer_callback(uint16_t**, uint32_t) -- alloc_uint_buffer_callback(uint32_t**, uint32_t) -- alloc_char_buffer_callback(char** uint32_t) -- alloc_matgloss_buffer_callback(t_matgloss**, uint32_t) -- alloc_descriptor_buffer_callback(t_descriptor_color**, uint32_t) -- alloc_matgloss_other_buffer_callback(t_matglossOther**, uint32_t) -- alloc_t_feature_buffer_callback(t_feature**, uint32_t) -- alloc_t_hotkey_buffer_callback(t_hotkey**, uint32_t) -- alloc_t_screen_buffer_callback(t_screen**, uint32_t) -- alloc_t_customWorkshop_buffer_callback(t_customWorkshop**, uint32_t) -- alloc_t_material_buffer_callback(t_material**, uint32_t) -- alloc_vein_buffer_callback(t_vein**, uint32_t) -- alloc_frozenliquidvein_buffer_callback(t_frozenliquidvein**, uint32_t) -- alloc_spattervein_buffer_callback(t_spattervein**, uint32_t) -- alloc_grassvein_buffer_callback(t_grassvein**, uint32_t) -- alloc_worldconstruction_buffer_callback(t_worldconstruction**, uint32_t) - - -Templates Make My Life Harder -------------------------------- -Several dfhack structures contain vectors, which (obviously) don't work in C. Therefore, these structures have C versions that replace the vector with a buffer and length, but are otherwise identical to their C++ counterparts. For each structure, there are three associated callbacks. One initializes an empty instance of the structure (*alloc_empty_colormodifier_callback*, for instance), one initializes an instance with values passed in (*alloc_colormodifier_callback*), and one allocates a buffer in the same manner as the other allocators (*alloc_colormodifier_buffer_callback*). - -The replaced structures and their callbacks are as follows. - -- c_colormodifier - * alloc_empty_colormodifier_callback(c_colormodifier*) - * alloc_colormodifier_callback(c_colormodifier*, const char*, uint32_t) - * alloc_colormodifier_buffer_callback(c_colormodifier*, uint32_t) -- c_creaturecaste - * alloc_empty_creaturecaste_callback(c_creaturecaste*) - * alloc_creaturecaste_callback(c_creaturecaste*, const char*, const char*, const char*, const char*, uint32_t, uint32_t) - * alloc_creaturecaste_buffer_callback(c_creaturecaste*, uint32_t) -- c_creaturetype - * alloc_empty_creaturetype_callback(c_creaturetype*) - * alloc_creaturetype_callback(c_creaturetype*, const char*, uint32_t, uint32_t, uint8_t, uint16_t, uint16_t, uint16_t) - * alloc_creaturetype_buffer_callback(c_creaturetype*, uint32_t) - -A Small Callback Example In Python -------------------------------------- -The Python bindings for dfhack implement the unsigned integer allocator callback like this: - -.. admonition:: util.py - - | from ctypes import \* - | - | def _allocate_array(t_type, count): - | arr_type = t_type * count - | arr = arr_type() - | - | return arr - | - | def _alloc_uint_buffer(ptr, count): - | a = _allocate_array(c_uint, count) - | - | p = cast(a, POINTER(c_uint)) - | - | ptr[0] = p - | - | return 1 - | - | _uint_functype = CFUNCTYPE(c_int, POINTER(c_uint), c_uint) - | alloc_uint_buffer = _uint_functype(_alloc_uint_buffer) - -.. admonition:: dftypes.py - - | from ctypes import \* - | from util import \* - | - | libdfhack = cdll.libdfhack - | - | def _register_callback(name, func): - | ptr = c_void_p.in_dll(libdfhack, name) - | ptr.value = cast(func, c_void_p).value - | - | _register_callback("alloc_uint_buffer_callback", alloc_uint_buffer) - -Modules -======== -Every dfhack module has a corresponding set of C functions. The functions are named _, as in 'Maps_Start', 'Materials_ReadOthers', etc. The first argument to any module function is a void pointer that points to an instance of the module object in question. diff --git a/library/include/dfhack-c/modules/Buildings_C.h b/library/include/dfhack-c/modules/Buildings_C.h deleted file mode 100644 index 772be4b76..000000000 --- a/library/include/dfhack-c/modules/Buildings_C.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -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 BUILDINGS_C_API -#define BUILDINGS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Buildings.h" -#include "dfhack-c/DFTypes_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Buildings_Start(DFHackObject* b_Ptr, uint32_t* numBuildings); -DFHACK_EXPORT int Buildings_Finish(DFHackObject* b_Ptr); - -DFHACK_EXPORT int Buildings_Read(DFHackObject* b_Ptr, const uint32_t index, t_building* building); - -DFHACK_EXPORT t_customWorkshop* Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr); -DFHACK_EXPORT int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Constructions_C.h b/library/include/dfhack-c/modules/Constructions_C.h deleted file mode 100644 index 53456bbf3..000000000 --- a/library/include/dfhack-c/modules/Constructions_C.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -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 CONSTRUCTIONS_C_API -#define CONSTRUCTIONS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Constructions.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Constructions_Start(DFHackObject* c_Ptr, uint32_t* numConstructions); -DFHACK_EXPORT int Constructions_Finish(DFHackObject* c_Ptr); - -DFHACK_EXPORT int Constructions_Read(DFHackObject* c_Ptr, const uint32_t index, t_construction* construction); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Creatures_C.h b/library/include/dfhack-c/modules/Creatures_C.h deleted file mode 100644 index 4b6a2d004..000000000 --- a/library/include/dfhack-c/modules/Creatures_C.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -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 CREATURES_C_API -#define CREATURES_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack/modules/Materials.h" -#include "dfhack/modules/Creatures.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Creatures_Start(DFHackObject* cPtr, uint32_t* numCreatures); -DFHACK_EXPORT int Creatures_Finish(DFHackObject* cPtr); - -DFHACK_EXPORT int32_t Creatures_ReadCreatureInBox(DFHackObject* cPtr, 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); - -DFHACK_EXPORT int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* furball); -DFHACK_EXPORT t_material* Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball); - -DFHACK_EXPORT uint32_t* Creatures_ReadInventoryIdx(DFHackObject* cPtr, const uint32_t index); -DFHACK_EXPORT uint32_t* Creatures_ReadInventoryPtr(DFHackObject* cPtr, const uint32_t index); - -DFHACK_EXPORT uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr); -DFHACK_EXPORT int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr); - -DFHACK_EXPORT int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); -DFHACK_EXPORT int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value); -DFHACK_EXPORT int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2); -DFHACK_EXPORT int Creatures_WriteFlags3(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2, const uint32_t flags3); -DFHACK_EXPORT int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul); -DFHACK_EXPORT int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature); -DFHACK_EXPORT int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex); -DFHACK_EXPORT int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul); -DFHACK_EXPORT int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood); -DFHACK_EXPORT int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill); -DFHACK_EXPORT int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count); -DFHACK_EXPORT int Creatures_WritePos(DFHackObject* cPtr, const uint32_t index, const t_creature* creature); -DFHACK_EXPORT int Creatures_WriteCiv(DFHackObject* cPtr, const uint32_t index, const int32_t civ); -DFHACK_EXPORT int Creatures_WritePregnancy(DFHackObject* cPtr, const uint32_t index, const uint32_t pregTimer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Gui_C.h b/library/include/dfhack-c/modules/Gui_C.h deleted file mode 100644 index e1014258b..000000000 --- a/library/include/dfhack-c/modules/Gui_C.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -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 GUI_C_API -#define GUI_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Gui.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Gui_Start(DFHackObject* gui); -DFHACK_EXPORT int Gui_Finish(DFHackObject* gui); - -DFHACK_EXPORT int Gui_getViewCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z); -DFHACK_EXPORT int Gui_setViewCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z); - -DFHACK_EXPORT int Gui_getCursorCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z); -DFHACK_EXPORT int Gui_setCursorCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z); - -DFHACK_EXPORT t_hotkey* Gui_ReadHotkeys(DFHackObject* gui); - -DFHACK_EXPORT int Gui_getWindowSize(DFHackObject* gui, int32_t* width, int32_t* height); - -DFHACK_EXPORT t_screen* Gui_getScreenTiles(DFHackObject* gui, int32_t width, int32_t height); - -DFHACK_EXPORT int Gui_ReadViewScreen(DFHackObject* gui, t_viewscreen* viewscreen); -DFHACK_EXPORT int Gui_ReadMenuState(DFHackObject* gui, uint32_t* menuState); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Items_C.h b/library/include/dfhack-c/modules/Items_C.h deleted file mode 100644 index 5f43dc0a7..000000000 --- a/library/include/dfhack-c/modules/Items_C.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -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 ITEMS_C_API -#define ITEMS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFProcess.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack/modules/Items.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Items_Start(DFHackObject* items); -DFHACK_EXPORT int Items_Finish(DFHackObject* items); - -DFHACK_EXPORT char* Items_getItemDescription(DFHackObject* items, dfh_item* item, DFHackObject* mats); -DFHACK_EXPORT char* Items_getItemClass(DFHackObject* items, int32_t index); -DFHACK_EXPORT int Items_getItemData(DFHackObject* items, uint32_t itemptr, dfh_item* item); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Maps_C.h b/library/include/dfhack-c/modules/Maps_C.h deleted file mode 100644 index 518a3623f..000000000 --- a/library/include/dfhack-c/modules/Maps_C.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -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 MAPS_C_API -#define MAPS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Maps.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Maps_Start(DFHackObject* maps); -DFHACK_EXPORT int Maps_Finish(DFHackObject* maps); - -DFHACK_EXPORT uint16_t* Maps_ReadGeology(DFHackObject* maps); - -DFHACK_EXPORT t_feature* Maps_ReadGlobalFeatures(DFHackObject* maps); -DFHACK_EXPORT c_featuremap_node* Maps_ReadLocalFeatures(DFHackObject* maps); - -DFHACK_EXPORT void Maps_getSize(DFHackObject* maps, uint32_t* x, uint32_t* y, uint32_t* z); -DFHACK_EXPORT void Maps_getPosition(DFHackObject* maps, int32_t* x, int32_t* y, int32_t* z); - -DFHACK_EXPORT int Maps_isValidBlock(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); - -DFHACK_EXPORT uint32_t Maps_getBlockPtr(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); - -DFHACK_EXPORT int Maps_ReadBlock40d(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, mapblock40d* buffer); - -DFHACK_EXPORT int Maps_ReadTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer); -DFHACK_EXPORT int Maps_WriteTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer); - -DFHACK_EXPORT int Maps_ReadDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer); -DFHACK_EXPORT int Maps_WriteDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer); - -DFHACK_EXPORT int Maps_ReadTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2); -DFHACK_EXPORT int Maps_WriteTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2); - -DFHACK_EXPORT int Maps_ReadOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer); -DFHACK_EXPORT int Maps_WriteOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer); - -DFHACK_EXPORT int Maps_ReadDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int* dirtybit); -DFHACK_EXPORT int Maps_WriteDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int dirtybit); - -DFHACK_EXPORT int Maps_ReadFeatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t* local, int16_t* global); -DFHACK_EXPORT int Maps_WriteLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local); -DFHACK_EXPORT int Maps_WriteEmptyLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); -DFHACK_EXPORT int Maps_WriteGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local); -DFHACK_EXPORT int Maps_WriteEmptyGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); - -DFHACK_EXPORT int Maps_ReadBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags* blockflags); -DFHACK_EXPORT int Maps_WriteBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags); - -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); -DFHACK_EXPORT t_grassvein* Maps_ReadGrassVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); -DFHACK_EXPORT t_worldconstruction* Maps_ReadWorldConstructions(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); - -typedef struct -{ - t_vein* veins; - t_frozenliquidvein* frozen_veins; - t_spattervein* spatter_veins; - t_grassvein* grass_veins; - t_worldconstruction* world_constructions; -} c_allveins; - -DFHACK_EXPORT int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_allveins* vein_struct); - -DFHACK_EXPORT dfh_plant* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Materials_C.h b/library/include/dfhack-c/modules/Materials_C.h deleted file mode 100644 index ca10e2152..000000000 --- a/library/include/dfhack-c/modules/Materials_C.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -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 MATERIALS_C_API -#define MATERIALS_C_API - -#include "dfhack-c/Common.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack/modules/Materials.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Materials_ReadInorganicMaterials(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadOrganicMaterials(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadWoodMaterials(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadPlantMaterials(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadCreatureTypes(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadCreatureTypesEx(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadDescriptorColors(DFHackObject* mat); -DFHACK_EXPORT int Materials_ReadOthers(DFHackObject* mat); - -DFHACK_EXPORT void Materials_ReadAllMaterials(DFHackObject* mat); - -DFHACK_EXPORT const char* Materials_getType(DFHackObject* mat, t_material* material); -DFHACK_EXPORT const char* Materials_getDescription(DFHackObject* mat, t_material* material); - -DFHACK_EXPORT int Materials_getInorganicSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getOrganicSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getTreeSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getPlantSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getRaceSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getRaceExSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getColorSize(DFHackObject* mat); -DFHACK_EXPORT int Materials_getOtherSize(DFHackObject* mat); - -DFHACK_EXPORT t_matgloss* Materials_getInorganic(DFHackObject* mat); -DFHACK_EXPORT t_matgloss* Materials_getOrganic(DFHackObject* mat); -DFHACK_EXPORT t_matgloss* Materials_getTree(DFHackObject* mat); -DFHACK_EXPORT t_matgloss* Materials_getPlant(DFHackObject* mat); -DFHACK_EXPORT t_matgloss* Materials_getRace(DFHackObject* mat); - -DFHACK_EXPORT c_creaturetype* Materials_getRaceEx(DFHackObject* mat); -DFHACK_EXPORT t_descriptor_color* Materials_getColor(DFHackObject* mat); -DFHACK_EXPORT t_matglossOther* Materials_getOther(DFHackObject* mat); -DFHACK_EXPORT t_matgloss* Materials_getAllDesc(DFHackObject* mat); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Translation_C.h b/library/include/dfhack-c/modules/Translation_C.h deleted file mode 100644 index 87665f454..000000000 --- a/library/include/dfhack-c/modules/Translation_C.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -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 TRANSLATION_C_API -#define TRANSLATION_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack-c/DFTypes_C.h" -#include "dfhack/modules/Translation.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Translation_Start(DFHackObject* trans); -DFHACK_EXPORT int Translation_Finish(DFHackObject* trans); - -DFHACK_EXPORT char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name); -DFHACK_EXPORT char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/Vegetation_C.h b/library/include/dfhack-c/modules/Vegetation_C.h deleted file mode 100644 index 8fbaf99b9..000000000 --- a/library/include/dfhack-c/modules/Vegetation_C.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -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 VEGETATION_C_API -#define VEGETATION_C_API - -#include "dfhack-c/Common.h" -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Vegetation.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees); -DFHACK_EXPORT int Vegetation_Finish(DFHackObject* veg); - -DFHACK_EXPORT int Vegetation_Read(DFHackObject* veg, const uint32_t index, dfh_plant* shrubbery); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/WindowIO_C.h b/library/include/dfhack-c/modules/WindowIO_C.h deleted file mode 100644 index 42c485d0f..000000000 --- a/library/include/dfhack-c/modules/WindowIO_C.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -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/Common.h" -#include "dfhack/modules/WindowIO.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DFHACK_EXPORT int WindowIO_TypeStr(DFHackObject* window, const char* input, uint32_t delay, int8_t useShift); - -DFHACK_EXPORT int WindowIO_TypeSpecial(DFHackObject* window, t_special command, uint32_t count, uint32_t delay); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack-c/modules/World_C.h b/library/include/dfhack-c/modules/World_C.h deleted file mode 100644 index d111f402f..000000000 --- a/library/include/dfhack-c/modules/World_C.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -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/Common.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); - -DFHACK_EXPORT int World_ReadCurrentWeather(DFHackObject* world, uint8_t* weather); -DFHACK_EXPORT int World_WriteCurrentWeather(DFHackObject* world, uint8_t weather); - -DFHACK_EXPORT int World_ReadGameMode(DFHackObject* world, t_gamemodes*); -DFHACK_EXPORT int World_WriteGameMode(DFHackObject* world, t_gamemodes); - -DFHACK_EXPORT int World_ReadPauseState(DFHackObject* gui); -DFHACK_EXPORT int World_SetPauseState(DFHackObject* gui, int8_t paused); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/library/include/dfhack/Console.h b/library/include/dfhack/Console.h new file mode 100644 index 000000000..cddaba475 --- /dev/null +++ b/library/include/dfhack/Console.h @@ -0,0 +1,99 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + +#pragma once +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include +#include "FakeSDL.h" +namespace DFHack +{ + class Private; + class DFHACK_EXPORT Console : public std::ostream + { + public: + enum color_value + { + COLOR_RESET = -1, + COLOR_BLACK = 0, + COLOR_BLUE, + COLOR_GREEN, + COLOR_CYAN, + COLOR_RED, + COLOR_MAGENTA, + COLOR_BROWN, + COLOR_GREY, + COLOR_DARKGREY, + COLOR_LIGHTBLUE, + COLOR_LIGHTGREEN, + COLOR_LIGHTCYAN, + COLOR_LIGHTRED, + COLOR_LIGHTMAGENTA, + COLOR_YELLOW, + COLOR_WHITE, + COLOR_MAX = COLOR_WHITE + }; + ///ctor, NOT thread-safe + Console(); + ///dtor, NOT thread-safe + ~Console(); + /// initialize the console. NOT thread-safe + bool init( void ); + /// shutdown the console. NOT thread-safe + bool shutdown( void ); + + /// Print a formatted string, like printf + int print(const char * format, ...); + /// Print a formatted string, like printf, in red + int printerr(const char * format, ...); + /// Clear the console, along with its scrollback + void clear(); + /// Position cursor at x,y. 1,1 = top left corner + void gotoxy(int x, int y); + /// Set color (ANSI color number) + void color(color_value c); + /// Reset color to default + void reset_color(void); + /// Enable or disable the caret/cursor + void cursor(bool enable = true); + /// Waits given number of milliseconds before continuing. + void msleep(unsigned int msec); + /// get the current number of columns + int get_columns(void); + /// get the current number of rows + int get_rows(void); + /// beep. maybe? + //void beep (void); + /// A simple line edit (raw mode) + int lineedit(const std::string& prompt, std::string& output); + /// add a command to the history + void history_add(const std::string& command); + /// clear the command history + void history_clear(); + private: + Private * d; + SDL::Mutex * wlock; + bool inited; + }; +} \ No newline at end of file diff --git a/library/include/dfhack/Core.h b/library/include/dfhack/Core.h new file mode 100644 index 000000000..8ca16714f --- /dev/null +++ b/library/include/dfhack/Core.h @@ -0,0 +1,166 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + +#pragma once + +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include "dfhack/FakeSDL.h" +#include +#include +#include +#include +#include "dfhack/Console.h" + +namespace DFHack +{ + class Process; + class Module; + class Creatures; + class Engravings; + class Maps; + class Gui; + class World; + class Materials; + class Items; + class Translation; + class Vegetation; + class Buildings; + class Constructions; + class Vermin; + class Notes; + class VersionInfo; + class VersionInfoFactory; + class PluginManager; + class Core; + // anon type, pretty much + struct DFLibrary; + + DFLibrary * OpenPlugin (const char * filename); + void * LookupPlugin (DFLibrary * plugin ,const char * function); + void ClosePlugin (DFLibrary * plugin); + + // Core is a singleton. Why? Because it is closely tied to SDL calls. It tracks the global state of DF. + // There should never be more than one instance + // Better than tracking some weird variables all over the place. + class DFHACK_EXPORT Core + { + friend int ::SDL_NumJoysticks(void); + friend void ::SDL_Quit(void); + friend int ::SDL_PollEvent(SDL::Event *); + public: + /// Get the single Core instance or make one. + static Core& getInstance() + { + // FIXME: add critical section for thread safety here. + static Core instance; + return instance; + } + /// try to acquire the activity lock + void Suspend(void); + /// return activity lock + void Resume(void); + /// Is everything OK? + bool isValid(void) { return !errorstate; } + + /// get the creatures module + Creatures * getCreatures(); + /// get the engravings module + Engravings * getEngravings(); + /// get the maps module + Maps * getMaps(); + /// get the gui module + Gui * getGui(); + /// get the world module + World * getWorld(); + /// get the materials module + Materials * getMaterials(); + /// get the items module + Items * getItems(); + /// get the translation module + Translation * getTranslation(); + /// get the vegetation module + Vegetation * getVegetation(); + /// get the buildings module + Buildings * getBuildings(); + /// get the constructions module + Constructions * getConstructions(); + /// get the vermin module + Vermin * getVermin(); + /// get the notes module + Notes * getNotes(); + /// sets the current hotkey command + bool setHotkeyCmd( std::string cmd ); + /// removes the hotkey command and gives it to the caller thread + std::string getHotkeyCmd( void ); + + DFHack::Process * p; + DFHack::VersionInfo * vinfo; + DFHack::Console con; + private: + Core(); + bool Init(); + int Update (void); + int Shutdown (void); + int SDL_Event(SDL::Event* event, int orig_return); + Core(Core const&); // Don't Implement + void operator=(Core const&); // Don't implement + bool errorstate; + // regulate access to DF + struct Cond; + SDL::Mutex * AccessMutex; + SDL::Mutex * StackMutex; + std::stack < Core::Cond * > suspended_tools; + Core::Cond * core_cond; + // FIXME: shouldn't be kept around like this + DFHack::VersionInfoFactory * vif; + // Module storage + struct + { + Creatures * pCreatures; + Engravings * pEngravings; + Maps * pMaps; + Gui * pGui; + World * pWorld; + Materials * pMaterials; + Items * pItems; + Translation * pTranslation; + Vegetation * pVegetation; + Buildings * pBuildings; + Constructions * pConstructions; + Vermin * pVermin; + Notes * pNotes; + } s_mods; + std::vector allModules; + DFHack::PluginManager * plug_mgr; + // hotkey-related stuff + int hotkey_states[16]; + std::string hotkey_cmd; + bool hotkey_set; + SDL::Mutex * HotkeyMutex; + SDL::Cond * HotkeyCond; + // Very important! + bool started; + }; +} diff --git a/library/include/dfhack/DFContext.h b/library/include/dfhack/DFContext.h deleted file mode 100644 index 7c5518157..000000000 --- a/library/include/dfhack/DFContext.h +++ /dev/null @@ -1,172 +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. -*/ - -#pragma once - -#ifndef CONTEXT_H_INCLUDED -#define CONTEXT_H_INCLUDED - -#include "DFExport.h" -namespace DFHack -{ - class Creatures; - class Engravings; - class Maps; - class Gui; - class World; - class Materials; - class Items; - class Translation; - class Vegetation; - class Buildings; - class Constructions; - class VersionInfo; - class DFContextShared; - class WindowIO; - class Process; - /** - * This class wraps all the different related objects for a particular Process - * \ingroup grp_context - */ - class DFHACK_EXPORT Context - { - public: - Context(Process * p); - ~Context(); - - /// @return true if there's version information for the associated Process - bool isValid(); - /// attach to the related process. Claims OS debugging resources - bool Attach(); - /// detach from the related process. Releases OS debugging resources - bool Detach(); - /// @return true if the process is attached. - 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(); - - VersionInfo *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); - - /// get the creatures module - Creatures * getCreatures(); - - /// get the engravings module - Engravings * getEngravings(); - - /// get the maps module - Maps * getMaps(); - - /// get the gui module - Gui * getGui(); - - /// get the world module - World * getWorld(); - - /// get the materials module - Materials * getMaterials(); - - /// get the items module - Items * getItems(); - - /// get the translation module - Translation * getTranslation(); - - /// get the vegetation module - Vegetation * getVegetation(); - - /// get the buildings module - Buildings * getBuildings(); - - /// get the constructions module - Constructions * getConstructions(); - - /// get the Window management and I/O module - WindowIO * getWindowIO(); - - // DEAD CODE, WAITING TO BE UPDATED TO DF2010 - /* - * Effects like mist, dragonfire or dust - */ - /* - bool InitReadEffects ( uint32_t & numeffects ); - bool ReadEffect(const uint32_t index, t_effect_df40d & effect); - bool WriteEffect(const uint32_t index, const t_effect_df40d & effect); - void FinishReadEffects(); - */ - /* - * Notes placed by the player - */ - /* - /// start reading notes. numnotes is an output - total notes present - bool InitReadNotes( uint32_t & numnotes ); - /// read note from the note vector at index - bool ReadNote(const int32_t index, t_note & note); - /// free the note vector - void FinishReadNotes(); - */ - /* - * Settlements - */ - /* - bool InitReadSettlements( uint32_t & numsettlements ); - bool ReadSettlement(const int32_t index, t_settlement & settlement); - bool ReadCurrentSettlement(t_settlement & settlement); - void FinishReadSettlements(); - */ - /* - * Item reading - */ - /* - bool InitReadItems(uint32_t & numitems); - bool getItemIndexesInBox(std::vector &indexes, - 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 ReadItem(const uint32_t index, t_item & item); - void FinishReadItems(); - */ - /* - * Get the other API parts for raw access - */ - private: - DFContextShared * d; - }; -} -#endif //CONTEXT_H_INCLUDED - diff --git a/library/include/dfhack/DFContextManager.h b/library/include/dfhack/DFContextManager.h deleted file mode 100644 index c70638ffd..000000000 --- a/library/include/dfhack/DFContextManager.h +++ /dev/null @@ -1,149 +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. -*/ - -#pragma once - -#ifndef CONTEXTMANAGER_H_INCLUDED -#define CONTEXTMANAGER_H_INCLUDED - - -#include "DFPragma.h" -#include "DFExport.h" -#include -#include -#include - -namespace DFHack -{ - class Context; - class BadContexts; - class Process; - /** - * Used to enumerate, create and destroy Contexts. The very base of DFHack. - * @see DFHack::Context - * \ingroup grp_context - */ - class DFHACK_EXPORT ContextManager - { - 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(); - - /** - * 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. The Context isn't attached! - */ - 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 - * \ingroup grp_context - */ - 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 diff --git a/library/include/dfhack/DFIntegers.h b/library/include/dfhack/DFIntegers.h deleted file mode 100644 index 6e4c6384f..000000000 --- a/library/include/dfhack/DFIntegers.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -This file is a wrapper for stdint.h - -Visual Studio doesn't have stdint.h - -stdint.h is part of the C99 standard. It's ancient and simply should be there. FAIL - -You can turn off the include by defining SKIP_DFHACK_STDINT -*/ - -#pragma once - -#ifndef SKIP_DFHACK_STDINT - #ifndef _MSC_VER - #include - #else - #include "DFstdint_win.h" - #endif -#endif diff --git a/library/include/dfhack/DFPragma.h b/library/include/dfhack/DFPragma.h deleted file mode 100644 index 74735ca50..000000000 --- a/library/include/dfhack/DFPragma.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#ifndef DFHACK_TRANQUILITY -#define DFHACK_TRANQUILITY - -// This is here to keep MSVC from spamming the build output with nonsense -// Call it public domain. - -#ifdef _MSC_VER - // don't spew nonsense - #pragma warning( disable: 4251 ) - // don't display bogus 'deprecation' and 'unsafe' warnings. - // See the idiocy: http://msdn.microsoft.com/en-us/magazine/cc163794.aspx - #define _CRT_SECURE_NO_DEPRECATE - #define _SCL_SECURE_NO_DEPRECATE - #pragma warning( disable: 4996 ) - // Let me demonstrate: - /** - * [peterix@peterix dfhack]$ man wcscpy_s - * No manual entry for wcscpy_s - * - * Proprietary extensions. - */ - // disable stupid - #pragma warning( disable: 4800 ) - // disable more stupid - #pragma warning( disable: 4068 ) -#endif - -#endif diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h deleted file mode 100644 index 9b7032c09..000000000 --- a/library/include/dfhack/DFProcess.h +++ /dev/null @@ -1,246 +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. -*/ - -#pragma once - -#ifndef PROCESS_H_INCLUDED -#define PROCESS_H_INCLUDED - -#include "DFPragma.h" -#include "DFExport.h" -#include -#include - -namespace DFHack -{ - class VersionInfo; - class Process; - class Window; - class DFVector; - - /** - * A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification) - * \ingroup grp_context - */ - 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 section of virtual memory inside a process - * \ingroup grp_context - */ - struct DFHACK_EXPORT t_memrange - { - uint64_t start; - uint64_t end; - // memory range name (if any) - char name[1024]; - // permission to read - bool read : 1; - // permission to write - bool write : 1; - // permission to execute - bool execute : 1; - // is a shared region - bool shared : 1; - inline bool isInRange( uint64_t address) - { - if (address >= start && address < end) return true; - return false; - } - bool valid; - uint8_t * buffer; - }; - struct t_vecTriplet - { - uint32_t start; - uint32_t end; - uint32_t alloc_end; - }; - - /** - * Allows low-level access to the memory of an OS process. OS processes can be enumerated by \ref ProcessEnumerator - * \ingroup grp_context - */ - class DFHACK_EXPORT Process - { - protected: - std::map classNameCache; - - public: - /// this is the single most important destructor ever. ~px - virtual ~Process(){}; - /// Set up stuff so we can read memory, suspends synchronously - virtual bool attach() = 0; - /// 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 - */ - virtual bool suspend() = 0; - /// asynchronous suspend to use together with polling and timers - virtual bool asyncSuspend() = 0; - /// resume DF execution - virtual bool resume() = 0; - /// force-resume DF execution - virtual bool forceresume() = 0; - - /// read a 8-byte integer - uint64_t readQuad(const uint32_t address) { uint64_t result; readQuad(address, result); return result; } - /// 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 - uint32_t readDWord(const uint32_t address) { uint32_t result; readDWord(address, result); return result; } - /// 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 - float readFloat(const uint32_t address) { float result; readFloat(address, result); return result; } - /// write a float - virtual void readFloat(const uint32_t address, float & value) = 0; - - /// read a 2-byte integer - uint16_t readWord(const uint32_t address) { uint16_t result; readWord(address, result); return result; } - /// 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 - uint8_t readByte(const uint32_t address) { uint8_t result; readByte(address, result); return result; } - /// 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 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 - * @return length written - */ - virtual size_t writeSTLString(const uint32_t address, const std::string writeString) = 0; - /** - * attempt to copy a string from source address to target address. may truncate or leak, depending on platform - * @return length copied - */ - virtual size_t copySTLString(const uint32_t address, const uint32_t target) - { - return writeSTLString(target, readSTLString(address)); - } - - /// read a STL vector - virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; - virtual void writeSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; - /// get class name of an object with rtti/type info - virtual std::string doReadClassName(uint32_t vptr) = 0; - - std::string readClassName(uint32_t vptr) - { - std::map::iterator it = classNameCache.find(vptr); - if (it != classNameCache.end()) - return it->second; - return classNameCache[vptr] = doReadClassName(vptr); - } - - /// 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; - /// @return true if this is a Process snapshot - virtual bool isSnapshot() { return false; }; - - /// find the thread IDs of the process - virtual bool getThreadIDs(std::vector & threads ) = 0; - /// get virtual memory ranges of the process (what is mapped where) - virtual void getMemRanges(std::vector & ranges ) = 0; - - /// get the flattened Memory.xml entry of this process - virtual VersionInfo *getDescriptor() = 0; - /// get the DF Process ID - virtual int getPID() = 0; - /// get the DF Process FilePath - virtual std::string getPath() = 0; - /// 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 - virtual char * getSHMStart (void) = 0; - /// set a SHM command and wait for a response, return 0 on error or throw exception - virtual bool SetAndWait (uint32_t state) = 0; - }; - - class DFHACK_EXPORT ClassNameCheck - { - std::string name; - mutable uint32_t vptr; - public: - ClassNameCheck() : vptr(0) {}; - ClassNameCheck(std::string _name) : name(_name), vptr(0) {}; - ClassNameCheck &operator= (const ClassNameCheck &b) - { - name = b.name; vptr = b.vptr; return *this; - } - bool operator() (Process *p, uint32_t ptr) const { - if (vptr == 0 && p->readClassName(ptr) == name) - vptr = ptr; - return (vptr && vptr == ptr); - }; - }; -} -#endif diff --git a/library/include/dfhack/DFProcessEnumerator.h b/library/include/dfhack/DFProcessEnumerator.h deleted file mode 100644 index 228219727..000000000 --- a/library/include/dfhack/DFProcessEnumerator.h +++ /dev/null @@ -1,136 +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. -*/ - -#pragma once - -#ifndef PROCESSMANAGER_H_INCLUDED -#define PROCESSMANAGER_H_INCLUDED - -#include "DFPragma.h" -#include "DFExport.h" - -namespace DFHack -{ - class VersionInfo; - class Process; - class BadProcesses; - /** - * Process enumerator - * Used to enumerate, create and destroy Processes. - * @see DFHack::Process - * \ingroup grp_context - */ - class DFHACK_EXPORT ProcessEnumerator - { - class Private; - Private * const d; - public: - /** - * 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(); - - /** - * 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 - * \ingroup grp_context - */ - 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 diff --git a/library/include/dfhack/DFVector.h b/library/include/dfhack/DFVector.h deleted file mode 100644 index a688919ea..000000000 --- a/library/include/dfhack/DFVector.h +++ /dev/null @@ -1,136 +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. -*/ - -#pragma once - -#ifndef DFVECTOR_H_INCLUDED -#define DFVECTOR_H_INCLUDED - -#include "DFPragma.h" -#include "DFExport.h" -#include "VersionInfo.h" -#include "DFProcess.h" - -#include - -namespace DFHack -{ - template - class DFHACK_EXPORT DfVector - { - private: - Process *_p; - uint32_t _address; - t_vecTriplet t; - t_vecTriplet t_read; - uint32_t _size;// vector size - - T * data; // cached data - - bool isMetadataInSync() - { - t_vecTriplet t2; - _p->readSTLVector(_address,t2); - return (t2.start == t.start || t2.end == t.end || t2.alloc_end == t.alloc_end); - } - public: - DfVector(Process *p, uint32_t address) : _p(p), _address(address) - { - p->readSTLVector(address,t); - t_read = t; - uint32_t byte_size = t.end - t.start; - _size = byte_size / sizeof(T); - data = new T[_size]; - p->read(t.start,byte_size, (uint8_t *)data); - }; - DfVector() - { - data = 0; - }; - ~DfVector() - { - if(data) - delete [] data; - }; - // get offset of the specified index - inline const T& operator[] (uint32_t index) - { - // FIXME: vector out of bounds exception - //assert(index < size); - return data[index]; - }; - // get offset of the specified index - inline const T& at (uint32_t index) - { - //assert(index < size); - return data[index]; - }; - // update value at index - bool set(uint32_t index, T value) - { - if (index >= _size) - return false; - data[index] = value; - _p->write(t.start + sizeof(T)*index, sizeof(T), (uint8_t *)&data[index]); - return true; - } - // remove value - bool remove(uint32_t index) - { - if (index >= _size || !isMetadataInSync()) - return false; - // Remove the item - _size--; - t.end -= sizeof(T); - int tail = (_size-index)*sizeof(T); - memmove(&data[index], &data[index+1], tail); - // Write back the data - if (tail) - _p->write(t.start + sizeof(T)*index, tail, (uint8_t *)&data[index]); - _p->writeSTLVector(_address,t); - return true; - } - // get vector size - inline uint32_t size () - { - return _size; - }; - // get vector start - inline uint32_t start () - { - return t.start; - }; - // get vector end - inline uint32_t end () - { - return t.end; - }; - // get vector start - inline const uint32_t alloc_end () - { - return t.alloc_end; - }; - }; -} -#endif // DFVECTOR_H_INCLUDED diff --git a/library/include/dfhack/DFstdint_win.h b/library/include/dfhack/DFstdint_win.h deleted file mode 100644 index d02608a59..000000000 --- a/library/include/dfhack/DFstdint_win.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/library/include/dfhack/DFError.h b/library/include/dfhack/Error.h similarity index 98% rename from library/include/dfhack/DFError.h rename to library/include/dfhack/Error.h index ff270d262..946cc2d4c 100644 --- a/library/include/dfhack/DFError.h +++ b/library/include/dfhack/Error.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -27,8 +27,8 @@ distribution. #ifndef ERROR_H_INCLUDED #define ERROR_H_INCLUDED -#include "DFExport.h" -#include "DFPragma.h" +#include "dfhack/Export.h" +#include "dfhack/Pragma.h" #include #include #include diff --git a/library/include/dfhack/DFExport.h b/library/include/dfhack/Export.h similarity index 79% rename from library/include/dfhack/DFExport.h rename to library/include/dfhack/Export.h index 797177df7..8ae6fd623 100644 --- a/library/include/dfhack/DFExport.h +++ b/library/include/dfhack/Export.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #pragma once #ifdef LINUX_BUILD @@ -39,3 +40,10 @@ distribution. #endif #endif #endif + +// C export macros for faking SDL and plugin exports +#ifdef LINUX_BUILD + #define DFhackCExport extern "C" __attribute__ ((visibility("default"))) +#else + #define DFhackCExport extern "C" __declspec(dllexport) +#endif \ No newline at end of file diff --git a/library/include/dfhack/FakeSDL.h b/library/include/dfhack/FakeSDL.h new file mode 100644 index 000000000..ad2af26ba --- /dev/null +++ b/library/include/dfhack/FakeSDL.h @@ -0,0 +1,72 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + +#pragma once + +/* + * Some much needed SDL fakery. + */ + +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include +#include + +// function and variable pointer... we don't try to understand what SDL does here +typedef void * fPtr; +typedef void * vPtr; +namespace SDL +{ + union Event; + struct Thread; + struct Mutex; + struct Cond; + struct Library; +} + +// mutex stuff +DFhackCExport SDL::Mutex * SDL_CreateMutex(void); +DFhackCExport int SDL_mutexP(SDL::Mutex *); +DFhackCExport int SDL_mutexV(SDL::Mutex *); +DFhackCExport void SDL_DestroyMutex(SDL::Mutex *); +// thread stuff +DFhackCExport SDL::Thread *SDL_CreateThread(int (*fn)(void *), void *data); +DFhackCExport uint32_t SDL_ThreadID(); +// condition variables +DFhackCExport SDL::Cond *SDL_CreateCond(void); +DFhackCExport void SDL_DestroyCond(SDL::Cond *cond); +DFhackCExport int SDL_CondSignal(SDL::Cond *cond); +DFhackCExport int SDL_CondWait(SDL::Cond *cond, SDL::Mutex * mut); + +// these functions are here because they call into DFHack::Core and therefore need to +// be declared as friend functions/known +DFhackCExport int SDL_NumJoysticks(void); +DFhackCExport void SDL_Quit(void); +DFhackCExport int SDL_PollEvent(SDL::Event* event); +/* +// not yet. +DFhackCExport int SDL_Init(uint32_t flags); +*/ + +// Other crud is in the OS-specific core files. diff --git a/library/include/dfhack/DFMiscUtils.h b/library/include/dfhack/MiscUtils.h similarity index 84% rename from library/include/dfhack/DFMiscUtils.h rename to library/include/dfhack/MiscUtils.h index 74452a621..5edca1b69 100644 --- a/library/include/dfhack/DFMiscUtils.h +++ b/library/include/dfhack/MiscUtils.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef DF_MISCUTILS @@ -5,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -13,9 +37,9 @@ using namespace std; -#include +#include #include -#include +#include void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) { diff --git a/library/include/dfhack/DFModule.h b/library/include/dfhack/Module.h similarity index 90% rename from library/include/dfhack/DFModule.h rename to library/include/dfhack/Module.h index 1e547abad..c583ab17c 100644 --- a/library/include/dfhack/DFModule.h +++ b/library/include/dfhack/Module.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -27,10 +27,9 @@ distribution. #ifndef MODULE_H_INCLUDED #define MODULE_H_INCLUDED -#include "DFExport.h" +#include "dfhack/Export.h" namespace DFHack { - class Context; /** * The parent class for all DFHack modules * \ingroup grp_modules @@ -41,6 +40,7 @@ namespace DFHack 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() { @@ -53,6 +53,7 @@ namespace DFHack { return false; }; + */ }; } #endif //MODULE_H_INCLUDED diff --git a/library/include/dfhack/PluginManager.h b/library/include/dfhack/PluginManager.h new file mode 100644 index 000000000..b176f4108 --- /dev/null +++ b/library/include/dfhack/PluginManager.h @@ -0,0 +1,140 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + +#pragma once + +#include "dfhack/Export.h" +#include +#include +#include +#include "FakeSDL.h" +struct DFLibrary; +namespace DFHack +{ + class Core; + class PluginManager; + enum command_result + { + CR_NOT_IMPLEMENTED = -1, + CR_FAILURE = 0, + CR_OK = 1 + }; + struct PluginCommand + { + PluginCommand(const char * _name, + const char * _description, + command_result (*function_)(Core *, std::vector &) + ) + { + name = _name; + description = _description; + function = function_; + } + PluginCommand (const PluginCommand & rhs) + { + name = rhs.name; + description = rhs.description; + function = rhs.function; + } + std::string name; + std::string description; + command_result (*function)(Core *, std::vector &); + }; + class Plugin + { + struct RefLock; + enum plugin_state + { + PS_UNLOADED, + PS_LOADED, + PS_BROKEN + }; + friend class PluginManager; + Plugin(DFHack::Core* core, const std::string& filepath, const std::string& filename, PluginManager * pm); + ~Plugin(); + command_result on_update(); + public: + bool load(); + bool unload(); + bool reload(); + command_result invoke( std::string & command, std::vector & parameters ); + plugin_state getState () const; + const PluginCommand& operator[] (std::size_t index) const + { + return commands[index]; + }; + std::size_t size() const + { + return commands.size(); + } + const std::string & getName() const + { + return name; + } + private: + RefLock * access; + std::vector commands; + std::string filename; + std::string name; + DFLibrary * plugin_lib; + PluginManager * parent; + plugin_state state; + command_result (*plugin_init)(Core *, std::vector &); + command_result (*plugin_status)(Core *, std::string &); + command_result (*plugin_shutdown)(Core *); + command_result (*plugin_onupdate)(Core *); + }; + class DFHACK_EXPORT PluginManager + { + // PRIVATE METHODS + friend class Core; + friend class Plugin; + PluginManager(Core * core); + ~PluginManager(); + void OnUpdate( void ); + void registerCommands( Plugin * p ); + void unregisterCommands( Plugin * p ); + // PUBLIC METHODS + public: + Plugin *getPluginByName (const std::string & name); + command_result InvokeCommand( std::string & command, std::vector & parameters ); + Plugin* operator[] (std::size_t index) + { + if(index >= all_plugins.size()) + return 0; + return all_plugins[index]; + }; + std::size_t size() + { + return all_plugins.size(); + } + // DATA + private: + SDL::Mutex * cmdlist_mutex; + std::map belongs; + std::vector all_plugins; + std::string plugin_path; + }; +} + diff --git a/library/include/dfhack/Pragma.h b/library/include/dfhack/Pragma.h new file mode 100644 index 000000000..5999faca8 --- /dev/null +++ b/library/include/dfhack/Pragma.h @@ -0,0 +1,54 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + +#pragma once + +#ifndef DFHACK_TRANQUILITY +#define DFHACK_TRANQUILITY + +// This is here to keep MSVC from spamming the build output with nonsense +// Call it public domain. + +#ifdef _MSC_VER + // don't spew nonsense + #pragma warning( disable: 4251 ) + // don't display bogus 'deprecation' and 'unsafe' warnings. + // See the idiocy: http://msdn.microsoft.com/en-us/magazine/cc163794.aspx + #define _CRT_SECURE_NO_DEPRECATE + #define _SCL_SECURE_NO_DEPRECATE + #pragma warning( disable: 4996 ) + // Let me demonstrate: + /** + * [peterix@peterix dfhack]$ man wcscpy_s + * No manual entry for wcscpy_s + * + * Proprietary extensions. + */ + // disable stupid + #pragma warning( disable: 4800 ) + // disable more stupid + #pragma warning( disable: 4068 ) +#endif + +#endif diff --git a/library/include/dfhack/Process.h b/library/include/dfhack/Process.h new file mode 100644 index 000000000..75b0edc86 --- /dev/null +++ b/library/include/dfhack/Process.h @@ -0,0 +1,299 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + + +#pragma once + +#ifndef PROCESS_H_INCLUDED +#define PROCESS_H_INCLUDED + +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include +#include +#include + +namespace DFHack +{ + class VersionInfo; + class Process; + class Window; + class DFVector; + class VersionInfoFactory; + class PlatformSpecific; + + /** + * A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification) + * \ingroup grp_context + */ + 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 section of virtual memory inside a process + * \ingroup grp_context + */ + struct DFHACK_EXPORT t_memrange + { + uint64_t start; + uint64_t end; + // memory range name (if any) + char name[1024]; + // permission to read + bool read : 1; + // permission to write + bool write : 1; + // permission to execute + bool execute : 1; + // is a shared region + bool shared : 1; + inline bool isInRange( uint64_t address) + { + if (address >= start && address < end) return true; + return false; + } + bool valid; + uint8_t * buffer; + }; + + /** + * Allows low-level access to the memory of an OS process. + * \ingroup grp_context + */ + class DFHACK_EXPORT Process + { + public: + /// this is the single most important destructor ever. ~px + Process(VersionInfoFactory * known_versions); + ~Process(); + /// read a 8-byte integer + uint64_t readQuad(const uint32_t address) + { + return *(uint64_t *)address; + } + /// read a 8-byte integer + void readQuad(const uint32_t address, uint64_t & value) + { + value = *(uint64_t *)address; + }; + /// write a 8-byte integer + void writeQuad(const uint32_t address, const uint64_t value) + { + (*(uint64_t *)address) = value; + }; + + /// read a 4-byte integer + uint32_t readDWord(const uint32_t address) + { + return *(uint32_t *)address; + } + /// read a 4-byte integer + void readDWord(const uint32_t address, uint32_t & value) + { + value = *(uint32_t *)address; + }; + /// write a 4-byte integer + void writeDWord(const uint32_t address, const uint32_t value) + { + (*(uint32_t *)address) = value; + }; + + /// read a float + float readFloat(const uint32_t address) + { + return *(float*)address; + } + /// write a float + void readFloat(const uint32_t address, float & value) + { + value = *(float*)address; + }; + + /// read a 2-byte integer + uint16_t readWord(const uint32_t address) + { + return *(uint16_t *)address; + } + /// read a 2-byte integer + void readWord(const uint32_t address, uint16_t & value) + { + value = *(uint16_t *)address; + }; + /// write a 2-byte integer + void writeWord(const uint32_t address, const uint16_t value) + { + (*(uint16_t *)address) = value; + }; + + /// read a byte + uint8_t readByte(const uint32_t address) + { + return *(uint8_t *)address; + } + /// read a byte + void readByte(const uint32_t address, uint8_t & value) + { + value = *(uint8_t *)address; + }; + /// write a byte + void writeByte(const uint32_t address, const uint8_t value) + { + (*(uint8_t *)address) = value; + }; + + /// read an arbitrary amount of bytes + void read( uint32_t address, uint32_t length, uint8_t* buffer) + { + memcpy(buffer, (void *) address, length); + }; + /// write an arbitrary amount of bytes + void write(uint32_t address, uint32_t length, uint8_t* buffer) + { + memcpy((void *) address, buffer, length); + }; + + /// read an STL string + const std::string readSTLString (uint32_t offset) + { + std::string * str = (std::string *) offset; + return *str; + }; + /// read an STL string + size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) + { + if(!bufcapacity || bufcapacity == 1) + return 0; + std::string * str = (std::string *) offset; + size_t copied = str->copy(buffer,bufcapacity-1); + buffer[copied] = 0; + return copied; + }; + /** + * write an STL string + * @return length written + */ + size_t writeSTLString(const uint32_t address, const std::string writeString) + { + std::string * str = (std::string *) address; + str->assign(writeString); + return writeString.size(); + }; + /** + * attempt to copy a string from source address to target address. may truncate or leak, depending on platform + * @return length copied + */ + size_t copySTLString(const uint32_t address, const uint32_t target) + { + std::string * strsrc = (std::string *) address; + std::string * str = (std::string *) target; + str->assign(*strsrc); + return str->size(); + } + + /// get class name of an object with rtti/type info + std::string doReadClassName(void * vptr); + + std::string readClassName(void * vptr) + { + std::map::iterator it = classNameCache.find(vptr); + if (it != classNameCache.end()) + return it->second; + return classNameCache[vptr] = doReadClassName(vptr); + } + + /// read a null-terminated C string + const std::string readCString (uint32_t offset) + { + return std::string((char *) offset); + }; + + /// @return true if the process is suspended + bool isSuspended() + { + return true; + }; + /// @return true if the process is identified -- has a Memory.xml entry + bool isIdentified() + { + return identified; + }; + /// find the thread IDs of the process + bool getThreadIDs(std::vector & threads ); + /// get virtual memory ranges of the process (what is mapped where) + void getMemRanges(std::vector & ranges ); + + /// get the flattened Memory.xml entry of this process + VersionInfo *getDescriptor() + { + return my_descriptor; + }; + uint32_t getBase(); + /// get the DF Process ID + int getPID(); + /// get the DF Process FilePath + std::string getPath(); + private: + VersionInfo * my_descriptor; + PlatformSpecific *d; + bool identified; + uint32_t my_pid; + uint32_t base; + std::map classNameCache; + }; + + class DFHACK_EXPORT ClassNameCheck + { + std::string name; + mutable void * vptr; + public: + ClassNameCheck() : vptr(0) {}; + ClassNameCheck(std::string _name) : name(_name), vptr(0) {}; + ClassNameCheck &operator= (const ClassNameCheck &b) + { + name = b.name; vptr = b.vptr; return *this; + } + bool operator() (Process *p, void * ptr) const { + if (vptr == 0 && p->readClassName(ptr) == name) + vptr = ptr; + return (vptr && vptr == ptr); + }; + }; +} +#endif diff --git a/library/include/dfhack/SDL_fakes/events.h b/library/include/dfhack/SDL_fakes/events.h new file mode 100644 index 000000000..b8b8b1eb6 --- /dev/null +++ b/library/include/dfhack/SDL_fakes/events.h @@ -0,0 +1,210 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +// Fake - only structs. Shamelessly pilfered from the SDL library. +// Needed for processing its event types without polluting our namespaces with C garbage + +#pragma once +#include "keyboard.h" + +namespace SDL +{ + enum ButtonState + { + BTN_RELEASED = 0, + BTN_PRESSED = 1 + }; + + /** Event enumerations */ + enum EventType + { + ET_NOEVENT = 0, /**< Unused (do not remove) */ + ET_ACTIVEEVENT, /**< Application loses/gains visibility */ + ET_KEYDOWN, /**< Keys pressed */ + ET_KEYUP, /**< Keys released */ + ET_MOUSEMOTION, /**< Mouse moved */ + ET_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + ET_MOUSEBUTTONUP, /**< Mouse button released */ + ET_JOYAXISMOTION, /**< Joystick axis motion */ + ET_JOYBALLMOTION, /**< Joystick trackball motion */ + ET_JOYHATMOTION, /**< Joystick hat position change */ + ET_JOYBUTTONDOWN, /**< Joystick button pressed */ + ET_JOYBUTTONUP, /**< Joystick button released */ + ET_QUIT, /**< User-requested quit */ + ET_SYSWMEVENT, /**< System specific event */ + ET_EVENT_RESERVEDA, /**< Reserved for future use.. */ + ET_EVENT_RESERVEDB, /**< Reserved for future use.. */ + ET_VIDEORESIZE, /**< User resized video mode */ + ET_VIDEOEXPOSE, /**< Screen needs to be redrawn */ + ET_EVENT_RESERVED2, /**< Reserved for future use.. */ + ET_EVENT_RESERVED3, /**< Reserved for future use.. */ + ET_EVENT_RESERVED4, /**< Reserved for future use.. */ + ET_EVENT_RESERVED5, /**< Reserved for future use.. */ + ET_EVENT_RESERVED6, /**< Reserved for future use.. */ + ET_EVENT_RESERVED7, /**< Reserved for future use.. */ + /** Events ET_USEREVENT through ET_MAXEVENTS-1 are for your use */ + ET_USEREVENT = 24, + /** This last event is only for bounding internal arrays + * It is the number of bits in the event mask datatype -- Uint32 + */ + ET_NUMEVENTS = 32 + }; + + /** Application visibility event structure */ + struct ActiveEvent + { + uint8_t type; /**< ET_ACTIVEEVENT */ + uint8_t gain; /**< Whether given states were gained or lost (1/0) */ + uint8_t state; /**< A mask of the focus states */ + }; + + /** Keyboard event structure */ + struct KeyboardEvent + { + uint8_t type; /**< ET_KEYDOWN or ET_KEYUP */ + uint8_t which; /**< The keyboard device index */ + uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */ + keysym ksym; + }; + + /** Mouse motion event structure */ + struct MouseMotionEvent + { + uint8_t type; /**< ET_MOUSEMOTION */ + uint8_t which; /**< The mouse device index */ + uint8_t state; /**< The current button state */ + uint16_t x, y; /**< The X/Y coordinates of the mouse */ + int16_t xrel; /**< The relative motion in the X direction */ + int16_t yrel; /**< The relative motion in the Y direction */ + }; + + /** Mouse button event structure */ + struct MouseButtonEvent + { + uint8_t type; /**< ET_MOUSEBUTTONDOWN or ET_MOUSEBUTTONUP */ + uint8_t which; /**< The mouse device index */ + uint8_t button; /**< The mouse button index */ + uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */ + uint16_t x, y; /**< The X/Y coordinates of the mouse at press time */ + }; + + /** Joystick axis motion event structure */ + struct JoyAxisEvent + { + uint8_t type; /**< ET_JOYAXISMOTION */ + uint8_t which; /**< The joystick device index */ + uint8_t axis; /**< The joystick axis index */ + int16_t value; /**< The axis value (range: -32768 to 32767) */ + }; + + /** Joystick trackball motion event structure */ + struct JoyBallEvent + { + uint8_t type; /**< ET_JOYBALLMOTION */ + uint8_t which; /**< The joystick device index */ + uint8_t ball; /**< The joystick trackball index */ + int16_t xrel; /**< The relative motion in the X direction */ + int16_t yrel; /**< The relative motion in the Y direction */ + }; + + /** Joystick hat position change event structure */ + struct JoyHatEvent + { + uint8_t type; /**< ET_JOYHATMOTION */ + uint8_t which; /**< The joystick device index */ + uint8_t hat; /**< The joystick hat index */ + uint8_t value; /**< The hat position value: + * SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP + * SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT + * SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN + * Note that zero means the POV is centered. + */ + }; + + /** Joystick button event structure */ + struct JoyButtonEvent + { + uint8_t type; /**< ET_JOYBUTTONDOWN or ET_JOYBUTTONUP */ + uint8_t which; /**< The joystick device index */ + uint8_t button; /**< The joystick button index */ + uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */ + }; + + /** The "window resized" event + * When you get this event, you are responsible for setting a new video + * mode with the new width and height. + */ + struct ResizeEvent + { + uint8_t type; /**< ET_VIDEORESIZE */ + int w; /**< New width */ + int h; /**< New height */ + }; + + /** The "screen redraw" event */ + struct ExposeEvent + { + uint8_t type; /**< ET_VIDEOEXPOSE */ + }; + + /** The "quit requested" event */ + struct QuitEvent + { + uint8_t type; /**< ET_QUIT */ + }; + + /** A user-defined event type */ + struct UserEvent + { + uint8_t type; /**< ETL_USEREVENT through ET_NUMEVENTS-1 */ + int code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ + }; + + /** If you want to use this event, you should include SDL_syswm.h */ + struct SysWMmsg; + struct SysWMEvent + { + uint8_t type; + SysWMmsg *msg; + }; + + /** General event structure */ + union Event + { + uint8_t type; + ActiveEvent active; + KeyboardEvent key; + MouseMotionEvent motion; + MouseButtonEvent button; + JoyAxisEvent jaxis; + JoyBallEvent jball; + JoyHatEvent jhat; + JoyButtonEvent jbutton; + ResizeEvent resize; + ExposeEvent expose; + QuitEvent quit; + UserEvent user; + SysWMEvent syswm; + }; +} \ No newline at end of file diff --git a/library/include/dfhack/SDL_fakes/keyboard.h b/library/include/dfhack/SDL_fakes/keyboard.h new file mode 100644 index 000000000..a49cf2517 --- /dev/null +++ b/library/include/dfhack/SDL_fakes/keyboard.h @@ -0,0 +1,61 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +// Fake - only structs. Shamelessly pilfered from the SDL library. +// Needed for processing its event types without polluting our namespaces with C garbage + +#pragma once +#include "keysym.h" +#include + +namespace SDL +{ + /** Keysym structure + * + * - The scancode is hardware dependent, and should not be used by general + * applications. If no hardware scancode is available, it will be 0. + * + * - The 'unicode' translated character is only available when character + * translation is enabled by the SDL_EnableUNICODE() API. If non-zero, + * this is a UNICODE character corresponding to the keypress. If the + * high 9 bits of the character are 0, then this maps to the equivalent + * ASCII character: + * @code + * char ch; + * if ( (keysym.unicode & 0xFF80) == 0 ) { + * ch = keysym.unicode & 0x7F; + * } else { + * An international character.. + * } + * @endcode + */ + typedef struct keysym + { + uint8_t scancode; /**< hardware specific scancode */ + Key sym; /**< SDL virtual keysym */ + Mod mod; /**< current key modifiers */ + uint16_t unicode; /**< translated character */ + } keysym; + + /** This is the mask which refers to all hotkey bindings */ + #define ALL_HOTKEYS 0xFFFFFFFF +} \ No newline at end of file diff --git a/library/include/dfhack/SDL_fakes/keysym.h b/library/include/dfhack/SDL_fakes/keysym.h new file mode 100644 index 000000000..4f01cfa9c --- /dev/null +++ b/library/include/dfhack/SDL_fakes/keysym.h @@ -0,0 +1,329 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +// Fake - only structs. Shamelessly pilfered from the SDL library. +// Needed for processing its event types without polluting our namespaces with C garbage + +#pragma once + +namespace SDL +{ + /** What we really want is a mapping of every raw key on the keyboard. + * To support international keyboards, we use the range 0xA1 - 0xFF + * as international virtual keycodes. We'll follow in the footsteps of X11... + * @brief The names of the keys + */ + enum Key + { + /** @name ASCII mapped keysyms + * The keyboard syms have been cleverly chosen to map to ASCII + */ + /*@{*/ + K_UNKNOWN = 0, + K_FIRST = 0, + K_BACKSPACE = 8, + K_TAB = 9, + K_CLEAR = 12, + K_RETURN = 13, + K_PAUSE = 19, + K_ESCAPE = 27, + K_SPACE = 32, + K_EXCLAIM = 33, + K_QUOTEDBL = 34, + K_HASH = 35, + K_DOLLAR = 36, + K_AMPERSAND = 38, + K_QUOTE = 39, + K_LEFTPAREN = 40, + K_RIGHTPAREN = 41, + K_ASTERISK = 42, + K_PLUS = 43, + K_COMMA = 44, + K_MINUS = 45, + K_PERIOD = 46, + K_SLASH = 47, + K_0 = 48, + K_1 = 49, + K_2 = 50, + K_3 = 51, + K_4 = 52, + K_5 = 53, + K_6 = 54, + K_7 = 55, + K_8 = 56, + K_9 = 57, + K_COLON = 58, + K_SEMICOLON = 59, + K_LESS = 60, + K_EQUALS = 61, + K_GREATER = 62, + K_QUESTION = 63, + K_AT = 64, + /* + Skip uppercase letters + */ + K_LEFTBRACKET = 91, + K_BACKSLASH = 92, + K_RIGHTBRACKET = 93, + K_CARET = 94, + K_UNDERSCORE = 95, + K_BACKQUOTE = 96, + K_a = 97, + K_b = 98, + K_c = 99, + K_d = 100, + K_e = 101, + K_f = 102, + K_g = 103, + K_h = 104, + K_i = 105, + K_j = 106, + K_k = 107, + K_l = 108, + K_m = 109, + K_n = 110, + K_o = 111, + K_p = 112, + K_q = 113, + K_r = 114, + K_s = 115, + K_t = 116, + K_u = 117, + K_v = 118, + K_w = 119, + K_x = 120, + K_y = 121, + K_z = 122, + K_DELETE = 127, + /* End of ASCII mapped keysyms */ + /*@}*/ + + /** @name International keyboard syms */ + /*@{*/ + K_WORLD_0 = 160, /* 0xA0 */ + K_WORLD_1 = 161, + K_WORLD_2 = 162, + K_WORLD_3 = 163, + K_WORLD_4 = 164, + K_WORLD_5 = 165, + K_WORLD_6 = 166, + K_WORLD_7 = 167, + K_WORLD_8 = 168, + K_WORLD_9 = 169, + K_WORLD_10 = 170, + K_WORLD_11 = 171, + K_WORLD_12 = 172, + K_WORLD_13 = 173, + K_WORLD_14 = 174, + K_WORLD_15 = 175, + K_WORLD_16 = 176, + K_WORLD_17 = 177, + K_WORLD_18 = 178, + K_WORLD_19 = 179, + K_WORLD_20 = 180, + K_WORLD_21 = 181, + K_WORLD_22 = 182, + K_WORLD_23 = 183, + K_WORLD_24 = 184, + K_WORLD_25 = 185, + K_WORLD_26 = 186, + K_WORLD_27 = 187, + K_WORLD_28 = 188, + K_WORLD_29 = 189, + K_WORLD_30 = 190, + K_WORLD_31 = 191, + K_WORLD_32 = 192, + K_WORLD_33 = 193, + K_WORLD_34 = 194, + K_WORLD_35 = 195, + K_WORLD_36 = 196, + K_WORLD_37 = 197, + K_WORLD_38 = 198, + K_WORLD_39 = 199, + K_WORLD_40 = 200, + K_WORLD_41 = 201, + K_WORLD_42 = 202, + K_WORLD_43 = 203, + K_WORLD_44 = 204, + K_WORLD_45 = 205, + K_WORLD_46 = 206, + K_WORLD_47 = 207, + K_WORLD_48 = 208, + K_WORLD_49 = 209, + K_WORLD_50 = 210, + K_WORLD_51 = 211, + K_WORLD_52 = 212, + K_WORLD_53 = 213, + K_WORLD_54 = 214, + K_WORLD_55 = 215, + K_WORLD_56 = 216, + K_WORLD_57 = 217, + K_WORLD_58 = 218, + K_WORLD_59 = 219, + K_WORLD_60 = 220, + K_WORLD_61 = 221, + K_WORLD_62 = 222, + K_WORLD_63 = 223, + K_WORLD_64 = 224, + K_WORLD_65 = 225, + K_WORLD_66 = 226, + K_WORLD_67 = 227, + K_WORLD_68 = 228, + K_WORLD_69 = 229, + K_WORLD_70 = 230, + K_WORLD_71 = 231, + K_WORLD_72 = 232, + K_WORLD_73 = 233, + K_WORLD_74 = 234, + K_WORLD_75 = 235, + K_WORLD_76 = 236, + K_WORLD_77 = 237, + K_WORLD_78 = 238, + K_WORLD_79 = 239, + K_WORLD_80 = 240, + K_WORLD_81 = 241, + K_WORLD_82 = 242, + K_WORLD_83 = 243, + K_WORLD_84 = 244, + K_WORLD_85 = 245, + K_WORLD_86 = 246, + K_WORLD_87 = 247, + K_WORLD_88 = 248, + K_WORLD_89 = 249, + K_WORLD_90 = 250, + K_WORLD_91 = 251, + K_WORLD_92 = 252, + K_WORLD_93 = 253, + K_WORLD_94 = 254, + K_WORLD_95 = 255, /* 0xFF */ + /*@}*/ + + /** @name Numeric keypad */ + /*@{*/ + K_KP0 = 256, + K_KP1 = 257, + K_KP2 = 258, + K_KP3 = 259, + K_KP4 = 260, + K_KP5 = 261, + K_KP6 = 262, + K_KP7 = 263, + K_KP8 = 264, + K_KP9 = 265, + K_KP_PERIOD = 266, + K_KP_DIVIDE = 267, + K_KP_MULTIPLY = 268, + K_KP_MINUS = 269, + K_KP_PLUS = 270, + K_KP_ENTER = 271, + K_KP_EQUALS = 272, + /*@}*/ + + /** @name Arrows + Home/End pad */ + /*@{*/ + K_UP = 273, + K_DOWN = 274, + K_RIGHT = 275, + K_LEFT = 276, + K_INSERT = 277, + K_HOME = 278, + K_END = 279, + K_PAGEUP = 280, + K_PAGEDOWN = 281, + /*@}*/ + + /** @name Function keys */ + /*@{*/ + K_F1 = 282, + K_F2 = 283, + K_F3 = 284, + K_F4 = 285, + K_F5 = 286, + K_F6 = 287, + K_F7 = 288, + K_F8 = 289, + K_F9 = 290, + K_F10 = 291, + K_F11 = 292, + K_F12 = 293, + K_F13 = 294, + K_F14 = 295, + K_F15 = 296, + /*@}*/ + + /** @name Key state modifier keys */ + /*@{*/ + K_NUMLOCK = 300, + K_CAPSLOCK = 301, + K_SCROLLOCK = 302, + K_RSHIFT = 303, + K_LSHIFT = 304, + K_RCTRL = 305, + K_LCTRL = 306, + K_RALT = 307, + K_LALT = 308, + K_RMETA = 309, + K_LMETA = 310, + K_LSUPER = 311, /**< Left "Windows" key */ + K_RSUPER = 312, /**< Right "Windows" key */ + K_MODE = 313, /**< "Alt Gr" key */ + K_COMPOSE = 314, /**< Multi-key compose key */ + /*@}*/ + + /** @name Miscellaneous function keys */ + /*@{*/ + K_HELP = 315, + K_PRINT = 316, + K_SYSREQ = 317, + K_BREAK = 318, + K_MENU = 319, + K_POWER = 320, /**< Power Macintosh power key */ + K_EURO = 321, /**< Some european keyboards */ + K_UNDO = 322, /**< Atari keyboard has Undo */ + /*@}*/ + + /* Add any other keys here */ + + K_LAST + }; + + /** Enumeration of valid key mods (possibly OR'd together) */ + enum Mod { + KMOD_NONE = 0x0000, + KMOD_LSHIFT= 0x0001, + KMOD_RSHIFT= 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LMETA = 0x0400, + KMOD_RMETA = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000, + KMOD_CTRL = (KMOD_LCTRL|KMOD_RCTRL), + KMOD_SHIFT = (KMOD_LSHIFT|KMOD_RSHIFT), + KMOD_ALT = (KMOD_LALT|KMOD_RALT), + KMOD_META = (KMOD_LMETA|KMOD_RMETA) + }; +} \ No newline at end of file diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/TileTypes.h similarity index 98% rename from library/include/dfhack/DFTileTypes.h rename to library/include/dfhack/TileTypes.h index db21f3ab1..f6ea56c7e 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/TileTypes.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -27,8 +27,8 @@ distribution. #ifndef TILETYPES_H_INCLUDED #define TILETYPES_H_INCLUDED -#include "DFPragma.h" -#include "DFExport.h" +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" namespace DFHack { diff --git a/library/include/dfhack/DFTypes.h b/library/include/dfhack/Types.h similarity index 81% rename from library/include/dfhack/DFTypes.h rename to library/include/dfhack/Types.h index e40c02791..5dc92f749 100644 --- a/library/include/dfhack/DFTypes.h +++ b/library/include/dfhack/Types.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,13 +22,14 @@ must not be misrepresented as being the original software. distribution. */ + #pragma once #ifndef TYPES_H_INCLUDED #define TYPES_H_INCLUDED -#include "DFPragma.h" -#include "DFExport.h" +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" #ifdef __cplusplus namespace DFHack @@ -49,6 +50,17 @@ struct junk_fill uint8_t data[SIZE]; }; +struct df_name +{ + std::string first_name; + std::string nick_name; + int32_t words[7]; + int16_t parts_of_speech[7]; + int32_t language; + int16_t unknown; + int16_t has_name; +}; + enum EFFECT_TYPE { EFF_MIASMA=0, @@ -96,6 +108,7 @@ struct t_effect_df40d //size 40 */ //#pragma pack(push,4) + struct t_name { char first_name[128]; @@ -106,31 +119,6 @@ struct t_name bool has_name; }; -struct t_note -{ - char symbol; - uint16_t foreground; - uint16_t background; - char name[128]; - uint16_t x; - uint16_t y; - uint16_t z; -}; - - -// local are numbered with top left as 0,0, name is indexes into the item vector -struct t_settlement -{ - uint32_t origin; - t_name name; - int16_t world_x; - int16_t world_y; - int16_t local_x1; - int16_t local_x2; - int16_t local_y1; - int16_t local_y2; -}; - struct t_attrib { uint32_t level; diff --git a/library/include/dfhack/Vector.h b/library/include/dfhack/Vector.h new file mode 100644 index 000000000..ec5840a0f --- /dev/null +++ b/library/include/dfhack/Vector.h @@ -0,0 +1,96 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + + +#pragma once + +#ifndef DFVECTOR_H_INCLUDED +#define DFVECTOR_H_INCLUDED + +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include "dfhack/VersionInfo.h" +#include "dfhack/Process.h" + +#include +#include + +namespace DFHack +{ + template + class DFHACK_EXPORT DfVector + { + private: + std::vector * real_vec; + public: + DfVector(uint32_t address) + { + real_vec = (std::vector *) address; + }; + ~DfVector() + { + }; + // get offset of the specified index + inline const T& operator[] (uint32_t index) + { + // FIXME: vector out of bounds exception + //assert(index < size); + return real_vec->at(index); + }; + // get offset of the specified index + inline const T& at (uint32_t index) + { + //assert(index < size); + return real_vec->at(index); + }; + // update value at index + bool set(uint32_t index, T value) + { + if (index >= real_vec->size()) + return false; + real_vec->at(index) = value; + return true; + } + // remove value + bool remove(uint32_t index) + { + if (index >= real_vec->size()) + return false; + // Remove the item + real_vec->erase(real_vec->begin() + index); + return true; + } + // get vector size + inline uint32_t size () + { + return real_vec->size(); + }; + // get vector start + inline const T * start () + { + return real_vec->data(); + }; + }; +} +#endif // DFVECTOR_H_INCLUDED diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index 0bff54ed3..d53f47c22 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,14 +22,15 @@ must not be misrepresented as being the original software. distribution. */ + #pragma once #ifndef MEMINFO_H_INCLUDED #define MEMINFO_H_INCLUDED -#include "DFPragma.h" -#include "DFExport.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" +#include "dfhack/Types.h" #include namespace DFHack @@ -182,7 +183,7 @@ namespace DFHack * 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 ); + bool resolveClassnameToVPtr ( const std::string classname, void * & vptr ); /** * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) diff --git a/library/include/dfhack/VersionInfoFactory.h b/library/include/dfhack/VersionInfoFactory.h index e424fc7bc..ab3131305 100644 --- a/library/include/dfhack/VersionInfoFactory.h +++ b/library/include/dfhack/VersionInfoFactory.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,13 +22,14 @@ must not be misrepresented as being the original software. distribution. */ + #pragma once #ifndef MEMINFO_MANAGER_H_INCLUDED #define MEMINFO_MANAGER_H_INCLUDED -#include "dfhack/DFPragma.h" -#include "dfhack/DFExport.h" +#include "dfhack/Pragma.h" +#include "dfhack/Export.h" class TiXmlElement; namespace DFHack diff --git a/library/include/DFHack_C.h b/library/include/dfhack/Virtual.h similarity index 65% rename from library/include/DFHack_C.h rename to library/include/dfhack/Virtual.h index 2fa044d72..fc6661f97 100644 --- a/library/include/DFHack_C.h +++ b/library/include/dfhack/Virtual.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -23,26 +23,14 @@ distribution. */ #pragma once -#ifndef DFHACK_C_API -#define DFHACK_C_API - -#include "dfhack/DFPragma.h" - -#include "dfhack/DFExport.h" -#include "dfhack/DFIntegers.h" - -typedef void DFHackObject; - -#ifdef __cplusplus - -namespace DFHack {}; -using namespace DFHack; - -extern "C" { -#endif -// some global stuff here -#ifdef __cplusplus -} -#endif - -#endif +#include +namespace DFHack +{ + /// very generic representation of a virtual class... just the pointer to the vtable. + /// this is intended for instances where wrapping the classes properly hasn't been done yet. + struct t_virtual + { + void * vptr; + std::string getClassName(); + }; +} \ No newline at end of file diff --git a/library/include/dfhack/extra/MapExtras.h b/library/include/dfhack/extra/MapExtras.h index b701d37c9..d0ea3597c 100644 --- a/library/include/dfhack/extra/MapExtras.h +++ b/library/include/dfhack/extra/MapExtras.h @@ -1,18 +1,42 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef MAPEXTRAS_H #define MAPEXTRAS_H -#include "../modules/Maps.h" -#include "../DFTileTypes.h" -#include "../DFIntegers.h" +#include "dfhack/modules/Maps.h" +#include "dfhack/TileTypes.h" +#include #include namespace MapExtras { void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) { memset(materials,-1,sizeof(materials)); - vector veins; - m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins); + std::vector veins; + m->SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins); //iterate through block rows for(uint32_t j = 0;j<16;j++) { @@ -24,9 +48,9 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & { for(int i = (int) veins.size() - 1; i >= 0;i--) { - if(!!(((1 << k) & veins[i].assignment[j]) >> k)) + if(!!(((1 << k) & veins[i]->assignment[j]) >> k)) { - materials[k][j] = veins[i].type; + materials[k][j] = veins[i]->type; i = -1; } } @@ -35,7 +59,7 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & } } -void SquashRocks ( vector< vector > * layerassign, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) +void SquashRocks ( std::vector< std::vector > * layerassign, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) { // get the layer materials for(uint32_t xx = 0;xx<16;xx++) @@ -57,7 +81,7 @@ void SquashRocks ( vector< vector > * layerassign, DFHack::mapblock40 class Block { public: - Block(DFHack::Maps *_m, DFHack::DFCoord _bcoord, vector< vector > * layerassign = 0) + Block(DFHack::Maps *_m, DFHack::DFCoord _bcoord, std::vector< std::vector > * layerassign = 0) { m = _m; dirty_designations = false; @@ -236,7 +260,7 @@ class MapCache { if(!valid) return 0; - map ::iterator iter = blocks.find(blockcoord); + std::map ::iterator iter = blocks.find(blockcoord); if(iter != blocks.end()) { return (*iter).second; @@ -399,7 +423,7 @@ class MapCache } bool WriteAll() { - map::iterator p; + std::map::iterator p; for(p = blocks.begin(); p != blocks.end(); p++) { p->second->Write(); @@ -408,7 +432,7 @@ class MapCache } void trash() { - map::iterator p; + std::map::iterator p; for(p = blocks.begin(); p != blocks.end(); p++) { delete p->second; @@ -423,9 +447,9 @@ class MapCache uint32_t x_tmax; uint32_t y_tmax; uint32_t z_max; - vector< vector > layerassign; + std::vector< std::vector > layerassign; DFHack::Maps * Maps; - map blocks; + std::map blocks; }; } #endif \ No newline at end of file diff --git a/library/include/dfhack/extra/termutil.h b/library/include/dfhack/extra/termutil.h index 7a54be6ab..702e6ba5b 100644 --- a/library/include/dfhack/extra/termutil.h +++ b/library/include/dfhack/extra/termutil.h @@ -1,3 +1,28 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ +#pragma once + #ifndef TERMUTIL_H #define TERMUTIL_H diff --git a/library/include/dfhack/modules/Buildings.h b/library/include/dfhack/modules/Buildings.h index f30e8b495..112a4d927 100644 --- a/library/include/dfhack/modules/Buildings.h +++ b/library/include/dfhack/modules/Buildings.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_BUILDINGS #define CL_MOD_BUILDINGS @@ -5,8 +29,8 @@ * \defgroup grp_buildings Building module parts - also includes zones and stockpiles * @ingroup grp_modules */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" #ifdef __cplusplus namespace DFHack @@ -31,7 +55,6 @@ namespace DFHack }; #ifdef __cplusplus - class DFContextShared; /** * The Buildings module - allows reading DF buildings * \ingroup grp_modules @@ -40,7 +63,7 @@ namespace DFHack class DFHACK_EXPORT Buildings : public Module { public: - Buildings(DFContextShared * d); + Buildings(); ~Buildings(); bool Start(uint32_t & numBuildings); // read one building at offset diff --git a/library/include/dfhack/modules/Constructions.h b/library/include/dfhack/modules/Constructions.h index 0b5c61691..046d8a074 100644 --- a/library/include/dfhack/modules/Constructions.h +++ b/library/include/dfhack/modules/Constructions.h @@ -1,11 +1,35 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_CONSTRUCTIONS #define CL_MOD_CONSTRUCTIONS /* * DF constructions */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" /** * \defgroup grp_constructions Construction module parts @@ -62,7 +86,7 @@ namespace DFHack class DFHACK_EXPORT Constructions : public Module { public: - Constructions(DFContextShared * d); + Constructions(); ~Constructions(); bool Start(uint32_t & numConstructions); bool Read (const uint32_t index, t_construction & constr); diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h index cc085f9a5..967218b56 100644 --- a/library/include/dfhack/modules/Creatures.h +++ b/library/include/dfhack/modules/Creatures.h @@ -1,11 +1,35 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_CREATURES #define CL_MOD_CREATURES /* * Creatures */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" #include "dfhack/modules/Items.h" /** * \defgroup grp_creatures Creatures module parts @@ -340,7 +364,7 @@ namespace DFHack class DFHACK_EXPORT Creatures : public Module { public: - Creatures(DFHack::DFContextShared * d); + Creatures(); ~Creatures(); bool Start( uint32_t & numCreatures ); bool Finish(); diff --git a/library/include/dfhack/modules/Engravings.h b/library/include/dfhack/modules/Engravings.h index 82aee38c7..0dfbb3f43 100644 --- a/library/include/dfhack/modules/Engravings.h +++ b/library/include/dfhack/modules/Engravings.h @@ -1,11 +1,35 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_ENGRAVINGS #define CL_MOD_ENGRAVINGS /* * DF engravings */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" /** * \defgroup grp_engraving Engraving module parts @@ -75,7 +99,6 @@ namespace DFHack t_engraving s; uint32_t origin; }; - class DFContextShared; /** * The Engravings module - allows reading engravings :D * \ingroup grp_modules @@ -84,7 +107,7 @@ namespace DFHack class DFHACK_EXPORT Engravings : public Module { public: - Engravings(DFContextShared * d); + Engravings(); ~Engravings(); bool Start(uint32_t & numEngravings); bool Read (const uint32_t index, dfh_engraving & engr); diff --git a/library/include/dfhack/modules/Gui.h b/library/include/dfhack/modules/Gui.h index 2865f5413..49bb050be 100644 --- a/library/include/dfhack/modules/Gui.h +++ b/library/include/dfhack/modules/Gui.h @@ -1,9 +1,35 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_GUI #define CL_MOD_GUI -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/Virtual.h" +#include /** * \defgroup grp_gui query DF's GUI state @@ -16,24 +42,41 @@ namespace DFHack /** * \ingroup grp_gui */ - struct t_viewscreen + struct t_viewscreen : public t_virtual + { + t_viewscreen * child; + t_viewscreen * parent; + char unk1; // varies + char unk2; // state? + }; + /** + * \ingroup grp_gui + */ + struct t_interface { - int32_t type; - //There is more info in these objects, but I don't know what it is yet + int fps; + t_viewscreen view; + unsigned int flags; // ? + // more crud this way ... }; + #define NUM_HOTKEYS 16 /** + * The hotkey structure * \ingroup grp_gui */ struct t_hotkey { - char name[10]; + std::string name; int16_t mode; int32_t x; int32_t y; int32_t z; }; + typedef t_hotkey hotkey_array[NUM_HOTKEYS]; + /** + * One tile of the screen. Possibly outdated. * \ingroup grp_gui */ struct t_screen @@ -45,6 +88,7 @@ namespace DFHack uint8_t gtile; uint8_t grayscale; }; + /** * The Gui module * \ingroup grp_modules @@ -54,7 +98,7 @@ namespace DFHack { public: - Gui(DFHack::DFContextShared * d); + Gui(); ~Gui(); bool Start(); bool Finish(); @@ -66,10 +110,20 @@ namespace DFHack 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); + /* + * Gui screens + */ + /// handle to the interface object + t_interface * df_interface; + /// Get the current top-level view-screen + t_viewscreen * GetCurrentScreen(); + /// The DF menu state (designation menu ect) + uint32_t * df_menu_state; + /* * Hotkeys (DF's zoom locations) */ - bool ReadHotkeys(t_hotkey hotkeys[]); + hotkey_array * hotkeys; /* * Window size in tiles @@ -80,11 +134,6 @@ namespace DFHack * Screen tiles */ bool getScreenTiles(int32_t width, int32_t height, t_screen screen[]); - - /// read the DF menu view state (stock screen, unit screen, other screens - bool ReadViewScreen(t_viewscreen &); - /// read the DF menu state (designation menu ect) - uint32_t ReadMenuState(); private: struct Private; diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index e726cd550..811783bef 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_ITEMS #define CL_MOD_ITEMS @@ -5,10 +29,12 @@ /* * Items! */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" -#include "dfhack/DFTypes.h" - +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/Types.h" +#include "dfhack/Virtual.h" +#include "dfhack/modules/Materials.h" +#include "dfhack/Process.h" /** * \defgroup grp_items Items module and its types * @ingroup grp_modules @@ -73,17 +99,31 @@ union t_itemflags }; }; +/** + * Describes relationship of an item with other objects + * \ingroup grp_items + */ +struct t_itemref : public t_virtual +{ + int32_t value; +}; + /** * Basic item data, read as a single chunk * \ingroup grp_items */ -struct t_item +struct t_item : public t_virtual { - uint32_t vtable; - int16_t x; - int16_t y; - int16_t z; - t_itemflags flags; + // vptr 0x0 + 4 + int16_t x; // 0x4 + 2 + int16_t y; // 0x6 + 2 + int16_t z; // 0x8 + 2 + // 2B padding 0xA + 2 + t_itemflags flags; // 0xC + 4 + uint32_t unk1; // 0x10 + 4 + uint32_t id; // 0x14 + 4 + std::vector unk2;// usage is pretty rare + std::vector itemrefs; }; /** @@ -92,13 +132,11 @@ struct t_item */ struct dfh_item { - int32_t id; - t_item base; + t_item * base; t_material matdesc; int32_t quantity; int32_t quality; int16_t wear_level; - uint32_t origin; }; /** @@ -119,13 +157,13 @@ struct t_improvement class DFHACK_EXPORT Items : public Module { public: - Items(DFContextShared * _d); + Items(); ~Items(); bool Start(); bool Finish(); - bool readItemVector(std::vector &items); - uint32_t findItemByID(int32_t id); + bool readItemVector(std::vector &items); + t_item * findItemByID(int32_t id); /// get a string describing an item std::string getItemDescription(const dfh_item & item, Materials * Materials); @@ -133,7 +171,7 @@ public: std::string getItemClass(int32_t index); std::string getItemClass(const dfh_item & item); /// read an item, including the extra attributes - bool readItem(uint32_t itemptr, dfh_item & item); + bool readItem(t_item * itembase, dfh_item & item); /// write item base (position and flags only = t_item part of dfh_item) bool writeItem(const dfh_item & item); /// dump offsets used by accessors to a string diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index b46a40b8c..d549bd4c8 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + /******************************************************************************* M A P S Read and write DF's map @@ -6,9 +30,11 @@ #ifndef CL_MOD_MAPS #define CL_MOD_MAPS -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" -#include "Vegetation.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/modules/Vegetation.h" +#include +#include "dfhack/Virtual.h" /** * \defgroup grp_maps Maps module and its types @@ -125,50 +151,47 @@ namespace DFHack * mineral vein object - bitmap with a material type * \ingroup grp_maps */ - struct t_vein + struct t_vein : public t_virtual { - uint32_t vtable; /// index into the inorganic material vector int32_t type; /// 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; - /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. - uint32_t address_of; - - - //zilpin: Functions to more conveniently check the assignment flags of the vein. - //Coordinates are given in tile within the block. - //Important to make these inline. - inline int getassignment( DFCoord xy ){ - return getassignment(xy.x,xy.y); - } - inline int getassignment( int x, int y ){ - return (assignment[y] & (1 << x)); - } - inline void setassignment( DFCoord xy, int bit ){ - return setassignment(xy.x,xy.y, bit); - } - inline void setassignment( int x, int y, int bit ){ - if(bit) - assignment[y] |= (1 << x); - else - assignment[y] &= 0xFFFF ^ (1 << x); - } + + //zilpin: Functions to more conveniently check the assignment flags of the vein. + //Coordinates are given in tile within the block. + //Important to make these inline. + inline bool getassignment( DFCoord & xy ) + { + return getassignment(xy.x,xy.y); + } + inline bool getassignment( int x, int y ) + { + return (assignment[y] & (1 << x)); + } + inline void setassignment( DFCoord & xy, bool bit ) + { + return setassignment(xy.x,xy.y, bit); + } + inline void setassignment( int x, int y, bool bit ) + { + if(bit) + assignment[y] |= (1 << x); + else + assignment[y] &= 0xFFFF ^ (1 << x); + } }; /** * stores what tiles should appear when the ice melts - bitmap of material types * \ingroup grp_maps */ - struct t_frozenliquidvein + struct t_frozenliquidvein : public t_virtual { - uint32_t vtable; /// a 16x16 array of the original tile types int16_t tiles[16][16]; - /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. - uint32_t address_of; }; /** * \ingroup grp_maps @@ -188,9 +211,8 @@ namespace DFHack * \ingroup grp_maps * @see PrintSplatterType */ - struct t_spattervein + struct t_spattervein : public t_virtual { - uint32_t vtable; /// generic material. uint16_t mat1; /// possibly alignment artifact @@ -204,37 +226,29 @@ namespace DFHack uint16_t matter_state; /// 16x16 array of covering 'intensity' uint8_t intensity[16][16]; - /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. - uint32_t address_of; }; /** * a 'grass vein' defines the grass coverage of a map block * bitmap of density (max = 100) with plant material type * \ingroup grp_maps */ - struct t_grassvein + struct t_grassvein : public t_virtual { - uint32_t vtable; /// material vector index uint32_t material; /// 16x16 array of covering 'intensity' uint8_t intensity[16][16]; - /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. - uint32_t address_of; }; /** * defines the world constructions present. The material member is a mystery. * \ingroup grp_maps */ - struct t_worldconstruction + struct t_worldconstruction : public t_virtual { - uint32_t vtable; /// material vector index uint32_t material; /// 16x16 array of bits uint16_t assignment[16]; - /// this is NOT part of the structure, but an address of it as seen by DFhack. - uint32_t address_of; }; /** @@ -448,6 +462,7 @@ namespace DFHack /// 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 + // FIXME: yes, it's a crazy dynamically sized array of flags. DERP. }; /** @@ -484,7 +499,7 @@ namespace DFHack * array of 16 biome indexes valid for the block * \ingroup grp_maps */ - typedef uint8_t biome_indices40d [16]; + typedef uint8_t biome_indices40d [9]; /** * 16x16 array of temperatures * \ingroup grp_maps @@ -515,7 +530,100 @@ namespace DFHack int32_t mystery; } mapblock40d; - class DFContextShared; + // A raw DF block. + // one of the vector is the 'effects' vector. another should be item id/index vector + struct df_block + { + // FIXME: wrap the flag array! + unsigned char * flagarray; + unsigned long flagarray_slots; + // how to handle this virtual mess? + std::vector block_events; + // no idea what these are + long unk1; + long unk2; + long unk3; + // feature indexes + signed long local_feature; // local feature index, -1 = no local feature + signed long global_feature; // global feature index, -1 = no global feature + signed long mystery; // no idea. couldn't manage to catch its use in debugger. + // more mysterious numbers + long unk4; + long unk5; + long unk6; + std::vector items; // item related - probly item IDs + std::vector effects; + signed long unk7; // -1 most of the time, another index? + unsigned long unk8; // again, index? + std::vector plants; + unsigned short map_x; + unsigned short map_y; + unsigned short map_z; + unsigned short region_x; + unsigned short region_y; + unsigned short tiletype[16][16]; // weird 2-byte alignment here + t_designation designation[16][16]; + t_occupancy occupancy[16][16]; + // following is uncertain, but total length should be fixed. + unsigned char unk9[16][16]; + unsigned long pathfinding[16][16]; + unsigned short unk10[16][16]; + unsigned short unk11[16][16]; + unsigned short unk12[16][16]; + // end uncertain section + unsigned short temperature_1[16][16]; + unsigned short temperature_2[16][16]; + // no idea again. needs research... + unsigned short unk13[16][16]; + unsigned short unk14[16][16]; + unsigned char region_offset[9]; + }; + template + struct df_array + { + inline T& operator[] (uint32_t index) + { + return array[index]; + }; + T * array; + }; + template + struct df_2darray + { + inline df_array& operator[] (uint32_t index) + { + return array[index]; + }; + df_array * array; + }; + template + struct df_3darray + { + inline df_2darray& operator[] (uint32_t index) + { + return array[index]; + }; + inline bool operator! () + { + return !array; + } + df_2darray * array; + }; + struct map_data + { + df_3darray map; + std::vector unk1; + void * unk2; + uint32_t x_size_blocks; + uint32_t y_size_blocks; + uint32_t z_size_blocks; + uint32_t x_size; + uint32_t y_size; + uint32_t z_size; + int32_t x_area_offset; + int32_t y_area_offset; + int32_t z_area_offset; + }; /** * The Maps module * \ingroup grp_modules @@ -524,8 +632,10 @@ namespace DFHack class DFHACK_EXPORT Maps : public Module { public: + // the map data of DF, as we know it. + map_data * mdata; - Maps(DFHack::DFContextShared * d); + Maps(); ~Maps(); bool Start(); bool Finish(); @@ -621,63 +731,61 @@ namespace DFHack void getPosition(int32_t& x, int32_t& y, int32_t& z); /** - * 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 + * Get the map block or NULL if block is not valid */ - uint32_t getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz); + df_block * getBlock (uint32_t blockx, uint32_t blocky, uint32_t blockz); - /// read the whole map block at block coords (see DFTypes.h for the block structure) + /// copy the whole map block at block coords (see DFTypes.h for the block structure) bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer); - /// read/write block tile types + /// copy/write block tile types bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer); bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer); - /// read/write block designations + /// copy/write block designations bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); - /// read/write temperatures + /// copy/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 + /// copy/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); - /// read/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging + /// copy/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit); bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit); - /// read/write the block flags + /// copy/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); - - /// read/write features + + /// copy/write features bool SetBlockLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); bool SetBlockGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); - /// read region offsets of a block - used for determining layer stone matgloss + /// copy region offsets of a block - used for determining layer stone matgloss bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer); - /// block event reading - mineral veins, what's under ice, blood smears and mud - bool ReadVeins(uint32_t x, uint32_t y, uint32_t z, - std::vector* veins, - std::vector* ices = 0, - std::vector* splatter = 0, - std::vector* grass = 0, - std::vector* constructions = 0 + /// sorts the block event vector into multiple vectors by type + /// mineral veins, what's under ice, blood smears and mud + bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, + std::vector* veins, + std::vector* ices = 0, + std::vector* splatter = 0, + std::vector* grass = 0, + std::vector* constructions = 0 ); - /// write a single vein back to the address it was retreived from - bool Maps::WriteVein(t_vein *vein); - /// read all plants in this block - bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants); + /// remove a block event from the block by address + bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which ); + + /// read all plants in this block + bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector*& plants); + private: struct Private; Private *d; diff --git a/library/include/dfhack/modules/Materials.h b/library/include/dfhack/modules/Materials.h index 3b50bdf7e..813ac3585 100644 --- a/library/include/dfhack/modules/Materials.h +++ b/library/include/dfhack/modules/Materials.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_MATERIALS #define CL_MOD_MATERIALS @@ -5,63 +29,235 @@ * \defgroup grp_materials Materials module - used for reading raws mostly * @ingroup grp_modules */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/Types.h" + +#include +#include + namespace DFHack { - class DFContextShared; + struct t_syndrome + { + // it's lonely here... + }; + /// Research by Quietust + struct df_material + { + std::string Material_ID; + std::string IS_GEM_singular; + std::string IS_GEM_plural; + std::string STONE_NAME; + int16_t SPEC_HEAT; + int16_t HEATDAM_POINT; + int16_t COLDDAM_POINT; + int16_t IGNITE_POINT; + int16_t MELTING_POINT; + int16_t BOILING_POINT; + int16_t MAT_FIXED_TEMP; + //int16_t padding; // added by compiler automatically + int32_t SOLID_DENSITY; + int32_t LIQUID_DENSITY; + int32_t MOLAR_MASS; + int32_t STATE_COLOR_SOLID; // (color token index) + int32_t STATE_COLOR_LIQUID; // (color token index) + int32_t STATE_COLOR_GAS; // (color token index) + int32_t STATE_COLOR_POWDER; // (color token index) + int32_t STATE_COLOR_PASTE; // (color token index) + int32_t STATE_COLOR_PRESSED;// (color token index) + std::string STATE_NAME_SOLID; + std::string STATE_NAME_LIQUID; + std::string STATE_NAME_GAS; + std::string STATE_NAME_POWDER; + std::string STATE_NAME_PASTE; + std::string STATE_NAME_PRESSED; + std::string STATE_ADJ_SOLID; + std::string STATE_ADJ_LIQUID; + std::string STATE_ADJ_GAS; + std::string STATE_ADJ_POWDER; + std::string STATE_ADJ_PASTE; + std::string STATE_ADJ_PRESSED; + int32_t ABSORPTION; + int32_t BENDING_YIELD; + int32_t SHEAR_YIELD; + int32_t TORSION_YIELD; + int32_t IMPACT_YIELD; + int32_t TENSILE_YIELD; + int32_t COMPRESSIVE_YIELD; + int32_t BENDING_FRACTURE; + int32_t SHEAR_FRACTURE; + int32_t TORSION_FRACTURE; + int32_t IMPACT_FRACTURE; + int32_t TENSILE_FRACTURE; + int32_t COMPRESSIVE_FRACTURE; + int32_t BENDING_STRAIN_AT_YIELD; + int32_t SHEAR_STRAIN_AT_YIELD; + int32_t TORSION_STRAIN_AT_YIELD; + int32_t IMPACT_STRAIN_AT_YIELD; + int32_t TENSILE_STRAIN_AT_YIELD; + int32_t COMPRESSIVE_STRAIN_AT_YIELD; + int32_t MAX_EDGE; + int32_t MATERIAL_VALUE; + // FIXME: needs flagarray implementation! + uint8_t * flagarray_properties; + uint32_t flagarray_properties_length; + int16_t EXTRACT_STORAGE;// (item type) + int16_t BUTCHER_SPECIAL_type;// (item type) + int16_t BUTCHER_SPECIAL_subtype;// (item subtype) + //int16_t padding; // added by compiler + std::string MEAT_NAME_1st_parm; // (adj) + std::string MEAT_NAME_2nd_parm; + std::string MEAT_NAME_3rd_parm; + std::string BLOCK_NAME_1st_parm; + std::string BLOCK_NAME_2nd_parm; + std::vector MATERIAL_REACTION_PRODUCT_1st_parm;// (e.g. TAN_MAT) + std::vector unknown1; + std::vector unknown2; + std::vector MATERIAL_REACTION_PRODUCT_2nd_parm;// (e.g. LOCAL_CREATURE_MAT) + std::vector MATERIAL_REACTION_PRODUCT_3rd_parm;// (e.g. LEATHER) + std::vector MATERIAL_REACTION_PRODUCT_4th_parm;// (if you used CREATURE_MAT or PLANT_MAT) + int16_t unknown3; + //int16_t padding; // added by compiler + int32_t unknown4; + std::string HARDENS_WITH_WATER_1st_parm;// (e.g. INORGANIC) + std::string HARDENS_WITH_WATER_2nd_parm;// (e.g. GYPSUM) + std::string HARDENS_WITH_WATER_3rd_parm;// (if you used CREATURE_MAT or PLANT_MAT) + std::vector REACTION_CLASS; + int8_t TILE; + int16_t BASIC_COLOR_foreground; + int16_t BASIC_COLOR_bright; + // what exactly ARE those colors? + int16_t BUILD_COLOR_foreground; + int16_t BUILD_COLOR_background; + int16_t BUILD_COLOR_bright; + // same... + int16_t TILE_COLOR_foreground; + int16_t TILE_COLOR_background; + int16_t TILE_COLOR_bright; + int8_t ITEM_SYMBOL; + int16_t POWDER_DYE; // (color token index) + int16_t TEMP_DIET_INFO;// (whatever it means) + std::vector SYNDROME; + int32_t SOAP_LEVEL; + std::string PREFIX; + // etc... + }; + /// Research by Quietust + struct df_inorganic_base + { + std::string Inorganic_ID; + // FIXME: needs flagarray implementation! + uint8_t * flagarray_inorganic; + uint32_t flagarray_inorganic_length; + std::vector empty1; + std::vector METAL_ORE_matID; + std::vector METAL_ORE_prob; + std::vector empty2; + std::vector THREAD_METAL_matID; + std::vector THREAD_METAL_prob; + std::vector unknown_in_1; + std::vector empty3; + std::vector ENVIRONMENT_SPEC_matID; + std::vector ENVIRONMENT_SPEC_inclusion_type; + std::vector ENVIRONMENT_SPEC_prob; + std::vector ENVIRONMENT_location; + std::vector ENVIRONMENT_inclusion_type; + std::vector ENVIRONMENT_prob; + int32_t unknown_in_2; + }; + struct df_inorganic_material:public df_inorganic_base, public df_material {}; /** + * A copy of the game's material data. * \ingroup grp_materials */ - struct t_matgloss + class DFHACK_EXPORT t_matgloss { - char id[128]; //the id in the raws - uint8_t fore; // Annoyingly the offset for this differs between types + public: + std::string id; // raw name + std::string name; // a sensible human-readable name + uint8_t fore; uint8_t back; uint8_t bright; - char name[128]; //this is the name displayed ingame + + int32_t value; // Material value + uint8_t wall_tile; // Tile when a natural wall + uint8_t boulder_tile; // Tile when a dug-out stone; + + public: + t_matgloss(); }; + /** + * A copy of the game's inorganic material data. + * \ingroup grp_materials + */ + class DFHACK_EXPORT t_matglossInorganic : public t_matgloss + { + public: + // Types of metals the ore will produce when smelted. Each number + // is an index into the inorganic matglass vector. + std::vector ore_types; + + // Percent chance that the ore will produce each type of metal + // when smelted. + std::vector ore_chances; + + // Types of metals the ore will produce from strand extraction. + // Each number is an index into the inorganic matglass vector. + std::vector strand_types; + + // Percent chance that the ore will produce each type of metal + // fram strand extraction. + std::vector strand_chances; + + public: + //t_matglossInorganic(); + + bool isOre(); + bool isGem(); + }; + /** * \ingroup grp_materials */ struct t_descriptor_color { - char id[128]; // id in the raws + std::string id; + std::string name; float red; float green; float blue; - char name[128]; //displayed name }; /** * \ingroup grp_materials */ struct t_matglossPlant { - char id[128]; //the id in the raws - uint8_t fore; // Annoyingly the offset for this differs between types + std::string id; + std::string name; + uint8_t fore; uint8_t back; uint8_t bright; - char name[128]; //this is the name displayed ingame - char drink_name[128]; //the name this item becomes a drink - char food_name[128]; - char extract_name[128]; + std::string drink_name; + std::string food_name; + std::string extract_name; }; /** * \ingroup grp_materials */ struct t_bodypart { - char id[128]; - char category[128]; - char single[128]; - char plural[128]; + std::string id; + std::string category; + std::string singular; + std::string plural; }; /** * \ingroup grp_materials */ struct t_colormodifier { - char part[128]; + std::string part; std::vector colorlist; uint32_t startdate; /* in days */ uint32_t enddate; /* in days */ @@ -71,10 +267,10 @@ namespace DFHack */ struct t_creaturecaste { - char rawname[128]; - char singular[128]; - char plural[128]; - char adjective[128]; + std::string id; + std::string singular; + std::string plural; + std::string adjective; std::vector ColorModifier; std::vector bodypart; @@ -103,21 +299,21 @@ namespace DFHack */ struct t_matglossOther { - char rawname[128]; + std::string id; }; /** * \ingroup grp_materials */ struct t_creatureextract { - char rawname[128]; + std::string id; }; /** * \ingroup grp_materials */ struct t_creaturetype { - char rawname[128]; + std::string id; std::vector castes; std::vector extract; uint8_t tile_character; @@ -149,11 +345,12 @@ namespace DFHack class DFHACK_EXPORT Materials : public Module { public: - Materials(DFHack::DFContextShared * _d); + Materials(); ~Materials(); bool Finish(); - std::vector inorganic; + std::vector* df_inorganic; + std::vector inorganic; std::vector organic; std::vector tree; std::vector plant; diff --git a/library/include/dfhack/modules/Notes.h b/library/include/dfhack/modules/Notes.h new file mode 100644 index 000000000..8339c1cdc --- /dev/null +++ b/library/include/dfhack/modules/Notes.h @@ -0,0 +1,65 @@ +#pragma once +#ifndef CL_MOD_NOTES +#define CL_MOD_NOTES +/** + * \defgroup grp_notes In game notes (and routes) + * @ingroup grp_notes + */ +#include "dfhack/Export.h" +#include "dfhack/Module.h" + +#include +#include + +#ifdef __cplusplus +namespace DFHack +{ +#endif + /** + * Game's structure for a note. + * \ingroup grp_notes + */ + struct t_note + { + // First note created has id 0, second has id 1, etc. Not affected + // by lower id notes being deleted. + uint32_t id; // 0 + uint8_t symbol; // 4 + uint8_t unk1; // alignment padding? + uint16_t foreground; // 6 + uint16_t background; // 8 + uint16_t unk2; // alignment padding? + + std::string name; // C + std::string text; // 10 + + uint16_t x; // 14 + uint16_t y; // 16 + uint16_t z; // 18 + + // Is there more? + }; + +#ifdef __cplusplus + + /** + * The notes module - allows reading DF in-game notes + * \ingroup grp_modules + * \ingroup grp_notes + */ + class DFHACK_EXPORT Notes : public Module + { + public: + Notes(); + ~Notes(){}; + bool Finish() + { + return true; + } + std::vector* notes; + }; + +} +#endif // __cplusplus + +#endif diff --git a/library/include/dfhack/modules/Translation.h b/library/include/dfhack/modules/Translation.h index 4c4ee0194..ba14c2d0d 100644 --- a/library/include/dfhack/modules/Translation.h +++ b/library/include/dfhack/modules/Translation.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_TRANSLATION #define CL_MOD_TRANSLATION @@ -6,10 +30,12 @@ * @ingroup grp_modules */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/Types.h" namespace DFHack { + class DFContextShared; /** * \ingroup grp_translation @@ -31,13 +57,18 @@ namespace DFHack class DFHACK_EXPORT Translation : public Module { public: - Translation(DFContextShared * d); + Translation(); ~Translation(); bool Start(); bool Finish(); // Get pointer to the two dictionary structures Dicts * getDicts(); + + // names, used by a few other modules. + bool InitReadNames(); + bool readName(t_name & name, uint32_t address); + bool copyName(uint32_t address, uint32_t target); // translate a name using the loaded dictionaries std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true); diff --git a/library/include/dfhack/modules/Vegetation.h b/library/include/dfhack/modules/Vegetation.h index 86236fcdf..91e6cac8c 100644 --- a/library/include/dfhack/modules/Vegetation.h +++ b/library/include/dfhack/modules/Vegetation.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_VEGETATION #define CL_MOD_VEGETATION @@ -6,9 +30,9 @@ * @ingroup grp_modules */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" +#include "dfhack/Types.h" namespace DFHack { /** @@ -19,9 +43,9 @@ namespace DFHack * \ingroup grp_vegetation */ #pragma pack(push, 2) - struct t_plant + struct df_plant { - // +0x3C + df_name name; union { uint16_t type; @@ -50,20 +74,6 @@ namespace DFHack // some more temperature stuff after that }; #pragma pack(pop) - /** - * Plant object read from the game - * \ingroup grp_vegetation - */ - struct dfh_plant - { - /// name of the plant - t_name name; - /// data with static size/address - t_plant sdata; - /// address where the plant was read from - uint32_t address; - }; - class DFContextShared; /** * The Vegetation module * \ingroup grp_vegetation @@ -72,16 +82,10 @@ namespace DFHack class DFHACK_EXPORT Vegetation : public Module { public: - Vegetation(DFContextShared * d); + Vegetation(); ~Vegetation(); - bool Start(uint32_t & numTrees); - bool Read (const uint32_t index, dfh_plant & shrubbery); - bool Write (dfh_plant & shrubbery); - bool Finish(); - - private: - struct Private; - Private *d; + bool Finish(){return true;}; + std::vector *all_plants; }; } #endif diff --git a/library/include/dfhack/modules/Vermin.h b/library/include/dfhack/modules/Vermin.h new file mode 100644 index 000000000..5fa345df0 --- /dev/null +++ b/library/include/dfhack/modules/Vermin.h @@ -0,0 +1,86 @@ +#pragma once +#ifndef CL_MOD_VERMIN +#define CL_MOD_VERMIN +/** + * \defgroup grp_vermin Wild vermin (ants, bees, etc) + * @ingroup grp_vermin + */ +#include "dfhack/Export.h" +#include "dfhack/Module.h" + +#ifdef __cplusplus +namespace DFHack +{ +#endif + /** + * Structure for holding a read DF vermin spawn point object + * \ingroup grp_vermin + */ + struct t_spawnPoint + { + uint32_t origin; + int16_t race; + uint16_t type; + uint16_t x; + uint16_t y; + uint16_t z; + bool in_use; + uint8_t unknown; + uint32_t countdown; + }; + +#ifdef __cplusplus + class DFContextShared; + class SpawnPoints; + + /** + * The Vermin module - allows reading DF vermin + * \ingroup grp_modules + * \ingroup grp_vermin + */ + class DFHACK_EXPORT Vermin : public Module + { + public: + Vermin(); + ~Vermin(); + + bool Finish(); + + // NOTE: caller must call delete on result when done. + SpawnPoints* getSpawnPoints(); + + private: + struct Private; + Private *d; + + friend class SpawnPoints; + }; + + class DFHACK_EXPORT SpawnPoints + { + public: + static const uint16_t TYPE_WILD_COLONY = 0xFFFF; + + protected: + SpawnPoints(Vermin * v); + + public: + ~SpawnPoints(); + + size_t size(); + bool Read (const uint32_t index, t_spawnPoint & point); + bool Write (const uint32_t index, t_spawnPoint & point); + bool isValid(); + + static bool isWildColony(t_spawnPoint & point); + + private: + Vermin* v; + std::vector * p_sp; + + friend class Vermin; + }; +} +#endif // __cplusplus + +#endif diff --git a/library/include/dfhack/modules/WindowIO.h b/library/include/dfhack/modules/WindowIO.h deleted file mode 100644 index f0fda8b98..000000000 --- a/library/include/dfhack/modules/WindowIO.h +++ /dev/null @@ -1,119 +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. -*/ -#pragma once -#ifndef KEYS_H_INCLUDED -#define KEYS_H_INCLUDED - -/** - * \defgroup grp_windowio WindowIO: Send events to DF's window - * @ingroup grp_modules - */ - - -#include "../DFPragma.h" -#include "../DFExport.h" -#include "../DFModule.h" - -namespace DFHack -{ -class Process; -/** - * enum of all possible special keys - * \ingroup grp_windowio - */ -enum t_special -{ - ENTER, - SPACE, - BACK_SPACE, - TAB, - CAPS_LOCK, - LEFT_SHIFT, - RIGHT_SHIFT, - LEFT_CONTROL, - RIGHT_CONTROL, - ALT, - WAIT, - ESCAPE, - UP, - DOWN, - LEFT, - RIGHT, - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - F9, - F10, - F11, - F12, - PAGE_UP, - PAGE_DOWN, - INSERT, - DFK_DELETE, // stupid windows fails here - HOME, - END, - KEYPAD_DIVIDE, - KEYPAD_MULTIPLY, - KEYPAD_SUBTRACT, - KEYPAD_ADD, - KEYPAD_ENTER, - KEYPAD_0, - KEYPAD_1, - KEYPAD_2, - KEYPAD_3, - KEYPAD_4, - KEYPAD_5, - KEYPAD_6, - KEYPAD_7, - KEYPAD_8, - KEYPAD_9, - KEYPAD_DECIMAL_POINT, - NUM_SPECIALS -}; -class DFContextShared; -/** - * The WindowIO module - * \ingroup grp_windowio - * \ingroup grp_modules - */ -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); - void TypeSpecial (t_special command, int count = 1, int delay = 0); -}; - -} -#endif // KEYS_H_INCLUDED diff --git a/library/include/dfhack/modules/World.h b/library/include/dfhack/modules/World.h index 3ba0babd0..7203d775f 100644 --- a/library/include/dfhack/modules/World.h +++ b/library/include/dfhack/modules/World.h @@ -1,3 +1,27 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ + #pragma once #ifndef CL_MOD_WORLD #define CL_MOD_WORLD @@ -7,8 +31,8 @@ * @ingroup grp_modules */ -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "dfhack/Export.h" +#include "dfhack/Module.h" #include namespace DFHack @@ -22,39 +46,38 @@ namespace DFHack RAINING, SNOWING }; + typedef unsigned char weather_map [5][5]; /** * \ingroup grp_world */ - enum ControlMode + enum GameMode { - CM_Managing = 0, - CM_DirectControl = 1, - CM_Kittens = 2, // not sure yet, but I think it will involve kittens - CM_Menu = 3, - CM_MAX = 3 + GAMEMODE_DWARF, + GAMEMODE_ADVENTURE, + GAMEMODENUM, + GAMEMODE_NONE }; /** * \ingroup grp_world */ - enum GameMode + enum GameType { - GM_Fort = 0, - GM_Adventurer = 1, - GM_Legends = 2, - GM_Menu = 3, - GM_Arena = 4, - GM_Arena_Assumed = 5, - GM_Kittens = 6, - GM_Worldgen = 7, - GM_MAX = 7, + GAMETYPE_DWARF_MAIN, + GAMETYPE_ADVENTURE_MAIN, + GAMETYPE_VIEW_LEGENDS, + GAMETYPE_DWARF_RECLAIM, + GAMETYPE_DWARF_ARENA, + GAMETYPE_ADVENTURE_ARENA, + GAMETYPENUM, + GAMETYPE_NONE }; /** * \ingroup grp_world */ struct t_gamemodes { - ControlMode control_mode; - GameMode game_mode; + GameMode g_mode; + GameType g_type; }; class DFContextShared; /** @@ -65,8 +88,8 @@ namespace DFHack class DFHACK_EXPORT World : public Module { public: - - World(DFHack::DFContextShared * d); + weather_map * wmap; + World(); ~World(); bool Start(); bool Finish(); @@ -84,6 +107,7 @@ namespace DFHack void SetCurrentWeather(uint8_t weather); bool ReadGameMode(t_gamemodes& rd); bool WriteGameMode(const t_gamemodes & wr); // this is very dangerous + std::string ReadWorldFolder(); private: struct Private; Private *d; diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 3d86a77d2..4083ac5d1 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,15 +30,14 @@ distribution. #include using namespace std; -#include "ContextShared.h" - #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFTypes.h" -#include "dfhack/DFError.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Types.h" +#include "dfhack/Error.h" #include "dfhack/modules/Buildings.h" #include "ModuleFactory.h" +#include "dfhack/Core.h" using namespace DFHack; //raw @@ -65,26 +65,25 @@ struct Buildings::Private uint32_t custom_workshop_name; int32_t custom_workshop_id; DfVector * p_bld; - DFContextShared *d; Process * owner; bool Inited; bool hasCustomWorkshops; bool Started; }; -Module* DFHack::createBuildings(DFContextShared * d) +Module* DFHack::createBuildings() { - return new Buildings(d); + return new Buildings(); } -Buildings::Buildings(DFContextShared * d_) +Buildings::Buildings() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; - d->owner = d_->p; d->p_bld = NULL; d->Inited = d->Started = d->hasCustomWorkshops = false; - VersionInfo * mem = d->d->offset_descriptor; + VersionInfo * mem = c.vinfo; + d->owner = c.p; OffsetGroup * OG_build = mem->getGroup("Buildings"); d->Inited = true; try @@ -125,7 +124,7 @@ bool Buildings::Start(uint32_t & numbuildings) { if(!d->Inited) return false; - d->p_bld = new DfVector (d->owner, d->buildings_vector); + d->p_bld = new DfVector (d->buildings_vector); numbuildings = d->p_bld->size(); d->Started = true; return true; @@ -178,7 +177,7 @@ bool Buildings::ReadCustomWorkshopTypes(map & btypes) return false; Process * p = d->owner; - DfVector p_matgloss (p, d->custom_workshop_vector); + DfVector p_matgloss (d->custom_workshop_vector); uint32_t size = p_matgloss.size(); btypes.clear(); diff --git a/library/modules/Buildings_C.cpp b/library/modules/Buildings_C.cpp deleted file mode 100644 index bf7b0a306..000000000 --- a/library/modules/Buildings_C.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* -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 -#include -#include -using namespace std; -#include "dfhack-c/modules/Buildings_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int Buildings_Start(DFHackObject* b_Ptr, uint32_t* numBuildings) -{ - if(b_Ptr != NULL) - { - return ((DFHack::Buildings*)b_Ptr)->Start(*numBuildings); - } - return -1; -} - -int Buildings_Finish(DFHackObject* b_Ptr) -{ - if(b_Ptr != NULL) - { - return ((DFHack::Buildings*)b_Ptr)->Finish(); - } - return -1; -} - -int Buildings_Read(DFHackObject* b_Ptr, const uint32_t index, t_building* building) -{ - if(b_Ptr != NULL) - { - return ((DFHack::Buildings*)b_Ptr)->Read(index, *building); - } - return -1; -} - -int Buildings_GetCustomWorkshopType(DFHackObject* b_Ptr, t_building* building) -{ - if(b_Ptr != NULL) - { - return ((DFHack::Buildings*)b_Ptr)->GetCustomWorkshopType(*building); - } - return -1; -} - -t_customWorkshop* Buildings_ReadCustomWorkshopTypes(DFHackObject* b_Ptr) -{ - if(b_Ptr != NULL) - { - int i; - t_customWorkshop* cw_Ptr = NULL; - std::map bTypes; - map::iterator bIter; - - if(!((DFHack::Buildings*)b_Ptr)->ReadCustomWorkshopTypes(bTypes)) - return NULL; - - (*alloc_customWorkshop_buffer_callback)(&cw_Ptr, bTypes.size()); - - if(cw_Ptr == NULL) - return NULL; - - for(i = 0, bIter = bTypes.begin(); bIter != bTypes.end(); bIter++, i++) - { - cw_Ptr[i].index = (*bIter).first; - size_t length = (*bIter).second.copy(cw_Ptr[i].name, 256); - cw_Ptr[i].name[length] = '\0'; - } - return cw_Ptr; - } - - return NULL; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Constructions.cpp b/library/modules/Constructions.cpp index 72e7233f1..079f37398 100644 --- a/library/modules/Constructions.cpp +++ b/library/modules/Constructions.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,14 +30,14 @@ distribution. #include using namespace std; -#include "ContextShared.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Types.h" #include "dfhack/modules/Constructions.h" #include "ModuleFactory.h" +#include "dfhack/Core.h" using namespace DFHack; @@ -46,25 +47,24 @@ struct Constructions::Private // translation DfVector * p_cons; - DFContextShared *d; Process * owner; bool Inited; bool Started; }; -Module* DFHack::createConstructions(DFContextShared * d) +Module* DFHack::createConstructions() { - return new Constructions(d); + return new Constructions(); } -Constructions::Constructions(DFContextShared * d_) +Constructions::Constructions() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; - d->owner = d_->p; + d->owner = c.p; d->p_cons = 0; d->Inited = d->Started = false; - VersionInfo * mem = d->d->offset_descriptor; + VersionInfo * mem = c.vinfo; d->construction_vector = mem->getGroup("Constructions")->getAddress ("vector"); d->Inited = true; } @@ -78,7 +78,7 @@ Constructions::~Constructions() bool Constructions::Start(uint32_t & numconstructions) { - d->p_cons = new DfVector (d->owner, d->construction_vector); + d->p_cons = new DfVector (d->construction_vector); numconstructions = d->p_cons->size(); d->Started = true; return true; diff --git a/library/modules/Constructions_C.cpp b/library/modules/Constructions_C.cpp deleted file mode 100644 index a77ba7fc7..000000000 --- a/library/modules/Constructions_C.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -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 -#include -#include -using namespace std; -#include "dfhack-c/modules/Constructions_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int Constructions_Start(DFHackObject* c_Ptr, uint32_t* numConstructions) -{ - if(c_Ptr != NULL) - { - return ((DFHack::Constructions*)c_Ptr)->Start(*numConstructions); - } - - return -1; -} - -int Constructions_Finish(DFHackObject* c_Ptr) -{ - if(c_Ptr != NULL) - { - return ((DFHack::Constructions*)c_Ptr)->Finish(); - } - - return -1; -} - -int Constructions_Read(DFHackObject* c_Ptr, const uint32_t index, t_construction* construction) -{ - if(c_Ptr != NULL) - { - return ((DFHack::Constructions*)c_Ptr)->Read(index, *construction); - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Creatures.cpp b/library/modules/Creatures.cpp index febd2b5b8..af2925c45 100644 --- a/library/modules/Creatures.cpp +++ b/library/modules/Creatures.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -31,18 +32,19 @@ distribution. #include using namespace std; -#include "ContextShared.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFError.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Error.h" +#include "dfhack/Types.h" // we connect to those #include "dfhack/modules/Materials.h" #include "dfhack/modules/Creatures.h" +#include "dfhack/modules/Translation.h" #include "ModuleFactory.h" +#include using namespace DFHack; @@ -115,26 +117,28 @@ struct Creatures::Private bool IdMapReady; std::map IdMap; DfVector *p_cre; - DFContextShared *d; Process *owner; + Translation * trans; }; -Module* DFHack::createCreatures(DFContextShared * d) +Module* DFHack::createCreatures() { - return new Creatures(d); + return new Creatures(); } -Creatures::Creatures(DFContextShared* _d) +Creatures::Creatures() { + Core & c = Core::getInstance(); d = new Private; - d->d = _d; - d->owner = _d->p; + d->owner = c.p; + VersionInfo * minfo = c.vinfo; d->Inited = false; d->Started = false; d->IdMapReady = false; d->p_cre = NULL; - d->d->InitReadNames(); // throws on error - VersionInfo * minfo = d->d->offset_descriptor; + d->trans = c.getTranslation(); + d->trans->InitReadNames(); // throws on error + OffsetGroup *OG_Creatures = minfo->getGroup("Creatures"); OffsetGroup *OG_creature = OG_Creatures->getGroup("creature"); OffsetGroup *OG_creature_ex = OG_creature->getGroup("advanced"); @@ -241,7 +245,7 @@ bool Creatures::Start( uint32_t &numcreatures ) { if(d->Ft_basic) { - d->p_cre = new DfVector (d->owner, d->creatures.vector); + d->p_cre = new DfVector (d->creatures.vector); d->Started = true; numcreatures = d->p_cre->size(); d->IdMapReady = false; @@ -277,7 +281,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) if(d->Ft_basic) { // name - d->d->readName(furball.name,addr_cr + offs.name_offset); + d->trans->readName(furball.name,addr_cr + offs.name_offset); // basic stuff p->readDWord (addr_cr + offs.id_offset, furball.id); @@ -307,7 +311,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) // mood stuff furball.mood = (int16_t) p->readWord (addr_cr + offs.mood_offset); furball.mood_skill = p->readWord (addr_cr + offs.mood_skill_offset); - d->d->readName(furball.artifact_name, addr_cr + offs.artifact_name_offset); + d->trans->readName(furball.artifact_name, addr_cr + offs.artifact_name_offset); // labors p->read (addr_cr + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors); @@ -317,7 +321,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) furball.pregnancy_timer = p->readDWord (addr_cr + offs.pregnancy_offset ); // appearance - DfVector app(p, addr_cr + offs.appearance_vector_offset); + DfVector app(addr_cr + offs.appearance_vector_offset); furball.nbcolors = app.size(); if(furball.nbcolors>MAX_COLORS) furball.nbcolors = MAX_COLORS; @@ -349,7 +353,7 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) { furball.has_default_soul = true; // get first soul's skills - DfVector skills(p, soul + offs.soul_skills_vector_offset); + DfVector skills(soul + offs.soul_skills_vector_offset); furball.defaultSoul.numSkills = skills.size(); for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) @@ -522,7 +526,7 @@ bool Creatures::WriteSkills(const uint32_t index, const t_soul &soul) return false; } - DfVector skills(p, souloff + d->creatures.soul_skills_vector_offset); + DfVector skills(souloff + d->creatures.soul_skills_vector_offset); for (uint32_t i=0; i con unsigned int i; Process * p = d->owner; Private::t_offsets & off = d->creatures; - DfVector cmats(p, furball->current_job.occupationPtr + off.job_materials_vector); + DfVector cmats(furball->current_job.occupationPtr + off.job_materials_vector); for(i=0;i & mat) Process * p = d->owner; Private::t_offsets & off = d->creatures; - DfVector cmats(p, furball->current_job.occupationPtr + off.job_materials_vector); + DfVector cmats(furball->current_job.occupationPtr + off.job_materials_vector); mat.resize(cmats.size()); for(i=0;i & it if(!d->Started || !d->Ft_inventory) return false; Process * p = d->owner; - DfVector citem(p, temp + d->creatures.inventory_offset); + DfVector citem(temp + d->creatures.inventory_offset); if(citem.size() == 0) return false; item.resize(citem.size()); @@ -741,7 +745,7 @@ bool Creatures::ReadOwnedItemsPtr(const uint32_t temp, std::vector & it if(!d->Started || !d->Ft_owned_items) return false; Process * p = d->owner; - DfVector citem(p, temp + d->creatures.owned_items_offset); + DfVector citem(temp + d->creatures.owned_items_offset); if(citem.size() == 0) return false; item.resize(citem.size()); @@ -766,7 +770,7 @@ bool Creatures::RemoveOwnedItemPtr(const uint32_t temp, int32_t id) if(!d->Started || !d->Ft_owned_items) return false; Process * p = d->owner; - DfVector citem(p, temp + d->creatures.owned_items_offset); + DfVector citem(temp + d->creatures.owned_items_offset); for (unsigned i = 0; i < citem.size(); i++) { if (citem[i] != id) @@ -783,6 +787,6 @@ void Creatures::CopyNameTo(t_creature &creature, uint32_t address) Private::t_offsets &offs = d->creatures; if(d->Ft_basic) - d->d->copyName(creature.origin + offs.name_offset, address); + d->trans->copyName(creature.origin + offs.name_offset, address); } diff --git a/library/modules/Creatures_C.cpp b/library/modules/Creatures_C.cpp deleted file mode 100644 index 76b01666e..000000000 --- a/library/modules/Creatures_C.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* -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 -#include -#include -#include -using namespace std; - -#include "dfhack-c/modules/Creatures_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int Creatures_Start(DFHackObject* cPtr, uint32_t* numCreatures) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->Start(*numCreatures); - } - - return -1; -} - -int Creatures_Finish(DFHackObject* cPtr) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->Finish(); - } - - return -1; -} - -int32_t Creatures_ReadCreatureInBox(DFHackObject* cPtr, 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) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->ReadCreatureInBox(index, *furball, x1, y1, z1, x2, y2, z2); - } - - return -1; -} - -int Creatures_ReadCreature(DFHackObject* cPtr, const int32_t index, t_creature* furball) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->ReadCreature(index, *furball); - } - - return -1; -} - -t_material* Creatures_ReadJob(DFHackObject* cPtr, const t_creature* furball) -{ - if(cPtr != NULL) - { - std::vector mat; - - if(((DFHack::Creatures*)cPtr)->ReadJob(furball, mat)) - { - if(mat.size() <= 0) - return NULL; - - t_material* buf = NULL; - - (*alloc_material_buffer_callback)(&buf, mat.size()); - - if(buf != NULL) - { - copy(mat.begin(), mat.end(), buf); - - return buf; - } - else - return NULL; - } - else - return NULL; - } - - return NULL; -} - -uint32_t* Creatures_ReadInventoryIdx(DFHackObject* cPtr, const uint32_t index) -{ - if(cPtr != NULL) - { - std::vector item; - - if(((DFHack::Creatures*)cPtr)->ReadInventoryIdx(index, item)) - { - if(item.size() <= 0) - return NULL; - - uint32_t* buf = NULL; - - (*alloc_uint_buffer_callback)(&buf, item.size()); - - if(buf != NULL) - { - copy(item.begin(), item.end(), buf); - - return buf; - } - else - return NULL; - } - } - - return NULL; -} - -uint32_t* Creatures_ReadInventoryPtr(DFHackObject* cPtr, const uint32_t index) -{ - if(cPtr != NULL) - { - std::vector item; - - if(((DFHack::Creatures*)cPtr)->ReadInventoryPtr(index, item)) - { - if(item.size() <= 0) - return NULL; - - uint32_t* buf = NULL; - - (*alloc_uint_buffer_callback)(&buf, item.size()); - - if(buf != NULL) - { - copy(item.begin(), item.end(), buf); - - return buf; - } - else - return NULL; - } - } - - return NULL; -} - -uint32_t Creatures_GetDwarfRaceIndex(DFHackObject* cPtr) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->GetDwarfRaceIndex(); - } - - return 0; -} - -int32_t Creatures_GetDwarfCivId(DFHackObject* cPtr) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->GetDwarfCivId(); - } - - return -1; -} - -int Creatures_WriteLabors(DFHackObject* cPtr, const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteLabors(index, labors); - } - - return -1; -} - -int Creatures_WriteHappiness(DFHackObject* cPtr, const uint32_t index, const uint32_t happiness_value) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteHappiness(index, happiness_value); - } - - return -1; -} - -int Creatures_WriteFlags(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteFlags(index, flags1, flags2); - } - - return -1; -} - -int Creatures_WriteFlags3(DFHackObject* cPtr, const uint32_t index, const uint32_t flags1, const uint32_t flags2, const uint32_t flags3) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteFlags(index, flags1, flags2, - flags3); - } - - return -1; -} - -int Creatures_WriteSkills(DFHackObject* cPtr, const uint32_t index, const t_soul* soul) -{ - if(cPtr != NULL && soul != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteSkills(index, *soul); - } - - return -1; -} - -int Creatures_WriteAttributes(DFHackObject* cPtr, const uint32_t index, const t_creature* creature) -{ - if(cPtr != NULL && creature != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteAttributes(index, *creature); - } - - return -1; -} - -int Creatures_WriteSex(DFHackObject* cPtr, const uint32_t index, const uint8_t sex) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteSex(index, sex); - } - - return -1; -} - -int Creatures_WriteTraits(DFHackObject* cPtr, const uint32_t index, const t_soul* soul) -{ - if(cPtr != NULL && soul != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteTraits(index, *soul); - } - - return -1; -} - -int Creatures_WriteMood(DFHackObject* cPtr, const uint32_t index, const uint16_t mood) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteMood(index, mood); - } - - return -1; -} - -int Creatures_WriteMoodSkill(DFHackObject* cPtr, const uint32_t index, const uint16_t moodSkill) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteMoodSkill(index, moodSkill); - } - - return -1; -} - -int Creatures_WriteJob(DFHackObject* cPtr, const t_creature* furball, const t_material* mat, const uint32_t mat_count) -{ - if(cPtr != NULL && furball != NULL && mat != NULL) - { - if(mat_count == 0) - return 0; - - std::vector mat_vec; - - copy(mat, mat + mat_count, mat_vec.begin()); - - return ((DFHack::Creatures*)cPtr)->WriteJob(furball, mat_vec); - } - - return -1; -} - -int Creatures_WritePos(DFHackObject* cPtr, const uint32_t index, const t_creature* creature) -{ - if(cPtr != NULL && creature != NULL) - { - return ((DFHack::Creatures*)cPtr)->WritePos(index, *creature); - } - - return -1; -} - -int Creatures_WriteCiv(DFHackObject* cPtr, const uint32_t index, const int32_t civ) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WriteCiv(index, civ); - } - - return -1; -} - -int Creatures_WritePregnancy(DFHackObject* cPtr, const uint32_t index, const uint32_t pregTimer) -{ - if(cPtr != NULL) - { - return ((DFHack::Creatures*)cPtr)->WritePregnancy(index, pregTimer); - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Engravings.cpp b/library/modules/Engravings.cpp index f0d53fe09..8e436b849 100644 --- a/library/modules/Engravings.cpp +++ b/library/modules/Engravings.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,14 +30,13 @@ distribution. #include using namespace std; -#include "ContextShared.h" - #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Types.h" #include "dfhack/modules/Engravings.h" #include "ModuleFactory.h" +#include "dfhack/Core.h" using namespace DFHack; @@ -46,26 +46,24 @@ struct Engravings::Private // translation DfVector * p_engr; - DFContextShared *d; Process * owner; bool Inited; bool Started; }; -Module* DFHack::createEngravings(DFContextShared * d) +Module* DFHack::createEngravings() { - return new Engravings(d); + return new Engravings(); } -Engravings::Engravings(DFContextShared * d_) +Engravings::Engravings() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; - d->owner = d_->p; + d->owner = c.p; d->p_engr = 0; d->Inited = d->Started = false; - VersionInfo * mem = d->d->offset_descriptor; - d->engraving_vector = mem->getGroup("Engravings")->getAddress ("vector"); + d->engraving_vector = c.vinfo->getGroup("Engravings")->getAddress ("vector"); d->Inited = true; } @@ -78,7 +76,7 @@ Engravings::~Engravings() bool Engravings::Start(uint32_t & numengravings) { - d->p_engr = new DfVector (d->owner, d->engraving_vector); + d->p_engr = new DfVector (d->engraving_vector); numengravings = d->p_engr->size(); d->Started = true; return true; diff --git a/library/modules/Graveyard.cpp b/library/modules/Graveyard.cpp deleted file mode 100644 index 4abe854f1..000000000 --- a/library/modules/Graveyard.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// This is just a graveyard of old 40d code. Things in here COULD be turned into modules, but it requires research. - -bool API::InitReadEffects ( uint32_t & numeffects ) -{ - if(d->effectsInited) - FinishReadEffects(); - int effects = 0; - try - { - effects = d->offset_descriptor->getAddress ("effects_vector"); - } - catch(Error::AllMemdef) - { - return false; - } - d->effectsInited = true; - d->p_effect = new DfVector (d->p, effects); - numeffects = d->p_effect->getSize(); - return true; -} - -bool API::ReadEffect(const uint32_t index, t_effect_df40d & effect) -{ - if(!d->effectsInited) - return false; - if(index >= d->p_effect->getSize()) - return false; - - // read pointer from vector at position - uint32_t temp = d->p_effect->at (index); - //read effect from memory - d->p->read (temp, sizeof (t_effect_df40d), (uint8_t *) &effect); - return true; -} - -// use with care! -bool API::WriteEffect(const uint32_t index, const t_effect_df40d & effect) -{ - if(!d->effectsInited) - return false; - if(index >= d->p_effect->getSize()) - return false; - // read pointer from vector at position - uint32_t temp = d->p_effect->at (index); - // write effect to memory - d->p->write(temp,sizeof(t_effect_df40d), (uint8_t *) &effect); - return true; -} - -void API::FinishReadEffects() -{ - if(d->p_effect) - { - delete d->p_effect; - d->p_effect = NULL; - } - d->effectsInited = false; -} - -bool API::InitReadNotes( uint32_t &numnotes ) -{ - try - { - memory_info * minfo = d->offset_descriptor; - int notes = minfo->getAddress ("notes"); - d->note_foreground_offset = minfo->getOffset ("note_foreground"); - d->note_background_offset = minfo->getOffset ("note_background"); - d->note_name_offset = minfo->getOffset ("note_name"); - d->note_xyz_offset = minfo->getOffset ("note_xyz"); - - d->p_notes = new DfVector (d->p, notes); - d->notesInited = true; - numnotes = d->p_notes->getSize(); - return true; - } - catch (Error::AllMemdef&) - { - d->notesInited = false; - numnotes = 0; - throw; - } -} -bool API::ReadNote (const int32_t index, t_note & note) -{ - if(!d->notesInited) return false; - // read pointer from vector at position - uint32_t temp = d->p_notes->at (index); - note.symbol = d->p->readByte(temp); - note.foreground = d->p->readWord(temp + d->note_foreground_offset); - note.background = d->p->readWord(temp + d->note_background_offset); - d->p->readSTLString (temp + d->note_name_offset, note.name, 128); - d->p->read (temp + d->note_xyz_offset, 3*sizeof (uint16_t), (uint8_t *) ¬e.x); - return true; -} -bool API::InitReadSettlements( uint32_t & numsettlements ) -{ - if(!d->InitReadNames()) return false; - try - { - memory_info * minfo = d->offset_descriptor; - int allSettlements = minfo->getAddress ("settlements"); - int currentSettlement = minfo->getAddress("settlement_current"); - d->settlement_name_offset = minfo->getOffset ("settlement_name"); - d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy"); - d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy"); - - d->p_settlements = new DfVector (d->p, allSettlements); - d->p_current_settlement = new DfVector(d->p, currentSettlement); - d->settlementsInited = true; - numsettlements = d->p_settlements->getSize(); - return true; - } - catch (Error::AllMemdef&) - { - d->settlementsInited = false; - numsettlements = 0; - throw; - } -} -bool API::ReadSettlement(const int32_t index, t_settlement & settlement) -{ - if(!d->settlementsInited) return false; - if(!d->p_settlements->getSize()) return false; - - // read pointer from vector at position - uint32_t temp = d->p_settlements->at (index); - settlement.origin = temp; - d->readName(settlement.name, temp + d->settlement_name_offset); - d->p->read(temp + d->settlement_world_xy_offset, 2 * sizeof(int16_t), (uint8_t *) &settlement.world_x); - d->p->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1); - return true; -} - -bool API::ReadCurrentSettlement(t_settlement & settlement) -{ - if(!d->settlementsInited) return false; - if(!d->p_current_settlement->getSize()) return false; - - uint32_t temp = d->p_current_settlement->at(0); - settlement.origin = temp; - d->readName(settlement.name, temp + d->settlement_name_offset); - d->p->read(temp + d->settlement_world_xy_offset, 2 * sizeof(int16_t), (uint8_t *) &settlement.world_x); - d->p->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1); - return true; -} - -void API::FinishReadSettlements() -{ - if(d->p_settlements) - { - delete d->p_settlements; - d->p_settlements = NULL; - } - if(d->p_current_settlement) - { - delete d->p_current_settlement; - d->p_current_settlement = NULL; - } - d->settlementsInited = false; -} - -void API::FinishReadNotes() -{ - if(d->p_notes) - { - delete d->p_notes; - d->p_notes = 0; - } - d->notesInited = false; -} diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index b0fdf2b59..c934adfba 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,32 +30,27 @@ distribution. #include using namespace std; -#include "ContextShared.h" #include "dfhack/modules/Gui.h" -#include "dfhack/DFProcess.h" +#include "dfhack/Process.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFTypes.h" -#include "dfhack/DFError.h" +#include "dfhack/Types.h" +#include "dfhack/Error.h" #include "ModuleFactory.h" +#include "dfhack/Core.h" using namespace DFHack; -Module* DFHack::createGui(DFContextShared * d) +Module* DFHack::createGui() { - return new Gui(d); + return new Gui(); } struct Gui::Private { Private() { - Started = ViewScreeInited = MenuStateInited = false; - StartedHotkeys = StartedScreen = false; + Started = false; + StartedScreen = false; } - bool ViewScreeInited; - uint32_t view_screen_offset; - - bool MenuStateInited; - uint32_t current_menu_state_offset; bool Started; uint32_t window_x_offset; @@ -63,39 +59,50 @@ struct Gui::Private uint32_t cursor_xyz_offset; uint32_t window_dims_offset; - bool StartedHotkeys; - uint32_t hotkey_start; - uint32_t hotkey_mode_offset; - uint32_t hotkey_xyz_offset; - uint32_t hotkey_size; - bool StartedScreen; uint32_t screen_tiles_ptr_offset; - DFContextShared *d; Process * owner; }; -Gui::Gui(DFContextShared * _d) +Gui::Gui() { - + Core & c = Core::getInstance(); d = new Private; - d->d = _d; - d->owner = _d->p; - VersionInfo * mem = d->d->offset_descriptor; + d->owner = c.p; + VersionInfo * mem = c.vinfo; OffsetGroup * OG_Gui = mem->getGroup("GUI"); + + // Setting up hotkeys try { - d->current_menu_state_offset = OG_Gui->getAddress("current_menu_state"); - d->MenuStateInited = true; + hotkeys = (hotkey_array *) OG_Gui->getAddress("hotkeys"); } - catch(exception &){}; + catch(Error::All &) + { + hotkeys = 0; + }; + + // Setting up menu state try { - d->view_screen_offset = OG_Gui->getAddress ("view_screen"); - d->ViewScreeInited = true; + df_menu_state = (uint32_t *) OG_Gui->getAddress("current_menu_state"); } - catch(exception &){}; + catch(Error::All &) + { + df_menu_state = 0; + }; + + // Setting up the view screen stuff + try + { + df_interface = (t_interface *) OG_Gui->getAddress ("interface"); + } + catch(exception &) + { + df_interface = 0; + }; + OffsetGroup * OG_Position; try { @@ -109,16 +116,6 @@ Gui::Gui(DFContextShared * _d) } catch(Error::All &){}; try - { - OffsetGroup * OG_Hotkeys = mem->getGroup("Hotkeys"); - d->hotkey_start = OG_Hotkeys->getAddress("start"); - d->hotkey_mode_offset = OG_Hotkeys->getOffset ("mode"); - d->hotkey_xyz_offset = OG_Hotkeys->getOffset("coords"); - d->hotkey_size = OG_Hotkeys->getHexValue("size"); - d->StartedHotkeys = true; - } - catch(Error::All &){}; - try { d->screen_tiles_ptr_offset = OG_Position->getAddress ("screen_tiles_pointer"); d->StartedScreen = true; @@ -141,48 +138,19 @@ bool Gui::Finish() return true; } -uint32_t Gui::ReadMenuState() +t_viewscreen * Gui::GetCurrentScreen() { - if(d->MenuStateInited) - return(d->owner->readDWord(d->current_menu_state_offset)); - return false; -} - -// FIXME: variable ‘screenAddr’ set but not used [-Wunused-but-set-variable] -bool Gui::ReadViewScreen (t_viewscreen &screen) -{ - if (!d->ViewScreeInited) return false; - Process * p = d->owner; - - uint32_t last = p->readDWord (d->view_screen_offset); - uint32_t screenAddr = p->readDWord (last); - uint32_t nextScreenPtr = p->readDWord (last + 4); - while (nextScreenPtr != 0) + if(!df_interface) + return 0; + t_viewscreen * ws = &df_interface->view; + while(ws) { - last = nextScreenPtr; - screenAddr = p->readDWord (nextScreenPtr); - nextScreenPtr = p->readDWord (nextScreenPtr + 4); + if(ws->child) + ws = ws->child; + else + return ws; } - return d->d->offset_descriptor->resolveObjectToClassID (last, screen.type); -} - -bool Gui::ReadHotkeys(t_hotkey hotkeys[]) -{ - if (!d->StartedHotkeys) - { - return false; - } - uint32_t currHotkey = d->hotkey_start; - Process * p = d->owner; - - for(uint32_t i = 0 ; i < NUM_HOTKEYS ;i++) - { - p->readSTLString(currHotkey,hotkeys[i].name,10); - hotkeys[i].mode = p->readWord(currHotkey+d->hotkey_mode_offset); - p->read (currHotkey + d->hotkey_xyz_offset, 3*sizeof (int32_t), (uint8_t *) &hotkeys[i].x); - currHotkey+=d->hotkey_size; - } - return true; + return 0; } bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) diff --git a/library/modules/Gui_C.cpp b/library/modules/Gui_C.cpp deleted file mode 100644 index a6739b8b8..000000000 --- a/library/modules/Gui_C.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* -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 -#include -#include -using namespace std; - -#include "dfhack-c/modules/Gui_C.h" -#include "dfhack-c/DFTypes_C.h" -#ifdef __cplusplus -extern "C" { -#endif - -int Gui_Start(DFHackObject* gui) -{ - if(gui != NULL) - { - return ((DFHack::Gui*)gui)->Start(); - } - - return -1; -} - -int Gui_Finish(DFHackObject* gui) -{ - if(gui != NULL) - { - return ((DFHack::Gui*)gui)->Finish(); - } - - return -1; -} - -int Gui_getViewCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z) -{ - if(gui != NULL) - { - int32_t tx, ty, tz; - - if(((DFHack::Gui*)gui)->getViewCoords(tx, ty, tz)) - { - *x = tx; - *y = ty; - *z = tz; - - return 1; - } - else - return 0; - } - - return -1; -} - -int Gui_setViewCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z) -{ - if(gui != NULL) - { - if(((DFHack::Gui*)gui)->setViewCoords(x, y, z)) - return 1; - else - return 0; - } - - return -1; -} - -int Gui_getCursorCoords(DFHackObject* gui, int32_t* x, int32_t* y, int32_t* z) -{ - if(gui != NULL) - { - int32_t tx, ty, tz; - - if(((DFHack::Gui*)gui)->getCursorCoords(tx, ty, tz)) - { - *x = tx; - *y = ty; - *z = tz; - - return 1; - } - else - return 0; - } - - return -1; -} - -int Gui_setCursorCoords(DFHackObject* gui, int32_t x, int32_t y, int32_t z) -{ - if(gui != NULL) - { - if(((DFHack::Gui*)gui)->setCursorCoords(x, y, z)) - return 1; - else - return 0; - } - - return -1; -} - -t_hotkey* Gui_ReadHotkeys(DFHackObject* gui) -{ - if(gui != NULL) - { - t_hotkey* buf; - - (*alloc_hotkey_buffer_callback)(&buf, NUM_HOTKEYS); - - if(buf != NULL) - { - if(((DFHack::Gui*)gui)->ReadHotkeys(buf)) - return buf; - else - return NULL; - } - else - return NULL; - } - - return NULL; -} - -int Gui_getWindowSize(DFHackObject* gui, int32_t* width, int32_t* height) -{ - if(gui != NULL) - { - int32_t tw, th; - - if(((DFHack::Gui*)gui)->getWindowSize(tw, th)) - { - *width = tw; - *height = th; - - return 1; - } - else - return 0; - } - - return -1; -} - -t_screen* Gui_getScreenTiles(DFHackObject* gui, int32_t width, int32_t height) -{ - if(gui != NULL) - { - t_screen* buf; - - (*alloc_screen_buffer_callback)(&buf, width * height); - - if(buf == NULL) - return NULL; - - if(((DFHack::Gui*)gui)->getScreenTiles(width, height, buf)) - return buf; - else - return NULL; - } - - return NULL; -} - -int Gui_ReadViewScreen(DFHackObject* gui, t_viewscreen* viewscreen) -{ - if(gui != NULL) - { - return ((DFHack::Gui*)gui)->ReadViewScreen(*viewscreen); - } - - return -1; -} - -int Gui_ReadMenuState(DFHackObject* gui, uint32_t* menuState) -{ - if(gui != NULL) - { - *menuState = ((DFHack::Gui*)gui)->ReadMenuState(); - - return 1; - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 9f9e4446e..21b1e9f92 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -31,21 +32,21 @@ distribution. #include using namespace std; -#include "ContextShared.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Types.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" #include "dfhack/modules/Materials.h" #include "dfhack/modules/Items.h" #include "dfhack/modules/Creatures.h" #include "ModuleFactory.h" +#include using namespace DFHack; -Module* DFHack::createItems(DFContextShared * d) +Module* DFHack::createItems() { - return new Items(d); + return new Items(); } enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT}; @@ -71,7 +72,7 @@ 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); std::string dump(); - int32_t getValue(uint32_t objectPtr); + int32_t getValue(t_item * objectPtr); bool isConstant(); }; class ItemImprovementDesc @@ -100,11 +101,11 @@ private: bool hasDecoration; int idFieldOffset; public: - ItemDesc(uint32_t VTable, Process * p); - bool readItem(uint32_t itemptr, dfh_item & item); + ItemDesc(void * VTable, Process * p); + bool readItem(t_item * itemptr, dfh_item & item); std::string dumpAccessors(); std::string className; - uint32_t vtable; + void * vtable; uint32_t mainType; std::vector improvement; }; @@ -305,7 +306,7 @@ string Accessor::dump() return sstr.str(); } -int32_t Accessor::getValue(uint32_t objectPtr) +int32_t Accessor::getValue(t_item * objectPtr) { int32_t offset = this->offset1; @@ -315,18 +316,18 @@ int32_t Accessor::getValue(uint32_t objectPtr) return this->constant; break; case ACCESSOR_DOUBLE_INDIRECT: - objectPtr = p->readDWord(objectPtr + this->offset1); + objectPtr = (t_item *) p->readDWord((uint32_t)objectPtr + this->offset1); offset = this->offset2; // fallthrough case ACCESSOR_INDIRECT: switch(this->dataWidth) { case Data32: - return p->readDWord(objectPtr + offset); + return p->readDWord((uint32_t)objectPtr + offset); case DataSigned16: - return (int16_t) p->readWord(objectPtr + offset); + return (int16_t) p->readWord((uint32_t)objectPtr + offset); case DataUnsigned16: - return (uint16_t) p->readWord(objectPtr + offset); + return (uint16_t) p->readWord((uint32_t)objectPtr + offset); default: return -1; } @@ -337,12 +338,12 @@ int32_t Accessor::getValue(uint32_t objectPtr) } // FIXME: turn into a proper factory with caching -Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint32_t vtable) +Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, void * vtable) { int32_t offset; if(I->getSafeOffset(name,offset)) { - return new Accessor( p->readDWord( vtable + offset ), p); + return new Accessor( p->readDWord( (uint32_t)vtable + offset ), p); } else { @@ -351,7 +352,7 @@ Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint3 } } -ItemDesc::ItemDesc(uint32_t VTable, Process *p) +ItemDesc::ItemDesc(void * VTable, Process *p) { OffsetGroup * Items = p->getDescriptor()->getGroup("Items"); @@ -372,7 +373,7 @@ ItemDesc::ItemDesc(uint32_t VTable, Process *p) this->vtable = VTable; this->p = p; - this->className = p->readClassName(VTable).substr(5); + this->className = p->readClassName((void *) VTable).substr(5); this->className.resize(this->className.size()-2); this->hasDecoration = false; @@ -399,17 +400,15 @@ string ItemDesc::dumpAccessors() } -bool ItemDesc::readItem(uint32_t itemptr, DFHack::dfh_item &item) +bool ItemDesc::readItem(t_item * itemptr, DFHack::dfh_item &item) { - item.id = p->readDWord(itemptr+idFieldOffset); - p->read(itemptr, sizeof(t_item), (uint8_t*)&item.base); + item.base = itemptr; item.matdesc.itemType = AMainType->getValue(itemptr); item.matdesc.subType = ASubType->getValue(itemptr); item.matdesc.subIndex = ASubIndex->getValue(itemptr); item.matdesc.index = AIndex->getValue(itemptr); item.quality = AQuality->getValue(itemptr); item.quantity = AQuantity->getValue(itemptr); - item.origin = itemptr; // FIXME: use templates. seriously. // Note: this accessor returns a 32-bit value with the higher // half sometimes containing garbage, so the cast is essential: @@ -423,8 +422,8 @@ class Items::Private DFContextShared *d; Process * owner; std::map descType; - std::map descVTable; - std::map idLookupTable; + std::map descVTable; + std::map idLookupTable; uint32_t refVectorOffset; uint32_t idFieldOffset; uint32_t itemVectorAddress; @@ -433,17 +432,17 @@ class Items::Private ClassNameCheck isContainsRefClass; }; -Items::Items(DFContextShared * d_) +Items::Items() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; - d->owner = d_->p; + d->owner = c.p; d->isOwnerRefClass = ClassNameCheck("general_ref_unit_itemownerst"); d->isContainerRefClass = ClassNameCheck("general_ref_contained_in_itemst"); d->isContainsRefClass = ClassNameCheck("general_ref_contains_itemst"); - DFHack::OffsetGroup* itemGroup = d_->offset_descriptor->getGroup("Items"); + DFHack::OffsetGroup* itemGroup = c.vinfo->getGroup("Items"); d->itemVectorAddress = itemGroup->getAddress("items_vector"); d->idFieldOffset = itemGroup->getOffset("id"); d->refVectorOffset = itemGroup->getOffset("item_ref_vector"); @@ -460,29 +459,31 @@ bool Items::Finish() return true; } -bool Items::readItemVector(std::vector &items) +bool Items::readItemVector(std::vector &items) { - DFHack::DfVector p_items(d->owner, d->itemVectorAddress); + std::vector *p_items = (std::vector *) d->itemVectorAddress; d->idLookupTable.clear(); - items.resize(p_items.size()); + items.resize(p_items->size()); - for (unsigned i = 0; i < p_items.size(); i++) { - uint32_t ptr = p_items[i]; + for (unsigned i = 0; i < p_items->size(); i++) + { + t_item * ptr = p_items->at(i); items[i] = ptr; - d->idLookupTable[d->owner->readDWord(ptr + d->idFieldOffset)] = ptr; + d->idLookupTable[ptr->id] = ptr; } return true; } -uint32_t Items::findItemByID(int32_t id) +t_item * Items::findItemByID(int32_t id) { if (id < 0) return 0; - if (d->idLookupTable.empty()) { - std::vector tmp; + if (d->idLookupTable.empty()) + { + std::vector tmp; readItemVector(tmp); } @@ -492,7 +493,7 @@ uint32_t Items::findItemByID(int32_t id) Items::~Items() { Finish(); - std::map::iterator it; + std::map::iterator it; it = d->descVTable.begin(); while (it != d->descVTable.end()) { @@ -504,13 +505,13 @@ Items::~Items() delete d; } -bool Items::readItem(uint32_t itemptr, DFHack::dfh_item &item) +bool Items::readItem(t_item * itembase, DFHack::dfh_item &item) { - std::map::iterator it; + std::map::iterator it; Process * p = d->owner; ItemDesc * desc; - uint32_t vtable = p->readDWord(itemptr); + void * vtable = itembase->vptr; it = d->descVTable.find(vtable); if(it == d->descVTable.end()) { @@ -521,25 +522,9 @@ bool Items::readItem(uint32_t itemptr, DFHack::dfh_item &item) else desc = it->second; - return desc->readItem(itemptr, item); -} - -bool Items::writeItem(const DFHack::dfh_item &item) -{ - if(item.origin) - { - d->owner->write(item.origin, sizeof(t_item),(uint8_t *)&(item.base)); - return true; - } - return false; + return desc->readItem(itembase, item); } -/* -void Items::setItemFlags(uint32_t itemptr, t_itemflags new_flags) -{ - d->owner->writeDWord(itemptr + 0x0C, new_flags.whole); -} -*/ int32_t Items::getItemOwnerID(const DFHack::dfh_item &item) { std::vector vals; @@ -565,15 +550,13 @@ bool Items::getContainedItems(const DFHack::dfh_item &item, std::vector bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector &values) { - DFHack::DfVector p_refs(d->owner, item.origin + d->refVectorOffset); - + std::vector &p_refs = item.base->itemrefs; values.clear(); for (uint32_t i=0; iowner->readDWord(p_refs[i]); - if (classname(d->owner, vtbl)) - values.push_back(int32_t(d->owner->readDWord(p_refs[i] + 4))); + if (classname(d->owner, p_refs[i]->vptr)) + values.push_back(int32_t(p_refs[i]->value)); } return !values.empty(); @@ -581,30 +564,24 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, bool Items::removeItemOwner(dfh_item &item, Creatures *creatures) { - DFHack::DfVector p_refs(d->owner, item.origin + d->refVectorOffset); - + std::vector &p_refs = item.base->itemrefs; for (uint32_t i=0; iowner->readDWord(p_refs[i]); - if (!d->isOwnerRefClass(d->owner, vtbl)) continue; + if (!d->isOwnerRefClass(d->owner, p_refs[i]->vptr)) + continue; - int32_t oid = d->owner->readDWord(p_refs[i]+4); + int32_t & oid = p_refs[i]->value; int32_t ix = creatures->FindIndexById(oid); - if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.id)) - { - cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.id << " FAILED!" << endl; - return false; - } - - if (!p_refs.remove(i--)) + if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.base->id)) { - cerr << "p_refs.remove FAILED!" << endl; + cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.base->id << " FAILED!" << endl; return false; } + p_refs.erase(p_refs.begin() + i--); } - item.base.flags.owned = 0; + item.base->flags.owned = 0; return true; } @@ -673,7 +650,7 @@ std::string Items::getItemDescription(const dfh_item & item, Materials * Materia /// dump offsets used by accessors of a valid item to a string std::string Items::dumpAccessors(const dfh_item & item) { - std::map< uint32_t, ItemDesc* >::const_iterator it = d->descVTable.find(item.base.vtable); + std::map< void *, ItemDesc* >::const_iterator it = d->descVTable.find(item.base->vptr); if(it != d->descVTable.end()) return it->second->dumpAccessors(); return "crud"; diff --git a/library/modules/Items_C.cpp b/library/modules/Items_C.cpp deleted file mode 100644 index ce56292a6..000000000 --- a/library/modules/Items_C.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -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 -#include -#include -using namespace std; - -#include "dfhack-c/modules/Items_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int Items_Start(DFHackObject* items) -{ - if(items != NULL) - { - return ((DFHack::Items*)items)->Start(); - } - - return -1; -} - -int Items_Finish(DFHackObject* items) -{ - if(items != NULL) - { - return ((DFHack::Items*)items)->Finish(); - } - - return -1; -} - -//FIXME: beware of bad null-termination! I haven't tested anything here, but it seems that it could be corrupting or truncating strings. - -char* Items_getItemDescription(DFHackObject* items, dfh_item * item, DFHackObject* mats) -{ - if(items != NULL && mats != NULL) - { - std::string desc = ((DFHack::Items*)items)->getItemDescription(*item, (DFHack::Materials*)mats); - - if(desc.size() > 0) - { - char* buf = NULL; - - (*alloc_char_buffer_callback)(&buf, desc.size()); - - if(buf != NULL) - { - size_t len = desc.copy(buf, desc.size()); - - if(len > 0) - buf[len] = '\0'; - else - buf[0] = '\0'; - } - - return buf; - } - } - - return NULL; -} - -char* Items_getItemClass(DFHackObject* items, int32_t index) -{ - if(items != NULL) - { - std::string iclass = ((DFHack::Items*)items)->getItemClass(index); - - if(iclass.size() > 0) - { - char* buf = NULL; - - (*alloc_char_buffer_callback)(&buf, iclass.size()); - - if(buf != NULL) - { - size_t len = iclass.copy(buf, iclass.size()); - - if(len > 0) - buf[len] = '\0'; - else - buf[0] = '\0'; - } - - return buf; - } - } - - return NULL; -} - -int Items_getItemData(DFHackObject* items, uint32_t itemptr, dfh_item* item) -{ - if(items != NULL) - { - return ((DFHack::Items*)items)->readItem(itemptr, *item); - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 8ab9a6c2e..0f2a909ce 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,23 +30,24 @@ distribution. #include #include #include +#include using namespace std; -#include "ContextShared.h" #include "dfhack/modules/Maps.h" -#include "dfhack/DFError.h" +#include "dfhack/Error.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" #include "ModuleFactory.h" +#include #define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized(); using namespace DFHack; -Module* DFHack::createMaps(DFContextShared * d) +Module* DFHack::createMaps() { - return new Maps(d); + return new Maps(); } const char * DFHack::sa_feature(e_feature index) @@ -67,45 +69,20 @@ const char * DFHack::sa_feature(e_feature index) struct Maps::Private { - uint32_t * block; - uint32_t x_block_count, y_block_count, z_block_count; - int32_t regionX, regionY, regionZ; uint32_t worldSizeX, worldSizeY; uint32_t maps_module; struct t_offsets { - uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data"); - uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count"); - uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count"); - uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count"); - /* - Block - */ - uint32_t tile_type_offset;// = d->offset_descriptor->getOffset ("type"); - uint32_t designation_offset;// = d->offset_descriptor->getOffset ("designation"); - uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy"); - uint32_t biome_stuffs;// = d->offset_descriptor->getOffset ("biome_stuffs"); - uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein"); - uint32_t vegvector; - uint32_t temperature1_offset; - uint32_t temperature2_offset; - uint32_t global_feature_offset; - uint32_t local_feature_offset; - uint32_t mystery; - - uint32_t vein_mineral_vptr; - uint32_t vein_ice_vptr; - uint32_t vein_spatter_vptr; - uint32_t vein_grass_vptr; - uint32_t vein_worldconstruction_vptr; + // FIXME: those need a rework really. Why did Toady use virtual inheritance for such vastly different types anyway? + void * vein_mineral_vptr; + void * vein_ice_vptr; + void * vein_spatter_vptr; + void * vein_grass_vptr; + void * vein_worldconstruction_vptr; /* GEOLOGY */ - uint32_t region_x_offset;// = minfo->getAddress ("region_x"); - uint32_t region_y_offset;// = minfo->getAddress ("region_y"); - uint32_t region_z_offset;// = minfo->getAddress ("region_z"); - uint32_t world_regions;// mem->getAddress ("ptr2_region_array"); uint32_t region_size;// = minfo->getHexValue ("region_size"); uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off"); @@ -118,21 +95,21 @@ struct Maps::Private /* FEATURES */ + // FIXME: replace with a struct pointer, eventually. needs to be mapped out first uint32_t world_data; - uint32_t local_f_start; // offset from world_data or absolute address. + uint32_t local_f_start; // offset from world_data + // FIXME: replace by virtual function call uint32_t local_material; + // FIXME: replace by virtual function call uint32_t local_submaterial; - uint32_t global_vector; // offset from world_data or absolute address. + uint32_t global_vector; // offset from world_data uint32_t global_funcptr; + // FIXME: replace by virtual function call uint32_t global_material; + // FIXME: replace by virtual function call uint32_t global_submaterial; - /* - * Vegetation - */ - uint32_t tree_desc_offset; } offsets; - DFContextShared *d; Process * owner; OffsetGroup *OG_vector; bool Inited; @@ -142,8 +119,6 @@ struct Maps::Private bool hasFeatures; bool hasVeggies; - bool usesWorldDataPtr; - set unknown_veins; // map between feature address and the read object @@ -154,79 +129,29 @@ struct Maps::Private vector v_geology[eBiomeCount]; }; -Maps::Maps(DFContextShared* _d) +Maps::Maps() { + Core & c = Core::getInstance(); d = new Private; - d->d = _d; - Process *p = d->owner = _d->p; + Process *p = d->owner = c.p; d->Inited = d->FeaturesStarted = d->Started = false; - d->block = NULL; - d->usesWorldDataPtr = false; - DFHack::VersionInfo * mem = p->getDescriptor(); + DFHack::VersionInfo * mem = c.vinfo; Private::t_offsets &off = d->offsets; d->hasFeatures = d->hasGeology = d->hasVeggies = true; // get the offsets once here OffsetGroup *OG_Maps = mem->getGroup("Maps"); - try - { - off.world_data = OG_Maps->getAddress("world_data"); - d->usesWorldDataPtr = true; - //cout << "uses world ptr" << endl; - }catch(Error::AllMemdef &){} - + off.world_data = OG_Maps->getAddress("world_data"); { - off.map_offset = OG_Maps->getAddress ("map_data"); - off.x_count_offset = OG_Maps->getAddress ("x_count_block"); - off.y_count_offset = OG_Maps->getAddress ("y_count_block"); - off.z_count_offset = OG_Maps->getAddress ("z_count_block"); - off.region_x_offset = OG_Maps->getAddress ("region_x"); - off.region_y_offset = OG_Maps->getAddress ("region_y"); - off.region_z_offset = OG_Maps->getAddress ("region_z"); - if(d->usesWorldDataPtr) - { - off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata"); - off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata"); - } - else - { - off.world_size_x = OG_Maps->getAddress ("world_size_x"); - off.world_size_y = OG_Maps->getAddress ("world_size_y"); - } - OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block"); - { - off.tile_type_offset = OG_MapBlock->getOffset ("type"); - off.designation_offset = OG_MapBlock->getOffset ("designation"); - off.occupancy_offset = OG_MapBlock->getOffset("occupancy"); - off.biome_stuffs = OG_MapBlock->getOffset ("biome_stuffs"); - off.veinvector = OG_MapBlock->getOffset ("vein_vector"); - off.local_feature_offset = OG_MapBlock->getOffset ("feature_local"); - off.global_feature_offset = OG_MapBlock->getOffset ("feature_global"); - off.temperature1_offset = OG_MapBlock->getOffset ("temperature1"); - off.temperature2_offset = OG_MapBlock->getOffset ("temperature2"); - } - try - { - off.mystery = OG_MapBlock->getOffset ("mystery_offset"); - } - catch(Error::AllMemdef &) - { - off.mystery = 0; - } + mdata = (map_data *) OG_Maps->getAddress ("map_data"); + off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata"); + off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata"); try { OffsetGroup *OG_Geology = OG_Maps->getGroup("geology"); - if(d->usesWorldDataPtr) - { - off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata"); - off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata"); - } - else - { - off.world_regions = OG_Geology->getAddress ("ptr2_region_array"); - off.world_geoblocks_vector = OG_Geology->getAddress ("geoblock_vector"); - } + off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata"); + off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata"); off.region_size = OG_Geology->getHexValue ("region_size"); off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset"); @@ -240,16 +165,8 @@ Maps::Maps(DFContextShared* _d) OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local"); try { - if(d->usesWorldDataPtr) - { - off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata"); - off.global_vector = OG_global_features->getOffset("vector_from_wdata"); - } - else - { - off.local_f_start = OG_local_features->getAddress("start_ptr"); - off.global_vector = OG_global_features->getAddress("vector"); - } + off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata"); + off.global_vector = OG_global_features->getOffset("vector_from_wdata"); off.local_material = OG_local_features->getOffset("material"); off.local_submaterial = OG_local_features->getOffset("submaterial"); @@ -261,17 +178,6 @@ Maps::Maps(DFContextShared* _d) { d->hasFeatures = false; } - - try - { - OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation"); - off.vegvector = OG_MapBlock->getOffset ("vegetation_vector"); - off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset"); - } - catch(Error::AllMemdef &) - { - d->hasVeggies = false; - } } d->OG_vector = mem->getGroup("vector"); @@ -287,7 +193,6 @@ Maps::Maps(DFContextShared* _d) mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr); off.vein_worldconstruction_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr); - d->Inited = true; } @@ -313,52 +218,26 @@ bool Maps::Start() Process *p = d->owner; Private::t_offsets &off = d->offsets; - // get the map pointer - uint32_t x_array_loc = p->readDWord (off.map_offset); - if (!x_array_loc) + // is there a map? + //uint32_t x_array_loc = p->readDWord (off.map_offset); + if (!mdata->map) { return false; } // get the size - uint32_t mx, my, mz; - mx = d->x_block_count = p->readDWord (off.x_count_offset); - my = d->y_block_count = p->readDWord (off.y_count_offset); - mz = d->z_block_count = p->readDWord (off.z_count_offset); + uint32_t & mx = mdata->x_size_blocks; + uint32_t & my = mdata->y_size_blocks; + uint32_t & mz = mdata->z_size_blocks; // test for wrong map dimensions if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0) { - cout << hex << off.x_count_offset << " " << off.y_count_offset << " " << off.z_count_offset << endl; - cout << dec << mx << " "<< my << " "<< mz << endl; - throw Error::BadMapDimensions(mx, my); - //return false; + cerr << hex << &mx << " " << &my << " " << &mz << endl; + cerr << dec << mx << " "<< my << " "<< mz << endl; + return false; } - // read position of the region inside DF world - p->readDWord (off.region_x_offset, (uint32_t &) d->regionX); - p->readDWord (off.region_y_offset, (uint32_t &) d->regionY); - p->readDWord (off.region_z_offset, (uint32_t &) d->regionZ); - - // alloc array for pointers to all blocks - d->block = new uint32_t[mx*my*mz]; - uint32_t *temp_x = new uint32_t[mx]; - uint32_t *temp_y = new uint32_t[my]; - - p->read (x_array_loc, mx * sizeof (uint32_t), (uint8_t *) temp_x); - for (uint32_t x = 0; x < mx; x++) - { - p->read (temp_x[x], my * sizeof (uint32_t), (uint8_t *) temp_y); - // y -> map column - for (uint32_t y = 0; y < my; y++) - { - p->read (temp_y[y], - mz * sizeof (uint32_t), - (uint8_t *) (d->block + x*my*mz + y*mz)); - } - } - delete [] temp_x; - delete [] temp_y; d->Started = true; return true; } @@ -367,27 +246,22 @@ bool Maps::Start() 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; + x = mdata->x_size_blocks; + y = mdata->y_size_blocks; + z = mdata->z_size_blocks; } // getter for map position void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z) { MAPS_GUARD - x = d->regionX; - y = d->regionY; - z = d->regionZ; + x = mdata->x_area_offset; + y = mdata->y_area_offset; + z = mdata->z_area_offset; } bool Maps::Finish() { - if (d->block != NULL) - { - delete [] d->block; - d->block = NULL; - } return true; } @@ -395,40 +269,33 @@ bool Maps::Finish() * Block reading */ -bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z) +df_block* Maps::getBlock (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; -} - -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) + if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks) return 0; - return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; + return mdata->map[x][y][z]; } bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer) { MAPS_GUARD Process *p = d->owner; - uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; - if (addr) + df_block * block = getBlock(x,y,z); + if (block) { buffer->position = DFCoord(x,y,z); - p->read (addr + d->offsets.tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes); - p->read (addr + d->offsets.designation_offset, sizeof (buffer->designation), (uint8_t *) buffer->designation); - p->read (addr + d->offsets.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy); - p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices); - p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) buffer->global_feature); - p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)buffer->local_feature); - p->readDWord(addr + d->offsets.mystery, (uint32_t&)buffer->mystery); - buffer->origin = addr; - uint32_t addr_of_struct = p->readDWord(addr); - buffer->blockflags.whole = p->readDWord(addr_of_struct); + memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d)); + memcpy(buffer->designation,block->designation, sizeof(designations40d)); + memcpy(buffer->occupancy,block->occupancy, sizeof(occupancies40d)); + memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset)); + buffer->global_feature = block->global_feature; + buffer->local_feature = block->local_feature; + buffer->mystery = block->mystery; + // FIXME: not 64-bit safe + buffer->origin = (uint32_t) █ + //uint32_t addr_of_struct = p->readDWord(addr); + buffer->blockflags.whole = *(uint32_t*) block->flagarray; return true; } return false; @@ -441,10 +308,10 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->read (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer); + memcpy(buffer, block->tiletype, sizeof(tiletypes40d)); return true; } return false; @@ -453,10 +320,11 @@ 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->write (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer); + memcpy(block->tiletype, buffer, sizeof(tiletypes40d)); + //d->owner->write (addr + d->offsets.tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer); return true; } return false; @@ -465,33 +333,31 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf /* * Dirty bit */ - +//FIXME: this is bullshit 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - uint32_t addr_of_struct = p->readDWord(addr); - dirtybit = p->readDWord(addr_of_struct) & 1; + if(!block->flagarray) + return false; + dirtybit = ((t_blockflags *)block->flagarray)->bits.designated; return true; } return false; } - +//FIXME: this is bullshit 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - uint32_t addr_of_struct = p->readDWord(addr); - uint32_t dirtydword = p->readDWord(addr_of_struct); - dirtydword &= 0xFFFFFFFE; - dirtydword |= (uint32_t) dirtybit; - p->writeDWord (addr_of_struct, dirtydword); + if(!block->flagarray) + return false; + t_blockflags & flagz = (*(t_blockflags *)block->flagarray); + flagz.bits.designated = dirtybit; return true; } return false; @@ -500,28 +366,31 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) /* * Block flags */ +//FIXME: this is bullshit 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - uint32_t addr_of_struct = p->readDWord(addr); - blockflags.whole = p->readDWord(addr_of_struct); + if(!block->flagarray) + return false; + blockflags = *(t_blockflags *) block->flagarray; return true; } return false; } +//FIXME: this is bullshit 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - uint32_t addr_of_struct = p->readDWord(addr); - p->writeDWord (addr_of_struct, blockflags.whole); + if(!block->flagarray) + return false; + t_blockflags & bf = *(t_blockflags *) block->flagarray; + bf.whole = blockflags.whole; return true; } return false; @@ -533,10 +402,10 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->read (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer); + memcpy(buffer, block->designation, sizeof(designations40d)); return true; } return false; @@ -545,10 +414,10 @@ 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->write (addr + d->offsets.designation_offset, sizeof (designations40d), (uint8_t *) buffer); + memcpy(block->designation, buffer, sizeof(designations40d)); return true; } return false; @@ -560,10 +429,10 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->read (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer); + memcpy(buffer, block->occupancy, sizeof(occupancies40d)); return true; } return false; @@ -572,10 +441,10 @@ 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->write (addr + d->offsets.occupancy_offset, sizeof (occupancies40d), (uint8_t *) buffer); + memcpy(block->occupancy, buffer, sizeof(occupancies40d)); return true; } return false; @@ -587,13 +456,13 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b 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) + df_block * block = getBlock(x,y,z); + if (block) { if(temp1) - d->owner->read (addr + d->offsets.temperature1_offset, sizeof (t_temperatures), (uint8_t *) temp1); + memcpy(temp1, block->temperature_1, sizeof(t_temperatures)); if(temp2) - d->owner->read (addr + d->offsets.temperature2_offset, sizeof (t_temperatures), (uint8_t *) temp2); + memcpy(temp2, block->temperature_2, sizeof(t_temperatures)); return true; } return false; @@ -601,13 +470,13 @@ 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) + df_block * block = getBlock(x,y,z); + if (block) { if(temp1) - d->owner->write (addr + d->offsets.temperature1_offset, sizeof (t_temperatures), (uint8_t *) temp1); + memcpy(block->temperature_1, temp1, sizeof(t_temperatures)); if(temp2) - d->owner->write (addr + d->offsets.temperature2_offset, sizeof (t_temperatures), (uint8_t *) temp2); + memcpy(block->temperature_2, temp2, sizeof(t_temperatures)); return true; } return false; @@ -619,10 +488,10 @@ 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) + df_block * block = getBlock(x,y,z); + if (block) { - d->owner->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer); + memcpy(buffer, block->region_offset,sizeof(biome_indices40d)); return true; } return false; @@ -639,10 +508,6 @@ bool Maps::StopFeatures() } return false; } -typedef uint32_t _DWORD; -typedef uint8_t _BYTE; -#define BYTEn(x, n) (*((_BYTE*)&(x)+n)) -#define BYTE4(x) BYTEn(x, 4) bool Maps::StartFeatures() { @@ -650,7 +515,7 @@ bool Maps::StartFeatures() if(d->FeaturesStarted) return true; if(!d->hasFeatures) return false; // can't be used without a map! - if(!d->block) + if(!mdata->map) return false; Process * p = d->owner; @@ -658,18 +523,10 @@ bool Maps::StartFeatures() uint32_t base = 0; uint32_t global_feature_vector = 0; - if(d->usesWorldDataPtr) - { - uint32_t world = p->readDWord(off.world_data); - if(!world) return false; - base = p->readDWord(world + off.local_f_start); - global_feature_vector = p->readDWord(off.world_data) + off.global_vector; - } - else - { - base = p->readDWord(off.local_f_start); - global_feature_vector = off.global_vector; - } + uint32_t world = p->readDWord(off.world_data); + if(!world) return false; + base = p->readDWord(world + off.local_f_start); + global_feature_vector = p->readDWord(off.world_data) + off.global_vector; // deref pointer to the humongo-structure if(!base) @@ -686,16 +543,16 @@ bool Maps::StartFeatures() const uint32_t loc_sub_mat_offset = off.local_submaterial; const uint32_t sizeof_16vec = 16* sizeof_vec; - for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) - for(uint32_t blockY = 0; blockY < d->y_block_count; blockY ++) + for(uint32_t blockX = 0; blockX < mdata->x_size_blocks; blockX ++) + for(uint32_t blockY = 0; blockY < mdata->y_size_blocks; blockY ++) { // regionX and regionY are in embark squares! // we convert to full region tiles // this also works in adventure mode // region X coord - whole regions - uint32_t region_x = ( (blockX / 3) + d->regionX ) / 16; + uint32_t region_x = ( (blockX / 3) + mdata->x_area_offset ) / 16; // region Y coord - whole regions - uint32_t region_y = ( (blockY / 3) + d->regionY ) / 16; + uint32_t region_y = ( (blockY / 3) + mdata->y_area_offset ) / 16; uint32_t bigregion_x = region_x / 16; uint32_t bigregion_y = region_y / 16; uint32_t sub_x = region_x % 16; @@ -711,7 +568,7 @@ bool Maps::StartFeatures() if(loc_f_array16x16) { uint32_t feat_vector = loc_f_array16x16 + sizeof_16vec * sub_x + sizeof_vec * sub_y; - DfVector p_features(p, feat_vector); + DfVector p_features(feat_vector); uint32_t size = p_features.size(); DFCoord pc(blockX,blockY); std::vector tempvec; @@ -735,7 +592,7 @@ bool Maps::StartFeatures() t_feature tftemp; tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); tftemp.origin = cur_ptr; - string name = p->readClassName(p->readDWord( cur_ptr )); + string name = p->readClassName((void *)p->readDWord( cur_ptr )); if(name == "feature_init_deep_special_tubest") { tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset ); @@ -766,7 +623,7 @@ bool Maps::StartFeatures() const uint32_t global_feature_funcptr = off.global_funcptr; const uint32_t glob_main_mat_offset = off.global_material; const uint32_t glob_sub_mat_offset = off.global_submaterial; - DfVector p_features (p,global_feature_vector); + DfVector p_features (global_feature_vector); d->v_global_feature.clear(); uint32_t size = p_features.size(); @@ -780,7 +637,7 @@ bool Maps::StartFeatures() temp.discovered = false; // FIXME: use the memory_info cache mechanisms - string name = p->readClassName(p->readDWord( feat_ptr)); + string name = p->readClassName((void *)p->readDWord( feat_ptr)); if(name == "feature_init_underworld_from_layerst") { temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset ); @@ -822,12 +679,11 @@ std::vector * Maps::GetLocalFeatures(DFCoord coord) 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) global); - p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)local); + local = block->local_feature; + global = block->global_feature; return true; } return false; @@ -836,12 +692,11 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const 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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - p->writeWord(addr + d->offsets.global_feature_offset, (const uint16_t&) global); - p->writeWord(addr + d->offsets.local_feature_offset, (const uint16_t&) local); + block->local_feature = local; + block->global_feature = global; return true; } return false; @@ -898,11 +753,10 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** gl bool Maps::SetBlockLocalFeature(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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - p->writeWord(addr + d->offsets.local_feature_offset, (uint16_t&)local); + block->local_feature = local; return true; } return false; @@ -911,11 +765,10 @@ bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t loca bool Maps::SetBlockGlobalFeature(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) + df_block * block = getBlock(x,y,z); + if (block) { - Process * p = d->owner; - p->writeWord(addr + d->offsets.global_feature_offset, (uint16_t&)global); + block->global_feature = global; return true; } return false; @@ -924,108 +777,89 @@ bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t glo /* * Block events */ -bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * veins, vector * ices, vector *splatter, vector *grass, vector *constructions) +bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector * veins, vector * ices, vector *splatter, vector *grass, vector *constructions) { MAPS_GUARD - t_vein v; - t_frozenliquidvein fv; - t_spattervein sv; - t_grassvein gv; - t_worldconstruction wcv; Process* p = d->owner; - uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; + df_block * block = getBlock(x,y,z); if(veins) veins->clear(); if(ices) ices->clear(); if(splatter) splatter->clear(); - if(grass) splatter->clear(); + if(grass) grass->clear(); if(constructions) constructions->clear(); Private::t_offsets &off = d->offsets; - if (!addr) return false; - // veins are stored as a vector of pointers to veins - /*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/ - DfVector p_veins (p, addr + off.veinvector); - uint32_t size = p_veins.size(); + if (!block) + return false; + uint32_t size = block->block_events.size(); // read all veins for (uint32_t i = 0; i < size;i++) { retry: // read the vein pointer from the vector - uint32_t temp = p_veins[i]; - uint32_t type = p->readDWord(temp); - if(type == off.vein_mineral_vptr) + t_virtual * temp = block->block_events[i]; + void * type = temp->vptr; + if(type == (void *) off.vein_mineral_vptr) { if(!veins) continue; - // read the vein data (dereference pointer) - p->read (temp, sizeof(t_vein), (uint8_t *) &v); - v.address_of = temp; // store it in the vector - veins->push_back (v); + veins->push_back ((t_vein *) temp); } - else if(type == off.vein_ice_vptr) + else if(type == (void *) off.vein_ice_vptr) { if(!ices) continue; - // read the ice vein data (dereference pointer) - p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv); - fv.address_of = temp; - // store it in the vector - ices->push_back (fv); + ices->push_back ((t_frozenliquidvein *) temp); } - else if(type == off.vein_spatter_vptr) + else if(type == (void *) off.vein_spatter_vptr) { if(!splatter) continue; - // read the splatter vein data (dereference pointer) - p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv); - sv.address_of = temp; - // store it in the vector - splatter->push_back (sv); + splatter->push_back ( (t_spattervein *)temp); } - else if(type == off.vein_grass_vptr) + else if(type == (void *) off.vein_grass_vptr) { if(!grass) continue; - // read the splatter vein data (dereference pointer) - p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv); - gv.address_of = temp; - // store it in the vector - grass->push_back (gv); + grass->push_back ((t_grassvein *) temp); } - else if(type == off.vein_worldconstruction_vptr) + else if(type == (void *) off.vein_worldconstruction_vptr) { if(!constructions) continue; - // read the splatter vein data (dereference pointer) - p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv); - wcv.address_of = temp; - // store it in the vector - constructions->push_back (wcv); + constructions->push_back ((t_worldconstruction *) temp); } // previously unseen type of vein else { string cname = p->readClassName(type); + //string cname = typeid(*(blockevent *)temp).name(); + //Core::getInstance().con.printerr("%s\n",cname.c_str()); if(!off.vein_ice_vptr && cname == "block_square_event_frozen_liquidst") { off.vein_ice_vptr = type; + //Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_mineral_vptr &&cname == "block_square_event_mineralst") { off.vein_mineral_vptr = type; + //Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_spatter_vptr && cname == "block_square_event_material_spatterst") { off.vein_spatter_vptr = type; + //Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_grass_vptr && cname=="block_square_event_grassst") { off.vein_grass_vptr = type; + //Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_worldconstruction_vptr && cname=="block_square_event_world_constructionst") { off.vein_worldconstruction_vptr = type; + //Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } #ifdef DEBUG @@ -1043,77 +877,26 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * veins, return true; } -/* -Write the vein retreived using ReadVeins back to the address it was taken from. -*/ -bool Maps::WriteVein(t_vein *vein) +bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which) { - if(!vein) return false; + MAPS_GUARD Process* p = d->owner; - //Write each part individually. - p->writeDWord(vein->address_of + 4 , vein->type ); - p->write( vein->address_of + 8 , 32 , (uint8_t *)vein->assignment ); - p->writeDWord(vein->address_of + 40 , vein->flags ); - - return true; -} - - -/* -__int16 __userpurge GetGeologicalRegion(__int16 block_X, int X, __int16 block_Y, int block_addr, int Y) -{ - char bio_off; // al@1 - int tile_designation; // ecx@1 - __int64 corrected_x; // qax@1 - __int64 corrected_y; // qax@1 - int difY; // eax@9 - int difX; // edx@9 - signed __int64 bio_off_2; // qax@9 - signed __int64 bio_off_2_; // qtt@9 - __int16 result; // ax@23 - - corrected_x = reg_off_x + (block_X + (signed int)*(_WORD *)(block_addr + 0x90)) / 48; - *(_WORD *)X = ((BYTE4(corrected_x) & 0xF) + (_DWORD)corrected_x) >> 4; - corrected_y = reg_off_y + (block_Y + (signed int)*(_WORD *)(block_addr + 0x92)) / 48; - *(_WORD *)Y = ((BYTE4(corrected_y) & 0xF) + (_DWORD)corrected_y) >> 4; - tile_designation = *(_DWORD *)(block_addr + 4 * (block_Y + 16 * block_X) + 0x29C); - bio_off = 0; - if ( tile_designation & 0x20000 ) - bio_off = 1; - if ( tile_designation & 0x40000 ) - bio_off |= 2u; - if ( tile_designation & 0x80000 ) - bio_off |= 4u; - if ( tile_designation & 0x100000 ) - bio_off |= 8u; - bio_off_2 = *(_BYTE *)(bio_off + block_addr + 0x1D9C); - bio_off_2_ = bio_off_2; - difY = bio_off_2 / 3; - difX = bio_off_2_ % 3; - if ( !difX ) - --*(_WORD *)X; - if ( difX == 2 ) - ++*(_WORD *)X; - if ( !difY ) - --*(_WORD *)Y; - if ( difY == 2 ) - ++*(_WORD *)Y; - if ( *(_WORD *)X < 0 ) - *(_WORD *)X = 0; - if ( *(_WORD *)Y < 0 ) - *(_WORD *)Y = 0; - if ( *(_WORD *)X >= (_WORD)World_size ) - *(_WORD *)X = World_size - 1; - result = HIWORD(World_size); - if ( *(_WORD *)Y >= HIWORD(World_size) ) - { - result = HIWORD(World_size) - 1; - *(_WORD *)Y = HIWORD(World_size) - 1; - } - return result; + df_block * block = getBlock(x,y,z); + if(block) + { + for(int i = 0; i < block->block_events.size();i++) + { + if (block->block_events[i] == which) + { + free(which); + block->block_events.erase(block->block_events.begin() + i); + return true; + } + } + } + return false; } -*/ /* * Layer geology @@ -1128,25 +911,14 @@ bool Maps::ReadGeology (vector < vector >& assign) uint32_t regions, geoblocks_vector_addr; Private::t_offsets &off = d->offsets; // get world size - if(d->usesWorldDataPtr) - { - uint32_t world = p->readDWord(off.world_data); - p->readWord (world + off.world_size_x, worldSizeX); - p->readWord (world + off.world_size_y, worldSizeY); - regions = p->readDWord ( world + off.world_regions); // ptr2_region_array - geoblocks_vector_addr = world + off.world_geoblocks_vector; - } - else - { - p->readWord (off.world_size_x, worldSizeX); - p->readWord (off.world_size_y, worldSizeY); - // get pointer to first part of 2d array of regions - regions = p->readDWord (off.world_regions); // ptr2_region_array - geoblocks_vector_addr = off.world_geoblocks_vector; - } + uint32_t world = p->readDWord(off.world_data); + p->readWord (world + off.world_size_x, worldSizeX); + p->readWord (world + off.world_size_y, worldSizeY); + regions = p->readDWord ( world + off.world_regions); // ptr2_region_array + geoblocks_vector_addr = world + off.world_geoblocks_vector; // read the geoblock vector - DfVector geoblocks (d->d->p, geoblocks_vector_addr); + DfVector geoblocks (geoblocks_vector_addr); // iterate over 8 surrounding regions + local region for (int i = eNorthWest; i < eBiomeCount; i++) @@ -1155,10 +927,10 @@ bool Maps::ReadGeology (vector < vector >& assign) // regionX is in embark squares // regionX/16 is in 16x16 embark square regions // i provides -1 .. +1 offset from the current region - int bioRX = d->regionX / 16 + ((i % 3) - 1); + int bioRX = mdata->x_area_offset / 16 + ((i % 3) - 1); if (bioRX < 0) bioRX = 0; if (bioRX >= worldSizeX) bioRX = worldSizeX - 1; - int bioRY = d->regionY / 16 + ((i / 3) - 1); + int bioRY = mdata->y_area_offset / 16 + ((i / 3) - 1); if (bioRY < 0) bioRY = 0; if (bioRY >= worldSizeY) bioRY = worldSizeY - 1; @@ -1179,7 +951,7 @@ bool Maps::ReadGeology (vector < vector >& assign) /// geology blocks have a vector of layer descriptors // get the vector with pointer to layers - DfVector geolayers (p, geoblock_off + off.geolayer_geoblock_offset); // let's hope + DfVector geolayers (geoblock_off + off.geolayer_geoblock_offset); // let's hope // make sure we don't load crap assert (geolayers.size() > 0 && geolayers.size() <= 16); @@ -1215,7 +987,7 @@ bool Maps::ReadLocalFeatures( std::map > & lo return false; } -bool Maps::ReadGlobalFeatures( std::vector & features) +bool Maps::ReadGlobalFeatures( std::vector & features ) { StopFeatures(); StartFeatures(); @@ -1227,26 +999,14 @@ bool Maps::ReadGlobalFeatures( std::vector & features) return false; } -bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants) +bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector*& plants) { if(!d->hasVeggies || !d->Started) return false; - uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; - if(!addr) + df_block * block = getBlock(x,y,z); + if(!block) return false; - - dfh_plant shrubbery; - plants->clear(); - Private::t_offsets &off = d->offsets; - DfVector vegptrs(d->owner, addr + off.vegvector); - for(size_t i = 0; i < vegptrs.size(); i++) - { - d->d->readName(shrubbery.name,vegptrs[i]); - d->owner->read (vegptrs[i] + off.tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata); - shrubbery.address = vegptrs[i]; - plants->push_back(shrubbery); - } - if(plants->empty()) return false; + plants = &block->plants; return true; } diff --git a/library/modules/Maps_C.cpp b/library/modules/Maps_C.cpp deleted file mode 100644 index 9ebe6e4b2..000000000 --- a/library/modules/Maps_C.cpp +++ /dev/null @@ -1,706 +0,0 @@ -/* -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/DFPragma.h" -#include -#include -#include -#include - -using namespace std; - -#include "dfhack-c/DFTypes_C.h" -#include "dfhack-c/modules/Maps_C.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int Maps_Start(DFHackObject* maps) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->Start(); - } - - return -1; -} - -int Maps_Finish(DFHackObject* maps) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->Finish(); - } - - return -1; -} - -uint16_t* Maps_ReadGeology(DFHackObject* maps) -{ - if(maps != NULL) - { - std::vector < std::vector > geology; - - if(((DFHack::Maps*)maps)->ReadGeology(geology)) - { - uint16_t** buf = NULL; - uint32_t geoLength = 0; - - for(unsigned int i = 0; i < geology.size(); i++) - { - for(unsigned int j = 0; j < geology[i].size(); j++) - { - geoLength += geology[i].size(); - } - } - - ((*alloc_ushort_buffer_callback)(buf, geoLength)); - - if(buf != NULL) - { - uint16_t* bufCopyPtr = *buf; - - for(unsigned int i = 0; i < geology.size(); i++) - { - copy(geology[i].begin(), geology[i].end(), bufCopyPtr); - - bufCopyPtr += geology[i].size(); - } - - return *buf; - } - else - return NULL; - } - } - - return NULL; -} - -t_feature* Maps_ReadGlobalFeatures(DFHackObject* maps) -{ - if(maps != NULL) - { - std::vector featureVec; - - if(((DFHack::Maps*)maps)->ReadGlobalFeatures(featureVec)) - { - if(featureVec.size() <= 0) - return NULL; - - t_feature** buf = NULL; - - ((*alloc_feature_buffer_callback)(buf, featureVec.size())); - - if(buf != NULL) - { - copy(featureVec.begin(), featureVec.end(), *buf); - - return *buf; - } - else - return NULL; - } - else - return NULL; - } - - return NULL; -} - -c_featuremap_node* Maps_ReadLocalFeatures(DFHackObject* maps) -{ - if(maps != NULL) - { - std::map > local_features; - std::map >::iterator iterate; - uint32_t i; - - if(((DFHack::Maps*)maps)->ReadLocalFeatures(local_features)) - { - if(local_features.empty() == true) - return NULL; - - c_featuremap_node* featuremap; - uint32_t* featuremap_size = (uint32_t*)calloc(local_features.size(), sizeof(uint32_t)); - - for(i = 0, iterate = local_features.begin(); iterate != local_features.end(); i++, iterate++) - featuremap_size[i] = (*iterate).second.size(); - - ((*alloc_featuremap_buffer_callback)(&featuremap, featuremap_size, local_features.size())); - - free(featuremap_size); - - if(featuremap == NULL) - return NULL; - - for(i = 0, iterate = local_features.begin(); iterate != local_features.end(); i++, iterate++) - { - uint32_t j; - - featuremap[i].coordinate.comparate = (*iterate).first.comparate; - - for(j = 0; j < (*iterate).second.size(); j++) - featuremap[i].features[j] = *((*iterate).second[j]); - - //copy((*iterate).second.begin(), (*iterate).second.end(), featuremap[i].features); - featuremap[i].feature_length = (*iterate).second.size(); - } - - return featuremap; - } - else - return NULL; - } - - return NULL; -} - -void Maps_getSize(DFHackObject* maps, uint32_t* x, uint32_t* y, uint32_t* z) -{ - if(maps != NULL) - { - ((DFHack::Maps*)maps)->getSize(*x, *y, *z); - } -} - -void Maps_getPosition(DFHackObject* maps, int32_t* x, int32_t* y, int32_t* z) -{ - if(maps != NULL) - { - ((DFHack::Maps*)maps)->getPosition(*x, *y, *z); - } -} - -int Maps_isValidBlock(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->isValidBlock(x, y, z); - } - - return -1; -} - -uint32_t Maps_getBlockPtr(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->getBlockPtr(x, y, z); - } - - return 0; -} - -int Maps_ReadBlock40d(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, mapblock40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->ReadBlock40d(x, y, z, buffer); - } - - return -1; -} - -int Maps_ReadTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->ReadTileTypes(x, y, z, buffer); - } - - return -1; -} - -int Maps_WriteTileTypes(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, tiletypes40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->WriteTileTypes(x, y, z, buffer); - } - - return -1; -} - -int Maps_ReadDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->ReadDesignations(x, y, z, buffer); - } - - return -1; -} - -int Maps_WriteDesignations(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, designations40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->WriteDesignations(x, y, z, buffer); - } - - return -1; -} - -int Maps_ReadTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2) -{ - if(maps != NULL && temp1 != NULL && temp2 != NULL) - { - return ((DFHack::Maps*)maps)->ReadTemperatures(x, y, z, temp1, temp2); - } - - return -1; -} - -int Maps_WriteTemperatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_temperatures* temp1, t_temperatures* temp2) -{ - if(maps != NULL && temp1 != NULL && temp2 != NULL) - { - return ((DFHack::Maps*)maps)->WriteTemperatures(x, y, z, temp1, temp2); - } - - return -1; -} - -int Maps_ReadOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->ReadOccupancy(x, y, z, buffer); - } - - return -1; -} - -int Maps_WriteOccupancy(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, occupancies40d* buffer) -{ - if(maps != NULL && buffer != NULL) - { - return ((DFHack::Maps*)maps)->WriteOccupancy(x, y, z, buffer); - } - - return -1; -} - -int Maps_ReadDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int* dirtybit) -{ - if(maps != NULL) - { - bool bit; - - int result = ((DFHack::Maps*)maps)->ReadDirtyBit(x, y, z, bit); - - *dirtybit = bit; - - return result; - } - - return -1; -} - -int Maps_WriteDirtyBit(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int dirtybit) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->WriteDirtyBit(x, y, z, (bool)dirtybit); - } - - return -1; -} - -int Maps_ReadFeatures(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t* local, int16_t* global) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->ReadFeatures(x, y, z, *local, *global); - } - - return -1; -} - -int Maps_WriteLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, local); - } - - return -1; -} - -int Maps_WriteEmptyLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, -1); - } - - return -1; -} - -int Maps_WriteGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, int16_t local) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, local); - } - - return -1; -} - -int Maps_WriteEmptyGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, -1); - } - - return -1; -} - -int Maps_ReadBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags* blockflags) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->ReadBlockFlags(x, y, z, *blockflags); - } - - return -1; -} - -int Maps_WriteBlockFlags(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->WriteBlockFlags(x, y, z, blockflags); - } - - return -1; -} - -int Maps_ReadRegionOffsets(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, biome_indices40d* buffer) -{ - if(maps != NULL) - { - return ((DFHack::Maps*)maps)->ReadRegionOffsets(x, y, z, buffer); - } - - 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 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())); - - if(v_buf == NULL) - return NULL; - - 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 veins; - vector 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())); - - if(fv_buf == NULL) - return NULL; - - 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 veins; - vector 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())); - - if(sv_buf == NULL) - return NULL; - - copy(spatter_veins.begin(), spatter_veins.end(), sv_buf); - } - - return sv_buf; - } - else - return NULL; - } - - return NULL; -} - -t_grassvein* Maps_ReadGrassVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - if(alloc_grassvein_buffer_callback == NULL) - return NULL; - - vector veins; - vector grass_veins; - bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, 0, &grass_veins); - - if(result) - { - t_grassvein* gs_buf = NULL; - - if(grass_veins.size() > 0) - { - ((*alloc_grassvein_buffer_callback)(&gs_buf, grass_veins.size())); - - if(gs_buf == NULL) - return NULL; - - copy(grass_veins.begin(), grass_veins.end(), gs_buf); - } - - return gs_buf; - } - else - return NULL; - } - - return NULL; -} - -t_worldconstruction* Maps_ReadWorldConstructions(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps != NULL) - { - if(alloc_worldconstruction_buffer_callback == NULL) - return NULL; - - vector veins; - vector constructions; - bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, 0, 0, 0, &constructions); - - if(result) - { - t_worldconstruction* ct_buf = NULL; - - if(constructions.size() > 0) - { - ((*alloc_worldconstruction_buffer_callback)(&ct_buf, constructions.size())); - - if(ct_buf == NULL) - return NULL; - - copy(constructions.begin(), constructions.end(), ct_buf); - } - - return ct_buf; - } - else - return NULL; - } - - return NULL; -} - -int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_allveins* vein_struct) -{ - if(maps != NULL) - { - if(alloc_vein_buffer_callback == NULL || alloc_frozenliquidvein_buffer_callback == NULL || - alloc_spattervein_buffer_callback == NULL || alloc_grassvein_buffer_callback == NULL || - alloc_worldconstruction_buffer_callback == NULL) - return -1; - - vector veins; - vector frozen_veins; - vector spatter_veins; - vector grass_veins; - vector constructions; - - bool result = ((DFHack::Maps*)maps)->ReadVeins(x, y, z, &veins, &frozen_veins, &spatter_veins, &grass_veins, &constructions); - - if(result) - { - t_vein* v_buf = NULL; - t_frozenliquidvein* fv_buf = NULL; - t_spattervein* sv_buf = NULL; - t_grassvein* gs_buf = NULL; - t_worldconstruction* ct_buf = NULL; - - if(veins.size() > 0) - { - ((*alloc_vein_buffer_callback)(&v_buf, veins.size())); - - if(v_buf == NULL) - return -1; - - copy(veins.begin(), veins.end(), v_buf); - - vein_struct->veins = v_buf; - } - - if(frozen_veins.size() > 0) - { - ((*alloc_frozenliquidvein_buffer_callback)(&fv_buf, frozen_veins.size())); - - if(fv_buf == NULL) - return -1; - - copy(frozen_veins.begin(), frozen_veins.end(), fv_buf); - - vein_struct->frozen_veins = fv_buf; - } - - if(spatter_veins.size() > 0) - { - ((*alloc_spattervein_buffer_callback)(&sv_buf, spatter_veins.size())); - - if(sv_buf == NULL) - return -1; - - copy(spatter_veins.begin(), spatter_veins.end(), sv_buf); - - vein_struct->spatter_veins = sv_buf; - } - - if(grass_veins.size() > 0) - { - ((*alloc_grassvein_buffer_callback)(&gs_buf, grass_veins.size())); - - if(gs_buf == NULL) - return -1; - - copy(grass_veins.begin(), grass_veins.end(), gs_buf); - - vein_struct->grass_veins = gs_buf; - } - - if(constructions.size() > 0) - { - ((*alloc_worldconstruction_buffer_callback)(&ct_buf, constructions.size())); - - if(ct_buf == NULL) - return -1; - - copy(constructions.begin(), constructions.end(), ct_buf); - - vein_struct->world_constructions = ct_buf; - } - - return 1; - } - else - return 0; - } - - return -1; -} - -//FIXME: doesn't copy out the address and name variables! -dfh_plant* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) -{ - if(maps == NULL) - return NULL; - else - { - std::vector plants; - dfh_plant* buf = NULL; - bool result = ((DFHack::Maps*)maps)->ReadVegetation(x, y, z, &plants); - if(!result || plants.size() <= 0) - { - return NULL; - } - else - { - ((*alloc_tree_buffer_callback)(&buf, plants.size())); - if(buf == NULL) - return NULL; - copy(plants.begin(), plants.end(), buf); - return buf; - } - } - - return NULL; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 212fb0aaf..ae1c74be3 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -30,54 +31,76 @@ distribution. #include using namespace std; -#include "ContextShared.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Types.h" #include "dfhack/modules/Materials.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include #include "ModuleFactory.h" +#include using namespace DFHack; -Module* DFHack::createMaterials(DFContextShared * d) +Module* DFHack::createMaterials() { - return new Materials(d); + return new Materials(); } class Materials::Private { public: - DFContextShared *d; Process * owner; OffsetGroup * OG_Materials; - uint32_t vector_inorganic; uint32_t vector_organic_all; uint32_t vector_organic_plants; uint32_t vector_organic_trees; uint32_t vector_races; uint32_t vector_other; - /* - bool Inited; - bool Started; +/* + class t_inorganic_extras + { + public: + uint32_t offset_ore_types; + uint32_t offset_ore_chances; + uint32_t offset_strand_types; + uint32_t offset_strand_chances; + uint32_t offset_value; + uint32_t offset_wall_tile; + uint32_t offset_boulder_tile; + }; + + t_inorganic_extras i_ex; */ }; -Materials::Materials(DFContextShared * d_) +Materials::Materials() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; - d->owner = d_->p; - OffsetGroup *OG_Materials = d->OG_Materials = d->owner->getDescriptor()->getGroup("Materials"); + d->owner = c.p; + OffsetGroup *OG_Materials = d->OG_Materials = c.vinfo->getGroup("Materials"); { - d->vector_inorganic = OG_Materials->getAddress("inorganics"); + df_inorganic = (vector *) OG_Materials->getAddress("inorganics"); d->vector_organic_all = OG_Materials->getAddress ("organics_all"); d->vector_organic_plants = OG_Materials->getAddress ("organics_plants"); d->vector_organic_trees = OG_Materials->getAddress ("organics_trees"); d->vector_races = OG_Materials->getAddress("creature_type_vector"); } + /* + OffsetGroup *OG_Offsets = OG_Materials->getGroup("inorganic_extras"); + { + d->i_ex.offset_ore_types = OG_Offsets->getOffset("ore_types"); + d->i_ex.offset_ore_chances = OG_Offsets->getOffset("ore_chances"); + d->i_ex.offset_strand_types = OG_Offsets->getOffset("strand_types"); + d->i_ex.offset_strand_chances = OG_Offsets->getOffset("strand_chances"); + d->i_ex.offset_value = OG_Offsets->getOffset("value"); + d->i_ex.offset_wall_tile = OG_Offsets->getOffset("wall_tile"); + d->i_ex.offset_boulder_tile = OG_Offsets->getOffset("boulder_tile"); + } + */ } + Materials::~Materials() { delete d; @@ -85,112 +108,9 @@ Materials::~Materials() 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: - if ( a1 - || (signed int)a2 < 0 - || a2 >= (inorg_end - inorg_start) >> 2 - || (v13 = *(_DWORD *)(inorg_start + 4 * a2), !v13) ) - { - switch ( a1 ) - { - case 1: - sub_40FDD0("AMBER"); - break; - case 2: - sub_40FDD0("CORAL"); - break; - case 3: - sub_40FDD0("GLASS_GREEN"); - break; - case 4: - sub_40FDD0("GLASS_CLEAR"); - break; - case 5: - sub_40FDD0("GLASS_CRYSTAL"); - break; - case 6: - sub_40FDD0("WATER"); - break; - case 7: - sub_40FDD0("COAL"); - break; - case 8: - sub_40FDD0("POTASH"); - break; - case 9: - sub_40FDD0("ASH"); - break; - case 10: - sub_40FDD0("PEARLASH"); - break; - case 11: - sub_40FDD0("LYE"); - break; - case 12: - sub_40FDD0("MUD"); - break; - case 13: - sub_40FDD0("VOMIT"); - break; - case 14: - sub_40FDD0("SALT"); - break; - case 15: - sub_40FDD0("FILTH_B"); - break; - case 16: - sub_40FDD0("FILTH_Y"); - break; - case 17: - sub_40FDD0("UNKNOWN_SUBSTANCE"); - break; - case 18: - sub_40FDD0("GRIME"); - break; - default: - sub_40A070("NONE", 4u); - break; - } - result = sub_40A070("NONE", 4u); - if ( a1 == 7 ) - { - result = a2; - if ( a2 ) - { - if ( a2 == 1 ) - result = sub_40A070("CHARCOAL", 8u); - } - else - { - result = sub_40A070("COKE", 4u); - } - } - } - else - { - sub_40A070("INORGANIC", 9u); - result = sub_409CA0(v13, 0, -1); - } - } - -*/ - /* bool API::ReadInorganicMaterials (vector & inorganic) { @@ -226,17 +146,43 @@ bool API::ReadInorganicMaterials (vector & inorganic) } */ +t_matgloss::t_matgloss() +{ + fore = 0; + back = 0; + bright = 0; + + value = 0; + wall_tile = 0; + boulder_tile = 0; +} + +bool t_matglossInorganic::isOre() +{ + if (!ore_chances.empty()) + return true; + if (!strand_chances.empty()) + return true; + return false; +} +// FIXME: implement properly +bool t_matglossInorganic::isGem() +{ + return (wall_tile == 15 && boulder_tile == 7); +} + // good for now inline bool ReadNamesOnly(Process* p, uint32_t address, vector & names) { - DfVector p_matgloss (p, address); + DfVector p_matgloss (address); uint32_t size = p_matgloss.size(); names.clear(); names.reserve (size); for (uint32_t i = 0; i < size;i++) { t_matgloss mat; - p->readSTLString (p_matgloss[i], mat.id, 128); + mat.id = *(std::string *)p_matgloss[i]; + //p->readSTLString (p_matgloss[i], mat.id, 128); names.push_back(mat); } return true; @@ -245,20 +191,26 @@ inline bool ReadNamesOnly(Process* p, uint32_t address, vector & nam bool Materials::ReadInorganicMaterials (void) { Process * p = d->owner; - DfVector p_matgloss (p, d->vector_inorganic); - uint32_t size = p_matgloss.size(); + uint32_t size = df_inorganic->size(); inorganic.clear(); inorganic.reserve (size); for (uint32_t i = 0; i < size;i++) { - t_matgloss mat; - - p->readSTLString (p_matgloss[i], mat.id, 128); + df_inorganic_material * orig = df_inorganic->at(i); + t_matglossInorganic mat; + mat.id = orig->Inorganic_ID; + mat.name = orig->STONE_NAME; //p->readSTLString (p_matgloss[i] + mat_name, mat.name, 128); - mat.name[0] = 0; - mat.fore = 0; - mat.back = 0; - mat.bright = 0; + + mat.ore_types = orig->METAL_ORE_matID; + mat.ore_chances = orig->METAL_ORE_prob; + mat.strand_types = orig->THREAD_METAL_matID; + mat.strand_chances = orig->THREAD_METAL_prob; + mat.value = orig->MATERIAL_VALUE; + mat.wall_tile = orig->TILE; + mat.boulder_tile = orig->ITEM_SYMBOL; + mat.bright = orig->BASIC_COLOR_bright; + mat.fore = orig->BASIC_COLOR_foreground; inorganic.push_back(mat); } return true; @@ -290,17 +242,17 @@ bool Materials::ReadOthers(void) Process * p = d->owner; uint32_t matBase = d->OG_Materials->getAddress ("other"); uint32_t i = 0; - uint32_t ptr; + std::string * ptr; other.clear(); while(1) { t_matglossOther mat; - ptr = p->readDWord(matBase + i*4); + ptr = (std::string *) p->readDWord(matBase + i*4); if(ptr==0) break; - p->readSTLString(ptr, mat.rawname, sizeof(mat.rawname)); + mat.id = *ptr; other.push_back(mat); i++; } @@ -311,7 +263,7 @@ bool Materials::ReadDescriptorColors (void) { Process * p = d->owner; OffsetGroup * OG_Descriptors = p->getDescriptor()->getGroup("Materials")->getGroup("descriptors"); - DfVector p_colors (p, OG_Descriptors->getAddress ("colors_vector")); + DfVector p_colors (OG_Descriptors->getAddress ("colors_vector")); uint32_t size = p_colors.size(); color.clear(); @@ -321,8 +273,8 @@ bool Materials::ReadDescriptorColors (void) for (uint32_t i = 0; i < size;i++) { t_descriptor_color col; - p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("rawname"), col.id, 128); - p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("name"), col.name, 128); + col.id = p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("rawname") ); + col.name = p->readSTLString (p_colors[i] + OG_Descriptors->getOffset ("name") ); col.red = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_r") ); col.green = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_v") ); col.blue = p->readFloat( p_colors[i] + OG_Descriptors->getOffset ("color_b") ); @@ -340,7 +292,7 @@ bool Materials::ReadCreatureTypesEx (void) uint32_t sizeof_string = OG_string->getHexValue ("sizeof"); OffsetGroup * OG_Mats = mem->getGroup("Materials"); - DfVector p_races (p, OG_Mats->getAddress ("creature_type_vector")); + DfVector p_races (OG_Mats->getAddress ("creature_type_vector")); OffsetGroup * OG_Creature = OG_Mats->getGroup("creature"); uint32_t castes_vector_offset = OG_Creature->getOffset ("caste_vector"); @@ -397,53 +349,53 @@ bool Materials::ReadCreatureTypesEx (void) // 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.id = p->readSTLString (p_races[i]); 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 p_castes(p, p_races[i] + castes_vector_offset); + DfVector p_castes(p_races[i] + castes_vector_offset); sizecas = p_castes.size(); for (uint32_t j = 0; j < sizecas;j++) { /* caste name */ t_creaturecaste caste; uint32_t caste_start = p_castes[j]; - p->readSTLString (caste_start, caste.rawname, sizeof(caste.rawname)); - p->readSTLString (caste_start + sizeof_string, caste.singular, sizeof(caste.singular)); - p->readSTLString (caste_start + 2 * sizeof_string, caste.plural, sizeof(caste.plural)); - p->readSTLString (caste_start + 3 * sizeof_string, caste.adjective, sizeof(caste.adjective)); + caste.id = p->readSTLString (caste_start); + caste.singular = p->readSTLString (caste_start + sizeof_string); + caste.plural = p->readSTLString (caste_start + 2 * sizeof_string); + caste.adjective = p->readSTLString (caste_start + 3 * sizeof_string); //cout << "Caste " << caste.rawname << " " << caste.singular << ": 0x" << hex << caste_start << endl; if(have_advanced) { /* color mod reading */ // Caste + offset > color mod vector - DfVector p_colormod(p, caste_start + caste_colormod_offset); + DfVector p_colormod(caste_start + caste_colormod_offset); sizecolormod = p_colormod.size(); caste.ColorModifier.resize(sizecolormod); for(uint32_t k = 0; k < sizecolormod;k++) { // color mod [0] -> color list - DfVector p_colorlist(p, p_colormod[k]); + DfVector p_colorlist(p_colormod[k]); sizecolorlist = p_colorlist.size(); caste.ColorModifier[k].colorlist.resize(sizecolorlist); for(uint32_t l = 0; l < sizecolorlist; l++) caste.ColorModifier[k].colorlist[l] = p_colorlist[l]; // color mod [color_modifier_part_offset] = string part - p->readSTLString( p_colormod[k] + color_modifier_part_offset, caste.ColorModifier[k].part, sizeof(caste.ColorModifier[k].part)); + caste.ColorModifier[k].part = p->readSTLString( p_colormod[k] + color_modifier_part_offset); caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset ); caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset ); } /* body parts */ - DfVector p_bodypart(p, caste_start + caste_bodypart_offset); + DfVector p_bodypart(caste_start + caste_bodypart_offset); caste.bodypart.empty(); sizebp = p_bodypart.size(); for(uint32_t k = 0; k < sizebp; k++) { t_bodypart part; - p->readSTLString (p_bodypart[k] + bodypart_id_offset, part.id, sizeof(part.id)); - p->readSTLString (p_bodypart[k] + bodypart_category_offset, part.category, sizeof(part.category)); + part.id = p->readSTLString (p_bodypart[k] + bodypart_id_offset); + part.category = p->readSTLString (p_bodypart[k] + bodypart_category_offset); caste.bodypart.push_back(part); } p->read(caste_start + caste_attributes_offset, sizeof(t_attrib) * NUM_CREAT_ATTRIBS, (uint8_t *)&caste.strength); @@ -454,11 +406,11 @@ bool Materials::ReadCreatureTypesEx (void) } mat.castes.push_back(caste); } - DfVector p_extract(p, p_races[i] + extract_vector_offset); + DfVector p_extract(p_races[i] + extract_vector_offset); for(uint32_t j = 0; j < p_extract.size(); j++) { t_creatureextract extract; - p->readSTLString( p_extract[j], extract.rawname, sizeof(extract.rawname)); + extract.id = p->readSTLString( p_extract[j] ); mat.extract.push_back(extract); } raceEx.push_back(mat); @@ -505,14 +457,14 @@ std::string Materials::getDescription(const t_material & mat) return "any"; if(mat.subIndex>=this->raceEx.size()) return "stuff"; - return this->raceEx[mat.subIndex].rawname; + return this->raceEx[mat.subIndex].id; } else { if (mat.index==-1) - return std::string(this->other[mat.subIndex].rawname); + return std::string(this->other[mat.subIndex].id); else - return std::string(this->other[mat.subIndex].rawname) + " derivate"; + return std::string(this->other[mat.subIndex].id) + " derivate"; } } else @@ -529,9 +481,9 @@ std::string Materials::getDescription(const t_material & mat) typeC -=19; if ((typeC<0) || (typeC>=this->raceEx[mat.index].extract.size())) { - return string(this->raceEx[mat.index].rawname).append(" extract"); + return string(this->raceEx[mat.index].id).append(" extract"); } - return std::string(this->raceEx[mat.index].rawname).append(" ").append(this->raceEx[mat.index].extract[typeC].rawname); + return std::string(this->raceEx[mat.index].id).append(" ").append(this->raceEx[mat.index].extract[typeC].id); } } else @@ -591,4 +543,4 @@ std::string Materials::getType(const t_material & mat) { return "organic"; } -} \ No newline at end of file +} diff --git a/library/modules/Materials_C.cpp b/library/modules/Materials_C.cpp deleted file mode 100644 index 5e95f715b..000000000 --- a/library/modules/Materials_C.cpp +++ /dev/null @@ -1,636 +0,0 @@ -/* -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 -#include -#include -#include -#include -using namespace std; -#include "dfhack-c/modules/Materials_C.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void BuildDescriptorList(std::vector & src, c_creaturetype_descriptor** dest) -{ - c_creaturetype_descriptor* descriptor = NULL; - - descriptor = (c_creaturetype_descriptor*)calloc(src.size(), sizeof(c_creaturetype_descriptor)); - - for(uint32_t i = 0; i < src.size(); i++) - { - uint32_t castes_size = src[i].castes.size(); - c_creaturetype_descriptor* current = &descriptor[i]; - - current->castesCount = castes_size; - current->caste_descriptors = (c_creaturecaste_descriptor*)calloc(castes_size, sizeof(c_creaturecaste_descriptor)); - - for(uint32_t j = 0; j < castes_size; j++) - { - uint32_t color_size = src[i].castes[j].ColorModifier.size(); - c_creaturecaste_descriptor* current_caste = ¤t->caste_descriptors[j]; - - current_caste->colorModifierLength = color_size; - current_caste->color_descriptors = (c_colormodifier_descriptor*)calloc(color_size, sizeof(c_colormodifier_descriptor)); - - for(uint32_t k = 0; k < color_size; k++) - { - c_colormodifier_descriptor* current_color = ¤t_caste->color_descriptors[k]; - - current_color->colorlistLength = src[i].castes[j].ColorModifier[k].colorlist.size(); - } - - current_caste->bodypartLength = src[i].castes[j].bodypart.size(); - } - - current->extractCount = src[i].extract.size(); - } - - *dest = descriptor; -} - -void FreeDescriptorList(c_creaturetype_descriptor* d, uint32_t length) -{ - for(uint32_t i = 0; i < length; i++) - { - c_creaturetype_descriptor* desc = &d[i]; - - for(uint32_t j = 0; j < desc->castesCount; j++) - free(desc->caste_descriptors[j].color_descriptors); - - free(desc->caste_descriptors); - } - - free(d); -} - -int CreatureTypeConvert(std::vector & src, c_creaturetype** out_buf) -{ - if(src.size() <= 0) - return 0; - else if(alloc_creaturetype_buffer_callback == NULL) - return -1; - else - { - c_creaturetype_descriptor* descriptor; - c_creaturetype* buf; - - BuildDescriptorList(src, &descriptor); - - ((*alloc_creaturetype_buffer_callback)(out_buf, descriptor, src.size())); - - FreeDescriptorList(descriptor, src.size()); - - if(out_buf == NULL) - return -1; - - buf = out_buf[0]; - - for(uint32_t i = 0; i < src.size(); i++) - { - c_creaturetype* current = &(buf[i]); - - memset(current->rawname, '\0', 128); - strncpy(current->rawname, src[i].rawname, 128); - - for(uint32_t j = 0; j < current->castesCount; j++) - { - c_creaturecaste* current_caste = ¤t->castes[j]; - t_creaturecaste* src_caste = &src[i].castes[j]; - - memset(current_caste->rawname, '\0', 128); - memset(current_caste->singular, '\0', 128); - memset(current_caste->plural, '\0', 128); - memset(current_caste->adjective, '\0', 128); - - strncpy(current_caste->rawname, src_caste->rawname, 128); - strncpy(current_caste->singular, src_caste->singular, 128); - strncpy(current_caste->plural, src_caste->plural, 128); - strncpy(current_caste->adjective, src_caste->adjective, 128); - - for(uint32_t k = 0; k < src[i].castes[j].ColorModifier.size(); k++) - { - c_colormodifier* current_color = ¤t_caste->colorModifier[k]; - - memset(current_color->part, '\0', 128); - strncpy(current_color->part, src_caste->ColorModifier[k].part, 128); - - copy(src_caste->ColorModifier[k].colorlist.begin(), src_caste->ColorModifier[k].colorlist.end(), current_color->colorlist); - current_color->colorlistLength = src_caste->ColorModifier[k].colorlist.size(); - - current_color->startdate = src_caste->ColorModifier[k].startdate; - current_color->enddate = src_caste->ColorModifier[k].enddate; - } - - current_caste->colorModifierLength = src_caste->ColorModifier.size(); - - copy(src_caste->bodypart.begin(), src_caste->bodypart.end(), current_caste->bodypart); - current_caste->bodypartLength = src_caste->bodypart.size(); - - current_caste->strength = src_caste->strength; - current_caste->agility = src_caste->agility; - current_caste->toughness = src_caste->toughness; - current_caste->endurance = src_caste->endurance; - current_caste->recuperation = src_caste->recuperation; - current_caste->disease_resistance = src_caste->disease_resistance; - current_caste->analytical_ability = src_caste->analytical_ability; - current_caste->focus = src_caste->focus; - current_caste->willpower = src_caste->willpower; - current_caste->creativity = src_caste->creativity; - current_caste->intuition = src_caste->intuition; - current_caste->patience = src_caste->patience; - current_caste->memory = src_caste->memory; - current_caste->linguistic_ability = src_caste->linguistic_ability; - current_caste->spatial_sense = src_caste->spatial_sense; - current_caste->musicality = src_caste->musicality; - current_caste->kinesthetic_sense = src_caste->kinesthetic_sense; - } - - copy(src[i].extract.begin(), src[i].extract.end(), current->extract); - current->extractCount = src[i].extract.size(); - - current->tile_character = src[i].tile_character; - - current->tilecolor.fore = src[i].tilecolor.fore; - current->tilecolor.back = src[i].tilecolor.back; - current->tilecolor.bright = src[i].tilecolor.bright; - } - - return 1; - } -} - - -int Materials_ReadInorganicMaterials(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadInorganicMaterials() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadOrganicMaterials(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadOrganicMaterials() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadWoodMaterials(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadWoodMaterials() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadPlantMaterials(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadPlantMaterials() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadCreatureTypes(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadCreatureTypes() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadCreatureTypesEx(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadCreatureTypesEx() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadDescriptorColors(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadDescriptorColors() == true) - return 1; - else - return 0; - } - - return -1; -} - -int Materials_ReadOthers(DFHackObject* mat) -{ - if(mat != NULL) - { - if(((DFHack::Materials*)mat)->ReadOthers() == true) - return 1; - else - return 0; - } - - return -1; -} - -void Materials_ReadAllMaterials(DFHackObject* mat) -{ - if(mat != NULL) - { - ((DFHack::Materials*)mat)->ReadAllMaterials(); - } -} - -const char* Materials_getType(DFHackObject* mat, t_material* material) -{ - if(mat != NULL) - { - std::string type = ((DFHack::Materials*)mat)->getType(*material); - - return type.c_str(); - } - - return "\0"; -} - -const char* Materials_getDescription(DFHackObject* mat, t_material* material) -{ - if(mat != NULL) - { - std::string description = ((DFHack::Materials*)mat)->getDescription(*material); - - return description.c_str(); - } - - return "\0"; -} - -//vector size getters - -int Materials_getInorganicSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->inorganic.size(); - } - - return -1; -} - -int Materials_getOrganicSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->organic.size(); - } - - return -1; -} - -int Materials_getTreeSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->tree.size(); - } - - return -1; -} - -int Materials_getPlantSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->plant.size(); - } - - return -1; -} - -int Materials_getRaceSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->race.size(); - } - - return -1; -} - -int Materials_getRaceExSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->raceEx.size(); - } - - return -1; -} - -int Materials_getColorSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->color.size(); - } - - return -1; -} - -int Materials_getOtherSize(DFHackObject* mat) -{ - if(mat != NULL) - { - return ((DFHack::Materials*)mat)->other.size(); - } - - return -1; -} - -//vector getters - -t_matgloss* Materials_getInorganic(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->inorganic.size() > 0) - { - t_matgloss* buf = NULL; - - if(alloc_matgloss_buffer_callback == NULL) - return NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->inorganic.size())); - - if(buf != NULL) - { - copy(materials->inorganic.begin(), materials->inorganic.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matgloss* Materials_getOrganic(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->organic.size() > 0) - { - t_matgloss* buf = NULL; - - if(alloc_matgloss_buffer_callback == NULL) - return NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->organic.size())); - - if(buf != NULL) - { - copy(materials->organic.begin(), materials->organic.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matgloss* Materials_getTree(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->tree.size() > 0) - { - t_matgloss* buf = NULL; - - if(alloc_matgloss_buffer_callback == NULL) - return NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->tree.size())); - - if(buf != NULL) - { - copy(materials->tree.begin(), materials->tree.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matgloss* Materials_getPlant(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->plant.size() > 0) - { - t_matgloss* buf = NULL; - - if(alloc_matgloss_buffer_callback == NULL) - return NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->plant.size())); - - if(buf != NULL) - { - copy(materials->plant.begin(), materials->plant.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matgloss* Materials_getRace(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->race.size() > 0) - { - t_matgloss* buf = NULL; - - if(alloc_matgloss_buffer_callback == NULL) - return NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->race.size())); - - if(buf != NULL) - { - copy(materials->race.begin(), materials->race.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -//race_ex getter goes here... -c_creaturetype* Materials_getRaceEx(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - int matSize = materials->raceEx.size(); - - if(matSize > 0) - { - c_creaturetype* buf = NULL; - - CreatureTypeConvert(((DFHack::Materials*)mat)->raceEx, &buf); - - return buf; - } - } - - return NULL; -} - -t_descriptor_color* Materials_getColor(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->color.size() > 0) - { - t_descriptor_color* buf = NULL; - - ((*alloc_descriptor_buffer_callback)(&buf, materials->color.size())); - - if(buf != NULL) - { - copy(materials->color.begin(), materials->color.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matglossOther* Materials_getOther(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->other.size() > 0) - { - t_matglossOther* buf = NULL; - - ((*alloc_matgloss_other_buffer_callback)(&buf, materials->other.size())); - - if(buf != NULL) - { - copy(materials->other.begin(), materials->other.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -t_matgloss* Materials_getAllDesc(DFHackObject* mat) -{ - if(mat != NULL) - { - DFHack::Materials* materials = (DFHack::Materials*)mat; - - if(materials->alldesc.size() > 0) - { - t_matgloss* buf = NULL; - - ((*alloc_matgloss_buffer_callback)(&buf, materials->alldesc.size())); - - if(buf != NULL) - { - copy(materials->race.begin(), materials->alldesc.end(), buf); - - return buf; - } - } - } - - return NULL; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Vegetation_C.cpp b/library/modules/Notes.cpp similarity index 60% rename from library/modules/Vegetation_C.cpp rename to library/modules/Notes.cpp index 58607dca6..293077a5d 100644 --- a/library/modules/Vegetation_C.cpp +++ b/library/modules/Notes.cpp @@ -1,6 +1,6 @@ /* www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild +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 @@ -23,50 +23,41 @@ distribution. */ #include "Internal.h" -#include + #include +#include +#include using namespace std; -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Vegetation.h" -#include "dfhack-c/modules/Vegetation_C.h" - +#include "dfhack/VersionInfo.h" +#include "dfhack/Types.h" +#include "dfhack/Error.h" +#include "dfhack/Process.h" +#include "ModuleFactory.h" +#include "dfhack/Core.h" +#include "dfhack/modules/Notes.h" using namespace DFHack; -#ifdef __cplusplus -extern "C" { -#endif - -int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees) +Module* DFHack::createNotes() { - if(veg != NULL) - { - return ((DFHack::Vegetation*)veg)->Start(*numTrees); - } - - return -1; + return new Notes(); } -int Vegetation_Finish(DFHackObject* veg) +Notes::Notes() { - if(veg != NULL) - { - return ((DFHack::Vegetation*)veg)->Finish(); - } - - return -1; -} + Core & c = Core::getInstance(); -int Vegetation_Read(DFHackObject* veg, const uint32_t index, dfh_plant* shrubbery) -{ - if(veg != NULL) + notes = NULL; + VersionInfo * mem = c.vinfo; + try { - return ((DFHack::Vegetation*)veg)->Read(index, *shrubbery); - } - - return -1; -} + OffsetGroup * OG_Notes = mem->getGroup("Notes"); -#ifdef __cplusplus + notes = (std::vector*) OG_Notes->getAddress("vector"); + } + catch(DFHack::Error::AllMemdef &e) + { + notes = NULL; + cerr << "Notes not available... " << e.what() << endl; + } } -#endif diff --git a/library/modules/Translation.cpp b/library/modules/Translation.cpp index 921b6cece..057b24ae2 100644 --- a/library/modules/Translation.cpp +++ b/library/modules/Translation.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -30,18 +30,18 @@ distribution. #include using namespace std; -#include "ContextShared.h" #include "dfhack/modules/Translation.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Types.h" #include "ModuleFactory.h" +#include using namespace DFHack; -Module* DFHack::createTranslation(DFContextShared * d) +Module* DFHack::createTranslation() { - return new Translation(d); + return new Translation(); } struct Translation::Private @@ -54,23 +54,33 @@ struct Translation::Private // translation Dicts dicts; - DFContextShared *d; bool Inited; bool Started; + // names + uint32_t name_firstname_offset; + uint32_t name_nickname_offset; + uint32_t name_words_offset; + uint32_t name_parts_offset; + uint32_t name_language_offset; + uint32_t name_set_offset; + bool namesInited; + bool namesFailed; }; -Translation::Translation(DFContextShared * d_) +Translation::Translation() { + Core & c = Core::getInstance(); d = new Private; - d->d = d_; d->Inited = d->Started = false; - OffsetGroup * OG_Translation = d->d->offset_descriptor->getGroup("Translations"); - OffsetGroup * OG_String = d->d->offset_descriptor->getGroup("string"); + OffsetGroup * OG_Translation = c.vinfo->getGroup("Translations"); + OffsetGroup * OG_String = c.vinfo->getGroup("string"); d->genericAddress = OG_Translation->getAddress ("language_vector"); d->transAddress = OG_Translation->getAddress ("translation_vector"); d->word_table_offset = OG_Translation->getOffset ("word_table"); d->sizeof_string = OG_String->getHexValue ("sizeof"); d->Inited = true; + d->namesInited = false; + d->namesFailed = false; } Translation::~Translation() @@ -82,12 +92,13 @@ Translation::~Translation() bool Translation::Start() { + Core & c = Core::getInstance(); if(!d->Inited) return false; - Process * p = d->d->p; + Process * p = c.p; Finish(); - DfVector genericVec (p, d->genericAddress); - DfVector transVec (p, d->transAddress); + DfVector genericVec (d->genericAddress); + DfVector transVec (d->transAddress); DFDict & translations = d->dicts.translations; DFDict & foreign_languages = d->dicts.foreign_languages; @@ -95,10 +106,10 @@ bool Translation::Start() for (uint32_t i = 0;i < genericVec.size();i++) { uint32_t genericNamePtr = genericVec.at(i); - for(int i=0; i<10;i++) + for(int j=0; j<10;i++) { - string word = p->readSTLString (genericNamePtr + i * d->sizeof_string); - translations[i].push_back (word); + string word = p->readSTLString (genericNamePtr + j * d->sizeof_string); + translations[j].push_back (word); } } @@ -106,7 +117,7 @@ bool Translation::Start() for (uint32_t i = 0; i < transVec.size();i++) { uint32_t transPtr = transVec.at(i); - DfVector trans_names_vec (p, transPtr + d->word_table_offset); + DfVector trans_names_vec (transPtr + d->word_table_offset); for (uint32_t j = 0;j < trans_names_vec.size();j++) { uint32_t transNamePtr = trans_names_vec.at(j); @@ -135,6 +146,69 @@ Dicts * Translation::getDicts() return 0; } +bool Translation::InitReadNames() +{ + Core & c = Core::getInstance(); + try + { + OffsetGroup * OG = c.vinfo->getGroup("name"); + d->name_firstname_offset = OG->getOffset("first"); + d->name_nickname_offset = OG->getOffset("nick"); + d->name_words_offset = OG->getOffset("second_words"); + d->name_parts_offset = OG->getOffset("parts_of_speech"); + d->name_language_offset = OG->getOffset("language"); + d->name_set_offset = OG->getOffset("has_name"); + } + catch(exception &) + { + d->namesFailed = true; + return false; + } + d->namesInited = true; + return true; +} + +bool Translation::readName(t_name & name, uint32_t address) +{ + Core & c = Core::getInstance(); + Process * p = c.p; + if(d->namesFailed) + { + return false; + } + if(!d->namesInited) + { + if(!InitReadNames()) return false; + } + p->readSTLString(address + d->name_firstname_offset , name.first_name, 128); + p->readSTLString(address + d->name_nickname_offset , name.nickname, 128); + p->read(address + d->name_words_offset, 7*4, (uint8_t *)name.words); + p->read(address + d->name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech); + name.language = p->readDWord(address + d->name_language_offset); + name.has_name = p->readByte(address + d->name_set_offset); + return true; +} + +bool Translation::copyName(uint32_t address, uint32_t target) +{ + uint8_t buf[28]; + + if (address == target) + return true; + Core & c = Core::getInstance(); + Process * p = c.p; + + p->copySTLString(address + d->name_firstname_offset, target + d->name_firstname_offset); + p->copySTLString(address + d->name_nickname_offset, target + d->name_nickname_offset); + p->read(address + d->name_words_offset, 7*4, buf); + p->write(target + d->name_words_offset, 7*4, buf); + p->read(address + d->name_parts_offset, 7*2, buf); + p->write(target + d->name_parts_offset, 7*2, buf); + p->writeDWord(target + d->name_language_offset, p->readDWord(address + d->name_language_offset)); + p->writeByte(target + d->name_set_offset, p->readByte(address + d->name_set_offset)); + return true; +} + string Translation::TranslateName(const t_name &name, bool inEnglish) { string out; diff --git a/library/modules/Translation_C.cpp b/library/modules/Translation_C.cpp deleted file mode 100644 index 23b07b24c..000000000 --- a/library/modules/Translation_C.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -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 "Internal.h" - -#include -#include -#include -using namespace std; - - -#include "dfhack/DFTypes.h" -#include "dfhack/modules/Translation.h" -#include "dfhack-c/modules/Translation_C.h" - -using namespace DFHack; - -#ifdef __cplusplus -extern "C" { -#endif - -int Translation_Start(DFHackObject* trans) -{ - if(trans != NULL) - { - return ((DFHack::Translation*)trans)->Start(); - } - - return -1; -} - -int Translation_Finish(DFHackObject* trans) -{ - if(trans != NULL) - { - return ((DFHack::Translation*)trans)->Finish(); - } - - return -1; -} - -char* Translation_TranslateNameEnglish(DFHackObject* trans, const DFHack::t_name* name) -{ - if(trans != NULL) - { - std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, true); - - if(nameTrans.size() > 0) - { - char* buf = NULL; - - (*alloc_char_buffer_callback)(&buf, nameTrans.size()); - - if(buf != NULL) - { - size_t len = nameTrans.copy(buf, nameTrans.size()); - - if(len > 0) - buf[len] = '\0'; - else - buf[0] = '\0'; - } - - return buf; - } - else - return NULL; - } - - return NULL; -} - -char* Translation_TranslateNameNonEnglish(DFHackObject* trans, const DFHack::t_name* name) -{ - if(trans != NULL) - { - std::string nameTrans = ((DFHack::Translation*)trans)->TranslateName(*name, false); - - if(nameTrans.size() > 0) - { - char* buf = NULL; - - (*alloc_char_buffer_callback)(&buf, nameTrans.size()); - - if(buf != NULL) - { - size_t len = nameTrans.copy(buf, nameTrans.size()); - - if(len > 0) - buf[len] = '\0'; - else - buf[0] = '\0'; - } - - return buf; - } - else - return NULL; - } - - return NULL; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/Vegetation.cpp b/library/modules/Vegetation.cpp index eb662da60..b581928a9 100644 --- a/library/modules/Vegetation.cpp +++ b/library/modules/Vegetation.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include @@ -29,95 +30,37 @@ distribution. #include using namespace std; -#include "ContextShared.h" - #include "dfhack/VersionInfo.h" -#include "dfhack/DFProcess.h" -#include "dfhack/DFVector.h" -#include "dfhack/DFTypes.h" +#include "dfhack/Process.h" +#include "dfhack/Vector.h" +#include "dfhack/Types.h" #include "dfhack/modules/Vegetation.h" #include "dfhack/modules/Translation.h" #include "ModuleFactory.h" +#include using namespace DFHack; -Module* DFHack::createVegetation(DFContextShared * d) +Module* DFHack::createVegetation() { - return new Vegetation(d); + return new Vegetation(); } -struct Vegetation::Private -{ - uint32_t vegetation_vector; - uint32_t tree_desc_offset; - // translation - DfVector * p_veg; - - DFContextShared *d; - Process * owner; - bool Inited; - bool Started; -}; - -Vegetation::Vegetation(DFContextShared * d_) +Vegetation::Vegetation() { - d = new Private; - d->owner = d_->p; - d->d = d_; - d->Inited = d->Started = false; - OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation"); - d->vegetation_vector = OG_Veg->getAddress ("vector"); - d->tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset"); - d->Inited = true; + Core & c = Core::getInstance(); + try + { + OffsetGroup * OG_Veg = c.vinfo->getGroup("Vegetation"); + all_plants = (vector *) OG_Veg->getAddress ("vector"); + } + catch(exception &) + { + all_plants = 0; + } } Vegetation::~Vegetation() { - if(d->Started) - Finish(); - delete d; -} - -bool Vegetation::Start(uint32_t & numplants) -{ - if(!d->Inited) - return false; - d->p_veg = new DfVector (d->owner, d->vegetation_vector); - numplants = d->p_veg->size(); - d->Started = true; - return true; } -bool Vegetation::Read (const uint32_t index, dfh_plant & shrubbery) -{ - if(!d->Started) - return false; - // read pointer from vector at position - uint32_t temp = d->p_veg->at (index); - // read from memory - d->d->readName(shrubbery.name,temp); - d->owner->read (temp + d->tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata); - shrubbery.address = temp; - return true; -} - -bool Vegetation::Write (dfh_plant & shrubbery) -{ - if(!d->Started) - return false; - d->owner->write (shrubbery.address + d->tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata); - return true; -} - - -bool Vegetation::Finish() -{ - if(d->p_veg) - { - delete d->p_veg; - d->p_veg = 0; - } - d->Started = false; - return true; -} - diff --git a/library/modules/Vermin.cpp b/library/modules/Vermin.cpp new file mode 100644 index 000000000..67fd623e4 --- /dev/null +++ b/library/modules/Vermin.cpp @@ -0,0 +1,191 @@ +/* +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 +#include +#include +using namespace std; + +#include "dfhack/VersionInfo.h" +#include "dfhack/Types.h" +#include "dfhack/Error.h" +#include "dfhack/Process.h" +#include "dfhack/modules/Vermin.h" +#include "ModuleFactory.h" +#include "dfhack/Core.h" +using namespace DFHack; + +struct Vermin::Private +{ + uint32_t spawn_points_vector; + uint32_t race_offset; + uint32_t type_offset; + uint32_t position_offset; + uint32_t in_use_offset; + uint32_t unknown_offset; + uint32_t countdown_offset; + Process * owner; + bool Inited; + bool Started; +}; + +Module* DFHack::createVermin() +{ + return new Vermin(); +} + +#include + +Vermin::Vermin() +{ + Core & c = Core::getInstance(); + + d = new Private; + d->owner = c.p; + d->Inited = d->Started = false; + VersionInfo * mem = c.vinfo; + OffsetGroup * OG_vermin = mem->getGroup("Vermin"); + OffsetGroup * OG_spawn = OG_vermin->getGroup("Spawn Points"); + d->Inited = true; + try + { + d->spawn_points_vector = OG_spawn->getAddress("vector"); + + d->race_offset = OG_spawn->getOffset("race"); + d->type_offset = OG_spawn->getOffset("type"); + d->position_offset = OG_spawn->getOffset("position"); + d->in_use_offset = OG_spawn->getOffset("in_use"); + d->unknown_offset = OG_spawn->getOffset("unknown"); + d->countdown_offset = OG_spawn->getOffset("countdown"); + } + catch(DFHack::Error::AllMemdef &e) + { + cerr << "Vermin not available... " << e.what() << endl; + d->Inited = false; + } +} + +bool Vermin::Finish() +{ + return true; +} + +Vermin::~Vermin() +{ + delete d; +} + +// NOTE: caller must call delete on result when done. +SpawnPoints* Vermin::getSpawnPoints() +{ + if (!d->Inited) + { + cerr << "Couldn't get spawn points: Vermin module not inited" << endl; + return NULL; + } + + return new SpawnPoints(this); +} + +SpawnPoints::SpawnPoints(Vermin* v_) +{ + v = v_; + p_sp = NULL; + + if (!v->d->Inited) + { + cerr << "Couldn't get spawn points: Vermin module not inited" << endl; + return; + } + + //p_sp = new DfVector (v->d->spawn_points_vector); + //p_sp = new vector (v->d->spawn_points_vector); + p_sp = (vector *) (v->d->spawn_points_vector); +} + +SpawnPoints::~SpawnPoints() +{ + // Do NOT delete p_sp; it's a pointer to memory the game owns. +} + +size_t SpawnPoints::size() +{ + if (!isValid()) + return 0; + + return p_sp->size(); +} + +bool SpawnPoints::Read (const uint32_t index, t_spawnPoint & sp) +{ + if(!isValid()) + return false; + + // read pointer from vector at position + uint32_t temp = (uint32_t) p_sp->at (index); + + sp.origin = temp; + sp.race = v->d->owner->readWord(temp + v->d->race_offset); + sp.type = v->d->owner->readWord(temp + v->d->type_offset); + sp.in_use = v->d->owner->readByte(temp + v->d->in_use_offset); + sp.unknown = v->d->owner->readByte(temp + v->d->unknown_offset); + sp.countdown = v->d->owner->readDWord(temp + v->d->countdown_offset); + + // Three consecutive 16 bit numbers for x/y/z + v->d->owner->read(temp + v->d->position_offset, 6, (uint8_t*) &sp.x); + + return true; +} + +bool SpawnPoints::Write (const uint32_t index, t_spawnPoint & sp) +{ + if(!isValid()) + return false; + + // read pointer from vector at position + uint32_t temp = (uint32_t) p_sp->at (index); + + v->d->owner->writeWord(temp + v->d->race_offset, sp.race); + v->d->owner->writeWord(temp + v->d->type_offset, sp.type); + v->d->owner->writeByte(temp + v->d->in_use_offset, sp.in_use); + v->d->owner->writeByte(temp + v->d->unknown_offset, sp.unknown); + v->d->owner->writeDWord(temp + v->d->countdown_offset, sp.countdown); + + // Three consecutive 16 bit numbers for x/y/z + v->d->owner->write(temp + v->d->position_offset, 6, (uint8_t*) &sp.x); + + return true; +} + +bool SpawnPoints::isWildColony(t_spawnPoint & point) +{ + return (point.type == TYPE_WILD_COLONY); +} + +bool SpawnPoints::isValid() +{ + return (v != NULL && v->d->Inited && p_sp != NULL); +} diff --git a/library/modules/WindowIO-linux.cpp b/library/modules/WindowIO-linux.cpp deleted file mode 100644 index 02c176b4b..000000000 --- a/library/modules/WindowIO-linux.cpp +++ /dev/null @@ -1,282 +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 -#include -#include -#include -using namespace std; - -#include "dfhack/modules/WindowIO.h" - -#include //need for X11 functions -#include -#include "ContextShared.h" -#include "ModuleFactory.h" - -using namespace DFHack; - -Module* DFHack::createWindowIO(DFContextShared * d) -{ - return new WindowIO(d); -} - -// should always reflect the enum in DFkeys.h -const static KeySym ksTable[NUM_SPECIALS]= -{ - XK_Return, - XK_space, - XK_BackSpace, - XK_Tab, - XK_Caps_Lock, - XK_Shift_L, - XK_Shift_R, - XK_Control_L, - XK_Control_R, - XK_Alt_L, - XK_VoidSymbol, // WAIT - XK_Escape, - XK_Up, - XK_Down, - XK_Left, - XK_Right, - XK_F1, - XK_F2, - XK_F3, - XK_F4, - XK_F5, - XK_F6, - XK_F7, - XK_F8, - XK_F9, - XK_F10, - XK_F11, - XK_F12, - XK_Page_Up, - XK_Page_Down, - XK_Insert, - XK_Delete, - XK_Home, - XK_End, - XK_KP_Divide, - XK_KP_Multiply, - XK_KP_Subtract, - XK_KP_Add, - XK_KP_Enter, - XK_KP_0, - XK_KP_1, - XK_KP_2, - XK_KP_3, - XK_KP_4, - XK_KP_5, - XK_KP_6, - XK_KP_7, - XK_KP_8, - XK_KP_9, - XK_KP_Decimal -}; - -class WindowIO::Private -{ - public: - Private(Process * _p) - { - p=_p; - }; - ~Private(){}; - - // Source: http://www.experts-exchange.com/OS/Unix/X_Windows/Q_21341279.html - // find named window recursively - Window EnumerateWindows (Display *display, Window rootWindow, const char *searchString); - - // iterate through X screens, find the window - // FIXME: use _NET_WM_PID primarily and this current stuff only as a fallback - // see http://www.mail-archive.com/devel@xfree86.org/msg05818.html - bool getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow); - - // send synthetic key events to a window - // Source: http://homepage3.nifty.com/tsato/xvkbd/events.html - void send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay); - - // our parent process - Process * p; -}; - -// ctor -WindowIO::WindowIO (DFContextShared * csh) -{ - d = new Private(csh->p); -} - -// dtor -WindowIO::~WindowIO () -{ - delete d; -} - -Window WindowIO::Private::EnumerateWindows (Display *display, Window rootWindow, const char *searchString) -{ - Window parent; - Window *children; - Window retWindow = BadWindow; - unsigned int noOfChildren; - int status; - - // get name of current window, compare to control, return if found - char * win_name; - status = XFetchName (display, rootWindow, &win_name); - if ( (status >= Success) && (win_name) && strcmp (win_name, searchString) == 0) - { - return rootWindow; - } - - // look at surrounding window tree nodes, bailout on error or no children - status = XQueryTree (display, rootWindow, &rootWindow, &parent, &children, &noOfChildren); - if (!status || !noOfChildren) - { - return BadWindow; - } - - // recurse into children - for (uint32_t i = 0; i < noOfChildren; i++) - { - Window tempWindow = EnumerateWindows (display, children[i], searchString); - if (tempWindow != BadWindow) - { - retWindow = tempWindow; - break; - } - } - - // free resources - XFree ( (char*) children); - return retWindow; -} - -bool WindowIO::Private::getDFWindow (Display *dpy, Window& dfWindow, Window & rootWindow) -{ - // int numScreeens = ScreenCount(dpy); - for (int i = 0;i < ScreenCount (dpy);i++) - { - rootWindow = RootWindow (dpy, i); - Window retWindow = EnumerateWindows (dpy, rootWindow, "Dwarf Fortress"); - if (retWindow != BadWindow) - { - dfWindow = retWindow; - return true; - } - } - return false; -} - -void WindowIO::Private::send_xkeyevent(Display *display, Window dfW,Window rootW, int keycode, int modstate, int is_press, useconds_t delay) -{ - XKeyEvent event; - - event.display = display; - event.window = dfW; - event.root = rootW; - event.subwindow = None; - event.time = CurrentTime; - event.x = 1; - event.y = 1; - event.x_root = 1; - event.y_root = 1; - event.same_screen = true; - - event.type = (is_press ? KeyPress : KeyRelease); - event.keycode = keycode; - event.state = modstate; - XSendEvent(event.display, event.window, true, KeyPressMask, (XEvent *) &event); - usleep(delay); -} - -void WindowIO::TypeStr (const char *input, int delay, bool useShift) -{ - Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY - Window dfWin; - Window rootWin; - if (d->getDFWindow (dpy, dfWin, rootWin)) - { - char cChar; - int realDelay = delay * 1000; - KeyCode xkeycode; - while ( (cChar = *input++)) // loops through chars - { - // HACK: the timing here is a strange beast - xkeycode = XKeysymToKeycode (dpy, cChar); - d->send_xkeyevent(dpy,dfWin,rootWin,XKeysymToKeycode(dpy, ksTable[DFHack::LEFT_SHIFT]),0,false, realDelay); - if (useShift || (cChar >= 'A' && cChar <= 'Z')) - { - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,true, realDelay); - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,ShiftMask,false, realDelay); - XSync (dpy, false); - } - else - { - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay); - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay); - XSync (dpy, false); - } - } - } - else - { - cout << "FAIL!" << endl; - } -} - -void WindowIO::TypeSpecial (t_special command, int count, int delay) -{ - if (command != WAIT) - { - KeySym mykeysym; - KeyCode xkeycode; - Display *dpy = XOpenDisplay (NULL); // null opens the display in $DISPLAY - int realDelay = delay * 1000; - Window dfWin; - Window rootWin; - if (d->getDFWindow (dpy, dfWin, rootWin)) - { - for (int i = 0;i < count; i++) - { - // HACK: the timing here is a strange beast - mykeysym = ksTable[command]; - xkeycode = XKeysymToKeycode (dpy, mykeysym); - d->send_xkeyevent(dpy,dfWin,rootWin,XKeysymToKeycode(dpy, ksTable[DFHack::LEFT_SHIFT]),0,false, realDelay); - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,true, realDelay); - d->send_xkeyevent(dpy,dfWin,rootWin,xkeycode,0,false, realDelay); - XSync (dpy, false); - } - } - else - { - cout << "FAIL!" << endl; - } - } - else - { - usleep (delay*1000 * count); - } -} diff --git a/library/modules/WindowIO-windows.cpp b/library/modules/WindowIO-windows.cpp deleted file mode 100644 index 55248d03c..000000000 --- a/library/modules/WindowIO-windows.cpp +++ /dev/null @@ -1,197 +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 "PlatformInternal.h" -#include -#include -using namespace std; -#include "ContextShared.h" -#include "dfhack/modules/WindowIO.h" -#include "dfhack/DFProcess.h" -#include "ModuleFactory.h" - -using namespace DFHack; - -Module* DFHack::createWindowIO(DFContextShared * d) -{ - return new WindowIO(d); -} - -// should always reflect the enum in DFkeys.h -const static int ksTable[NUM_SPECIALS]= -{ - VK_RETURN, - VK_SPACE, - VK_BACK, - VK_TAB, - VK_CAPITAL, - VK_LSHIFT, - VK_RSHIFT, - VK_LCONTROL, - VK_RCONTROL, - VK_MENU, - 0, //XK_VoidSymbol, // WAIT - VK_ESCAPE, - VK_UP, - VK_DOWN, - VK_LEFT, - VK_RIGHT, - VK_F1, - VK_F2, - VK_F3, - VK_F4, - VK_F5, - VK_F6, - VK_F7, - VK_F8, - VK_F9, - VK_F10, - VK_F11, - VK_F12, - VK_PRIOR, - VK_NEXT, - VK_INSERT, - VK_DELETE, - VK_HOME, - VK_END, - VK_DIVIDE, - VK_MULTIPLY, - VK_SUBTRACT, - VK_ADD, - VK_RETURN, - VK_NUMPAD0, - VK_NUMPAD1, - VK_NUMPAD2, - VK_NUMPAD3, - VK_NUMPAD4, - VK_NUMPAD5, - VK_NUMPAD6, - VK_NUMPAD7, - VK_NUMPAD8, - VK_NUMPAD9, - VK_SEPARATOR -}; -//Windows key handlers -struct window -{ - HWND windowHandle; - uint32_t pid; -}; - -BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam) -{ - uint32_t pid; - - GetWindowThreadProcessId (hwnd, (LPDWORD) &pid); - if (pid == ( (window *) lParam)->pid) - { - ( (window *) lParam)->windowHandle = hwnd; - return FALSE; - } - return TRUE; -} - -class WindowIO::Private -{ - public: - Private(Process * _p) - { - p=_p; - }; - ~Private(){}; - // our parent process - Process * p; -}; - -// ctor -WindowIO::WindowIO (DFContextShared * schr) -{ - d = new Private(schr->p); -} - -// dtor -WindowIO::~WindowIO () -{ - delete d; -} - -// TODO: also investigate possible problems with UIPI on Vista and 7 -void WindowIO::TypeStr (const char *input, int delay, bool useShift) -{ - //sendmessage needs a window handle HWND, so have to get that from the process HANDLE - window myWindow; - myWindow.pid = d->p->getPID(); - EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); - char cChar; - DWORD dfProcess = GetWindowThreadProcessId(myWindow.windowHandle,NULL); - DWORD currentProcess = GetCurrentThreadId(); - AttachThreadInput(currentProcess,dfProcess,TRUE); //The two threads have to have attached input in order to change the keyboard state, which is needed to set the shift state - while ( (cChar = *input++)) // loops through chars - { - short vk = VkKeyScan (cChar); // keycode of char - if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift - { - vk = vk & 0xFF; // remove the shift state from the virtual key code - BYTE keybstate[256] = {0}; - BYTE keybstateOrig[256] = {0}; - GetKeyboardState((LPBYTE)&keybstateOrig); - GetKeyboardState((LPBYTE)&keybstate); - keybstate[VK_SHIFT] |= 0x80; //Set shift state to on in variable - SetKeyboardState((LPBYTE)&keybstate); //set the current state to the variable - SendMessage(myWindow.windowHandle,WM_KEYDOWN,vk,0); - SendMessage(myWindow.windowHandle,WM_KEYUP,vk,0); - SetKeyboardState((LPBYTE)&keybstateOrig); // reset the shift state to the original state - } - else - { - SendMessage(myWindow.windowHandle,WM_KEYDOWN,vk,0); - SendMessage(myWindow.windowHandle,WM_KEYUP,vk,0); - } - } - AttachThreadInput(currentProcess,dfProcess,FALSE); //detach the threads - Sleep (delay); -} - -void WindowIO::TypeSpecial (t_special command, int count, int delay) -{ - if (command != WAIT) - { - HWND currentWindow = GetForegroundWindow(); - window myWindow; - myWindow.pid = d->p->getPID(); - EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); - - for (int i = 0; i < count;i++) - { - SendMessage(myWindow.windowHandle,WM_KEYDOWN,ksTable[command],0); - SendMessage(myWindow.windowHandle,WM_KEYUP,ksTable[command],0); - } - Sleep (delay); - } - else - { - Sleep (delay*count); - } -} diff --git a/library/modules/WindowIO_C.cpp b/library/modules/WindowIO_C.cpp deleted file mode 100644 index 51dd92eab..000000000 --- a/library/modules/WindowIO_C.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -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 -#include -#include -using namespace std; - -#include "dfhack-c/Common.h" -#include "dfhack/DFIntegers.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, uint32_t delay, int8_t useShift) -{ - if(window != NULL) - { - bool shifting = false; - - if(useShift > 0) - shifting = true; - - ((DFHack::WindowIO*)window)->TypeStr(input, delay, shifting); - return 1; - } - - return -1; -} - -int WindowIO_TypeSpecial(DFHackObject* window, t_special command, uint32_t count, uint32_t delay) -{ - if(window != NULL) - { - ((DFHack::WindowIO*)window)->TypeSpecial(command, count, delay); - return 1; - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/modules/World.cpp b/library/modules/World.cpp index b0b893a48..f19f94a9d 100644 --- a/library/modules/World.cpp +++ b/library/modules/World.cpp @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ + #include "Internal.h" #include #include @@ -29,19 +30,19 @@ distribution. #include using namespace std; -#include "ContextShared.h" #include "dfhack/modules/World.h" -#include "dfhack/DFProcess.h" +#include "dfhack/Process.h" #include "dfhack/VersionInfo.h" -#include "dfhack/DFTypes.h" -#include "dfhack/DFError.h" +#include "dfhack/Types.h" +#include "dfhack/Error.h" #include "ModuleFactory.h" +#include using namespace DFHack; -Module* DFHack::createWorld(DFContextShared * d) +Module* DFHack::createWorld() { - return new World(d); + return new World(); } struct World::Private @@ -66,18 +67,21 @@ struct World::Private uint32_t gamemode_offset; uint32_t controlmode_offset; uint32_t controlmodecopy_offset; - DFContextShared *d; + + bool StartedFolder; + uint32_t folder_name_offset; + Process * owner; }; -World::World(DFContextShared * _d) +World::World() { - + Core & c = Core::getInstance(); d = new Private; - d->d = _d; - d->owner = _d->p; + d->owner = c.p; + wmap = 0; - OffsetGroup * OG_World = d->d->offset_descriptor->getGroup("World"); + OffsetGroup * OG_World = c.vinfo->getGroup("World"); try { d->year_offset = OG_World->getAddress( "current_year" ); @@ -85,7 +89,7 @@ World::World(DFContextShared * _d) d->StartedTime = true; } catch(Error::All &){}; - OffsetGroup * OG_Gui = d->d->offset_descriptor->getGroup("GUI"); // FIXME: legacy + OffsetGroup * OG_Gui = c.vinfo->getGroup("GUI"); try { d->pause_state_offset = OG_Gui->getAddress ("pause_state"); @@ -95,6 +99,7 @@ World::World(DFContextShared * _d) try { d->weather_offset = OG_World->getAddress( "current_weather" ); + wmap = (weather_map *) d->weather_offset; d->StartedWeather = true; } catch(Error::All &){}; @@ -105,6 +110,14 @@ World::World(DFContextShared * _d) d->StartedMode = true; } catch(Error::All &){}; + try + { + d->folder_name_offset = OG_World->getAddress( "save_folder" ); + d->StartedFolder = true; + } + catch(Error::All &){}; + + d->Inited = true; } @@ -126,7 +139,6 @@ bool World::Finish() bool World::ReadPauseState() { if(!d->PauseInited) return false; - uint32_t pauseState = d->owner->readDWord (d->pause_state_offset); return pauseState & 1; } @@ -155,8 +167,8 @@ bool World::ReadGameMode(t_gamemodes& rd) { if(d->Inited && d->StartedMode) { - rd.control_mode = (ControlMode) d->owner->readDWord( d->controlmode_offset); - rd.game_mode = (GameMode) d->owner->readDWord(d->gamemode_offset); + rd.g_mode = (GameMode) d->owner->readDWord( d->controlmode_offset); + rd.g_type = (GameType) d->owner->readDWord(d->gamemode_offset); return true; } return false; @@ -165,8 +177,8 @@ bool World::WriteGameMode(const t_gamemodes & wr) { if(d->Inited && d->StartedMode) { - d->owner->writeDWord(d->gamemode_offset,wr.game_mode); - d->owner->writeDWord(d->controlmode_offset,wr.control_mode); + d->owner->writeDWord(d->gamemode_offset,wr.g_mode); + d->owner->writeDWord(d->controlmode_offset,wr.g_type); return true; } return false; @@ -220,3 +232,12 @@ void World::SetCurrentWeather(uint8_t weather) d->owner->write(d->weather_offset,sizeof(buf),buf); } } + +string World::ReadWorldFolder() +{ + if (d->Inited && d->StartedFolder) + { + return string( * ( (string*) d->folder_name_offset ) ); + } + return string(""); +} diff --git a/library/modules/World_C.cpp b/library/modules/World_C.cpp deleted file mode 100644 index a87a7f6f1..000000000 --- a/library/modules/World_C.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* -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 -#include -#include -using namespace std; -#include "dfhack-c/Common.h" -#include "dfhack/modules/World.h" -#include "dfhack-c/modules/World_C.h" -#include "dfhack-c/DFTypes_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; -} - -int World_ReadCurrentWeather(DFHackObject* world, uint8_t* weather) -{ - if(world != NULL) - { - *weather = ((DFHack::World*)world)->ReadCurrentWeather(); - return 1; - } - - return -1; -} - -int World_WriteCurrentWeather(DFHackObject* world, uint8_t weather) -{ - if(world != NULL) - { - ((DFHack::World*)world)->SetCurrentWeather(weather); - return 1; - } - - return -1; -} - -int World_ReadGameMode(DFHackObject* world, t_gamemodes* modes) -{ - if(world != NULL) - { - if(((DFHack::World*)world)->ReadGameMode(*modes)) - return 1; - else - return 0; - } - - return -1; -} - -int World_WriteGameMode(DFHackObject* world, t_gamemodes modes) -{ - if(world != NULL) - { - if(((DFHack::World*)world)->WriteGameMode(modes)) - return 1; - else - return 0; - } - - return -1; -} - -int World_ReadPauseState(DFHackObject* gui) -{ - if(gui != NULL) - { - return ((DFHack::World*)gui)->ReadPauseState(); - } - - return -1; -} - -int World_SetPauseState(DFHackObject* gui, int8_t paused) -{ - if(gui != NULL) - { - bool pauseState = false; - - if(paused > 0) - pauseState = true; - - ((DFHack::World*)gui)->SetPauseState(pauseState); - - return 1; - } - - return -1; -} - -#ifdef __cplusplus -} -#endif diff --git a/library/private/ContextShared.h b/library/private/ContextShared.h deleted file mode 100644 index 4a248d0b3..000000000 --- a/library/private/ContextShared.h +++ /dev/null @@ -1,118 +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. -*/ - -#pragma once - -#ifndef APIPRIVATE_H_INCLUDED -#define APIPRIVATE_H_INCLUDED - -namespace DFHack -{ - class Module; - - class Creatures; - class Engravings; - class Maps; - class Gui; - class World; - class Materials; - class Items; - class Translation; - class Vegetation; - class Buildings; - class Constructions; - class WindowIO; - - class ProcessEnumerator; - class Process; - class VersionInfo; - struct t_name; - class DFContextShared - { - public: - DFContextShared(); - ~DFContextShared(); - - // names, used by a few other modules. - void readName(t_name & name, uint32_t address); - void copyName(uint32_t address, uint32_t target); - // get the name offsets - bool InitReadNames(); - uint32_t name_firstname_offset; - uint32_t name_nickname_offset; - uint32_t name_words_offset; - uint32_t name_parts_offset; - uint32_t name_language_offset; - uint32_t name_set_offset; - bool namesInited; - bool namesFailed; - - ProcessEnumerator* pm; - Process* p; - char * shm_start; - VersionInfo* offset_descriptor; - string xml; - - // Modules - struct - { - Creatures * pCreatures; - Engravings * pEngravings; - Maps * pMaps; - Gui * pPosition; // blerp - Gui * pGui; - World * pWorld; - Materials * pMaterials; - Items * pItems; - Translation * pTranslation; - Vegetation * pVegetation; - Buildings * pBuildings; - Constructions * pConstructions; - WindowIO * pWindowIO; - } s_mods; - std::vector allModules; - /* - uint32_t item_material_offset; - - uint32_t note_foreground_offset; - uint32_t note_background_offset; - uint32_t note_name_offset; - uint32_t note_xyz_offset; - - 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; - DfVector *p_itm; - DfVector *p_notes; - DfVector *p_settlements; - DfVector *p_current_settlement; - */ - }; -} -#endif - diff --git a/library/private/Internal.h b/library/private/Internal.h index 4c1d714a4..34cc40901 100644 --- a/library/private/Internal.h +++ b/library/private/Internal.h @@ -1,6 +1,6 @@ /* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any @@ -32,20 +32,16 @@ distribution. #define BUILD_DFHACK_LIB #endif -// wizardry for adding quotes to macros -#define _QUOTEME(x) #x -#define QUOT(x) _QUOTEME(x) - // force large file support #ifdef LINUX_BUILD #define _FILE_OFFSET_BITS 64 #endif // one file for telling the MSVC compiler where it can shove its pointless warnings -#include "dfhack/DFPragma.h" +#include "dfhack/Pragma.h" // C99 integer types -#include "dfhack/DFIntegers.h" +#include #endif // DFCOMMONINTERNAL_H_INCLUDED diff --git a/library/private/LinuxProcess.h b/library/private/LinuxProcess.h deleted file mode 100644 index 4b35006ba..000000000 --- a/library/private/LinuxProcess.h +++ /dev/null @@ -1,85 +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. -*/ - -#pragma once - -#ifndef LINUX_PROCESS_H_INCLUDED -#define LINUX_PROCESS_H_INCLUDED - -#include "dfhack/DFProcess.h" - -namespace DFHack -{ - class LinuxProcessBase : public Process - { - protected: - VersionInfo * my_descriptor; - pid_t my_pid; - string memFile; - int memFileHandle; - bool attached:1; - bool suspended:1; - bool identified:1; - public: - LinuxProcessBase(uint32_t pid); - ~LinuxProcessBase(); - - void readQuad(const uint32_t address, uint64_t & value); - void writeQuad(const uint32_t address, const uint64_t value); - - void readDWord(const uint32_t address, uint32_t & value); - void writeDWord(const uint32_t address, const uint32_t value); - - void readFloat(const uint32_t address, float & value); - - void readWord(const uint32_t address, uint16_t & value); - void writeWord(const uint32_t address, const uint16_t value); - - void readByte(const uint32_t address, uint8_t & value); - void writeByte(const uint32_t address, const uint8_t value); - - void read( uint32_t address, uint32_t length, uint8_t* buffer); - void write(uint32_t address, uint32_t length, uint8_t* buffer); - - const std::string readCString (uint32_t offset); - - bool isSuspended(); - bool isAttached(); - bool isIdentified(); - - VersionInfo *getDescriptor(); - int getPID(); - std::string getPath(); - - bool getThreadIDs(std::vector & threads ); - void getMemRanges(std::vector & ranges ); - // get module index by name and version. bool 1 = error - bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { OUTPUT=0; return false;}; - // get the SHM start if available - char * getSHMStart (void){return 0;}; - // set a SHM command and wait for a response - bool SetAndWait (uint32_t state){return false;}; - }; -} -#endif diff --git a/library/private/MicrosoftSTL.h b/library/private/MicrosoftSTL.h deleted file mode 100644 index 1b9eab57b..000000000 --- a/library/private/MicrosoftSTL.h +++ /dev/null @@ -1,46 +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. -*/ - -#pragma once - -namespace DFHack { - class Process; - class MicrosoftSTL - { - private: - uint32_t STLSTR_buf_off; - uint32_t STLSTR_size_off; - uint32_t STLSTR_cap_off; - - Process* p; - public: - void init(Process* p); - - const std::string readSTLString (uint32_t offset); - size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - size_t writeSTLString(const uint32_t address, const std::string writeString); - // get class name of an object with rtti/type info - std::string readClassName(uint32_t vptr); - }; -} diff --git a/library/private/ModuleFactory.h b/library/private/ModuleFactory.h index 40a122a24..8a795c0d6 100644 --- a/library/private/ModuleFactory.h +++ b/library/private/ModuleFactory.h @@ -1,26 +1,26 @@ /* - w ww.so*urceforge.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. - */ +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +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. +*/ #pragma once @@ -30,18 +30,18 @@ namespace DFHack { class Module; - class DFContextShared; - Module* createCreatures(DFContextShared * d); - Module* createEngravings(DFContextShared * d); - Module* createGui(DFContextShared * d); - Module* createWindowIO(DFContextShared * d); - Module* createWorld(DFContextShared * d); - Module* createMaterials(DFContextShared * d); - Module* createItems(DFContextShared * d); - Module* createTranslation(DFContextShared * d); - Module* createVegetation(DFContextShared * d); - Module* createBuildings(DFContextShared * d); - Module* createConstructions(DFContextShared * d); - Module* createMaps(DFContextShared * d); + Module* createCreatures(); + Module* createEngravings(); + Module* createGui(); + Module* createWorld(); + Module* createMaterials(); + Module* createItems(); + Module* createTranslation(); + Module* createVegetation(); + Module* createBuildings(); + Module* createConstructions(); + Module* createMaps(); + Module* createVermin(); + Module* createNotes(); } -#endif \ No newline at end of file +#endif diff --git a/library/private/PlatformInternal.h b/library/private/PlatformInternal.h deleted file mode 100644 index 4b2a3f424..000000000 --- a/library/private/PlatformInternal.h +++ /dev/null @@ -1,102 +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. - */ - -#pragma once - -#ifndef DFPLATFORMINTERNAL_H_INCLUDED -#define DFPLATFORMINTERNAL_H_INCLUDED - -// platform includes and defines -#ifdef LINUX_BUILD - #include - #include - #include - #include - #include - #include - #include - #include -#else - // WINDOWS - #define _WIN32_WINNT 0x0501 // needed for INPUT struct - #define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32 - #define WIN32_LEAN_AND_MEAN - #include - #include - #include - #include - //#include // NOT present in mingw32 - typedef LONG NTSTATUS; - #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) - - // FIXME: it is uncertain how these map to 64bit - typedef struct _DEBUG_BUFFER - { - HANDLE SectionHandle; - PVOID SectionBase; - PVOID RemoteSectionBase; - ULONG SectionBaseDelta; - HANDLE EventPairHandle; - ULONG Unknown[2]; - HANDLE RemoteThreadHandle; - ULONG InfoClassMask; - ULONG SizeOfInfo; - ULONG AllocatedSize; - ULONG SectionSize; - PVOID ModuleInformation; - PVOID BackTraceInformation; - PVOID HeapInformation; - PVOID LockInformation; - PVOID Reserved[8]; - } DEBUG_BUFFER, *PDEBUG_BUFFER; - - typedef struct _DEBUG_HEAP_INFORMATION - { - ULONG Base; // 0×00 - ULONG Flags; // 0×04 - USHORT Granularity; // 0×08 - USHORT Unknown; // 0x0A - ULONG Allocated; // 0x0C - ULONG Committed; // 0×10 - ULONG TagCount; // 0×14 - ULONG BlockCount; // 0×18 - ULONG Reserved[7]; // 0x1C - PVOID Tags; // 0×38 - PVOID Blocks; // 0x3C - } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; - - // RtlQueryProcessDebugInformation.DebugInfoClassMask constants - #define PDI_MODULES 0x01 - #define PDI_BACKTRACE 0x02 - #define PDI_HEAPS 0x04 - #define PDI_HEAP_TAGS 0x08 - #define PDI_HEAP_BLOCKS 0x10 - #define PDI_LOCKS 0x20 - - extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlQueryProcessDebugInformation( IN ULONG ProcessId, IN ULONG DebugInfoClassMask, IN OUT PDEBUG_BUFFER DebugBuffer); - extern "C" __declspec(dllimport) PDEBUG_BUFFER __stdcall RtlCreateQueryDebugBuffer( IN ULONG Size, IN BOOLEAN EventPair); - extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlDestroyQueryDebugBuffer( IN PDEBUG_BUFFER DebugBuffer); -#endif // WINDOWS - -#endif // DFPLATFORMINTERNAL_H_INCLUDED \ No newline at end of file diff --git a/library/private/ProcessFactory.h b/library/private/ProcessFactory.h deleted file mode 100644 index ed697d570..000000000 --- a/library/private/ProcessFactory.h +++ /dev/null @@ -1,39 +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. -*/ - -#ifndef PROCESS_FACTORY_H_INCLUDED -#define PROCESS_FACTORY_H_INCLUDED - -#include "dfhack/DFProcess.h" -#include "dfhack/VersionInfoFactory.h" - -namespace DFHack -{ - Process* createNormalProcess(uint32_t pid, VersionInfoFactory * factory); - Process* createSHMProcess(uint32_t pid, VersionInfoFactory * factory); -#ifdef LINUX_BUILD - Process* createWineProcess(uint32_t pid, VersionInfoFactory * factory); -#endif -} -#endif diff --git a/library/private/SHMProcess.h b/library/private/SHMProcess.h deleted file mode 100644 index 7ff463189..000000000 --- a/library/private/SHMProcess.h +++ /dev/null @@ -1,152 +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. -*/ - -#pragma once - -#ifndef SHM_PROCESS_H_INCLUDED -#define SHM_PROCESS_H_INCLUDED - -#include "dfhack/DFProcess.h" -#include "dfhack/DFIntegers.h" -#include "dfhack/VersionInfoFactory.h" - -namespace DFHack -{ - class DFHACK_EXPORT SHMProcess : public Process - { - private: - class Private; - Private * const d; - - public: - SHMProcess(uint32_t PID, VersionInfoFactory * factory); - ~SHMProcess(); - // Set up stuff so we can read memory - bool attach(); - bool detach(); - - bool suspend(); - bool asyncSuspend(); - bool resume(); - bool forceresume(); - - void readQuad(const uint32_t address, uint64_t & value); - void writeQuad(const uint32_t address, const uint64_t value); - - void readDWord(const uint32_t address, uint32_t & value); - void writeDWord(const uint32_t address, const uint32_t value); - - void readFloat(const uint32_t address, float & value); - - void readWord(const uint32_t address, uint16_t & value); - void writeWord(const uint32_t address, const uint16_t value); - - void readByte(const uint32_t address, uint8_t & value); - void writeByte(const uint32_t address, const uint8_t value); - - void read( uint32_t address, uint32_t length, uint8_t* buffer); - void write(uint32_t address, uint32_t length, uint8_t* buffer); - - const std::string readSTLString (uint32_t offset); - size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - size_t writeSTLString(const uint32_t address, const std::string writeString); - - void readSTLVector(const uint32_t address, t_vecTriplet & triplet); - void writeSTLVector(const uint32_t address, t_vecTriplet & triplet); - // get class name of an object with rtti/type info - std::string doReadClassName(uint32_t vptr); - - const std::string readCString (uint32_t offset); - - bool isSuspended(); - bool isAttached(); - bool isIdentified(); - - bool getThreadIDs(std::vector & threads ); - void getMemRanges(std::vector & ranges ); - VersionInfo *getDescriptor(); - int getPID(); - std::string getPath(); - // get module index by name and version. bool 1 = error - bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT); - // get the SHM start if available - char * getSHMStart (void); - bool SetAndWait (uint32_t state); - private: - bool acquireSuspendLock(); - bool releaseSuspendLock(); - }; - - class SHMProcess::Private - { - public: - Private(SHMProcess * self_); - ~Private(){} - VersionInfo * memdescriptor; - SHMProcess * self; - char *shm_addr; - int attachmentIdx; - - bool attached; - bool locked; - bool identified; - bool useYield; - - uint8_t vector_start; - -#ifdef LINUX_BUILD - pid_t process_ID; - int shm_ID; - int server_lock; - int client_lock; - int suspend_lock; -#else - typedef uint32_t pid_t; - uint32_t process_ID; - HANDLE DFSVMutex; - HANDLE DFCLMutex; - HANDLE DFCLSuspendMutex; -#endif - - bool validate(VersionInfoFactory * factory); - - bool Aux_Core_Attach(bool & versionOK, pid_t& PID); - bool SetAndWait (uint32_t state); - bool GetLocks(); - bool AreLocksOk(); - void FreeLocks(); - }; -} - -// some helpful macros to keep the code bloat in check -#define SHMCMD ( (uint32_t *) shm_addr)[attachmentIdx] -#define D_SHMCMD ( (uint32_t *) (d->shm_addr))[d->attachmentIdx] - -#define SHMHDR ((shm_core_hdr *)shm_addr) -#define D_SHMHDR ((shm_core_hdr *)(d->shm_addr)) - -#define SHMDATA(type) ((type *)(shm_addr + SHM_HEADER)) -#define D_SHMDATA(type) ((type *)(d->shm_addr + SHM_HEADER)) - -#endif diff --git a/library/private/wdirent.h b/library/private/wdirent.h new file mode 100644 index 000000000..445d040dc --- /dev/null +++ b/library/private/wdirent.h @@ -0,0 +1,372 @@ +/***************************************************************************** + * dirent.h - dirent API for Microsoft Visual Studio + * + * Copyright (C) 2006 Toni Ronkko + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Mar 15, 2011, Toni Ronkko + * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0. + * + * Aug 11, 2010, Toni Ronkko + * Added d_type and d_namlen fields to dirent structure. The former is + * especially useful for determining whether directory entry represents a + * file or a directory. For more information, see + * http://www.delorie.com/gnu/docs/glibc/libc_270.html + * + * Aug 11, 2010, Toni Ronkko + * Improved conformance to the standards. For example, errno is now set + * properly on failure and assert() is never used. Thanks to Peter Brockam + * for suggestions. + * + * Aug 11, 2010, Toni Ronkko + * Fixed a bug in rewinddir(): when using relative directory names, change + * of working directory no longer causes rewinddir() to fail. + * + * Dec 15, 2009, John Cunningham + * Added rewinddir member function + * + * Jan 18, 2008, Toni Ronkko + * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string + * between multi-byte and unicode representations. This makes the + * code simpler and also allows the code to be compiled under MingW. Thanks + * to Azriel Fasten for the suggestion. + * + * Mar 4, 2007, Toni Ronkko + * Bug fix: due to the strncpy_s() function this file only compiled in + * Visual Studio 2005. Using the new string functions only when the + * compiler version allows. + * + * Nov 2, 2006, Toni Ronkko + * Major update: removed support for Watcom C, MS-DOS and Turbo C to + * simplify the file, updated the code to compile cleanly on Visual + * Studio 2005 with both unicode and multi-byte character strings, + * removed rewinddir() as it had a bug. + * + * Aug 20, 2006, Toni Ronkko + * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified + * comments by removing SGML tags. + * + * May 14 2002, Toni Ronkko + * Embedded the function definitions directly to the header so that no + * source modules need to be included in the Visual Studio project. Removed + * all the dependencies to other projects so that this very header can be + * used independently. + * + * May 28 1998, Toni Ronkko + * First version. + *****************************************************************************/ +#ifndef DIRENT_H +#define DIRENT_H + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +/* Entries missing from MSVC 6.0 */ +#if !defined(FILE_ATTRIBUTE_DEVICE) +# define FILE_ATTRIBUTE_DEVICE 0x40 +#endif + +/* File type and permission flags for stat() */ +#if defined(_MSC_VER) && !defined(S_IREAD) +# define S_IFMT _S_IFMT /* file type mask */ +# define S_IFDIR _S_IFDIR /* directory */ +# define S_IFCHR _S_IFCHR /* character device */ +# define S_IFFIFO _S_IFFIFO /* pipe */ +# define S_IFREG _S_IFREG /* regular file */ +# define S_IREAD _S_IREAD /* read permission */ +# define S_IWRITE _S_IWRITE /* write permission */ +# define S_IEXEC _S_IEXEC /* execute permission */ +#endif +#define S_IFBLK 0 /* block device */ +#define S_IFLNK 0 /* link */ +#define S_IFSOCK 0 /* socket */ + +#if defined(_MSC_VER) +# define S_IRUSR S_IREAD /* read, user */ +# define S_IWUSR S_IWRITE /* write, user */ +# define S_IXUSR 0 /* execute, user */ +# define S_IRGRP 0 /* read, group */ +# define S_IWGRP 0 /* write, group */ +# define S_IXGRP 0 /* execute, group */ +# define S_IROTH 0 /* read, others */ +# define S_IWOTH 0 /* write, others */ +# define S_IXOTH 0 /* execute, others */ +#endif + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct dirent +{ + char d_name[MAX_PATH + 1]; /* File name */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ +} dirent; + + +typedef struct DIR +{ + dirent curentry; /* Current directory entry */ + WIN32_FIND_DATAA find_data; /* Private file data */ + int cached; /* True if data is valid */ + HANDLE search_handle; /* Win32 search handle */ + char patt[MAX_PATH + 3]; /* Initial directory name */ +} DIR; + + +/* Forward declarations */ +static DIR *opendir(const char *dirname); +static struct dirent *readdir(DIR *dirp); +static int closedir(DIR *dirp); +static void rewinddir(DIR* dirp); + + +/* Use the new safe string functions introduced in Visual Studio 2005 */ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE) +#else +# define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size)) +#endif + +/* Set errno variable */ +#if defined(_MSC_VER) +#define DIRENT_SET_ERRNO(x) _set_errno (x) +#else +#define DIRENT_SET_ERRNO(x) (errno = (x)) +#endif + + +/***************************************************************************** + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static DIR *opendir(const char *dirname) +{ + DIR *dirp; + + /* ensure that the resulting search pattern will be a valid file name */ + if (dirname == NULL) { + DIRENT_SET_ERRNO (ENOENT); + return NULL; + } + if (strlen (dirname) + 3 >= MAX_PATH) { + DIRENT_SET_ERRNO (ENAMETOOLONG); + return NULL; + } + + /* construct new DIR structure */ + dirp = (DIR*) malloc (sizeof (struct DIR)); + if (dirp != NULL) { + int error; + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly when the current working + * directory is changed between opendir() and rewinddir(). + */ + if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) { + char *p; + + /* append the search pattern "\\*\0" to the directory name */ + p = strchr (dirp->patt, '\0'); + if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') { + *p++ = '\\'; + } + *p++ = '*'; + *p = '\0'; + + /* open directory stream and retrieve the first entry */ + dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + /* a directory entry is now waiting in memory */ + dirp->cached = 1; + error = 0; + } else { + /* search pattern is not a directory name? */ + DIRENT_SET_ERRNO (ENOENT); + error = 1; + } + } else { + /* buffer too small */ + DIRENT_SET_ERRNO (ENOMEM); + error = 1; + } + + if (error) { + free (dirp); + dirp = NULL; + } + } + + return dirp; +} + + +/***************************************************************************** + * Read a directory entry, and return a pointer to a dirent structure + * containing the name of the entry in d_name field. Individual directory + * entries returned by this very function include regular files, + * sub-directories, pseudo-directories "." and "..", but also volume labels, + * hidden files and system files may be returned. + */ +static struct dirent *readdir(DIR *dirp) +{ + DWORD attr; + if (dirp == NULL) { + /* directory stream did not open */ + DIRENT_SET_ERRNO (EBADF); + return NULL; + } + + /* get next directory entry */ + if (dirp->cached != 0) { + /* a valid directory entry already in memory */ + dirp->cached = 0; + } else { + /* get the next directory entry from stream */ + if (dirp->search_handle == INVALID_HANDLE_VALUE) { + return NULL; + } + if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) { + /* the very last entry has been processed or an error occured */ + FindClose (dirp->search_handle); + dirp->search_handle = INVALID_HANDLE_VALUE; + return NULL; + } + } + + /* copy as a multibyte character string */ + DIRENT_STRNCPY ( dirp->curentry.d_name, + dirp->find_data.cFileName, + sizeof(dirp->curentry.d_name) ); + dirp->curentry.d_name[MAX_PATH] = '\0'; + + /* compute the length of name */ + dirp->curentry.d_namlen = strlen (dirp->curentry.d_name); + + /* determine file type */ + attr = dirp->find_data.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + dirp->curentry.d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + dirp->curentry.d_type = DT_DIR; + } else { + dirp->curentry.d_type = DT_REG; + } + return &dirp->curentry; +} + + +/***************************************************************************** + * Close directory stream opened by opendir() function. Close of the + * directory stream invalidates the DIR structure as well as any previously + * read directory entry. + */ +static int closedir(DIR *dirp) +{ + if (dirp == NULL) { + /* invalid directory stream */ + DIRENT_SET_ERRNO (EBADF); + return -1; + } + + /* release search handle */ + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->search_handle); + dirp->search_handle = INVALID_HANDLE_VALUE; + } + + /* release directory structure */ + free (dirp); + return 0; +} + + +/***************************************************************************** + * Resets the position of the directory stream to which dirp refers to the + * beginning of the directory. It also causes the directory stream to refer + * to the current state of the corresponding directory, as a call to opendir() + * would have done. If dirp does not refer to a directory stream, the effect + * is undefined. + */ +static void rewinddir(DIR* dirp) +{ + if (dirp != NULL) { + /* release search handle */ + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->search_handle); + } + + /* open new search handle and retrieve the first entry */ + dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + /* a directory entry is now waiting in memory */ + dirp->cached = 1; + } else { + /* failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + } + } +} + + +#ifdef __cplusplus +} +#endif +#endif /*DIRENT_H*/ diff --git a/library/shm/CMakeLists.txt b/library/shm/CMakeLists.txt deleted file mode 100644 index 0f712cad3..000000000 --- a/library/shm/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -################################################################################ -# DFCONNECT -### -SET(DFCONNECT_HDRS -shms.h -mod-core.h -mod-maps.h -) - -SET(PROJECT_SRCS -mod-core.cpp -mod-maps.cpp -#mod-creature40d.cpp -) - -SET(PROJECT_HDRS_LINUX -) - -SET(PROJECT_HDRS_WINDOWS -) - -SET(PROJECT_SRCS_LINUX -shms-linux.cpp -) - -SET(PROJECT_SRCS_WINDOWS -shms-windows.cpp -) - -IF(UNIX) - LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_LINUX}) - LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_LINUX}) -ELSE(UNIX) - LIST(APPEND PROJECT_HDRS ${PROJECT_HDRS_WINDOWS}) - LIST(APPEND PROJECT_SRCS ${PROJECT_SRCS_WINDOWS}) -ENDIF(UNIX) - - -SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) - -LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) - -#IF(CMAKE_SIZEOF_VOID_P EQUAL 4) - add_definitions(-DBUILD_SHM) - IF(UNIX) - add_definitions(-DLINUX_BUILD) - SET(PROJECT_LIBS rt) - SET(CMAKE_CXX_FLAGS "-fvisibility=hidden") - ADD_LIBRARY(dfconnect SHARED ${PROJECT_SRCS}) - TARGET_LINK_LIBRARIES(dfconnect ${PROJECT_LIBS}) - ELSE(UNIX) - # SET(PROJECT_LIBS psapi) - ADD_LIBRARY(SDL SHARED ${PROJECT_SRCS}) - TARGET_LINK_LIBRARIES(SDL ${PROJECT_LIBS}) - ENDIF(UNIX) -#ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4) diff --git a/library/shm/mod-core.cpp b/library/shm/mod-core.cpp deleted file mode 100644 index 2fd54d6e9..000000000 --- a/library/shm/mod-core.cpp +++ /dev/null @@ -1,364 +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's core module. - */ - -#include -#include "dfhack/DFIntegers.h" -#include -#include -#include -#include - -#define SHM_INTERNAL // for things only visible to the SHM - -#include "shms.h" -#include "mod-core.h" -#include "mod-maps.h" -#include "mod-creature40d.h" - -std::vector module_registry; - -// shared by shms_OS -extern int errorstate; -extern char *shm; -extern int shmid; - -// file-globals -bool useYield = 0; -int currentClient = -1; - -#define SHMHDR ((shm_core_hdr *)shm) -#define SHMCMD ((uint32_t *)shm )[currentClient] -#define SHMDATA(type) ((type *)(shm + SHM_HEADER)) - -void ReadRaw (void * data) -{ - memcpy(SHMDATA(void), (void *) SHMHDR->address,SHMHDR->length); -} - -void ReadQuad (void * data) -{ - SHMHDR->Qvalue = *((uint64_t*) SHMHDR->address); -} - -void ReadDWord (void * data) -{ - SHMHDR->value = *((uint32_t*) SHMHDR->address); -} - -void ReadWord (void * data) -{ - SHMHDR->value = *((uint16_t*) SHMHDR->address); -} - -void ReadByte (void * data) -{ - SHMHDR->value = *((uint8_t*) SHMHDR->address); -} - -void WriteRaw (void * data) -{ - memcpy((void *)SHMHDR->address, SHMDATA(void),SHMHDR->length); -} - -void WriteQuad (void * data) -{ - (*(uint64_t*)SHMHDR->address) = SHMHDR->Qvalue; -} - -void WriteDWord (void * data) -{ - (*(uint32_t*)SHMHDR->address) = SHMHDR->value; -} - -void WriteWord (void * data) -{ - (*(uint16_t*)SHMHDR->address) = SHMHDR->value; -} - -void WriteByte (void * data) -{ - (*(uint8_t*)SHMHDR->address) = SHMHDR->value; -} - -void ReadSTLString (void * data) -{ - std::string * myStringPtr = (std::string *) SHMHDR->address; - unsigned int l = myStringPtr->length(); - SHMHDR->value = l; - // FIXME: there doesn't have to be a null terminator! - strncpy( SHMDATA(char),myStringPtr->c_str(),l+1); -} - -void WriteSTLString (void * data) -{ - std::string * myStringPtr = (std::string *) SHMHDR->address; - // here we DO expect a 0 terminator - myStringPtr->assign( SHMDATA(const char) ); -} - -// MIT HAKMEM bitcount -int bitcount(uint32_t n) -{ - register uint32_t tmp; - - tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111); - return ((tmp + (tmp >> 3)) & 030707070707) % 63; -} - -// get local and remote affinity, set up yield if required (single core available) -void CoreAttach (void * data) -{ - // sync affinity - uint32_t local = OS_getAffinity(); - uint32_t remote = SHMDATA(coreattach)->cl_affinity; - uint32_t pool = local | remote; - SHMDATA(coreattach)->sv_useYield = useYield = (bitcount(pool) == 1); - // return our PID - SHMDATA(coreattach)->sv_PID = OS_getPID(); - // return core version - SHMDATA(coreattach)->sv_version = module_registry[0].version; -} - -void FindModule (void * data) -{ - bool found = false; - modulelookup * payload = SHMDATA(modulelookup); - std::string test = payload->name; - uint32_t version = payload->version; - for(unsigned int i = 0; i < module_registry.size();i++) - { - if(module_registry[i].name == test && module_registry[i].version == version) - { - // gotcha - SHMHDR->value = i; - found = true; - break; - } - } - SHMHDR->error = !found; -} - -void FindCommand (void * data) -{ - bool found = false; - commandlookup * payload = SHMDATA(commandlookup); - std::string modname = payload->module; - std::string cmdname = payload->name; - uint32_t version = payload->version; - for(unsigned int i = 0; i < module_registry.size();i++) - { - if(module_registry[i].name == modname && module_registry[i].version == version) - { - for(unsigned int j = 0 ; j < module_registry[i].commands.size();j++) - { - if(module_registry[i].commands[j].name == cmdname) - { - // gotcha - SHMHDR->value = j + (i << 16); - SHMHDR->error = false; - return; - } - } - } - } - SHMHDR->error = true; -} - -void ReleaseSuspendLock( void * data ) -{ - OS_releaseSuspendLock(currentClient); -} - -void AcquireSuspendLock( void * data ) -{ - OS_lockSuspendLock(currentClient); -} - - -DFPP_module 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); - // basic states - core.set_command(CORE_RUNNING, CANCELLATION, "Running"); - //core.set_command(CORE_RUN, FUNCTION, "Run!",AcquireSuspendLock,CORE_RUNNING); - core.set_command(CORE_RUN, CANCELLATION, "Run!",0,CORE_RUNNING); - core.set_command(CORE_STEP, CANCELLATION, "Suspend on next step",0,CORE_SUSPEND);// set command to CORE_SUSPEND, check next client - core.set_command(CORE_SUSPEND, FUNCTION, "Suspend", ReleaseSuspendLock , CORE_SUSPENDED, LOCKING_LOCKS); - core.set_command(CORE_SUSPENDED, CLIENT_WAIT, "Suspended"); - core.set_command(CORE_ERROR, CANCELLATION, "Error"); - - // utility commands - core.set_command(CORE_ATTACH, FUNCTION,"Core attach",CoreAttach, CORE_SUSPENDED); - core.set_command(CORE_ACQUIRE_MODULE, FUNCTION, "Module lookup", FindModule, CORE_SUSPENDED); - core.set_command(CORE_ACQUIRE_COMMAND, FUNCTION, "Command lookup", FindCommand, CORE_SUSPENDED); - - // raw reads - core.set_command(CORE_READ, FUNCTION,"Raw read",ReadRaw, CORE_SUSPENDED); - core.set_command(CORE_READ_QUAD, FUNCTION,"Read QUAD",ReadQuad, CORE_SUSPENDED); - core.set_command(CORE_READ_DWORD, FUNCTION,"Read DWORD",ReadDWord, CORE_SUSPENDED); - core.set_command(CORE_READ_WORD, FUNCTION,"Read WORD",ReadWord, CORE_SUSPENDED); - core.set_command(CORE_READ_BYTE, FUNCTION,"Read BYTE",ReadByte, CORE_SUSPENDED); - - // raw writes - core.set_command(CORE_WRITE, FUNCTION, "Raw write", WriteRaw, CORE_SUSPENDED); - core.set_command(CORE_WRITE_QUAD, FUNCTION, "Write QUAD", WriteQuad, CORE_SUSPENDED); - core.set_command(CORE_WRITE_DWORD, FUNCTION, "Write DWORD", WriteDWord, CORE_SUSPENDED); - core.set_command(CORE_WRITE_WORD, FUNCTION, "Write WORD", WriteWord, CORE_SUSPENDED); - core.set_command(CORE_WRITE_BYTE, FUNCTION, "Write BYTE", WriteByte, CORE_SUSPENDED); - - // stl string commands - core.set_command(CORE_READ_STL_STRING, FUNCTION, "Read STL string", ReadSTLString, CORE_SUSPENDED); - core.set_command(CORE_READ_C_STRING, CLIENT_WAIT, "RESERVED"); - core.set_command(CORE_WRITE_STL_STRING, FUNCTION, "Write STL string", WriteSTLString, CORE_SUSPENDED); - return core; -} - -void InitModules (void) -{ - // create the core module - module_registry.push_back(InitCore()); - module_registry.push_back(DFHack::Server::Maps::Init()); - //module_registry.push_back(DFHack::Server::Creatures::Init()); - for(int i = 0; i < module_registry.size();i++) - { - fprintf(stderr,"Initialized module %s, version %d\n",module_registry[i].name.c_str(),module_registry[i].version); - } - // TODO: dynamic module init -} - -void KillModules (void) -{ - for(unsigned int i = 0; i < module_registry.size();i++) - { - if(module_registry[i].modulestate) - free(module_registry[i].modulestate); - } - module_registry.clear(); -} - -void SHM_Act (void) -{ - volatile uint32_t atomic = 0; - if(errorstate) - { - return; - } - //static uint oldcl = 88; - for(currentClient = 0; currentClient < SHM_MAX_CLIENTS;currentClient++) - { - // set the offset for the shared memory used for the client - uint32_t numwaits = 0; - check_again: // goto target!!! - if(numwaits == 10000) - { - // this tests if there's a process on the other side - if(isValidSHM(currentClient)) - { - numwaits = 0; - } - else - { - full_barrier - SHMCMD = CORE_RUNNING; - fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n"); - } - } - full_barrier // I don't want the compiler to reorder my code. - - - //fprintf(stderr,"%d: %x %x\n",currentClient, (uint) SHMHDR, (uint) &(SHMHDR->cmd[currentClient])); - - // this is very important! copying two words separately from the command variable leads to inconsistency. - // Always copy the thing in one go. - // Also, this whole SHM thing probably only works on intel processors - atomic = SHMCMD; - full_barrier - - DFPP_module & mod = module_registry[ ((shm_cmd)atomic).parts.module ]; - DFPP_command & cmd = mod.commands[ ((shm_cmd)atomic).parts.command ]; - /* - if(atomic == CORE_RUNNING) - { - // we are running again for this process - // reaquire the suspend lock - OS_lockSuspendLock(currentClient); - continue; - } - full_barrier - */ - // set next state BEFORE we act on the command - good for locks - if(cmd.locking == LOCKING_LOCKS) - { - if(cmd.nextState != -1) SHMCMD = cmd.nextState; - } - - if(cmd._function) - { - cmd._function(mod.modulestate); - } - full_barrier - - // set next state AFTER we act on the command - good for busy waits - if(cmd.locking == LOCKING_BUSY) - { - /* - char text [512]; - char text2 [512]; - sprintf (text,"Client %d invoked %d:%d = %x = %s\n",currentClient,((shm_cmd)atomic).parts.module,((shm_cmd)atomic).parts.command, cmd._function,cmd.name.c_str()); - sprintf(text2, "Server set %d\n",cmd.nextState); - */ - // FIXME: WHAT HAPPENS WHEN A 'NEXTSTATE' IS FROM A DIFFERENT MODULE THAN 'CORE'? Yeah. It doesn't work. - if(cmd.nextState != -1) SHMCMD = cmd.nextState; - //MessageBox(0,text,text2, MB_OK); - - //fflush(stderr); // make sure this finds its way to the terminal! - - } - full_barrier - - if(cmd.type != CANCELLATION) - { - if(useYield) - { - SCHED_YIELD - } - numwaits ++; // watchdog timeout - goto check_again; - } - full_barrier - - // we are running again for this process - // reaquire the suspend lock - OS_lockSuspendLock(currentClient); - } -} diff --git a/library/shm/mod-core.h b/library/shm/mod-core.h deleted file mode 100644 index a5540a0a0..000000000 --- a/library/shm/mod-core.h +++ /dev/null @@ -1,100 +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. -*/ - -#ifndef SHMS_CORE_H -#define SHMS_CORE_H - -// increment on every core change -#define CORE_VERSION 10 - -typedef struct -{ - shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY! - uint32_t address; - uint32_t value; - uint32_t length; - uint32_t error; - uint64_t Qvalue; -} shm_core_hdr; - -typedef struct -{ - uint32_t version; - char name[256]; -} modulelookup; - -typedef struct -{ - uint32_t version; - char module[256]; - char name[256]; -} commandlookup; - -typedef struct -{ - uint32_t sv_version; // output - uint32_t cl_affinity; // input - uint32_t sv_PID; // output - uint32_t sv_useYield; // output -} coreattach; - -enum CORE_COMMAND -{ - // basic states - CORE_RUNNING = 0, // no command, normal server execution - CORE_RUN, // sent by the client to restart the server execution - CORE_STEP, // client suspend sets step - CORE_SUSPEND, // client notifies server to wait for commands (server is stalled in busy wait) - CORE_SUSPENDED, // response to WAIT, server is stalled in busy wait - CORE_ERROR, // there was a server error - - // utility commands - CORE_ATTACH, // compare affinity, get core version and process ID - CORE_ACQUIRE_MODULE, // get index of a loaded module by name and version - CORE_ACQUIRE_COMMAND, // get module::command callsign by module name, command name and module version - - // raw reads - CORE_READ, // cl -> sv, read some data - CORE_READ_QUAD, // cl -> sv, read a quad - CORE_READ_DWORD, // cl -> sv, read a dword - CORE_READ_WORD, // cl -> sv, read a word - CORE_READ_BYTE, // cl -> sv, read a byte - - // raw writes - CORE_WRITE,// client writes to server - CORE_WRITE_QUAD,// client writes a QUAD to server - CORE_WRITE_DWORD,// client writes a DWORD to server - CORE_WRITE_WORD,// client writes a WORD to server - CORE_WRITE_BYTE,// client writes a BYTE to server - - // string functions - CORE_READ_STL_STRING,// client requests contents of STL string at address - CORE_READ_C_STRING,// client requests contents of a C string at address, max length (0 means zero terminated) - CORE_WRITE_STL_STRING,// client wants to set STL string at address to something - - // total commands - NUM_CORE_CMDS -}; -#endif - diff --git a/library/shm/mod-creature2010.h b/library/shm/mod-creature2010.h deleted file mode 100644 index 64a9936a6..000000000 --- a/library/shm/mod-creature2010.h +++ /dev/null @@ -1,105 +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. -*/ - -#ifndef MOD_CREATURES2010_H -#define MOD_CREATURES2010_H - -namespace DFHack -{ - namespace Creatures2010 - { - -#define CREATURES2010_VERSION 1 -typedef struct -{ - // creature offsets - uint32_t vector; - uint32_t pos_offset; - uint32_t profession_offset; - uint32_t custom_profession_offset; - uint32_t race_offset; - int32_t civ_offset; - uint32_t flags1_offset; - uint32_t flags2_offset; - uint32_t name_offset; - uint32_t sex_offset; - uint32_t caste_offset; - uint32_t id_offset; - uint32_t labors_offset; - uint32_t happiness_offset; - uint32_t artifact_name_offset; - uint32_t physical_offset; - uint32_t mood_offset; - uint32_t mood_skill_offset; - uint32_t pickup_equipment_bit; - uint32_t soul_vector_offset; - uint32_t default_soul_offset; - uint32_t current_job_offset; - // soul offsets - uint32_t soul_skills_vector_offset; - // name offsets (needed for reading creature names) - uint32_t name_firstname_offset; - uint32_t name_nickname_offset; - uint32_t name_words_offset; - uint32_t soul_mental_offset; - uint32_t soul_traits_offset; - uint32_t appearance_vector_offset; - uint32_t birth_year_offset; - uint32_t birth_time_offset; - uint32_t inventory_offset; -} creature_offsets; - -typedef struct -{ - bool inited; - creature_offsets offsets; -} creature_modulestate; - -typedef struct -{ - shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY! - // box - uint32_t x; - uint32_t y; - uint32_t z; - uint32_t x2; - uint32_t y2; - uint32_t z2; - // starting index - int32_t index; -} shm_creature_hdr; - -enum CREATURE_COMMAND -{ - CREATURE_INIT = 0, // initialization - CREATURE_FIND_IN_BOX, - CREATURE_AT_INDEX, - NUM_CREATURE_CMDS -}; -DFPP_module Init(void); - - } -} - -#endif diff --git a/library/shm/mod-creature40d.cpp b/library/shm/mod-creature40d.cpp deleted file mode 100644 index 627719a0c..000000000 --- a/library/shm/mod-creature40d.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include - -#include "shms.h" -#include "mod-core.h" -#include "mod-creature40d.h" -#include -#include - -#include -#include -#include -#include - -extern char *shm; - -namespace DFHack{ - namespace Server{ - namespace Creatures{ // start of namespace - -#define SHMHDR ((shm_creature_hdr *)shm) -#define SHMDATA(type) ((type *)(shm + SHM_HEADER)) - -void readName(t_name & name, char * address, creature_offsets & offsets) -{ - // custom profession - std::string * fname = (std::string *) (address + offsets.name_firstname_offset); - strncpy(name.first_name,fname->c_str(),127); - name.first_name[127] = 0; - - std::string * nname = (std::string *) (address + offsets.name_nickname_offset); - strncpy(name.nickname,nname->c_str(),127); - name.nickname[127] = 0; - - memcpy(name.words, (void *)(address + offsets.name_words_offset), 48); -} - -void InitOffsets (void* data) -{ - creature_modulestate * state = (creature_modulestate *) data; - memcpy((void *) &(state->offsets), SHMDATA(void), sizeof(creature_offsets)); - ((creature_modulestate *) data)->inited = true; -} - -void ReadCreatureAtIndex(void *data) -{ - creature_modulestate * state = (creature_modulestate *) data; - creature_offsets & offsets = state->offsets; - std::vector * creaturev = (std::vector *) (offsets.creature_vector + offsets.vector_correct); - uint32_t length = creaturev->size(); - int32_t index = SHMHDR->index; - - // read pointer from vector at position - char * temp = (char *) creaturev->at (index); - t_creature *furball = SHMDATA(t_creature); - furball->origin = (uint32_t) temp; - //read creature from memory - memcpy(&(furball->x),temp + offsets.creature_pos_offset,3* sizeof(uint16_t)); - furball->type = *(uint32_t *) (temp + offsets.creature_type_offset); - furball->flags1.whole = *(uint32_t *) (temp + offsets.creature_flags1_offset); - furball->flags2.whole = *(uint32_t *) (temp + offsets.creature_flags2_offset); - // names - - readName(furball->name,temp + offsets.creature_name_offset, offsets); - readName(furball->squad_name, temp + offsets.creature_squad_name_offset, offsets); - readName(furball->artifact_name, temp + offsets.creature_artifact_name_offset, offsets); - - // custom profession - std::string * custprof = (std::string *) (temp + offsets.creature_custom_profession_offset); - strncpy(furball->custom_profession,custprof->c_str(),127); - furball->custom_profession[127] = 0; - - // labors - memcpy(furball->labors, temp + offsets.creature_labors_offset, NUM_CREATURE_LABORS); - - // traits - memcpy(furball->traits, temp + offsets.creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS); - - typedef struct - { - uint8_t id; - junk_fill <3> fill1; - uint8_t rating; - junk_fill <3> fill2; - uint16_t experience; - } raw_skill; - // learned skills - std::vector * skillv = (std::vector *) (temp + offsets.creature_skills_offset + offsets.vector_correct); - furball->numSkills = skillv->size(); - for (uint32_t i = 0; i < furball->numSkills;i++) - { - //skills.read(i, (uint8_t *) &temp2); - // a byte: this gives us 256 skills maximum. - furball->skills[i].id = ( (raw_skill*) skillv->at(i))->id; - furball->skills[i].rating = ( (raw_skill*) skillv->at(i))->rating; - furball->skills[i].experience = ( (raw_skill*) skillv->at(i))->experience; - } - // profession - furball->profession = *(uint8_t *) (temp + offsets.creature_profession_offset); - // current job HACK: the job object isn't cleanly represented here - uint32_t jobIdAddr = *(uint32_t *) (temp + offsets.creature_current_job_offset); - - if (jobIdAddr) - { - furball->current_job.active = true; - furball->current_job.jobId = *(uint8_t *) (jobIdAddr + offsets.creature_current_job_id_offset); - } - else - { - furball->current_job.active = false; - } - - //likes - std::vector * likev = (std::vector *) (temp + offsets.creature_likes_offset + offsets.vector_correct); - furball->numLikes = likev->size(); - for(uint32_t i = 0;inumLikes;i++) - { - memcpy(&furball->likes[i], likev->at(i), sizeof(t_skill)); - } - - furball->mood = *(int16_t *) (temp + offsets.creature_mood_offset); - - - furball->happiness = *(uint32_t *) (temp + offsets.creature_happiness_offset); - furball->id = *(uint32_t *) (temp + offsets.creature_id_offset); - furball->agility = *(uint32_t *) (temp + offsets.creature_agility_offset); - furball->strength = *(uint32_t *) (temp + offsets.creature_strength_offset); - furball->toughness = *(uint32_t *) (temp + offsets.creature_toughness_offset); - furball->money = *(uint32_t *) (temp + offsets.creature_money_offset); - furball->squad_leader_id = *(int32_t*) (temp + offsets.creature_squad_leader_id_offset); - furball->sex = *(uint8_t*) (temp + offsets.creature_sex_offset); - - furball->pregnancy_timer = *(uint32_t *)(temp+offsets.creature_pregnancy_offset); - furball->blood_max = *(int32_t*) (temp+offsets.creature_blood_max_offset); - furball->blood_current = *(int32_t*) (temp+offsets.creature_blood_current_offset); - furball->bleed_rate = *(uint32_t*) (temp+offsets.creature_bleed_offset); -} - -void FindNextCreatureInBox (void * data) -{ - int32_t index = SHMHDR->index; - // sanity - if(index == -1) return; - - creature_modulestate * state = (creature_modulestate *) data; - creature_offsets & offsets = state->offsets; - uint32_t x,y,z,x2,y2,z2; - - x = SHMHDR->x; x2 = SHMHDR->x2; - y = SHMHDR->y; y2 = SHMHDR->y2; - z = SHMHDR->z; z2 = SHMHDR->x2; - - std::vector * creaturev = (std::vector *) (offsets.creature_vector + offsets.vector_correct); - - uint32_t length = creaturev->size(); - typedef uint16_t coords[3]; - - // look at all creatures, starting at index - // if you find one in the specified 'box', return the creature in the data - // section and the index in the header - for(;index < length;index++) - { - coords& coo = *(coords*) (creaturev->at(index) + offsets.creature_pos_offset); - if(coo[0] >=x && coo[0] < x2 - && coo[1] >=y && coo[1] < y2 - && coo[2] >=z && coo[2] < z2) - { - // we found a creature! - SHMHDR->index = index; - ReadCreatureAtIndex(data); - return; // we're done here - } - } - // nothing found - SHMHDR->index = -1; -} - -DFPP_module Init( void ) -{ - DFPP_module creatures; - creatures.name = "Creatures40d"; - creatures.version = CREATURES40D_VERSION; - // freed by the core - creatures.modulestate = malloc(sizeof(creature_modulestate)); // we store a flag - memset(creatures.modulestate,0,sizeof(creature_modulestate)); - - creatures.reserve(NUM_CREATURE_CMDS); - - creatures.set_command(CREATURE_INIT, FUNCTION, "Supply the Creature40d module with offsets",InitOffsets,CORE_SUSPENDED); - creatures.set_command(CREATURE_FIND_IN_BOX, FUNCTION, "Get next creature in a box, return new index or -1", FindNextCreatureInBox, CORE_SUSPENDED); - creatures.set_command(CREATURE_AT_INDEX, FUNCTION, "Get creature at index", ReadCreatureAtIndex, CORE_SUSPENDED); - - return creatures; -} - -}}} // end of namespace diff --git a/library/shm/mod-creature40d.h b/library/shm/mod-creature40d.h deleted file mode 100644 index 7b835c766..000000000 --- a/library/shm/mod-creature40d.h +++ /dev/null @@ -1,109 +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. -*/ - -#ifndef MOD_CREATURES40D_H -#define MOD_CREATURES40D_H - -namespace DFHack -{ - namespace Server - { - namespace Creatures - { - -#define CREATURES40D_VERSION 1 -typedef struct -{ - // creature offsets - uint32_t creature_vector; - uint32_t creature_pos_offset; - uint32_t creature_type_offset; - uint32_t creature_flags1_offset; - uint32_t creature_flags2_offset; - uint32_t creature_name_offset; - uint32_t creature_custom_profession_offset; - uint32_t creature_profession_offset; - uint32_t creature_sex_offset; - uint32_t creature_id_offset; - uint32_t creature_squad_name_offset; - uint32_t creature_squad_leader_id_offset; - uint32_t creature_money_offset; - uint32_t creature_current_job_offset; - uint32_t creature_current_job_id_offset; - uint32_t creature_strength_offset; - uint32_t creature_agility_offset; - uint32_t creature_toughness_offset; - uint32_t creature_skills_offset; - uint32_t creature_labors_offset; - uint32_t creature_happiness_offset; - uint32_t creature_traits_offset; - uint32_t creature_likes_offset; - uint32_t creature_artifact_name_offset; - uint32_t creature_mood_offset; - uint32_t creature_pregnancy_offset; - uint32_t creature_blood_max_offset; - uint32_t creature_blood_current_offset; - uint32_t creature_bleed_offset; - // name offsets (needed for reading creature names) - uint32_t name_firstname_offset; - uint32_t name_nickname_offset; - uint32_t name_words_offset; - // HACK: vector address correction for SHM server - int32_t vector_correct; -} creature_offsets; - -typedef struct -{ - bool inited; - creature_offsets offsets; -} creature_modulestate; - -typedef struct -{ - shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY! - // box - uint32_t x; - uint32_t y; - uint32_t z; - uint32_t x2; - uint32_t y2; - uint32_t z2; - // starting index - int32_t index; -} shm_creature_hdr; - -enum CREATURE_COMMAND -{ - CREATURE_INIT = 0, // initialization - CREATURE_FIND_IN_BOX, - CREATURE_AT_INDEX, - NUM_CREATURE_CMDS -}; -DFPP_module Init(void); - - } - } -} -#endif - diff --git a/library/shm/mod-maps.cpp b/library/shm/mod-maps.cpp deleted file mode 100644 index 4274b47a2..000000000 --- a/library/shm/mod-maps.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include - -#include "shms.h" -#include "mod-core.h" -#include "mod-maps.h" -#include -#include -using namespace DFHack; -using namespace DFHack::Server::Maps; - -#include -#include - -extern char *shm; - -//TODO: circular buffer streaming primitives required -//TODO: commands can fail without the proper offsets. Hot to handle that? - -namespace DFHack{ - namespace Server{ // start of namespace - namespace Maps{ // start of namespace - -#define SHMHDR ((shm_maps_hdr *)shm) -#define SHMCMD ((shm_cmd *)shm)->pingpong -#define SHMDATA(type) ((type *)(shm + SHM_HEADER)) - -void NullCommand (void* data) -{ -}; - -void InitOffsets (void* data) -{ - maps_modulestate * state = (maps_modulestate *) data; - memcpy((void *) &(state->offsets), SHMDATA(void), sizeof(maps_offsets)); - ((maps_modulestate *) data)->inited = true; -} - -void GetMapSize (void *data) -{ - maps_modulestate * state = (maps_modulestate *) data; - if(state->inited) - { - SHMHDR->x = *(uint32_t *) (state->offsets.x_count_offset); - SHMHDR->y = *(uint32_t *) (state->offsets.y_count_offset); - SHMHDR->z = *(uint32_t *) (state->offsets.z_count_offset); - SHMHDR->error = false; - } - else - { - SHMHDR->error = true; - } -} - -struct mblock -{ - uint32_t * ptr_to_dirty; -}; - -inline void ReadBlockByAddress (void * data) -{ - maps_modulestate * state = (maps_modulestate *) data; - maps_offsets & offsets = state->offsets; - mblock * block = (mblock *) SHMHDR->address; - if(block) - { - memcpy(&(SHMDATA(mapblock40d)->tiletypes), ((char *) block) + offsets.tile_type_offset, sizeof(SHMDATA(mapblock40d)->tiletypes)); - memcpy(&(SHMDATA(mapblock40d)->designation), ((char *) block) + offsets.designation_offset, sizeof(SHMDATA(mapblock40d)->designation)); - memcpy(&(SHMDATA(mapblock40d)->occupancy), ((char *) block) + offsets.occupancy_offset, sizeof(SHMDATA(mapblock40d)->occupancy)); - memcpy(&(SHMDATA(mapblock40d)->biome_indices), ((char *) block) + offsets.biome_stuffs, sizeof(SHMDATA(mapblock40d)->biome_indices)); - SHMDATA(mapblock40d)->blockflags.whole = *block->ptr_to_dirty; - - SHMDATA(mapblock40d)->local_feature = *(int16_t *)((char*) block + offsets.local_feature_offset); - SHMDATA(mapblock40d)->global_feature = *(int16_t *)((char*) block + offsets.global_feature_offset); - - SHMDATA(mapblock40d)->origin = (uint32_t)(uint64_t)block; // this is STUPID - SHMHDR->error = false; - } - else - { - SHMHDR->error = true; - } -} - -void ReadBlockByCoords (void * data) -{ - maps_modulestate * state = (maps_modulestate *) data; - maps_offsets & offsets = state->offsets; - /* map_offset is a pointer to - a pointer to - an X block of pointers to - an Y blocks of pointers to - a Z blocks of pointers to - map blocks - only Z blocks can have NULL pointers? TODO: verify - */ - mblock * *** mapArray = *(mblock * ****)offsets.map_offset; - SHMHDR->address = (uint32_t) (uint64_t) mapArray[SHMHDR->x][SHMHDR->y][SHMHDR->z];// this is STUPID - ReadBlockByAddress(data); // I wonder... will this inline properly? -} - -DFPP_module Init( void ) -{ - DFPP_module maps; - maps.name = "Maps"; - maps.version = MAPS_VERSION; - // freed by the core - maps.modulestate = malloc(sizeof(maps_modulestate)); // we store a flag - memset(maps.modulestate,0,sizeof(maps_modulestate)); - - maps.reserve(NUM_MAPS_CMDS); - - // client sends a maps_offsets struct -> inited = true; - maps.set_command(MAP_INIT, FUNCTION, "Supply the module with offsets",InitOffsets,CORE_SUSPENDED); - maps.set_command(MAP_GET_SIZE, FUNCTION, "Get map size in 16x16x1 tile blocks", GetMapSize, CORE_SUSPENDED); - maps.set_command(MAP_READ_BLOCK_BY_COORDS, FUNCTION, "Read the whole block with specified coords", ReadBlockByCoords, CORE_SUSPENDED); - maps.set_command(MAP_READ_BLOCK_BY_ADDRESS, FUNCTION, "Read the whole block from an address", ReadBlockByAddress, CORE_SUSPENDED); - - // will it fit into 1MB? We shouldn't assume this is the case - maps.set_command(MAP_READ_BLOCKTREE, FUNCTION,"Get the tree of block pointers as a single structure", NullCommand, CORE_SUSPENDED); - - // really doesn't fit into 1MB, there should be a streaming variant to better utilize context switches - maps.set_command(MAP_READ_BLOCKS_3D, FUNCTION, "Read a range of blocks between two sets of coords", NullCommand, CORE_SUSPENDED); - - return maps; -} - -}}} // end of namespace diff --git a/library/shm/mod-maps.h b/library/shm/mod-maps.h deleted file mode 100644 index 8ae72cbcc..000000000 --- a/library/shm/mod-maps.h +++ /dev/null @@ -1,134 +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. -*/ - -#ifndef MOD_MAPS_H -#define MOD_MAPS_H - -#include "dfhack/DFTypes.h" - -namespace DFHack -{ - namespace Server - { - namespace Maps - { -// increment on every change -#define MAPS_VERSION 5 -typedef struct -{ - uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data"); - uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count"); - uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count"); - uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count"); - /* - Block - */ - uint32_t tile_type_offset;// = d->offset_descriptor->getOffset ("type"); - uint32_t designation_offset;// = d->offset_descriptor->getOffset ("designation"); - uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy"); - uint32_t biome_stuffs;// = d->offset_descriptor->getOffset ("biome_stuffs"); - uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein"); - uint32_t vegvector; - uint32_t temperature1_offset; - uint32_t temperature2_offset; - uint32_t global_feature_offset; - uint32_t local_feature_offset; - - uint32_t vein_mineral_vptr; - uint32_t vein_ice_vptr; - uint32_t vein_spatter_vptr; - uint32_t vein_grass_vptr; - uint32_t vein_worldconstruction_vptr; - /* - GEOLOGY - */ - uint32_t region_x_offset;// = minfo->getAddress ("region_x"); - uint32_t region_y_offset;// = minfo->getAddress ("region_y"); - uint32_t region_z_offset;// = minfo->getAddress ("region_z"); - - uint32_t world_regions;// mem->getAddress ("ptr2_region_array"); - uint32_t region_size;// = minfo->getHexValue ("region_size"); - uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off"); - uint32_t world_geoblocks_vector;// = minfo->getOffset ("geoblock_vector"); - uint32_t world_size_x;// = minfo->getOffset ("world_size_x"); - uint32_t world_size_y;// = minfo->getOffset ("world_size_y"); - uint32_t geolayer_geoblock_offset;// = minfo->getOffset ("geolayer_geoblock_offset"); - uint32_t type_inside_geolayer;// = mem->getOffset ("type_inside_geolayer"); - - /* - FEATURES - */ - uint32_t world_data; - uint32_t local_f_start; // offset from world_data or absolute address. - uint32_t local_material; - uint32_t local_submaterial; - uint32_t global_vector; // offset from world_data or absolute address. - uint32_t global_funcptr; - uint32_t global_material; - uint32_t global_submaterial; - /* - * Vegetation - */ - uint32_t tree_desc_offset; -} maps_offsets; - -typedef struct -{ - bool inited; - maps_offsets offsets; -} maps_modulestate; - -typedef struct -{ - shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY! - uint32_t x; - uint32_t y; - uint32_t z; - uint32_t x2; - uint32_t y2; - uint32_t z2; - uint32_t address; - uint32_t error; -} shm_maps_hdr; - -enum MAPS_COMMAND -{ - MAP_INIT = 0, // initialization - MAP_PROBE, // check if the map is still there - MAP_GET_SIZE, // get the map size in 16x16x1 blocks - MAP_READ_BLOCKTREE, // read the structure of pointers to blocks - MAP_READ_BLOCK_BY_COORDS, // read block by cords - MAP_READ_BLOCK_BY_ADDRESS, // read block by address - MAP_WRITE_BLOCK, - MAP_READ_BLOCKS_3D, // read blocks between two coords (volumetric) - MAP_READ_ALL_BLOCKS, // read the entire map - MAP_REVEAL, // reveal the whole map - NUM_MAPS_CMDS -}; -DFPP_module Init(void); - } - } -} -#endif - diff --git a/library/shm/readme.txt b/library/shm/readme.txt deleted file mode 100644 index 54ab2d6d4..000000000 --- a/library/shm/readme.txt +++ /dev/null @@ -1,14 +0,0 @@ -Using the shm server: -copy files to DF/libs folder -g++ -fPIC -c dfconnect.c -o dfconnect.o -g++ -shared -o dfconnect.so dfconnect.o -ldl - -edit DF/df script and add this line just before DF is called: -export LD_PRELOAD="./libs/dfconnect.so" # Hack DF! - -save and run the script! - -Has to be compiled for 32bit arch, otherwise the library isn't recognised. Client can be any arch. - -Precompiled dfconnect library is made available. dfconnect.so goes in DF/libs, df-hacked script goes in DF/ -Run ./df-hacked to use the shared memory API \ No newline at end of file diff --git a/library/shm/shms-linux.cpp b/library/shm/shms-linux.cpp deleted file mode 100644 index 9c601de12..000000000 --- a/library/shm/shms-linux.cpp +++ /dev/null @@ -1,402 +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 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "shms.h" -#include "mod-core.h" -#include - -#define DFhackCExport extern "C" __attribute__ ((visibility("default"))) - -// various crud -int counter = 0; -int errorstate = 0; -char *shm = 0; -int shmid = 0; -bool inited = 0; - -int fd_svlock = -1; -int fd_cllock[SHM_MAX_CLIENTS]; -int fd_clSlock[SHM_MAX_CLIENTS]; -int held_clSlock[SHM_MAX_CLIENTS]; -int numheld = SHM_MAX_CLIENTS; - -/******************************************************************************* -* SHM part starts here * -*******************************************************************************/ -// is the other side still there? -bool isValidSHM(int which) -{ - // if we get the client lock here, the client process failed and we need to reclaim our suspend lock - if(lockf(fd_cllock[which],F_TLOCK,0) == 0) - { - // we get back our suspend lock from the cold, dead hands of the former client :P - OS_lockSuspendLock(which); - // free the client lock again - lockf(fd_cllock[which],F_ULOCK,0); - return false; - } - return true; -} - -uint32_t OS_getPID() -{ - return getpid(); -} - -uint32_t OS_getAffinity() -{ - cpu_set_t mask; - sched_getaffinity(0,sizeof(cpu_set_t),&mask); - // FIXME: truncation - uint32_t affinity = *(uint32_t *) &mask; - return affinity; -} - -void OS_lockSuspendLock(int which) -{ - if(numheld == SHM_MAX_CLIENTS) - return; - // lock not held by server and can be picked up. OK. - if(held_clSlock[which] == 0 && lockf(fd_clSlock[which],F_LOCK,0) == 0) - { - held_clSlock[which] = 1; - numheld++; - } - // lock couldn't be picked up! - else if (held_clSlock[which] == 0) - { - fprintf(stderr,"lock %d failed to lock\n", which); - } -} - -void OS_releaseSuspendLock(int which) -{ - /* - if(which >=0 && which < SHM_MAX_CLIENTS) - return; - */ - if(numheld != SHM_MAX_CLIENTS) - { - fprintf(stderr,"TOTAL FAILURE OF LOCKING SYSTEM\n"); - return; - } - // lock hel by server and can be released -> OK - if(held_clSlock[which] == 1 && lockf(fd_clSlock[which],F_ULOCK,0) == 0) - { - numheld--; - held_clSlock[which] = 0; - } - // locked and not can't be released? FAIL! - else if (held_clSlock[which] == 1) - fprintf(stderr,"lock %d failed to unlock\n", which); -} - -void SHM_Init ( void ) -{ - // check that we do this only once per process - if(inited) - { - fprintf(stderr, "SDL_Init was called twice or more!\n"); - return; - } - inited = true; - char name[256]; - char name2[256]; - // make folder structure for our lock files - sprintf(name, "/tmp/DFHack/%d",OS_getPID()); - mode_t createmode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; - mkdir("/tmp/DFHack", createmode); - mkdir(name, createmode); - - // create and lock the server lock file - sprintf(name2, "%s/SVlock",name); - fd_svlock = open(name2,O_WRONLY | O_CREAT, createmode); - lockf( fd_svlock, F_LOCK, 0 ); - - for(int i = 0; i < SHM_MAX_CLIENTS; i++) - { - // create the client lock file - sprintf(name2, "%s/CLlock%d",name,i); - fd_cllock[i] = open(name2,O_WRONLY | O_CREAT, createmode); - // get and lock the suspend locks - sprintf(name2, "%s/CLSlock%d",name,i); - fd_clSlock[i] = open(name2,O_WRONLY | O_CREAT, createmode); - lockf(fd_clSlock[i],F_LOCK,0); - held_clSlock[i] = 1; - } - - // name for the segment, an accident waiting to happen - key_t key = SHM_KEY + OS_getPID(); - - // find previous segment, check if it's used by some processes. - // if it isn't, kill it with fire - if ((shmid = shmget(key, SHM_SIZE, 0600)) != -1) - { - shmid_ds descriptor; - shmctl(shmid, IPC_STAT, &descriptor); - if(descriptor.shm_nattch == 0) - { - shmctl(shmid,IPC_RMID,NULL); - fprintf(stderr,"dfhack: killed dangling resources from crashed DF.\n"); - } - } - // create the segment, make sure only ww are really creating it - if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0600)) < 0) - { - perror("shmget"); - errorstate = 1; - return; - } - - // attach the segment - if ((shm = (char *) shmat(shmid, 0, 0)) == (char *) -1) - { - perror("shmat"); - errorstate = 1; - return; - } - full_barrier - // make sure we don't stall or do crazy stuff - for(int i = 0; i < SHM_MAX_CLIENTS;i++) - { - ((uint32_t *)shm)[i] = CORE_RUNNING; - } - InitModules(); -} - -void SHM_Destroy ( void ) -{ - if(inited && !errorstate) - { - KillModules(); - shmid_ds descriptor; - shmctl(shmid, IPC_STAT, &descriptor); - shmdt(shm); - while(descriptor.shm_nattch != 0) - { - shmctl(shmid, IPC_STAT, &descriptor); - } - shmctl(shmid,IPC_RMID,NULL); - - char name[256]; - char name2[256]; - sprintf(name, "/tmp/DFHack/%d",OS_getPID()); - - // unlock and close server lock, close client lock, destroy files - lockf(fd_svlock,F_ULOCK,0); - for(int i = 0; i < SHM_MAX_CLIENTS; i++) - { - close(fd_cllock[i]); - fd_cllock[i] = 0; - close(fd_clSlock[i]); - fd_clSlock[i] = 0; - held_clSlock[i] = 0; - sprintf(name2, "%s/CLlock%d",name,i); - unlink(name2); - sprintf(name2, "%s/CLSlock%d",name,i); - unlink(name2); - } - close(fd_svlock); - fd_svlock = 0; - sprintf(name2, "%s/SVlock",name); - unlink(name2); - // remove the PID folder - rmdir(name); - fprintf(stderr,"dfhack: destroyed shared segment.\n"); - inited = false; - } -} - -/******************************************************************************* -* SDL part starts here * -*******************************************************************************/ -// this is supported from 0.31.04 forward -DFhackCExport int SDL_NumJoysticks(void) -{ - if(errorstate) - return -1; - if(!inited) - { - SHM_Init(); - return -2; - } - SHM_Act(); - return -3; -} - - -// ptr to the real functions -//static void (*_SDL_GL_SwapBuffers)(void) = 0; -static void (*_SDL_Quit)(void) = 0; -static int (*_SDL_Init)(uint32_t flags) = 0; -//static int (*_SDL_Flip)(void * some_ptr) = 0; -/* -// hook - called every tick in OpenGL mode of DF -DFhackCExport void SDL_GL_SwapBuffers(void) -{ - if(_SDL_GL_SwapBuffers) - { - if(!errorstate) - { - SHM_Act(); - } - counter ++; - _SDL_GL_SwapBuffers(); - } -} -*/ -/* -// hook - called every tick in the 2D mode of DF -DFhackCExport int SDL_Flip(void * some_ptr) -{ - if(_SDL_Flip) - { - if(!errorstate) - { - SHM_Act(); - } - counter ++; - return _SDL_Flip(some_ptr); - } - return 0; -} -*/ - -// hook - called at program exit -DFhackCExport void SDL_Quit(void) -{ - if(!errorstate) - { - SHM_Destroy(); - errorstate = true; - } - if(_SDL_Quit) - { - _SDL_Quit(); - } -} - -// hook - called at program start, initialize some stuffs we'll use later -DFhackCExport int SDL_Init(uint32_t flags) -{ - // find real functions - //_SDL_GL_SwapBuffers = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_GL_SwapBuffers"); - _SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init"); - //_SDL_Flip = (int (*)( void * )) dlsym(RTLD_NEXT, "SDL_Flip"); - _SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit"); - - // check if we got them - if(/*_SDL_GL_SwapBuffers &&*/ _SDL_Init && _SDL_Quit) - { - fprintf(stderr,"dfhack: hooking successful\n"); - } - else - { - // bail, this would be a disaster otherwise - fprintf(stderr,"dfhack: something went horribly wrong\n"); - errorstate = true; - exit(1); - } - //SHM_Init(); - - return _SDL_Init(flags); -} -//*/ -/******************************************************************************* -* NCURSES part starts here * -*******************************************************************************/ - -static int (*_refresh)(void) = 0; -//extern NCURSES_EXPORT(int) refresh (void); -DFhackCExport int refresh (void) -{ - if(_refresh) - { - /* - if(!errorstate) - { - SHM_Act(); - } - counter ++; - */ - return _refresh(); - } - return 0; -} - -static int (*_endwin)(void) = 0; -//extern NCURSES_EXPORT(int) endwin (void); -DFhackCExport int endwin (void) -{ - if(!errorstate) - { - SHM_Destroy(); - errorstate = true; - } - if(_endwin) - { - return _endwin(); - } - return 0; -} - -typedef void WINDOW; -//extern NCURSES_EXPORT(WINDOW *) initscr (void); -static WINDOW * (*_initscr)(void) = 0; -DFhackCExport WINDOW * initscr (void) -{ - // find real functions - //_refresh = (int (*)( void )) dlsym(RTLD_NEXT, "refresh"); - _endwin = (int (*)( void )) dlsym(RTLD_NEXT, "endwin"); - _initscr = (WINDOW * (*)( void )) dlsym(RTLD_NEXT, "initscr"); - // check if we got them - if(_refresh && _endwin && _initscr) - { - fprintf(stderr,"dfhack: hooking successful\n"); - } - else - { - // bail, this would be a disaster otherwise - fprintf(stderr,"dfhack: something went horribly wrong\n"); - exit(1); - } - //SHM_Init(); - return _initscr(); -} diff --git a/library/shm/shms.h b/library/shm/shms.h deleted file mode 100644 index ce7913383..000000000 --- a/library/shm/shms.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DFCONNECT_H -#define DFCONNECT_H - -#define SHM_KEY 123466 -#define SHM_MAX_CLIENTS 4 -#define SHM_HEADER 1024 // 1kB reserved for a header -#define SHM_BODY 1024*1024 // 4MB reserved for bulk data transfer -#define SHM_SIZE SHM_HEADER+SHM_BODY -//#define SHM_ALL_CLIENTS SHM_MAX_CLIENTS*(SHM_SIZE) -//#define SHM_CL(client_idx) client_idx*(SHM_SIZE) - -// FIXME: add YIELD for linux, add single-core and multi-core compile targets for optimal speed -#ifdef LINUX_BUILD - // a full memory barrier! better be safe than sorry. - #define full_barrier asm volatile("" ::: "memory"); __sync_synchronize(); - #define SCHED_YIELD sched_yield(); // a requirement for single-core -#else - // we need windows.h for Sleep() - #define _WIN32_WINNT 0x0501 // needed for INPUT struct - #define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32 - #define WIN32_LEAN_AND_MEAN - #include - #define SCHED_YIELD Sleep(0); // avoids infinite lockup on single core - // FIXME: detect MSVC here and use the right barrier magic - #ifdef __MINGW32__ - #define full_barrier asm volatile("" ::: "memory"); - #else - #include - #pragma intrinsic(_ReadWriteBarrier) - #define full_barrier _ReadWriteBarrier(); - #endif -#endif - -enum DFPP_Locking -{ - LOCKING_BUSY = 0, - LOCKING_LOCKS = 1 -}; - -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 -{ - void (*_function)(void *); - DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons - std::string name; - uint32_t nextState; - DFPP_Locking locking; -}; - -struct DFPP_module -{ - DFPP_module() - { - name = "Uninitialized module"; - version = 0; - modulestate = 0; - } - // ALERT: the structures share state - DFPP_module(const DFPP_module & orig) - { - commands = orig.commands; - name = orig.name; - modulestate = orig.modulestate; - version = orig.version; - } - inline void set_command(const unsigned int index, const DFPP_CmdType type, const char * name, void (*_function)(void *) = 0,uint32_t nextState = -1, DFPP_Locking locking = LOCKING_BUSY) - { - commands[index].type = type; - commands[index].name = name; - commands[index]._function = _function; - commands[index].nextState = nextState; - commands[index].locking = locking; - } - inline void reserve (unsigned int numcommands) - { - commands.clear(); - DFPP_command cmd = {0,CANCELLATION,"",0}; - commands.resize(numcommands,cmd); - } - std::string name; - uint32_t version; // version - std::vector commands; - void * modulestate; -}; - -union shm_cmd -{ - struct - { - volatile uint16_t command; - volatile uint16_t module; - } parts; - volatile uint32_t pingpong; - shm_cmd(volatile uint32_t z) - { - pingpong = z; - } -}; - -void SHM_Act (void); -void InitModules (void); -void KillModules (void); -bool isValidSHM(int current); -uint32_t OS_getPID(); -uint32_t OS_getAffinity(); // limited to 32 processors. Silly, eh? -void OS_releaseSuspendLock(int currentClient); -void OS_lockSuspendLock(int currentClient); - -#endif diff --git a/offsetedit/CMakeLists.txt b/offsetedit/CMakeLists.txt deleted file mode 100644 index f8065bc4c..000000000 --- a/offsetedit/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -project(dfoffsetedit) -cmake_minimum_required(VERSION 2.6) -find_package(Qt4 QUIET) -if(QT4_FOUND) - add_subdirectory (src) -else(QT4_FOUND) - MESSAGE(STATUS "Qt4 libraries not found - offset editor can't be built.") -endif(QT4_FOUND) diff --git a/offsetedit/src/CMakeLists.txt b/offsetedit/src/CMakeLists.txt deleted file mode 100644 index 9a2218413..000000000 --- a/offsetedit/src/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) - -set ( dfoffsetedit_SRCS - dfedit.cpp - memxmlModel.cpp - main.cpp -) - -SET ( dfoffsetedit_UI - gui/main.ui -) - -SET( dfoffsetedit_RCS - gui/resources.qrc -) - -# this command will generate rules that will run rcc on all files from dfoffsetedit_RCS -# in result dfoffsetedit_RC_SRCS variable will contain paths to files produced by rcc -QT4_ADD_RESOURCES( dfoffsetedit_RC_SRCS ${dfoffsetedit_RCS} ) - -QT4_WRAP_UI(dfoffsetedit_UI_h ${dfoffsetedit_UI}) -qt4_automoc(${dfoffsetedit_SRCS}) - -add_executable(dfoffsetedit ${dfoffsetedit_SRCS} ${dfoffsetedit_RC_SRCS} ${dfoffsetedit_UI_h}) -target_link_libraries(dfoffsetedit ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ) \ No newline at end of file diff --git a/offsetedit/src/gui/dIsForDwarf.svg b/offsetedit/src/gui/dIsForDwarf.svg deleted file mode 100644 index 51b7acf0f..000000000 --- a/offsetedit/src/gui/dIsForDwarf.svg +++ /dev/null @@ -1,1621 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - D - D - - - - - - X - - - - - X - - - - - - - - - - - - - 32 x 32 + 16 x 16 - X - - - - - X - - - - - - diff --git a/offsetedit/src/gui/main.ui b/offsetedit/src/gui/main.ui deleted file mode 100644 index dfff8fa02..000000000 --- a/offsetedit/src/gui/main.ui +++ /dev/null @@ -1,195 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 633 - 622 - - - - MainWindow - - - - :/main_icon/main_64.png:/main_icon/main_64.png - - - - - - - - - - - - toolBar - - - TopToolBarArea - - - false - - - - - - - - - QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea - - - Description - - - 2 - - - - - - - - 1 - 1 - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Raised - - - 1 - - - 0 - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:xx-large; font-weight:600;">Title text</span></p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Some other text.</p></body></html> - - - Qt::AutoText - - - false - - - Qt::AlignTop - - - true - - - - - - - - - false - - - QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea - - - Entries - - - 1 - - - - - - - - - - - - - 0 - 0 - 633 - 22 - - - - - File - - - - - - - - - Settings - - - - - - - - - Open - - - - - Save - - - - - Save As - - - - - Quit - - - - - Run DF - - - - - Setup DF executables - - - - - - - - diff --git a/offsetedit/src/gui/main_16.png b/offsetedit/src/gui/main_16.png deleted file mode 100644 index 04367e58d..000000000 Binary files a/offsetedit/src/gui/main_16.png and /dev/null differ diff --git a/offsetedit/src/gui/main_32.png b/offsetedit/src/gui/main_32.png deleted file mode 100644 index 39137fed1..000000000 Binary files a/offsetedit/src/gui/main_32.png and /dev/null differ diff --git a/offsetedit/src/gui/main_64.png b/offsetedit/src/gui/main_64.png deleted file mode 100644 index e6823a94f..000000000 Binary files a/offsetedit/src/gui/main_64.png and /dev/null differ diff --git a/offsetedit/src/gui/resources.qrc b/offsetedit/src/gui/resources.qrc deleted file mode 100644 index 707294060..000000000 --- a/offsetedit/src/gui/resources.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - main_64.png - main_16.png - main_32.png - - diff --git a/offsetedit/src/main.cpp b/offsetedit/src/main.cpp deleted file mode 100644 index 36334656d..000000000 --- a/offsetedit/src/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include "dfedit.h" - - -int main(int argc, char** argv) -{ - QApplication app(argc, argv); - dfedit appGui; - appGui.show(); - return app.exec(); -} diff --git a/offsetedit/src/memxmlModel.cpp b/offsetedit/src/memxmlModel.cpp deleted file mode 100644 index 3df8849bf..000000000 --- a/offsetedit/src/memxmlModel.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2005-2006 Trolltech ASA. All rights reserved. -** -** This file was part of the example classes of the Qt Toolkit. -** Now it's being hacked into some other shape... :) -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.trolltech.com/products/qt/opensource.html -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://www.trolltech.com/products/qt/licensing.html or contact the -** sales department at sales@trolltech.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "memxmlModel.h" -#include -#include -#include -#include - -class DomItem -{ -public: - DomItem(QDomNode &node, int row, DomItem *parent = 0); - ~DomItem(); - DomItem *child(int i); - DomItem *parent(); - QDomNode node() const; - int row(); - -private: - QDomNode domNode; - QHash childItems; - DomItem *parentItem; - int rowNumber; -}; - -DomItem::DomItem(QDomNode &node, int row, DomItem *parent) -{ - domNode = node; - // Record the item's location within its parent. - rowNumber = row; - parentItem = parent; -} - -DomItem::~DomItem() -{ - QHash::iterator it; - for (it = childItems.begin(); it != childItems.end(); ++it) - delete it.value(); -} - -QDomNode DomItem::node() const -{ - return domNode; -} - -DomItem *DomItem::parent() -{ - return parentItem; -} - -DomItem *DomItem::child(int i) -{ - if (childItems.contains(i)) - return childItems[i]; - - if (i >= 0 && i < domNode.childNodes().count()) { - QDomNode childNode = domNode.childNodes().item(i); - DomItem *childItem = new DomItem(childNode, i, this); - childItems[i] = childItem; - return childItem; - } - return 0; -} - -int DomItem::row() -{ - return rowNumber; -} - -MemXMLModel::MemXMLModel(QDomDocument document, QObject *parent) - : QAbstractItemModel(parent), domDocument(document) -{ - rootItem = new DomItem(domDocument, 0); -} - -MemXMLModel::~MemXMLModel() -{ - delete rootItem; -} - -int MemXMLModel::columnCount(const QModelIndex & parent) const -{ - Q_UNUSED(parent); - return 3; -} - -QVariant MemXMLModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (role != Qt::DisplayRole) - return QVariant(); - - DomItem *item = static_cast(index.internalPointer()); - - QDomNode node = item->node(); - QStringList attributes; - QDomNamedNodeMap attributeMap = node.attributes(); - - switch (index.column()) { - case 0: - return node.nodeName(); - case 1: - for (int i = 0; (unsigned int)(i) < attributeMap.count(); ++i) - { - QDomNode attribute = attributeMap.item(i); - attributes << attribute.nodeName() + "=\"" +attribute.nodeValue() + "\""; - } - return attributes.join(" "); - case 2: - return node.nodeValue().split("\n").join(" "); - default: - return QVariant(); - } -} - -Qt::ItemFlags MemXMLModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::ItemIsEnabled; - } - - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -QVariant MemXMLModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Name"); - case 1: - return tr("Attributes"); - case 2: - return tr("Value"); - default: - return QVariant(); - } - } - - return QVariant(); -} - -QModelIndex MemXMLModel::index(int row, int column, const QModelIndex &parent) const -{ - DomItem *parentItem; - - if (!parent.isValid()) - parentItem = rootItem; - else - parentItem = static_cast(parent.internalPointer()); - - DomItem *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); -} - -QModelIndex MemXMLModel::parent(const QModelIndex &child) const -{ - if (!child.isValid()) - return QModelIndex(); - - DomItem *childItem = static_cast(child.internalPointer()); - DomItem *parentItem = childItem->parent(); - - if (!parentItem || parentItem == rootItem) - return QModelIndex(); - - return createIndex(parentItem->row(), 0, parentItem); -} - -int MemXMLModel::rowCount(const QModelIndex &parent) const -{ - DomItem *parentItem; - - if (!parent.isValid()) - parentItem = rootItem; - else - parentItem = static_cast(parent.internalPointer()); - - return parentItem->node().childNodes().count(); -} - -#include "memxmlModel.moc" diff --git a/offsetedit/src/memxmlModel.h b/offsetedit/src/memxmlModel.h deleted file mode 100644 index 2879f4b5f..000000000 --- a/offsetedit/src/memxmlModel.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef memxmlModel_H -#define memxmlModel_H - -#include -#include - -class DomItem; - -class MemXMLModel : public QAbstractItemModel -{ - Q_OBJECT -public: - MemXMLModel(QDomDocument document, QObject *parent = 0); - ~MemXMLModel(); - - QVariant data(const QModelIndex &index, int role) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &child) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - -private: - QDomDocument domDocument; - DomItem *rootItem; -}; -#endif // memxmlModel diff --git a/output/.gitignore b/output/.gitignore deleted file mode 100644 index ff94317d8..000000000 --- a/output/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Debug -Release -RelWithDebInfo diff --git a/output/stones.py b/output/stones.py deleted file mode 100644 index 2cc7a2d7f..000000000 --- a/output/stones.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -from pydfhack import API -DF = API("Memory.xml") - -if DF.Attach(): - Mats = DF.materials - stones = Mats.Read_Inorganic_Materials() - print "Dumping all stone" - for matgloss in stones: - print "ID %s, name %s" % (matgloss.id, matgloss.name) - DF.Detach() diff --git a/package/debian/99-dfhack.conf b/package/debian/99-dfhack.conf deleted file mode 100644 index a0a17e681..000000000 --- a/package/debian/99-dfhack.conf +++ /dev/null @@ -1,2 +0,0 @@ -# some settings required for dfhack. fucks up local security... -kernel.randomize_va_space = 0 \ No newline at end of file diff --git a/package/debian/postinst b/package/debian/postinst deleted file mode 100755 index 13f47935d..000000000 --- a/package/debian/postinst +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh - diff --git a/package/debian/postrm b/package/debian/postrm deleted file mode 100755 index 3b8cdfc62..000000000 --- a/package/debian/postrm +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -# do nothing. blah. \ No newline at end of file diff --git a/package/debian/preinst b/package/debian/preinst deleted file mode 100755 index 13f47935d..000000000 --- a/package/debian/preinst +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh - diff --git a/package/linux/dfhack b/package/linux/dfhack new file mode 100755 index 000000000..28ec21e98 --- /dev/null +++ b/package/linux/dfhack @@ -0,0 +1,74 @@ +#!/bin/sh + +# NOTE: This is dfhack's modification of the normal invocation script, +# changed to properly set LD_PRELOAD so as to run DFHACK. +# +# You can run DF under gdb by passing -g or --gdb as the first argument. +# +# If the file ".dfhackrc" exists in the DF directory or your home directory +# it will be sourced by this script, to let you set environmental variables. +# If it exists in both places it will first source the one in your home +# directory, then the on in the game directory. +# +# Shell variables .dfhackrc can set to affect this script: +# DF_GDB_OPTS: Options to pass to gdb, if it's being run +# DF_VALGRIND_OPTS: Options to pass to valgrind, if it's being run +# DF_HELGRIND_OPTS: Options to pass to helgrind, if it's being run +# DF_RESET_OPTS: Options to pass the reset command at the end of +# this script +# DF_POST_CMD: Shell command to be run at very end of script + +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. + +# User config files +RC=".dfhackrc" + +if [ -r "$HOME/$RC" ]; then + . $HOME/$RC +fi +if [ -r "./$RC" ]; then + . "./$RC" +fi + +# Now run + +case "$1" in + -g | --gdb) + shift + echo "set environment LD_PRELOAD=./libdfhack.so" > gdbcmd.tmp + gdb $DF_GDB_OPTS -x gdbcmd.tmp ./libs/Dwarf_Fortress $* + rm gdbcmd.tmp + ret=$? + ;; + -h | --helgrind) + shift + LD_PRELOAD=./libdfhack.so valgrind $DF_HELGRIND_OPTS --tool=helgrind --log-file=helgrind.log ./libs/Dwarf_Fortress $* + ret=$? + ;; + -v | --valgrind) + shift + LD_PRELOAD=./libdfhack.so valgrind $DF_VALGRIND_OPTS --log-file=valgrind.log ./libs/Dwarf_Fortress $* + ret=$? + ;; + -c | --callgrind) + shift + LD_PRELOAD=./libdfhack.so valgrind $DF_CALLGRIND_OPTS --tool=callgrind --separate-threads=yes --dump-instr=yes --instr-atstart=no --log-file=callgrind.log ./libs/Dwarf_Fortress $* + ret=$? + ;; + *) + LD_PRELOAD=./libdfhack.so ./libs/Dwarf_Fortress $* + ret=$? + ;; +esac + +# Reset terminal to sane state in case of a crash +reset $DF_RESET_OPTS + +if [ -n "$DF_POST_CMD" ]; then + eval $DF_POST_CMD +fi + +exit $ret diff --git a/package/ubuntu-10.10/99-dfhack.conf b/package/ubuntu-10.10/99-dfhack.conf deleted file mode 100644 index bc7cd2bc2..000000000 --- a/package/ubuntu-10.10/99-dfhack.conf +++ /dev/null @@ -1,6 +0,0 @@ -# some settings required for dfhack. fucks up local security... -# shame on kernel devs and ubuntu people for not providing -# an /official/ way to manipulate things and just putting up roadblocks -# instead of proper design -kernel.randomize_va_space = 0 -kernel.yama.ptrace_scope = 0 \ No newline at end of file diff --git a/package/ubuntu-10.10/postinst b/package/ubuntu-10.10/postinst deleted file mode 100755 index ed50fde48..000000000 --- a/package/ubuntu-10.10/postinst +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -echo "Setting required kernel parameters." -# I actually do it three times, hoping to hammer this into Ubuntu's dense skull. -sysctl -w kernel.randomize_va_space=0 -sysctl -w kernel.yama.ptrace_scope=0 -if grep -q "kernel.yama.ptrace_scope=0" /etc/sysctl.conf -then - echo "Already installed into /etc/sysctl.conf, doing nothing." -else - echo "kernel.randomize_va_space=0" >> /etc/sysctl.conf - echo "kernel.yama.ptrace_scope=0" >> /etc/sysctl.conf -fi - diff --git a/package/ubuntu-10.10/postrm b/package/ubuntu-10.10/postrm deleted file mode 100755 index 3b8cdfc62..000000000 --- a/package/ubuntu-10.10/postrm +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -# do nothing. blah. \ No newline at end of file diff --git a/package/ubuntu-10.10/preinst b/package/ubuntu-10.10/preinst deleted file mode 100755 index 13f47935d..000000000 --- a/package/ubuntu-10.10/preinst +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh - diff --git a/package/windows/SDLreal.dll b/package/windows/SDLreal.dll new file mode 100644 index 000000000..3ce97a59d Binary files /dev/null and b/package/windows/SDLreal.dll differ diff --git a/package/windows/sdl license.txt b/package/windows/sdl license.txt new file mode 100644 index 000000000..e819febfb --- /dev/null +++ b/package/windows/sdl license.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/output/doxygen/.keep b/plugins/.keep similarity index 100% rename from output/doxygen/.keep rename to plugins/.keep diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 000000000..f985fd95e --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,132 @@ +#FIXME: inherit all macros and stuff from the dfhack SDK +IF(UNIX) + add_definitions(-DLINUX_BUILD) + SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall") + SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -m32") + SET(CMAKE_C_FLAGS "-fvisibility=hidden -m32") +ENDIF() + +include_directories("${dfhack_SOURCE_DIR}/library/include") +MACRO(CAR var) + SET(${var} ${ARGV1}) +ENDMACRO(CAR) + +MACRO(CDR var junk) + SET(${var} ${ARGN}) +ENDMACRO(CDR) + +MACRO(LIST_CONTAINS var value) + SET(${var}) + FOREACH (value2 ${ARGN}) + IF (${value} STREQUAL ${value2}) + SET(${var} TRUE) + ENDIF (${value} STREQUAL ${value2}) + ENDFOREACH (value2) +ENDMACRO(LIST_CONTAINS) + +MACRO(PARSE_ARGUMENTS prefix arg_names option_names) + SET(DEFAULT_ARGS) + FOREACH(arg_name ${arg_names}) + SET(${prefix}_${arg_name}) + ENDFOREACH(arg_name) + FOREACH(option ${option_names}) + SET(${prefix}_${option} FALSE) + ENDFOREACH(option) + + SET(current_arg_name DEFAULT_ARGS) + SET(current_arg_list) + FOREACH(arg ${ARGN}) + LIST_CONTAINS(is_arg_name ${arg} ${arg_names}) + IF (is_arg_name) + SET(${prefix}_${current_arg_name} ${current_arg_list}) + SET(current_arg_name ${arg}) + SET(current_arg_list) + ELSE (is_arg_name) + LIST_CONTAINS(is_option ${arg} ${option_names}) + IF (is_option) + SET(${prefix}_${arg} TRUE) + ELSE (is_option) + SET(current_arg_list ${current_arg_list} ${arg}) + ENDIF (is_option) + ENDIF (is_arg_name) + ENDFOREACH(arg) + SET(${prefix}_${current_arg_name} ${current_arg_list}) +ENDMACRO(PARSE_ARGUMENTS) + +MACRO(DFHACK_PLUGIN) + PARSE_ARGUMENTS(PLUGIN + "LINK_LIBRARIES;DEPENDS" + "SOME_OPT" + ${ARGN} + ) + CAR(PLUGIN_NAME ${PLUGIN_DEFAULT_ARGS}) + CDR(PLUGIN_SOURCES ${PLUGIN_DEFAULT_ARGS}) + + ADD_LIBRARY(${PLUGIN_NAME} MODULE ${PLUGIN_SOURCES}) + TARGET_LINK_LIBRARIES(${PLUGIN_NAME} dfhack ${PLUGIN_LINK_LIBRARIES}) + IF(UNIX) + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES SUFFIX .plug.so PREFIX "") + ELSE() + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES SUFFIX .plug.dll) + ENDIF() + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DFHACK_PLUGIN_OUTPUT_DIR}) + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${DFHACK_PLUGIN_OUTPUT_DIR}) + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${DFHACK_PLUGIN_OUTPUT_DIR}) + install(TARGETS ${PLUGIN_NAME} + LIBRARY DESTINATION ${DFHACK_PLUGIN_DESTINATION} + RUNTIME DESTINATION ${DFHACK_PLUGIN_DESTINATION}) + #MESSAGE("Depends: ${PLUGIN_DEPENDS}") + #IF (PLUGIN_AUTO_INSTALL) + # MESSAGE("Auto install") + #ENDIF (PLUGIN_AUTO_INSTALL) + #IF (PLUGIN_NO_MODULE) + # MESSAGE("No module") + #ENDIF (PLUGIN_NO_MODULE) +ENDMACRO(DFHACK_PLUGIN) + +# add all subdirectories. can be used in those subdirectories, etc... +# needs a re-run of cmake to pick up the changes +#macro(RECURSE_DIRS) +# file(GLOB sub-dir RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *) +# foreach(dir ${sub-dir}) +# if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${dir}) +# add_subdirectory (${dir}) +# endif() +# endforeach() +#endmacro() + +#RECURSE_DIRS() + +OPTION(BUILD_QTPLUG "Build the experimental Qt plugin." OFF) +if(BUILD_QTPLUG) + add_subdirectory (qtplug) +endif() + +OPTION(BUILD_STONESENSE "Build stonesense (needs a checkout first)." OFF) +if(BUILD_STONESENSE) + add_subdirectory (stonesense) +endif() + + +OPTION(BUILD_KITTENS "Build the kittens plugin." OFF) +if(BUILD_KITTENS) + DFHACK_PLUGIN(kittens kittens.cpp) +endif() + +IF(UNIX) + OPTION(BUILD_VECTORS "Build the vectors search plugin." OFF) + if(BUILD_VECTORS) + DFHACK_PLUGIN(vectors vectors.cpp) + endif() +endif() + + +DFHACK_PLUGIN(reveal reveal.cpp) +DFHACK_PLUGIN(prospector prospector.cpp) +DFHACK_PLUGIN(rawdump rawdump.cpp) +DFHACK_PLUGIN(cleanmap cleanmap.cpp) +DFHACK_PLUGIN(weather weather.cpp) +DFHACK_PLUGIN(vdig vdig.cpp) +DFHACK_PLUGIN(colonies colonies.cpp) +DFHACK_PLUGIN(itemhacks itemhacks.cpp) +DFHACK_PLUGIN(notes notes.cpp) diff --git a/plugins/cleanmap.cpp b/plugins/cleanmap.cpp new file mode 100644 index 000000000..132b8bd4f --- /dev/null +++ b/plugins/cleanmap.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +DFhackCExport command_result cleanmap (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "cleanmap"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("cleanmap","Cleans the map from various substances. Options: 'snow' for removing snow, 'mud' for mud.",cleanmap)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +DFhackCExport command_result cleanmap (Core * c, vector & parameters) +{ + const uint32_t water_idx = 6; + const uint32_t mud_idx = 12; + + bool snow = false; + bool mud = false; + for(int i = 0; i < parameters.size();i++) + { + if(parameters[i] == "snow") + snow = true; + else if(parameters[i] == "mud") + mud = true; + } + c->Suspend(); + vector splatter; + DFHack::Maps *Mapz = c->getMaps(); + + // init the map + if(!Mapz->Start()) + { + c->con << "Can't init map." << std::endl; + c->Resume(); + return CR_FAILURE; + } + + uint32_t x_max,y_max,z_max; + Mapz->getSize(x_max,y_max,z_max); + + // walk the map + for(uint32_t x = 0; x< x_max;x++) + { + for(uint32_t y = 0; y< y_max;y++) + { + for(uint32_t z = 0; z< z_max;z++) + { + df_block * block = Mapz->getBlock(x,y,z); + if(block) + { + Mapz->SortBlockEvents(x,y,z,0,0,&splatter); + for(int i = 0; i < 16; i++) + for(int j = 0; j < 16; j++) + { + block->occupancy[i][j].bits.arrow_color = 0; + block->occupancy[i][j].bits.broken_arrows_variant = 0; + } + for(uint32_t i = 0; i < splatter.size(); i++) + { + DFHack::t_spattervein * vein = splatter[i]; + // filter snow + if(!snow && vein->mat1 == water_idx && vein->matter_state == DFHack::state_powder) + continue; + // filter mud + if(!mud && vein->mat1 == mud_idx && vein->matter_state == DFHack::state_solid) + continue; + Mapz->RemoveBlockEvent(x,y,z,(t_virtual *) vein); + } + } + } + } + } + c->Resume(); + return CR_OK; +} diff --git a/plugins/colonies.cpp b/plugins/colonies.cpp new file mode 100644 index 000000000..6674e64a0 --- /dev/null +++ b/plugins/colonies.cpp @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; +#include + +DFhackCExport command_result colonies (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "colonies"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("colonies", + "List or change wild colonies (ants hills and such)\ +\n Options: 'kill' = destroy all colonies\ +\n 'bees' = change all colonies to honey bees", + colonies)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +void destroyColonies(DFHack::SpawnPoints *points); +void convertColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials); +void showColonies(Core *c, DFHack::SpawnPoints *points, + DFHack::Materials *Materials); + +DFhackCExport command_result colonies (Core * c, vector & parameters) +{ + bool destroy = false; + bool convert = false; + + for(int i = 0; i < parameters.size();i++) + { + if(parameters[i] == "kill") + destroy = true; + else if(parameters[i] == "bees") + convert = true; + } + + if (destroy && convert) + { + + c->con << "Kill or make bees? DECIDE!" << std::endl; + return CR_FAILURE; + } + + c->Suspend(); + + Vermin * vermin = c->getVermin(); + Materials * materials = c->getMaterials(); + + SpawnPoints *points = vermin->getSpawnPoints(); + + if(!points->isValid()) + { + c->con << "vermin not supported for this DF version" << std::endl; + return CR_FAILURE; + } + + materials->ReadCreatureTypesEx(); + + if (destroy) + destroyColonies(points); + else if (convert) + convertColonies(points, materials); + else + showColonies(c, points, materials); + + delete points; + + vermin->Finish(); + materials->Finish(); + + c->Resume(); + return CR_OK; +} + +void destroyColonies(DFHack::SpawnPoints *points) +{ + uint32_t numSpawnPoints = points->size(); + for (uint32_t i = 0; i < numSpawnPoints; i++) + { + DFHack::t_spawnPoint sp; + points->Read(i, sp); + + if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp)) + { + sp.in_use = false; + points->Write(i, sp); + } + } +} + +// Convert all colonies to honey bees. +void convertColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials) +{ + int bee_idx = -1; + for (size_t i = 0; i < Materials->raceEx.size(); i++) + if (Materials->raceEx[i].id == "HONEY_BEE") + { + bee_idx = i; + break; + } + + if (bee_idx == -1) + { + std::cerr << "Honey bees not present in game." << std::endl; + return; + } + + uint32_t numSpawnPoints = points->size(); + for (uint32_t i = 0; i < numSpawnPoints; i++) + { + DFHack::t_spawnPoint sp; + points->Read(i, sp); + + if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp)) + { + sp.race = bee_idx; + points->Write(i, sp); + } + } +} + +void showColonies(Core *c, DFHack::SpawnPoints *points, + DFHack::Materials *Materials) +{ + uint32_t numSpawnPoints = points->size(); + int numColonies = 0; + for (uint32_t i = 0; i < numSpawnPoints; i++) + { + DFHack::t_spawnPoint sp; + + points->Read(i, sp); + + if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp)) + { + numColonies++; + string race="(no race)"; + if(sp.race != -1) + race = Materials->raceEx[sp.race].id; + + c->con.print("Spawn point %u: %s at %d:%d:%d\n", i, + race.c_str(), sp.x, sp.y, sp.z); + } + } + + if (numColonies == 0) + c->con << "No colonies present." << std::endl; +} diff --git a/plugins/itemhacks.cpp b/plugins/itemhacks.cpp new file mode 100644 index 000000000..b518dc2d2 --- /dev/null +++ b/plugins/itemhacks.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +DFhackCExport command_result df_dumpitems (Core * c, vector & parameters); +DFhackCExport command_result df_itscanvec1 (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "itemhacks"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("dumpitems", "Dump items...", df_dumpitems)); + commands.push_back(PluginCommand("itscanvec1", "Dump items that have the first vector valid.", df_itscanvec1)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +DFhackCExport command_result df_itscanvec1 (Core * c, vector & parameters) +{ + c->Suspend(); + DFHack::Items * Items = c->getItems(); + Items->Start(); + std::vector p_items; + Items->readItemVector(p_items); + for(int i = 0; i < p_items.size();i++) + { + t_item * itm = p_items[i]; + if(itm->unk2.size()) + { + c->con.print("Found %x, size %d\n",itm,itm->unk2.size()); + } + } + c->Resume(); + return CR_OK; +} + +DFhackCExport command_result df_dumpitems (Core * c, vector & parameters) +{ + c->Suspend(); + bool print_hex = false; + if(parameters.size() && parameters[0] == "hex") + print_hex = true; + DFHack::Materials * Materials = c->getMaterials(); + Materials->ReadAllMaterials(); + + DFHack::Gui * Gui = c->getGui(); + + DFHack::Items * Items = c->getItems(); + Items->Start(); + + int32_t x,y,z; + Gui->getCursorCoords(x,y,z); + + std::vector p_items; + Items->readItemVector(p_items); + uint32_t size = p_items.size(); + + for(size_t i = 0; i < size; i++) + { + DFHack::dfh_item itm; + memset(&itm, 0, sizeof(DFHack::dfh_item)); + Items->readItem(p_items[i],itm); + + if (x != -30000 + && !(itm.base->x == x && itm.base->y == y && itm.base->z == z + && itm.base->flags.on_ground + && !itm.base->flags.in_chest + && !itm.base->flags.in_inventory + && !itm.base->flags.in_building)) + continue; + + c->con.print( + "%5d: addr:0x%08x %6d %08x (%d,%d,%d) vptr:0x%08x [%d] *%d %s - %s\n", + i, itm.base, itm.base->id, itm.base->flags.whole, + itm.base->x, itm.base->y, itm.base->z, + itm.base->vptr, + itm.wear_level, + itm.quantity, + Items->getItemClass(itm.matdesc.itemType).c_str(), + Items->getItemDescription(itm, Materials).c_str() + ); + /* + if (print_hex) + hexdump(DF,p_items[i],0x300); +*/ + /* + if (print_acc) + c->con << Items->dumpAccessors(itm) << endl; + */ +/* + if (print_refs) { + DFHack::DfVector p_refs(p, itm.origin + ref_vector); + for (size_t j = 0; j < p_refs.size(); j++) { + uint32_t vptr = p->readDWord(p_refs[j]); + uint32_t val = p->readDWord(p_refs[j]+4); + c->con.print("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str()); + } + } + */ + } + c->Resume(); + return CR_OK; +} diff --git a/plugins/kittens.cpp b/plugins/kittens.cpp new file mode 100644 index 000000000..f41137b8b --- /dev/null +++ b/plugins/kittens.cpp @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include +#include +#include "dfhack/extra/stopwatch.h" + +using std::vector; +using std::string; +using namespace DFHack; +//FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core. +bool shutdown_flag = false; +bool final_flag = true; +bool timering = false; +uint64_t timeLast = 0; + +DFhackCExport command_result kittens (Core * c, vector & parameters); +DFhackCExport command_result ktimer (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "kittens"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("nyan","NYAN CAT INVASION!",kittens)); + commands.push_back(PluginCommand("ktimer","Time events...",ktimer)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + shutdown_flag = true; + while(!final_flag) + { + c->con.msleep(60); + } + return CR_OK; +} + + + +DFhackCExport command_result plugin_onupdate ( Core * c ) +{ + if(timering == true) + { + uint64_t time2 = GetTimeMs64(); + // harmless potential data race here... + uint64_t delta = time2-timeLast; + // harmless potential data race here... + timeLast = time2; + c->con.print("Time delta = %d ms\n", delta); + } + return CR_OK; +} + +DFhackCExport command_result ktimer (Core * c, vector & parameters) +{ + if(timering) + { + timering = false; + return CR_OK; + } + uint64_t timestart = GetTimeMs64(); + c->Suspend(); + c->Resume(); + uint64_t timeend = GetTimeMs64(); + c->con.print("Time to suspend = %d ms\n",timeend - timestart); + // harmless potential data race here... + timeLast = timeend; + timering = true; + return CR_OK; +} + +DFhackCExport command_result kittens (Core * c, vector & parameters) +{ + final_flag = false; + Console & con = c->con; + // http://evilzone.org/creative-arts/nyan-cat-ascii/ + const char * nyan []= + { + "NYAN NYAN NYAN NYAN NYAN NYAN NYAN", + "+ o + o ", + " + o + +", + "o +", + " o + + +", + "+ o o + o", + "-_-_-_-_-_-_-_,------, o ", + "_-_-_-_-_-_-_-| /\\_/\\ ", + "-_-_-_-_-_-_-~|__( ^ .^) + + ", + "_-_-_-_-_-_-_-\"\" \"\" ", + "+ o o + o", + " + +", + "o o o o +", + " o +", + "+ + o o + ", + "NYAN NYAN NYAN NYAN NYAN NYAN NYAN", + 0 + }; + const char * kittenz1 []= + { + " ____", + " (. \\", + " \\ | ", + " \\ |___(\\--/)", + " __/ ( . . )", + " \"'._. '-.O.'", + " '-. \\ \"|\\", + " '.,,/'.,,mrf", + 0 + }; + con.cursor(false); + con.clear(); + Console::color_value color = Console::COLOR_BLUE; + while(1) + { + if(shutdown_flag) + { + final_flag = true; + con.reset_color(); + con << std::endl << "NYAN!" << std::endl << std::flush; + return CR_OK; + } + con.color(color); + int index = 0; + const char * kit = nyan[index]; + con.gotoxy(1,1); + //con << "Your DF is now full of kittens!" << std::endl; + while (kit != 0) + { + con.gotoxy(1,1+index); + con << kit << std::endl; + index++; + kit = nyan[index]; + } + con.flush(); + con.msleep(60); + ((int&)color) ++; + if(color > Console::COLOR_MAX) + color = Console::COLOR_BLUE; + } +} diff --git a/plugins/notes.cpp b/plugins/notes.cpp new file mode 100644 index 000000000..32b436121 --- /dev/null +++ b/plugins/notes.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +DFhackCExport command_result df_notes (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "notes"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("dumpnotes", + "Dumps in-game notes", + df_notes)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +DFhackCExport command_result df_notes (Core * c, vector & parameters) +{ + Console & con = c->con; + c->Suspend(); + + DFHack::Notes * note_mod = c->getNotes(); + std::vector* note_list = note_mod->notes; + + if (note_list == NULL) + { + con.printerr("Notes are not supported under this version of DF.\n"); + c->Resume(); + return CR_OK; + } + + if (note_list->empty()) + { + con << "There are no notes." << std::endl; + c->Resume(); + return CR_OK; + } + + + for (size_t i = 0; i < note_list->size(); i++) + { + t_note* note = (*note_list)[i]; + + con.print("Note %x at: %d/%d/%d\n",note, note->x, note->y, note->z); + con.print("Note id: %d\n", note->id); + con.print("Note symbol: '%c'\n", note->symbol); + + if (note->name.length() > 0) + con << "Note name: " << (note->name) << std::endl; + if (note->text.length() > 0) + con << "Note text: " << (note->text) << std::endl; + + if (note->unk1 != 0) + con.print("unk1: %x\n", note->unk1); + if (note->unk2 != 0) + con.print("unk2: %x\n", note->unk2); + + con << std::endl; + } + + c->Resume(); + return CR_OK; +} diff --git a/tools/supported/prospector.cpp b/plugins/prospector.cpp similarity index 64% rename from tools/supported/prospector.cpp rename to plugins/prospector.cpp index 1aa6e1d23..751218fc0 100644 --- a/tools/supported/prospector.cpp +++ b/plugins/prospector.cpp @@ -15,8 +15,12 @@ using namespace std; #include #include -#include #include +#include +#include +#include + +using namespace DFHack; typedef std::map MatMap; typedef std::vector< pair > MatSorter; @@ -24,49 +28,12 @@ typedef std::vector< pair > MatSorter; typedef std::vector FeatureList; typedef std::vector FeatureListPointer; typedef std::map FeatureMap; -typedef std::vector PlantList; +typedef std::vector PlantList; -bool parseOptions(int argc, char **argv, bool &showHidden, bool &showPlants, - bool &showSlade, bool &showTemple) -{ - char c; - xgetopt opt(argc, argv, "apst"); - opt.opterr = 0; - while ((c = opt()) != -1) - { - switch (c) - { - case 'a': - showHidden = true; - break; - case 'p': - showPlants = false; - break; - case 's': - showSlade = false; - break; - case 't': - showTemple = false; - break; - case '?': - switch (opt.optopt) - { - // For when we take arguments - default: - if (isprint(opt.optopt)) - std::cerr << "Unknown option -" << opt.optopt << "!" - << std::endl; - else - std::cerr << "Unknown option character " << (int) opt.optopt << "!" - << std::endl; - } - default: - // Um..... - return false; - } - } - return true; -} +#define TO_PTR_VEC(obj_vec, ptr_vec) \ + ptr_vec.clear(); \ + for (size_t i = 0; i < obj_vec.size(); i++) \ + ptr_vec.push_back(&obj_vec[i]) template