├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── CMakeModules ├── FindGLEW.cmake └── FindSDL2.cmake ├── LICENSE ├── README.md ├── data ├── config.xml ├── cstrike.xml └── halflife.xml ├── docs ├── README ├── compiling.md └── overlaps.md ├── extras ├── logo.png └── logo.psd └── src ├── ConfigXML.cpp ├── ConfigXML.h ├── VideoSystem.cpp ├── VideoSystem.h ├── bsp.cpp ├── bsp.h ├── common.h ├── entities.cpp ├── entities.h ├── halfmapper.cpp ├── icon.ico ├── resources.rc ├── wad.cpp └── wad.h /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "thirdparty/tinyxml2"] 2 | path = thirdparty/tinyxml2 3 | url = https://github.com/leethomason/tinyxml2 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) 2 | message(FATAL_ERROR "Do not build in-tree. Create a build folder, and run cmake there.") 3 | endif() 4 | 5 | cmake_minimum_required(VERSION 2.8.4) 6 | set(PROJECT_NAME "halfmapper") 7 | project(${PROJECT_NAME}) 8 | 9 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${${PROJECT_NAME}_SOURCE_DIR}/CMakeModules") 10 | 11 | #Find the required packages, and add them to the includes list. 12 | find_package(SDL2 REQUIRED) 13 | find_package(OpenGL REQUIRED) 14 | find_package(GLEW REQUIRED) 15 | include_directories(${SDL2_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}) 16 | 17 | #Set the CXXFLAGS for Clang, GCC or MINGW. 18 | #Should cover OSX, Linux and MINGW Windows 19 | if(UNIX OR MINGW) 20 | set(CMAKE_CXX_FLAGS "-std=c++0x -O2 -Wall -Wpedantic -Wextra") 21 | endif(UNIX OR MINGW) 22 | 23 | 24 | #Set compiller flags when on MSVC Windows. 25 | if(MSVC) 26 | add_definitions("/W4 /D_CRT_SECURE_NO_WARNINGS") 27 | endif(MSVC) 28 | 29 | 30 | #Add all source and header files for all platforms. 31 | file(GLOB SOURCE_FILES 32 | "src/*.h" 33 | "src/*.cpp" 34 | ) 35 | 36 | file(GLOB TINYXML2_FILES 37 | "thirdparty/tinyxml2/tinyxml2.cpp" 38 | "thirdparty/tinyxml2/tinyxml2.h" 39 | ) 40 | 41 | #Make sure tinyxml is in its own group in Visual Studio, and in the include path. 42 | SOURCE_GROUP(tinyxml2 FILES ${TINYXML2_FILES}) 43 | include_directories("thirdparty/tinyxml2") 44 | 45 | #Add Windows resources. 46 | if(MSVC OR MINGW) 47 | file(GLOB RESOURCE_FILES 48 | "src/*.ico" 49 | "src/*.rc" 50 | ) 51 | endif(MSVC OR MINGW) 52 | 53 | add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${TINYXML2_FILES} ${RESOURCE_FILES}) 54 | 55 | 56 | #Add link libraries. 57 | target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARY} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY}) 58 | -------------------------------------------------------------------------------- /CMakeModules/FindGLEW.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindGLEW 3 | # -------- 4 | # 5 | # Find the OpenGL Extension Wrangler Library (GLEW) 6 | # 7 | # IMPORTED Targets 8 | # ^^^^^^^^^^^^^^^^ 9 | # 10 | # This module defines the :prop_tgt:`IMPORTED` target ``GLEW::GLEW``, 11 | # if GLEW has been found. 12 | # 13 | # Result Variables 14 | # ^^^^^^^^^^^^^^^^ 15 | # 16 | # This module defines the following variables: 17 | # 18 | # :: 19 | # 20 | # GLEW_INCLUDE_DIRS - include directories for GLEW 21 | # GLEW_LIBRARIES - libraries to link against GLEW 22 | # GLEW_FOUND - true if GLEW has been found and can be used 23 | # 24 | # Modified by Anthony Birkett 25 | # * Added Windows support through the envvar GLEW 26 | # * Path pointed to by %GLEW% will be searched 27 | # * Added 64 bit checks 28 | 29 | #============================================================================= 30 | # Copyright 2012 Benjamin Eikel 31 | # 32 | # CMake - Cross Platform Makefile Generator 33 | # Copyright 2000-2015 Kitware, Inc. 34 | # Copyright 2000-2011 Insight Software Consortium 35 | # All rights reserved. 36 | # 37 | # Redistribution and use in source and binary forms, with or without 38 | # modification, are permitted provided that the following conditions 39 | # are met: 40 | # 41 | # * Redistributions of source code must retain the above copyright 42 | # notice, this list of conditions and the following disclaimer. 43 | # 44 | # * Redistributions in binary form must reproduce the above copyright 45 | # notice, this list of conditions and the following disclaimer in the 46 | # documentation and/or other materials provided with the distribution. 47 | # 48 | # * Neither the names of Kitware, Inc., the Insight Software Consortium, 49 | # nor the names of their contributors may be used to endorse or promote 50 | # products derived from this software without specific prior written 51 | # permission. 52 | # 53 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 54 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 55 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 56 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 57 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 58 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 59 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 63 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 | # 65 | # This software is distributed WITHOUT ANY WARRANTY; without even the 66 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 67 | # See the License for more information. 68 | #============================================================================= 69 | # (To distribute this file outside of CMake, substitute the full 70 | # License text for the above reference.) 71 | 72 | FIND_PATH(GLEW_INCLUDE_DIR GL/glew.h 73 | HINTS 74 | ${GLEW} 75 | $ENV{GLEW} 76 | PATH_SUFFIXES include 77 | i686-w64-mingw32/include 78 | x86_64-w64-mingw32/include 79 | PATHS 80 | ~/Library/Frameworks 81 | /Library/Frameworks 82 | /usr/local/include/GL 83 | /usr/include/GL 84 | /sw # Fink 85 | /opt/local # DarwinPorts 86 | /opt/csw # Blastwave 87 | /opt 88 | ) 89 | 90 | # Lookup the 64 bit libs on x64 91 | IF(CMAKE_SIZEOF_VOID_P EQUAL 8) 92 | FIND_LIBRARY(GLEW_LIBRARY_TEMP GLEW32 GLEW glew 93 | HINTS 94 | ${GLEW} 95 | $ENV{GLEW} 96 | PATH_SUFFIXES lib64 lib 97 | lib/Release/x64 98 | lib/x64 99 | x86_64-w64-mingw32/lib 100 | PATHS 101 | /sw 102 | /opt/local 103 | /opt/csw 104 | /opt 105 | ) 106 | # On 32bit build find the 32bit libs 107 | ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) 108 | FIND_LIBRARY(GLEW_LIBRARY_TEMP GLEW32 GLEW glew 109 | HINTS 110 | ${GLEW} 111 | $ENV{GLEW} 112 | PATH_SUFFIXES lib 113 | lib/Release/Win32 114 | lib/x86 115 | i686-w64-mingw32/lib 116 | PATHS 117 | /sw 118 | /opt/local 119 | /opt/csw 120 | /opt 121 | ) 122 | ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) 123 | 124 | 125 | SET(GLEW_FOUND "NO") 126 | IF(GLEW_LIBRARY_TEMP) 127 | # Set the final string here so the GUI reflects the final state. 128 | SET(GLEW_LIBRARY ${GLEW_LIBRARY_TEMP} CACHE STRING "Where the GLEW Library can be found") 129 | # Set the temp variable to INTERNAL so it is not seen in the CMake GUI 130 | SET(GLEW_LIBRARY_TEMP "${GLEW_LIBRARY_TEMP}" CACHE INTERNAL "") 131 | 132 | SET(GLEW_FOUND "YES") 133 | ENDIF(GLEW_LIBRARY_TEMP) 134 | 135 | INCLUDE(FindPackageHandleStandardArgs) 136 | 137 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLEW REQUIRED_VARS GLEW_LIBRARY GLEW_INCLUDE_DIR) 138 | 139 | -------------------------------------------------------------------------------- /CMakeModules/FindSDL2.cmake: -------------------------------------------------------------------------------- 1 | # Locate SDL2 library 2 | # This module defines 3 | # SDL2_LIBRARY, the name of the library to link against 4 | # SDL2_FOUND, if false, do not try to link to SDL2 5 | # SDL2_INCLUDE_DIR, where to find SDL.h 6 | # 7 | # This module responds to the the flag: 8 | # SDL2_BUILDING_LIBRARY 9 | # If this is defined, then no SDL2_main will be linked in because 10 | # only applications need main(). 11 | # Otherwise, it is assumed you are building an application and this 12 | # module will attempt to locate and set the the proper link flags 13 | # as part of the returned SDL2_LIBRARY variable. 14 | # 15 | # Don't forget to include SDL2main.h and SDL2main.m your project for the 16 | # OS X framework based version. (Other versions link to -lSDL2main which 17 | # this module will try to find on your behalf.) Also for OS X, this 18 | # module will automatically add the -framework Cocoa on your behalf. 19 | # 20 | # 21 | # Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration 22 | # and no SDL2_LIBRARY, it means CMake did not find your SDL2 library 23 | # (SDL2.dll, libsdl2.so, SDL2.framework, etc). 24 | # Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. 25 | # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value 26 | # as appropriate. These values are used to generate the final SDL2_LIBRARY 27 | # variable, but when these values are unset, SDL2_LIBRARY does not get created. 28 | # 29 | # 30 | # $SDL2 is an environment variable that would 31 | # correspond to the ./configure --prefix=$SDL2 32 | # used in building SDL2. 33 | # l.e.galup 9-20-02 34 | # 35 | # Modified by Eric Wing. 36 | # Added code to assist with automated building by using environmental variables 37 | # and providing a more controlled/consistent search behavior. 38 | # Added new modifications to recognize OS X frameworks and 39 | # additional Unix paths (FreeBSD, etc). 40 | # Also corrected the header search path to follow "proper" SDL2 guidelines. 41 | # Added a search for SDL2main which is needed by some platforms. 42 | # Added a search for threads which is needed by some platforms. 43 | # Added needed compile switches for MinGW. 44 | # 45 | # On OSX, this will prefer the Framework version (if found) over others. 46 | # People will have to manually change the cache values of 47 | # SDL2_LIBRARY to override this selection or set the CMake environment 48 | # CMAKE_INCLUDE_PATH to modify the search paths. 49 | # 50 | # Note that the header path has changed from SDL2/SDL.h to just SDL.h 51 | # This needed to change because "proper" SDL2 convention 52 | # is #include "SDL.h", not . This is done for portability 53 | # reasons because not all systems place things in SDL2/ (see FreeBSD). 54 | # 55 | # Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake 56 | # module with the minor edit of changing "SDL" to "SDL2" where necessary. This 57 | # was not created for redistribution, and exists temporarily pending official 58 | # SDL2 CMake modules. 59 | # 60 | # Note that on windows this will only search for the 32bit libraries, to search 61 | # for 64bit change x86/i686-w64 to x64/x86_64-w64 62 | 63 | #============================================================================= 64 | # Copyright 2003-2009 Kitware, Inc. 65 | # 66 | # CMake - Cross Platform Makefile Generator 67 | # Copyright 2000-2014 Kitware, Inc. 68 | # Copyright 2000-2011 Insight Software Consortium 69 | # All rights reserved. 70 | # 71 | # Redistribution and use in source and binary forms, with or without 72 | # modification, are permitted provided that the following conditions 73 | # are met: 74 | # 75 | # * Redistributions of source code must retain the above copyright 76 | # notice, this list of conditions and the following disclaimer. 77 | # 78 | # * Redistributions in binary form must reproduce the above copyright 79 | # notice, this list of conditions and the following disclaimer in the 80 | # documentation and/or other materials provided with the distribution. 81 | # 82 | # * Neither the names of Kitware, Inc., the Insight Software Consortium, 83 | # nor the names of their contributors may be used to endorse or promote 84 | # products derived from this software without specific prior written 85 | # permission. 86 | # 87 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 88 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 89 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 90 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 91 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 92 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 93 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 94 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 95 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 96 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 97 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 98 | # 99 | # This software is distributed WITHOUT ANY WARRANTY; without even the 100 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 101 | # See the License for more information. 102 | #============================================================================= 103 | # (To distribute this file outside of CMake, substitute the full 104 | # License text for the above reference.) 105 | 106 | FIND_PATH(SDL2_INCLUDE_DIR SDL.h 107 | HINTS 108 | ${SDL2} 109 | $ENV{SDL2} 110 | PATH_SUFFIXES include/SDL2 include SDL2 111 | i686-w64-mingw32/include/SDL2 112 | x86_64-w64-mingw32/include/SDL2 113 | PATHS 114 | ~/Library/Frameworks 115 | /Library/Frameworks 116 | /usr/local/include/SDL2 117 | /usr/include/SDL2 118 | /sw # Fink 119 | /opt/local # DarwinPorts 120 | /opt/csw # Blastwave 121 | /opt 122 | ) 123 | 124 | # Lookup the 64 bit libs on x64 125 | IF(CMAKE_SIZEOF_VOID_P EQUAL 8) 126 | FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 127 | HINTS 128 | ${SDL2} 129 | $ENV{SDL2} 130 | PATH_SUFFIXES lib64 lib 131 | lib/x64 132 | x86_64-w64-mingw32/lib 133 | PATHS 134 | /sw 135 | /opt/local 136 | /opt/csw 137 | /opt 138 | ) 139 | # On 32bit build find the 32bit libs 140 | ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) 141 | FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 142 | HINTS 143 | ${SDL2} 144 | $ENV{SDL2} 145 | PATH_SUFFIXES lib 146 | lib/x86 147 | i686-w64-mingw32/lib 148 | PATHS 149 | /sw 150 | /opt/local 151 | /opt/csw 152 | /opt 153 | ) 154 | ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) 155 | 156 | IF(NOT SDL2_BUILDING_LIBRARY) 157 | IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 158 | # Non-OS X framework versions expect you to also dynamically link to 159 | # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms 160 | # seem to provide SDL2main for compatibility even though they don't 161 | # necessarily need it. 162 | # Lookup the 64 bit libs on x64 163 | IF(CMAKE_SIZEOF_VOID_P EQUAL 8) 164 | FIND_LIBRARY(SDL2MAIN_LIBRARY 165 | NAMES SDL2main 166 | HINTS 167 | ${SDL2} 168 | $ENV{SDL2} 169 | PATH_SUFFIXES lib64 lib 170 | lib/x64 171 | x86_64-w64-mingw32/lib 172 | PATHS 173 | /sw 174 | /opt/local 175 | /opt/csw 176 | /opt 177 | ) 178 | # On 32bit build find the 32bit libs 179 | ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) 180 | FIND_LIBRARY(SDL2MAIN_LIBRARY 181 | NAMES SDL2main 182 | HINTS 183 | ${SDL2} 184 | $ENV{SDL2} 185 | PATH_SUFFIXES lib 186 | lib/x86 187 | i686-w64-mingw32/lib 188 | PATHS 189 | /sw 190 | /opt/local 191 | /opt/csw 192 | /opt 193 | ) 194 | ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) 195 | ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 196 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 197 | 198 | # SDL2 may require threads on your system. 199 | # The Apple build may not need an explicit flag because one of the 200 | # frameworks may already provide it. 201 | # But for non-OSX systems, I will use the CMake Threads package. 202 | IF(NOT APPLE) 203 | FIND_PACKAGE(Threads) 204 | ENDIF(NOT APPLE) 205 | 206 | # MinGW needs an additional library, mwindows 207 | # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows 208 | # (Actually on second look, I think it only needs one of the m* libraries.) 209 | IF(MINGW) 210 | SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") 211 | ENDIF(MINGW) 212 | 213 | SET(SDL2_FOUND "NO") 214 | IF(SDL2_LIBRARY_TEMP) 215 | # For SDL2main 216 | IF(NOT SDL2_BUILDING_LIBRARY) 217 | IF(SDL2MAIN_LIBRARY) 218 | SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) 219 | ENDIF(SDL2MAIN_LIBRARY) 220 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 221 | 222 | # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. 223 | # CMake doesn't display the -framework Cocoa string in the UI even 224 | # though it actually is there if I modify a pre-used variable. 225 | # I think it has something to do with the CACHE STRING. 226 | # So I use a temporary variable until the end so I can set the 227 | # "real" variable in one-shot. 228 | IF(APPLE) 229 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") 230 | ENDIF(APPLE) 231 | 232 | # For threads, as mentioned Apple doesn't need this. 233 | # In fact, there seems to be a problem if I used the Threads package 234 | # and try using this line, so I'm just skipping it entirely for OS X. 235 | IF(NOT APPLE) 236 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) 237 | ENDIF(NOT APPLE) 238 | 239 | # For MinGW library 240 | IF(MINGW) 241 | SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) 242 | ENDIF(MINGW) 243 | 244 | # Set the final string here so the GUI reflects the final state. 245 | SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") 246 | # Set the temp variable to INTERNAL so it is not seen in the CMake GUI 247 | SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") 248 | 249 | SET(SDL2_FOUND "YES") 250 | ENDIF(SDL2_LIBRARY_TEMP) 251 | 252 | INCLUDE(FindPackageHandleStandardArgs) 253 | 254 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) 255 | 256 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![HalfMapper](https://github.com/gzalo/HalfMapper/blob/master/extras/logo.png) 2 | 3 | This project is a renderer designed specifically to explore the world of Half-Life. 4 | It allows for realtime rendering of the Black Mesa Research Facility. 5 | 6 | **The main aim is not to make it playable**, just to be able to navigable (noclip). Models, decals, and other objects won't be rendered. 7 | 8 | ## Download 9 | The latest binary for Windows can be downloaded here: http://gzalo.com/halfmapper_en/ 10 | 11 | The configuration file, config.xml, lets you set a few settings (FOV, resolution). Another config file can be created in order to load maps from GoldSrc games, for instance check halflife.xml. In order to load another config file, drag and drop it to the executable (or pass it in the commandline as an argument). 12 | 13 | **It needs a Half Life installation** 14 | If using the WON version, PAK files will have to be extracted. The map folder and files halflife.wad and liquids.wad are needed for the program to run. WON is untested, so please report any issues. 15 | For other platforms it can be compiled after installing the required libraries and using the alternate makefile. It can be compiled under Windows with MinGW. 16 | 17 | Isometric is supported! (samples here: http://imgur.com/a/jPVgD and http://imgur.com/a/40J7N) 18 | ![Isometric support](http://i.imgur.com/ghh8OeT.jpg) 19 | ![Lambda Core](http://i.imgur.com/y5xzn7Q.png) 20 | Counter-Strike 1.6 maps are supported as well! 21 | ![Counter-Strike 1.6](http://i.imgur.com/Imyw50V.png) 22 | 23 | Video showing the program http://www.youtube.com/watch?v=Hl2HbV3UbMs 24 | 25 | **List of overlaps found: https://github.com/gzalo/HalfMapper/blob/master/docs/overlaps.md ** 26 | 27 | ## TODO list (ordered from highest to lowest priority) 28 | - Try to add other Black Mesa maps to expand the universe: Opposing Force, Blue Shift and Decay might be possible. Other GoldSrc games maps will probably load without problems, such as Counter-Strike. 29 | 30 | - Fixing areas that overlap (map loading sections) that cause z-fighting and some extra walls 31 | 32 | - Improve code, clean up some stuff and use newer OpenGL3. 33 | 34 | ## Used libraries 35 | - SDL for window and event management 36 | 37 | - OpenGL and GLU for rendering 38 | 39 | - GLEW for easy extension access 40 | 41 | - TinyXML2 for configuration files 42 | -------------------------------------------------------------------------------- /data/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | D:\Games\Steam\steamapps\common\Half-Life\valve\ 5 | D:\Games\Steam\steamapps\common\Half-Life\valve\cstrike 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/cstrike.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | cstrike 4 | cs_assault 5 | cs_dust 6 | de_aztec 7 | cs_office 8 | itsitaly 9 | cs_bdog 10 | halflife 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 | -------------------------------------------------------------------------------- /data/halflife.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | halflife 4 | liquids 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 | -------------------------------------------------------------------------------- /docs/README: -------------------------------------------------------------------------------- 1 | HalfMapper by gzalo 2 | 3 | Before running, please edit the config files and correctly select the game folder (Half-life/valve/) 4 | If using the Steam version, the path should be Steam_Folder/SteamApps/common/Half-Life/valve/. 5 | 6 | Controls: 7 | Mouse: Camera view 8 | WASD: Lateral movement 9 | Q/E: Move up and down 10 | Shift: Faster movement 11 | Control: Slower movement 12 | Escape: Quit 13 | 14 | If you found a bug, please report it in the issues page, inside github. 15 | -------------------------------------------------------------------------------- /docs/compiling.md: -------------------------------------------------------------------------------- 1 | # Compiling with CMake 2 | 3 | The CMake Build System allows you to generate project files for your native environment. 4 | 5 | CMake can generate Visual Studio solutions, XCode projects and Makefiles, using one, cross-platform, build definition file (CMakeLists.txt). 6 | 7 | ## General Notes 8 | Find scripts for SDL2 and GLEW are included in /CMakeModules. These allow CMake to search for headers and link libraries on the system. 9 | 10 | On Windows, we use the environment variables, SDL2 and GLEW, to point to the downloaded development libraries. 11 | 12 | CMake is designed to allow out-of-tree builds. Always create a new folder, outside of the tree to build in. Run CMake from your build folder, and point it to the source tree. 13 | 14 | The commands below assume two directories. The source tree (halfmapper-src), and the build directory (halfmapper-build). 15 | 16 | On Linux and Mac OSX, CMake will obey CC and CCX env vars. You can force CMake to use gcc or clang. For example: 17 | ```shell 18 | export CC=/usr/bin/clang 19 | export CXX=/usr/bin/clang++ 20 | ``` 21 | 22 | Before starting, you will need to clone the repository, and prepare the submodules: 23 | ```shell 24 | git clone https://github.com/gzalo/halfmapper halfmapper-src 25 | cd halfmapper-src 26 | git submodule init 27 | git submodule update 28 | ``` 29 | 30 | ## Windows Visual Studio 31 | **Prerequisites** 32 | * [SDL2 2.0.x Development Libraries For Visual Studio](http://libsdl.org/release/SDL2-devel-2.0.4-VC.zip) 33 | * [GLEW Development Libraries For Windows](https://sourceforge.net/projects/glew/files/glew/1.13.0/glew-1.13.0-win32.zip/download) 34 | * Windows SDK (Installed automatically with Visual Studio 2010 and newer) 35 | 36 | **General build process** 37 | * Create environment variables pointing to SDL2 and GLEW 38 | * Create a new build directory outside the source tree 39 | * Change to the build directory 40 | * Generate a Visual Studio solution by invoking CMake 41 | * Compile and debug inside Visual Studio 42 | 43 | ```shell 44 | set SDL2="C:\Users\Someone\Downloads\SDL2-2.0.4\" 45 | set GLEW="C:\Users\Someone\Downloads\GLEW-1.13.0\" 46 | mkdir ../halfmapper-build 47 | cd ../half-mapper-build 48 | cmake ../halfmapper-src 49 | 50 | #VS Solution is now in "halfmapper-build" 51 | ``` 52 | 53 | 54 | ## Linux Makefiles 55 | (Assuming Debian or Ubuntu - package names may be different!) 56 | 57 | **Prerequisites** 58 | * libsdl2-dev (For SDL2) 59 | * mesa-common-dev (For OpenGL) 60 | * libglew-dev (For GLEW) 61 | 62 | **General build process** 63 | * Create a new build directory outside the source tree 64 | * Change to the build directory 65 | * Generate Makefiles 66 | * Compile with make 67 | 68 | ```shell 69 | mkdir ../halfmapper-build 70 | cd ../halfmapper-build 71 | cmake ../halfmapper-src 72 | make 73 | 74 | #Binary is now in the build folder 75 | ``` 76 | 77 | 78 | ## OSX, *BSD, Solaris 79 | Completely untested. Should be similar to the Linux process. 80 | XCode projects will be generated on OSX. 81 | 82 | ## Windows MinGW 83 | Untested. Should work using Makefiles. 84 | -------------------------------------------------------------------------------- /docs/overlaps.md: -------------------------------------------------------------------------------- 1 | # Overlapping areas by chapter 2 | 3 | **Work in progress** 4 | 5 | Images of every chapter can be found here: http://imgur.com/a/WDGAd 6 | 7 | ## Black Mesa inbound 8 | 9 | **All maps get correctly matched** 10 | 11 | **OVERLAP** ![Overlapping c0a0b c0a0c](http://i.imgur.com/diKLR69.jpg) 12 | 13 | ## Anomalous materials 14 | 15 | **All maps get correctly matched** 16 | 17 | ## Unforeseen consecuences 18 | 19 | **All maps get correctly matched** 20 | 21 | ## Office complex 22 | 23 | **All maps get correctly matched** 24 | 25 | ## We've got hostiles 26 | 27 | **All maps get correctly matched** 28 | 29 | ## Blast pit 30 | 31 | **All maps get correctly matched** 32 | 33 | **MINOR OVERLAPS** ![Small overlap with the supply room](http://i.imgur.com/0QNcS8n.png) 34 | 35 | ## Power up 36 | 37 | **All maps get correctly matched** 38 | 39 | **MINOR OVERLAPS** 40 | 41 | ## On a Rail 42 | 43 | **All maps get correctly matched** 44 | 45 | ## Apprehension 46 | 47 | **All maps get correctly matched** 48 | 49 | **Unknowns: Trash compactor location** 50 | 51 | ## Residue processing 52 | 53 | **All maps get correctly matched** 54 | 55 | ## Questionable Ethics 56 | 57 | **All maps get correctly matched** 58 | 59 | ## Surface Tension 60 | 61 | **All maps get correctly matched** 62 | 63 | **MAJOR OVERLAPS** 64 | 65 | ## Forget about Freeman 66 | 67 | **All maps get correctly matched** 68 | 69 | **MAJOR OVERLAPS** 70 | 71 | ## Lambda Core 72 | 73 | **All maps get correctly matched** -------------------------------------------------------------------------------- /extras/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/extras/logo.png -------------------------------------------------------------------------------- /extras/logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/extras/logo.psd -------------------------------------------------------------------------------- /src/ConfigXML.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/src/ConfigXML.cpp -------------------------------------------------------------------------------- /src/ConfigXML.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/src/ConfigXML.h -------------------------------------------------------------------------------- /src/VideoSystem.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/src/VideoSystem.cpp -------------------------------------------------------------------------------- /src/VideoSystem.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/src/VideoSystem.h -------------------------------------------------------------------------------- /src/bsp.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "bsp.h" 3 | #include "entities.h" 4 | #include "ConfigXML.h" 5 | #include 6 | 7 | map textures; 8 | map > > landmarks; 9 | map > dontRenderModel; 10 | map offsets; 11 | 12 | //Correct UV coordinates 13 | static inline COORDS calcCoords(VERTEX v, VERTEX vs, VERTEX vt, float sShift, float tShift){ 14 | COORDS ret; 15 | ret.u = sShift + vs.x*v.x + vs.y*v.y + vs.z*v.z; 16 | ret.v = tShift + vt.x*v.x + vt.y*v.y + vt.z*v.z; 17 | return ret; 18 | } 19 | 20 | BSP::BSP(const std::vector &szGamePaths, const string &filename, const MapEntry &sMapEntry){ 21 | string id = sMapEntry.m_szName; 22 | 23 | uint8_t gammaTable[256]; 24 | for(int i=0;i<256;i++) 25 | gammaTable[i] = pow(i/255.0,1.0/3.0)*255; 26 | 27 | //Light map atlas 28 | lmapAtlas = new uint8_t[1024*1024*3]; 29 | 30 | ifstream inBSP; 31 | 32 | // Try to open the file from all known gamepaths. 33 | for (size_t i = 0; i < szGamePaths.size(); i++) { 34 | if (!inBSP.is_open()) { 35 | inBSP.open(szGamePaths[i] + filename.c_str(), ios::binary); 36 | } 37 | } 38 | 39 | // If the BSP wasn't found in any of the gamepaths... 40 | if(!inBSP.is_open()){ cerr << "Can't open BSP " << filename << "." << endl; return;} 41 | 42 | //Check BSP version 43 | BSPHEADER bHeader; 44 | inBSP.read((char*)&bHeader, sizeof(bHeader)); 45 | if(bHeader.nVersion != 30){ cerr << "BSP version is not 30 (" << filename << ")." << endl; return;} 46 | 47 | //Read Entities 48 | inBSP.seekg(bHeader.lump[LUMP_ENTITIES].nOffset, ios::beg); 49 | char *bff = new char[bHeader.lump[LUMP_ENTITIES].nLength]; 50 | inBSP.read(bff, bHeader.lump[LUMP_ENTITIES].nLength); 51 | parseEntities(bff,id,sMapEntry); 52 | delete []bff; 53 | 54 | //Read Models and hide some faces 55 | BSPMODEL *models = new BSPMODEL[bHeader.lump[LUMP_MODELS].nLength/(int)sizeof(BSPMODEL)]; 56 | inBSP.seekg(bHeader.lump[LUMP_MODELS].nOffset, ios::beg); 57 | inBSP.read((char*)models, bHeader.lump[LUMP_MODELS].nLength); 58 | 59 | map dontRenderFace; 60 | for(unsigned int i=0;i vertices; 72 | inBSP.seekg(bHeader.lump[LUMP_VERTICES].nOffset, ios::beg); 73 | for(int i=0;i verticesPrime; 86 | inBSP.seekg(bHeader.lump[LUMP_SURFEDGES].nOffset, ios::beg); 87 | for(int i=0;i0?e:-e].iVertex[e>0?0:1]]); 91 | } 92 | 93 | //Read Lightmaps 94 | inBSP.seekg(bHeader.lump[LUMP_LIGHTING].nOffset, ios::beg); 95 | int size = bHeader.lump[LUMP_LIGHTING].nLength; 96 | uint8_t *lmap = new uint8_t[size]; 97 | inBSP.read((char*)lmap, size); 98 | vector lmaps; 99 | 100 | //Read Textures 101 | inBSP.seekg(bHeader.lump[LUMP_TEXTURES].nOffset, ios::beg); 102 | BSPTEXTUREHEADER theader; 103 | inBSP.read((char*)&theader, sizeof(theader)); 104 | int *texOffSets = new int[theader.nMipTextures]; 105 | inBSP.read((char*)texOffSets, theader.nMipTextures*sizeof(int)); 106 | 107 | vector texNames; 108 | 109 | for(unsigned int i=0;i 17 || lmh > 17) lmw = lmh = 1; 257 | LMAP l; l.w = lmw; l.h = lmh; l.offset = lmap+f.nLightmapOffset; 258 | lmaps.push_back(l); 259 | } 260 | 261 | int lmapRover[1024]; memset(lmapRover, 0, 1024*4); 262 | 263 | //Light map "rover" algorithm from Quake 2 (http://fabiensanglard.net/quake2/quake2_opengl_renderer.php) 264 | for(unsigned int i=0;i= best) 272 | break; 273 | if(lmapRover[a+j] > best2) 274 | best2 = lmapRover[a+j]; 275 | } 276 | if(j == lmaps[i].w){ 277 | lmaps[i].finalX = a; 278 | lmaps[i].finalY = best = best2; 279 | } 280 | } 281 | 282 | if(best + lmaps[i].h > 1024){ 283 | cout << "Lightmap atlas is too small (" << filename <<")." << endl; 284 | break; 285 | } 286 | 287 | for(int a=0;a 17) continue; 323 | if(lmh > 17) continue; 324 | 325 | float mid_poly_s = (minUV[i*2] + maxUV[i*2])/2.0f; 326 | float mid_poly_t = (minUV[i*2+1] + maxUV[i*2+1])/2.0f; 327 | float mid_tex_s = (float)lmw / 2.0f; 328 | float mid_tex_t = (float)lmh / 2.0f; 329 | float fX = lmaps[i].finalX; 330 | float fY = lmaps[i].finalY; 331 | TEXTURE t = textures[faceTexName]; 332 | 333 | vector *vt = &texturedTris[faceTexName].triangles; 334 | 335 | for(int j=2,k=1;jpush_back(VECFINAL(v1,c1,c1l)); 364 | vt->push_back(VECFINAL(v2,c2,c2l)); 365 | vt->push_back(VECFINAL(v3,c3,c3l)); 366 | } 367 | texturedTris[faceTexName].texId = textures[faceTexName].texId; 368 | } 369 | 370 | 371 | delete []btfs; 372 | delete []texOffSets; 373 | delete []edges; 374 | 375 | inBSP.close(); 376 | 377 | glGenTextures(1, &lmapTexId); 378 | glBindTexture(GL_TEXTURE_2D, lmapTexId); 379 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 380 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 381 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, lmapAtlas); 382 | delete []lmapAtlas; 383 | 384 | bufObjects = new GLuint[texturedTris.size()]; 385 | glGenBuffers(texturedTris.size(), bufObjects); 386 | 387 | int i=0; 388 | totalTris=0; 389 | for(map ::iterator it = texturedTris.begin();it != texturedTris.end();it++, i++){ 390 | glBindBuffer(GL_ARRAY_BUFFER, bufObjects[i]); 391 | glBufferData(GL_ARRAY_BUFFER, (*it).second.triangles.size()*sizeof(VECFINAL), (void*)&(*it).second.triangles[0], GL_STATIC_DRAW); 392 | totalTris += (*it).second.triangles.size(); 393 | } 394 | 395 | mapId = id; 396 | 397 | } 398 | 399 | void BSP::calculateOffset(){ 400 | if(offsets.count(mapId) != 0){ 401 | offset = offsets[mapId]; 402 | }else{ 403 | if(mapId == "c0a0"){ 404 | //Origin for other maps 405 | offsets[mapId] = VERTEX(0,0,0); 406 | }else{ 407 | float ox=0,oy=0,oz=0; 408 | bool found=false; 409 | for(map > >::iterator it = landmarks.begin(); it != landmarks.end();it++){ 410 | if((*it).second.size() > 1){ 411 | for(size_t i=0;i<(*it).second.size();i++){ 412 | if((*it).second[i].second == mapId){ 413 | if(i == 0){ 414 | if(offsets.count((*it).second[i+1].second) != 0){ 415 | VERTEX c1 = (*it).second[i].first; 416 | VERTEX c2 = (*it).second[i+1].first; 417 | VERTEX c3 = offsets[(*it).second[i+1].second]; 418 | ox = + c2.x + c3.x - c1.x; 419 | oy = + c2.y + c3.y - c1.y; 420 | oz = + c2.z + c3.z - c1.z; 421 | 422 | found=true; 423 | cout << "Matched " << (*it).second[i].second << " " << (*it).second[i+1].second << endl; 424 | break; 425 | } 426 | }else{ 427 | if(offsets.count((*it).second[i-1].second) != 0){ 428 | VERTEX c1 = (*it).second[i].first; 429 | VERTEX c2 = (*it).second[i-1].first; 430 | VERTEX c3 = offsets[(*it).second[i-1].second]; 431 | ox = + c2.x + c3.x - c1.x; 432 | oy = + c2.y + c3.y - c1.y; 433 | oz = + c2.z + c3.z - c1.z; 434 | 435 | found=true; 436 | cout << "Matched " << (*it).second[i].second << " " << (*it).second[i-1].second << endl; 437 | break; 438 | } 439 | } 440 | 441 | } 442 | } 443 | } 444 | } 445 | if(!found){ 446 | cout << "Cant find matching landmarks for " << mapId << endl; 447 | } 448 | offsets[mapId] = VERTEX(ox,oy,oz); 449 | } 450 | } 451 | } 452 | 453 | void BSP::render(){ 454 | //Calculate map offset based on landmarks 455 | calculateOffset(); 456 | 457 | glPushMatrix(); 458 | glTranslatef(offset.x + ConfigOffsetChapter.x, offset.y + ConfigOffsetChapter.y, offset.z + ConfigOffsetChapter.z); 459 | 460 | glEnableClientState(GL_VERTEX_ARRAY); 461 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 462 | 463 | glActiveTextureARB(GL_TEXTURE0_ARB); 464 | glEnable(GL_TEXTURE_2D); 465 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 466 | 467 | glActiveTextureARB(GL_TEXTURE1_ARB); 468 | glEnable(GL_TEXTURE_2D); 469 | glBindTexture(GL_TEXTURE_2D, lmapTexId); 470 | 471 | glClientActiveTextureARB(GL_TEXTURE1_ARB); 472 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 473 | 474 | int i=0; 475 | for(map ::iterator it = texturedTris.begin();it != texturedTris.end();it++, i++){ 476 | //Don't render some dummy triangles (triggers and such) 477 | if((*it).first != "aaatrigger" && (*it).first != "origin" && (*it).first != "clip" && (*it).first != "sky" && (*it).first[0]!='{' && (*it).second.triangles.size() != 0){ 478 | //if(mapId == "c1a0e.bsp") cout << (*it).first << endl; 479 | glBindBuffer(GL_ARRAY_BUFFER, bufObjects[i]); 480 | 481 | /////T0 482 | glActiveTextureARB(GL_TEXTURE0_ARB); 483 | glBindTexture(GL_TEXTURE_2D, (*it).second.texId); 484 | 485 | glClientActiveTextureARB(GL_TEXTURE0_ARB); 486 | glTexCoordPointer(2, GL_FLOAT, sizeof(VECFINAL), (char*)NULL+4*3); 487 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 488 | 489 | ////T1 490 | glClientActiveTextureARB(GL_TEXTURE1_ARB); 491 | glTexCoordPointer(2, GL_FLOAT, sizeof(VECFINAL), (char*)NULL+4*5); 492 | 493 | glVertexPointer(3, GL_FLOAT, sizeof(VECFINAL), (void*)0); 494 | glDrawArrays(GL_TRIANGLES, 0, (*it).second.triangles.size()); 495 | } 496 | } 497 | glPopMatrix(); 498 | } 499 | 500 | void BSP::SetChapterOffset(const float x, const float y, const float z) 501 | { 502 | ConfigOffsetChapter.x = x; 503 | ConfigOffsetChapter.y = y; 504 | ConfigOffsetChapter.z = z; 505 | } 506 | -------------------------------------------------------------------------------- /src/bsp.h: -------------------------------------------------------------------------------- 1 | #ifndef BSP_H 2 | #define BSP_H 3 | 4 | #include "common.h" 5 | 6 | //Extracted from http://hlbsp.sourceforge.net/index.php?content=bspdef 7 | 8 | #define LUMP_ENTITIES 0 9 | #define LUMP_PLANES 1 10 | #define LUMP_TEXTURES 2 11 | #define LUMP_VERTICES 3 12 | #define LUMP_VISIBILITY 4 13 | #define LUMP_NODES 5 14 | #define LUMP_TEXINFO 6 15 | #define LUMP_FACES 7 16 | #define LUMP_LIGHTING 8 17 | #define LUMP_CLIPNODES 9 18 | #define LUMP_LEAVES 10 19 | #define LUMP_MARKSURFACES 11 20 | #define LUMP_EDGES 12 21 | #define LUMP_SURFEDGES 13 22 | #define LUMP_MODELS 14 23 | #define HEADER_LUMPS 15 24 | #define MAXTEXTURENAME 16 25 | #define MIPLEVELS 4 26 | 27 | struct MapEntry; // Dont include ConfigXML.h here. 28 | 29 | struct BSPLUMP{ 30 | int32_t nOffset; // File offset to data 31 | int32_t nLength; // Length of data 32 | }; 33 | struct BSPHEADER{ 34 | int32_t nVersion; // Must be 30 for a valid HL BSP file 35 | BSPLUMP lump[HEADER_LUMPS]; // Stores the directory of lumps 36 | }; 37 | struct BSPFACE{ 38 | uint16_t iPlane; // Plane the face is parallel to 39 | uint16_t nPlaneSide; // Set if different normals orientation 40 | uint32_t iFirstEdge; // Index of the first surfedge 41 | uint16_t nEdges; // Number of consecutive surfedges 42 | uint16_t iTextureInfo; // Index of the texture info structure 43 | uint8_t nStyles[4]; // Specify lighting styles 44 | uint32_t nLightmapOffset; // Offsets into the raw lightmap data 45 | }; 46 | struct BSPEDGE{ 47 | uint16_t iVertex[2]; // Indices into vertex array 48 | }; 49 | struct BSPTEXTUREINFO{ 50 | VERTEX vS; 51 | float fSShift; // Texture shift in s direction 52 | VERTEX vT; 53 | float fTShift; // Texture shift in t direction 54 | uint32_t iMiptex; // Index into textures array 55 | uint32_t nFlags; // Texture flags, seem to always be 0 56 | }; 57 | struct BSPTEXTUREHEADER{ 58 | uint32_t nMipTextures; // Number of BSPMIPTEX structures 59 | }; 60 | struct BSPMIPTEX{ 61 | char szName[MAXTEXTURENAME]; // Name of texture 62 | uint32_t nWidth, nHeight; // Extends of the texture 63 | uint32_t nOffsets[MIPLEVELS]; // Offsets to texture mipmaps BSPMIPTEX; 64 | }; 65 | 66 | #define MAX_MAP_HULLS 4 67 | struct BSPMODEL{ 68 | float nMins[3], nMaxs[3]; // Defines bounding box 69 | VERTEX vOrigin; // Coordinates to move the // coordinate system 70 | int32_t iHeadnodes[MAX_MAP_HULLS]; // Index into nodes array 71 | int32_t nVisLeafs; // ??? 72 | int32_t iFirstFace, nFaces; // Index and count into faces 73 | }; 74 | 75 | struct COORDS{ 76 | float u, v; 77 | }; 78 | struct VECFINAL{ 79 | float x,y,z,u,v,ul,vl; 80 | VECFINAL(float _x, float _y, float _z, float _u, float _v){ 81 | x = _x; 82 | y = _y; 83 | z = _z; 84 | u = _u; 85 | v = _v; 86 | } 87 | VECFINAL(VERTEX vt, COORDS c, COORDS c2){ 88 | x = vt.x, y = vt.y, z = vt.z; 89 | u = c.u, v = c.v; 90 | ul = c2.u; 91 | vl = c2.v; 92 | } 93 | }; 94 | struct TEXTURE{ 95 | GLuint texId; 96 | int w,h; 97 | }; 98 | struct LMAP{ 99 | unsigned char *offset; int w,h; 100 | int finalX, finalY; 101 | }; 102 | 103 | struct TEXSTUFF{ 104 | vector triangles; 105 | int texId; 106 | }; 107 | 108 | class BSP{ 109 | public: 110 | BSP(const std::vector &szGamePaths, const string &filename, const MapEntry &sMapEntry); 111 | void render(); 112 | int totalTris; 113 | void SetChapterOffset(const float x, const float y, const float z); 114 | private: 115 | void calculateOffset(); 116 | 117 | unsigned char *lmapAtlas; GLuint lmapTexId; 118 | map texturedTris; 119 | GLuint *bufObjects; 120 | string mapId; 121 | VERTEX offset; 122 | 123 | VERTEX ConfigOffsetChapter; 124 | }; 125 | 126 | extern map textures; 127 | extern map > > landmarks; 128 | extern map > dontRenderModel; 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include //Mainly for memset (in bsp.cpp) 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #ifndef _MSC_VER 20 | #include 21 | #endif 22 | 23 | using namespace std; 24 | 25 | struct VERTEX{ 26 | float x,y,z; 27 | void fixHand(){ 28 | float swapY = y; 29 | y = z; 30 | z = swapY; 31 | x = -x; 32 | } 33 | VERTEX(float _x, float _y, float _z){ 34 | x=_x; y=_y; z=_z; 35 | } 36 | VERTEX(){ 37 | } 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/entities.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "bsp.h" 3 | #include "ConfigXML.h" 4 | 5 | void parseEntities(const string &szStr, const string &id, const MapEntry &sMapEntry){ 6 | stringstream ss(szStr); 7 | 8 | int status = 0; 9 | 10 | string origin, targetname,landmark, modelname; 11 | bool isLandMark=false,isChangeLevel=false,isTeleport=false; 12 | 13 | map changelevels; 14 | map ret; 15 | 16 | while(ss.good()){ 17 | string str; 18 | getline(ss, str); 19 | if(status == 0){ 20 | if(str == "{"){ 21 | status = 1, isLandMark=false,isChangeLevel=false,isTeleport=false; 22 | }else{ 23 | if(ss.good()) 24 | cerr << "Missing stuff in entity: " << str << endl; 25 | } 26 | }else if(status == 1){ 27 | if(str == "}"){ 28 | status = 0; 29 | if(isLandMark){ 30 | float x,y,z; 31 | sscanf(origin.c_str(),"%f %f %f", &x,&y,&z); 32 | VERTEX v(x,y,z); 33 | v.fixHand(); 34 | 35 | if (sMapEntry.m_szOffsetTargetName == targetname) { 36 | // Apply map offsets from the config, to fix landmark positions. 37 | v.x += sMapEntry.m_fOffsetX; 38 | v.y += sMapEntry.m_fOffsetY; 39 | v.z += sMapEntry.m_fOffsetZ; 40 | } 41 | 42 | ret[targetname] = v; 43 | 44 | }else if(isChangeLevel){ 45 | if(landmark.size()>0) 46 | changelevels[landmark]=1; 47 | } 48 | if(isTeleport || isChangeLevel){ 49 | dontRenderModel[id].push_back(modelname); 50 | } 51 | }else{ 52 | if(str == "\"classname\" \"info_landmark\""){ 53 | isLandMark=true; 54 | } 55 | if(str == "\"classname\" \"trigger_changelevel\""){ 56 | isChangeLevel=true; 57 | } 58 | if(str == "\"classname\" \"trigger_teleport\"" || str == "\"classname\" \"func_pendulum\"" || str == "\"classname\" \"trigger_transition\"" 59 | || str == "\"classname\" \"trigger_hurt\"" || str == "\"classname\" \"func_train\"" || str == "\"classname\" \"func_door_rotating\""){ 60 | isTeleport=true; 61 | } 62 | if(str.substr(0,8) == "\"origin\""){ 63 | origin = str.substr(10); 64 | origin.erase(origin.size() - 1); 65 | } 66 | if(str.substr(0,7) == "\"model\""){ 67 | modelname = str.substr(9); 68 | modelname.erase(modelname.size() - 1); 69 | } 70 | if(str.substr(0,12) == "\"targetname\""){ 71 | targetname = str.substr(14); 72 | targetname.erase(targetname.size() - 1); 73 | } 74 | if(str.substr(0,10) == "\"landmark\""){ 75 | landmark = str.substr(12); 76 | landmark.erase(landmark.size() - 1); 77 | } 78 | } 79 | } 80 | } 81 | for(map ::iterator it=ret.begin(); it!=ret.end(); it++){ 82 | if(changelevels.count((*it).first) != 0){ 83 | landmarks[(*it).first].push_back(make_pair((*it).second, id)); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/entities.h: -------------------------------------------------------------------------------- 1 | #ifndef ENTITIES_H 2 | #define ENTITIES_H 3 | 4 | struct MapEntry; 5 | 6 | void parseEntities(const string &str, const string &id, const MapEntry &sMapEntry); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/halfmapper.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "VideoSystem.h" 3 | #include "wad.h" 4 | #include "bsp.h" 5 | #include "ConfigXML.h" 6 | 7 | int main(int argc, char **argv){ 8 | ConfigXML *xmlconfig = new ConfigXML(); 9 | 10 | xmlconfig->LoadProgramConfig(); 11 | 12 | if(argc >= 2){ 13 | xmlconfig->LoadMapConfig(argv[1]); 14 | }else{ 15 | xmlconfig->LoadMapConfig("halflife.xml"); 16 | } 17 | 18 | VideoSystem *videosystem = new VideoSystem( 19 | xmlconfig->m_iWidth, 20 | xmlconfig->m_iHeight, 21 | xmlconfig->m_fFov, 22 | xmlconfig->m_bFullscreen, 23 | xmlconfig->m_bMultisampling, 24 | xmlconfig->m_bVsync 25 | ); 26 | 27 | if(videosystem->Init() == -1) return -1; 28 | 29 | //Texture loading 30 | for(size_t i=0;im_vWads.size();i++){ 31 | if(wadLoad(xmlconfig->m_szGamePaths, xmlconfig->m_vWads[i] + ".wad") == -1) return -1; 32 | } 33 | 34 | //Map loading 35 | vector maps; 36 | 37 | int t = SDL_GetTicks(), mapCount = 0, mapRenderCount = 0; 38 | int totalTris=0; 39 | 40 | for(unsigned int i = 0; i < xmlconfig->m_vChapterEntries.size(); i++) { 41 | for (unsigned int j = 0; j < xmlconfig->m_vChapterEntries[i].m_vMapEntries.size(); j++) { 42 | ChapterEntry sChapterEntry = xmlconfig->m_vChapterEntries[i]; 43 | MapEntry sMapEntry = xmlconfig->m_vChapterEntries[i].m_vMapEntries[j]; 44 | 45 | if (sChapterEntry.m_bRender && sMapEntry.m_bRender) { 46 | BSP *b = new BSP(xmlconfig->m_szGamePaths, "maps/" + sMapEntry.m_szName + ".bsp", sMapEntry); 47 | b->SetChapterOffset(sChapterEntry.m_fOffsetX, sChapterEntry.m_fOffsetY, sChapterEntry.m_fOffsetZ); 48 | totalTris += b->totalTris; 49 | maps.push_back(b); 50 | mapRenderCount++; 51 | } 52 | 53 | mapCount++; 54 | } 55 | } 56 | 57 | cout << mapCount << " maps found in config file." << endl; 58 | cout << mapRenderCount << " maps to render - loaded in " << SDL_GetTicks()-t << " ms." << endl; 59 | cout << "Total triangles: " << totalTris << endl; 60 | 61 | //--- 62 | 63 | bool quit=false; 64 | int kw=0, ks=0, ka=0, kd=0, kq=0, ke=0, kr=0, kc=0; 65 | float position[3] = {0.0f, 0.0f, 0.0f}; 66 | float rotation[2] = {0.0f, 0.0f}; 67 | float isoBounds=1000.0; 68 | int oldMs = SDL_GetTicks(), frame=0; 69 | 70 | while(!quit){ 71 | SDL_Event event; 72 | while(SDL_PollEvent(&event)){ 73 | if(event.type==SDL_QUIT) quit=true; 74 | if(event.type==SDL_KEYDOWN){ 75 | if(event.key.keysym.sym == SDLK_ESCAPE) quit=true; 76 | if(event.key.keysym.sym == SDLK_w) kw=1; 77 | if(event.key.keysym.sym == SDLK_s) ks=1; 78 | if(event.key.keysym.sym == SDLK_a) ka=1; 79 | if(event.key.keysym.sym == SDLK_d) kd=1; 80 | if(event.key.keysym.sym == SDLK_q) kq=1; 81 | if(event.key.keysym.sym == SDLK_e) ke=1; 82 | 83 | if(event.key.keysym.sym == SDLK_LSHIFT) kr=1; 84 | if(event.key.keysym.sym == SDLK_LCTRL) kc=1; 85 | } 86 | if(event.type==SDL_KEYUP){ 87 | if(event.key.keysym.sym == SDLK_w) kw=0; 88 | if(event.key.keysym.sym == SDLK_s) ks=0; 89 | if(event.key.keysym.sym == SDLK_a) ka=0; 90 | if(event.key.keysym.sym == SDLK_d) kd=0; 91 | if(event.key.keysym.sym == SDLK_q) kq=0; 92 | if(event.key.keysym.sym == SDLK_e) ke=0; 93 | 94 | if(event.key.keysym.sym == SDLK_LSHIFT) kr=0; 95 | if(event.key.keysym.sym == SDLK_LCTRL) kc=0; 96 | } 97 | if(event.type == SDL_MOUSEMOTION){ 98 | rotation[0] += event.motion.xrel/15.0f; 99 | rotation[1] += event.motion.yrel/15.0f; 100 | } 101 | } 102 | 103 | //Clamp mouse aim 104 | if(rotation[0] > 360) rotation[0] -= 360.0; 105 | if(rotation[0] < 0) rotation[0] += 360.0; 106 | if(rotation[1] < -89) rotation[1] = -89; 107 | if(rotation[1] > 89) rotation[1] = 89; 108 | 109 | //Velocities 110 | int vsp = kr?32:(kc?2:8), hsp = kr?32:(kc?2:8); 111 | 112 | float m_left = 0.0f, m_frontal = 0.0f; 113 | 114 | if(kw) m_frontal++; 115 | if(ks) m_frontal--; 116 | if(ka) m_left++; 117 | if(kd) m_left--; 118 | 119 | if(xmlconfig->m_bIsometric){ 120 | position[2] += m_left * hsp; 121 | position[1] += m_frontal * hsp; 122 | 123 | if(ke) isoBounds += vsp * 10.0f; 124 | if(kq) isoBounds -= vsp * 10.0f; 125 | isoBounds = max(10.0f, isoBounds); 126 | }else{ 127 | if(m_frontal || m_left){ 128 | float rotationF = rotation[0]* (float)M_PI / 180.0f + atan2(m_frontal, m_left); 129 | position[0] -= hsp * cos(rotationF); 130 | position[2] -= hsp * sin(rotationF); 131 | } 132 | if(ke) position[1] += vsp; 133 | if(kq) position[1] -= vsp; 134 | } 135 | 136 | videosystem->ClearBuffer(); 137 | 138 | //Camera setup 139 | if(xmlconfig->m_bIsometric){ 140 | glMatrixMode(GL_PROJECTION); 141 | glLoadIdentity(); 142 | glOrtho(-isoBounds, isoBounds, -isoBounds, isoBounds, -100000.0, 100000.0); 143 | 144 | glMatrixMode(GL_MODELVIEW); 145 | glLoadIdentity(); 146 | glScalef(1.0f,2.0f,1.0f); 147 | glRotatef(rotation[1], 1.0f, 0.0f, 0.0f); 148 | glRotatef(rotation[0], 0.0f, 1.0f, 0.0f); 149 | glTranslatef(-position[0], -position[1], -position[2]); 150 | }else{ 151 | glMatrixMode(GL_MODELVIEW); 152 | glLoadIdentity(); 153 | glRotated(rotation[1], 1.0f, 0.0f, 0.0f); 154 | glRotated(rotation[0], 0.0f, 1.0f, 0.0f); 155 | glTranslatef(-position[0], -position[1], -position[2]); 156 | } 157 | //Map render 158 | for(size_t i=0;irender(); 160 | } 161 | 162 | videosystem->SwapBuffers(); 163 | 164 | frame++; 165 | if(frame==30){ 166 | frame=0; 167 | 168 | //FPS calculation 169 | int dt = SDL_GetTicks()-oldMs; 170 | oldMs = SDL_GetTicks(); 171 | char bf[64]; 172 | sprintf(bf, "%.2f FPS - %.2f %.2f %.2f", 30000.0f/(float)dt, position[0], position[1], position[2]); 173 | videosystem->SetWindowTitle(bf); 174 | } 175 | } 176 | SDL_Quit(); 177 | 178 | return 0; 179 | } 180 | -------------------------------------------------------------------------------- /src/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzalo/HalfMapper/934a20d6ece28c5e0fc957f79c2e48fd9636d6a0/src/icon.ico -------------------------------------------------------------------------------- /src/resources.rc: -------------------------------------------------------------------------------- 1 | id ICON "icon.ico" -------------------------------------------------------------------------------- /src/wad.cpp: -------------------------------------------------------------------------------- 1 | #include "bsp.h" 2 | #include "wad.h" 3 | 4 | int wadLoad(const std::vector &szGamePaths, const string &filename) { 5 | ifstream inWAD; 6 | 7 | // Try to open the file from all known gamepaths. 8 | for (size_t i = 0; i < szGamePaths.size(); i++) { 9 | if (!inWAD.is_open()) { 10 | inWAD.open(szGamePaths[i] + filename.c_str(), ios::binary); 11 | } 12 | } 13 | 14 | // If the WAD wasn't found in any of the gamepaths... 15 | if(!inWAD.is_open()){ cerr << "Can't load WAD " << filename << "." << endl; return -1; } 16 | 17 | //Read header 18 | WADHEADER wh; inWAD.read((char*)&wh, sizeof(wh)); 19 | if(wh.szMagic[0] != 'W' || wh.szMagic[1] != 'A' || wh.szMagic[2] != 'D' || wh.szMagic[3] != '3') return -1; 20 | 21 | //Read directory entries 22 | WADDIRENTRY *wdes = new WADDIRENTRY[wh.nDir]; 23 | inWAD.seekg(wh.nDirOffset, ios::beg); 24 | inWAD.read((char*)wdes, sizeof(WADDIRENTRY)*wh.nDir); 25 | 26 | uint8_t *dataDr = new uint8_t[512*512]; //Raw texture data 27 | uint8_t *dataUp = new uint8_t[512*512*4]; //32 bit texture 28 | uint8_t *dataPal = new uint8_t[256*3]; //256 color pallete 29 | 30 | for(int i=0;i=0;mip--){ 51 | inWAD.seekg(wdes[i].nFilePos+bmt.nOffsets[mip], ios::beg); 52 | inWAD.read((char*)dataDr, bmt.nWidth*bmt.nHeight/dimensionsSquared[mip]); 53 | 54 | if(mip == 3){ 55 | //Read the pallete (comes after last mipmap) 56 | uint16_t dummy; inWAD.read((char*)&dummy, 2); 57 | inWAD.read((char*)dataPal, 256*3); 58 | } 59 | 60 | for(uint32_t y=0;y 5 | 6 | //Extracted from http://hlbsp.sourceforge.net/index.php?content=waddef 7 | 8 | struct WADHEADER{ 9 | char szMagic[4]; // should be WAD2/WAD3 10 | int32_t nDir; // number of directory entries 11 | int32_t nDirOffset; // offset into directory 12 | }; 13 | 14 | struct WADDIRENTRY{ 15 | int32_t nFilePos; // offset in WAD 16 | int32_t nDiskSize; // size in file 17 | int32_t nSize; // uncompressed size 18 | int8_t nType; // type of entry 19 | bool bCompression; // 0 if none 20 | int16_t nDummy; // not used 21 | char szName[16]; // must be null terminated 22 | }; 23 | 24 | int wadLoad(const std::vector &szGamePaths, const string &filename); 25 | 26 | #endif 27 | --------------------------------------------------------------------------------