diff --git a/README.md b/README.md index 6f34b7d2f..aff99ba8e 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,13 @@ This is the source code for Serious Engine v.1.10, including the following proje * `GameAgent` The serverlist masterserver written in Python * `libogg`, `libvorbis` Third party libraries used for playing OGG-encoded ingame music (see http://www.vorbis.com/ for more information) -These have been modified to run correctly under the recent version of Windows. (Tested: Win7 x64, Win8 x64, Win8.1 x64) +These have been modified to run correctly under recent versions of Windows. (Tested: Win7 x64, Win8 x64, Win8.1 x64) Building -------- +There are still many asserts in the engine. Most of them are irrelevant and should be removed, but while it's not done, the asserts will effectively kill the engine when triggered in the Debug build. Use Release or RelWithDebInfo build if you intend to play (automatically set as RelWithDebInfo in the build scripts). + ### Windows To build Serious Engine 1, you'll need Visual Studio 2013 or 2015, Professional or Community edition ( https://www.visualstudio.com/post-download-vs?sku=community ). @@ -43,7 +45,7 @@ Once you've installed Visual Studio and (optionally) DirectX8 SDK, you can build Type this in your terminal: ``` -git clone https://github.com/rcgordon/Serious-Engine.git +git clone https://github.com/ptitSeb/Serious-Engine cd Serious-Engine ``` @@ -52,26 +54,35 @@ cd Serious-Engine If you have access to a copy of the game (either by CD or through Steam), you can copy the *.gro files from the game directory to the repository. +Note that **for running SS:TFE, you have to delete or rename the ModEXT.txt file**, it's only for SS:TSE. + +Alternatively, you can simply copy the whole content of the Windows install as base dir, add the `SE1_10.gro` from the repo in the root folder of the install, and then copy the binary built in `Bin` folder + #### Building (only for SS:TSE) Type this in your terminal: ``` -Sources/build-linux64.sh # use build-linux32.sh for 32-bits +cd Sources +./build-linux64.sh # use build-linux32.sh for 32-bits +cd .. cp Sources/cmake-build/ssam Bin/ -cp Sources/cmake-build/Debug/* Bin/Debug/ +cp Sources/cmake-build/Debug/* Bin/ ``` #### Building (only for SS:TFE) -Same as SS:SE, but note the following: +Type this in your terminal: -- Before running build-linux64.sh, modify the file by passing `-DTFE=TRUE` to cmake. -- After building, you need to copy 'ssam**-tfe**' instead of 'ssam', as shown: +``` +cd Sources +./build-linux64.sh -DTFE=TRUE # use build-linux32.sh for 32-bits +cd .. +cp Sources/cmake-build/ssam-tfe Bin/ +cp Sources/cmake-build/Debug/* Bin/ +``` - ``` - cp Sources/cmake-build/ssam-tfe Bin/ - ``` +Note that the CD version of SS:TSE used MP3 for music. You will need to build / get `libamp11lib.so` and copy it inside `Bin` with the other libs to have music. Steam version uses ogg and doesn't need this library. #### Running @@ -112,7 +123,6 @@ And its working directory: Common problems --------------- -Before starting the build process, make sure you have a "Temp" folder in your development directory. If it doesn't exist, create it. SeriousSkaStudio has some issues with MFC windows that can prevent the main window from being displayed properly. License diff --git a/Scripts/menu/ApplyShadowmaps.ini b/Scripts/Menu/ApplyShadowmaps.ini similarity index 100% rename from Scripts/menu/ApplyShadowmaps.ini rename to Scripts/Menu/ApplyShadowmaps.ini diff --git a/Scripts/menu/ApplyTextures.ini b/Scripts/Menu/ApplyTextures.ini similarity index 100% rename from Scripts/menu/ApplyTextures.ini rename to Scripts/Menu/ApplyTextures.ini diff --git a/Scripts/menu/ApplyVideo.ini b/Scripts/Menu/ApplyVideo.ini similarity index 100% rename from Scripts/menu/ApplyVideo.ini rename to Scripts/Menu/ApplyVideo.ini diff --git a/Scripts/menu/GameOptions.cfg b/Scripts/Menu/GameOptions.cfg similarity index 100% rename from Scripts/menu/GameOptions.cfg rename to Scripts/Menu/GameOptions.cfg diff --git a/Scripts/menu/RenderingOptions.cfg b/Scripts/Menu/RenderingOptions.cfg similarity index 100% rename from Scripts/menu/RenderingOptions.cfg rename to Scripts/Menu/RenderingOptions.cfg diff --git a/Scripts/menu/SPOptions.cfg b/Scripts/Menu/SPOptions.cfg similarity index 100% rename from Scripts/menu/SPOptions.cfg rename to Scripts/Menu/SPOptions.cfg diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt old mode 100644 new mode 100755 index ef8aee257..87889fd64 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 3.7.2) project(SeriousEngine) # Set @rpath for Mac OS X shared library install names. @@ -7,6 +7,8 @@ project(SeriousEngine) # Use system SDL2 is on by default option(USE_SYSTEM_SDL2 "Use systems sdl2 development files" On) option(USE_SYSTEM_ZLIB "Use systems zlib development files" On) +option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE}) + # fallback for cmake versions without add_compile_options # RAKE! Borrowed from dhewm3 project if(NOT COMMAND add_compile_options) @@ -18,12 +20,22 @@ if(NOT COMMAND add_compile_options) endfunction() endif() -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(CheckCXXCompilerFlag) +include(ParserAndScanner) # ssam expects the libs to be in Debug/ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Debug) +if(USE_CCACHE) + find_program(CCACHE_FOUND ccache) + if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) + endif() +endif() + + # Use systemwide SDL2 or custom build # RAKE!: Find a way to use their custom built library if # they want to use that instead or if their system only @@ -47,6 +59,8 @@ if(USE_SYSTEM_ZLIB) else() message(FATAL_ERROR "Error! USE_SYSTEM_ZLIB is set but neccessary developer files are missing") endif() +else() + include_directories(${CMAKE_SOURCE_DIR}/Engine/zlib) endif() # RAKE! Where to install the binaries. @@ -84,30 +98,73 @@ endif() ## ** RAKE! clean up for SeriousEngine use. Also ** ## ** RAKE! need to make this pandora safe. ** # compiler specific flags -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") # This section and the like are for flags/defines that can be shared between # c and c++ compile options add_compile_options(-Wall) add_compile_options(-pipe) add_compile_options(-fPIC) - add_compile_options(-march=native) + if(NOT PANDORA AND NOT PYRA AND NOT (MACOSX AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")) + add_compile_options(-march=native) + endif() + if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm.*") + if(PYRA) + add_compile_options(-mfpu=neon-vfpv4) + add_compile_options(-mcpu=cortex-a15) + add_compile_options(-mfloat-abi=hard) + add_compile_options(-marm) + elseif(NOT (MACOSX AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")) + add_compile_options(-mfpu=neon) + else() + add_compile_options(-mfpu=neon) + endif() + add_compile_options(-fsigned-char) + endif() add_compile_options(-fno-strict-aliasing) add_definitions(-D_REENTRANT=1) add_definitions(-D_MT=1) - ## Add your custom C and CXX flags on the command line aka -DCMAKE_C_FLAGS=-std=c98 or -DCMAKE_CXX_FLAGS=-std=c++11 + ## Add your custom C and CXX flags on the command line aka -DCMAKE_C_FLAGS=-std=c98 or -DCMAKE_CXX_FLAGS=-std=c++11 ## For C flags set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -D_DEBUG=1 -DDEBUG=1 -O0") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O3 -fno-unsafe-math-optimizations") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -fno-unsafe-math-optimizations") - set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -fno-unsafe-math-optimizations") + if(PANDORA) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -faligned-new -ffast-math") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -faligned-new -ffast-math") + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -ffast-math") + elseif(PYRA) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -marm -faligned-new -ffast-math") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -marm -faligned-new -ffast-math") + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -marm -ffast-math") + elseif(MACOSX AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O0 -fno-unsafe-math-optimizations") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O0 -fno-unsafe-math-optimizations") + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O0 -fno-unsafe-math-optimizations") + else() + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -fno-unsafe-math-optimizations") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -fno-unsafe-math-optimizations") + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -fno-unsafe-math-optimizations") + endif() ## For C++ flags set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -D_DEBUG=1 -DDEBUG=1 -O0") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O3 -fno-unsafe-math-optimizations") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -fno-unsafe-math-optimizations") ## RAKE! Does -DNDEBUG=1 and -D_NDEBUG=1 mess with RelWithDebInfo? - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -fno-unsafe-math-optimizations") + if(PANDORA) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O3 -faligned-new -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -faligned-new -ffast-math") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -ffast-math") + elseif(PYRA) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O3 -marm -faligned-new -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -marm -faligned-new -ffast-math") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -marm -ffast-math") + elseif(MACOSX AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O0 -fno-unsafe-math-optimizations") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O0 -fno-unsafe-math-optimizations") ## RAKE! Does -DNDEBUG=1 and -D_NDEBUG=1 mess with RelWithDebInfo? + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O0 -fno-unsafe-math-optimizations") + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -O3 -fno-unsafe-math-optimizations") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -g -O3 -fno-unsafe-math-optimizations") ## RAKE! Does -DNDEBUG=1 and -D_NDEBUG=1 mess with RelWithDebInfo? + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -D_NDEBUG=1 -Os -fno-unsafe-math-optimizations") + endif() # TODO fix these warnings add_compile_options(-Wno-switch) @@ -118,7 +175,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") add_compile_options(-Wno-missing-braces) add_compile_options(-Wno-overloaded-virtual) add_compile_options(-Wno-invalid-offsetof) - MESSAGE(WARNING, "re-enable some of the warnings some day!") + #MESSAGE(WARNING, "re-enable some of the warnings some day!") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") # !!! FIXME: turn a bunch of these off, this is just for now. I hope. --ryan. @@ -218,6 +275,11 @@ if (PANDORA) add_definitions(-DPLATFORM_PANDORA=1) endif() +option(PYRA "Compile for Pyra" FALSE) +if (PYRA) + add_definitions(-DPLATFORM_PYRA=1) +endif() + option(USE_TREMOR "Use Tremor instead of Vorbis" FALSE) if (USE_TREMOR) add_definitions(-DUSE_TREMOR=1) @@ -253,40 +315,16 @@ else() include_directories(External/libvorbis/include) endif() -# We build ECC, then use it to generate C++ code for the game entities... -macro(add_parser_and_scanner _PARSER _SCANNER) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_SCANNER}.cpp" - MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_SCANNER}.l" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND flex - ARGS -o${_SCANNER}.cpp ${_SCANNER}.l - ) - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.hpp" - MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.y" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND bison - ARGS -o${_PARSER}.cpp ${_PARSER}.y -d - ) - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.h" - MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.hpp" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND ${CMAKE_COMMAND} - ARGS -E copy ${_PARSER}.hpp ${_PARSER}.h - ) -endmacro() - # Build ECC from source if there wasn't a prebuilt-one specified on the command line. # Normally we build it here, but we might need a prebuilt, native binary if # we're cross-compiling the rest of the game. -if(NOT ECC) - add_parser_and_scanner("Ecc/Parser" "Ecc/Scanner") - add_executable(ecc Ecc/Main.cpp Ecc/Parser.cpp Ecc/Parser.h Ecc/Scanner.cpp) - set(ECC "ecc") +if(ECC) + # Use given ecc. +elseif(CMAKE_CROSSCOMPILING) + message(FATAL_ERROR "ECC variable must point to native ecc binary when cross-compiling.") +else() + add_subdirectory(Ecc) + set(ECC ecc) endif() macro(entity _NAME) @@ -702,6 +740,33 @@ if(NOT USE_SYSTEM_ZLIB) Engine/zlib/uncompr.c) endif() +set(ENGINE_SAFEMATH_SRCS + Engine/Brushes/Brush.cpp + Engine/Brushes/BrushPolygon.cpp + Engine/Brushes/BrushSector.cpp + Engine/Entities/Entity.cpp + Engine/Entities/EntityClass.cpp + Engine/Entities/EntityCollision.cpp + Engine/Entities/PlayerCharacter.cpp + Engine/Terrain/TerrainMisc.cpp + Engine/Terrain/TerrainRayCasting.cpp + Engine/World/WorldCSG.cpp + Engine/World/WorldRayCasting.cpp + Engine/World/WorldCollision.cpp + Engine/World/WorldCollisionGrid.cpp + + Engine/Math/Projection_Simple_DOUBLE.cpp + Engine/Math/Geometry_DOUBLE.cpp +) +add_library(engine_safemath STATIC + ${ENGINE_SAFEMATH_SRCS} +) +target_compile_options(engine_safemath PRIVATE "-fno-unsafe-math-optimizations") +if(PANDORA) + target_compile_options(engine_safemath PRIVATE "-mfpu=vfpv3") +endif() +add_dependencies(engine_safemath ParseEntities) + set(ENGINE_SRCS ${ENGINE_ENTITIES_CPP} Engine/Engine.cpp @@ -741,23 +806,16 @@ set(ENGINE_SRCS Engine/Base/SDL/SDLInput.cpp Engine/Base/SDL/SDLEvents.cpp ${SYNCHRO_SRCS} - Engine/Brushes/Brush.cpp Engine/Brushes/BrushIO.cpp Engine/Brushes/BrushShadows.cpp Engine/Brushes/BrushTriangularize.cpp Engine/Brushes/BrushArchive.cpp Engine/Brushes/BrushImport.cpp Engine/Brushes/BrushMip.cpp - Engine/Brushes/BrushPolygon.cpp Engine/Brushes/BrushExport.cpp - Engine/Brushes/BrushSector.cpp - Engine/Entities/Entity.cpp Engine/Entities/NearestPolygon.cpp Engine/Entities/EntityProperties.cpp - Engine/Entities/PlayerCharacter.cpp - Engine/Entities/EntityClass.cpp Engine/Entities/FieldBSPTesting.cpp - Engine/Entities/EntityCollision.cpp Engine/Entities/EntityCopying.cpp Engine/Entities/LastPositions.cpp Engine/Math/Projection_Isometric.cpp @@ -767,14 +825,12 @@ set(ENGINE_SRCS Engine/Math/Float.cpp Engine/Math/Object3D_CSG.cpp Engine/Math/Projection_Simple.cpp - Engine/Math/Projection_Simple_DOUBLE.cpp Engine/Math/Functions.cpp Engine/Math/ObjectSector.cpp Engine/Math/Placement.cpp Engine/Math/TextureMapping.cpp Engine/Math/Geometry.cpp Engine/Math/Projection.cpp - Engine/Math/Geometry_DOUBLE.cpp #Engine/Math/Object3D_IO.cpp # Exploration 3D support. #Engine/Models/EditModel.cpp Engine/Models/Model.cpp @@ -837,8 +893,6 @@ set(ENGINE_SRCS Engine/Terrain/TerrainArchive.cpp Engine/Terrain/TerrainEditing.cpp Engine/Terrain/TerrainLayer.cpp - Engine/Terrain/TerrainMisc.cpp - Engine/Terrain/TerrainRayCasting.cpp Engine/Terrain/TerrainRender.cpp Engine/Terrain/TerrainTile.cpp Engine/Rendering/Render.cpp @@ -873,14 +927,10 @@ set(ENGINE_SRCS Engine/Templates/NameTable_CTFileName.cpp Engine/Templates/NameTable_CTranslationPair.cpp Engine/Templates/BSP.cpp - Engine/World/WorldCSG.cpp Engine/World/PhysicsProfile.cpp - Engine/World/WorldCollision.cpp - Engine/World/WorldIO.cpp - Engine/World/WorldRayCasting.cpp Engine/World/World.cpp - Engine/World/WorldCollisionGrid.cpp Engine/World/WorldEditingProfile.cpp + Engine/World/WorldIO.cpp ${ADDITIONAL_ENGINE_SRCS} ${ZLIB_SRCS} ) @@ -900,16 +950,19 @@ add_executable(ssam SeriousSam/MenuGadgets.cpp SeriousSam/MenuPrinting.cpp ) +target_link_libraries(ssam engine_safemath) add_dependencies(ssam ParseEntities) # Make symbols in the main executable available to dynamic objects set_target_properties(ssam PROPERTIES ENABLE_EXPORTS ON) + # !!! FIXME: this is an option because you have to recompile the entire engine twice. # !!! FIXME: If we can put the engine in a static library and not lose symbols, # !!! FIXME: that's a better plan and we can remove the toggle here. option(BUILD_DEDICATED_SERVER "Compile the dedicated server, too" FALSE) if(BUILD_DEDICATED_SERVER) add_executable(SeriousSamDedicated ${ENGINE_SRCS} DedicatedServer/DedicatedServer.cpp) + target_link_libraries(SeriousSamDedicated engine_safemath) add_dependencies(SeriousSamDedicated ParseEntities) # Make symbols in the main executable available to dynamic objects set_target_properties(SeriousSamDedicated PROPERTIES ENABLE_EXPORTS ON) diff --git a/Sources/Depend/Dependency.cpp b/Sources/Depend/Dependency.cpp index c923c25f1..624cbc2a3 100644 --- a/Sources/Depend/Dependency.cpp +++ b/Sources/Depend/Dependency.cpp @@ -29,12 +29,7 @@ void AdjustFilePath_t(CTFileName &fnm) } // class constructor -CDependInfo::CDependInfo(CTFileName fnFileName, CTFileName fnParent) -{ - // copy file name - di_fnFileName = fnFileName; - di_fnParent = fnParent; -} +CDependInfo::CDependInfo(CTFileName fnFileName, CTFileName fnParent): /*copy file name*/ di_fnFileName(fnFileName), di_fnParent(fnParent){} BOOL CDependInfo::IsFileOnDiskUpdated(void) { diff --git a/Sources/Ecc/CMakeLists.txt b/Sources/Ecc/CMakeLists.txt new file mode 100644 index 000000000..3a51733eb --- /dev/null +++ b/Sources/Ecc/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.7.2) +project(Ecc) + +if(MSVC) + add_compile_options(/W4) +else() + add_compile_options(-Wall) +endif() + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") +include(ParserAndScanner) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_parser_and_scanner("Parser" "Scanner") +add_executable(ecc Main.cpp Parser.cpp Parser.h Scanner.cpp) diff --git a/Sources/Ecc/Main.cpp b/Sources/Ecc/Main.cpp index 558ae5885..b5ab5c2ec 100644 --- a/Sources/Ecc/Main.cpp +++ b/Sources/Ecc/Main.cpp @@ -178,7 +178,6 @@ void ReplaceFileRL(const char *strOld, const char *strNew) // process each charachter for(int ich=0;ich #include -#ifdef PLATFORM_WIN32 +#ifdef _WIN32 #include -#endif - -#ifdef PLATFORM_UNIX +#else #include #include #include diff --git a/Sources/Ecc/unistd.h b/Sources/Ecc/unistd.h deleted file mode 100644 index c9c1cb0a7..000000000 --- a/Sources/Ecc/unistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. -This program is free software; you can redistribute it and/or modify -it under the terms of version 2 of the GNU General Public License as published by -the Free Software Foundation - - -This program 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 this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -#include diff --git a/Sources/Engine/Base/Anim.cpp b/Sources/Engine/Base/Anim.cpp index 8eff66e0b..be8dd73d9 100644 --- a/Sources/Engine/Base/Anim.cpp +++ b/Sources/Engine/Base/Anim.cpp @@ -458,15 +458,15 @@ void CAnimData::Write_t( CTStream *ostrFile) // throw char * // First we save main ID ostrFile->WriteID_t( CChunkID( "ADAT")); // Then we save number of how many animations do we have and then save them all - ostrFile->Write_t( &ad_NumberOfAnims, sizeof( INDEX)); + (*ostrFile)<Write_t( &ad_Anims[i].oa_Name, sizeof( NAME)); - ostrFile->Write_t( &ad_Anims[i].oa_SecsPerFrame, sizeof( TIME)); - ostrFile->Write_t( &ad_Anims[i].oa_NumberOfFrames, sizeof( INDEX)); - ostrFile->Write_t( ad_Anims[i].oa_FrameIndices, - ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX)); + (*ostrFile)< -#ifndef PLATFORM_WIN32 -#include "SDL.h" -#endif - INDEX con_bNoWarnings = 0; // global handle for application window in full-screen mode diff --git a/Sources/Engine/Base/FileName.cpp b/Sources/Engine/Base/FileName.cpp index ffd30b411..a036e736e 100644 --- a/Sources/Engine/Base/FileName.cpp +++ b/Sources/Engine/Base/FileName.cpp @@ -37,7 +37,7 @@ const char *CTFileName::convertFromWin32(const char *src) static const char *dirsep = NULL; static size_t seplen = 0; static char buf[MAX_PATH]; // This is NOT thread safe, fyi. - char *dest = buf; + char *dest; if (src == NULL) { @@ -78,7 +78,7 @@ const char *CTFileName::convertToWin32(const char *src) static const char *dirsep = NULL; static size_t seplen = 0; static char buf[MAX_PATH]; // This is NOT thread safe, fyi. - char *dest = buf; + char *dest; if (src == NULL) { diff --git a/Sources/Engine/Base/Profiling.h b/Sources/Engine/Base/Profiling.h old mode 100644 new mode 100755 index 4bd9154d0..6fae05a6e --- a/Sources/Engine/Base/Profiling.h +++ b/Sources/Engine/Base/Profiling.h @@ -118,6 +118,9 @@ class CProfileForm { /* Get current value of a counter. */ INDEX GetCounterCount(INDEX iCounter); + inline void CountersClear() {pf_apcCounters.Clear();}; + inline void TimersClear() {pf_aptTimers.Clear();}; + #if TIMER_PROFILING /* Start a timer. */ inline void StartTimer(INDEX iTimer) { @@ -173,11 +176,14 @@ class CProfileForm { inline void IncrementCounter(INDEX iCounter, INDEX ctAdd=1) {} inline void StartTimer(INDEX iTimer) {}; inline void StopTimer(INDEX iTimer) {}; + inline void IncrementAveragingCounter(INDEX ctAdd=1) {}; inline void IncrementTimerAveragingCounter(INDEX iTimer, INDEX ctAdd=1) {}; inline void SetCounterName_internal(INDEX iCounter, const CTString &strName) {}; inline void SetTimerName_internal(INDEX iTimer, const CTString &strName, const CTString &strAveragingName) {}; #define SETCOUNTERNAME(a,b) SetCounterName_internal(a,"") #define SETTIMERNAME(a,b,c) SetTimerName_internal(a,"","") + inline void CountersClear() {}; + inline void TimersClear() {}; #endif // ENGINE_INTERNAL diff --git a/Sources/Engine/Base/SDL/SDLEvents.cpp b/Sources/Engine/Base/SDL/SDLEvents.cpp index aad7b99ee..ef507a68c 100755 --- a/Sources/Engine/Base/SDL/SDLEvents.cpp +++ b/Sources/Engine/Base/SDL/SDLEvents.cpp @@ -50,10 +50,10 @@ BOOL PeekMessage(MSG *msg, void *hwnd, UINT wMsgFilterMin, case SDL_KEYUP: if (sdlevent.key.keysym.sym == SDLK_BACKQUOTE) msg->unicode = '~'; // !!! FIXME: this is all a hack. - #ifdef PLATFORM_PANDORA - if(sdlevent.key.keysym.sym == SDLK_RCTRL) { + #if defined(PLATFORM_PANDORA) || defined(PPLATFORM_PYRA) + if(sdlevent.key.keysym.sym == SDLK_RSHIFT) { msg->message = (sdlevent.type==SDL_KEYDOWN)?WM_RBUTTONDOWN:WM_RBUTTONUP; - } else if(sdlevent.key.keysym.sym == SDLK_RSHIFT) { + } else if(sdlevent.key.keysym.sym == SDLK_RCTRL) { msg->message = (sdlevent.type==SDL_KEYDOWN)?WM_LBUTTONDOWN:WM_LBUTTONUP; } else #endif @@ -85,6 +85,11 @@ BOOL PeekMessage(MSG *msg, void *hwnd, UINT wMsgFilterMin, msg->message = WM_PAINT; return TRUE; } + if (sdlevent.window.event == SDL_WINDOWEVENT_MINIMIZED) + { + msg->wParam = sdlevent.window.event; + return TRUE; + } break; // These all map to WM_* things without any drama. @@ -114,8 +119,8 @@ void DispatchMessage(MSG *msg) SHORT GetKeyState(int vk) { SHORT retval = 0; -#ifdef PLATFORM_PANDORA - Uint8 *keystate = SDL_GetKeyboardState(NULL); +#if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + const Uint8 *keystate = SDL_GetKeyboardState(NULL); #endif switch (vk) @@ -123,8 +128,8 @@ SHORT GetKeyState(int vk) case VK_LBUTTON: if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LMASK) retval = 0x8000; - #ifdef PLATFORM_PANDORA - if(keystate[SDL_SCANCODE_RSHIFT]) + #if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + if(keystate[SDL_SCANCODE_RCTRL]) retval = 0x8000; #endif break; @@ -132,8 +137,8 @@ SHORT GetKeyState(int vk) case VK_RBUTTON: if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_RMASK) retval = 0x8000; - #ifdef PLATFORM_PANDORA - if(keystate[SDL_SCANCODE_RCTRL]) + #if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + if(keystate[SDL_SCANCODE_RSHIFT]) retval = 0x8000; #endif break; @@ -145,7 +150,7 @@ SHORT GetKeyState(int vk) default: STUBBED("this can't possibly be right, yeah?"); - #ifdef PLATFORM_PANDORA + #if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) if (keystate[SDL_GetScancodeFromKey((SDL_Keycode)vk)]) #else if (SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey((SDL_Keycode)vk)]) diff --git a/Sources/Engine/Base/SDL/SDLInput.cpp b/Sources/Engine/Base/SDL/SDLInput.cpp index 17ebefa7e..32f10afe1 100755 --- a/Sources/Engine/Base/SDL/SDLInput.cpp +++ b/Sources/Engine/Base/SDL/SDLInput.cpp @@ -2,6 +2,7 @@ /* rcg10072001 Moved stuff into this file. */ +#define __STDC_LIMIT_MACROS 1 #include "SDL.h" #include @@ -287,11 +288,11 @@ static void SetKeyFromEvent(const SDL_Event *event, const BOOL bDown) return; } // if - #ifdef PLATFORM_PANDORA - if(event->key.keysym.sym==SDLK_RSHIFT) { + #if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + if(event->key.keysym.sym==SDLK_RCTRL) { _abKeysPressed[KID_MOUSE1] = bDown; return; - } else if(event->key.keysym.sym==SDLK_RCTRL) { + } else if(event->key.keysym.sym==SDLK_RSHIFT) { _abKeysPressed[KID_MOUSE2] = bDown; return; } @@ -724,7 +725,7 @@ void CInput::GetInput(BOOL bPreScan) // clear button's buffer memset( inp_ubButtonsBuffer, 0, sizeof( inp_ubButtonsBuffer)); - Uint8 *keystate = SDL_GetKeyboardState(NULL); + const Uint8 *keystate = SDL_GetKeyboardState(NULL); // for each Key for (INDEX iKey=0; iKey diff --git a/Sources/Engine/Base/Shell.cpp b/Sources/Engine/Base/Shell.cpp index 26115287e..3fe98ea82 100644 --- a/Sources/Engine/Base/Shell.cpp +++ b/Sources/Engine/Base/Shell.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation @@ -182,6 +182,7 @@ CTString ScriptEsc(const CTString &str) #pragma inline_depth(0) void MakeAccessViolation(void* pArgs) + { INDEX bDont = NEXTARGUMENT(INDEX); if( bDont) return; @@ -674,7 +675,7 @@ FLOAT CShell::GetFLOAT(const CTString &strName) // error ASSERT(FALSE); return -666.0f; - } + } // get it return *(FLOAT*)pss->ss_pvValue; } @@ -688,7 +689,7 @@ void CShell::SetFLOAT(const CTString &strName, FLOAT fValue) // error ASSERT(FALSE); return; - } + } // set it *(FLOAT*)pss->ss_pvValue = fValue; } @@ -703,7 +704,7 @@ INDEX CShell::GetINDEX(const CTString &strName) // error ASSERT(FALSE); return -666; - } + } // get it return *(INDEX*)pss->ss_pvValue; } @@ -717,7 +718,7 @@ void CShell::SetINDEX(const CTString &strName, INDEX iValue) // error ASSERT(FALSE); return; - } + } // set it *(INDEX*)pss->ss_pvValue = iValue; } @@ -732,7 +733,7 @@ CTString CShell::GetString(const CTString &strName) // error ASSERT(FALSE); return ""; - } + } // get it return *(CTString*)pss->ss_pvValue; } @@ -746,7 +747,7 @@ void CShell::SetString(const CTString &strName, const CTString &strValue) // error ASSERT(FALSE); return; - } + } // set it *(CTString*)pss->ss_pvValue = strValue; } @@ -762,7 +763,7 @@ CTString CShell::GetValue(const CTString &strName) // error ASSERT(FALSE); return ""; - } + } // get it ShellTypeType stt = _shell_ast[pss->ss_istType].st_sttType; @@ -795,7 +796,7 @@ void CShell::SetValue(const CTString &strName, const CTString &strValue) // error ASSERT(FALSE); return; - } + } // get it ShellTypeType stt = _shell_ast[pss->ss_istType].st_sttType; switch(stt) { diff --git a/Sources/Engine/Base/Statistics.cpp b/Sources/Engine/Base/Statistics.cpp index ffb84a1d4..67ceac5b3 100644 --- a/Sources/Engine/Base/Statistics.cpp +++ b/Sources/Engine/Base/Statistics.cpp @@ -195,3 +195,8 @@ void STAT_Report(CTString &strReport) { _sfStats.Report(strReport); } + +void STAT_Enable(BOOL enable) +{ + _sfStats.sf_enabled = enable; +} diff --git a/Sources/Engine/Base/Statistics.h b/Sources/Engine/Base/Statistics.h index 121b77db9..b351780f1 100644 --- a/Sources/Engine/Base/Statistics.h +++ b/Sources/Engine/Base/Statistics.h @@ -24,6 +24,7 @@ ENGINE_API void STAT_Reset(void); // make a new report ENGINE_API void STAT_Report(CTString &strReport); +ENGINE_API void STAT_Enable(BOOL enable); #endif /* include-once check. */ diff --git a/Sources/Engine/Base/Statistics_Internal.h b/Sources/Engine/Base/Statistics_Internal.h index 3ba689fd2..de18cdb94 100644 --- a/Sources/Engine/Base/Statistics_Internal.h +++ b/Sources/Engine/Base/Statistics_Internal.h @@ -77,6 +77,7 @@ class CStatForm { CStaticArray sf_ascCounters; // profiling counters CStaticArray sf_astTimers; // profiling timers CStaticArray sf_aslLabels; // profiling labels + BOOL sf_enabled; // interface: enum StatLabelIndex @@ -157,13 +158,15 @@ class CStatForm { inline void StartTimer(INDEX iTimer) { CStatTimer &st = sf_astTimers[iTimer]; ASSERT( sf_astTimers[iTimer].st_tvStarted.tv_llValue == -1); - st.st_tvStarted = _pTimer->GetHighPrecisionTimer(); + if (sf_enabled) + st.st_tvStarted = _pTimer->GetHighPrecisionTimer(); }; /* Stop a timer. */ inline void StopTimer(INDEX iTimer) { CStatTimer &st = sf_astTimers[iTimer]; ASSERT( sf_astTimers[iTimer].st_tvStarted.tv_llValue != -1); - st.st_tvElapsed += _pTimer->GetHighPrecisionTimer()-st.st_tvStarted; + if (sf_enabled) + st.st_tvElapsed += _pTimer->GetHighPrecisionTimer()-st.st_tvStarted; st.st_tvStarted.tv_llValue = -1; }; diff --git a/Sources/Engine/Base/Stream.cpp b/Sources/Engine/Base/Stream.cpp index 79cc5d6a3..653ed17c9 100755 --- a/Sources/Engine/Base/Stream.cpp +++ b/Sources/Engine/Base/Stream.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include // !!! FIXME : rcg10162001 Need this anymore, since _findfirst() is abstracted? #ifdef PLATFORM_WIN32 @@ -497,6 +498,7 @@ SLONG CTStream::GetSize_t(void) // throws char * SLONG chunkSize; Read_t( (char *) &chunkSize, sizeof( SLONG)); + BYTESWAP(chunkSize); return( chunkSize); } @@ -918,7 +920,13 @@ void CTFileStream::Open_t(const CTFileName &fnFileName, CTStream::OpenMode om/*= static void MakeSureDirectoryPathExists(const CTFileName &fnmFullFileName) { - STUBBED("!!! FIXME: get the code back in from Ryan's original port."); + CTFileName fnDirectory = fnmFullFileName.FileDir(); + const char *path = (const char *) (CTString&)fnDirectory; + std::error_code ec; + std::filesystem::create_directories(path, ec); + if (ec) { + FatalError("Cannot create directory path:\n%s", path); + } } /* diff --git a/Sources/Engine/Base/Timer.cpp b/Sources/Engine/Base/Timer.cpp index b82043b46..604b9aa1a 100755 --- a/Sources/Engine/Base/Timer.cpp +++ b/Sources/Engine/Base/Timer.cpp @@ -46,7 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc., static inline __int64 ReadTSC(void) { #if USE_GETTIMEOFDAY -#ifdef PLATFORM_PANDORA +#if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); return( (((__int64) tp.tv_sec) * 1000000000LL) + ((__int64) tp.tv_nsec)); @@ -180,6 +180,8 @@ void CTimer_TimerFunc_internal(void) _pTimer->tm_tvLastTimeOnTime = tvTimeNow; _pTimer->tm_tmLastTickOnTime = tmTickNow; + _pTimer->tm_tvLowPrecisionTimer = tvTimeNow; + // } CTSTREAM_END; } @@ -322,7 +324,7 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/) #if USE_GETTIMEOFDAY // just use gettimeofday. - #ifdef PLATFORM_PANDORA + #if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) tm_llCPUSpeedHZ = tm_llPerformanceCounterFrequency = 1000000000LL; #else tm_llCPUSpeedHZ = tm_llPerformanceCounterFrequency = 1000000; diff --git a/Sources/Engine/Base/Timer.h b/Sources/Engine/Base/Timer.h index f0660e1bf..04a934773 100755 --- a/Sources/Engine/Base/Timer.h +++ b/Sources/Engine/Base/Timer.h @@ -78,6 +78,8 @@ class ENGINE_API CTimer { CTimerValue tm_tvLastTimeOnTime; // last time when timer was on time TIME tm_tmLastTickOnTime; // last tick when timer was on time + CTimerValue tm_tvLowPrecisionTimer; + TIME tm_RealTimeTimer; // this really ticks at 1/TickQuantum frequency FLOAT tm_fLerpFactor; // factor used for lerping between frames FLOAT tm_fLerpFactor2; // secondary lerp-factor used for unpredicted movement @@ -137,6 +139,8 @@ class ENGINE_API CTimer { /* Get current timer value of high precision timer. */ CTimerValue GetHighPrecisionTimer(void); + inline CTimerValue GetLowPrecisionTimer(void) const { return tm_tvLowPrecisionTimer; }; + /* * rcg10072001 * put current process to sleep for at least (milliseconds) milliseconds. diff --git a/Sources/Engine/Base/Types.h b/Sources/Engine/Base/Types.h old mode 100644 new mode 100755 index 0a7d54391..c7966754a --- a/Sources/Engine/Base/Types.h +++ b/Sources/Engine/Base/Types.h @@ -56,7 +56,7 @@ typedef uint32_t UINT; #endif // TODO: add more architecture detection routines -#if __POWERPC__ || (defined __ppc64__) || (defined __alpha__) || (defined __sparc__) /* rcg03232004 */ +#if (defined __hppa__) || (defined __m68k__) || (defined __s390x__) || (defined __sparc__) || __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ /* rcg03232004 */ #define PLATFORM_BIGENDIAN 1 #define PLATFORM_LITTLEENDIAN 0 #else @@ -65,7 +65,7 @@ typedef uint32_t UINT; #endif #if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_ARCH_PPC64) \ - || defined(_M_IA64) || defined(__IA64__) + || defined(_M_IA64) || defined(__IA64__) || defined(__e2k__) || defined(__alpha__) || defined(__loongarch__) || defined(__riscv) || defined(__s390x__) || (defined(__mips__) && _MIPS_SIM == _ABI64) || (defined(__sparc__) && defined(__arch64__)) #define PLATFORM_64BIT 1 @@ -78,7 +78,6 @@ typedef uint32_t UINT; #error "Unknown CPU-Architecture, adapt this code to detect 32/64bitness of your system!" #endif - // if the compiler complains about the typedef created by MY_STATIC_ASSERT being invalid // (because of array with negative size), it means the check for cond has failed #define MY_STATIC_ASSERT(namesuffx, cond) \ @@ -233,7 +232,7 @@ MY_STATIC_ASSERT(size_tSize, sizeof(size_t) == sizeof(void*)); } } - inline ULONG _rotl(ULONG ul, int bits) + inline ULONG rotl(ULONG ul, int bits) { #if (defined __GNU_INLINE_X86_32__) // This, on the other hand, is wicked fast. :) @@ -760,6 +759,9 @@ inline __uint64 BYTESWAP64_unsigned(__uint64 x) val = *((SLONG *) &uval); } +/** + * BOOL is int32_t , just like SLONG + * so don't define the same function twice static inline void BYTESWAP(BOOL &val) { // !!! FIXME: reinterpret_cast ? @@ -767,6 +769,7 @@ inline __uint64 BYTESWAP64_unsigned(__uint64 x) BYTESWAP(uval); val = *((BOOL *) &uval); } +*/ static inline void BYTESWAP(FLOAT &val) { diff --git a/Sources/Engine/Base/Unix/UnixFileSystem.cpp b/Sources/Engine/Base/Unix/UnixFileSystem.cpp index 32a24e2e7..779a0e62f 100644 --- a/Sources/Engine/Base/Unix/UnixFileSystem.cpp +++ b/Sources/Engine/Base/Unix/UnixFileSystem.cpp @@ -22,6 +22,43 @@ ENGINE_API CFileSystem *_pFileSystem = NULL; +// Stolen from SDL2/src/filesystem/unix/SDL_sysfilesystem.c +static char * readSymLink(const char *path) +{ + char *retval = NULL; + ssize_t len = 64; + ssize_t rc = -1; + + while (1) + { + char *ptr = (char *) SDL_realloc(retval, (size_t) len); + if (ptr == NULL) { + SDL_OutOfMemory(); + break; + } + + retval = ptr; + + rc = readlink(path, retval, len); + if (rc == -1) { + break; /* not a symlink, i/o error, etc. */ + } else if (rc < len) { + retval[rc] = '\0'; /* readlink doesn't null-terminate. */ + + /* try to shrink buffer... */ + ptr = (char *) SDL_realloc(retval, strlen(retval) + 1); + if (ptr != NULL) + retval = ptr; /* oh well if it failed. */ + + return retval; /* we're good to go. */ + } + + len *= 2; /* grow buffer, try again. */ + } + + SDL_free(retval); + return NULL; +} class CUnixFileSystem : public CFileSystem { @@ -77,7 +114,7 @@ BOOL CFileSystem::IsDirectory(const char *fname) CUnixFileSystem::CUnixFileSystem(const char *argv0, const char *gamename) { - exePath = SDL_GetBasePath(); + exePath = readSymLink("/proc/self/exe"); userDir = SDL_GetPrefPath("Serious Engine", gamename); } diff --git a/Sources/Engine/Base/Unzip.cpp b/Sources/Engine/Base/Unzip.cpp index 66df7a8cb..a76bb570c 100644 --- a/Sources/Engine/Base/Unzip.cpp +++ b/Sources/Engine/Base/Unzip.cpp @@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., typedef unsigned char Byte; // !!! FIXME: not sure why I suddenly needed this typedef here. #endif -#include +#include extern CTCriticalSection zip_csLock; // critical section for access to zlib functions #pragma pack(1) @@ -166,11 +166,8 @@ CTString GetZlibError(int ierr) } } -CZipHandle::CZipHandle(void) +CZipHandle::CZipHandle(void): zh_bOpen(FALSE), zh_fFile(NULL), zh_pubBufIn(NULL) { - zh_bOpen = FALSE; - zh_fFile = NULL; - zh_pubBufIn = NULL; memset(&zh_zstream, 0, sizeof(zh_zstream)); } void CZipHandle::Clear(void) diff --git a/Sources/Engine/Base/Win32/Win32DynamicLoader.cpp b/Sources/Engine/Base/Win32/Win32DynamicLoader.cpp index a0af2fa06..bb419eeed 100644 --- a/Sources/Engine/Base/Win32/Win32DynamicLoader.cpp +++ b/Sources/Engine/Base/Win32/Win32DynamicLoader.cpp @@ -2,6 +2,8 @@ /* rcg10072001 Implemented. */ +#ifdef PLATFORM_WIN32 + #include #include @@ -83,6 +85,7 @@ CWin32DynamicLoader::~CWin32DynamicLoader(void) ::FreeLibrary(module); } +#endif //PLATFORM_WIN32 // end of Win32DynamicLoader.cpp ... diff --git a/Sources/Engine/Base/Win32/Win32FileSystem.cpp b/Sources/Engine/Base/Win32/Win32FileSystem.cpp index fe6f3cfaf..e64582f15 100644 --- a/Sources/Engine/Base/Win32/Win32FileSystem.cpp +++ b/Sources/Engine/Base/Win32/Win32FileSystem.cpp @@ -4,6 +4,8 @@ // !!! FIXME: rcg10142001 This should really be using CTStrings... +#ifdef PLATFORM_WIN32 + #include #include @@ -116,6 +118,6 @@ CDynamicArray CWin32FileSystem::FindFiles(const char *dir, return(retval); } -// end of Win32FileSystem.cpp ... - +#endif //PLATFORM_WIN32 +// end of Win32FileSystem.cpp ... diff --git a/Sources/Engine/Base/Win32/Win32Input.cpp b/Sources/Engine/Base/Win32/Win32Input.cpp index 41fff9792..213fe1914 100644 --- a/Sources/Engine/Base/Win32/Win32Input.cpp +++ b/Sources/Engine/Base/Win32/Win32Input.cpp @@ -2,6 +2,8 @@ /* rcg10072001 Moved stuff into this file. */ +#ifdef PLATFORM_WIN32 + #include #include #include @@ -982,5 +984,7 @@ LONG CInput::PlatformGetJoystickCount(void) return((LONG) joyGetNumDevs()); } +#endif //PLATFORM_WIN32 + // end of Win32Input.cpp ... diff --git a/Sources/Engine/Base/Win32/Win32Synchronization.cpp b/Sources/Engine/Base/Win32/Win32Synchronization.cpp index 00a009349..655101e05 100644 --- a/Sources/Engine/Base/Win32/Win32Synchronization.cpp +++ b/Sources/Engine/Base/Win32/Win32Synchronization.cpp @@ -13,6 +13,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifdef PLATFORM_WIN32 + #include "Engine/StdH.h" #include @@ -317,3 +319,4 @@ void CTSingleLock::Unlock(void) sl_bLocked = FALSE; } +#endif //PLATFORM_WIN32 diff --git a/Sources/Engine/Base/Win32/Win32Timer.cpp b/Sources/Engine/Base/Win32/Win32Timer.cpp index 8eb701e8a..bb4d3a9a3 100644 --- a/Sources/Engine/Base/Win32/Win32Timer.cpp +++ b/Sources/Engine/Base/Win32/Win32Timer.cpp @@ -2,6 +2,8 @@ /* rcg10072001 Moved stuff into this file. */ +#ifdef PLATFORM_WIN32 + #include #include @@ -10,6 +12,8 @@ void CTimer::Sleep(DWORD milliseconds) ::Sleep(milliseconds); } +#endif //PLATFORM_WIN32 + // end of Win32Timer.cpp ... diff --git a/Sources/Engine/Brushes/Brush.h b/Sources/Engine/Brushes/Brush.h old mode 100644 new mode 100755 index 7458953f6..bd991c324 --- a/Sources/Engine/Brushes/Brush.h +++ b/Sources/Engine/Brushes/Brush.h @@ -407,6 +407,8 @@ class ENGINE_API CBrushPolygon { /* Create a BSP polygon from this polygon. */ void CreateBSPPolygon(BSPPolygon &bspo); void CreateBSPPolygonNonPrecise(BSPPolygon &bspo); + void CreateBSPPolygon(BSPPolygon &bspo); + void CreateBSPPolygonNonPrecise(BSPPolygon &bspo); /* Create shadow map for the polygon. */ void MakeShadowMap(CWorld *pwoWorld, BOOL bDoDirectionalLights); /* Initialize shadow map for the polygon. */ @@ -422,20 +424,21 @@ class ENGINE_API CBrushPolygon { void Triangulate(void); public: // interface: + FLOATaabbox3D bpo_boxBoundingBox; // bounding box + ULONG bpo_ulFlags; // flags + CBrushPlane *bpo_pbplPlane; // plane of this polygon CStaticArray bpo_abpePolygonEdges; // edges in this polygon CStaticArray bpo_apbvxTriangleVertices; // triangle vertices CStaticArray bpo_aiTriangleElements; // element indices inside vertex arrays CBrushPolygonTexture bpo_abptTextures[3]; // texture on this polygon COLOR bpo_colColor; // color of this polygon - ULONG bpo_ulFlags; // flags COLOR bpo_colShadow; // color of shadow on this polygon CBrushShadowMap bpo_smShadowMap; // shadow map of this polygon CMappingDefinition bpo_mdShadow; // mapping of shadow on polygon CBrushPolygonProperties bpo_bppProperties; // additional properties class CScreenPolygon *bpo_pspoScreenPolygon; // used in rendering - FLOATaabbox3D bpo_boxBoundingBox; // bounding box CBrushSector *bpo_pbscSector; // sector of this polygon CRelationSrc bpo_rsOtherSideSectors; // relation to sectors on other side of portal @@ -479,7 +482,11 @@ class ENGINE_API CBrushPolygon { // get amount of memory used by this object SLONG GetUsedMemory(void); -}; +} +#ifdef __arm__ +__attribute__((aligned(64))) +#endif +; // get pointer to embedding brush polygon inline CBrushPolygon *CBrushShadowMap::GetBrushPolygon(void) { @@ -562,7 +569,7 @@ class ENGINE_API CBrushSector { FLOATaabbox3D bsc_boxBoundingBox; // bounding box in absolute space FLOATaabbox3D bsc_boxRelative; // bounding box in relative space CListNode bsc_lnInActiveSectors; // node in sectors active in some operation (e.g. rendering) - DOUBLEbsptree3D &bsc_bspBSPTree; // the local bsp tree of the sector + FLOATbsptree3D &bsc_bspBSPTree; // the local bsp tree of the sector CRelationDst bsc_rdOtherSidePortals; // relation to portals pointing to this sector CRelationSrc bsc_rsEntities; // relation to all entities in this sector CTString bsc_strName; // sector name diff --git a/Sources/Engine/Brushes/BrushArchive.cpp b/Sources/Engine/Brushes/BrushArchive.cpp old mode 100644 new mode 100755 index f7b5e0a86..2478446e5 --- a/Sources/Engine/Brushes/BrushArchive.cpp +++ b/Sources/Engine/Brushes/BrushArchive.cpp @@ -150,10 +150,10 @@ void CBrushArchive::LinkPortalsAndSectors(void) } // create a BSP polygon from the brush polygon CBrushPolygon &brpo2 = *itbpo2; - BSPPolygon bspo2; + BSPPolygon bspo2; brpo2.CreateBSPPolygonNonPrecise(bspo2); // split the polygon with the BSP of the sector - DOUBLEbspcutter3D bcCutter(bspo2, *itbsc1->bsc_bspBSPTree.bt_pbnRoot); + FLOATbspcutter3D bcCutter(bspo2, *itbsc1->bsc_bspBSPTree.bt_pbnRoot); // if anything remains on the border looking outside if (bcCutter.bc_abedInside.Count()>0 ||bcCutter.bc_abedBorderInside.Count()>0 diff --git a/Sources/Engine/Brushes/BrushIO.cpp b/Sources/Engine/Brushes/BrushIO.cpp index 1a93dae89..be5b58fc3 100644 --- a/Sources/Engine/Brushes/BrushIO.cpp +++ b/Sources/Engine/Brushes/BrushIO.cpp @@ -246,7 +246,7 @@ void CBrushPolygonTexture::Read_t( CTStream &strm) // throw char * void CBrushPolygonTexture::Write_t( CTStream &strm) // throw char * { strm<Write_t(&itbvx->bvx_vdPreciseRelative, sizeof(DOUBLE3D)); + (*postrm)<bvx_vdPreciseRelative; }} (*postrm).WriteID_t("PLNs"); // 'planes' @@ -289,7 +289,7 @@ void CBrushSector::Write_t( CTStream *postrm) // throw char * // for each plane {FOREACHINSTATICARRAY(bsc_abplPlanes, CBrushPlane, itbpl) { // write precise plane coordinates - postrm->Write_t(&itbpl->bpl_pldPreciseRelative, sizeof(DOUBLEplane3D)); + (*postrm)<bpl_pldPreciseRelative; }} (*postrm).WriteID_t("EDGs"); // 'edges' @@ -320,7 +320,7 @@ void CBrushSector::Write_t( CTStream *postrm) // throw char * bpo.bpo_abptTextures[1].Write_t(*postrm); bpo.bpo_abptTextures[2].Write_t(*postrm); // write other polygon properties - (*postrm).Write_t(&bpo.bpo_bppProperties, sizeof(bpo.bpo_bppProperties)); + (*postrm)<0) { - (*postrm).Write_t(&bpo.bpo_aiTriangleElements[0], ctElements*sizeof(INDEX)); + for (INDEX i = 0; i < ctElements; i++) { + (*postrm)< &bspo) }} bspo.bpo_abedPolygonEdges.Unlock(); } + +void CBrushPolygon::CreateBSPPolygon(BSPPolygon &bspo) +{ + ASSERT(GetFPUPrecision()==FPT_53BIT); + CBrushPolygon &brpo = *this; + + // set the plane of the bsp polygon + ((FLOATplane3D &)bspo) = DOUBLEtoFLOAT(*brpo.bpo_pbplPlane->bpl_ppldPreciseAbsolute); + bspo.bpo_ulPlaneTag = (size_t)brpo.bpo_pbscSector->bsc_abplPlanes.Index(brpo.bpo_pbplPlane); + + // create the array of edges in the bsp polygon + INDEX ctEdges = brpo.bpo_abpePolygonEdges.Count(); + bspo.bpo_abedPolygonEdges.New(ctEdges); + + // for all edges in the polygon + bspo.bpo_abedPolygonEdges.Lock(); + {for(INDEX iEdge=0; iEdge &bed = bspo.bpo_abedPolygonEdges[iEdge]; + // create the bsp edge in the bsp polygon + Vector v0, v1; + brped.GetVertexCoordinatesPreciseAbsolute(v0, v1); + bed.bed_vVertex0 = DOUBLEtoFLOAT(v0); + bed.bed_vVertex1 = DOUBLEtoFLOAT(v1); + }} + bspo.bpo_abedPolygonEdges.Unlock(); +} + void CBrushPolygon::CreateBSPPolygonNonPrecise(BSPPolygon &bspo) { CBrushPolygon &brpo = *this; @@ -133,6 +161,39 @@ void CBrushPolygon::CreateBSPPolygonNonPrecise(BSPPolygon &bspo) bspo.bpo_abedPolygonEdges.Unlock(); } +void CBrushPolygon::CreateBSPPolygonNonPrecise(BSPPolygon &bspo) +{ + CBrushPolygon &brpo = *this; + + // offset for epsilon testing + const FLOAT fOffset = -0.01f; + + // set the plane of the bsp polygon + ((FLOATplane3D &)bspo) = brpo.bpo_pbplPlane->bpl_plAbsolute; + bspo.bpo_ulPlaneTag = (size_t)brpo.bpo_pbscSector->bsc_abplPlanes.Index(brpo.bpo_pbplPlane); + // calculate offset for points + FLOAT3D vOffset = ((FLOAT3D&)brpo.bpo_pbplPlane->bpl_plAbsolute)*-fOffset; + // offset the plane + bspo.Offset(fOffset); + + // create the array of edges in the bsp polygon + INDEX ctEdges = brpo.bpo_abpePolygonEdges.Count(); + bspo.bpo_abedPolygonEdges.New(ctEdges); + + // for all edges in the polygon + bspo.bpo_abedPolygonEdges.Lock(); + {for(INDEX iEdge=0; iEdge &bed = bspo.bpo_abedPolygonEdges[iEdge]; + // create the offseted bsp edge in the bsp polygon + FLOAT3D v0, v1; + brped.GetVertexCoordinatesAbsolute(v0, v1); + bed.bed_vVertex0 = v0+vOffset; + bed.bed_vVertex1 = v1+vOffset; + }} + bspo.bpo_abedPolygonEdges.Unlock(); +} + /* * Select adjacent polygons with same color as this one. */ diff --git a/Sources/Engine/Brushes/BrushSector.cpp b/Sources/Engine/Brushes/BrushSector.cpp old mode 100644 new mode 100755 index 09d9f9015..e8ddae8cf --- a/Sources/Engine/Brushes/BrushSector.cpp +++ b/Sources/Engine/Brushes/BrushSector.cpp @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., //template CDynamicArray; CBrushSector::CBrushSector(const CBrushSector &c) -: bsc_bspBSPTree(*new DOUBLEbsptree3D) +: bsc_bspBSPTree(*new FLOATbsptree3D) { ASSERT(FALSE); }; @@ -53,8 +53,8 @@ CBrushSector::CBrushSector(void) , bsc_ulFlags2(0) , bsc_ulTempFlags(0) , bsc_ulVisFlags(0) -, bsc_bspBSPTree(*new DOUBLEbsptree3D) , bsc_strName("") +, bsc_bspBSPTree(*new FLOATbsptree3D) { }; @@ -140,7 +140,7 @@ void CBrushSector::CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelative ((pen->en_ulFlags&ENF_ZONING) || pen->en_RenderType==CEntity::RT_FIELDBRUSH) ) { // create an array of bsp polygons for sector polygons INDEX ctPolygons = bsc_abpoPolygons.Count(); - CDynamicArray< BSPPolygon > arbpoPolygons; + CDynamicArray< BSPPolygon > arbpoPolygons; arbpoPolygons.New(ctPolygons); // for all polygons in this sector @@ -148,7 +148,7 @@ void CBrushSector::CalculateBoundingBoxes(CSimpleProjection3D_DOUBLE &prRelative {for(INDEX iPolygon=0; iPolygon &bspo = arbpoPolygons[iPolygon]; + BSPPolygon &bspo = arbpoPolygons[iPolygon]; brpo.CreateBSPPolygon(bspo); }} arbpoPolygons.Unlock(); @@ -234,14 +234,14 @@ void CBrushSector::FindEntitiesInSector(void) // if the sphere is inside the sector if (bsc_bspBSPTree.TestSphere( - FLOATtoDOUBLE(vSphereCenter), FLOATtoDOUBLE(fSphereRadius))>=0) { + vSphereCenter, fSphereRadius)>=0) { // make oriented bounding box of the entity FLOATobbox3D boxEntity(iten->en_boxSpatialClassification, iten->en_plPlacement.pl_PositionVector, iten->en_mRotation); // if the box is inside the sector if (boxSector.HasContactWith(boxEntity) && - bsc_bspBSPTree.TestBox(FLOATtoDOUBLE(boxEntity))>=0) { + bsc_bspBSPTree.TestBox(boxEntity)>=0) { // relate the entity to the sector if (iten->en_RenderType==CEntity::RT_BRUSH ||iten->en_RenderType==CEntity::RT_FIELDBRUSH diff --git a/Sources/Engine/Classes/MovableEntity.es b/Sources/Engine/Classes/MovableEntity.es old mode 100644 new mode 100755 index 7bc441e65..518787d34 --- a/Sources/Engine/Classes/MovableEntity.es +++ b/Sources/Engine/Classes/MovableEntity.es @@ -899,8 +899,8 @@ functions: } // get min/max parameters of entity inside sector - double dMin, dMax; - bsc.bsc_bspBSPTree.FindLineMinMax(FLOATtoDOUBLE(vMin), FLOATtoDOUBLE(vMax), dMin, dMax); + float dMin, dMax; + bsc.bsc_bspBSPTree.FindLineMinMax(vMin, vMax, dMin, dMax); // if sector content is not default INDEX iContent = bsc.GetContentType(); diff --git a/Sources/Engine/CurrentVersion.h b/Sources/Engine/CurrentVersion.h old mode 100644 new mode 100755 diff --git a/Sources/Engine/Engine.cpp b/Sources/Engine/Engine.cpp index 8bb493611..90700a9b7 100755 --- a/Sources/Engine/Engine.cpp +++ b/Sources/Engine/Engine.cpp @@ -45,9 +45,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -#if PLATFORM_UNIX -#include "SDL.h" -#endif // this version string can be referenced from outside the engine ENGINE_API CTString _strEngineBuild = ""; @@ -128,13 +125,6 @@ BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReser static void DetectCPU(void) { char strVendor[12+1] = { 0 }; -#if (defined USE_PORTABLE_C) // rcg10072001 - CPrintF(TRANSV(" (No CPU detection in this binary.)\n")); - #ifdef PLATFORM_PANDORA - sys_iCPUMHz = 400; // conservative, ARM -> x86 cpu translation is not 1 to 1. - #endif - -#else strVendor[12] = 0; ULONG ulTFMS = 0; ULONG ulFeatures = 0; @@ -221,8 +211,13 @@ static void DetectCPU(void) sys_iCPUStepping = iStepping; sys_bCPUHasMMX = bMMX!=0; sys_bCPUHasCMOV = bCMOV!=0; +#ifdef PLATFORM_PANDORA + sys_iCPUMHz = 400; // conservative, ARM -> x86 cpu translation is not 1 to 1. +#elif defined(PLATFORM_PYRA) + sys_iCPUMHz = 1000; +#else sys_iCPUMHz = INDEX(_pTimer->tm_llCPUSpeedHZ/1E6); - +#endif if( !bMMX) FatalError( TRANS("MMX support required but not present!")); } @@ -784,20 +779,20 @@ ENGINE_API void SE_EndEngine(void) // shutdown profilers _sfStats.Clear(); - _pfGfxProfile .pf_apcCounters.Clear(); - _pfGfxProfile .pf_aptTimers .Clear(); - _pfModelProfile .pf_apcCounters.Clear(); - _pfModelProfile .pf_aptTimers .Clear(); - _pfSoundProfile .pf_apcCounters.Clear(); - _pfSoundProfile .pf_aptTimers .Clear(); - _pfNetworkProfile .pf_apcCounters.Clear(); - _pfNetworkProfile .pf_aptTimers .Clear(); - _pfRenderProfile .pf_apcCounters.Clear(); - _pfRenderProfile .pf_aptTimers .Clear(); - _pfWorldEditingProfile .pf_apcCounters.Clear(); - _pfWorldEditingProfile .pf_aptTimers .Clear(); - _pfPhysicsProfile .pf_apcCounters.Clear(); - _pfPhysicsProfile .pf_aptTimers .Clear(); + _pfGfxProfile .CountersClear(); + _pfGfxProfile .TimersClear(); + _pfModelProfile .CountersClear(); + _pfModelProfile .TimersClear(); + _pfSoundProfile .CountersClear(); + _pfSoundProfile .TimersClear(); + _pfNetworkProfile .CountersClear(); + _pfNetworkProfile .TimersClear(); + _pfRenderProfile .CountersClear(); + _pfRenderProfile .TimersClear(); + _pfWorldEditingProfile .CountersClear(); + _pfWorldEditingProfile .TimersClear(); + _pfPhysicsProfile .CountersClear(); + _pfPhysicsProfile .TimersClear(); // remove default fonts if needed if( _pfdDisplayFont != NULL) { delete _pfdDisplayFont; _pfdDisplayFont=NULL; } diff --git a/Sources/Engine/Engine.h b/Sources/Engine/Engine.h old mode 100644 new mode 100755 index 0df14e55c..7f016501c --- a/Sources/Engine/Engine.h +++ b/Sources/Engine/Engine.h @@ -24,8 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc., // set this to 1 to enable checks whether somethig is deleted while iterating some array/container #define CHECKARRAYLOCKING 0 - - #include #include diff --git a/Sources/Engine/Entities/Entity.cpp b/Sources/Engine/Entities/Entity.cpp old mode 100644 new mode 100755 index 9117b760c..305d8324b --- a/Sources/Engine/Entities/Entity.cpp +++ b/Sources/Engine/Entities/Entity.cpp @@ -1826,7 +1826,6 @@ void CEntity::FindSectorsAroundEntity(void) // make oriented bounding box of the entity FLOATobbox3D boxEntity = FLOATobbox3D(en_boxSpatialClassification, en_plPlacement.pl_PositionVector, en_mRotation); - DOUBLEobbox3D boxdEntity = FLOATtoDOUBLE(boxEntity); // unset spatial clasification en_rdSectors.Clear(); @@ -1850,10 +1849,10 @@ void CEntity::FindSectorsAroundEntity(void) // if the sphere is inside the sector if (itbsc->bsc_bspBSPTree.TestSphere( - FLOATtoDOUBLE(vSphereCenter), FLOATtoDOUBLE(fSphereRadius))>=0) { + vSphereCenter, fSphereRadius)>=0) { // if the box is inside the sector - if (itbsc->bsc_bspBSPTree.TestBox(boxdEntity)>=0) { + if (itbsc->bsc_bspBSPTree.TestBox(boxEntity)>=0) { // relate the entity to the sector if (en_RenderType==RT_BRUSH ||en_RenderType==RT_FIELDBRUSH @@ -1890,7 +1889,6 @@ void CEntity::FindSectorsAroundEntityNear(void) // make oriented bounding box of the entity FLOATobbox3D oboxEntity = FLOATobbox3D(en_boxSpatialClassification, en_plPlacement.pl_PositionVector, en_mRotation); - DOUBLEobbox3D oboxdEntity = FLOATtoDOUBLE(oboxEntity); CListHead lhActive; // for each sector around this entity @@ -1921,13 +1919,13 @@ void CEntity::FindSectorsAroundEntityNear(void) (pbsc->bsc_boxBoundingBox.HasContactWith(boxEntity))&& // the sphere is inside the sector (pbsc->bsc_bspBSPTree.TestSphere( - FLOATtoDOUBLE(vSphereCenter), FLOATtoDOUBLE(fSphereRadius))>=0)&& + vSphereCenter, fSphereRadius)>=0)&& // (use more detailed testing for moving brushes) (en_RenderType!=RT_BRUSH|| // oriented box touches box of sector ((oboxEntity.HasContactWith(FLOATobbox3D(pbsc->bsc_boxBoundingBox)))&& // oriented box is in bsp - (pbsc->bsc_bspBSPTree.TestBox(oboxdEntity)>=0))); + (pbsc->bsc_bspBSPTree.TestBox(oboxEntity)>=0))); // if it is not if (!bIn) { // if it has link @@ -2866,7 +2864,7 @@ CBrushSector *CEntity::GetSectorFromPoint(const FLOAT3D &vPointAbs) // for each sector around entity {FOREACHSRCOFDST(en_rdSectors, CBrushSector, bsc_rsEntities, pbsc) // if point is in this sector - if( pbsc->bsc_bspBSPTree.TestSphere(FLOATtoDOUBLE(vPointAbs), 0.01)>=0) { + if( pbsc->bsc_bspBSPTree.TestSphere(vPointAbs, 0.01)>=0) { // return that return pbsc; } @@ -3407,7 +3405,7 @@ void CEntity::Write_t( CTStream *ostr) // throw char * <en_plPlacement.pl_PositionVector; const FLOATmatrix3D &m = pen->en_mRotation; FLOATobbox3D boxEntity = FLOATobbox3D(pen->en_boxSpatialClassification, v, m); - DOUBLEobbox3D boxdEntity = FLOATtoDOUBLE(boxEntity); // if the box touches the sector's BSP if (boxEntity.HasContactWith(FLOATobbox3D(_pbsc->bsc_boxBoundingBox)) && - _pbsc->bsc_bspBSPTree.TestBox(boxdEntity)<=0) { + _pbsc->bsc_bspBSPTree.TestBox(boxEntity)<=0) { // for each collision sphere CStaticArray &absSpheres = pen->en_pciCollisionInfo->ci_absSpheres; @@ -56,7 +55,7 @@ static BOOL EntityIsInside(CEntity *pen) ms.ms_vRelativeCenter0 = ms.ms_vCenter*m+v; // if the sphere is in the sector if (_pbsc->bsc_bspBSPTree.TestSphere( - FLOATtoDOUBLE(ms.ms_vRelativeCenter0), ms.ms_fR)<=0) { + ms.ms_vRelativeCenter0, ms.ms_fR)<=0) { return TRUE; } } diff --git a/Sources/Engine/GameAgent/GameAgent.cpp b/Sources/Engine/GameAgent/GameAgent.cpp index f459d2586..a5eb0ab65 100644 --- a/Sources/Engine/GameAgent/GameAgent.cpp +++ b/Sources/Engine/GameAgent/GameAgent.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation @@ -593,7 +593,7 @@ extern void GameAgent_EnumTrigger(BOOL bInternet) if ( _pNetwork->ga_bEnumerationChange ) { return; } - + if ( !bInternet && ga_bMSLegacy) { // make sure that there are no requests still stuck in buffer ga_asrRequests.Clear(); @@ -866,7 +866,7 @@ extern void GameAgent_EnumTrigger(BOOL bInternet) _bActivated = TRUE; _bInitialized = TRUE; _initializeWinsock(); - + } } } @@ -1051,7 +1051,7 @@ extern void GameAgent_EnumUpdate(void) pthread_detach(_hThread); } _bActivatedLocal = FALSE; - } + } #else /* MSLegacy */ if(_bActivated) { @@ -1152,7 +1152,7 @@ void* _MS_Thread(void *arg) { /** do recvfrom stuff **/ iRet = recvfrom(_sockudp, _szBuffer, 2048, 0, (sockaddr*)&_sinClient, &_iClientLength); FD_CLR(_sockudp, &readfds_udp); - if(iRet != -1 && iRet > 100 && iRet != SOCKET_ERROR) { + if(iRet > 100 && iRet != SOCKET_ERROR) { // null terminate the buffer _szBuffer[iRet] = 0; char *sPch = NULL; @@ -1360,7 +1360,7 @@ void* _LocalNet_Thread(void *arg) { /** do recvfrom stuff **/ iRet = recvfrom(_sockudp, _szBuffer, 2048, 0, (sockaddr*)&_sinClient, &_iClientLength); FD_CLR(_sockudp, &readfds_udp); - if(iRet != -1 && iRet > 100 && iRet != SOCKET_ERROR) { + if(iRet > 100 && iRet != SOCKET_ERROR) { // null terminate the buffer _szBuffer[iRet] = 0; char *sPch = NULL; @@ -1370,7 +1370,7 @@ void* _LocalNet_Thread(void *arg) { if(_szIPPortBufferLocal != NULL) { delete[] _szIPPortBufferLocal; } - _szIPPortBufferLocal = NULL; + _szIPPortBufferLocal = NULL; WSACleanup(); return 0; } else { diff --git a/Sources/Engine/Graphics/Adapter.cpp b/Sources/Engine/Graphics/Adapter.cpp index 32e23d1fe..956689f72 100644 --- a/Sources/Engine/Graphics/Adapter.cpp +++ b/Sources/Engine/Graphics/Adapter.cpp @@ -22,9 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc., // !!! FIXME : rcg11052001 move this somewhere. -#ifdef PLATFORM_UNIX -#include "SDL.h" -#endif +//#ifdef PLATFORM_UNIX +//#include "SDL.h" +//#endif extern BOOL _bDedicatedServer; #ifdef SE1_D3D diff --git a/Sources/Engine/Graphics/Benchmark.cpp b/Sources/Engine/Graphics/Benchmark.cpp old mode 100644 new mode 100755 index dd5df5e14..8585c315f --- a/Sources/Engine/Graphics/Benchmark.cpp +++ b/Sources/Engine/Graphics/Benchmark.cpp @@ -48,7 +48,7 @@ static CTexParams _tpLocal; static CStaticStackArray _avtx; static CStaticStackArray _atex; static CStaticStackArray _acol; -static CStaticStackArray _aiElements; +static CStaticStackArray _aiElements; @@ -88,7 +88,7 @@ static DOUBLE FillRatePass(INDEX ct) avtx[3].x = _pixSizeI; avtx[3].y = 0; avtx[3].z = 0.5f; GFXTexCoord atex[4] = { {0,0}, {0,1}, {1,1}, {1,0} }; GFXColor acol[4] = { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFF00FF }; - INDEX aidx[6] = { 0,1,2, 0,2,3}; + INDEX_T aidx[6] = { 0,1,2, 0,2,3}; gfxSetVertexArray( &avtx[0], 4); gfxSetTexCoordArray( &atex[0], FALSE); gfxSetColorArray( &acol[0]); diff --git a/Sources/Engine/Graphics/Color.cpp b/Sources/Engine/Graphics/Color.cpp old mode 100644 new mode 100755 index 6a6519ce6..d1788f305 --- a/Sources/Engine/Graphics/Color.cpp +++ b/Sources/Engine/Graphics/Color.cpp @@ -124,6 +124,12 @@ BOOL CompareChroma( COLOR col1, COLOR col2) SLONG slR2=0, slG2=0, slB2=0; ColorToRGB( col1, (UBYTE&)slR1, (UBYTE&)slG1, (UBYTE&)slB1); ColorToRGB( col2, (UBYTE&)slR2, (UBYTE&)slG2, (UBYTE&)slB2); + BYTESWAP(slR1); + BYTESWAP(slG1); + BYTESWAP(slB1); + BYTESWAP(slR2); + BYTESWAP(slG2); + BYTESWAP(slB2); SLONG slMax1 = Max(Max(slR1,slG1),slB1); SLONG slMax2 = Max(Max(slR2,slG2),slB2); // trivial? @@ -425,10 +431,10 @@ COLOR MulColors( COLOR col1, COLOR col2) conv1.col = col1; conv2.col = col2; - conv1.bytes[0] = (UBYTE) ((((DWORD) conv1.bytes[0]) * ((DWORD) conv2.bytes[0])) / 255); - conv1.bytes[1] = (UBYTE) ((((DWORD) conv1.bytes[1]) * ((DWORD) conv2.bytes[1])) / 255); - conv1.bytes[2] = (UBYTE) ((((DWORD) conv1.bytes[2]) * ((DWORD) conv2.bytes[2])) / 255); - conv1.bytes[3] = (UBYTE) ((((DWORD) conv1.bytes[3]) * ((DWORD) conv2.bytes[3])) / 255); + conv1.bytes[0] = (UBYTE) ((((DWORD) conv1.bytes[0]) * ((DWORD) conv2.bytes[0])) >> 8); + conv1.bytes[1] = (UBYTE) ((((DWORD) conv1.bytes[1]) * ((DWORD) conv2.bytes[1])) >> 8); + conv1.bytes[2] = (UBYTE) ((((DWORD) conv1.bytes[2]) * ((DWORD) conv2.bytes[2])) >> 8); + conv1.bytes[3] = (UBYTE) ((((DWORD) conv1.bytes[3]) * ((DWORD) conv2.bytes[3])) >> 8); return(conv1.col); #endif diff --git a/Sources/Engine/Graphics/DepthCheck.cpp b/Sources/Engine/Graphics/DepthCheck.cpp old mode 100644 new mode 100755 index 1f1aa5c05..17e267b70 --- a/Sources/Engine/Graphics/DepthCheck.cpp +++ b/Sources/Engine/Graphics/DepthCheck.cpp @@ -251,7 +251,7 @@ extern void CheckDelayedDepthPoints( const CDrawPort *pdp, INDEX iMirrorLevel/*= ASSERT( pdp!=NULL && iMirrorLevel>=0); // check only if time lapse allows - const CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); + const CTimerValue tvNow = _pTimer->GetLowPrecisionTimer(); const TIME tmDelta = (tvNow-_tvLast[iMirrorLevel]).GetSeconds(); ASSERT( tmDelta>=0); if( gap_iOptimizeDepthReads==2 && tmDelta<0.1f) return; diff --git a/Sources/Engine/Graphics/DrawPort.cpp b/Sources/Engine/Graphics/DrawPort.cpp index ce03348ad..506dffdc5 100755 --- a/Sources/Engine/Graphics/DrawPort.cpp +++ b/Sources/Engine/Graphics/DrawPort.cpp @@ -462,6 +462,7 @@ void CDrawPort::DrawPoint( PIX pixI, PIX pixJ, COLOR col, PIX pixRadius/*=1*/) c if( eAPI==GAT_OGL) { const FLOAT fI = pixI+0.5f; const FLOAT fJ = pixJ+0.5f; + BYTESWAP(col); glCOLOR(col); pglPointSize(fR); pglBegin(GL_POINTS); @@ -508,6 +509,7 @@ void CDrawPort::DrawPoint3D( FLOAT3D v, COLOR col, FLOAT fRadius/*=1.0f*/) const // OpenGL if( eAPI==GAT_OGL) { + BYTESWAP(col); glCOLOR(col); pglPointSize(fRadius); pglBegin(GL_POINTS); @@ -569,6 +571,7 @@ void CDrawPort::DrawLine( PIX pixI0, PIX pixJ0, PIX pixI1, PIX pixJ1, COLOR col, if( eAPI==GAT_OGL) { const FLOAT fI0 = pixI0+0.5f; const FLOAT fJ0 = pixJ0+0.5f; const FLOAT fI1 = pixI1+0.5f; const FLOAT fJ1 = pixJ1+0.5f; + BYTESWAP(col); glCOLOR(col); pglBegin( GL_LINES); pglTexCoord2f( 0,0); pglVertex2f(fI0,fJ0); @@ -615,6 +618,7 @@ void CDrawPort::DrawLine3D( FLOAT3D v0, FLOAT3D v1, COLOR col) const col = AdjustColor( col, _slTexHueShift, _slTexSaturation); // OpenGL if( eAPI==GAT_OGL) { + BYTESWAP(col); glCOLOR(col); pglBegin( GL_LINES); pglVertex3f( v0(1),v0(2),v0(3)); @@ -680,6 +684,7 @@ void CDrawPort::DrawBorder( PIX pixI, PIX pixJ, PIX pixWidth, PIX pixHeight, COL // OpenGL if( eAPI==GAT_OGL) { + BYTESWAP(col); glCOLOR(col); pglBegin( GL_LINES); pglTexCoord2f(0,0); pglVertex2f(fI0,fJ0); pglTexCoord2f(fD,0); pglVertex2f(fI1, fJ0); // up @@ -1567,7 +1572,7 @@ void CDrawPort::AddTexture( const FLOAT fI0, const FLOAT fJ0, const FLOAT fI1, c GFXVertex *pvtx = _avtxCommon.Push(4); GFXTexCoord *ptex = _atexCommon.Push(4); GFXColor *pcol = _acolCommon.Push(4); - INDEX *pelm = _aiCommonElements.Push(6); + INDEX_T *pelm = _aiCommonElements.Push(6); pvtx[0].x = fI0; pvtx[0].y = fJ0; pvtx[0].z = 0; pvtx[1].x = fI0; pvtx[1].y = fJ1; pvtx[1].z = 0; pvtx[2].x = fI1; pvtx[2].y = fJ1; pvtx[2].z = 0; @@ -1591,7 +1596,7 @@ void CDrawPort::AddTexture( const FLOAT fI0, const FLOAT fJ0, const FLOAT fI1, c GFXVertex *pvtx = _avtxCommon.Push(4); GFXTexCoord *ptex = _atexCommon.Push(4); GFXColor *pcol = _acolCommon.Push(4); - INDEX *pelm = _aiCommonElements.Push(6); + INDEX_T *pelm = _aiCommonElements.Push(6); pvtx[0].x = fI0; pvtx[0].y = fJ0; pvtx[0].z = 0; pvtx[1].x = fI0; pvtx[1].y = fJ1; pvtx[1].z = 0; pvtx[2].x = fI1; pvtx[2].y = fJ1; pvtx[2].z = 0; @@ -1619,7 +1624,7 @@ void CDrawPort::AddTriangle( const FLOAT fI0, const FLOAT fJ0, GFXVertex *pvtx = _avtxCommon.Push(3); /* GFXTexCoord *ptex = */ _atexCommon.Push(3); GFXColor *pcol = _acolCommon.Push(3); - INDEX *pelm = _aiCommonElements.Push(3); + INDEX_T *pelm = _aiCommonElements.Push(3); pvtx[0].x = fI0; pvtx[0].y = fJ0; pvtx[0].z = 0; pvtx[1].x = fI1; pvtx[1].y = fJ1; pvtx[1].z = 0; pvtx[2].x = fI2; pvtx[2].y = fJ2; pvtx[2].z = 0; @@ -1646,7 +1651,7 @@ void CDrawPort::AddTexture( const FLOAT fI0, const FLOAT fJ0, const FLOAT fU0, c GFXVertex *pvtx = _avtxCommon.Push(4); GFXTexCoord *ptex = _atexCommon.Push(4); GFXColor *pcol = _acolCommon.Push(4); - INDEX *pelm = _aiCommonElements.Push(6); + INDEX_T *pelm = _aiCommonElements.Push(6); pvtx[0].x = fI0; pvtx[0].y = fJ0; pvtx[0].z = 0; pvtx[1].x = fI1; pvtx[1].y = fJ1; pvtx[1].z = 0; pvtx[2].x = fI2; pvtx[2].y = fJ2; pvtx[2].z = 0; diff --git a/Sources/Engine/Graphics/DrawPort_RenderScene.cpp b/Sources/Engine/Graphics/DrawPort_RenderScene.cpp old mode 100644 new mode 100755 index 18c0033cd..01718ebf1 --- a/Sources/Engine/Graphics/DrawPort_RenderScene.cpp +++ b/Sources/Engine/Graphics/DrawPort_RenderScene.cpp @@ -62,7 +62,7 @@ static GfxAPIType eAPI; static CStaticStackArray _avtxPass; static CStaticStackArray _atexPass[MAXTEXUNITS]; static CStaticStackArray _acolPass; -static CStaticStackArray _aiElements; +static CStaticStackArray _aiElements; // general coordinate stack referenced by the scene polygons CStaticStackArray _avtxScene; @@ -141,7 +141,7 @@ __forceinline void AddElements( ScenePolygon *pspo) { const INDEX ctElems = pspo->spo_ctElements; - INDEX *piDst = _aiElements.Push(ctElems); + INDEX_T *piDst = _aiElements.Push(ctElems); #if (defined __MSVC_INLINE__) __asm { diff --git a/Sources/Engine/Graphics/Fog.cpp b/Sources/Engine/Graphics/Fog.cpp index 531c84221..fbcb8b603 100644 --- a/Sources/Engine/Graphics/Fog.cpp +++ b/Sources/Engine/Graphics/Fog.cpp @@ -109,7 +109,11 @@ ULONG PrepareTexture( UBYTE *pubTexture, PIX pixSizeI, PIX pixSizeJ) DWORD* dst = (DWORD*)(pubTexture+pixTextureSize); for (int i=0; i -#endif - // control for partial usage of compiled vertex arrays BOOL CVA_b2D = FALSE; BOOL CVA_bWorld = FALSE; @@ -66,8 +61,8 @@ BOOL CVA_bModels = FALSE; CStaticStackArray _avtxCommon; CStaticStackArray _atexCommon; CStaticStackArray _acolCommon; -CStaticStackArray _aiCommonElements; -CStaticStackArray _aiCommonQuads; // predefined array for rendering quads thru triangles in glDrawElements() +CStaticStackArray _aiCommonElements; +CStaticStackArray _aiCommonQuads; // predefined array for rendering quads thru triangles in glDrawElements() // global texture parameters CTexParams _tpGlobal[GFX_MAXTEXUNITS]; @@ -795,7 +790,7 @@ extern BOOL ProbeMode( CTimerValue tvLast) } // clamp and determine probe mode if( gfx_tmProbeDecay>999) gfx_tmProbeDecay = 999; - CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); + CTimerValue tvNow = _pTimer->GetLowPrecisionTimer(); const TIME tmDelta = (tvNow-tvLast).GetSeconds(); if( tmDelta>gfx_tmProbeDecay) return TRUE; return FALSE; @@ -1718,7 +1713,7 @@ void CGfxLibrary::ReduceShadows(void) // clamp shadow caching variables shd_fCacheSize = Clamp( shd_fCacheSize, 0.1f, 128.0f); shd_tmFlushDelay = Clamp( shd_tmFlushDelay, 0.1f, 120.0f); - CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); // readout current time + CTimerValue tvNow = _pTimer->GetLowPrecisionTimer(); // readout current time const TIME tmAcientDelay = Clamp( shd_tmFlushDelay*3, 60.0f, 300.0f); // determine cached shadowmaps stats (if needed) diff --git a/Sources/Engine/Graphics/GfxLibrary.h b/Sources/Engine/Graphics/GfxLibrary.h old mode 100644 new mode 100755 index eba0a14ea..68dd19605 --- a/Sources/Engine/Graphics/GfxLibrary.h +++ b/Sources/Engine/Graphics/GfxLibrary.h @@ -33,8 +33,8 @@ with this program; if not, write to the Free Software Foundation, Inc., extern CStaticStackArray _avtxCommon; extern CStaticStackArray _atexCommon; extern CStaticStackArray _acolCommon; -extern CStaticStackArray _aiCommonElements; -extern CStaticStackArray _aiCommonQuads; +extern CStaticStackArray _aiCommonElements; +extern CStaticStackArray _aiCommonQuads; #include #include diff --git a/Sources/Engine/Graphics/Gfx_Direct3D.cpp b/Sources/Engine/Graphics/Gfx_Direct3D.cpp index 9aabf6636..835f82007 100644 --- a/Sources/Engine/Graphics/Gfx_Direct3D.cpp +++ b/Sources/Engine/Graphics/Gfx_Direct3D.cpp @@ -15,6 +15,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "Engine/StdH.h" +#ifdef SE1_D3D + #include #include #include @@ -27,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -#ifdef SE1_D3D + // asm shortcuts diff --git a/Sources/Engine/Graphics/Gfx_wrapper.cpp b/Sources/Engine/Graphics/Gfx_wrapper.cpp old mode 100644 new mode 100755 index b284d7df0..b9b37907b --- a/Sources/Engine/Graphics/Gfx_wrapper.cpp +++ b/Sources/Engine/Graphics/Gfx_wrapper.cpp @@ -126,7 +126,7 @@ void (*gfxSetVertexArray)( GFXVertex4 *pvtx, INDEX ctVtx) = NULL; void (*gfxSetNormalArray)( GFXNormal *pnor) = NULL; void (*gfxSetTexCoordArray)( GFXTexCoord *ptex, BOOL b4) = NULL; void (*gfxSetColorArray)( GFXColor *pcol) = NULL; -void (*gfxDrawElements)( INDEX ctElem, INDEX *pidx) = NULL; +void (*gfxDrawElements)( INDEX ctElem, INDEX_T *pidx) = NULL; void (*gfxSetConstantColor)(COLOR col) = NULL; void (*gfxEnableColorArray)(void) = NULL; void (*gfxDisableColorArray)(void) = NULL; @@ -555,7 +555,7 @@ extern void gfxUnlockArrays(void) void AddQuadElements( const INDEX ctQuads) { const INDEX iStart = _aiCommonQuads.Count() /6*4; - INDEX *piQuads = _aiCommonQuads.Push(ctQuads*6); + INDEX_T *piQuads = _aiCommonQuads.Push(ctQuads*6); for( INDEX i=0; igl_eCurrentAPI==GAT_OGL); #ifndef NDEBUG @@ -1136,7 +1136,7 @@ static void ogl_DrawElements( INDEX ctElem, INDEX *pidx) // arrays or elements if( pidx==NULL) pglDrawArrays( GL_QUADS, 0, ctElem); - else pglDrawElements( GL_TRIANGLES, ctElem, GL_UNSIGNED_INT, pidx); + else pglDrawElements( GL_TRIANGLES, ctElem, INDEX_GL, pidx); OGL_CHECKERROR; _sfStats.StopTimer(CStatForm::STI_GFXAPI); diff --git a/Sources/Engine/Graphics/Graphics.cpp b/Sources/Engine/Graphics/Graphics.cpp index 440c27f52..3216615ea 100644 --- a/Sources/Engine/Graphics/Graphics.cpp +++ b/Sources/Engine/Graphics/Graphics.cpp @@ -882,16 +882,17 @@ void DitherBitmap( INDEX iDitherType, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth #else union uConv { - ULONG val; + __int64 val; DWORD dwords[2]; UWORD words[4]; WORD iwords[4]; UBYTE bytes[8]; - }; + } __attribute__((packed)); //avoid optimisation and BUSERROR on Pyra build for (int i=0; i>= mmShifter; } dith.val &= mmMask; uConv* src = (uConv*)(pulSrc+i*pixWidth); diff --git a/Sources/Engine/Graphics/ImageInfo.cpp b/Sources/Engine/Graphics/ImageInfo.cpp index 84ea7ff72..95e71952a 100644 --- a/Sources/Engine/Graphics/ImageInfo.cpp +++ b/Sources/Engine/Graphics/ImageInfo.cpp @@ -372,6 +372,10 @@ STUBBED("Byte swapping TGA data"); // TGA header starts at the begining of the TGA file pTGAHdr = (struct TGAHeader*)pTGABuffer; + BYTESWAP(pTGAHdr->Width); + BYTESWAP(pTGAHdr->Height); + BYTESWAP(pTGAHdr->Xorigin); + BYTESWAP(pTGAHdr->Yorigin); // TGA image bytes definition follows up pTGAImage = pTGABuffer + sizeof(struct TGAHeader) + pTGAHdr->IdLength; @@ -475,9 +479,13 @@ void CImageInfo::SaveTGA_t( const CTFileName &strFileName) const // throw char * // set TGA picture size dimensions memset( pTGABuffer, 0x0, sizeof(struct TGAHeader)); pTGAHdr->Width = (UWORD)ii_Width; + BYTESWAP(pTGAHdr->Width); pTGAHdr->Height = (UWORD)ii_Height; + BYTESWAP(pTGAHdr->Height); pTGAHdr->BitsPerPixel = (UBYTE)ii_BitsPerPixel; pTGAHdr->ImageType = 2; + BYTESWAP(pTGAHdr->Xorigin); + BYTESWAP(pTGAHdr->Yorigin); // flip image vertically BOOL bAlphaChannel = (slBytesPerPixel==4); diff --git a/Sources/Engine/Graphics/SDL/SDLAdapter.cpp b/Sources/Engine/Graphics/SDL/SDLAdapter.cpp old mode 100644 new mode 100755 index 7f867c0cc..625044c08 --- a/Sources/Engine/Graphics/SDL/SDLAdapter.cpp +++ b/Sources/Engine/Graphics/SDL/SDLAdapter.cpp @@ -1,4 +1,5 @@ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ +#define __STDC_LIMIT_MACROS 1 #include diff --git a/Sources/Engine/Graphics/Shader.cpp b/Sources/Engine/Graphics/Shader.cpp old mode 100644 new mode 100755 index ea39eb53d..e4b08300c --- a/Sources/Engine/Graphics/Shader.cpp +++ b/Sources/Engine/Graphics/Shader.cpp @@ -45,7 +45,7 @@ static GFXTexCoord *_paHazeUVMap = NULL; // UVMap for haze pass static GFXColor *_pacolVtxHaze = NULL; // array of vertex colors for haze static CTextureObject **_paTextures = NULL;// array of textures to chose from -static INDEX *_paIndices = NULL; // current array of triangle indices +static INDEX_T *_paIndices = NULL; // current array of triangle indices static GFXColor _colAmbient = 0x000000FF; // Ambient color static COLOR _colModel = 0x000000FF; // Model color @@ -352,7 +352,7 @@ void shaSetNormalArray(GFXNormal *paNormals) } // Set array of indices -void shaSetIndices(INDEX *paIndices,INDEX ctIndices) +void shaSetIndices(INDEX_T *paIndices,INDEX ctIndices) { ASSERT(paIndices!=NULL); ASSERT(ctIndices>0); @@ -576,7 +576,7 @@ GFXVertex4 *shaGetVertexArray(void) } // Get index array -INDEX *shaGetIndexArray(void) +INDEX_T *shaGetIndexArray(void) { return _paIndices; } diff --git a/Sources/Engine/Graphics/Shader.h b/Sources/Engine/Graphics/Shader.h old mode 100644 new mode 100755 index 14c57d332..b4901e2c5 --- a/Sources/Engine/Graphics/Shader.h +++ b/Sources/Engine/Graphics/Shader.h @@ -97,7 +97,7 @@ ENGINE_API void shaSetVertexArray(GFXVertex4 *paVertices,INDEX ctVertices); // Set array of normals ENGINE_API void shaSetNormalArray(GFXNormal *paNormals); // Set array of indices -ENGINE_API void shaSetIndices(INDEX *paIndices, INDEX ctIndices); +ENGINE_API void shaSetIndices(INDEX_T *paIndices, INDEX ctIndices); // Set array of texture objects for shader ENGINE_API void shaSetTextureArray(CTextureObject **paTextureObject, INDEX ctTextures); // Set array of uv maps @@ -159,7 +159,7 @@ ENGINE_API COLOR &shaGetCurrentColor(void); // Get vertex array ENGINE_API GFXVertex4 *shaGetVertexArray(void); // Get index array -ENGINE_API INDEX *shaGetIndexArray(void); +ENGINE_API INDEX_T *shaGetIndexArray(void); // Get normal array ENGINE_API GFXNormal *shaGetNormalArray(void); // Get uvmap array from array of uvmaps diff --git a/Sources/Engine/Graphics/ShadowMap.cpp b/Sources/Engine/Graphics/ShadowMap.cpp old mode 100644 new mode 100755 index 05d168f7e..08ba57319 --- a/Sources/Engine/Graphics/ShadowMap.cpp +++ b/Sources/Engine/Graphics/ShadowMap.cpp @@ -251,7 +251,7 @@ void CShadowMap::MarkDrawn(void) ASSERT( sm_lnInGfx.IsLinked()); sm_lnInGfx.Remove(); // set time stamp - sm_tvLastDrawn = _pTimer->GetHighPrecisionTimer(); + sm_tvLastDrawn = _pTimer->GetLowPrecisionTimer(); // put at the end of the list _pGfx->gl_lhCachedShadows.AddTail(sm_lnInGfx); } diff --git a/Sources/Engine/Graphics/Texture.cpp b/Sources/Engine/Graphics/Texture.cpp index 514f252f1..909c80f01 100644 --- a/Sources/Engine/Graphics/Texture.cpp +++ b/Sources/Engine/Graphics/Texture.cpp @@ -752,8 +752,9 @@ void CTextureData::Read_t( CTStream *inFile) // alloc memory block and read mip-maps inFile->Read_t( td_pulFrames, slTexSize); #if PLATFORM_BIGENDIAN - for (SLONG i = 0; i < slTexSize/4; i++) - BYTESWAP(td_pulFrames[i]); + UWORD *uwptr = (UWORD *)td_pulFrames; + for (SLONG i = 0; i < slTexSize/2; i++) + BYTESWAP(uwptr[i]); #endif } // if current version @@ -765,10 +766,6 @@ void CTextureData::Read_t( CTStream *inFile) if( bAlphaChannel) { // read texture with alpha channel from file inFile->Read_t( pulCurrentFrame, pixFrameSizeOnDisk *4); - #if PLATFORM_BIGENDIAN - for (SLONG i = 0; i < pixFrameSizeOnDisk; i++) - BYTESWAP(pulCurrentFrame[i]); - #endif } else { // read texture without alpha channel from file inFile->Read_t( pulCurrentFrame, pixFrameSizeOnDisk *3); @@ -825,6 +822,15 @@ void CTextureData::Read_t( CTStream *inFile) ULONG ulSize = AllocEffectBuffers(this); inFile->Read_t( td_pubBuffer1, ulSize); inFile->Read_t( td_pubBuffer2, ulSize); + #if PLATFORM_BIGENDIAN + SWORD* pNew = (SWORD*)td_pubBuffer1; + SWORD* pOld = (SWORD*)td_pubBuffer2; + for (int i = 0; i < ulSize / 2; i++) + { + BYTESWAP(pNew[i]); + BYTESWAP(pOld[i]); + } + #endif } // if this is chunk containing effect data else if( idChunk == CChunkID("FXDT")) @@ -1008,10 +1014,6 @@ void CTextureData::Read_t( CTStream *inFile) // writes texutre to file void CTextureData::Write_t( CTStream *outFile) // throw char * { - #if PLATFORM_BIGENDIAN - STUBBED("Byte swapping"); - #endif - // cannot write textures that have been mangled somehow _bExport = FALSE; if( td_ptegEffect==NULL && IsModified()) throw( TRANS("Cannot write texture that has modified frames.")); @@ -1084,14 +1086,15 @@ void CTextureData::Write_t( CTStream *outFile) // throw char * { // write type of effect source *outFile << itEffectSource->tes_ulEffectSourceType; // write structure holding effect source properties - outFile->Write_t( &itEffectSource->tes_tespEffectSourceProperties, sizeof( struct TextureEffectSourceProperties)); + *outFile >> itEffectSource->tes_tespEffectSourceProperties; INDEX ctEffectSourcePixels = itEffectSource->tes_atepPixels.Count(); // write count of effect pixels *outFile << ctEffectSourcePixels; // if there are any effect pixels if( ctEffectSourcePixels>0) { // write all effect pixels in one block - outFile->Write_t( &itEffectSource->tes_atepPixels[0], sizeof(struct TextureEffectPixel)*ctEffectSourcePixels); + for (INDEX i = 0; i < ctEffectSourcePixels; i++) + *outFile >> itEffectSource->tes_atepPixels[i]; } } // if effect buffers are valid diff --git a/Sources/Engine/Graphics/Texture.h b/Sources/Engine/Graphics/Texture.h index 01daf30c3..808e416c4 100644 --- a/Sources/Engine/Graphics/Texture.h +++ b/Sources/Engine/Graphics/Texture.h @@ -97,7 +97,7 @@ class ENGINE_API CTextureData : public CAnimData { inline ULONG GetNoOfFineMips(void) const { return td_ctFineMipLevels; }; // mark that texture has been used - inline void MarkDrawn(void) { td_tvLastDrawn = _pTimer->GetHighPrecisionTimer(); }; + inline void MarkDrawn(void) { td_tvLastDrawn = _pTimer->GetLowPrecisionTimer(); }; // get string description of texture size, mips and parameters CTString GetDescription(void); diff --git a/Sources/Engine/Graphics/TextureEffects.cpp b/Sources/Engine/Graphics/TextureEffects.cpp index 8834a3b5c..d59b65cf5 100644 --- a/Sources/Engine/Graphics/TextureEffects.cpp +++ b/Sources/Engine/Graphics/TextureEffects.cpp @@ -1250,7 +1250,7 @@ static void AnimateWater( SLONG slDensity) //////////////////////////// displace texture -#define PIXEL(u,v) pulTextureBase[ ((u)&(SLONG&)mmBaseWidthMask) + ((v)&(SLONG&)mmBaseHeightMask) *pixBaseWidth] +#define PIXEL(u,v) pulTextureBase[ ((ULONG)(u)&mmBaseWidthMask) + (((ULONG)(v)&mmBaseHeightMask) *pixBaseWidth)] ULONG _slHeightMapStep_renderWater = 0; PIX _pixBaseWidth_renderWater = 0; diff --git a/Sources/Engine/Graphics/Win32/Win32Adapter.cpp b/Sources/Engine/Graphics/Win32/Win32Adapter.cpp index d2100b3fd..9a45ff750 100644 --- a/Sources/Engine/Graphics/Win32/Win32Adapter.cpp +++ b/Sources/Engine/Graphics/Win32/Win32Adapter.cpp @@ -1,5 +1,7 @@ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ +#ifdef PLATFORM_WIN32 + #include ULONG DetermineDesktopWidth(void) @@ -7,4 +9,4 @@ ULONG DetermineDesktopWidth(void) return((ULONG) ::GetSystemMetrics(SM_CXSCREEN)); } - +#endif diff --git a/Sources/Engine/Graphics/Win32/Win32OpenGL.cpp b/Sources/Engine/Graphics/Win32/Win32OpenGL.cpp index 2ecf9d3a3..eb525c930 100644 --- a/Sources/Engine/Graphics/Win32/Win32OpenGL.cpp +++ b/Sources/Engine/Graphics/Win32/Win32OpenGL.cpp @@ -1,5 +1,7 @@ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ +#ifdef PLATFORM_WIN32 + #include static void FailFunction_t(const char *strName) { @@ -438,3 +440,4 @@ BOOL CGfxLibrary::SetCurrentViewport_OGL(CViewPort *pvp) return TRUE; } +#endif // PLATFORM_WIN32 diff --git a/Sources/Engine/Light/LayerMixer.cpp b/Sources/Engine/Light/LayerMixer.cpp index 9b9992de6..67aa226b2 100755 --- a/Sources/Engine/Light/LayerMixer.cpp +++ b/Sources/Engine/Light/LayerMixer.cpp @@ -125,7 +125,8 @@ class CLayerMixer // increment a byte without overflowing it static inline void IncrementByteWithClip( UBYTE &ub, SLONG slAdd) { - ub = pubClipByte[(SLONG)ub+slAdd]; + SLONG t = (SLONG)ub+slAdd; + ub = (t<0)?0:pubClipByte[t]; } #if 0 // DG: unused. @@ -142,21 +143,48 @@ static inline void IncrementColorWithClip( UBYTE &ubR, UBYTE &ubG, UBYTE &ubB, // add the intensity to the pixel inline void CLayerMixer::AddToCluster( UBYTE *pub) { +#if PLATFORM_LITTLEENDIAN IncrementByteWithClip(pub[0], ((UBYTE*)&lm_colLight)[3]); IncrementByteWithClip(pub[1], ((UBYTE*)&lm_colLight)[2]); IncrementByteWithClip(pub[2], ((UBYTE*)&lm_colLight)[1]); +#else + IncrementByteWithClip(pub[0], ((UBYTE*)&lm_colLight)[0]); + IncrementByteWithClip(pub[1], ((UBYTE*)&lm_colLight)[1]); + IncrementByteWithClip(pub[2], ((UBYTE*)&lm_colLight)[2]); + IncrementByteWithClip(pub[3], ((UBYTE*)&lm_colLight)[3]); +#endif } inline void CLayerMixer::AddAmbientToCluster( UBYTE *pub) { +#if PLATFORM_LITTLEENDIAN IncrementByteWithClip(pub[0], ((UBYTE*)&lm_colAmbient)[3]); IncrementByteWithClip(pub[1], ((UBYTE*)&lm_colAmbient)[2]); IncrementByteWithClip(pub[2], ((UBYTE*)&lm_colAmbient)[1]); +#else + IncrementByteWithClip(pub[0], ((UBYTE*)&lm_colAmbient)[0]); + IncrementByteWithClip(pub[1], ((UBYTE*)&lm_colAmbient)[1]); + IncrementByteWithClip(pub[2], ((UBYTE*)&lm_colAmbient)[2]); + IncrementByteWithClip(pub[3], ((UBYTE*)&lm_colAmbient)[3]); +#endif } inline void CLayerMixer::AddToCluster( UBYTE *pub, SLONG slIntensity) { +#if PLATFORM_LITTLEENDIAN IncrementByteWithClip(pub[0], (long) (((UBYTE*)&lm_colLight)[3] *slIntensity)>>16); IncrementByteWithClip(pub[1], (long) (((UBYTE*)&lm_colLight)[2] *slIntensity)>>16); IncrementByteWithClip(pub[2], (long) (((UBYTE*)&lm_colLight)[1] *slIntensity)>>16); +#else + UBYTE r, g, b, a; + ColorToRGBA(lm_colLight, r, g, b, a); + + SLONG dR = ((SLONG)r * (SLONG)slIntensity) >> 16; + SLONG dG = ((SLONG)g * (SLONG)slIntensity) >> 16; + SLONG dB = ((SLONG)b * (SLONG)slIntensity) >> 16; + + IncrementByteWithClip(pub[0], dR); + IncrementByteWithClip(pub[1], dG); + IncrementByteWithClip(pub[2], dB); +#endif } @@ -867,7 +895,7 @@ void CLayerMixer::AddDiffusionPoint(void) sl1oL = auw1oSqrt[sl1oL]; SLONG slIntensity = _slLightMax; if( sl1oL<256) slIntensity = 0; - else if( sl1oL>16*/; + else if( sl1oL>16*/; + else if( sl1oLlm_pixCanvasSizeU * this->lm_pixCanvasSizeV; + ULONG count = this->lm_pixCanvasSizeU * this->lm_pixCanvasSizeV; #if PLATFORM_LITTLEENDIAN // Forces C fallback; BYTESWAP itself is a no-op on little endian. - register ULONG swapped = BYTESWAP32_unsigned(colAmbient); + ULONG swapped = BYTESWAP32_unsigned(colAmbient); #else - STUBBED("actually need byteswap?"); - // (uses inline asm on MacOS PowerPC) - register ULONG swapped = colAmbient; - BYTESWAP(swapped); + ULONG swapped = colAmbient; #endif for (ULONG *ptr = this->lm_pulShadowMap; count; count--) @@ -1963,7 +1994,11 @@ __forceinline void CLayerMixer::FillShadowLayer( COLOR col) #else DWORD* dst = (DWORD*)lm_pulShadowMap; int n = lm_pixCanvasSizeU*lm_pixCanvasSizeV; +#if PLATFORM_LITTLEENDIAN DWORD color = BYTESWAP32_unsigned(col); +#else + DWORD color = col; +#endif while(n--) {*(dst++)=color;} #endif } @@ -2001,9 +2036,8 @@ void CLayerMixer::MixOneMipmapDynamic( CBrushShadowMap *pbsm, INDEX iMipmap) // constructor -CLayerMixer::CLayerMixer( CBrushShadowMap *pbsm, INDEX iFirstMip, INDEX iLastMip, BOOL bDynamic) +CLayerMixer::CLayerMixer( CBrushShadowMap *pbsm, INDEX iFirstMip, INDEX iLastMip, BOOL bDynamic): lm_bDynamic(bDynamic) { - lm_bDynamic = bDynamic; if( bDynamic) { // check dynamic layers for complete blackness BOOL bAllBlack = TRUE; diff --git a/Sources/Engine/Light/LightSource.cpp b/Sources/Engine/Light/LightSource.cpp old mode 100644 new mode 100755 index 24188acf5..2e7d6bf0a --- a/Sources/Engine/Light/LightSource.cpp +++ b/Sources/Engine/Light/LightSource.cpp @@ -417,7 +417,7 @@ void CLightSource::FindShadowLayersPoint(BOOL bSelectedOnly) } // for each layer of the light source - DOUBLE3D dvOrigin = FLOATtoDOUBLE(*_pvOrigin); + FLOAT3D dvOrigin = *_pvOrigin; {FORDELETELIST(CBrushShadowLayer, bsl_lnInLightSource, ls_lhLayers, itbsl) { CBrushPolygon *pbpo = itbsl->bsl_pbsmShadowMap->GetBrushPolygon(); CEntity *penWithPolygon = pbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity; @@ -490,7 +490,7 @@ void CLightSource::FindShadowLayersPoint(BOOL bSelectedOnly) if (!itbsc->bsc_boxBoundingBox.HasContactWith(_boxLight) ||(itbsc->bsc_bspBSPTree.bt_pbnRoot!=NULL &&!(itbsc->bsc_bspBSPTree.TestSphere( - dvOrigin, FLOATtoDOUBLE(_rRange))>=0) )) { + dvOrigin, _rRange)>=0) )) { // skip it continue; } diff --git a/Sources/Engine/Math/AABBox.h b/Sources/Engine/Math/AABBox.h old mode 100644 new mode 100755 index bac1a9448..bacc29f14 --- a/Sources/Engine/Math/AABBox.h +++ b/Sources/Engine/Math/AABBox.h @@ -400,6 +400,53 @@ inline FLOATaabbox3D DOUBLEtoFLOAT(const DOUBLEaabbox3D &pld) { return FLOATaabbox3D( DOUBLEtoFLOAT(pld.Min()), DOUBLEtoFLOAT(pld.Max())); } +/* Specialized copy for FLOATaabb3D */ + +/* Check if intersects or touches another bounding box. */ +template<> +inline BOOL AABBox::HasContactWith(const AABBox &b) const +{ + // if spans in any dimension don't have contact + if (maxvect(1)b.maxvect(1) + || maxvect(2)b.maxvect(2) + || maxvect(3)b.maxvect(3) + ) { + // whole bounding boxes don't have contact + return FALSE; + } + return TRUE; +} +/* Check if intersects or touches another bounding box. */ +template<> +inline BOOL AABBox::HasContactWith(const AABBox &b, FLOAT tEpsilon) const +{ + // if spans in any dimension don't have contact + if( (maxvect(1)+tEpsilonb.maxvect(1)) + || (maxvect(2)+tEpsilonb.maxvect(2)) + || (maxvect(3)+tEpsilonb.maxvect(3)) + ) { + // whole bounding boxes don't have contact + return FALSE; + } + return TRUE; +} +/* Check if intersects or touches a sphere. */ +template<> +inline BOOL AABBox::TouchesSphere( + const Vector &vSphereCenter, FLOAT fSphereRadius) const +{ + // if spans in any dimension don't have contact + if( (vSphereCenter(1)+fSphereRadiusmaxvect(1)) + || (vSphereCenter(2)+fSphereRadiusmaxvect(2)) + || (vSphereCenter(3)+fSphereRadiusmaxvect(3)) + ) { + // no contact + return FALSE; + } + return TRUE; +} + + #endif /* include-once check. */ diff --git a/Sources/Engine/Math/Clipping.inl b/Sources/Engine/Math/Clipping.inl old mode 100644 new mode 100755 diff --git a/Sources/Engine/Math/Functions.cpp b/Sources/Engine/Math/Functions.cpp index 6fa0c9e33..9618707ad 100644 --- a/Sources/Engine/Math/Functions.cpp +++ b/Sources/Engine/Math/Functions.cpp @@ -69,7 +69,7 @@ double adCosQuadrants[4][2] = {1.0, -90.0}, {1.0, 0.0}, }; - +/* FLOAT Sin(ANGLE a) { double aWrapped = WrapAngle(a); @@ -92,3 +92,4 @@ FLOAT Tan(ANGLE a) { return Sin(a)/Cos(a); } +*/ diff --git a/Sources/Engine/Math/Functions.h b/Sources/Engine/Math/Functions.h index 1108e7100..cac7defb3 100755 --- a/Sources/Engine/Math/Functions.h +++ b/Sources/Engine/Math/Functions.h @@ -445,7 +445,7 @@ printf("CHECK THIS: %s:%d\n", __FILE__, __LINE__); // square root (works with negative numbers) -#ifdef __arm__ +#if !defined(__i386__) && !defined(__x86_64__) inline FLOAT Sqrt( FLOAT x) { return sqrtf( ClampDn( x, 0.0f)); } #else inline FLOAT Sqrt( FLOAT x) { return (FLOAT)sqrt( ClampDn( x, 0.0f)); } @@ -495,11 +495,17 @@ inline FLOAT RadAngle(ANGLE aAngle) { return FLOAT (WrapAngle(aAngle)*PI/ANGLE_180); } -ENGINE_API FLOAT Sin(ANGLE a); -ENGINE_API FLOAT Cos(ANGLE a); -ENGINE_API FLOAT Tan(ANGLE a); +#if !defined(__i386__) && !defined(__x86_64__) +inline ENGINE_API FLOAT Sin(ANGLE a) { return sinf(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT Cos(ANGLE a) { return cosf(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT Tan(ANGLE a) { return tanf(a*(PI/ANGLE_180)); }; +#else +inline ENGINE_API FLOAT Sin(ANGLE a) { return sin(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT Cos(ANGLE a) { return cos(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT Tan(ANGLE a) { return tan(a*(PI/ANGLE_180)); }; +#endif -#ifdef __arm__ +#if !defined(__i386__) && !defined(__x86_64__) inline ENGINE_API FLOAT SinFast(ANGLE a) { return sinf(a*(PI/ANGLE_180)); }; inline ENGINE_API FLOAT CosFast(ANGLE a) { return cosf(a*(PI/ANGLE_180)); }; inline ENGINE_API FLOAT TanFast(ANGLE a) { return tanf(a*(PI/ANGLE_180)); }; diff --git a/Sources/Engine/Math/Matrix.h b/Sources/Engine/Math/Matrix.h old mode 100644 new mode 100755 index a4167b49f..841d0d2e4 --- a/Sources/Engine/Math/Matrix.h +++ b/Sources/Engine/Math/Matrix.h @@ -68,11 +68,38 @@ class Matrix { friend __forceinline CTStream &operator>>(CTStream &strm, Matrix &matrix) { strm.Read_t(&matrix, sizeof(matrix)); + #if PLATFORM_BIGENDIAN + for (int i = 0; i < iRows; i++) + { + for (int j = 0; j < iColumns; j++) + { + BYTESWAP(matrix.matrix[i][j]); + } + } + #endif return strm; } friend __forceinline CTStream &operator<<(CTStream &strm, Matrix &matrix) { + #if PLATFORM_BIGENDIAN + for (int i = 0; i < iRows; i++) + { + for (int j = 0; j < iColumns; j++) + { + BYTESWAP(matrix.matrix[i][j]); + } + } + #endif strm.Write_t(&matrix, sizeof(matrix)); + #if PLATFORM_BIGENDIAN + for (int i = 0; i < iRows; i++) + { + for (int j = 0; j < iColumns; j++) + { + BYTESWAP(matrix.matrix[i][j]); + } + } + #endif return strm; } }; diff --git a/Sources/Engine/Math/Object3D_CSG.cpp b/Sources/Engine/Math/Object3D_CSG.cpp index 98bc4a342..26e70c781 100644 --- a/Sources/Engine/Math/Object3D_CSG.cpp +++ b/Sources/Engine/Math/Object3D_CSG.cpp @@ -195,9 +195,7 @@ class CObjectCSG { // array for holding edges that proceed with testing CDynamicArray oc_abedProceeding; - CObjectCSG(void) { - oc_bCSGIngoringEnabled = FALSE; - oc_bSkipObjectB = FALSE; + CObjectCSG(void): oc_bCSGIngoringEnabled(FALSE), oc_bSkipObjectB(FALSE){ } /* Add an entire array of BSP edges to some polygon according to action code. */ diff --git a/Sources/Engine/Math/Quaternion.h b/Sources/Engine/Math/Quaternion.h index 19dbae58e..1bfc6bde8 100755 --- a/Sources/Engine/Math/Quaternion.h +++ b/Sources/Engine/Math/Quaternion.h @@ -370,7 +370,7 @@ void Quaternion::FromEuler(const Vector &a) template Type Quaternion::EPS(Type orig) const { -#ifdef PLATFORM_PANDORA +#if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) if ((orig <= 1e-4f) && (orig >= -1e-4f)) #else if ((orig <= 10e-6f) && (orig >= -10e-6f)) @@ -388,9 +388,9 @@ void Quaternion::ToMatrix(Matrix &m) const Type yy = 2*q_y*q_y; Type yz = 2*q_y*q_z; Type zz = 2*q_z*q_z; Type wx = 2*q_w*q_x; Type wy = 2*q_w*q_y; Type wz = 2*q_w*q_z; - m(1,1) = EPS(1.0f-(yy+zz));m(1,2) = EPS(xy-wz); m(1,3) = EPS(xz+wy); - m(2,1) = EPS(xy+wz); m(2,2) = EPS(1.0f-(xx+zz));m(2,3) = EPS(yz-wx); - m(3,1) = EPS(xz-wy); m(3,2) = EPS(yz+wx); m(3,3) = EPS(1.0f-(xx+yy)); + m(1,1) = 1.0f-EPS(yy+zz); m(1,2) = EPS(xy-wz); m(1,3) = EPS(xz+wy); + m(2,1) = EPS(xy+wz); m(2,2) = 1.0f-EPS(xx+zz); m(2,3) = EPS(yz-wx); + m(3,1) = EPS(xz-wy); m(3,2) = EPS(yz+wx); m(3,3) = 1.0f-EPS(xx+yy); } // conversion from matrix diff --git a/Sources/Engine/Models/Model.cpp b/Sources/Engine/Models/Model.cpp index e3847d20c..80c9fd7e1 100644 --- a/Sources/Engine/Models/Model.cpp +++ b/Sources/Engine/Models/Model.cpp @@ -1178,10 +1178,6 @@ void CModelData::Write_t( CTStream *pFile) // throw char * // Save flags (*pFile) << md_Flags; - #if PLATFORM_BIGENDIAN - STUBBED("byte order"); - #endif - // Save vertices and frames ct pFile->WriteFullChunk_t( CChunkID("IVTX"), &md_VerticesCt, sizeof(INDEX)); pFile->WriteFullChunk_t( CChunkID("IFRM"), &md_FramesCt, sizeof(INDEX)); @@ -1689,6 +1685,7 @@ void CModelData::Read_t( CTStream *pFile) // throw char * // Read color names (Read count, read existing names) INDEX iValidColorsCt; pFile->ReadFullChunk_t( CChunkID("ICLN"), &iValidColorsCt, sizeof(INDEX)); + BYTESWAP(iValidColorsCt); for( i=0; iWriteID_t( CChunkID( "MODT")); *pFile << mo_colBlendColor; - pFile->Write_t( &mo_PatchMask, sizeof(ULONG)); - pFile->Write_t( &mo_Stretch, sizeof(FLOAT3D)); - pFile->Write_t( &mo_ColorMask, sizeof(ULONG)); + *pFile << mo_PatchMask; + *pFile << mo_Stretch; + *pFile << mo_ColorMask; } //------------------------------------------ READ void CModelObject::Read_t( CTStream *pFile) // throw char * diff --git a/Sources/Engine/Models/ModelData.h b/Sources/Engine/Models/ModelData.h old mode 100644 new mode 100755 index 41aa6c284..858281be7 --- a/Sources/Engine/Models/ModelData.h +++ b/Sources/Engine/Models/ModelData.h @@ -67,7 +67,7 @@ struct ENGINE_API ModelMipInfo CStaticArray mmpi_avBumpV; // bump directions for each surface vertex ULONG mmpi_ulLayerFlags; // all texture layers needed in this mip INDEX mmpi_ctTriangles; // total triangles in this mip - CStaticStackArray mmpi_aiElements; + CStaticStackArray mmpi_aiElements; void Clear(); // clears this mip model's arays and their sub-arrays, dealocates memory void Read_t( CTStream *istrFile, BOOL bReadPolygonalPatches, BOOL bReadPolygonsPerSurface, diff --git a/Sources/Engine/Models/RenderModel_View.cpp b/Sources/Engine/Models/RenderModel_View.cpp old mode 100644 new mode 100755 index e5cf4ce6b..35fba1351 --- a/Sources/Engine/Models/RenderModel_View.cpp +++ b/Sources/Engine/Models/RenderModel_View.cpp @@ -332,7 +332,7 @@ static void PrepareSurfaceElements( ModelMipInfo &mmi, MappingSurface &ms) // create elements ms.ms_ctSrfEl = ctTriangles*3; - INDEX *paiElements = mmi.mmpi_aiElements.Push(ms.ms_ctSrfEl); + INDEX_T *paiElements = mmi.mmpi_aiElements.Push(ms.ms_ctSrfEl); // dump all triangles //_RPT0(_CRT_WARN, "Result:\n"); INDEX iel = 0; @@ -587,7 +587,7 @@ static void SetCol(void) _icol = (_icol+1)%_ctcol; } -static void DrawStrips( const INDEX ct, const INDEX *pai) +static void DrawStrips( const INDEX ct, const INDEX_T *pai) { // set strip color pglDisableClientState( GL_COLOR_ARRAY); @@ -603,9 +603,9 @@ static void DrawStrips( const INDEX ct, const INDEX *pai) while( i0); // choose rendering mode @@ -2106,6 +2106,37 @@ void CModelObject::RenderModel_View( CRenderModel &rm) vtxEnd: pop ebx } +#elif defined(__ARM_NEON__) && !defined (PLATFORM_MACOSX) + register float tc_u __asm__("s0") = fTexCorrU; + register float tc_v __asm__("s1") = fTexCorrV; + const void *tc_src = pvTexCoord->vector; + GFXTexCoord *tc_dst = ptexSrfBase; + int tc_cnt = ctSrfVx; + __asm__ __volatile__ ( + "vmov d1, d0\n" + "0:\n" + "subs %[c], #2\n" + "blt 1f\n" + "vld1.32 {d2}, [%[src]]\n" + "add %[src], %[src_s]\n" + "vld1.32 {d3}, [%[src]]\n" + "add %[src], %[src_s]\n" + "vmul.f32 q1, q1, q0\n" + "pld [%[src], #64]\n" + "vst1.32 {q1}, [%[dst]]!\n" + "b 0b\n" + "1:\n" + "tst %[c], #1\n" + "beq 2f\n" + "vld1.32 {d2}, [%[src]]\n" + "vmul.f32 d2, d2, d0\n" + "vst1.32 {d2}, [%[dst]]\n" + "2:\n" + : [c] "=&r"(tc_cnt), [src] "=&r"(tc_src), [dst] "=&r"(tc_dst) + : "[c]"(tc_cnt), "[src]"(tc_src), "[dst]"(tc_dst), + "t"(tc_u), "t"(tc_v), [src_s] "I"(sizeof(pvTexCoord[0])) + : "d1", "q1", "cc", "memory" + ); #else // setup texcoord array for( INDEX iSrfVx=0; iSrfVxpa_ulSequence,FALSE); - if (ppaPacket->pa_ulSequence == 8) { - ppaPacket->pa_ulSequence = 8; - } // a packet can be accepted from the broadcast ID only if it is an acknowledge packet or // if it is a connection confirmation response packet and the client isn't already connected if (ppaPacket->pa_adrAddress.adr_uwID == SLASHSLASH || ppaPacket->pa_adrAddress.adr_uwID == 0) { diff --git a/Sources/Engine/Network/Compression.cpp b/Sources/Engine/Network/Compression.cpp index fe788a30e..509744cbc 100644 --- a/Sources/Engine/Network/Compression.cpp +++ b/Sources/Engine/Network/Compression.cpp @@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include +#include extern CTCriticalSection zip_csLock; // critical section for access to zlib functions diff --git a/Sources/Engine/Network/EMsgBuffer.h b/Sources/Engine/Network/EMsgBuffer.h index 1c33c90a5..e95796242 100644 --- a/Sources/Engine/Network/EMsgBuffer.h +++ b/Sources/Engine/Network/EMsgBuffer.h @@ -81,12 +81,7 @@ struct TickMarker { UBYTE tm_ubAcknowledgesExpected; UWORD tm_uwNumMessages; - TickMarker() { - tm_fTickTime = -1; - tm_slTickOffset = -1; - tm_ubAcknowledgesExpected = 0; - tm_uwNumMessages = 0; - } + TickMarker(): tm_fTickTime(-1), tm_fTickTime(-1), tm_ubAcknowledgesExpected(0), tm_uwNumMessages (0){} }; diff --git a/Sources/Engine/Network/EntityHashing.h b/Sources/Engine/Network/EntityHashing.h index f51585121..73d34df47 100644 --- a/Sources/Engine/Network/EntityHashing.h +++ b/Sources/Engine/Network/EntityHashing.h @@ -47,7 +47,7 @@ class CEntityHashItem { CEntityPointer ehi_epEntityPointer; CClientEntry ehi_ceClientEntries[SERVER_CLIENTS]; - CEntityHashItem() {ehi_ulEntityID = -1;} // entity pointer will initialize itself to NULL + CEntityHashItem(): ehi_ulEntityID(-1){} // entity pointer will initialize itself to NULL ~CEntityItem() {}; // entity poiner will destroy itself and remove the reference diff --git a/Sources/Engine/Network/Network.cpp b/Sources/Engine/Network/Network.cpp index d283a1a30..a5c25ba9f 100644 --- a/Sources/Engine/Network/Network.cpp +++ b/Sources/Engine/Network/Network.cpp @@ -185,9 +185,7 @@ class CGatherCRC { ~CGatherCRC(); }; -CGatherCRC::CGatherCRC() { - bOld = CRCT_bGatherCRCs; -} +CGatherCRC::CGatherCRC(): bOld(CRCT_bGatherCRCs){} CGatherCRC::~CGatherCRC() { CRCT_bGatherCRCs = bOld; } diff --git a/Sources/Engine/Network/NetworkMessage.cpp b/Sources/Engine/Network/NetworkMessage.cpp index 1c8df0829..b6bf0b872 100644 --- a/Sources/Engine/Network/NetworkMessage.cpp +++ b/Sources/Engine/Network/NetworkMessage.cpp @@ -915,7 +915,13 @@ CNetworkMessage &operator<<(CNetworkMessage &nm, const CPlayerAction &pa) } else { UBYTE ub=1; nm.WriteBits(&ub, 1); +#if PLATFORM_BIGENDIAN + ULONG tmp = *pul; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 32); +#else nm.WriteBits(pul, 32); +#endif } pul++; } @@ -933,27 +939,57 @@ CNetworkMessage &operator<<(CNetworkMessage &nm, const CPlayerAction &pa) } else if (ulFlags <= 3) { UBYTE ub=4; nm.WriteBits(&ub, 3); +#if PLATFORM_BIGENDIAN + ULONG tmp = ulFlags; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 1); +#else nm.WriteBits(&ulFlags, 1); +#endif // (4-15) 0001 = 4 bit value follows } else if (ulFlags <= 15) { UBYTE ub=8; nm.WriteBits(&ub, 4); +#if PLATFORM_BIGENDIAN + ULONG tmp = ulFlags; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 4); +#else nm.WriteBits(&ulFlags, 4); +#endif // (16-255) 00001 = 8 bit value follows } else if (ulFlags <= 255) { UBYTE ub=16; nm.WriteBits(&ub, 5); +#if PLATFORM_BIGENDIAN + ULONG tmp = ulFlags; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 8); +#else nm.WriteBits(&ulFlags, 8); +#endif // (256-65535) 000001 = 16 bit value follows } else if (ulFlags <= 65535) { UBYTE ub=32; nm.WriteBits(&ub, 6); +#if PLATFORM_BIGENDIAN + ULONG tmp = ulFlags; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 16); +#else nm.WriteBits(&ulFlags, 16); +#endif // (65536-) 000000 = 32 bit value follows } else { UBYTE ub=0; nm.WriteBits(&ub, 6); +#if PLATFORM_BIGENDIAN + ULONG tmp = ulFlags; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 32); +#else nm.WriteBits(&ulFlags, 32); +#endif } return nm; } @@ -970,6 +1006,7 @@ CNetworkMessage &operator>>(CNetworkMessage &nm, CPlayerAction &pa) *pul = 0; } else { nm.ReadBits(pul, 32); + BYTESWAP(*pul); } pul++; } @@ -995,23 +1032,28 @@ CNetworkMessage &operator>>(CNetworkMessage &nm, CPlayerAction &pa) } else if (iZeros==2) { ulFlags = 0; nm.ReadBits(&ulFlags, 1); + BYTESWAP(ulFlags); ulFlags |= 2; // (4-15) 0001 = 4 bit value follows } else if (iZeros==3) { ulFlags = 0; nm.ReadBits(&ulFlags, 4); + BYTESWAP(ulFlags); // (16-255) 00001 = 8 bit value follows } else if (iZeros==4) { ulFlags = 0; nm.ReadBits(&ulFlags, 8); // (256-65535) 000001 = 16 bit value follows + BYTESWAP(ulFlags); } else if (iZeros==5) { ulFlags = 0; nm.ReadBits(&ulFlags, 16); + BYTESWAP(ulFlags); // (65536-) 000000 = 32 bit value follows } else { ulFlags = 0; nm.ReadBits(&ulFlags, 32); + BYTESWAP(ulFlags); } pa.pa_ulButtons = ulFlags; return nm; diff --git a/Sources/Engine/Network/NetworkMessage.h b/Sources/Engine/Network/NetworkMessage.h index 800e66277..064ee78be 100644 --- a/Sources/Engine/Network/NetworkMessage.h +++ b/Sources/Engine/Network/NetworkMessage.h @@ -160,23 +160,24 @@ class ENGINE_API CNetworkMessage { void WriteBits(const void *pvBuffer, INDEX ctBits); /* Read an object from message. */ - inline CNetworkMessage &operator>>(float &f) { Read( &f, sizeof( f)); return *this; } - inline CNetworkMessage &operator>>(ULONG &ul) { Read(&ul, sizeof(ul)); return *this; } - inline CNetworkMessage &operator>>(UWORD &uw) { Read(&uw, sizeof(uw)); return *this; } + inline CNetworkMessage &operator>>(float &f) { Read( &f, sizeof( f)); BYTESWAP(f); return *this; } + inline CNetworkMessage &operator>>(double &d) { Read( &d, sizeof( d)); BYTESWAP(d); return *this; } + inline CNetworkMessage &operator>>(ULONG &ul) { Read(&ul, sizeof(ul)); BYTESWAP(ul); return *this; } + inline CNetworkMessage &operator>>(UWORD &uw) { Read(&uw, sizeof(uw)); BYTESWAP(uw); return *this; } inline CNetworkMessage &operator>>(UBYTE &ub) { Read(&ub, sizeof(ub)); return *this; } - inline CNetworkMessage &operator>>(SLONG &sl) { Read(&sl, sizeof(sl)); return *this; } - inline CNetworkMessage &operator>>(SWORD &sw) { Read(&sw, sizeof(sw)); return *this; } + inline CNetworkMessage &operator>>(SLONG &sl) { Read(&sl, sizeof(sl)); BYTESWAP(sl); return *this; } + inline CNetworkMessage &operator>>(SWORD &sw) { Read(&sw, sizeof(sw)); BYTESWAP(sw); return *this; } inline CNetworkMessage &operator>>(SBYTE &sb) { Read(&sb, sizeof(sb)); return *this; } inline CNetworkMessage &operator>>(MESSAGETYPE &mt) { Read(&mt, sizeof(mt)); return *this; } CNetworkMessage &operator>>(CTString &str); /* Write an object into message. */ - inline CNetworkMessage &operator<<(const float &f) { Write( &f, sizeof( f)); return *this; } - inline CNetworkMessage &operator<<(const double &d) { Write( &d, sizeof( d)); return *this; } - inline CNetworkMessage &operator<<(const ULONG &ul) { Write(&ul, sizeof(ul)); return *this; } - inline CNetworkMessage &operator<<(const UWORD &uw) { Write(&uw, sizeof(uw)); return *this; } + inline CNetworkMessage &operator<<(const float &f) { float zf = f; BYTESWAP( zf); Write( &zf, sizeof( zf)); return *this; } + inline CNetworkMessage &operator<<(const double &d) { double zd = d; BYTESWAP( zd); Write( &zd, sizeof( zd)); return *this; } + inline CNetworkMessage &operator<<(const ULONG &ul) { ULONG zul = ul; BYTESWAP(zul); Write(&zul, sizeof(zul)); return *this; } + inline CNetworkMessage &operator<<(const UWORD &uw) { UWORD zuw = uw; BYTESWAP(zuw); Write(&zuw, sizeof(zuw)); return *this; } inline CNetworkMessage &operator<<(const UBYTE &ub) { Write(&ub, sizeof(ub)); return *this; } - inline CNetworkMessage &operator<<(const SLONG &sl) { Write(&sl, sizeof(sl)); return *this; } - inline CNetworkMessage &operator<<(const SWORD &sw) { Write(&sw, sizeof(sw)); return *this; } + inline CNetworkMessage &operator<<(const SLONG &sl) { SLONG zsl = sl; BYTESWAP(zsl); Write(&zsl, sizeof(zsl)); return *this; } + inline CNetworkMessage &operator<<(const SWORD &sw) { SWORD zsw = sw; BYTESWAP(zsw); Write(&zsw, sizeof(zsw)); return *this; } inline CNetworkMessage &operator<<(const SBYTE &sb) { Write(&sb, sizeof(sb)); return *this; } inline CNetworkMessage &operator<<(const MESSAGETYPE &mt) { Write(&mt, sizeof(mt)); return *this; } CNetworkMessage &operator<<(const CTString &str); diff --git a/Sources/Engine/Network/PlayerBuffer.cpp b/Sources/Engine/Network/PlayerBuffer.cpp index 622101cf6..c177be9c9 100644 --- a/Sources/Engine/Network/PlayerBuffer.cpp +++ b/Sources/Engine/Network/PlayerBuffer.cpp @@ -71,6 +71,7 @@ void CPlayerBuffer::ReceiveActionPacket(CNetworkMessage *pnm, INDEX iMaxBuffer) // read sendbehind INDEX iSendBehind = 0; pnm->ReadBits(&iSendBehind, 2); + BYTESWAP(iSendBehind); // foreach resent action for(INDEX i=0; iGetRealTimeTick(), SLONG(pls_paAction.pa_llCreated)); @@ -217,7 +229,13 @@ void CPlayerSource::WriteActionPacket(CNetworkMessage &nm) } // save sendbehind if needed +#if PLATFORM_BIGENDIAN + tmp = iSendBehind; + BYTESWAP(tmp); + nm.WriteBits(&tmp, 2); +#else nm.WriteBits(&iSendBehind, 2); +#endif for(INDEX i=0; iSendToClient(iClient, nmPings); @@ -1354,11 +1369,13 @@ void CServer::Handle(INDEX iClient, CNetworkMessage &nmMessage) // see if saved in the message BOOL bSaved = 0; nmMessage.ReadBits(&bSaved, 1); + BYTESWAP(bSaved); // if saved if (bSaved) { // read client index INDEX iPlayer = 0; nmMessage.ReadBits(&iPlayer, 4); + BYTESWAP(iPlayer); CPlayerBuffer &plb = srv_aplbPlayers[iPlayer]; // if the player is not on that client if (plb.plb_iClient!=iClient) { @@ -1369,6 +1386,7 @@ void CServer::Handle(INDEX iClient, CNetworkMessage &nmMessage) // read ping plb.plb_iPing = 0; nmMessage.ReadBits(&plb.plb_iPing, 10); + BYTESWAP(plb.plb_iPing); // let the corresponding client buffer receive the message INDEX iMaxBuffer = sso.sso_sspParams.ssp_iBufferActions; extern INDEX cli_bPredictIfServer; diff --git a/Sources/Engine/Network/SessionState.cpp b/Sources/Engine/Network/SessionState.cpp index cdc3b9e41..54a1cb534 100644 --- a/Sources/Engine/Network/SessionState.cpp +++ b/Sources/Engine/Network/SessionState.cpp @@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #define SESSIONSTATEVERSION_OLD 1 #define SESSIONSTATEVERSION_WITHBULLETTIME 2 @@ -1614,6 +1615,46 @@ void CSessionState::Read_t(CTStream *pstr) // throw char * // read session properties from stream (*pstr)>>_pNetwork->ga_strSessionName; pstr->Read_t(_pNetwork->ga_aubProperties, NET_MAXSESSIONPROPERTIES); + CSessionProperties* psp = (CSessionProperties*)_pNetwork->ga_aubProperties; + BYTESWAP(psp->sp_ctMaxPlayers); + BYTESWAP(psp->sp_bWaitAllPlayers); + BYTESWAP(psp->sp_bQuickTest); + BYTESWAP(psp->sp_bCooperative); + BYTESWAP(psp->sp_bSinglePlayer); + BYTESWAP(psp->sp_bUseFrags); + BYTESWAP((INDEX&)psp->sp_gmGameMode); + BYTESWAP((INDEX&)psp->sp_gdGameDifficulty); + BYTESWAP(psp->sp_ulSpawnFlags); + BYTESWAP(psp->sp_bMental); + BYTESWAP(psp->sp_iScoreLimit); + BYTESWAP(psp->sp_iFragLimit); + BYTESWAP(psp->sp_iTimeLimit); + BYTESWAP(psp->sp_bTeamPlay); + BYTESWAP(psp->sp_bFriendlyFire); + BYTESWAP(psp->sp_bWeaponsStay); + BYTESWAP(psp->sp_bAmmoStays); + BYTESWAP(psp->sp_bHealthArmorStays); + BYTESWAP(psp->sp_bPlayEntireGame); + BYTESWAP(psp->sp_bAllowHealth); + BYTESWAP(psp->sp_bAllowArmor); + BYTESWAP(psp->sp_bInfiniteAmmo); + BYTESWAP(psp->sp_bRespawnInPlace); + BYTESWAP(psp->sp_fEnemyMovementSpeed); + BYTESWAP(psp->sp_fEnemyAttackSpeed); + BYTESWAP(psp->sp_fDamageStrength); + BYTESWAP(psp->sp_fAmmoQuantity); + BYTESWAP(psp->sp_fManaTransferFactor); + BYTESWAP(psp->sp_iInitialMana); + BYTESWAP(psp->sp_fExtraEnemyStrength); + BYTESWAP(psp->sp_fExtraEnemyStrengthPerPlayer); + BYTESWAP(psp->sp_ctCredits); + BYTESWAP(psp->sp_ctCreditsLeft); + BYTESWAP(psp->sp_tmSpawnInvulnerability); + BYTESWAP(psp->sp_iBlood); + BYTESWAP(psp->sp_bGibs); + BYTESWAP(psp->sp_bEndOfGame); + BYTESWAP(psp->sp_ulLevelsMask); + BYTESWAP(psp->sp_bUseExtraEnemies); // read world and its state ReadWorldAndState_t(pstr); @@ -1764,7 +1805,48 @@ void CSessionState::Write_t(CTStream *pstr) // throw char * (*pstr)<ga_strSessionName; - pstr->Write_t(_pNetwork->ga_aubProperties, NET_MAXSESSIONPROPERTIES); + CUniversalSessionProperties sp; + memcpy(&sp, _pNetwork->ga_aubProperties, NET_MAXSESSIONPROPERTIES); + BYTESWAP(sp.usp_sp.sp_ctMaxPlayers); + BYTESWAP(sp.usp_sp.sp_bWaitAllPlayers); + BYTESWAP(sp.usp_sp.sp_bQuickTest); + BYTESWAP(sp.usp_sp.sp_bCooperative); + BYTESWAP(sp.usp_sp.sp_bSinglePlayer); + BYTESWAP(sp.usp_sp.sp_bUseFrags); + BYTESWAP((INDEX&)sp.usp_sp.sp_gmGameMode); + BYTESWAP((INDEX&)sp.usp_sp.sp_gdGameDifficulty); + BYTESWAP(sp.usp_sp.sp_ulSpawnFlags); + BYTESWAP(sp.usp_sp.sp_bMental); + BYTESWAP(sp.usp_sp.sp_iScoreLimit); + BYTESWAP(sp.usp_sp.sp_iFragLimit); + BYTESWAP(sp.usp_sp.sp_iTimeLimit); + BYTESWAP(sp.usp_sp.sp_bTeamPlay); + BYTESWAP(sp.usp_sp.sp_bFriendlyFire); + BYTESWAP(sp.usp_sp.sp_bWeaponsStay); + BYTESWAP(sp.usp_sp.sp_bAmmoStays); + BYTESWAP(sp.usp_sp.sp_bHealthArmorStays); + BYTESWAP(sp.usp_sp.sp_bPlayEntireGame); + BYTESWAP(sp.usp_sp.sp_bAllowHealth); + BYTESWAP(sp.usp_sp.sp_bAllowArmor); + BYTESWAP(sp.usp_sp.sp_bInfiniteAmmo); + BYTESWAP(sp.usp_sp.sp_bRespawnInPlace); + BYTESWAP(sp.usp_sp.sp_fEnemyMovementSpeed); + BYTESWAP(sp.usp_sp.sp_fEnemyAttackSpeed); + BYTESWAP(sp.usp_sp.sp_fDamageStrength); + BYTESWAP(sp.usp_sp.sp_fAmmoQuantity); + BYTESWAP(sp.usp_sp.sp_fManaTransferFactor); + BYTESWAP(sp.usp_sp.sp_iInitialMana); + BYTESWAP(sp.usp_sp.sp_fExtraEnemyStrength); + BYTESWAP(sp.usp_sp.sp_fExtraEnemyStrengthPerPlayer); + BYTESWAP(sp.usp_sp.sp_ctCredits); + BYTESWAP(sp.usp_sp.sp_ctCreditsLeft); + BYTESWAP(sp.usp_sp.sp_tmSpawnInvulnerability); + BYTESWAP(sp.usp_sp.sp_iBlood); + BYTESWAP(sp.usp_sp.sp_bGibs); + BYTESWAP(sp.usp_sp.sp_bEndOfGame); + BYTESWAP(sp.usp_sp.sp_ulLevelsMask); + BYTESWAP(sp.usp_sp.sp_bUseExtraEnemies); + pstr->Write_t(&sp, NET_MAXSESSIONPROPERTIES); // write world and its state WriteWorldAndState_t(pstr); @@ -2003,10 +2085,12 @@ void CSessionState::SessionStateLoop(void) CPlayerTarget &plt = ses_apltPlayers[i]; BOOL bHas = 0; nmMessage.ReadBits(&bHas, 1); + BYTESWAP(bHas); if (bHas) { if (plt.IsActive() && plt.plt_penPlayerEntity!=NULL) { INDEX iPing = 0; nmMessage.ReadBits(&iPing, 10); + BYTESWAP(iPing); plt.plt_penPlayerEntity->en_tmPing = iPing/1000.0f; } } diff --git a/Sources/Engine/Rendering/RenCache.cpp b/Sources/Engine/Rendering/RenCache.cpp old mode 100644 new mode 100755 index 3b6fba0a8..19f7f590f --- a/Sources/Engine/Rendering/RenCache.cpp +++ b/Sources/Engine/Rendering/RenCache.cpp @@ -262,7 +262,7 @@ void CRenderer::SetupFogAndHaze(void) // if viewer is not in haze if( !re_bViewerInHaze) { // if viewer is in this sector - if( bsc.bsc_bspBSPTree.TestSphere(re_vdViewSphere, 0.01)>=0) { + if( bsc.bsc_bspBSPTree.TestSphere(re_vdViewSphere, 0.01f)>=0) { // mark that viewer is in haze re_bViewerInHaze = TRUE; } diff --git a/Sources/Engine/Rendering/RenderAdding.cpp b/Sources/Engine/Rendering/RenderAdding.cpp old mode 100644 new mode 100755 index 807f4287b..db3178de4 --- a/Sources/Engine/Rendering/RenderAdding.cpp +++ b/Sources/Engine/Rendering/RenderAdding.cpp @@ -662,7 +662,7 @@ void CRenderer::AddZoningSectorsAroundEntity(CEntity *pen, const FLOAT3D &vEyesP ASSERT(!(pen->en_ulFlags&ENF_ZONING)); // make parameters for minimum sphere to add - re_vdViewSphere = FLOATtoDOUBLE(vEyesPos); + re_vdViewSphere = vEyesPos; re_dViewSphereR = re_prProjection->NearClipDistanceR()*1.5f; CListHead lhToAdd; @@ -751,7 +751,7 @@ void CRenderer::AddZoningSectorsAroundBox(const FLOATaabbox3D &boxNear) FLOAT3D vSphereCenter = boxNear.Center(); re_dViewSphereR = re_prProjection->NearClipDistanceR()*1.5f; - re_vdViewSphere = FLOATtoDOUBLE(vSphereCenter); + re_vdViewSphere = vSphereCenter; // for all entities in world FOREACHINDYNAMICCONTAINER(re_pwoWorld->wo_cenEntities, CEntity, iten) { @@ -792,7 +792,7 @@ void CRenderer::AddZoningSectorsAroundBox(const FLOATaabbox3D &boxNear) &&!((itbsc->bsc_ulFlags&BSCF_HIDDEN) && !re_bRenderingShadows)) { // if the sphere is inside the sector if (itbsc->bsc_bspBSPTree.TestSphere( - FLOATtoDOUBLE(vSphereCenter), FLOATtoDOUBLE(fSphereRadius))>=0) { + vSphereCenter, fSphereRadius)>=0) { // add that sector to active sectors AddActiveSector(itbsc.Current()); diff --git a/Sources/Engine/Rendering/Render_internal.h b/Sources/Engine/Rendering/Render_internal.h old mode 100644 new mode 100755 index a81f9193d..d9c3b38e2 --- a/Sources/Engine/Rendering/Render_internal.h +++ b/Sources/Engine/Rendering/Render_internal.h @@ -287,8 +287,8 @@ class CRenderer { CEntity *re_penViewer; // entity that is viewed from CDynamicContainer *re_pcspoViewPolygons; // polygons that is viewed from (for mirrors) CAnyProjection3D re_prProjection; // projection to viewer space - DOUBLE3D re_vdViewSphere; - DOUBLE re_dViewSphereR; + FLOAT3D re_vdViewSphere; + FLOAT re_dViewSphereR; // used for fixing problems with extra trapezoids generated on t-junctions FLOAT re_fEdgeOffsetI; diff --git a/Sources/Engine/Rendering/SelectOnRender.cpp b/Sources/Engine/Rendering/SelectOnRender.cpp index 561cb3b94..41a75cc63 100644 --- a/Sources/Engine/Rendering/SelectOnRender.cpp +++ b/Sources/Engine/Rendering/SelectOnRender.cpp @@ -165,8 +165,7 @@ void SelectVertexOnRender(CBrushVertex &bvx, const PIX2D &vpix) // if selecting with lasso } else { // if the vertex is set in lasso buffer - if (_pubLassoBuffer!=NULL - &&_pubLassoBuffer[vpix(2)*_pixSizeI+vpix(1)]) { + if (_pubLassoBuffer[vpix(2)*_pixSizeI+vpix(1)]) { // if alternative if (_bSelectAlternative) { diff --git a/Sources/Engine/Ska/AnimSet.cpp b/Sources/Engine/Ska/AnimSet.cpp index 3dd133f4c..37a3d6d00 100644 --- a/Sources/Engine/Ska/AnimSet.cpp +++ b/Sources/Engine/Ska/AnimSet.cpp @@ -396,7 +396,10 @@ void CAnimSet::Write_t(CTStream *ostrFile) // write bone envelope ID (*ostrFile)<Write_t(&be.be_mDefaultPos[0],sizeof(FLOAT)*12); + for(int i = 0; i < 12; i++) + { + (*ostrFile)<Write_t(&be.be_apPos[ip],sizeof(AnimPos)); + (*ostrFile)<Write_t(&arRot,sizeof(AnimRot)); + (*ostrFile)<0) @@ -439,7 +442,10 @@ void CAnimSet::Write_t(CTStream *ostrFile) // write morph factors count INDEX ctmf = me.me_aFactors.Count(); (*ostrFile)<Write_t(&me.me_aFactors[0],sizeof(FLOAT)*ctmf); + for(int i = 0; i < ctmf; i++) + { + (*ostrFile)<Write_t(&mLod.mlod_aVertices[0],sizeof(MeshVertex)*ctVx); + for (int i = 0; i < ctVx; i++) (*ostrFile)<<(MeshVertex)mLod.mlod_aVertices[i]; // write normals - ostrFile->Write_t(&mLod.mlod_aNormals[0],sizeof(MeshNormal)*ctVx); + for (int i = 0; i < ctVx; i++) (*ostrFile)<<(MeshNormal)mLod.mlod_aNormals[i]; // write uvmaps count (*ostrFile)<Write_t(&mLod.mlod_aUVMaps[iuv].muv_aTexCoords[0],sizeof(MeshTexCoord)*ctVx); + for (int i = 0; i < ctVx; i++) (*ostrFile)<<(MeshTexCoord)mLod.mlod_aUVMaps[iuv].muv_aTexCoords[i]; } // write surfaces count - ostrFile->Write_t(&ctSf,sizeof(INDEX)); + (*ostrFile)<Write_t(&mLod.mlod_aSurfaces[isf].msrf_aTriangles[0],sizeof(MeshTriangle)*ctTris); + for (int i = 0; i < ctTris; i++) (*ostrFile)<<(MeshTriangle)mLod.mlod_aSurfaces[isf].msrf_aTriangles[i]; // write bool that this surface has a shader INDEX bShaderExists = (msrf.msrf_pShader!=NULL); @@ -652,7 +652,7 @@ void CMesh::Write_t(CTStream *ostrFile) // write wertex weights count (*ostrFile)<Write_t(&mLod.mlod_aWeightMaps[iwm].mwm_aVertexWeight[0],sizeof(MeshVertexWeight)*ctWw); + for (int i = 0; i < ctWw; i++) (*ostrFile)<<(MeshVertexWeight)mLod.mlod_aWeightMaps[ctWw].mwm_aVertexWeight[i]; } // write morphmaps count @@ -667,9 +667,9 @@ void CMesh::Write_t(CTStream *ostrFile) (*ostrFile)<Write_t(&mLod.mlod_aMorphMaps[imm].mmp_bRelative,sizeof(BOOL)); // write morph sets count - ostrFile->Write_t(&ctms,sizeof(INDEX)); + (*ostrFile)<Write_t(&mLod.mlod_aMorphMaps[imm].mmp_aMorphMap[0],sizeof(MeshVertexMorph)*ctms); + for (int i = 0; i < ctms; i++) (*ostrFile)<>(CTStream &strm, MeshVertex &mv) return(strm); } -static inline CTStream &operator>>(CTStream &strm, const MeshVertex &mv) +static inline CTStream &operator<<(CTStream &strm, const MeshVertex &mv) { strm<>(CTStream &strm, MeshNormal &mn) return(strm); } -static inline CTStream &operator>>(CTStream &strm, const MeshNormal &mn) +static inline CTStream &operator<<(CTStream &strm, const MeshNormal &mn) { strm<>(CTStream &strm, MeshTriangle &mt) @@ -193,7 +193,7 @@ static inline CTStream &operator>>(CTStream &strm, MeshVertexMorph &mwm) return(strm); } -static inline CTStream &operator>>(CTStream &strm, const MeshVertexMorph &mwm) +static inline CTStream &operator<<(CTStream &strm, const MeshVertexMorph &mwm) { strm<Write_t(&sb.sb_mAbsPlacement,sizeof(FLOAT)*12); + for (int i = 0; i < 12; i++) (*ostrFile)<Write_t(&sb.sb_qvRelPlacement,sizeof(QVect)); + (*ostrFile)<ogg_vfVorbisFile, pch, ctBytesToDecode-ctDecoded, &iCurrrentSection); #else long iRes = pov_read(sdc_pogg->ogg_vfVorbisFile, pch, ctBytesToDecode-ctDecoded, - 0, 2, 1, &iCurrrentSection); + PLATFORM_BIGENDIAN, 2, 1, &iCurrrentSection); #endif if (iRes<=0) { return ctDecoded; diff --git a/Sources/Engine/Sound/SoundLibrary.cpp b/Sources/Engine/Sound/SoundLibrary.cpp index 8bf813305..abade4415 100644 --- a/Sources/Engine/Sound/SoundLibrary.cpp +++ b/Sources/Engine/Sound/SoundLibrary.cpp @@ -25,10 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "initguid.h" #endif -// !!! FIXME : Move all the SDL stuff to a different file... -#ifdef PLATFORM_UNIX -#include "SDL.h" -#endif #include #include @@ -223,9 +219,9 @@ static BOOL StartUp_SDLaudio( CSoundLibrary &sl, BOOL bReport=TRUE) if (bps <= 8) desired.format = AUDIO_U8; else if (bps <= 16) - desired.format = AUDIO_S16LSB; + desired.format = AUDIO_S16SYS; else if (bps <= 32) - desired.format = AUDIO_S32LSB; + desired.format = AUDIO_S32SYS; else { CPrintF(TRANSV("Unsupported bits-per-sample: %d\n"), bps); return FALSE; @@ -266,7 +262,6 @@ static BOOL StartUp_SDLaudio( CSoundLibrary &sl, BOOL bReport=TRUE) // report success if( bReport) { - STUBBED("Report actual SDL device name?"); CPrintF( TRANSV(" opened device: %s\n"), "SDL audio stream"); CPrintF( TRANSV(" %dHz, %dbit, %s\n"), sl.sl_SwfeFormat.nSamplesPerSec, diff --git a/Sources/Engine/StdH.h b/Sources/Engine/StdH.h old mode 100644 new mode 100755 index 8547abf81..562d53f5a --- a/Sources/Engine/StdH.h +++ b/Sources/Engine/StdH.h @@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define ENGINE_INTERNAL 1 #define ENGINE_EXPORTS 1 +#define __STDC_LIMIT_MACROS 1 #include #include #include diff --git a/Sources/Engine/Templates/BSP.cpp b/Sources/Engine/Templates/BSP.cpp old mode 100644 new mode 100755 index 32dce0e65..ee781d341 --- a/Sources/Engine/Templates/BSP.cpp +++ b/Sources/Engine/Templates/BSP.cpp @@ -506,6 +506,310 @@ FLOAT BSPNode::TestSphere(const Vector &vS } } } + +#ifdef SPHERE_HACK +// truncate doubles in d0-d3 to floats in d0-d1 +// destroys d2-d7 +#define doubles_to_floats \ + "vmov.i32 q3, #0xff800000\n" \ + "vshrn.i64 d4, q0, #29\n" \ + "vshrn.i64 d5, q1, #29\n" \ + "vshrn.i64 d0, q0, #32\n" \ + "vshrn.i64 d1, q1, #32\n" \ + "vsub.i32 q2, q3\n" \ + "vbic.i32 q3, #0xc0000000\n" \ + "vshl.i32 q1, q0, #1\n" \ + "vceq.i32 q1, q1, #0\n" \ + "vadd.i32 q2, q3\n" \ + "vorr.i32 q1, #0x80000000\n" \ + "vbif.32 q0, q2, q1\n" + +// params[6]: vec[3], -1, radius, -radius +template<> +int BSPNode::TestSphere_hack(const FLOAT *params) const +{ + const BSPNode *node, *next; + +#ifdef __arm__ + register double params_q8 __asm__("q8"); + __asm__ __volatile__ ( + "vld1.64 {d16,d17}, [%[prm], :64]\n" + : "=w"(params_q8) + : [prm] "r"(params) + ); +#endif + + node = this; + for (;;) + { +#ifdef __arm__ + register double vec_q0 __asm__("q0"); + register double vec_d2 __asm__("d2"); + __asm__ __volatile__ ( + "vld1.64 {d0,d1,d2}, [%[vec], :64]\n" + : "=w"(vec_q0), "=w"(vec_d2) + : [vec] "r"(node->vector) + ); +#endif + // if this is an inside node + if (node->bn_bnlLocation == BNL_INSIDE) { + // it is inside + return 1; + // if this is an outside node + } else if (node->bn_bnlLocation == BNL_OUTSIDE) { + // it is outside + return -1; + // if this is a branch + } else { + ASSERT(node->bn_bnlLocation == BNL_BRANCH); + // test the sphere against the split plane + //double tCenterDistance = node->PointDistance(vSphereCenter); +#ifdef __arm__ + register double dist_d3 __asm__("d3") = node->pl_distance; + + __asm__ __volatile__ ( + doubles_to_floats + "vmul.f32 q0, q0, q8\n" + "ldr r2, %[pbnF]\n" + "vldr d2, %[rad]\n" + "ldr r3, %[pbnB]\n" + "vpadd.f32 d0, d0, d1\n" + "vmov d3, r3, r2\n" // pbnF.pbnB + "vpadd.f32 d0, d0, d0\n" // tCenterDistance + "vcgt.f32 d4, d0, d2\n" // [0] tCenterDistance > radius + "vcgt.f32 d5, d2, d0\n" // [1] -radius > tCenterDistance + "vext.32 d0, d5, d4, #1\n" // [0].[1] + "vand d0, d3\n" + "vpadd.i32 d0, d3\n" + "vmov.i32 %[next], d0[0]\n" + : [next] "=r"(next), + "=w"(vec_q0), "=w"(vec_d2), "=w"(dist_d3) + : "w"(vec_q0), "w"(vec_d2), "w"(dist_d3), "w"(params_q8), + [pbnF] "m"(node->bn_pbnFront), + [pbnB] "m"(node->bn_pbnBack), + [rad] "m"(params[4]) + : "r2", "r3", "q2", "q3" + ); +#else + float tCenterDistance = + node->vector[0] * params[0] + + node->vector[1] * params[1] + + node->vector[2] * params[2] - node->pl_distance; + + // if the sphere is in front of the plane + if (tCenterDistance > +params[4]) { + next = node->bn_pbnFront; + // if the sphere is behind the plane + } else if (tCenterDistance < params[5]) { + next = node->bn_pbnBack; + // if the sphere is split by the plane + } else { + next = NULL; + } +#endif + if (next == NULL) + break; + node = next; + } + } + + // if front node touches + int iFront = node->bn_pbnFront->TestSphere_hack(params); + if (iFront==0) { + // it touches + return 0; + } + // if back node touches + int iBack = node->bn_pbnBack->TestSphere_hack(params); + if (iBack==0) { + // it touches + return 0; + } + // if front and back have same classification + if (iFront==iBack) { + // return it + return iFront; + // if front and back have different classification + } else { + // it touches + return 0; + } +} + +// _ZNK7BSPNodeIdLi3EE10TestSphereERK6VectorIdLi3EEd +template<> +FLOAT BSPNode::TestSphere(const Vector &vSphereCenter, double tSphereRadius) const +{ + float params[6] __attribute__((aligned(8))); + +#ifdef __arm__ + register double radius __asm__("d3") = tSphereRadius; + __asm__ __volatile__ ( + "vld1.64 {d0,d1,d2}, [%[vec], :64]\n" + doubles_to_floats + "vmov.i32 d4, #0\n" + "vmov.i32 d4[1], %[sgn]\n" + "vmov.f32 d3, #-1.0\n" + "vdup.32 d2, d1[1]\n" + "vsli.i64 d1, d3, #32\n" + "veor d2, d4\n" + "vst1.32 {d0,d1,d2}, [%[prm], :64]\n" + : "=w"(radius) + : [vec] "r"(vSphereCenter.vector), + [prm] "r"(params), + [sgn] "r"(0x80000000), + "w"(radius) + : "q0", "d2", "q2", "q3" + ); +#else + params[0] = vSphereCenter.vector[0]; + params[1] = vSphereCenter.vector[1]; + params[2] = vSphereCenter.vector[2]; + params[3] = -1.0f; + params[4] = tSphereRadius; + params[5] = -tSphereRadius; +#endif + + return TestSphere_hack(params); +} + +// params[6]: vec[3], -1, radius, -radius +template<> +int BSPNode::TestSphere_hack(const FLOAT *params) const +{ + const BSPNode *node = this; + +#ifdef __arm__ + register double params_q8 __asm__("q8"); + register double radius_d18 __asm__("d18"); + register double cdist_d6 __asm__("d6"); + __asm__ __volatile__ ( + "vld1.32 {d0,d1}, [%[vec]]\n" + "vldr s3, %[dist]\n" + "vld1.64 {d16,d17,d18}, [%[prm], :64]\n" + "vmul.f32 q0, q0, q8\n" + "vpadd.f32 d6, d0, d1\n" + : "=w"(cdist_d6), + "=w"(params_q8), + "=w"(radius_d18) + : [prm] "r"(params), + [vec] "r"(node->vector), + [dist] "m"(node->pl_distance) + ); +#endif + + for (;;) + { + // if this is an inside node + if (node->bn_bnlLocation == BNL_INSIDE) { + // it is inside + return 1; + // if this is an outside node + } else if (node->bn_bnlLocation == BNL_OUTSIDE) { + // it is outside + return -1; + // if this is a branch + } else { + ASSERT(node->bn_bnlLocation == BNL_BRANCH); + // test the sphere against the split plane + //float tCenterDistance = node->PointDistance(vSphereCenter); +#ifdef __arm__ + int gt_radius, lt_nradius; + __asm__ __volatile__ ( + "vpadd.f32 d6, d6, d6\n" // tCenterDistance + "vld1.32 {d0,d1}, [%[pbnFv]]\n" + "vldr s3, %[pbnFd]\n" + "vcgt.f32 d4, d6, d18\n" // [0] tCenterDistance > radius + "vcgt.f32 d5, d18, d6\n" // [1] -radius > tCenterDistance + "vld1.32 {d2,d3}, [%[pbnBv]]\n" + "vldr s7, %[pbnBd]\n" + "vmov.i32 %[gt], d4[0]\n" + "vmov.i32 %[lt], d5[1]\n" + + "vdup.i32 q2, d5[1]\n" + "vbit q0, q1, q2\n" + "vmul.f32 q0, q0, q8\n" + "vpadd.f32 d6, d0, d1\n" + : [gt] "=r"(gt_radius), [lt] "=r"(lt_nradius), + "=w"(cdist_d6) + : "w"(cdist_d6), "w"(params_q8), "w"(radius_d18), + [pbnFv] "r"(node->bn_pbnFront->vector), + [pbnFd] "m"(node->bn_pbnFront->pl_distance), + [pbnBv] "r"(node->bn_pbnBack->vector), + [pbnBd] "m"(node->bn_pbnBack->pl_distance) + : "q0", "q1", "q2", "d7" + ); + + // if the sphere is in front of the plane + if (gt_radius) { + node = node->bn_pbnFront; + // if the sphere is behind the plane + } else if (lt_nradius) { + node = node->bn_pbnBack; + // if the sphere is split by the plane + } else { + break; + } +#else + float tCenterDistance = + node->vector[0] * params[0] + + node->vector[1] * params[1] + + node->vector[2] * params[2] - node->pl_distance; + + // if the sphere is in front of the plane + if (tCenterDistance > +params[4]) { + node = node->bn_pbnFront; + // if the sphere is behind the plane + } else if (tCenterDistance < params[5]) { + node = node->bn_pbnBack; + // if the sphere is split by the plane + } else { + break; + } +#endif + } + } + + // if front node touches + int iFront = node->bn_pbnFront->TestSphere_hack(params); + if (iFront==0) { + // it touches + return 0; + } + // if back node touches + int iBack = node->bn_pbnBack->TestSphere_hack(params); + if (iBack==0) { + // it touches + return 0; + } + // if front and back have same classification + if (iFront==iBack) { + // return it + return iFront; + // if front and back have different classification + } else { + // it touches + return 0; + } +} + +template<> +FLOAT BSPNode::TestSphere(const Vector &vSphereCenter, float tSphereRadius) const +{ + float params[6] __attribute__((aligned(8))); + + params[0] = vSphereCenter.vector[0]; + params[1] = vSphereCenter.vector[1]; + params[2] = vSphereCenter.vector[2]; + params[3] = -1.0f; + params[4] = tSphereRadius; + params[5] = -tSphereRadius; + + return TestSphere_hack(params); +} + +#endif + /* Test if a box is inside, outside, or intersecting. (Just a trivial rejection test) */ template FLOAT BSPNode::TestBox(const OBBox &box) const @@ -1210,7 +1514,10 @@ void BSPTree::Read_t(CTStream &strm) // throw char * BSPNode &bn = bt_abnNodes[iNode]; // read it from disk //strm.Read_t(&(Plane&)bn, sizeof(Plane)); - strm >> ((Plane&)bn); + //strm >> ((Plane&)bn); + Plane tmp; + strm >> tmp; + ((Plane &)bn) = DOUBLEtoFLOAT(tmp); strm>>(INDEX&)bn.bn_bnlLocation; diff --git a/Sources/Engine/Templates/BSP.h b/Sources/Engine/Templates/BSP.h old mode 100644 new mode 100755 index 5d390ca6a..fd06b8af8 --- a/Sources/Engine/Templates/BSP.h +++ b/Sources/Engine/Templates/BSP.h @@ -60,9 +60,9 @@ class BSPTree { Type &tMin, Type &tMax) const; /* Test if a sphere is inside, outside, or intersecting. (Just a trivial rejection test) */ - FLOAT TestSphere(const Vector &vSphereCenter, Type tSphereRadius) const; + FLOAT FASTMATH TestSphere(const Vector &vSphereCenter, Type tSphereRadius) const; /* Test if a box is inside, outside, or intersecting. (Just a trivial rejection test) */ - FLOAT TestBox(const OBBox &box) const; + FLOAT FASTMATH TestBox(const OBBox &box) const; /* Read/write entire bsp tree to disk. */ void Read_t(CTStream &strm); // throw char * void Write_t(CTStream &strm); // throw char * diff --git a/Sources/Engine/Templates/BSP_internal.h b/Sources/Engine/Templates/BSP_internal.h old mode 100644 new mode 100755 index 57ccbda64..2527ed0b3 --- a/Sources/Engine/Templates/BSP_internal.h +++ b/Sources/Engine/Templates/BSP_internal.h @@ -21,6 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc., extern FLOAT mth_fCSGEpsilon; +#if defined __arm__ && defined __ARM_PCS_VFP +#define SPHERE_HACK +#endif + /* * Type used to identify BSP-node locations */ @@ -169,6 +173,9 @@ class BSPNode : public Plane { // split plane /* Test if a sphere is inside, outside, or intersecting. (Just a trivial rejection test) */ FLOAT TestSphere(const Vector &vSphereCenter, Type tSphereRadius) const; + #ifdef SPHERE_HACK + int TestSphere_hack(const FLOAT *params) const; + #endif /* Test if a box is inside, outside, or intersecting. (Just a trivial rejection test) */ FLOAT TestBox(const OBBox &box) const; }; diff --git a/Sources/Engine/Templates/StaticArray.cpp b/Sources/Engine/Templates/StaticArray.cpp old mode 100644 new mode 100755 index 6b62639c1..59c6bd320 --- a/Sources/Engine/Templates/StaticArray.cpp +++ b/Sources/Engine/Templates/StaticArray.cpp @@ -30,12 +30,6 @@ inline void CStaticArray::operator=(const CStaticArray &arOriginal) CopyArray(arOriginal); } -template -/* Destroy all objects, and reset the array to initial (empty) state. */ -inline void CStaticArray::Clear(void) { - if (sa_Count!=0) Delete(); -} - /* * Create a given number of objects. */ diff --git a/Sources/Engine/Templates/StaticArray.h b/Sources/Engine/Templates/StaticArray.h old mode 100644 new mode 100755 index 99c022706..9a5e81db8 --- a/Sources/Engine/Templates/StaticArray.h +++ b/Sources/Engine/Templates/StaticArray.h @@ -61,7 +61,9 @@ class CStaticArray { sa_Array = NULL; } /* Destroy all objects, and reset the array to initial (empty) state. */ - inline void Clear(void); + inline void Clear(void) { + if (sa_Count!=0) Delete(); + } /* Random access operator. */ inline Type &operator[](INDEX iObject) diff --git a/Sources/Engine/Terrain/ArrayHolder.h b/Sources/Engine/Terrain/ArrayHolder.h old mode 100644 new mode 100755 index 9c96cbf35..f0cc5b585 --- a/Sources/Engine/Terrain/ArrayHolder.h +++ b/Sources/Engine/Terrain/ArrayHolder.h @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., struct TileLayer { - CStaticStackArray tl_auiIndices; // Array of indices for one layer + CStaticStackArray tl_auiIndices; // Array of indices for one layer CStaticStackArray tl_acColors; // Array of colors for one layer CStaticStackArray tl_atcTexCoords; // Array of texcoords for one layer CStaticStackArray tl_avVertices; // Array of vertices for one layer (used only if tile layer) @@ -48,7 +48,7 @@ struct TileArrays CStaticStackArray ta_auvTexCoords; // Array of texcoords for one tile (not used in highest lod) CStaticStackArray ta_auvShadowMap; // Array of texcoords for shadow map CStaticStackArray ta_auvDetailMap; // Array of texcoords for detail map - CStaticStackArray ta_auiIndices; // Array of indices for one tile + CStaticStackArray ta_auiIndices; // Array of indices for one tile CStaticStackArray ta_atlLayers; // Array if layers per tile (used only in highest lod) CTextureData *ta_ptdTopMap; // Pointer to tile top map }; diff --git a/Sources/Engine/Terrain/Terrain.cpp b/Sources/Engine/Terrain/Terrain.cpp index 9af3da68c..70cb2ac8d 100644 --- a/Sources/Engine/Terrain/Terrain.cpp +++ b/Sources/Engine/Terrain/Terrain.cpp @@ -1972,10 +1972,12 @@ void CTerrain::Write_t( CTStream *ostrFile) INDEX iShadingMapSize = GetShadingMapWidth() * GetShadingMapHeight() * sizeof(UWORD); // Write shadow map ASSERT(tr_tdShadowMap.td_pulFrames!=NULL); - ostrFile->Write_t(&tr_tdShadowMap.td_pulFrames[0],iShadowMapSize); + for (INDEX i = 0; i < iShadowMapSize; i++) + (*ostrFile)<Write_t(&tr_auwShadingMap[0],iShadingMapSize); + for (INDEX i = 0; i < iShadingMapSize; i++) + (*ostrFile)<WriteID_t("TSEN"); // 'Terrain shadowmap end' @@ -1989,7 +1991,7 @@ void CTerrain::Write_t( CTStream *ostrFile) (*ostrFile).WriteID_t("TRHM"); // 'Terrain heightmap' // write height map - (*ostrFile).Write_t(&tr_auwHeightMap[0],sizeof(UWORD)*tr_pixHeightMapWidth*tr_pixHeightMapHeight); + for (int i = 0; i < (tr_pixHeightMapWidth * tr_pixHeightMapHeight); i++) (*ostrFile)< _avExtVertices; -CStaticStackArray _aiExtIndices; +CStaticStackArray _aiExtIndices; CStaticStackArray _aiExtColors; CStaticStackArray _aiHitTiles; @@ -210,7 +210,7 @@ FLOAT GetExactHitLocation(INDEX iTileIndex, FLOAT3D &vOrigin, FLOAT3D &vTarget, QuadTreeNode &qtn = _ptrTerrain->tr_aqtnQuadTreeNodes[iTileIndex]; GFXVertex *pavVertices; - INDEX *paiIndices; + INDEX_T *paiIndices; INDEX ctVertices; INDEX ctIndices; @@ -222,7 +222,7 @@ FLOAT GetExactHitLocation(INDEX iTileIndex, FLOAT3D &vOrigin, FLOAT3D &vTarget, // for each triangle for(INDEX iTri=0;iTri> Remove Rect from ExtractPolygonsInBox") // Extract polygons in given box and returns clipped rectangle Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract, GFXVertex4 **pavVtx, - INDEX **paiInd, INDEX &ctVtx,INDEX &ctInd,BOOL bFixSize/*=FALSE*/) + INDEX_T **paiInd, INDEX &ctVtx,INDEX &ctInd,BOOL bFixSize/*=FALSE*/) { ASSERT(ptrTerrain!=NULL); @@ -309,11 +309,16 @@ Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract Rect rc; if(!bFixSize) { // max vector of bbox in incremented for one, because first vertex is at 0,0,0 in world and in heightmap is at 1,1 -#ifdef __arm__ - rc.rc_iLeft = (isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); - rc.rc_iTop = (isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); - rc.rc_iRight = (isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(1)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); - rc.rc_iBottom = (isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(3)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#if !defined(__i386__) && !defined(__x86_64__) +#if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + #define Isinf(a) (((*(unsigned int*)&a)&0x7fffffff)==0x7f800000) +#else + #define Isinf isinff +#endif + rc.rc_iLeft = (Isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iTop = (Isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); + rc.rc_iRight = (Isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(1)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iBottom = (Isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(3)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); #else rc.rc_iLeft = Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iTop = Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); @@ -322,11 +327,11 @@ Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract #endif } else { // max vector of bbox in incremented for one, because first vertex is at 0,0,0 in world and in heightmap is at 1,1 -#ifdef __arm__ - rc.rc_iLeft = (isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); - rc.rc_iTop = (isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); - rc.rc_iRight = (isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(1)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); - rc.rc_iBottom = (isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(3)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#if !defined(__i386__) && !defined(__x86_64__) + rc.rc_iLeft = (Isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iTop = (Isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); + rc.rc_iRight = (Isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(1)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iBottom = (Isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(3)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); #else rc.rc_iLeft = Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iTop = Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); @@ -363,7 +368,7 @@ Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract _aiExtIndices.Push(ctIndices); GFXVertex4 *pavVertices = &_avExtVertices[0]; - INDEX *pauiIndices = &_aiExtIndices[0]; + INDEX_T *pauiIndices = &_aiExtIndices[0]; // for each row INDEX iy, ix; @@ -451,7 +456,7 @@ Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract } void ExtractVerticesInRect(CTerrain *ptrTerrain, Rect &rc, GFXVertex4 **pavVtx, - INDEX **paiInd, INDEX &ctVtx,INDEX &ctInd) + INDEX_T **paiInd, INDEX &ctVtx,INDEX &ctInd) { _avExtVertices.PopAll(); _aiExtIndices.PopAll(); @@ -492,7 +497,7 @@ void ExtractVerticesInRect(CTerrain *ptrTerrain, Rect &rc, GFXVertex4 **pavVtx, puwHeight+=iStepY; } - INDEX *pauiIndices = &_aiExtIndices[0]; + INDEX_T *pauiIndices = &_aiExtIndices[0]; INDEX ivx=0; //INDEX ind=0; INDEX iFacing=iFirstHeight; diff --git a/Sources/Engine/Terrain/TerrainMisc.h b/Sources/Engine/Terrain/TerrainMisc.h old mode 100644 new mode 100755 index 717a1c80a..df01e3fe4 --- a/Sources/Engine/Terrain/TerrainMisc.h +++ b/Sources/Engine/Terrain/TerrainMisc.h @@ -22,10 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include // Extract polygons in given box and returns clipped rectangle Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bbox, GFXVertex4 **pavVtx, - INDEX **paiInd, INDEX &ctVtx,INDEX &ctInd,BOOL bFixSize=FALSE); + INDEX_T **paiInd, INDEX &ctVtx,INDEX &ctInd,BOOL bFixSize=FALSE); void ExtractVerticesInRect(CTerrain *ptrTerrain, Rect &rc, GFXVertex4 **pavVtx, - INDEX **paiInd, INDEX &ctVtx,INDEX &ctInd); + INDEX_T **paiInd, INDEX &ctVtx,INDEX &ctInd); // check whether a polygon is below given point, but not too far away diff --git a/Sources/Engine/Terrain/TerrainRayCasting.cpp b/Sources/Engine/Terrain/TerrainRayCasting.cpp old mode 100644 new mode 100755 index 4cbea47b8..9fa4a38e5 --- a/Sources/Engine/Terrain/TerrainRayCasting.cpp +++ b/Sources/Engine/Terrain/TerrainRayCasting.cpp @@ -32,7 +32,7 @@ static FLOATplane3D _plHitPlane; // hit plane // TEMP static CStaticStackArray _avRCVertices; -static CStaticStackArray _aiRCIndices; +static CStaticStackArray _aiRCIndices; static FLOAT3D _vHitBegin; static FLOAT3D _vHitEnd; static FLOAT _fDistance; @@ -89,7 +89,7 @@ static FLOAT HitCheckQuad(const PIX ix, const PIX iz) (pvx[0].y<=_fMaxHeight || pvx[2].y<=_fMinHeight || pvx[1].y<=_fMinHeight) && ((pvx[0].shade + pvx[2].shade + pvx[1].shade == 255*3) | _bHitInvisibleTris)) { // Add this triangle - INDEX *pind = _aiRCIndices.Push(3); + INDEX_T *pind = _aiRCIndices.Push(3); pind[0] = ctVertices+0; pind[1] = ctVertices+2; pind[2] = ctVertices+1; @@ -100,7 +100,7 @@ static FLOAT HitCheckQuad(const PIX ix, const PIX iz) (pvx[1].y<=_fMaxHeight || pvx[2].y<=_fMaxHeight || pvx[3].y<=_fMaxHeight) && ((pvx[1].shade + pvx[2].shade + pvx[3].shade == 255*3) | _bHitInvisibleTris)) { // Add this triangle - INDEX *pind = _aiRCIndices.Push(3); + INDEX_T *pind = _aiRCIndices.Push(3); pind[0] = ctVertices+1; pind[1] = ctVertices+2; pind[2] = ctVertices+3; @@ -112,7 +112,7 @@ static FLOAT HitCheckQuad(const PIX ix, const PIX iz) (pvx[2].y<=_fMaxHeight || pvx[3].y<=_fMaxHeight || pvx[0].y<=_fMaxHeight) && ((pvx[2].shade + pvx[3].shade + pvx[0].shade == 255*3) | _bHitInvisibleTris)) { // Add this triangle - INDEX *pind = _aiRCIndices.Push(3); + INDEX_T *pind = _aiRCIndices.Push(3); pind[0] = ctVertices+2; pind[1] = ctVertices+3; pind[2] = ctVertices+0; @@ -123,7 +123,7 @@ static FLOAT HitCheckQuad(const PIX ix, const PIX iz) (pvx[0].y<=_fMaxHeight || pvx[3].y<=_fMaxHeight || pvx[1].y<=_fMaxHeight) && ((pvx[0].shade + pvx[3].shade + pvx[1].shade == 255*3) | _bHitInvisibleTris)) { // Add this triangle - INDEX *pind = _aiRCIndices.Push(3); + INDEX_T *pind = _aiRCIndices.Push(3); pind[0] = ctVertices+0; pind[1] = ctVertices+3; pind[2] = ctVertices+1; @@ -135,10 +135,10 @@ static FLOAT HitCheckQuad(const PIX ix, const PIX iz) return fDistance; } - INDEX *paiIndices = &_aiRCIndices[_aiRCIndices.Count() - ctIndices]; + INDEX_T *paiIndices = &_aiRCIndices[_aiRCIndices.Count() - ctIndices]; // for each triangle for(INDEX iTri=0;iTri _avLerpedTileLayerVertices; // Arrays for batch rendering of tiles is lowest mip static CStaticStackArray _avDelayedVertices; -static CStaticStackArray _aiDelayedIndices; +static CStaticStackArray _aiDelayedIndices; static CStaticStackArray _auvDelayedTexCoords; static CStaticStackArray _auvDelayedShadowMapTC; @@ -770,7 +770,7 @@ static void RenderBatchedTiles(void) GFXVertex4 *pavVertices = &_avDelayedVertices[0]; GFXTexCoord *pauvTexCoords = &_auvDelayedTexCoords[0]; GFXTexCoord *pauvShadowMapTC = &_auvDelayedShadowMapTC[0]; - INDEX *paiIndices = &_aiDelayedIndices[0]; + INDEX_T *paiIndices = &_aiDelayedIndices[0]; INDEX ctVertices = _avDelayedVertices.Count(); INDEX ctIndices = _aiDelayedIndices.Count(); @@ -826,12 +826,12 @@ static void BatchTile(INDEX itt) GFXVertex4 *pavVertices = &tt.GetVertices()[0]; GFXTexCoord *pauvTexCoords = &tt.GetTexCoords()[0]; GFXTexCoord *pauvShadowMapTC = &tt.GetShadowMapTC()[0]; - INDEX *paiIndices = &tt.GetIndices()[0]; + INDEX_T *paiIndices = &tt.GetIndices()[0]; GFXVertex4 *pavDelVertices = _avDelayedVertices.Push(9); GFXTexCoord *pauvDelTexCoords = _auvDelayedTexCoords.Push(9); GFXTexCoord *pauvDelShadowMapTC = _auvDelayedShadowMapTC.Push(9); - INDEX *paiDelIndices = _aiDelayedIndices.Push(24); + INDEX_T *paiDelIndices = _aiDelayedIndices.Push(24); // for each vertex in tile for(INDEX ivx=0;ivx<9;ivx++) { @@ -891,7 +891,7 @@ static void RenderFogLayer(INDEX itt) _fFogAddH = (_fog_vHDirAbs % vObjPosition) + _fog_fp.fp_fH3; GFXVertex *pvVtx; - INDEX *piIndices; + INDEX_T *piIndices; INDEX ctVertices; INDEX ctIndices; // if this is tile @@ -947,7 +947,7 @@ static void RenderHazeLayer(INDEX itt) _fHazeAdd += _vViewer(3) * (vObjPosition(3) - _aprProjection->pr_vViewerPosition(3)); GFXVertex *pvVtx; - INDEX *piIndices; + INDEX_T *piIndices; INDEX ctVertices; INDEX ctIndices; // if this is tile @@ -1103,7 +1103,7 @@ static void RenderTile(INDEX itt) gfxSetTextureMatrix2(NULL); INDEX ctIndices = tt.GetIndices().Count(); if(ctIndices>0) { - INDEX *paiIndices = &tt.GetIndices()[0]; + INDEX_T *paiIndices = &tt.GetIndices()[0]; // if detail map exists if(_ptrTerrain->tr_ptdDetailMap!=NULL) { @@ -1157,7 +1157,7 @@ static void RenderTile(INDEX itt) if(_wrpWorldRenderPrefs.wrp_shtShadows!=CWorldRenderPrefs::SHT_NONE) { gfxDepthFunc(GFX_EQUAL); INDEX ctIndices = tt.GetIndices().Count(); - INDEX *paiIndices = &tt.GetIndices()[0]; + INDEX_T *paiIndices = &tt.GetIndices()[0]; gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP); gfxBlendFunc(GFX_DST_COLOR,GFX_SRC_COLOR); diff --git a/Sources/Engine/Terrain/TerrainTile.cpp b/Sources/Engine/Terrain/TerrainTile.cpp old mode 100644 new mode 100755 index 677551bfd..505f473b6 --- a/Sources/Engine/Terrain/TerrainTile.cpp +++ b/Sources/Engine/Terrain/TerrainTile.cpp @@ -164,7 +164,7 @@ inline void CTerrainTile::AddTriangle(INDEX iind1,INDEX iind2,INDEX iind3) } // Add one triangle - INDEX *pIndices = GetIndices().Push(3); + INDEX_T *pIndices = GetIndices().Push(3); pIndices[0] = iind1; pIndices[1] = iind2; pIndices[2] = iind3; @@ -181,14 +181,14 @@ inline void CTerrainTile::AddTriangle(INDEX iind1,INDEX iind2,INDEX iind3) COLOR ul = ttl.tl_acColors[iind1].ub.a + ttl.tl_acColors[iind2].ub.a + ttl.tl_acColors[iind3].ub.a; if(ul>0) { - INDEX *pIndices = ttl.tl_auiIndices.Push(3); + INDEX_T *pIndices = ttl.tl_auiIndices.Push(3); pIndices[0] = iind1; pIndices[1] = iind2; pIndices[2] = iind3; } } } else { - INDEX *pIndices = GetIndices().Push(3); + INDEX_T *pIndices = GetIndices().Push(3); pIndices[0] = iind1; pIndices[1] = iind2; pIndices[2] = iind3; @@ -309,7 +309,7 @@ void CTerrainTile::ReGenerateTileLayer(INDEX iTileLayer) ASSERT(ttl.tl_avVertices.Count()==0 && ttl.tl_atcTexCoords.Count()==0 && ttl.tl_auiIndices.Count()==0); GFXVertex *pvtx = ttl.tl_avVertices.Push(ctVertices); GFXTexCoord *ptc = ttl.tl_atcTexCoords.Push(ctVertices); - INDEX *pind = ttl.tl_auiIndices.Push(ctIndices); + INDEX_T *pind = ttl.tl_auiIndices.Push(ctIndices); UBYTE *pubMask = tl.tl_aubColors; INDEX ivx = 0; @@ -565,7 +565,7 @@ void CTerrainTile::UpdateQuadTreeNode() // resize aabox for this node FLOATaabbox3D bboxNewBox; GFXVertex4 *pavVertices; - INDEX *paiIndices; + INDEX_T *paiIndices; INDEX ctVertices; INDEX ctIndices; QuadTreeNode &qtn = _ptrTerrain->tr_aqtnQuadTreeNodes[tt_iIndex]; @@ -973,7 +973,7 @@ __forceinline CStaticStackArray &CTerrainTile::GetDetailTC() { TileArrays &ta = ah.ah_ataTileArrays[tt_iArrayIndex]; return ta.ta_auvDetailMap; } -__forceinline CStaticStackArray &CTerrainTile::GetIndices() { +__forceinline CStaticStackArray &CTerrainTile::GetIndices() { ASSERT(tt_iArrayIndex!=-1); ASSERT(tt_iLod!=-1); CArrayHolder &ah = _ptrTerrain->tr_aArrayHolders[tt_iLod]; diff --git a/Sources/Engine/Terrain/TerrainTile.h b/Sources/Engine/Terrain/TerrainTile.h old mode 100644 new mode 100755 index 9edb69478..fb5569b79 --- a/Sources/Engine/Terrain/TerrainTile.h +++ b/Sources/Engine/Terrain/TerrainTile.h @@ -58,7 +58,7 @@ class ENGINE_API CTerrainTile CStaticStackArray &GetTexCoords(); CStaticStackArray &GetShadowMapTC(); CStaticStackArray &GetDetailTC(); - CStaticStackArray &GetIndices(); + CStaticStackArray &GetIndices(); CStaticStackArray &GetTileLayers(); CTextureData *GetTopMap(); diff --git a/Sources/Engine/World/WorldCollision.cpp b/Sources/Engine/World/WorldCollision.cpp old mode 100644 new mode 100755 index 28e98427d..bd90b8016 --- a/Sources/Engine/World/WorldCollision.cpp +++ b/Sources/Engine/World/WorldCollision.cpp @@ -350,8 +350,12 @@ void CClipMove::ClipMovingSphereToBrushPolygon(const CMovingSphere &msMoving, // create an intersector CIntersector isIntersector(vHitPoint(iMajorAxis1), vHitPoint(iMajorAxis2)); // for all edges in the polygon - FOREACHINSTATICARRAY(pbpoPolygon->bpo_abpePolygonEdges, CBrushPolygonEdge, - itbpePolygonEdge) { + /*FOREACHINSTATICARRAY(pbpoPolygon->bpo_abpePolygonEdges, CBrushPolygonEdge, + itbpePolygonEdge) {*/ + CBrushPolygonEdge *itbpePolygonEdge = pbpoPolygon->bpo_abpePolygonEdges.sa_Array; + int i; + const int count = pbpoPolygon->bpo_abpePolygonEdges.sa_Count; + for (i = 0; i < count; i++, itbpePolygonEdge++) { // get edge vertices (edge direction is irrelevant here!) const FLOAT3D &vVertex0 = itbpePolygonEdge->bpe_pbedEdge->bed_pbvxVertex0->bvx_vRelative; const FLOAT3D &vVertex1 = itbpePolygonEdge->bpe_pbedEdge->bed_pbvxVertex1->bvx_vRelative; @@ -380,7 +384,11 @@ void CClipMove::ClipMovingSphereToBrushPolygon(const CMovingSphere &msMoving, } // for each edge in polygon - FOREACHINSTATICARRAY(pbpoPolygon->bpo_abpePolygonEdges, CBrushPolygonEdge, itbpe) { + //FOREACHINSTATICARRAY(pbpoPolygon->bpo_abpePolygonEdges, CBrushPolygonEdge, itbpe) { + CBrushPolygonEdge *itbpe = pbpoPolygon->bpo_abpePolygonEdges.sa_Array; + int i; + const int count = pbpoPolygon->bpo_abpePolygonEdges.sa_Count; + for (i = 0; i < count; i++, itbpe++) { // get edge vertices (edge direction is important here!) FLOAT3D vVertex0, vVertex1; itbpe->GetVertexCoordinatesRelative(vVertex0, vVertex1); @@ -509,8 +517,12 @@ void CClipMove::ClipMoveToTerrainPolygon(const FLOAT3D &v0, const FLOAT3D &v1, c { _pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_CLIPMOVETOBRUSHPOLYGON); // for each sphere of entity A - FOREACHINSTATICARRAY(*cm_pamsA, CMovingSphere, itmsMoving) { - // clip moving sphere to the polygon + //FOREACHINSTATICARRAY(*cm_pamsA, CMovingSphere, itmsMoving) { + CMovingSphere *itmsMoving = cm_pamsA->sa_Array; + int i; + const int count = cm_pamsA->sa_Count; + for (i = 0; i < count; i++, itmsMoving++) { + // clip moving sphere to the polygon ClipMovingSphereToTerrainPolygon(*itmsMoving, v0, v1, v2); } _pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_CLIPMOVETOBRUSHPOLYGON); @@ -523,7 +535,11 @@ void CClipMove::ClipMoveToBrushPolygon(CBrushPolygon *pbpoPolygon) { _pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_CLIPMOVETOBRUSHPOLYGON); // for each sphere of entity A - FOREACHINSTATICARRAY(*cm_pamsA, CMovingSphere, itmsMoving) { + //FOREACHINSTATICARRAY(*cm_pamsA, CMovingSphere, itmsMoving) { + CMovingSphere *itmsMoving = cm_pamsA->sa_Array; + int i; + const int count = cm_pamsA->sa_Count; + for (i = 0; i < count; i++, itmsMoving++) { // clip moving sphere to the polygon ClipMovingSphereToBrushPolygon(*itmsMoving, pbpoPolygon); } @@ -869,10 +885,15 @@ void CClipMove::ClipToNonZoningSector(CBrushSector *pbsc) CPhysicsProfile::PTI_CLIPTONONZONINGSECTOR, pbsc->bsc_abpoPolygons.Count()); // for each polygon in the sector - FOREACHINSTATICARRAY(pbsc->bsc_abpoPolygons, CBrushPolygon, itbpo) { + //FOREACHINSTATICARRAY(pbsc->bsc_abpoPolygons, CBrushPolygon, itbpo) { + CBrushPolygon *itbpo = pbsc->bsc_abpoPolygons.sa_Array; + int i; + const int count = pbsc->bsc_abpoPolygons.sa_Count; + for (i = 0; i < count; i++, itbpo++) { // if its bbox has no contact with bbox of movement path, or it is passable - if (!itbpo->bpo_boxBoundingBox.HasContactWith(cm_boxMovementPath) - ||(itbpo->bpo_ulFlags&BPOF_PASSABLE)) { + __builtin_prefetch(&itbpo[1].bpo_ulFlags); + if ((itbpo->bpo_ulFlags&BPOF_PASSABLE) + ||!itbpo->bpo_boxBoundingBox.HasContactWith(cm_boxMovementPath)) { // skip it continue; } @@ -893,7 +914,7 @@ void CClipMove::ClipToTerrain(CEntity *pen) CTerrain &tr = *pen->en_ptrTerrain; GFXVertex4 *pavVertices; - INDEX *paiIndices; + INDEX_T *paiIndices; INDEX ctVertices,ctIndices; FLOAT3D vMin = cm_boxMovementPath.Min(); @@ -920,9 +941,9 @@ void CClipMove::ClipToTerrain(CEntity *pen) // for each triangle for(INDEX iTri=0;iTri -#pragma GCC optimize 0 +//#pragma GCC optimize 0 #include #include #include @@ -47,15 +47,27 @@ static inline void BoxToGrid( FLOAT fMinZ = boxEntity.Min()(3); FLOAT fMaxX = boxEntity.Max()(1); FLOAT fMaxZ = boxEntity.Max()(3); - iMinX = (isinf(fMinX))?INDEX(GRID_MIN):INDEX(floor(fMinX/GRID_CELLSIZE)); - iMinZ = (isinf(fMinZ))?INDEX(GRID_MIN):INDEX(floor(fMinZ/GRID_CELLSIZE)); - iMaxX = (isinf(fMaxX))?INDEX(GRID_MIN):INDEX(ceil(fMaxX/GRID_CELLSIZE)); - iMaxZ = (isinf(fMaxZ))?INDEX(GRID_MIN):INDEX(ceil(fMaxZ/GRID_CELLSIZE)); +#if !defined(__i386__) && !defined(__x86_64__) +#if defined(PLATFORM_PANDORA) || defined(PLATFORM_PYRA) + #define Isinf(a) (((*(unsigned int*)&a)&0x7fffffff)==0x7f800000) +#else + #define Isinf isinff +#endif + iMinX = (Isinf(fMinX))?INDEX(GRID_MIN):Clamp(INDEX(floor(fMinX/GRID_CELLSIZE)), (INDEX)GRID_MIN, (INDEX)GRID_MAX); + iMinZ = (Isinf(fMinZ))?INDEX(GRID_MIN):Clamp(INDEX(floor(fMinZ/GRID_CELLSIZE)), (INDEX)GRID_MIN, (INDEX)GRID_MAX); + iMaxX = (Isinf(fMaxX))?INDEX(GRID_MIN):Clamp(INDEX(ceil(fMaxX/GRID_CELLSIZE)), (INDEX)GRID_MIN, (INDEX)GRID_MAX); + iMaxZ = (Isinf(fMaxZ))?INDEX(GRID_MIN):Clamp(INDEX(ceil(fMaxZ/GRID_CELLSIZE)), (INDEX)GRID_MIN, (INDEX)GRID_MAX); +#else + iMinX = INDEX(floor(fMinX/GRID_CELLSIZE)); + iMinZ = INDEX(floor(fMinZ/GRID_CELLSIZE)); + iMaxX = INDEX(ceil(fMaxX/GRID_CELLSIZE)); + iMaxZ = INDEX(ceil(fMaxZ/GRID_CELLSIZE)); iMinX = Clamp(iMinX, (INDEX)GRID_MIN, (INDEX)GRID_MAX); iMinZ = Clamp(iMinZ, (INDEX)GRID_MIN, (INDEX)GRID_MAX); iMaxX = Clamp(iMaxX, (INDEX)GRID_MIN, (INDEX)GRID_MAX); iMaxZ = Clamp(iMaxZ, (INDEX)GRID_MIN, (INDEX)GRID_MAX); +#endif } // key calculations diff --git a/Sources/Engine/World/WorldIO.cpp b/Sources/Engine/World/WorldIO.cpp index a2c69833d..19a372227 100644 --- a/Sources/Engine/World/WorldIO.cpp +++ b/Sources/Engine/World/WorldIO.cpp @@ -197,7 +197,7 @@ void CWorld::ReadBrushes_t( CTStream *istrm)// throw char * wo_baBrushes.Read_t(istrm); CallProgressHook_t(1.0f); - // if there are some terrais in world + // if there are some terrains in world if(istrm->PeekID_t()==CChunkID("TRAR")) { // 'terrain archive' SetProgressDescription(TRANS("loading terrains")); CallProgressHook_t(0.0f); diff --git a/Sources/Engine/World/WorldRayCasting.cpp b/Sources/Engine/World/WorldRayCasting.cpp index 82bec484b..3c158e916 100644 --- a/Sources/Engine/World/WorldRayCasting.cpp +++ b/Sources/Engine/World/WorldRayCasting.cpp @@ -470,9 +470,15 @@ void CCastRay::TestBrushSector(CBrushSector *pbscSector) // don't cast ray return; } + + const CEntity *l_cr_penOrigin = cr_penOrigin; + // for each polygon in the sector - FOREACHINSTATICARRAY(pbscSector->bsc_abpoPolygons, CBrushPolygon, itpoPolygon) { - CBrushPolygon &bpoPolygon = itpoPolygon.Current(); + // FOREACHINSTATICARRAY(pbscSector->bsc_abpoPolygons, CBrushPolygon, itpoPolygon) { + CBrushPolygon *itpoPolygon = pbscSector->bsc_abpoPolygons.sa_Array; + int i; + for (i = 0; i < pbscSector->bsc_abpoPolygons.sa_Count; i++, itpoPolygon++) { + CBrushPolygon &bpoPolygon = *itpoPolygon; if (&bpoPolygon==cr_pbpoIgnore) { continue; @@ -480,7 +486,7 @@ void CCastRay::TestBrushSector(CBrushSector *pbscSector) ULONG ulFlags = bpoPolygon.bpo_ulFlags; // if not testing recursively - if (cr_penOrigin==NULL) { + if (l_cr_penOrigin==NULL) { // if the polygon is portal if (ulFlags&BPOF_PORTAL) { // if it is translucent or selected @@ -506,13 +512,34 @@ void CCastRay::TestBrushSector(CBrushSector *pbscSector) continue; } } +#if defined __ARM_NEON__ && !defined PLATFORM_MACOSX // get distances of ray points from the polygon plane + register FLOAT fDistance0 __asm__("s0") = bpoPolygon.bpo_pbplPlane->bpl_plAbsolute.PointDistance(cr_vOrigin); + register FLOAT fDistance1 __asm__("s2") = bpoPolygon.bpo_pbplPlane->bpl_plAbsolute.PointDistance(cr_vTarget); + FLOAT fFraction; + int gege; + __asm__ __volatile__ ( + "vcge.f32 d2, d0, #0\n" + "vcge.f32 d3, d0, d1\n" + "vand d2, d3\n" + "ldr %[gege], %[nnpptr]\n" // take the cache miss, slight chance of a crash + "pld %[nplane]\n" + "vmov %[gege], d2[0]\n" + : [gege] "=&r"(gege) + : [nnpptr] "m"(itpoPolygon[2].bpo_pbplPlane), + [nplane] "m"(*itpoPolygon[1].bpo_pbplPlane), + "t"(fDistance0), "t"(fDistance1) + : "d2", "d3" + ); + + if (gege) { +#else FLOAT fDistance0 = bpoPolygon.bpo_pbplPlane->bpl_plAbsolute.PointDistance(cr_vOrigin); FLOAT fDistance1 = bpoPolygon.bpo_pbplPlane->bpl_plAbsolute.PointDistance(cr_vTarget); - // if the ray hits the polygon plane if (fDistance0>=0 && fDistance0>=fDistance1) { // calculate fraction of line before intersection +#endif FLOAT fFraction = fDistance0/((fDistance0-fDistance1) + 0.0000001f/*correction*/); // calculate intersection coordinate FLOAT3D vHitPoint = cr_vOrigin+(cr_vTarget-cr_vOrigin)*fFraction; diff --git a/Sources/EngineGui/EngineGUI.cpp b/Sources/EngineGui/EngineGUI.cpp index 18026008b..17b2dce1f 100644 --- a/Sources/EngineGui/EngineGUI.cpp +++ b/Sources/EngineGui/EngineGUI.cpp @@ -154,7 +154,7 @@ CTFileName CEngineGUI::CreateTexture(CTFileName fnTexFileToRecreate/*=CTString(" CDlgChooseTextureType dlgChooseTextureType; int iDlgResult = dlgChooseTextureType.DoModal(); // if user choosed a texture type - if( (iDlgResult != -1) && (iDlgResult >= 0) && (iDlgResult <= 2) ) + if( (iDlgResult >= 0) && (iDlgResult <= 2) ) { // if result is 2 we want to create effect texture if( iDlgResult == 2) diff --git a/Sources/Entities/BloodSpray.es b/Sources/Entities/BloodSpray.es index 2f27e9252..cf6ed0c7c 100644 --- a/Sources/Entities/BloodSpray.es +++ b/Sources/Entities/BloodSpray.es @@ -22,7 +22,7 @@ event ESpawnSpray { enum SprayParticlesType sptType, // type of particles FLOAT fDamagePower, // factor saying how powerfull damage has been FLOAT fSizeMultiplier, // stretch factor - FLOAT3D vDirection, // dammage direction + FLOAT3D vDirection, // damage direction CEntityPointer penOwner, // who spawned the spray }; @@ -35,7 +35,7 @@ properties: 1 enum SprayParticlesType m_sptType = SPT_NONE, // type of particles 2 FLOAT m_tmStarted = 0.0f, // time when spawned - 3 FLOAT3D m_vDirection = FLOAT3D(0,0,0), // dammage direction + 3 FLOAT3D m_vDirection = FLOAT3D(0,0,0), // damage direction 5 CEntityPointer m_penOwner, // who spawned the spray 6 FLOAT m_fDamagePower = 1.0f, // power of inflicted damage 8 FLOATaabbox3D m_boxOwner = FLOATaabbox3D(FLOAT3D(0,0,0), 0.01f), // bounding box of blood spray's owner diff --git a/Sources/Entities/Camera.es b/Sources/Entities/Camera.es index aa547bba8..afb5b57af 100644 --- a/Sources/Entities/Camera.es +++ b/Sources/Entities/Camera.es @@ -391,10 +391,8 @@ procedures: // determine camera type and jump to corresponding routine PlayCamera() { - // eventually add to movers list - CCameraMarker &cm = (CCameraMarker&)*m_penTarget; // if we have at least one marker - if( &cm!=NULL) { + if( m_penTarget!=NULL) { // treat camera as movable jump PlayMovingCamera(); // if there isn't any markers diff --git a/Sources/Entities/Common/Common.h b/Sources/Entities/Common/Common.h index 14fc1f323..9733306ce 100644 --- a/Sources/Entities/Common/Common.h +++ b/Sources/Entities/Common/Common.h @@ -1,215 +1,228 @@ -// common headers for flesh entity classes - -#include /* rcg10062001 need enum definition... */ -#include /* rcg10062001 need enum definition... */ - -#define SURFACE_SAND 9 -#define SURFACE_WATER 12 -#define SURFACE_RED_SAND 13 - -// Max ammo -#define MAX_BULLETS INDEX(500) -#define MAX_SHELLS INDEX(100) -#define MAX_ROCKETS INDEX(50) -#define MAX_GRENADES INDEX(50) -//#define MAX_NAPALM INDEX(250) -#define MAX_ELECTRICITY INDEX(400) -#define MAX_IRONBALLS INDEX(30) -//#define MAX_NUKEBALLS INDEX(3) - -// Bit shifters for ammo -#define AMMO_BULLETS 0 -#define AMMO_SHELLS 1 -#define AMMO_ROCKETS 2 -#define AMMO_GRENADES 3 -//#define AMMO_NAPALM 4 -#define AMMO_ELECTRICITY 5 -//#define AMMO_NUKEBALLS 6 -#define AMMO_IRONBALLS 7 - - -// Ammo mana Value -#define AV_SHELLS INDEX(70) -#define AV_BULLETS INDEX(10) -#define AV_ROCKETS INDEX(150) -#define AV_GRENADES INDEX(150) -#define AV_ELECTRICITY INDEX(250) -#define AV_IRONBALLS INDEX(700) -//#define AV_NUKEBALLS INDEX(1800) -//#define AV_NAPALM INDEX(200) - -enum EmptyShellType { - ESL_BULLET = 0, - ESL_SHOTGUN = 1, - ESL_BUBBLE = 2, - ESL_BULLET_SMOKE = 3, - ESL_SHOTGUN_SMOKE = 4, - ESL_COLT_SMOKE = 5, -}; -// empty shell launch info -#define MAX_FLYING_SHELLS 32 -struct ShellLaunchData { - FLOAT sld_fSize; // size multiplier - FLOAT3D sld_vPos; // launch position - FLOAT3D sld_vSpeed; // launch speed - FLOAT3D sld_vUp; // up vector in moment of launch - FLOAT sld_tmLaunch; // time of launch - EmptyShellType sld_estType; // shell type -}; -#define ShellLaunchData_array m_asldData[MAX_FLYING_SHELLS] - -// world change -struct WorldChange { - CTString strGroup; // group name - CPlacement3D plLink; // link placement for relative change - INDEX iType; // change type -}; -extern struct WorldChange _SwcWorldChange; - -// entity info -struct EntityInfo { - EntityInfoBodyType Eeibt; // body type - FLOAT fMass; // mass (in kg) - FLOAT vSourceCenter[3]; // body point (offset from handle) when entity look another entity - FLOAT vTargetCenter[3]; // body point (offset from handle) when entity is target of look -}; - -// entity info -struct EntityStats { - CTString es_strName; - INDEX es_ctCount; - INDEX es_ctAmmount; - FLOAT es_fValue; - INDEX es_iScore; - inline void Clear() { es_strName.Clear(); } -}; - -// statistics data for player stats management -struct DECL_DLL PlayerStats { - INDEX ps_iScore; - INDEX ps_iKills; - INDEX ps_iDeaths; - INDEX ps_iSecrets; - TIME ps_tmTime; - - PlayerStats(void) - { - ps_iScore = 0; - ps_iKills = 0; - ps_iDeaths = 0; - ps_iSecrets = 0; - ps_tmTime = 0.0f; - } -}; - -// get info position for entity -DECL_DLL void GetEntityInfoPosition(CEntity *pen, FLOAT *pf, FLOAT3D &vPos); -// get source and target positions for ray cast -DECL_DLL void GetPositionCastRay(CEntity *penSource, CEntity *penTarget, FLOAT3D &vSource, FLOAT3D &vTarget); - -// set bool from bool enum type -DECL_DLL void SetBoolFromBoolEType(BOOL &bSet, BoolEType bet); -// send event to target -DECL_DLL void SendToTarget(CEntity *penSendEvent, EventEType eetEventType, CEntity *penCaused = NULL); -// send event in range -DECL_DLL void SendInRange(CEntity *penSource, EventEType eetEventType, const FLOATaabbox3D &boxRange); - -// spawn reminder -DECL_DLL CEntityPointer SpawnReminder(CEntity *penOwner, FLOAT fWaitTime, INDEX iValue); -// spawn flame -//CEntityPointer SpawnFlame(CEntity *penOwner, CEntity *penAttach, const FLOAT3D &vSource); - -// Set components -DECL_DLL void SetComponents(CEntity *pen, CModelObject &mo, ULONG ulIDModel, ULONG ulIDTexture, - ULONG ulIDReflectionTexture, ULONG ulIDSpecularTexture, ULONG ulIDBumpTexture); -// Add attachment to model -DECL_DLL void AddAttachmentToModel(CEntity *pen, CModelObject &mo, INDEX iAttachment, ULONG ulIDModel, ULONG ulIDTexture, - ULONG ulIDReflectionTexture, ULONG ulIDSpecularTexture, ULONG ulIDBumpTexture); -// Remove attachment from model -DECL_DLL void RemoveAttachmentFromModel(CModelObject &mo, INDEX iAttachment); - -// Kick entity -DECL_DLL void KickEntity(CEntity *penTarget, FLOAT3D vSpeed); - - -// lens flare variables -extern CLensFlareType _lftStandard; -extern CLensFlareType _lftStandardReflections; -extern CLensFlareType _lftYellowStarRedRing; -extern CLensFlareType _lftYellowStarRedRingFar; -extern CLensFlareType _lftWhiteGlowStarRedRing; -extern CLensFlareType _lftWhiteGlowStar; -extern CLensFlareType _lftWhiteGlowStarNG; -extern CLensFlareType _lftWhiteStarRedRingStreaks; -extern CLensFlareType _lftWhiteStarRedReflections; -extern CLensFlareType _lftBlueStarBlueReflections; -extern CLensFlareType _lftProjectileStarGlow; -extern CLensFlareType _lftProjectileWhiteBubbleGlow; -extern CLensFlareType _lftProjectileYellowBubbleGlow; -extern CLensFlareType _lftPVSpaceShipWindowFlare; -extern CLensFlareType _lftCatmanFireGlow; -extern CLensFlareType _lftWhiteGlowFar; -// init lens flare effects -void InitLensFlares(void); -// close lens flares effects -void CloseLensFlares(void); - -DECL_DLL BOOL SetPlayerAppearance(CModelObject *mo, CPlayerCharacter *ppc, CTString &strName, BOOL bPreview); - -// debugging functions -DECL_DLL const char *PrintConsole(void); -DECL_DLL const char *PrintStack(CEntity *pen); - -// debris spawning -DECL_DLL void Debris_Begin( - EntityInfoBodyType Eeibt, - enum DebrisParticlesType dptParticles, - enum BasicEffectType betStain, - FLOAT fEntitySize, // entity size in meters - const FLOAT3D &vSpeed, - const FLOAT3D &vSpawnerSpeed, // how fast was the entity moving - const FLOAT fConeSize, // size multiplier for debris cone - const FLOAT fSpeedUp, // size multiplier for debris catapulting up (0-no multiply) - const COLOR colDebris=C_WHITE // multiply color -); -DECL_DLL CEntityPointer Debris_Spawn( - CEntity *penSpawner, - CEntity *penComponents, - SLONG idModelComponent, - SLONG idTextureComponent, - SLONG idReflectionTextureComponent, - SLONG idSpecularTextureComponent, - SLONG idBumpTextureComponent, - INDEX iModelAnim, - FLOAT fSize, // size relative to entity size (or 0 for absolute stretch of 1) - const FLOAT3D &vPosRatio); - -// get default entity info for given body type -DECL_DLL EntityInfo *GetStdEntityInfo(EntityInfoBodyType eibt); -// damage control functions -DECL_DLL FLOAT DamageStrength(EntityInfoBodyType eibtBody, enum DamageType dtDamage); - -// Print center screen message -DECL_DLL void PrintCenterMessage(CEntity *penThis, CEntity *penTarget, - const CTString &strMessage, TIME tmLength, enum MessageSound mssSound); - -// get name of a key item -DECL_DLL const char *GetKeyName(enum KeyItemType kit); - -// get session properties -DECL_DLL inline const CSessionProperties *GetSP(void) -{ - return ((const CSessionProperties *)_pNetwork->GetSessionProperties()); -} - -// i.e. weapon sound when fireing or exploding -DECL_DLL void SpawnRangeSound( CEntity *penPlayer, CEntity *penPos, enum SoundType st, FLOAT fRange); - -// get some player for trigger source if any is existing -DECL_DLL CEntity *FixupCausedToPlayer(CEntity *penThis, CEntity *penCaused, BOOL bWarning=TRUE); - -// precisely lerp between two placement using quaternions -DECL_DLL CPlacement3D LerpPlacementsPrecise(const CPlacement3D &pl0, const CPlacement3D &pl1, FLOAT fRatio); - -// obtain game extra damage per enemy and per player -DECL_DLL FLOAT GetGameDamageMultiplier(void); +// common headers for flesh entity classes + +#include /* rcg10062001 need enum definition... */ +#include /* rcg10062001 need enum definition... */ + +#define SURFACE_SAND 9 +#define SURFACE_WATER 12 +#define SURFACE_RED_SAND 13 + +// Max ammo +#define MAX_BULLETS INDEX(500) +#define MAX_SHELLS INDEX(100) +#define MAX_ROCKETS INDEX(50) +#define MAX_GRENADES INDEX(50) +//#define MAX_NAPALM INDEX(250) +#define MAX_ELECTRICITY INDEX(400) +#define MAX_IRONBALLS INDEX(30) +//#define MAX_NUKEBALLS INDEX(3) + +// Bit shifters for ammo +#define AMMO_BULLETS 0 +#define AMMO_SHELLS 1 +#define AMMO_ROCKETS 2 +#define AMMO_GRENADES 3 +//#define AMMO_NAPALM 4 +#define AMMO_ELECTRICITY 5 +//#define AMMO_NUKEBALLS 6 +#define AMMO_IRONBALLS 7 + + +// Ammo mana Value +#define AV_SHELLS INDEX(70) +#define AV_BULLETS INDEX(10) +#define AV_ROCKETS INDEX(150) +#define AV_GRENADES INDEX(150) +#define AV_ELECTRICITY INDEX(250) +#define AV_IRONBALLS INDEX(700) +//#define AV_NUKEBALLS INDEX(1800) +//#define AV_NAPALM INDEX(200) + +enum EmptyShellType { + ESL_BULLET = 0, + ESL_SHOTGUN = 1, + ESL_BUBBLE = 2, + ESL_BULLET_SMOKE = 3, + ESL_SHOTGUN_SMOKE = 4, + ESL_COLT_SMOKE = 5, +}; +// empty shell launch info +#define MAX_FLYING_SHELLS 32 +struct ShellLaunchData { + FLOAT sld_fSize; // size multiplier + FLOAT3D sld_vPos; // launch position + FLOAT3D sld_vSpeed; // launch speed + FLOAT3D sld_vUp; // up vector in moment of launch + FLOAT sld_tmLaunch; // time of launch + EmptyShellType sld_estType; // shell type +}; +#define ShellLaunchData_array m_asldData[MAX_FLYING_SHELLS] + +// world change +struct WorldChange { + CTString strGroup; // group name + CPlacement3D plLink; // link placement for relative change + INDEX iType; // change type +}; +extern struct WorldChange _SwcWorldChange; + +// entity info +struct EntityInfo { + EntityInfoBodyType Eeibt; // body type + FLOAT fMass; // mass (in kg) + FLOAT vSourceCenter[3]; // body point (offset from handle) when entity look another entity + FLOAT vTargetCenter[3]; // body point (offset from handle) when entity is target of look +}; + +// entity info +struct EntityStats { + CTString es_strName; + INDEX es_ctCount; + INDEX es_ctAmmount; + FLOAT es_fValue; + INDEX es_iScore; + inline void Clear() { es_strName.Clear(); } +}; + +// statistics data for player stats management +struct DECL_DLL PlayerStats { + INDEX ps_iScore; + INDEX ps_iKills; + INDEX ps_iDeaths; + INDEX ps_iSecrets; + TIME ps_tmTime; + + PlayerStats(void): ps_iScore(0), ps_iKills(0), ps_iDeaths(0), ps_iSecrets(0), ps_tmTime(0.0f){} +}; + +static inline CTStream &operator>>(CTStream &strm, PlayerStats &ps) +{ + strm>>ps.ps_iScore; + strm>>ps.ps_iKills; + strm>>ps.ps_iDeaths; + strm>>ps.ps_iSecrets; + strm>>ps.ps_tmTime; + return strm; +} + +static inline CTStream &operator<<(CTStream &strm, const PlayerStats &ps) +{ + strm<GetSessionProperties()); +} + +// i.e. weapon sound when fireing or exploding +DECL_DLL void SpawnRangeSound( CEntity *penPlayer, CEntity *penPos, enum SoundType st, FLOAT fRange); + +// get some player for trigger source if any is existing +DECL_DLL CEntity *FixupCausedToPlayer(CEntity *penThis, CEntity *penCaused, BOOL bWarning=TRUE); + +// precisely lerp between two placement using quaternions +DECL_DLL CPlacement3D LerpPlacementsPrecise(const CPlacement3D &pl0, const CPlacement3D &pl1, FLOAT fRatio); + +// obtain game extra damage per enemy and per player +DECL_DLL FLOAT GetGameDamageMultiplier(void); diff --git a/Sources/Entities/Common/HUD.cpp b/Sources/Entities/Common/HUD.cpp index a776e57de..fd1db27bd 100644 --- a/Sources/Entities/Common/HUD.cpp +++ b/Sources/Entities/Common/HUD.cpp @@ -1,1108 +1,1108 @@ - -#include "../StdH/StdH.h" - -#include -#include -#include -#include -#include -#include - - -// armor & health constants -// NOTE: these _do not_ reflect easy/tourist maxvalue adjustments. that is by design! -#define TOP_ARMOR 100 -#define TOP_HEALTH 100 - - -// cheats -extern INDEX cht_bEnable; -extern INDEX cht_bGod; -extern INDEX cht_bFly; -extern INDEX cht_bGhost; -extern INDEX cht_bInvisible; -extern FLOAT cht_fTranslationMultiplier; - -// interface control -extern INDEX hud_bShowInfo; -extern INDEX hud_bShowLatency; -extern INDEX hud_bShowMessages; -extern INDEX hud_iShowPlayers; -extern INDEX hud_iSortPlayers; -extern FLOAT hud_fOpacity; -extern FLOAT hud_fScaling; -extern FLOAT hud_tmWeaponsOnScreen; - - -// player statistics sorting keys -enum SortKeys { - PSK_NAME = 1, - PSK_HEALTH = 2, - PSK_SCORE = 3, - PSK_MANA = 4, - PSK_FRAGS = 5, - PSK_DEATHS = 6, -}; - -// where is the bar lowest value -enum BarOrientations { - BO_LEFT = 1, - BO_RIGHT = 2, - BO_UP = 3, - BO_DOWN = 4, -}; - - - -// maximal mana for master status -#define MANA_MASTER 10000 - -// drawing variables -static const CPlayer *_penPlayer; -static CPlayerWeapons *_penWeapons; -static CDrawPort *_pDP; -static PIX _pixDPWidth, _pixDPHeight; -static FLOAT _fResolutionScaling; -static FLOAT _fCustomScaling; -static ULONG _ulAlphaHUD; -static COLOR _colHUD; -static TIME _tmNow = -1.0f; -static CFontData _fdNumbersFont; - -// array for pointers of all players -CPlayer *_apenPlayers[NET_MAXGAMEPLAYERS] = {0}; - -// status bar textures -static CTextureObject _toHealth; -static CTextureObject _toArmor; -static CTextureObject _toOxygen; -static CTextureObject _toScore; -static CTextureObject _toHiScore; -static CTextureObject _toMessage; -static CTextureObject _toMana; -static CTextureObject _toFrags; -static CTextureObject _toDeaths; -// ammo textures -static CTextureObject _toAShells; -static CTextureObject _toABullets; -static CTextureObject _toARockets; -static CTextureObject _toAGrenades; -static CTextureObject _toANapalm; -static CTextureObject _toAElectricity; -static CTextureObject _toAIronBall; -// weapon textures -static CTextureObject _toWKnife; -static CTextureObject _toWColt; -static CTextureObject _toWSingleShotgun; -static CTextureObject _toWDoubleShotgun; -static CTextureObject _toWTommygun; -static CTextureObject _toWMinigun; -static CTextureObject _toWRocketLauncher; -static CTextureObject _toWGrenadeLauncher; -static CTextureObject _toWPipeBomb; -static CTextureObject _toWFlamer; -static CTextureObject _toWGhostBuster; -static CTextureObject _toWLaser; -static CTextureObject _toWIronCannon; -// tile texture (one has corners, edges and center) -static CTextureObject _toTile; - - -// all info about color transitions -struct ColorTransitionTable { - COLOR ctt_colFine; // color for values over 1.0 - COLOR ctt_colHigh; // color for values from 1.0 to 'fMedium' - COLOR ctt_colMedium; // color for values from 'fMedium' to 'fLow' - COLOR ctt_colLow; // color for values under fLow - FLOAT ctt_fMediumHigh; // when to switch to high color (normalized float!) - FLOAT ctt_fLowMedium; // when to switch to medium color (normalized float!) - BOOL ctt_bSmooth; // should colors have smooth transition -}; -static struct ColorTransitionTable _cttHUD; - - -// ammo's info structure -struct AmmoInfo { - CTextureObject *ai_ptoAmmo; - struct WeaponInfo *ai_pwiWeapon1; - struct WeaponInfo *ai_pwiWeapon2; - INDEX ai_iAmmoAmmount; - INDEX ai_iMaxAmmoAmmount; - INDEX ai_iLastAmmoAmmount; - TIME ai_tmAmmoChanged; - BOOL ai_bHasWeapon; -}; - -// weapons' info structure -struct WeaponInfo { - enum WeaponType wi_wtWeapon; - CTextureObject *wi_ptoWeapon; - struct AmmoInfo *wi_paiAmmo; - BOOL wi_bHasWeapon; -}; - -extern struct WeaponInfo _awiWeapons[18]; -static struct AmmoInfo _aaiAmmo[8] = { - { &_toAShells, &_awiWeapons[4], &_awiWeapons[5], 0, 0, 0, -9, FALSE }, - { &_toABullets, &_awiWeapons[6], &_awiWeapons[7], 0, 0, 0, -9, FALSE }, - { &_toARockets, &_awiWeapons[8], NULL, 0, 0, 0, -9, FALSE }, - { &_toAGrenades, &_awiWeapons[9], &_awiWeapons[10], 0, 0, 0, -9, FALSE }, - { &_toANapalm, &_awiWeapons[12], NULL, 0, 0, 0, -9, FALSE }, - { &_toAElectricity, &_awiWeapons[14], &_awiWeapons[15], 0, 0, 0, -9, FALSE }, - { &_toAIronBall, &_awiWeapons[16], NULL, 0, 0, 0, -9, FALSE }, - { &_toAIronBall, &_awiWeapons[17], NULL, 0, 0, 0, -9, FALSE }, -}; - -struct WeaponInfo _awiWeapons[18] = { - { WEAPON_NONE, NULL, NULL, FALSE }, // 0 - { WEAPON_KNIFE, &_toWKnife, NULL, FALSE }, // 1 - { WEAPON_COLT, &_toWColt, NULL, FALSE }, // 2 - { WEAPON_DOUBLECOLT, &_toWColt, NULL, FALSE }, // 3 - { WEAPON_SINGLESHOTGUN, &_toWSingleShotgun, &_aaiAmmo[0], FALSE }, // 4 - { WEAPON_DOUBLESHOTGUN, &_toWDoubleShotgun, &_aaiAmmo[0], FALSE }, // 5 - { WEAPON_TOMMYGUN, &_toWTommygun, &_aaiAmmo[1], FALSE }, // 6 - { WEAPON_MINIGUN, &_toWMinigun, &_aaiAmmo[1], FALSE }, // 7 - { WEAPON_ROCKETLAUNCHER, &_toWRocketLauncher, &_aaiAmmo[2], FALSE }, // 8 - { WEAPON_GRENADELAUNCHER, &_toWGrenadeLauncher, &_aaiAmmo[3], FALSE }, // 9 - { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_PIPEBOMB, &_toWPipeBomb, &_aaiAmmo[3], FALSE }, // 10 - { WEAPON_NONE, NULL, NULL, FALSE }, // 11 - { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_FLAMER, &_toWFlamer, &_aaiAmmo[4], FALSE }, // 12 - { WEAPON_NONE, NULL, NULL, FALSE }, // 13 - { WEAPON_LASER, &_toWLaser, &_aaiAmmo[5], FALSE }, // 14 - { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_GHOSTBUSTER, &_toWGhostBuster, &_aaiAmmo[5], FALSE }, // 15 - { WEAPON_IRONCANNON, &_toWIronCannon, &_aaiAmmo[6], FALSE }, // 16 - { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_NUKECANNON, &_toWNukeCannon, &_aaiAmmo[7], FALSE }, // 17 -}; - - -// compare functions for qsort() -static int qsort_CompareNames( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - CTString strName0 = en0.GetPlayerName(); - CTString strName1 = en1.GetPlayerName(); - return strnicmp( strName0, strName1, 8); -} - -static int qsort_CompareScores( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = en0.m_psGameStats.ps_iScore; - SLONG sl1 = en1.m_psGameStats.ps_iScore; - if( sl0sl1) return -1; - else return 0; -} - -static int qsort_CompareHealth( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = (SLONG)ceil(en0.GetHealth()); - SLONG sl1 = (SLONG)ceil(en1.GetHealth()); - if( sl0sl1) return -1; - else return 0; -} - -static int qsort_CompareManas( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = en0.m_iMana; - SLONG sl1 = en1.m_iMana; - if( sl0sl1) return -1; - else return 0; -} - -static int qsort_CompareFrags( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = en0.m_psGameStats.ps_iKills; - SLONG sl1 = en1.m_psGameStats.ps_iKills; - if( sl0sl1) return -1; - else return 0; -} - -static int qsort_CompareDeaths( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = en0.m_psGameStats.ps_iDeaths; - SLONG sl1 = en1.m_psGameStats.ps_iDeaths; - if( sl0sl1) return -1; - else return 0; -} - -#if 0 // DG: unused -static int qsort_CompareLatencies( const void *ppPEN0, const void *ppPEN1) { - CPlayer &en0 = **(CPlayer**)ppPEN0; - CPlayer &en1 = **(CPlayer**)ppPEN1; - SLONG sl0 = (SLONG)ceil(en0.m_tmLatency); - SLONG sl1 = (SLONG)ceil(en1.m_tmLatency); - if( sl0sl1) return -1; - else return 0; -} -#endif // 0 (unused) - -// prepare color transitions -static void PrepareColorTransitions( COLOR colFine, COLOR colHigh, COLOR colMedium, COLOR colLow, - FLOAT fMediumHigh, FLOAT fLowMedium, BOOL bSmooth) -{ - _cttHUD.ctt_colFine = colFine; - _cttHUD.ctt_colHigh = colHigh; - _cttHUD.ctt_colMedium = colMedium; - _cttHUD.ctt_colLow = colLow; - _cttHUD.ctt_fMediumHigh = fMediumHigh; - _cttHUD.ctt_fLowMedium = fLowMedium; - _cttHUD.ctt_bSmooth = bSmooth; -} - - - -// calculates shake ammount and color value depanding on value change -#define SHAKE_TIME (2.0f) -static COLOR AddShaker( PIX const pixAmmount, INDEX const iCurrentValue, INDEX &iLastValue, - TIME &tmChanged, FLOAT &fMoverX, FLOAT &fMoverY) -{ - // update shaking if needed - fMoverX = fMoverY = 0.0f; - const TIME tmNow = _pTimer->GetLerpedCurrentTick(); - if( iCurrentValue != iLastValue) { - iLastValue = iCurrentValue; - tmChanged = tmNow; - } else { - // in case of loading (timer got reseted) - tmChanged = ClampUp( tmChanged, tmNow); - } - - // no shaker? - const TIME tmDelta = tmNow - tmChanged; - if( tmDelta > SHAKE_TIME) return NONE; - ASSERT( tmDelta>=0); - // shake, baby shake! - const FLOAT fAmmount = _fResolutionScaling * _fCustomScaling * pixAmmount; - const FLOAT fMultiplier = (SHAKE_TIME-tmDelta)/SHAKE_TIME *fAmmount; - const INDEX iRandomizer = (INDEX)(tmNow*511.0f)*fAmmount*iCurrentValue; - const FLOAT fNormRnd1 = (FLOAT)((iRandomizer ^ (iRandomizer>>9)) & 1023) * 0.0009775f; // 1/1023 - normalized - const FLOAT fNormRnd2 = (FLOAT)((iRandomizer ^ (iRandomizer>>7)) & 1023) * 0.0009775f; // 1/1023 - normalized - fMoverX = (fNormRnd1 -0.5f) * fMultiplier; - fMoverY = (fNormRnd2 -0.5f) * fMultiplier; - // clamp to adjusted ammount (pixels relative to resolution and HUD scale - fMoverX = Clamp( fMoverX, -fAmmount, fAmmount); - fMoverY = Clamp( fMoverY, -fAmmount, fAmmount); - if( tmDelta < SHAKE_TIME/3) return C_WHITE; - else return NONE; -//return FloatToInt(tmDelta*4) & 1 ? C_WHITE : NONE; -} - - -// get current color from local color transitions table -static COLOR GetCurrentColor( FLOAT fNormalizedValue) -{ - // if value is in 'low' zone just return plain 'low' alert color - if( fNormalizedValue < _cttHUD.ctt_fLowMedium) return( _cttHUD.ctt_colLow & 0xFFFFFF00); - // if value is in out of 'extreme' zone just return 'extreme' color - if( fNormalizedValue > 1.0f) return( _cttHUD.ctt_colFine & 0xFFFFFF00); - - COLOR col; - // should blend colors? - if( _cttHUD.ctt_bSmooth) - { // lets do some interpolations - FLOAT fd, f1, f2; - COLOR col1, col2; - UBYTE ubH,ubS,ubV, ubH2,ubS2,ubV2; - // determine two colors for interpolation - if( fNormalizedValue > _cttHUD.ctt_fMediumHigh) { - f1 = 1.0f; - f2 = _cttHUD.ctt_fMediumHigh; - col1 = _cttHUD.ctt_colHigh; - col2 = _cttHUD.ctt_colMedium; - } else { // fNormalizedValue > _cttHUD.ctt_fLowMedium == TRUE ! - f1 = _cttHUD.ctt_fMediumHigh; - f2 = _cttHUD.ctt_fLowMedium; - col1 = _cttHUD.ctt_colMedium; - col2 = _cttHUD.ctt_colLow; - } - // determine interpolation strength - fd = (fNormalizedValue-f2) / (f1-f2); - // convert colors to HSV - ColorToHSV( col1, ubH, ubS, ubV); - ColorToHSV( col2, ubH2, ubS2, ubV2); - // interpolate H, S and V components - ubH = (UBYTE)(ubH*fd + ubH2*(1.0f-fd)); - ubS = (UBYTE)(ubS*fd + ubS2*(1.0f-fd)); - ubV = (UBYTE)(ubV*fd + ubV2*(1.0f-fd)); - // convert HSV back to COLOR - col = HSVToColor( ubH, ubS, ubV); - } - else - { // simple color picker - col = _cttHUD.ctt_colMedium; - if( fNormalizedValue > _cttHUD.ctt_fMediumHigh) col = _cttHUD.ctt_colHigh; - } - // all done - return( col & 0xFFFFFF00); -} - - - -// fill array with players' statistics (returns current number of players in game) -extern INDEX SetAllPlayersStats( INDEX iSortKey) -{ - // determine maximum number of players for this session - INDEX iPlayers = 0; - INDEX iMaxPlayers = _penPlayer->GetMaxPlayers(); - CPlayer *penCurrent; - // loop thru potentional players - for( INDEX i=0; iGetPlayerEntity(i); - if( penCurrent==NULL) continue; - // fill in player parameters - _apenPlayers[iPlayers] = penCurrent; - // advance to next real player - iPlayers++; - } - // sort statistics by some key if needed - switch( iSortKey) { - case PSK_NAME: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareNames); break; - case PSK_SCORE: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareScores); break; - case PSK_HEALTH: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareHealth); break; - case PSK_MANA: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareManas); break; - case PSK_FRAGS: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareFrags); break; - case PSK_DEATHS: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareDeaths); break; - default: break; // invalid or NONE key specified so do nothing - } - // all done - return iPlayers; -} - - - -// ----------------------- drawing functions - -// draw border with filter -static void HUD_DrawBorder( FLOAT fCenterX, FLOAT fCenterY, FLOAT fSizeX, FLOAT fSizeY, COLOR colTiles) -{ - // determine location - const FLOAT fCenterI = fCenterX*_pixDPWidth / 640.0f; - const FLOAT fCenterJ = fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment); - const FLOAT fSizeI = _fResolutionScaling*fSizeX; - const FLOAT fSizeJ = _fResolutionScaling*fSizeY; - const FLOAT fTileSize = 8*_fResolutionScaling*_fCustomScaling; - // determine exact positions - const FLOAT fLeft = fCenterI - fSizeI/2 -1; - const FLOAT fRight = fCenterI + fSizeI/2 +1; - const FLOAT fUp = fCenterJ - fSizeJ/2 -1; - const FLOAT fDown = fCenterJ + fSizeJ/2 +1; - const FLOAT fLeftEnd = fLeft + fTileSize; - const FLOAT fRightBeg = fRight - fTileSize; - const FLOAT fUpEnd = fUp + fTileSize; - const FLOAT fDownBeg = fDown - fTileSize; - // prepare texture - colTiles |= _ulAlphaHUD; - // put corners - _pDP->InitTexture( &_toTile, TRUE); // clamping on! - _pDP->AddTexture( fLeft, fUp, fLeftEnd, fUpEnd, colTiles); - _pDP->AddTexture( fRight,fUp, fRightBeg,fUpEnd, colTiles); - _pDP->AddTexture( fRight,fDown, fRightBeg,fDownBeg, colTiles); - _pDP->AddTexture( fLeft, fDown, fLeftEnd, fDownBeg, colTiles); - // put edges - _pDP->AddTexture( fLeftEnd,fUp, fRightBeg,fUpEnd, 0.4f,0.0f, 0.6f,1.0f, colTiles); - _pDP->AddTexture( fLeftEnd,fDown, fRightBeg,fDownBeg, 0.4f,0.0f, 0.6f,1.0f, colTiles); - _pDP->AddTexture( fLeft, fUpEnd, fLeftEnd, fDownBeg, 0.0f,0.4f, 1.0f,0.6f, colTiles); - _pDP->AddTexture( fRight, fUpEnd, fRightBeg,fDownBeg, 0.0f,0.4f, 1.0f,0.6f, colTiles); - // put center - _pDP->AddTexture( fLeftEnd, fUpEnd, fRightBeg, fDownBeg, 0.4f,0.4f, 0.6f,0.6f, colTiles); - _pDP->FlushRenderingQueue(); -} - - -// draw icon texture (if color = NONE, use colortransitions structure) -static void HUD_DrawIcon( FLOAT fCenterX, FLOAT fCenterY, CTextureObject &toIcon, - COLOR colDefault, FLOAT fNormValue, BOOL bBlink) -{ - // determine color - COLOR col = colDefault; - if( col==NONE) col = GetCurrentColor( fNormValue); - // determine blinking state - if( bBlink && fNormValue<=(_cttHUD.ctt_fLowMedium/2)) { - // activate blinking only if value is <= half the low edge - INDEX iCurrentTime = (INDEX)(_tmNow*4); - if( iCurrentTime&1) col = C_vdGRAY; - } - // determine location - const FLOAT fCenterI = fCenterX*_pixDPWidth / 640.0f; - const FLOAT fCenterJ = fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment); - // determine dimensions - CTextureData *ptd = (CTextureData*)toIcon.GetData(); - const FLOAT fHalfSizeI = _fResolutionScaling*_fCustomScaling * ptd->GetPixWidth() *0.5f; - const FLOAT fHalfSizeJ = _fResolutionScaling*_fCustomScaling * ptd->GetPixHeight() *0.5f; - // done - _pDP->InitTexture( &toIcon); - _pDP->AddTexture( fCenterI-fHalfSizeI, fCenterJ-fHalfSizeJ, - fCenterI+fHalfSizeI, fCenterJ+fHalfSizeJ, col|_ulAlphaHUD); - _pDP->FlushRenderingQueue(); -} - - -// draw text (or numbers, whatever) -static void HUD_DrawText( FLOAT fCenterX, FLOAT fCenterY, const CTString &strText, - COLOR colDefault, FLOAT fNormValue) -{ - // determine color - COLOR col = colDefault; - if( col==NONE) col = GetCurrentColor( fNormValue); - // determine location - PIX pixCenterI = (PIX)(fCenterX*_pixDPWidth / 640.0f); - PIX pixCenterJ = (PIX)(fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment)); - // done - _pDP->SetTextScaling( _fResolutionScaling*_fCustomScaling); - _pDP->PutTextCXY( strText, pixCenterI, pixCenterJ, col|_ulAlphaHUD); -} - - -// draw bar -static void HUD_DrawBar( FLOAT fCenterX, FLOAT fCenterY, PIX pixSizeX, PIX pixSizeY, - enum BarOrientations eBarOrientation, COLOR colDefault, FLOAT fNormValue) -{ - // determine color - COLOR col = colDefault; - if( col==NONE) col = GetCurrentColor( fNormValue); - // determine location and size - PIX pixCenterI = (PIX)(fCenterX*_pixDPWidth / 640.0f); - PIX pixCenterJ = (PIX)(fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment)); - PIX pixSizeI = (PIX)(_fResolutionScaling*pixSizeX); - PIX pixSizeJ = (PIX)(_fResolutionScaling*pixSizeY); - // fill bar background area - PIX pixLeft = pixCenterI-pixSizeI/2; - PIX pixUpper = pixCenterJ-pixSizeJ/2; - // determine bar position and inner size - switch( eBarOrientation) { - case BO_UP: - pixSizeJ *= fNormValue; - break; - case BO_DOWN: - pixUpper = pixUpper + (PIX)ceil(pixSizeJ * (1.0f-fNormValue)); - pixSizeJ *= fNormValue; - break; - case BO_LEFT: - pixSizeI *= fNormValue; - break; - case BO_RIGHT: - pixLeft = pixLeft + (PIX)ceil(pixSizeI * (1.0f-fNormValue)); - pixSizeI *= fNormValue; - break; - } - // done - _pDP->Fill( pixLeft, pixUpper, pixSizeI, pixSizeJ, col|_ulAlphaHUD); -} - - -// helper functions - -// fill weapon and ammo table with current state -static void FillWeaponAmmoTables(void) -{ - // ammo quantities - _aaiAmmo[0].ai_iAmmoAmmount = _penWeapons->m_iShells; - _aaiAmmo[0].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxShells; - _aaiAmmo[1].ai_iAmmoAmmount = _penWeapons->m_iBullets; - _aaiAmmo[1].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxBullets; - _aaiAmmo[2].ai_iAmmoAmmount = _penWeapons->m_iRockets; - _aaiAmmo[2].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxRockets; - _aaiAmmo[3].ai_iAmmoAmmount = _penWeapons->m_iGrenades; - _aaiAmmo[3].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxGrenades; - _aaiAmmo[4].ai_iAmmoAmmount = 0;//_penWeapons->m_iNapalm; - _aaiAmmo[4].ai_iMaxAmmoAmmount = 0;//_penWeapons->m_iMaxNapalm; - _aaiAmmo[5].ai_iAmmoAmmount = _penWeapons->m_iElectricity; - _aaiAmmo[5].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxElectricity; - _aaiAmmo[6].ai_iAmmoAmmount = _penWeapons->m_iIronBalls; - _aaiAmmo[6].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxIronBalls; - _aaiAmmo[7].ai_iAmmoAmmount = 0;//_penWeapons->m_iNukeBalls; - _aaiAmmo[7].ai_iMaxAmmoAmmount = 0;//_penWeapons->m_iMaxNukeBalls; - - // prepare ammo table for weapon possesion - INDEX i, iAvailableWeapons = _penWeapons->m_iAvailableWeapons; - for( i=0; i<8; i++) _aaiAmmo[i].ai_bHasWeapon = FALSE; - // weapon possesion - for( i=WEAPON_NONE+1; iai_bHasWeapon |= _awiWeapons[i].wi_bHasWeapon; - } - } -} - - - -// main - -// render interface (frontend) to drawport -// (units are in pixels for 640x480 resolution - for other res HUD will be scalled automatically) -extern void DrawHUD( const CPlayer *penPlayerCurrent, CDrawPort *pdpCurrent, BOOL bSnooping) -{ - // no player - no info, sorry - if( penPlayerCurrent==NULL || (penPlayerCurrent->GetFlags()&ENF_DELETED)) return; - - // find last values in case of predictor - CPlayer *penLast = (CPlayer*)penPlayerCurrent; - if( penPlayerCurrent->IsPredictor()) penLast = (CPlayer*)(((CPlayer*)penPlayerCurrent)->GetPredicted()); - ASSERT( penLast!=NULL); - if( penLast==NULL) return; // !!!! just in case - - // cache local variables - hud_fOpacity = Clamp( hud_fOpacity, 0.1f, 1.0f); - hud_fScaling = Clamp( hud_fScaling, 0.5f, 1.2f); - _penPlayer = penPlayerCurrent; - _penWeapons = (CPlayerWeapons*)&*_penPlayer->m_penWeapons; - _pDP = pdpCurrent; - _pixDPWidth = _pDP->GetWidth(); - _pixDPHeight = _pDP->GetHeight(); - _fCustomScaling = hud_fScaling; - _fResolutionScaling = (FLOAT)_pixDPWidth /640.0f; - _colHUD = C_GREEN; - _ulAlphaHUD = NormFloatToByte(hud_fOpacity); - _tmNow = _pTimer->CurrentTick(); - - // set HUD colorization; - COLOR colMax = _colHUD; - COLOR colTop = _colHUD; - COLOR colMid = _colHUD; - - // adjust borders color in case of spying mode - COLOR colBorder = _colHUD; - if( bSnooping) { - UBYTE ubR,ubG,ubB; - ColorToRGB( colBorder, ubR,ubG,ubB); - colBorder = RGBToColor( ubG,ubB,ubR); // shift and xor color components - if( ((ULONG)(_tmNow*5))&1) { - colBorder = (colBorder>>1) & 0x7F7F7F00; // darken flash and scale - _fCustomScaling *= 0.933f; - } - } - - // prepare font and text dimensions - CTString strValue; - PIX pixCharWidth; - FLOAT fValue, fNormValue, fCol, fRow; - _pDP->SetFont( &_fdNumbersFont); - pixCharWidth = _fdNumbersFont.GetWidth() + _fdNumbersFont.GetCharSpacing() +1; - FLOAT fChrUnit = pixCharWidth * _fCustomScaling; - - const PIX pixTopBound = 6; - const PIX pixLeftBound = 6; - const PIX pixBottomBound = (480 * _pDP->dp_fWideAdjustment) -pixTopBound; - const PIX pixRightBound = 640-pixLeftBound; - FLOAT fOneUnit = (32+0) * _fCustomScaling; // unit size - FLOAT fAdvUnit = (32+4) * _fCustomScaling; // unit advancer - FLOAT fNextUnit = (32+8) * _fCustomScaling; // unit advancer - FLOAT fHalfUnit = fOneUnit * 0.5f; - FLOAT fMoverX, fMoverY; - COLOR colDefault; - - // prepare and draw health info - fValue = ClampDn( _penPlayer->GetHealth(), 0.0f); // never show negative health - fNormValue = fValue/TOP_HEALTH; - strValue.PrintF( "%d", (SLONG)ceil(fValue)); - PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); - fRow = pixBottomBound-fHalfUnit; - fCol = pixLeftBound+fHalfUnit; - colDefault = AddShaker( 5, fValue, penLast->m_iLastHealth, penLast->m_tmHealthChanged, fMoverX, fMoverY); - HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); - fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); - HUD_DrawText( fCol, fRow, strValue, colDefault, fNormValue); - fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, _toHealth, _colHUD, fNormValue, TRUE); - - // prepare and draw armor info (eventually) - fValue = _penPlayer->m_fArmor; - if( fValue > 0.0f) { - fNormValue = fValue/TOP_ARMOR; - strValue.PrintF( "%d", (SLONG)ceil(fValue)); - PrepareColorTransitions( colMax, colTop, colMid, C_lGRAY, 0.5f, 0.25f, FALSE); - fRow = pixBottomBound- (fNextUnit+fHalfUnit);//*_pDP->dp_fWideAdjustment; - fCol = pixLeftBound+ fHalfUnit; - colDefault = AddShaker( 3, fValue, penLast->m_iLastArmor, penLast->m_tmArmorChanged, fMoverX, fMoverY); - HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); - fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); - HUD_DrawText( fCol, fRow, strValue, NONE, fNormValue); - fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, _toArmor, _colHUD, fNormValue, FALSE); - } - - // prepare and draw ammo and weapon info - CTextureObject *ptoCurrentAmmo=NULL, *ptoCurrentWeapon=NULL, *ptoWantedWeapon=NULL; - INDEX iCurrentWeapon = _penWeapons->m_iCurrentWeapon; - INDEX iWantedWeapon = _penWeapons->m_iWantedWeapon; - // determine corresponding ammo and weapon texture component - ptoCurrentWeapon = _awiWeapons[iCurrentWeapon].wi_ptoWeapon; - ptoWantedWeapon = _awiWeapons[iWantedWeapon].wi_ptoWeapon; - - AmmoInfo *paiCurrent = _awiWeapons[iCurrentWeapon].wi_paiAmmo; - if( paiCurrent!=NULL) ptoCurrentAmmo = paiCurrent->ai_ptoAmmo; - - // draw complete weapon info if knife isn't current weapon - if( ptoCurrentAmmo!=NULL && !GetSP()->sp_bInfiniteAmmo) { - // determine ammo quantities - FLOAT fMaxValue = _penWeapons->GetMaxAmmo(); - fValue = _penWeapons->GetAmmo(); - fNormValue = fValue / fMaxValue; - strValue.PrintF( "%d", (SLONG)ceil(fValue)); - PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); - BOOL bDrawAmmoIcon = _fCustomScaling<=1.0f; - // draw ammo, value and weapon - fRow = pixBottomBound-fHalfUnit; - fCol = 175 + fHalfUnit; - colDefault = AddShaker( 4, fValue, penLast->m_iLastAmmo, penLast->m_tmAmmoChanged, fMoverX, fMoverY); - HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); - fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); - if( bDrawAmmoIcon) { - fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawIcon( fCol, fRow, *ptoCurrentAmmo, _colHUD, fNormValue, TRUE); - fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; - } - HUD_DrawText( fCol, fRow, strValue, colDefault, fNormValue); - fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; - HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, *ptoCurrentWeapon, _colHUD, fNormValue, !bDrawAmmoIcon); - } else if( ptoCurrentWeapon!=NULL) { - // draw only knife or colt icons (ammo is irrelevant) - fRow = pixBottomBound-fHalfUnit; - fCol = 205 + fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawIcon( fCol, fRow, *ptoCurrentWeapon, _colHUD, fNormValue, FALSE); - } - - - // display all ammo infos - INDEX i; - FLOAT fAdv; - COLOR colIcon, colBar; - PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); - // reduce the size of icon slightly - _fCustomScaling = ClampDn( _fCustomScaling*0.8f, 0.5f); - const FLOAT fOneUnitS = fOneUnit *0.8f; - const FLOAT fAdvUnitS = fAdvUnit *0.8f; - //const FLOAT fNextUnitS = fNextUnit *0.8f; - const FLOAT fHalfUnitS = fHalfUnit *0.8f; - - // prepare postition and ammo quantities - fRow = pixBottomBound-fHalfUnitS; - fCol = pixRightBound -fHalfUnitS; - const FLOAT fBarPos = fHalfUnitS*0.7f; - FillWeaponAmmoTables(); - - // loop thru all ammo types - if (!GetSP()->sp_bInfiniteAmmo) { - for( i=7; i>=0; i--) { - // if no ammo and hasn't got that weapon - just skip this ammo - AmmoInfo &ai = _aaiAmmo[i]; - ASSERT( ai.ai_iAmmoAmmount>=0); - if( ai.ai_iAmmoAmmount==0 && !ai.ai_bHasWeapon) continue; - // display ammo info - colIcon = _colHUD; - if( ai.ai_iAmmoAmmount==0) colIcon = C_GRAY; - if( ptoCurrentAmmo == ai.ai_ptoAmmo) colIcon = C_WHITE; - fNormValue = (FLOAT)ai.ai_iAmmoAmmount / ai.ai_iMaxAmmoAmmount; - colBar = AddShaker( 4, ai.ai_iAmmoAmmount, ai.ai_iLastAmmoAmmount, ai.ai_tmAmmoChanged, fMoverX, fMoverY); - HUD_DrawBorder( fCol, fRow+fMoverY, fOneUnitS, fOneUnitS, colBorder); - HUD_DrawIcon( fCol, fRow+fMoverY, *_aaiAmmo[i].ai_ptoAmmo, colIcon, fNormValue, FALSE); - HUD_DrawBar( fCol+fBarPos, fRow+fMoverY, fOneUnitS/5, fOneUnitS-2, BO_DOWN, colBar, fNormValue); - // advance to next position - fCol -= fAdvUnitS; - } - } - - // if weapon change is in progress - _fCustomScaling = hud_fScaling; - hud_tmWeaponsOnScreen = Clamp( hud_tmWeaponsOnScreen, 0.0f, 10.0f); - if( (_tmNow - _penWeapons->m_tmWeaponChangeRequired) < hud_tmWeaponsOnScreen) { - // determine number of weapons that player has - INDEX ctWeapons = 0; - for( i=WEAPON_NONE+1; iai_iAmmoAmmount==0) colIcon = C_dGRAY; - if( ptoWantedWeapon == _awiWeapons[i].wi_ptoWeapon) colIcon = C_WHITE; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colIcon); - HUD_DrawIcon( fCol, fRow, *_awiWeapons[i].wi_ptoWeapon, colIcon, 1.0f, FALSE); - // advance to next position - fCol += fAdvUnit; - } - } - - const FLOAT fUpperSize = ClampDn(_fCustomScaling*0.5f, 0.5f)/_fCustomScaling; - _fCustomScaling*=fUpperSize; - ASSERT( _fCustomScaling>=0.5f); - fChrUnit *= fUpperSize; - fOneUnit *= fUpperSize; - fHalfUnit *= fUpperSize; - fAdvUnit *= fUpperSize; - fNextUnit *= fUpperSize; - - // draw oxygen info if needed - BOOL bOxygenOnScreen = FALSE; - fValue = _penPlayer->en_tmMaxHoldBreath - (_pTimer->CurrentTick() - _penPlayer->en_tmLastBreathed); - if( _penPlayer->IsConnected() && (_penPlayer->GetFlags()&ENF_ALIVE) && fValue<30.0f) { - // prepare and draw oxygen info - fRow = pixTopBound + fOneUnit + fNextUnit; - fCol = 280.0f; - fAdv = fAdvUnit + fOneUnit*4/2 - fHalfUnit; - PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); - fNormValue = fValue/30.0f; - fNormValue = ClampDn(fNormValue, 0.0f); - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawBorder( fCol+fAdv, fRow, fOneUnit*4, fOneUnit, colBorder); - HUD_DrawBar( fCol+fAdv, fRow, fOneUnit*4*0.975, fOneUnit*0.9375, BO_LEFT, NONE, fNormValue); - HUD_DrawIcon( fCol, fRow, _toOxygen, _colHUD, fNormValue, TRUE); - bOxygenOnScreen = TRUE; - } - - // draw boss energy if needed - if( _penPlayer->m_penMainMusicHolder!=NULL) { - CMusicHolder &mh = (CMusicHolder&)*_penPlayer->m_penMainMusicHolder; - fNormValue = 0; - - if( mh.m_penBoss!=NULL && (mh.m_penBoss->en_ulFlags&ENF_ALIVE)) { - CEnemyBase &eb = (CEnemyBase&)*mh.m_penBoss; - ASSERT( eb.m_fMaxHealth>0); - fValue = eb.GetHealth(); - fNormValue = fValue/eb.m_fMaxHealth; - } - if( mh.m_penCounter!=NULL) { - CEnemyCounter &ec = (CEnemyCounter&)*mh.m_penCounter; - if (ec.m_iCount>0) { - fValue = ec.m_iCount; - fNormValue = fValue/ec.m_iCountFrom; - } - } - if (fNormValue>0) { - // prepare and draw boss energy info - PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); - fRow = pixTopBound + fOneUnit + fNextUnit; - fCol = 184.0f; - fAdv = fAdvUnit+ fOneUnit*16/2 -fHalfUnit; - if( bOxygenOnScreen) fRow += fNextUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawBorder( fCol+fAdv, fRow, fOneUnit*16, fOneUnit, colBorder); - HUD_DrawBar( fCol+fAdv, fRow, fOneUnit*16*0.995, fOneUnit*0.9375, BO_LEFT, NONE, fNormValue); - HUD_DrawIcon( fCol, fRow, _toHealth, _colHUD, fNormValue, FALSE); - } - } - - // determine scaling of normal text and play mode - const FLOAT fTextScale = (_fResolutionScaling+1) *0.5f; - const BOOL bSinglePlay = GetSP()->sp_bSinglePlayer; - const BOOL bCooperative = GetSP()->sp_bCooperative && !bSinglePlay; - const BOOL bScoreMatch = !GetSP()->sp_bCooperative && !GetSP()->sp_bUseFrags; - const BOOL bFragMatch = !GetSP()->sp_bCooperative && GetSP()->sp_bUseFrags; - COLOR colMana, colFrags, colDeaths, colHealth, colArmor; - COLOR colScore = _colHUD; - INDEX iScoreSum = 0; - - // if not in single player mode, we'll have to calc (and maybe printout) other players' info - if( !bSinglePlay) - { - // set font and prepare font parameters - _pfdDisplayFont->SetVariableWidth(); - _pDP->SetFont( _pfdDisplayFont); - _pDP->SetTextScaling( fTextScale); - FLOAT fCharHeight = (_pfdDisplayFont->GetHeight()-2)*fTextScale; - // generate and sort by mana list of active players - BOOL bMaxScore=TRUE, bMaxMana=TRUE, bMaxFrags=TRUE, bMaxDeaths=TRUE; - hud_iSortPlayers = Clamp( hud_iSortPlayers, -1, 6); - SortKeys eKey = (SortKeys)hud_iSortPlayers; - if (hud_iSortPlayers==-1) { - if (bCooperative) eKey = PSK_HEALTH; - else if (bScoreMatch) eKey = PSK_SCORE; - else if (bFragMatch) eKey = PSK_FRAGS; - else { ASSERT(FALSE); eKey = PSK_NAME; } - } - if( bCooperative) eKey = (SortKeys)Clamp( (INDEX)eKey, 0, 3); - if( eKey==PSK_HEALTH && (bScoreMatch || bFragMatch)) { eKey = PSK_NAME; }; // prevent health snooping in deathmatch - INDEX iPlayers = SetAllPlayersStats(eKey); - // loop thru players - for( INDEX i=0; iGetPlayerName(); - const INDEX iScore = penPlayer->m_psGameStats.ps_iScore; - const INDEX iMana = penPlayer->m_iMana; - const INDEX iFrags = penPlayer->m_psGameStats.ps_iKills; - const INDEX iDeaths = penPlayer->m_psGameStats.ps_iDeaths; - const INDEX iHealth = ClampDn( (INDEX)ceil( penPlayer->GetHealth()), 0); - const INDEX iArmor = ClampDn( (INDEX)ceil( penPlayer->m_fArmor), 0); - CTString strScore, strMana, strFrags, strDeaths, strHealth, strArmor; - strScore.PrintF( "%d", iScore); - strMana.PrintF( "%d", iMana); - strFrags.PrintF( "%d", iFrags); - strDeaths.PrintF( "%d", iDeaths); - strHealth.PrintF( "%d", iHealth); - strArmor.PrintF( "%d", iArmor); - // detemine corresponding colors - colHealth = C_mlRED; - colMana = colScore = colFrags = colDeaths = colArmor = C_lGRAY; - if( iMana > _penPlayer->m_iMana) { bMaxMana = FALSE; colMana = C_WHITE; } - if( iScore > _penPlayer->m_psGameStats.ps_iScore) { bMaxScore = FALSE; colScore = C_WHITE; } - if( iFrags > _penPlayer->m_psGameStats.ps_iKills) { bMaxFrags = FALSE; colFrags = C_WHITE; } - if( iDeaths > _penPlayer->m_psGameStats.ps_iDeaths) { bMaxDeaths = FALSE; colDeaths = C_WHITE; } - if( penPlayer==_penPlayer) colScore = colMana = colFrags = colDeaths = _colHUD; // current player - if( iHealth>25) colHealth = _colHUD; - if( iArmor >25) colArmor = _colHUD; - // eventually print it out - if( hud_iShowPlayers==1 || (hud_iShowPlayers==-1 && !bSinglePlay)) { - // printout location and info aren't the same for deathmatch and coop play - const FLOAT fCharWidth = (PIX)((_pfdDisplayFont->GetWidth()-2) *fTextScale); - if( bCooperative) { - _pDP->PutTextR( strName+":", _pixDPWidth-8*fCharWidth, fCharHeight*i+fOneUnit*2, colScore |_ulAlphaHUD); - _pDP->PutText( "/", _pixDPWidth-4*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); - _pDP->PutTextC( strHealth, _pixDPWidth-6*fCharWidth, fCharHeight*i+fOneUnit*2, colHealth|_ulAlphaHUD); - _pDP->PutTextC( strArmor, _pixDPWidth-2*fCharWidth, fCharHeight*i+fOneUnit*2, colArmor |_ulAlphaHUD); - } else if( bScoreMatch) { - _pDP->PutTextR( strName+":", _pixDPWidth-12*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); - _pDP->PutText( "/", _pixDPWidth- 5*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); - _pDP->PutTextC( strScore, _pixDPWidth- 8*fCharWidth, fCharHeight*i+fOneUnit*2, colScore|_ulAlphaHUD); - _pDP->PutTextC( strMana, _pixDPWidth- 2*fCharWidth, fCharHeight*i+fOneUnit*2, colMana |_ulAlphaHUD); - } else { // fragmatch! - _pDP->PutTextR( strName+":", _pixDPWidth-8*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); - _pDP->PutText( "/", _pixDPWidth-4*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); - _pDP->PutTextC( strFrags, _pixDPWidth-6*fCharWidth, fCharHeight*i+fOneUnit*2, colFrags |_ulAlphaHUD); - _pDP->PutTextC( strDeaths, _pixDPWidth-2*fCharWidth, fCharHeight*i+fOneUnit*2, colDeaths|_ulAlphaHUD); - } - } - // calculate summ of scores (for coop mode) - iScoreSum += iScore; - } - - // prepare color for local player printouts - bMaxScore ? colScore = C_WHITE : colScore = C_lGRAY; - bMaxMana ? colMana = C_WHITE : colMana = C_lGRAY; - bMaxFrags ? colFrags = C_WHITE : colFrags = C_lGRAY; - bMaxDeaths ? colDeaths = C_WHITE : colDeaths = C_lGRAY; - } - - // printout player latency if needed - if( hud_bShowLatency) { - CTString strLatency; - strLatency.PrintF( "%4.0fms", _penPlayer->m_tmLatency*1000.0f); - PIX pixFontHeight = (PIX)(_pfdDisplayFont->GetHeight() *fTextScale +fTextScale+1); - _pfdDisplayFont->SetFixedWidth(); - _pDP->SetFont( _pfdDisplayFont); - _pDP->SetTextScaling( fTextScale); - _pDP->SetTextCharSpacing( -2.0f*fTextScale); - _pDP->PutTextR( strLatency, _pixDPWidth, _pixDPHeight-pixFontHeight, C_WHITE|CT_OPAQUE); - } - // restore font defaults - _pfdDisplayFont->SetVariableWidth(); - _pDP->SetFont( &_fdNumbersFont); - _pDP->SetTextCharSpacing(1); - - // prepare output strings and formats depending on game type - FLOAT fWidthAdj = 8; - INDEX iScore = _penPlayer->m_psGameStats.ps_iScore; - INDEX iMana = _penPlayer->m_iMana; - if( bFragMatch) { - fWidthAdj = 4; - iScore = _penPlayer->m_psGameStats.ps_iKills; - iMana = _penPlayer->m_psGameStats.ps_iDeaths; - } else if( bCooperative) { - // in case of coop play, show squad (common) score - iScore = iScoreSum; - } - - // prepare and draw score or frags info - strValue.PrintF( "%d", iScore); - fRow = pixTopBound +fHalfUnit; - fCol = pixLeftBound +fHalfUnit; - fAdv = fAdvUnit+ fChrUnit*fWidthAdj/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*fWidthAdj, fOneUnit, colBorder); - HUD_DrawText( fCol+fAdv, fRow, strValue, colScore, 1.0f); - HUD_DrawIcon( fCol, fRow, _toFrags, colScore, 1.0f, FALSE); - - // eventually draw mana info - if( bScoreMatch || bFragMatch) { - strValue.PrintF( "%d", iMana); - fRow = pixTopBound + fNextUnit+fHalfUnit; - fCol = pixLeftBound + fHalfUnit; - fAdv = fAdvUnit+ fChrUnit*fWidthAdj/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*fWidthAdj, fOneUnit, colBorder); - HUD_DrawText( fCol+fAdv, fRow, strValue, colMana, 1.0f); - HUD_DrawIcon( fCol, fRow, _toDeaths, colMana, 1.0f, FALSE); - } - - // if single player or cooperative mode - if( bSinglePlay || bCooperative) - { - // prepare and draw hiscore info - strValue.PrintF( "%d", Max(_penPlayer->m_iHighScore, _penPlayer->m_psGameStats.ps_iScore)); - BOOL bBeating = _penPlayer->m_psGameStats.ps_iScore>_penPlayer->m_iHighScore; - fRow = pixTopBound+fHalfUnit; - fCol = 320.0f-fOneUnit-fChrUnit*8/2; - fAdv = fAdvUnit+ fChrUnit*8/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); - HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*8, fOneUnit, colBorder); - HUD_DrawText( fCol+fAdv, fRow, strValue, NONE, bBeating ? 0.0f : 1.0f); - HUD_DrawIcon( fCol, fRow, _toHiScore, _colHUD, 1.0f, FALSE); - - // prepare and draw unread messages - if( hud_bShowMessages && _penPlayer->m_ctUnreadMessages>0) { - strValue.PrintF( "%d", _penPlayer->m_ctUnreadMessages); - fRow = pixTopBound+fHalfUnit; - fCol = pixRightBound-fHalfUnit-fAdvUnit-fChrUnit*4; - const FLOAT tmIn = 0.5f; - const FLOAT tmOut = 0.5f; - const FLOAT tmStay = 2.0f; - FLOAT tmDelta = _pTimer->GetLerpedCurrentTick()-_penPlayer->m_tmAnimateInbox; - COLOR col = _colHUD; - if (tmDelta>0 && tmDelta<(tmIn+tmStay+tmOut) && bSinglePlay) { - FLOAT fRatio = 0.0f; - if (tmDeltatmIn+tmStay) { - fRatio = (tmIn+tmStay+tmOut-tmDelta)/tmOut; - } else { - fRatio = 1.0f; - } - fRow+=fAdvUnit*5*fRatio; - fCol-=fAdvUnit*15*fRatio; - col = LerpColor(_colHUD, C_WHITE|0xFF, fRatio); - } - fAdv = fAdvUnit+ fChrUnit*4/2 -fHalfUnit; - HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, col); - HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*4, fOneUnit, col); - HUD_DrawText( fCol+fAdv, fRow, strValue, col, 1.0f); - HUD_DrawIcon( fCol, fRow, _toMessage, col, 0.0f, TRUE); - } - } - - // draw cheat modes - if( GetSP()->sp_ctMaxPlayers==1) { - INDEX iLine=1; - ULONG ulAlpha = sin(_tmNow*16)*96 +128; - PIX pixFontHeight = _pfdConsoleFont->fd_pixCharHeight; - const COLOR colCheat = _colHUD; - _pDP->SetFont( _pfdConsoleFont); - _pDP->SetTextScaling( 1.0f); - const FLOAT fchtTM = cht_fTranslationMultiplier; // for text formatting sake :) - if( fchtTM > 1.0f) { _pDP->PutTextR( "turbo", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } - if( cht_bInvisible) { _pDP->PutTextR( "invisible", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } - if( cht_bGhost) { _pDP->PutTextR( "ghost", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } - if( cht_bFly) { _pDP->PutTextR( "fly", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } - if( cht_bGod) { _pDP->PutTextR( "god", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } - } -} - - - -// initialized all whats need for drawing HUD -extern void InitHUD(void) -{ - // try to - try { - // initialize and load HUD numbers font - DECLARE_CTFILENAME( fnFont, "Fonts\\Numbers3.fnt"); - _fdNumbersFont.Load_t( fnFont); - //_fdNumbersFont.SetCharSpacing(0); - - // initialize status bar textures - _toHealth.SetData_t( CTFILENAME("Textures\\Interface\\HSuper.tex")); - _toArmor.SetData_t( CTFILENAME("Textures\\Interface\\ArStrong.tex")); - _toOxygen.SetData_t( CTFILENAME("Textures\\Interface\\Oxygen-2.tex")); - _toFrags.SetData_t( CTFILENAME("Textures\\Interface\\IBead.tex")); - _toDeaths.SetData_t( CTFILENAME("Textures\\Interface\\ISkull.tex")); - _toScore.SetData_t( CTFILENAME("Textures\\Interface\\IScore.tex")); - _toHiScore.SetData_t( CTFILENAME("Textures\\Interface\\IHiScore.tex")); - _toMessage.SetData_t( CTFILENAME("Textures\\Interface\\IMessage.tex")); - _toMana.SetData_t( CTFILENAME("Textures\\Interface\\IValue.tex")); - // initialize ammo textures - _toAShells.SetData_t( CTFILENAME("Textures\\Interface\\AmShells.tex")); - _toABullets.SetData_t( CTFILENAME("Textures\\Interface\\AmBullets.tex")); - _toARockets.SetData_t( CTFILENAME("Textures\\Interface\\AmRockets.tex")); - _toAGrenades.SetData_t( CTFILENAME("Textures\\Interface\\AmGrenades.tex")); - _toANapalm.SetData_t( CTFILENAME("Textures\\Interface\\AmFuelReservoir.tex")); - _toAElectricity.SetData_t( CTFILENAME("Textures\\Interface\\AmElectricity.tex")); - _toAIronBall.SetData_t( CTFILENAME("Textures\\Interface\\AmCannon.tex")); - // initialize weapon textures - _toWKnife.SetData_t( CTFILENAME("Textures\\Interface\\WKnife.tex")); - _toWColt.SetData_t( CTFILENAME("Textures\\Interface\\WColt.tex")); - _toWSingleShotgun.SetData_t( CTFILENAME("Textures\\Interface\\WSingleShotgun.tex")); - _toWDoubleShotgun.SetData_t( CTFILENAME("Textures\\Interface\\WDoubleShotgun.tex")); - _toWTommygun.SetData_t( CTFILENAME("Textures\\Interface\\WTommygun.tex")); - _toWMinigun.SetData_t( CTFILENAME("Textures\\Interface\\WMinigun.tex")); - _toWRocketLauncher.SetData_t( CTFILENAME("Textures\\Interface\\WRocketLauncher.tex")); - _toWGrenadeLauncher.SetData_t( CTFILENAME("Textures\\Interface\\WGrenadeLauncher.tex")); - _toWPipeBomb.SetData_t( CTFILENAME("Textures\\Interface\\WPipeBomb.tex")); - _toWFlamer.SetData_t( CTFILENAME("Textures\\Interface\\WFlamer.tex")); - _toWGhostBuster.SetData_t( CTFILENAME("Textures\\Interface\\WGhostBuster.tex")); - _toWLaser.SetData_t( CTFILENAME("Textures\\Interface\\WLaser.tex")); - _toWIronCannon.SetData_t( CTFILENAME("Textures\\Interface\\WCannon.tex")); - // initialize tile texture - _toTile.SetData_t( CTFILENAME("Textures\\Interface\\Tile.tex")); - - // set all textures as constant - ((CTextureData*)_toHealth .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toArmor .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toOxygen .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toFrags .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toDeaths .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toScore .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toHiScore.GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toMessage.GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toMana .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toAShells .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toABullets .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toARockets .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toAGrenades .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toANapalm .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toAElectricity.GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toAIronBall .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWKnife .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWColt .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWSingleShotgun .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWDoubleShotgun .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWTommygun .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWMinigun .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWRocketLauncher .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWGrenadeLauncher.GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWPipeBomb .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWFlamer .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWGhostBuster .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWLaser .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toWIronCannon .GetData())->Force(TEX_CONSTANT); - ((CTextureData*)_toTile .GetData())->Force(TEX_CONSTANT); - } - catch( char *strError) { - FatalError( strError); - } - -} - - -// clean up -extern void EndHUD(void) -{ - -} - + +#include "../StdH/StdH.h" + +#include +#include +#include +#include +#include +#include + + +// armor & health constants +// NOTE: these _do not_ reflect easy/tourist maxvalue adjustments. that is by design! +#define TOP_ARMOR 100 +#define TOP_HEALTH 100 + + +// cheats +extern INDEX cht_bEnable; +extern INDEX cht_bGod; +extern INDEX cht_bFly; +extern INDEX cht_bGhost; +extern INDEX cht_bInvisible; +extern FLOAT cht_fTranslationMultiplier; + +// interface control +extern INDEX hud_bShowInfo; +extern INDEX hud_bShowLatency; +extern INDEX hud_bShowMessages; +extern INDEX hud_iShowPlayers; +extern INDEX hud_iSortPlayers; +extern FLOAT hud_fOpacity; +extern FLOAT hud_fScaling; +extern FLOAT hud_tmWeaponsOnScreen; + + +// player statistics sorting keys +enum SortKeys { + PSK_NAME = 1, + PSK_HEALTH = 2, + PSK_SCORE = 3, + PSK_MANA = 4, + PSK_FRAGS = 5, + PSK_DEATHS = 6, +}; + +// where is the bar lowest value +enum BarOrientations { + BO_LEFT = 1, + BO_RIGHT = 2, + BO_UP = 3, + BO_DOWN = 4, +}; + + + +// maximal mana for master status +#define MANA_MASTER 10000 + +// drawing variables +static const CPlayer *_penPlayer; +static CPlayerWeapons *_penWeapons; +static CDrawPort *_pDP; +static PIX _pixDPWidth, _pixDPHeight; +static FLOAT _fResolutionScaling; +static FLOAT _fCustomScaling; +static ULONG _ulAlphaHUD; +static COLOR _colHUD; +static TIME _tmNow = -1.0f; +static CFontData _fdNumbersFont; + +// array for pointers of all players +CPlayer *_apenPlayers[NET_MAXGAMEPLAYERS] = {0}; + +// status bar textures +static CTextureObject _toHealth; +static CTextureObject _toArmor; +static CTextureObject _toOxygen; +static CTextureObject _toScore; +static CTextureObject _toHiScore; +static CTextureObject _toMessage; +static CTextureObject _toMana; +static CTextureObject _toFrags; +static CTextureObject _toDeaths; +// ammo textures +static CTextureObject _toAShells; +static CTextureObject _toABullets; +static CTextureObject _toARockets; +static CTextureObject _toAGrenades; +static CTextureObject _toANapalm; +static CTextureObject _toAElectricity; +static CTextureObject _toAIronBall; +// weapon textures +static CTextureObject _toWKnife; +static CTextureObject _toWColt; +static CTextureObject _toWSingleShotgun; +static CTextureObject _toWDoubleShotgun; +static CTextureObject _toWTommygun; +static CTextureObject _toWMinigun; +static CTextureObject _toWRocketLauncher; +static CTextureObject _toWGrenadeLauncher; +static CTextureObject _toWPipeBomb; +static CTextureObject _toWFlamer; +static CTextureObject _toWGhostBuster; +static CTextureObject _toWLaser; +static CTextureObject _toWIronCannon; +// tile texture (one has corners, edges and center) +static CTextureObject _toTile; + + +// all info about color transitions +struct ColorTransitionTable { + COLOR ctt_colFine; // color for values over 1.0 + COLOR ctt_colHigh; // color for values from 1.0 to 'fMedium' + COLOR ctt_colMedium; // color for values from 'fMedium' to 'fLow' + COLOR ctt_colLow; // color for values under fLow + FLOAT ctt_fMediumHigh; // when to switch to high color (normalized float!) + FLOAT ctt_fLowMedium; // when to switch to medium color (normalized float!) + BOOL ctt_bSmooth; // should colors have smooth transition +}; +static struct ColorTransitionTable _cttHUD; + + +// ammo's info structure +struct AmmoInfo { + CTextureObject *ai_ptoAmmo; + struct WeaponInfo *ai_pwiWeapon1; + struct WeaponInfo *ai_pwiWeapon2; + INDEX ai_iAmmoAmmount; + INDEX ai_iMaxAmmoAmmount; + INDEX ai_iLastAmmoAmmount; + TIME ai_tmAmmoChanged; + BOOL ai_bHasWeapon; +}; + +// weapons' info structure +struct WeaponInfo { + enum WeaponType wi_wtWeapon; + CTextureObject *wi_ptoWeapon; + struct AmmoInfo *wi_paiAmmo; + BOOL wi_bHasWeapon; +}; + +extern struct WeaponInfo _awiWeapons[18]; +static struct AmmoInfo _aaiAmmo[8] = { + { &_toAShells, &_awiWeapons[4], &_awiWeapons[5], 0, 0, 0, -9, FALSE }, + { &_toABullets, &_awiWeapons[6], &_awiWeapons[7], 0, 0, 0, -9, FALSE }, + { &_toARockets, &_awiWeapons[8], NULL, 0, 0, 0, -9, FALSE }, + { &_toAGrenades, &_awiWeapons[9], &_awiWeapons[10], 0, 0, 0, -9, FALSE }, + { &_toANapalm, &_awiWeapons[12], NULL, 0, 0, 0, -9, FALSE }, + { &_toAElectricity, &_awiWeapons[14], &_awiWeapons[15], 0, 0, 0, -9, FALSE }, + { &_toAIronBall, &_awiWeapons[16], NULL, 0, 0, 0, -9, FALSE }, + { &_toAIronBall, &_awiWeapons[17], NULL, 0, 0, 0, -9, FALSE }, +}; + +struct WeaponInfo _awiWeapons[18] = { + { WEAPON_NONE, NULL, NULL, FALSE }, // 0 + { WEAPON_KNIFE, &_toWKnife, NULL, FALSE }, // 1 + { WEAPON_COLT, &_toWColt, NULL, FALSE }, // 2 + { WEAPON_DOUBLECOLT, &_toWColt, NULL, FALSE }, // 3 + { WEAPON_SINGLESHOTGUN, &_toWSingleShotgun, &_aaiAmmo[0], FALSE }, // 4 + { WEAPON_DOUBLESHOTGUN, &_toWDoubleShotgun, &_aaiAmmo[0], FALSE }, // 5 + { WEAPON_TOMMYGUN, &_toWTommygun, &_aaiAmmo[1], FALSE }, // 6 + { WEAPON_MINIGUN, &_toWMinigun, &_aaiAmmo[1], FALSE }, // 7 + { WEAPON_ROCKETLAUNCHER, &_toWRocketLauncher, &_aaiAmmo[2], FALSE }, // 8 + { WEAPON_GRENADELAUNCHER, &_toWGrenadeLauncher, &_aaiAmmo[3], FALSE }, // 9 + { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_PIPEBOMB, &_toWPipeBomb, &_aaiAmmo[3], FALSE }, // 10 + { WEAPON_NONE, NULL, NULL, FALSE }, // 11 + { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_FLAMER, &_toWFlamer, &_aaiAmmo[4], FALSE }, // 12 + { WEAPON_NONE, NULL, NULL, FALSE }, // 13 + { WEAPON_LASER, &_toWLaser, &_aaiAmmo[5], FALSE }, // 14 + { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_GHOSTBUSTER, &_toWGhostBuster, &_aaiAmmo[5], FALSE }, // 15 + { WEAPON_IRONCANNON, &_toWIronCannon, &_aaiAmmo[6], FALSE }, // 16 + { WEAPON_NONE, NULL, NULL, FALSE }, //{ WEAPON_NUKECANNON, &_toWNukeCannon, &_aaiAmmo[7], FALSE }, // 17 +}; + + +// compare functions for qsort() +static int qsort_CompareNames( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + CTString strName0 = en0.GetPlayerName(); + CTString strName1 = en1.GetPlayerName(); + return strnicmp( strName0, strName1, 8); +} + +static int qsort_CompareScores( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = en0.m_psGameStats.ps_iScore; + SLONG sl1 = en1.m_psGameStats.ps_iScore; + if( sl0sl1) return -1; + else return 0; +} + +static int qsort_CompareHealth( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = (SLONG)ceil(en0.GetHealth()); + SLONG sl1 = (SLONG)ceil(en1.GetHealth()); + if( sl0sl1) return -1; + else return 0; +} + +static int qsort_CompareManas( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = en0.m_iMana; + SLONG sl1 = en1.m_iMana; + if( sl0sl1) return -1; + else return 0; +} + +static int qsort_CompareFrags( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = en0.m_psGameStats.ps_iKills; + SLONG sl1 = en1.m_psGameStats.ps_iKills; + if( sl0sl1) return -1; + else return 0; +} + +static int qsort_CompareDeaths( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = en0.m_psGameStats.ps_iDeaths; + SLONG sl1 = en1.m_psGameStats.ps_iDeaths; + if( sl0sl1) return -1; + else return 0; +} + +#if 0 // DG: unused +static int qsort_CompareLatencies( const void *ppPEN0, const void *ppPEN1) { + CPlayer &en0 = **(CPlayer**)ppPEN0; + CPlayer &en1 = **(CPlayer**)ppPEN1; + SLONG sl0 = (SLONG)ceil(en0.m_tmLatency); + SLONG sl1 = (SLONG)ceil(en1.m_tmLatency); + if( sl0sl1) return -1; + else return 0; +} +#endif // 0 (unused) + +// prepare color transitions +static void PrepareColorTransitions( COLOR colFine, COLOR colHigh, COLOR colMedium, COLOR colLow, + FLOAT fMediumHigh, FLOAT fLowMedium, BOOL bSmooth) +{ + _cttHUD.ctt_colFine = colFine; + _cttHUD.ctt_colHigh = colHigh; + _cttHUD.ctt_colMedium = colMedium; + _cttHUD.ctt_colLow = colLow; + _cttHUD.ctt_fMediumHigh = fMediumHigh; + _cttHUD.ctt_fLowMedium = fLowMedium; + _cttHUD.ctt_bSmooth = bSmooth; +} + + + +// calculates shake ammount and color value depanding on value change +#define SHAKE_TIME (2.0f) +static COLOR AddShaker( PIX const pixAmmount, INDEX const iCurrentValue, INDEX &iLastValue, + TIME &tmChanged, FLOAT &fMoverX, FLOAT &fMoverY) +{ + // update shaking if needed + fMoverX = fMoverY = 0.0f; + const TIME tmNow = _pTimer->GetLerpedCurrentTick(); + if( iCurrentValue != iLastValue) { + iLastValue = iCurrentValue; + tmChanged = tmNow; + } else { + // in case of loading (timer got reseted) + tmChanged = ClampUp( tmChanged, tmNow); + } + + // no shaker? + const TIME tmDelta = tmNow - tmChanged; + if( tmDelta > SHAKE_TIME) return NONE; + ASSERT( tmDelta>=0); + // shake, baby shake! + const FLOAT fAmmount = _fResolutionScaling * _fCustomScaling * pixAmmount; + const FLOAT fMultiplier = (SHAKE_TIME-tmDelta)/SHAKE_TIME *fAmmount; + const INDEX iRandomizer = (INDEX)(tmNow*511.0f)*fAmmount*iCurrentValue; + const FLOAT fNormRnd1 = (FLOAT)((iRandomizer ^ (iRandomizer>>9)) & 1023) * 0.0009775f; // 1/1023 - normalized + const FLOAT fNormRnd2 = (FLOAT)((iRandomizer ^ (iRandomizer>>7)) & 1023) * 0.0009775f; // 1/1023 - normalized + fMoverX = (fNormRnd1 -0.5f) * fMultiplier; + fMoverY = (fNormRnd2 -0.5f) * fMultiplier; + // clamp to adjusted ammount (pixels relative to resolution and HUD scale + fMoverX = Clamp( fMoverX, -fAmmount, fAmmount); + fMoverY = Clamp( fMoverY, -fAmmount, fAmmount); + if( tmDelta < SHAKE_TIME/3) return C_WHITE; + else return NONE; +//return FloatToInt(tmDelta*4) & 1 ? C_WHITE : NONE; +} + + +// get current color from local color transitions table +static COLOR GetCurrentColor( FLOAT fNormalizedValue) +{ + // if value is in 'low' zone just return plain 'low' alert color + if( fNormalizedValue < _cttHUD.ctt_fLowMedium) return( _cttHUD.ctt_colLow & 0xFFFFFF00); + // if value is in out of 'extreme' zone just return 'extreme' color + if( fNormalizedValue > 1.0f) return( _cttHUD.ctt_colFine & 0xFFFFFF00); + + COLOR col; + // should blend colors? + if( _cttHUD.ctt_bSmooth) + { // lets do some interpolations + FLOAT fd, f1, f2; + COLOR col1, col2; + UBYTE ubH,ubS,ubV, ubH2,ubS2,ubV2; + // determine two colors for interpolation + if( fNormalizedValue > _cttHUD.ctt_fMediumHigh) { + f1 = 1.0f; + f2 = _cttHUD.ctt_fMediumHigh; + col1 = _cttHUD.ctt_colHigh; + col2 = _cttHUD.ctt_colMedium; + } else { // fNormalizedValue > _cttHUD.ctt_fLowMedium == TRUE ! + f1 = _cttHUD.ctt_fMediumHigh; + f2 = _cttHUD.ctt_fLowMedium; + col1 = _cttHUD.ctt_colMedium; + col2 = _cttHUD.ctt_colLow; + } + // determine interpolation strength + fd = (fNormalizedValue-f2) / (f1-f2); + // convert colors to HSV + ColorToHSV( col1, ubH, ubS, ubV); + ColorToHSV( col2, ubH2, ubS2, ubV2); + // interpolate H, S and V components + ubH = (UBYTE)(ubH*fd + ubH2*(1.0f-fd)); + ubS = (UBYTE)(ubS*fd + ubS2*(1.0f-fd)); + ubV = (UBYTE)(ubV*fd + ubV2*(1.0f-fd)); + // convert HSV back to COLOR + col = HSVToColor( ubH, ubS, ubV); + } + else + { // simple color picker + col = _cttHUD.ctt_colMedium; + if( fNormalizedValue > _cttHUD.ctt_fMediumHigh) col = _cttHUD.ctt_colHigh; + } + // all done + return( col & 0xFFFFFF00); +} + + + +// fill array with players' statistics (returns current number of players in game) +extern INDEX SetAllPlayersStats( INDEX iSortKey) +{ + // determine maximum number of players for this session + INDEX iPlayers = 0; + INDEX iMaxPlayers = _penPlayer->GetMaxPlayers(); + CPlayer *penCurrent; + // loop thru potentional players + for( INDEX i=0; iGetPlayerEntity(i); + if( penCurrent==NULL) continue; + // fill in player parameters + _apenPlayers[iPlayers] = penCurrent; + // advance to next real player + iPlayers++; + } + // sort statistics by some key if needed + switch( iSortKey) { + case PSK_NAME: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareNames); break; + case PSK_SCORE: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareScores); break; + case PSK_HEALTH: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareHealth); break; + case PSK_MANA: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareManas); break; + case PSK_FRAGS: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareFrags); break; + case PSK_DEATHS: qsort( _apenPlayers, iPlayers, sizeof(CPlayer*), qsort_CompareDeaths); break; + default: break; // invalid or NONE key specified so do nothing + } + // all done + return iPlayers; +} + + + +// ----------------------- drawing functions + +// draw border with filter +static void HUD_DrawBorder( FLOAT fCenterX, FLOAT fCenterY, FLOAT fSizeX, FLOAT fSizeY, COLOR colTiles) +{ + // determine location + const FLOAT fCenterI = fCenterX*_pixDPWidth / 640.0f; + const FLOAT fCenterJ = fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment); + const FLOAT fSizeI = _fResolutionScaling*fSizeX; + const FLOAT fSizeJ = _fResolutionScaling*fSizeY; + const FLOAT fTileSize = 8*_fResolutionScaling*_fCustomScaling; + // determine exact positions + const FLOAT fLeft = fCenterI - fSizeI/2 -1; + const FLOAT fRight = fCenterI + fSizeI/2 +1; + const FLOAT fUp = fCenterJ - fSizeJ/2 -1; + const FLOAT fDown = fCenterJ + fSizeJ/2 +1; + const FLOAT fLeftEnd = fLeft + fTileSize; + const FLOAT fRightBeg = fRight - fTileSize; + const FLOAT fUpEnd = fUp + fTileSize; + const FLOAT fDownBeg = fDown - fTileSize; + // prepare texture + colTiles |= _ulAlphaHUD; + // put corners + _pDP->InitTexture( &_toTile, TRUE); // clamping on! + _pDP->AddTexture( fLeft, fUp, fLeftEnd, fUpEnd, colTiles); + _pDP->AddTexture( fRight,fUp, fRightBeg,fUpEnd, colTiles); + _pDP->AddTexture( fRight,fDown, fRightBeg,fDownBeg, colTiles); + _pDP->AddTexture( fLeft, fDown, fLeftEnd, fDownBeg, colTiles); + // put edges + _pDP->AddTexture( fLeftEnd,fUp, fRightBeg,fUpEnd, 0.4f,0.0f, 0.6f,1.0f, colTiles); + _pDP->AddTexture( fLeftEnd,fDown, fRightBeg,fDownBeg, 0.4f,0.0f, 0.6f,1.0f, colTiles); + _pDP->AddTexture( fLeft, fUpEnd, fLeftEnd, fDownBeg, 0.0f,0.4f, 1.0f,0.6f, colTiles); + _pDP->AddTexture( fRight, fUpEnd, fRightBeg,fDownBeg, 0.0f,0.4f, 1.0f,0.6f, colTiles); + // put center + _pDP->AddTexture( fLeftEnd, fUpEnd, fRightBeg, fDownBeg, 0.4f,0.4f, 0.6f,0.6f, colTiles); + _pDP->FlushRenderingQueue(); +} + + +// draw icon texture (if color = NONE, use colortransitions structure) +static void HUD_DrawIcon( FLOAT fCenterX, FLOAT fCenterY, CTextureObject &toIcon, + COLOR colDefault, FLOAT fNormValue, BOOL bBlink) +{ + // determine color + COLOR col = colDefault; + if( col==NONE) col = GetCurrentColor( fNormValue); + // determine blinking state + if( bBlink && fNormValue<=(_cttHUD.ctt_fLowMedium/2)) { + // activate blinking only if value is <= half the low edge + INDEX iCurrentTime = (INDEX)(_tmNow*4); + if( iCurrentTime&1) col = C_vdGRAY; + } + // determine location + const FLOAT fCenterI = fCenterX*_pixDPWidth / 640.0f; + const FLOAT fCenterJ = fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment); + // determine dimensions + CTextureData *ptd = (CTextureData*)toIcon.GetData(); + const FLOAT fHalfSizeI = _fResolutionScaling*_fCustomScaling * ptd->GetPixWidth() *0.5f; + const FLOAT fHalfSizeJ = _fResolutionScaling*_fCustomScaling * ptd->GetPixHeight() *0.5f; + // done + _pDP->InitTexture( &toIcon); + _pDP->AddTexture( fCenterI-fHalfSizeI, fCenterJ-fHalfSizeJ, + fCenterI+fHalfSizeI, fCenterJ+fHalfSizeJ, col|_ulAlphaHUD); + _pDP->FlushRenderingQueue(); +} + + +// draw text (or numbers, whatever) +static void HUD_DrawText( FLOAT fCenterX, FLOAT fCenterY, const CTString &strText, + COLOR colDefault, FLOAT fNormValue) +{ + // determine color + COLOR col = colDefault; + if( col==NONE) col = GetCurrentColor( fNormValue); + // determine location + PIX pixCenterI = (PIX)(fCenterX*_pixDPWidth / 640.0f); + PIX pixCenterJ = (PIX)(fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment)); + // done + _pDP->SetTextScaling( _fResolutionScaling*_fCustomScaling); + _pDP->PutTextCXY( strText, pixCenterI, pixCenterJ, col|_ulAlphaHUD); +} + + +// draw bar +static void HUD_DrawBar( FLOAT fCenterX, FLOAT fCenterY, PIX pixSizeX, PIX pixSizeY, + enum BarOrientations eBarOrientation, COLOR colDefault, FLOAT fNormValue) +{ + // determine color + COLOR col = colDefault; + if( col==NONE) col = GetCurrentColor( fNormValue); + // determine location and size + PIX pixCenterI = (PIX)(fCenterX*_pixDPWidth / 640.0f); + PIX pixCenterJ = (PIX)(fCenterY*_pixDPHeight / (480.0f * _pDP->dp_fWideAdjustment)); + PIX pixSizeI = (PIX)(_fResolutionScaling*pixSizeX); + PIX pixSizeJ = (PIX)(_fResolutionScaling*pixSizeY); + // fill bar background area + PIX pixLeft = pixCenterI-pixSizeI/2; + PIX pixUpper = pixCenterJ-pixSizeJ/2; + // determine bar position and inner size + switch( eBarOrientation) { + case BO_UP: + pixSizeJ *= fNormValue; + break; + case BO_DOWN: + pixUpper = pixUpper + (PIX)ceil(pixSizeJ * (1.0f-fNormValue)); + pixSizeJ *= fNormValue; + break; + case BO_LEFT: + pixSizeI *= fNormValue; + break; + case BO_RIGHT: + pixLeft = pixLeft + (PIX)ceil(pixSizeI * (1.0f-fNormValue)); + pixSizeI *= fNormValue; + break; + } + // done + _pDP->Fill( pixLeft, pixUpper, pixSizeI, pixSizeJ, col|_ulAlphaHUD); +} + + +// helper functions + +// fill weapon and ammo table with current state +static void FillWeaponAmmoTables(void) +{ + // ammo quantities + _aaiAmmo[0].ai_iAmmoAmmount = _penWeapons->m_iShells; + _aaiAmmo[0].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxShells; + _aaiAmmo[1].ai_iAmmoAmmount = _penWeapons->m_iBullets; + _aaiAmmo[1].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxBullets; + _aaiAmmo[2].ai_iAmmoAmmount = _penWeapons->m_iRockets; + _aaiAmmo[2].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxRockets; + _aaiAmmo[3].ai_iAmmoAmmount = _penWeapons->m_iGrenades; + _aaiAmmo[3].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxGrenades; + _aaiAmmo[4].ai_iAmmoAmmount = 0;//_penWeapons->m_iNapalm; + _aaiAmmo[4].ai_iMaxAmmoAmmount = 0;//_penWeapons->m_iMaxNapalm; + _aaiAmmo[5].ai_iAmmoAmmount = _penWeapons->m_iElectricity; + _aaiAmmo[5].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxElectricity; + _aaiAmmo[6].ai_iAmmoAmmount = _penWeapons->m_iIronBalls; + _aaiAmmo[6].ai_iMaxAmmoAmmount = _penWeapons->m_iMaxIronBalls; + _aaiAmmo[7].ai_iAmmoAmmount = 0;//_penWeapons->m_iNukeBalls; + _aaiAmmo[7].ai_iMaxAmmoAmmount = 0;//_penWeapons->m_iMaxNukeBalls; + + // prepare ammo table for weapon possesion + INDEX i, iAvailableWeapons = _penWeapons->m_iAvailableWeapons; + for( i=0; i<8; i++) _aaiAmmo[i].ai_bHasWeapon = FALSE; + // weapon possesion + for( i=WEAPON_NONE+1; iai_bHasWeapon |= _awiWeapons[i].wi_bHasWeapon; + } + } +} + + + +// main + +// render interface (frontend) to drawport +// (units are in pixels for 640x480 resolution - for other res HUD will be scalled automatically) +extern void DrawHUD( const CPlayer *penPlayerCurrent, CDrawPort *pdpCurrent, BOOL bSnooping) +{ + // no player - no info, sorry + if( penPlayerCurrent==NULL || (penPlayerCurrent->GetFlags()&ENF_DELETED)) return; + + // find last values in case of predictor + CPlayer *penLast = (CPlayer*)penPlayerCurrent; + if( penPlayerCurrent->IsPredictor()) penLast = (CPlayer*)(((CPlayer*)penPlayerCurrent)->GetPredicted()); + ASSERT( penLast!=NULL); + if( penLast==NULL) return; // !!!! just in case + + // cache local variables + hud_fOpacity = Clamp( hud_fOpacity, 0.1f, 1.0f); + hud_fScaling = Clamp( hud_fScaling, 0.5f, 1.2f); + _penPlayer = penPlayerCurrent; + _penWeapons = (CPlayerWeapons*)&*_penPlayer->m_penWeapons; + _pDP = pdpCurrent; + _pixDPWidth = _pDP->GetWidth(); + _pixDPHeight = _pDP->GetHeight(); + _fCustomScaling = hud_fScaling; + _fResolutionScaling = (FLOAT)_pixDPWidth /640.0f; + _colHUD = C_GREEN; + _ulAlphaHUD = NormFloatToByte(hud_fOpacity); + _tmNow = _pTimer->CurrentTick(); + + // set HUD colorization; + COLOR colMax = _colHUD; + COLOR colTop = _colHUD; + COLOR colMid = _colHUD; + + // adjust borders color in case of spying mode + COLOR colBorder = _colHUD; + if( bSnooping) { + UBYTE ubR,ubG,ubB; + ColorToRGB( colBorder, ubR,ubG,ubB); + colBorder = RGBToColor( ubG,ubB,ubR); // shift and xor color components + if( ((ULONG)(_tmNow*5))&1) { + colBorder = (colBorder>>1) & 0x7F7F7F00; // darken flash and scale + _fCustomScaling *= 0.933f; + } + } + + // prepare font and text dimensions + CTString strValue; + PIX pixCharWidth; + FLOAT fValue, fNormValue, fCol, fRow; + _pDP->SetFont( &_fdNumbersFont); + pixCharWidth = _fdNumbersFont.GetWidth() + _fdNumbersFont.GetCharSpacing() +1; + FLOAT fChrUnit = pixCharWidth * _fCustomScaling; + + const PIX pixTopBound = 6; + const PIX pixLeftBound = 6; + const PIX pixBottomBound = (480 * _pDP->dp_fWideAdjustment) -pixTopBound; + const PIX pixRightBound = 640-pixLeftBound; + FLOAT fOneUnit = (32+0) * _fCustomScaling; // unit size + FLOAT fAdvUnit = (32+4) * _fCustomScaling; // unit advancer + FLOAT fNextUnit = (32+8) * _fCustomScaling; // unit advancer + FLOAT fHalfUnit = fOneUnit * 0.5f; + FLOAT fMoverX, fMoverY; + COLOR colDefault; + + // prepare and draw health info + fValue = ClampDn( _penPlayer->GetHealth(), 0.0f); // never show negative health + fNormValue = fValue/TOP_HEALTH; + strValue.PrintF( "%d", (SLONG)ceil(fValue)); + PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); + fRow = pixBottomBound-fHalfUnit; + fCol = pixLeftBound+fHalfUnit; + colDefault = AddShaker( 5, fValue, penLast->m_iLastHealth, penLast->m_tmHealthChanged, fMoverX, fMoverY); + HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); + fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); + HUD_DrawText( fCol, fRow, strValue, colDefault, fNormValue); + fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, _toHealth, _colHUD, fNormValue, TRUE); + + // prepare and draw armor info (eventually) + fValue = _penPlayer->m_fArmor; + if( fValue > 0.0f) { + fNormValue = fValue/TOP_ARMOR; + strValue.PrintF( "%d", (SLONG)ceil(fValue)); + PrepareColorTransitions( colMax, colTop, colMid, C_lGRAY, 0.5f, 0.25f, FALSE); + fRow = pixBottomBound- (fNextUnit+fHalfUnit);//*_pDP->dp_fWideAdjustment; + fCol = pixLeftBound+ fHalfUnit; + colDefault = AddShaker( 3, fValue, penLast->m_iLastArmor, penLast->m_tmArmorChanged, fMoverX, fMoverY); + HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); + fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); + HUD_DrawText( fCol, fRow, strValue, NONE, fNormValue); + fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, _toArmor, _colHUD, fNormValue, FALSE); + } + + // prepare and draw ammo and weapon info + CTextureObject *ptoCurrentAmmo=NULL, *ptoCurrentWeapon=NULL, *ptoWantedWeapon=NULL; + INDEX iCurrentWeapon = _penWeapons->m_iCurrentWeapon; + INDEX iWantedWeapon = _penWeapons->m_iWantedWeapon; + // determine corresponding ammo and weapon texture component + ptoCurrentWeapon = _awiWeapons[iCurrentWeapon].wi_ptoWeapon; + ptoWantedWeapon = _awiWeapons[iWantedWeapon].wi_ptoWeapon; + + AmmoInfo *paiCurrent = _awiWeapons[iCurrentWeapon].wi_paiAmmo; + if( paiCurrent!=NULL) ptoCurrentAmmo = paiCurrent->ai_ptoAmmo; + + // draw complete weapon info if knife isn't current weapon + if( ptoCurrentAmmo!=NULL && !GetSP()->sp_bInfiniteAmmo) { + // determine ammo quantities + FLOAT fMaxValue = _penWeapons->GetMaxAmmo(); + fValue = _penWeapons->GetAmmo(); + fNormValue = fValue / fMaxValue; + strValue.PrintF( "%d", (SLONG)ceil(fValue)); + PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); + BOOL bDrawAmmoIcon = _fCustomScaling<=1.0f; + // draw ammo, value and weapon + fRow = pixBottomBound-fHalfUnit; + fCol = 175 + fHalfUnit; + colDefault = AddShaker( 4, fValue, penLast->m_iLastAmmo, penLast->m_tmAmmoChanged, fMoverX, fMoverY); + HUD_DrawBorder( fCol+fMoverX, fRow+fMoverY, fOneUnit, fOneUnit, colBorder); + fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fChrUnit*3, fOneUnit, colBorder); + if( bDrawAmmoIcon) { + fCol += fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawIcon( fCol, fRow, *ptoCurrentAmmo, _colHUD, fNormValue, TRUE); + fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; + } + HUD_DrawText( fCol, fRow, strValue, colDefault, fNormValue); + fCol -= fAdvUnit+fChrUnit*3/2 -fHalfUnit; + HUD_DrawIcon( fCol+fMoverX, fRow+fMoverY, *ptoCurrentWeapon, _colHUD, fNormValue, !bDrawAmmoIcon); + } else if( ptoCurrentWeapon!=NULL) { + // draw only knife or colt icons (ammo is irrelevant) + fRow = pixBottomBound-fHalfUnit; + fCol = 205 + fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawIcon( fCol, fRow, *ptoCurrentWeapon, _colHUD, fNormValue, FALSE); + } + + + // display all ammo infos + INDEX i; + FLOAT fAdv; + COLOR colIcon, colBar; + PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); + // reduce the size of icon slightly + _fCustomScaling = ClampDn( _fCustomScaling*0.8f, 0.5f); + const FLOAT fOneUnitS = fOneUnit *0.8f; + const FLOAT fAdvUnitS = fAdvUnit *0.8f; + //const FLOAT fNextUnitS = fNextUnit *0.8f; + const FLOAT fHalfUnitS = fHalfUnit *0.8f; + + // prepare postition and ammo quantities + fRow = pixBottomBound-fHalfUnitS; + fCol = pixRightBound -fHalfUnitS; + const FLOAT fBarPos = fHalfUnitS*0.7f; + FillWeaponAmmoTables(); + + // loop thru all ammo types + if (!GetSP()->sp_bInfiniteAmmo) { + for( i=7; i>=0; i--) { + // if no ammo and hasn't got that weapon - just skip this ammo + AmmoInfo &ai = _aaiAmmo[i]; + ASSERT( ai.ai_iAmmoAmmount>=0); + if( ai.ai_iAmmoAmmount==0 && !ai.ai_bHasWeapon) continue; + // display ammo info + colIcon = _colHUD; + if( ai.ai_iAmmoAmmount==0) colIcon = C_GRAY; + if( ptoCurrentAmmo == ai.ai_ptoAmmo) colIcon = C_WHITE; + fNormValue = (FLOAT)ai.ai_iAmmoAmmount / ai.ai_iMaxAmmoAmmount; + colBar = AddShaker( 4, ai.ai_iAmmoAmmount, ai.ai_iLastAmmoAmmount, ai.ai_tmAmmoChanged, fMoverX, fMoverY); + HUD_DrawBorder( fCol, fRow+fMoverY, fOneUnitS, fOneUnitS, colBorder); + HUD_DrawIcon( fCol, fRow+fMoverY, *_aaiAmmo[i].ai_ptoAmmo, colIcon, fNormValue, FALSE); + HUD_DrawBar( fCol+fBarPos, fRow+fMoverY, fOneUnitS/5, fOneUnitS-2, BO_DOWN, colBar, fNormValue); + // advance to next position + fCol -= fAdvUnitS; + } + } + + // if weapon change is in progress + _fCustomScaling = hud_fScaling; + hud_tmWeaponsOnScreen = Clamp( hud_tmWeaponsOnScreen, 0.0f, 10.0f); + if( (_tmNow - _penWeapons->m_tmWeaponChangeRequired) < hud_tmWeaponsOnScreen) { + // determine number of weapons that player has + INDEX ctWeapons = 0; + for( i=WEAPON_NONE+1; iai_iAmmoAmmount==0) colIcon = C_dGRAY; + if( ptoWantedWeapon == _awiWeapons[i].wi_ptoWeapon) colIcon = C_WHITE; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colIcon); + HUD_DrawIcon( fCol, fRow, *_awiWeapons[i].wi_ptoWeapon, colIcon, 1.0f, FALSE); + // advance to next position + fCol += fAdvUnit; + } + } + + const FLOAT fUpperSize = ClampDn(_fCustomScaling*0.5f, 0.5f)/_fCustomScaling; + _fCustomScaling*=fUpperSize; + ASSERT( _fCustomScaling>=0.5f); + fChrUnit *= fUpperSize; + fOneUnit *= fUpperSize; + fHalfUnit *= fUpperSize; + fAdvUnit *= fUpperSize; + fNextUnit *= fUpperSize; + + // draw oxygen info if needed + BOOL bOxygenOnScreen = FALSE; + fValue = _penPlayer->en_tmMaxHoldBreath - (_pTimer->CurrentTick() - _penPlayer->en_tmLastBreathed); + if( _penPlayer->IsConnected() && (_penPlayer->GetFlags()&ENF_ALIVE) && fValue<30.0f) { + // prepare and draw oxygen info + fRow = pixTopBound + fOneUnit + fNextUnit; + fCol = 280.0f; + fAdv = fAdvUnit + fOneUnit*4/2 - fHalfUnit; + PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); + fNormValue = fValue/30.0f; + fNormValue = ClampDn(fNormValue, 0.0f); + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawBorder( fCol+fAdv, fRow, fOneUnit*4, fOneUnit, colBorder); + HUD_DrawBar( fCol+fAdv, fRow, fOneUnit*4*0.975, fOneUnit*0.9375, BO_LEFT, NONE, fNormValue); + HUD_DrawIcon( fCol, fRow, _toOxygen, _colHUD, fNormValue, TRUE); + bOxygenOnScreen = TRUE; + } + + // draw boss energy if needed + if( _penPlayer->m_penMainMusicHolder!=NULL) { + CMusicHolder &mh = (CMusicHolder&)*_penPlayer->m_penMainMusicHolder; + fNormValue = 0; + + if( mh.m_penBoss!=NULL && (mh.m_penBoss->en_ulFlags&ENF_ALIVE)) { + CEnemyBase &eb = (CEnemyBase&)*mh.m_penBoss; + ASSERT( eb.m_fMaxHealth>0); + fValue = eb.GetHealth(); + fNormValue = fValue/eb.m_fMaxHealth; + } + if( mh.m_penCounter!=NULL) { + CEnemyCounter &ec = (CEnemyCounter&)*mh.m_penCounter; + if (ec.m_iCount>0) { + fValue = ec.m_iCount; + fNormValue = fValue/ec.m_iCountFrom; + } + } + if (fNormValue>0) { + // prepare and draw boss energy info + PrepareColorTransitions( colMax, colTop, colMid, C_RED, 0.5f, 0.25f, FALSE); + fRow = pixTopBound + fOneUnit + fNextUnit; + fCol = 184.0f; + fAdv = fAdvUnit+ fOneUnit*16/2 -fHalfUnit; + if( bOxygenOnScreen) fRow += fNextUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawBorder( fCol+fAdv, fRow, fOneUnit*16, fOneUnit, colBorder); + HUD_DrawBar( fCol+fAdv, fRow, fOneUnit*16*0.995, fOneUnit*0.9375, BO_LEFT, NONE, fNormValue); + HUD_DrawIcon( fCol, fRow, _toHealth, _colHUD, fNormValue, FALSE); + } + } + + // determine scaling of normal text and play mode + const FLOAT fTextScale = (_fResolutionScaling+1) *0.5f; + const BOOL bSinglePlay = GetSP()->sp_bSinglePlayer; + const BOOL bCooperative = GetSP()->sp_bCooperative && !bSinglePlay; + const BOOL bScoreMatch = !GetSP()->sp_bCooperative && !GetSP()->sp_bUseFrags; + const BOOL bFragMatch = !GetSP()->sp_bCooperative && GetSP()->sp_bUseFrags; + COLOR colMana, colFrags, colDeaths, colHealth, colArmor; + COLOR colScore = _colHUD; + INDEX iScoreSum = 0; + + // if not in single player mode, we'll have to calc (and maybe printout) other players' info + if( !bSinglePlay) + { + // set font and prepare font parameters + _pfdDisplayFont->SetVariableWidth(); + _pDP->SetFont( _pfdDisplayFont); + _pDP->SetTextScaling( fTextScale); + FLOAT fCharHeight = (_pfdDisplayFont->GetHeight()-2)*fTextScale; + // generate and sort by mana list of active players + BOOL bMaxScore=TRUE, bMaxMana=TRUE, bMaxFrags=TRUE, bMaxDeaths=TRUE; + hud_iSortPlayers = Clamp( hud_iSortPlayers, -1, 6); + SortKeys eKey = (SortKeys)hud_iSortPlayers; + if (hud_iSortPlayers==-1) { + if (bCooperative) eKey = PSK_HEALTH; + else if (bScoreMatch) eKey = PSK_SCORE; + else if (bFragMatch) eKey = PSK_FRAGS; + else { ASSERT(FALSE); eKey = PSK_NAME; } + } + if( bCooperative) eKey = (SortKeys)Clamp( (INDEX)eKey, 0, 3); + if( eKey==PSK_HEALTH && (bScoreMatch || bFragMatch)) { eKey = PSK_NAME; }; // prevent health snooping in deathmatch + INDEX iPlayers = SetAllPlayersStats(eKey); + // loop thru players + for( INDEX i=0; iGetPlayerName(); + const INDEX iScore = penPlayer->m_psGameStats.ps_iScore; + const INDEX iMana = penPlayer->m_iMana; + const INDEX iFrags = penPlayer->m_psGameStats.ps_iKills; + const INDEX iDeaths = penPlayer->m_psGameStats.ps_iDeaths; + const INDEX iHealth = ClampDn( (INDEX)ceil( penPlayer->GetHealth()), 0); + const INDEX iArmor = ClampDn( (INDEX)ceil( penPlayer->m_fArmor), 0); + CTString strScore, strMana, strFrags, strDeaths, strHealth, strArmor; + strScore.PrintF( "%d", iScore); + strMana.PrintF( "%d", iMana); + strFrags.PrintF( "%d", iFrags); + strDeaths.PrintF( "%d", iDeaths); + strHealth.PrintF( "%d", iHealth); + strArmor.PrintF( "%d", iArmor); + // detemine corresponding colors + colHealth = C_mlRED; + colMana = colScore = colFrags = colDeaths = colArmor = C_lGRAY; + if( iMana > _penPlayer->m_iMana) { bMaxMana = FALSE; colMana = C_WHITE; } + if( iScore > _penPlayer->m_psGameStats.ps_iScore) { bMaxScore = FALSE; colScore = C_WHITE; } + if( iFrags > _penPlayer->m_psGameStats.ps_iKills) { bMaxFrags = FALSE; colFrags = C_WHITE; } + if( iDeaths > _penPlayer->m_psGameStats.ps_iDeaths) { bMaxDeaths = FALSE; colDeaths = C_WHITE; } + if( penPlayer==_penPlayer) colScore = colMana = colFrags = colDeaths = _colHUD; // current player + if( iHealth>25) colHealth = _colHUD; + if( iArmor >25) colArmor = _colHUD; + // eventually print it out + if( hud_iShowPlayers==1 || hud_iShowPlayers==-1) { + // printout location and info aren't the same for deathmatch and coop play + const FLOAT fCharWidth = (PIX)((_pfdDisplayFont->GetWidth()-2) *fTextScale); + if( bCooperative) { + _pDP->PutTextR( strName+":", _pixDPWidth-8*fCharWidth, fCharHeight*i+fOneUnit*2, colScore |_ulAlphaHUD); + _pDP->PutText( "/", _pixDPWidth-4*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); + _pDP->PutTextC( strHealth, _pixDPWidth-6*fCharWidth, fCharHeight*i+fOneUnit*2, colHealth|_ulAlphaHUD); + _pDP->PutTextC( strArmor, _pixDPWidth-2*fCharWidth, fCharHeight*i+fOneUnit*2, colArmor |_ulAlphaHUD); + } else if( bScoreMatch) { + _pDP->PutTextR( strName+":", _pixDPWidth-12*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); + _pDP->PutText( "/", _pixDPWidth- 5*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); + _pDP->PutTextC( strScore, _pixDPWidth- 8*fCharWidth, fCharHeight*i+fOneUnit*2, colScore|_ulAlphaHUD); + _pDP->PutTextC( strMana, _pixDPWidth- 2*fCharWidth, fCharHeight*i+fOneUnit*2, colMana |_ulAlphaHUD); + } else { // fragmatch! + _pDP->PutTextR( strName+":", _pixDPWidth-8*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); + _pDP->PutText( "/", _pixDPWidth-4*fCharWidth, fCharHeight*i+fOneUnit*2, _colHUD |_ulAlphaHUD); + _pDP->PutTextC( strFrags, _pixDPWidth-6*fCharWidth, fCharHeight*i+fOneUnit*2, colFrags |_ulAlphaHUD); + _pDP->PutTextC( strDeaths, _pixDPWidth-2*fCharWidth, fCharHeight*i+fOneUnit*2, colDeaths|_ulAlphaHUD); + } + } + // calculate summ of scores (for coop mode) + iScoreSum += iScore; + } + + // prepare color for local player printouts + bMaxScore ? colScore = C_WHITE : colScore = C_lGRAY; + bMaxMana ? colMana = C_WHITE : colMana = C_lGRAY; + bMaxFrags ? colFrags = C_WHITE : colFrags = C_lGRAY; + bMaxDeaths ? colDeaths = C_WHITE : colDeaths = C_lGRAY; + } + + // printout player latency if needed + if( hud_bShowLatency) { + CTString strLatency; + strLatency.PrintF( "%4.0fms", _penPlayer->m_tmLatency*1000.0f); + PIX pixFontHeight = (PIX)(_pfdDisplayFont->GetHeight() *fTextScale +fTextScale+1); + _pfdDisplayFont->SetFixedWidth(); + _pDP->SetFont( _pfdDisplayFont); + _pDP->SetTextScaling( fTextScale); + _pDP->SetTextCharSpacing( -2.0f*fTextScale); + _pDP->PutTextR( strLatency, _pixDPWidth, _pixDPHeight-pixFontHeight, C_WHITE|CT_OPAQUE); + } + // restore font defaults + _pfdDisplayFont->SetVariableWidth(); + _pDP->SetFont( &_fdNumbersFont); + _pDP->SetTextCharSpacing(1); + + // prepare output strings and formats depending on game type + FLOAT fWidthAdj = 8; + INDEX iScore = _penPlayer->m_psGameStats.ps_iScore; + INDEX iMana = _penPlayer->m_iMana; + if( bFragMatch) { + fWidthAdj = 4; + iScore = _penPlayer->m_psGameStats.ps_iKills; + iMana = _penPlayer->m_psGameStats.ps_iDeaths; + } else if( bCooperative) { + // in case of coop play, show squad (common) score + iScore = iScoreSum; + } + + // prepare and draw score or frags info + strValue.PrintF( "%d", iScore); + fRow = pixTopBound +fHalfUnit; + fCol = pixLeftBound +fHalfUnit; + fAdv = fAdvUnit+ fChrUnit*fWidthAdj/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*fWidthAdj, fOneUnit, colBorder); + HUD_DrawText( fCol+fAdv, fRow, strValue, colScore, 1.0f); + HUD_DrawIcon( fCol, fRow, _toFrags, colScore, 1.0f, FALSE); + + // eventually draw mana info + if( bScoreMatch || bFragMatch) { + strValue.PrintF( "%d", iMana); + fRow = pixTopBound + fNextUnit+fHalfUnit; + fCol = pixLeftBound + fHalfUnit; + fAdv = fAdvUnit+ fChrUnit*fWidthAdj/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*fWidthAdj, fOneUnit, colBorder); + HUD_DrawText( fCol+fAdv, fRow, strValue, colMana, 1.0f); + HUD_DrawIcon( fCol, fRow, _toDeaths, colMana, 1.0f, FALSE); + } + + // if single player or cooperative mode + if( bSinglePlay || bCooperative) + { + // prepare and draw hiscore info + strValue.PrintF( "%d", Max(_penPlayer->m_iHighScore, _penPlayer->m_psGameStats.ps_iScore)); + BOOL bBeating = _penPlayer->m_psGameStats.ps_iScore>_penPlayer->m_iHighScore; + fRow = pixTopBound+fHalfUnit; + fCol = 320.0f-fOneUnit-fChrUnit*8/2; + fAdv = fAdvUnit+ fChrUnit*8/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, colBorder); + HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*8, fOneUnit, colBorder); + HUD_DrawText( fCol+fAdv, fRow, strValue, NONE, bBeating ? 0.0f : 1.0f); + HUD_DrawIcon( fCol, fRow, _toHiScore, _colHUD, 1.0f, FALSE); + + // prepare and draw unread messages + if( hud_bShowMessages && _penPlayer->m_ctUnreadMessages>0) { + strValue.PrintF( "%d", _penPlayer->m_ctUnreadMessages); + fRow = pixTopBound+fHalfUnit; + fCol = pixRightBound-fHalfUnit-fAdvUnit-fChrUnit*4; + const FLOAT tmIn = 0.5f; + const FLOAT tmOut = 0.5f; + const FLOAT tmStay = 2.0f; + FLOAT tmDelta = _pTimer->GetLerpedCurrentTick()-_penPlayer->m_tmAnimateInbox; + COLOR col = _colHUD; + if (tmDelta>0 && tmDelta<(tmIn+tmStay+tmOut) && bSinglePlay) { + FLOAT fRatio = 0.0f; + if (tmDeltatmIn+tmStay) { + fRatio = (tmIn+tmStay+tmOut-tmDelta)/tmOut; + } else { + fRatio = 1.0f; + } + fRow+=fAdvUnit*5*fRatio; + fCol-=fAdvUnit*15*fRatio; + col = LerpColor(_colHUD, C_WHITE|0xFF, fRatio); + } + fAdv = fAdvUnit+ fChrUnit*4/2 -fHalfUnit; + HUD_DrawBorder( fCol, fRow, fOneUnit, fOneUnit, col); + HUD_DrawBorder( fCol+fAdv, fRow, fChrUnit*4, fOneUnit, col); + HUD_DrawText( fCol+fAdv, fRow, strValue, col, 1.0f); + HUD_DrawIcon( fCol, fRow, _toMessage, col, 0.0f, TRUE); + } + } + + // draw cheat modes + if( GetSP()->sp_ctMaxPlayers==1) { + INDEX iLine=1; + ULONG ulAlpha = sin(_tmNow*16)*96 +128; + PIX pixFontHeight = _pfdConsoleFont->fd_pixCharHeight; + const COLOR colCheat = _colHUD; + _pDP->SetFont( _pfdConsoleFont); + _pDP->SetTextScaling( 1.0f); + const FLOAT fchtTM = cht_fTranslationMultiplier; // for text formatting sake :) + if( fchtTM > 1.0f) { _pDP->PutTextR( "turbo", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } + if( cht_bInvisible) { _pDP->PutTextR( "invisible", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } + if( cht_bGhost) { _pDP->PutTextR( "ghost", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } + if( cht_bFly) { _pDP->PutTextR( "fly", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } + if( cht_bGod) { _pDP->PutTextR( "god", _pixDPWidth-1, _pixDPHeight-pixFontHeight*iLine, colCheat|ulAlpha); iLine++; } + } +} + + + +// initialized all whats need for drawing HUD +extern void InitHUD(void) +{ + // try to + try { + // initialize and load HUD numbers font + DECLARE_CTFILENAME( fnFont, "Fonts\\Numbers3.fnt"); + _fdNumbersFont.Load_t( fnFont); + //_fdNumbersFont.SetCharSpacing(0); + + // initialize status bar textures + _toHealth.SetData_t( CTFILENAME("Textures\\Interface\\HSuper.tex")); + _toArmor.SetData_t( CTFILENAME("Textures\\Interface\\ArStrong.tex")); + _toOxygen.SetData_t( CTFILENAME("Textures\\Interface\\Oxygen-2.tex")); + _toFrags.SetData_t( CTFILENAME("Textures\\Interface\\IBead.tex")); + _toDeaths.SetData_t( CTFILENAME("Textures\\Interface\\ISkull.tex")); + _toScore.SetData_t( CTFILENAME("Textures\\Interface\\IScore.tex")); + _toHiScore.SetData_t( CTFILENAME("Textures\\Interface\\IHiScore.tex")); + _toMessage.SetData_t( CTFILENAME("Textures\\Interface\\IMessage.tex")); + _toMana.SetData_t( CTFILENAME("Textures\\Interface\\IValue.tex")); + // initialize ammo textures + _toAShells.SetData_t( CTFILENAME("Textures\\Interface\\AmShells.tex")); + _toABullets.SetData_t( CTFILENAME("Textures\\Interface\\AmBullets.tex")); + _toARockets.SetData_t( CTFILENAME("Textures\\Interface\\AmRockets.tex")); + _toAGrenades.SetData_t( CTFILENAME("Textures\\Interface\\AmGrenades.tex")); + _toANapalm.SetData_t( CTFILENAME("Textures\\Interface\\AmFuelReservoir.tex")); + _toAElectricity.SetData_t( CTFILENAME("Textures\\Interface\\AmElectricity.tex")); + _toAIronBall.SetData_t( CTFILENAME("Textures\\Interface\\AmCannon.tex")); + // initialize weapon textures + _toWKnife.SetData_t( CTFILENAME("Textures\\Interface\\WKnife.tex")); + _toWColt.SetData_t( CTFILENAME("Textures\\Interface\\WColt.tex")); + _toWSingleShotgun.SetData_t( CTFILENAME("Textures\\Interface\\WSingleShotgun.tex")); + _toWDoubleShotgun.SetData_t( CTFILENAME("Textures\\Interface\\WDoubleShotgun.tex")); + _toWTommygun.SetData_t( CTFILENAME("Textures\\Interface\\WTommygun.tex")); + _toWMinigun.SetData_t( CTFILENAME("Textures\\Interface\\WMinigun.tex")); + _toWRocketLauncher.SetData_t( CTFILENAME("Textures\\Interface\\WRocketLauncher.tex")); + _toWGrenadeLauncher.SetData_t( CTFILENAME("Textures\\Interface\\WGrenadeLauncher.tex")); + _toWPipeBomb.SetData_t( CTFILENAME("Textures\\Interface\\WPipeBomb.tex")); + _toWFlamer.SetData_t( CTFILENAME("Textures\\Interface\\WFlamer.tex")); + _toWGhostBuster.SetData_t( CTFILENAME("Textures\\Interface\\WGhostBuster.tex")); + _toWLaser.SetData_t( CTFILENAME("Textures\\Interface\\WLaser.tex")); + _toWIronCannon.SetData_t( CTFILENAME("Textures\\Interface\\WCannon.tex")); + // initialize tile texture + _toTile.SetData_t( CTFILENAME("Textures\\Interface\\Tile.tex")); + + // set all textures as constant + ((CTextureData*)_toHealth .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toArmor .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toOxygen .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toFrags .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toDeaths .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toScore .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toHiScore.GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toMessage.GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toMana .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toAShells .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toABullets .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toARockets .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toAGrenades .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toANapalm .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toAElectricity.GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toAIronBall .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWKnife .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWColt .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWSingleShotgun .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWDoubleShotgun .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWTommygun .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWMinigun .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWRocketLauncher .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWGrenadeLauncher.GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWPipeBomb .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWFlamer .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWGhostBuster .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWLaser .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toWIronCannon .GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toTile .GetData())->Force(TEX_CONSTANT); + } + catch( char *strError) { + FatalError( strError); + } + +} + + +// clean up +extern void EndHUD(void) +{ + +} + diff --git a/Sources/Entities/Common/Particles.cpp b/Sources/Entities/Common/Particles.cpp index a7a956cbf..f46be6d68 100644 --- a/Sources/Entities/Common/Particles.cpp +++ b/Sources/Entities/Common/Particles.cpp @@ -1,2988 +1,2984 @@ -#include "../StdH/StdH.h" -#include "Entities/BloodSpray.h" -#include "Entities/PlayerWeapons.h" -#include "Entities/WorldSettingsController.h" -#include "Entities/BackgroundViewer.h" - -static CTextureObject _toRomboidTrail; -static CTextureObject _toBombTrail; -static CTextureObject _toFirecrackerTrail; -static CTextureObject _toSpiralTrail; -static CTextureObject _toColoredStarsTrail; -static CTextureObject _toFireball01Trail; -static CTextureObject _toGrenadeTrail; -static CTextureObject _toCannonBall; -static CTextureObject _toRocketTrail; -static CTextureObject _toVerticalGradient; -static CTextureObject _toVerticalGradientAlpha; -static CTextureObject _toBlood01Trail; -static CTextureObject _toLavaTrailGradient; -static CTextureObject _toLavaTrailSmoke; -static CTextureObject _toFlamethrowerTrail; -static CTextureObject _toBoubble01; -static CTextureObject _toBoubble02; -static CTextureObject _toBoubble03; -static CTextureObject _toStar01; -static CTextureObject _toStar02; -static CTextureObject _toStar03; -static CTextureObject _toStar04; -static CTextureObject _toStar05; -static CTextureObject _toStar06; -static CTextureObject _toStar07; -static CTextureObject _toStar08; -static CTextureObject _toBlood; -static CTextureObject _toWaterfallGradient; -static CTextureObject _toGhostbusterBeam; -static CTextureObject _toLightning; -static CTextureObject _toSand; -static CTextureObject _toSandFlowGradient; -static CTextureObject _toWater; -static CTextureObject _toWaterFlowGradient; -static CTextureObject _toLava; -static CTextureObject _toLavaFlowGradient; -static CTextureObject _toBloodSprayTexture; -static CTextureObject _toFlowerSprayTexture; -static CTextureObject _toBonesSprayTexture; -static CTextureObject _toFeatherSprayTexture; -static CTextureObject _toStonesSprayTexture; -static CTextureObject _toLavaSprayTexture; -static CTextureObject _toBeastProjectileSprayTexture; -static CTextureObject _toLavaEruptingTexture; -static CTextureObject _toWoodSprayTexture; -static CTextureObject _toLavaBombTrailSmoke; -static CTextureObject _toLavaBombTrailGradient; -static CTextureObject _toElectricitySparks; -static CTextureObject _toBeastProjectileTrailTexture; -static CTextureObject _toBeastProjectileTrailGradient; -static CTextureObject _toBeastBigProjectileTrailTexture; -static CTextureObject _toBeastBigProjectileTrailGradient; -static CTextureObject _toBeastDebrisTrailGradient; -static CTextureObject _toBeastDebrisTrailTexture; -static CTextureObject _toRaindrop; -static CTextureObject _toSnowdrop; -static CTextureObject _toBulletStone; -static CTextureObject _toBulletSand; -static CTextureObject _toBulletSpark; -static CTextureObject _toBulletSmoke; -static CTextureObject _toBulletWater; -static CTextureObject _toPlayerParticles; -static CTextureObject _toWaterfallFoam; -static CTextureObject _toMetalSprayTexture; - -// array for model vertices in absolute space -CStaticStackArray avVertices; - -#define CT_MAX_PARTICLES_TABLE 512 - -FLOAT afTimeOffsets[CT_MAX_PARTICLES_TABLE]; -FLOAT afStarsPositions[CT_MAX_PARTICLES_TABLE][3]; -UBYTE auStarsColors[CT_MAX_PARTICLES_TABLE][3]; - -void InitParticleTables(void); - -// init particle effects -void InitParticles(void) -{ - try - { - _toRomboidTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Romboid.tex")); - _toBombTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WhiteBubble.tex")); - _toFirecrackerTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FireCracker.tex")); - _toSpiralTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke01.tex")); - _toColoredStarsTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Star01.tex")); - _toFireball01Trail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Fireball01.tex")); - _toGrenadeTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke02.tex")); - _toCannonBall.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\CannonBall.tex")); - _toRocketTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke06.tex")); - _toVerticalGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\VerticalGradient.tex")); - _toVerticalGradientAlpha.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\VerticalGradientAlpha.tex")); - _toBlood01Trail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Blood02.tex")); - _toLavaTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaTrailGradient.tex")); - _toLavaTrailSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaTrailSmoke.tex")); - _toFlamethrowerTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FlameThrower01.tex")); - _toBoubble01.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble01.tex")); - _toBoubble02.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble02.tex")); - _toBoubble03.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble03.tex")); - _toStar01.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star01.tex")); - _toStar02.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star02.tex")); - _toStar03.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star03.tex")); - _toStar04.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star04.tex")); - _toStar05.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star05.tex")); - _toStar06.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star06.tex")); - _toStar07.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star07.tex")); - _toStar08.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star08.tex")); - _toWaterfallGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\Waterfall08.tex")); - _toGhostbusterBeam.SetData_t(CTFILENAME("Models\\Weapons\\GhostBuster\\Projectile\\Ray.tex")); - _toLightning.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Lightning.tex")); - _toSand.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Sand.tex")); - _toSandFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\SandFlow01.tex")); - _toWater.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Water.tex")); - _toWaterFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\WaterFlow01.tex")); - _toLava.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Lava.tex")); - _toLavaFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\LavaFlow01.tex")); - _toBloodSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Blood03.tex")); - _toFlowerSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Flowers.tex")); - _toBonesSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BonesSpill01.tex")); - _toFeatherSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FeatherSpill01.tex")); - _toStonesSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\StonesSpill01.tex")); - _toLavaSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaSpill01.tex")); - _toBeastProjectileSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileSpill.tex")); - _toLavaEruptingTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaErupting.tex")); - _toWoodSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WoodSpill01.tex")); - _toLavaBombTrailSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaBomb.tex")); - _toLavaBombTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaBombGradient.tex")); - _toBeastDebrisTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastDebrisTrailGradient.tex")); - _toBeastProjectileTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileTrail.tex")); - _toBeastProjectileTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileTrailGradient.tex")); - _toBeastBigProjectileTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastBigProjectileTrail.tex")); - _toBeastBigProjectileTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastBigProjectileTrailGradient.tex")); - _toBeastDebrisTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastDebrisTrail.tex")); - _toElectricitySparks.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\ElectricitySparks.tex")); - _toRaindrop.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Raindrop.tex")); - _toSnowdrop.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Snowdrop.tex")); - _toBulletStone.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpray.tex")); - _toBulletWater.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSprayWater.tex")); - _toBulletSand.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpraySand.tex")); - _toBulletSpark.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpark.tex")); - _toBulletSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\SmokeAnim01.tex")); - _toPlayerParticles.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\PlayerParticles.tex")); - _toWaterfallFoam.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WaterfallFoam.tex")); - _toMetalSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\MetalSpill.tex")); - - ((CTextureData*)_toLavaTrailGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toLavaBombTrailGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toBeastDebrisTrailGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toBeastProjectileTrailGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toBeastBigProjectileTrailGradient.GetData())->Force(TEX_STATIC); - ((CTextureData*)_toWaterfallGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toSandFlowGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toWaterFlowGradient .GetData())->Force(TEX_STATIC); - ((CTextureData*)_toLavaFlowGradient .GetData())->Force(TEX_STATIC); - } - catch(char *strError) - { - FatalError(TRANS("Unable to obtain texture: %s"), strError); - } - InitParticleTables(); -} - -// close particle effects -void CloseParticles(void) -{ - _toRomboidTrail.SetData(NULL); - _toBombTrail.SetData(NULL); - _toFirecrackerTrail.SetData(NULL); - _toSpiralTrail.SetData(NULL); - _toColoredStarsTrail.SetData(NULL); - _toFireball01Trail.SetData(NULL); - _toRocketTrail.SetData(NULL); - _toGrenadeTrail.SetData(NULL); - _toCannonBall.SetData(NULL); - _toVerticalGradient.SetData(NULL); - _toVerticalGradientAlpha.SetData(NULL); - _toBlood01Trail.SetData(NULL); - _toLavaTrailGradient.SetData(NULL); - _toWaterfallGradient.SetData(NULL); - _toGhostbusterBeam.SetData( NULL); - _toLightning.SetData( NULL); - _toLavaTrailSmoke.SetData(NULL); - _toFlamethrowerTrail.SetData(NULL); - _toBoubble01.SetData(NULL); - _toBoubble02.SetData(NULL); - _toBoubble03.SetData(NULL); - _toStar01.SetData(NULL); - _toStar02.SetData(NULL); - _toStar03.SetData(NULL); - _toStar04.SetData(NULL); - _toStar05.SetData(NULL); - _toStar06.SetData(NULL); - _toStar07.SetData(NULL); - _toStar08.SetData(NULL); - _toSand.SetData(NULL); - _toSandFlowGradient.SetData(NULL); - _toWater.SetData(NULL); - _toWaterFlowGradient.SetData(NULL); - _toLava.SetData(NULL); - _toLavaFlowGradient.SetData(NULL); - _toLavaBombTrailSmoke.SetData(NULL); - _toLavaBombTrailGradient.SetData(NULL); - _toBloodSprayTexture.SetData(NULL); - _toFlowerSprayTexture.SetData(NULL); - _toBonesSprayTexture.SetData(NULL); - _toFeatherSprayTexture.SetData(NULL); - _toStonesSprayTexture.SetData(NULL); - _toLavaSprayTexture.SetData(NULL); - _toBeastProjectileSprayTexture.SetData(NULL); - _toLavaEruptingTexture.SetData(NULL); - _toWoodSprayTexture.SetData(NULL); - _toElectricitySparks.SetData(NULL); - _toBeastDebrisTrailGradient.SetData(NULL); - _toBeastProjectileTrailTexture.SetData(NULL); - _toBeastProjectileTrailGradient.SetData(NULL); - _toBeastBigProjectileTrailTexture.SetData(NULL); - _toBeastBigProjectileTrailGradient.SetData(NULL); - _toBeastDebrisTrailTexture.SetData(NULL); - _toRaindrop.SetData(NULL); - _toSnowdrop.SetData(NULL); - _toBulletStone.SetData(NULL); - _toBulletWater.SetData(NULL); - _toBulletSand.SetData(NULL); - _toBulletSpark.SetData(NULL); - _toBulletSmoke.SetData(NULL); - _toPlayerParticles.SetData(NULL); - _toWaterfallFoam.SetData(NULL); - _toMetalSprayTexture.SetData(NULL); -} - -void Particles_ViewerLocal(CEntity *penView) -{ - ASSERT(penView!=NULL); - - // ----------- Obtain world settings controller - CWorldSettingsController *pwsc = NULL; - // obtain bcg viewer - CBackgroundViewer *penBcgViewer = (CBackgroundViewer *) penView->GetWorld()->GetBackgroundViewer(); - if( penBcgViewer != NULL) - { - // obtain world settings controller - pwsc = (CWorldSettingsController *) &*penBcgViewer->m_penWorldSettingsController; - } - - // ***** Storm appearing effects - // if world settings controller is valid - if( (pwsc != NULL) && (pwsc->m_tmStormStart != -1)) - { - FLOAT fStormFactor = pwsc->GetStormFactor(); - if( fStormFactor != 0.0f) - { - FLOATaabbox3D boxRainMap; - CTextureData *ptdRainMap; - pwsc->GetHeightMapData( ptdRainMap, boxRainMap); - Particles_Rain( penView, 1.25f, 32, fStormFactor, ptdRainMap, boxRainMap); - } - } -} - -// different particle effects -#define ROMBOID_TRAIL_POSITIONS 16 -void Particles_RomboidTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(ROMBOID_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toRomboidTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - //FLOAT fRand = rand()/FLOAT(RAND_MAX); - FLOAT fAngle = fSeconds*256+iPos*2.0f*PI/ROMBOID_TRAIL_POSITIONS; - FLOAT fSin = FLOAT(sin(fAngle)); - vPos(2) += fSin*iPos/ROMBOID_TRAIL_POSITIONS; - FLOAT fSize = (ROMBOID_TRAIL_POSITIONS-iPos)*0.5f/ROMBOID_TRAIL_POSITIONS+0.1f; - UBYTE ub = 255-iPos*255/ROMBOID_TRAIL_POSITIONS; - Particle_RenderSquare( vPos, fSize, fAngle, RGBToColor(255-ub,ub,255-ub)|ub); - } - // all done - Particle_Flush(); -} - -#define BOMB_TRAIL_POSITIONS 8 -#define BOMB_TRAIL_INTERPOSITIONS 4 -void Particles_BombTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(BOMB_TRAIL_POSITIONS); -} -void Particles_BombTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(BOMB_TRAIL_POSITIONS); - - Particle_PrepareTexture(&_toBombTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); - for(INDEX iPos = plp->lp_ctUsed-1; iPos>=1; iPos--) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - for (INDEX iInter=0; iInterGetLastPositions(FIRECRACKER_TRAIL_POSITIONS); -} -void Particles_FirecrackerTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(FIRECRACKER_TRAIL_POSITIONS); - Particle_PrepareTexture(&_toFirecrackerTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - if( plp->lp_ctUsed<2) return; - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); - INDEX iParticle = plp->lp_ctUsed*FIRECRACKER_TRAIL_INTERPOSITIONS; - for(INDEX iPos = plp->lp_ctUsed-2; iPos>=0; iPos--) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - for (INDEX iInter=0; iInterGetLastPositions(SPIRAL_TRAIL_POSITIONS); - - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - Particle_PrepareTexture(&_toSpiralTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - FLOAT fAngle = fSeconds*32.0f+iPos*2*PI/SPIRAL_TRAIL_POSITIONS; - FLOAT fSin = FLOAT(sin(fAngle)); - FLOAT fCos = FLOAT(cos(fAngle)); - - vPos(1) += fSin*iPos*1.0f/SPIRAL_TRAIL_POSITIONS; - vPos(2) += fCos*iPos*1.0f/SPIRAL_TRAIL_POSITIONS; - - UBYTE ub = iPos*SPIRAL_TRAIL_POSITIONS; - Particle_RenderSquare( vPos, 0.2f, fAngle, RGBToColor(ub,ub,ub)|ub); - } - // all done - Particle_Flush(); -} - -static COLOR _aColors[] = { C_WHITE, C_GRAY, - C_RED, C_GREEN, C_BLUE, C_CYAN, C_MAGENTA, C_YELLOW, C_ORANGE, C_BROWN, C_PINK, - C_lRED, C_lGREEN, C_lBLUE, C_lCYAN, C_lMAGENTA, C_lYELLOW, C_lORANGE, C_lBROWN, C_lPINK -}; - -#define COLORED_STARS_TRAIL_POSITIONS 16 -void Particles_ColoredStarsTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(COLORED_STARS_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toColoredStarsTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos1 = plp->GetPosition(iPos); - //FLOAT3D vPos2 = vPos1; - - FLOAT fAngle = fSeconds*64.0f+iPos*2*PI/COLORED_STARS_TRAIL_POSITIONS; - FLOAT fSin = FLOAT(sin(fAngle)); - //FLOAT fCos = FLOAT(cos(fAngle)); - - FLOAT fDeltaY = fSin/2.0f; - vPos1(2) += fDeltaY; - //vPos2(2) -= fDeltaY; - - FLOAT fRand = rand()/FLOAT(RAND_MAX); - INDEX iRandColor = INDEX(fRand*sizeof(_aColors)/sizeof(COLOR)); - COLOR colColor1 = _aColors[ iRandColor]; - Particle_RenderSquare( vPos1, 0.4f, fAngle, colColor1); - } - // all done - Particle_Flush(); -} - -#define WHITE_LINE_TRAIL_POSITIONS 8 -void Particles_WhiteLineTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(WHITE_LINE_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toSpiralTrail, PBT_ADD); - Particle_SetTexturePart( 1, 1, 256, 256); - - FLOAT3D vOldPos = plp->GetPosition(0); - for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - FLOAT fAngle = fSeconds*4.0f+iPos*PI/WHITE_LINE_TRAIL_POSITIONS; - FLOAT fSin = FLOAT(sin(fAngle)); - FLOAT fCos = FLOAT(cos(fAngle)); - - vPos(1) += fSin*iPos*1.0f/WHITE_LINE_TRAIL_POSITIONS; - vPos(2) += fCos*iPos*1.0f/WHITE_LINE_TRAIL_POSITIONS; - - //UBYTE ub = 255-iPos*256/WHITE_LINE_TRAIL_POSITIONS; - FLOAT fLerpFactor = FLOAT(iPos)/WHITE_LINE_TRAIL_POSITIONS; - COLOR colColor = LerpColor( C_YELLOW, C_dRED, fLerpFactor); - Particle_RenderLine( vPos, vOldPos, 0.05f, colColor); - vOldPos =vPos; - } - // all done - Particle_Flush(); -} - - -#define FIREBALL01_TRAIL_POSITIONS 8 -#define FIREBALL01_TRAIL_INTERPOSITIONS 4 -#define FIREBALL01_TRAIL_PARTICLES (FIREBALL01_TRAIL_INTERPOSITIONS*FIREBALL01_TRAIL_POSITIONS) -void Particles_Fireball01Trail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(FIREBALL01_TRAIL_POSITIONS); -} -void Particles_Fireball01Trail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(FIREBALL01_TRAIL_POSITIONS); - Particle_PrepareTexture(&_toFireball01Trail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*FIREBALL01_TRAIL_INTERPOSITIONS; - for(INDEX iPos = plp->lp_ctUsed-2; iPos>=0; iPos--) { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - COLOR colColor; - for (INDEX iInter=0; iInterGetLastPositions(GRENADE_TRAIL_POSITIONS); -} -void Particles_GrenadeTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(GRENADE_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toGrenadeTrail, PBT_MULTIPLY); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(0); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*GRENADE_TRAIL_INTERPOSITIONS; - for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - for (INDEX iInter=0; iInterGetLastPositions(CANNON_TRAIL_POSITIONS); -} -void Particles_CannonBall(CEntity *pen, FLOAT fSpeedRatio) -{ - CLastPositions *plp = pen->GetLastPositions(CANNON_TRAIL_POSITIONS); - // FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toCannonBall, PBT_BLEND); - Particle_SetTexturePart( 512, 512, 0, 0); - - FLOAT3D vOldPos = plp->GetPosition(1); - for( INDEX iPos=2; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - UBYTE ub = UBYTE((255-iPos*256/plp->lp_ctUsed)*fSpeedRatio); - FLOAT fSize = (CANNON_TRAIL_POSITIONS-iPos)*0.04f+0.04f; - Particle_RenderLine( vPos, vOldPos, fSize, RGBToColor(ub,ub,ub)|ub); - vOldPos=vPos; - } - // all done - Particle_Flush(); -} - -#define LAVA_TRAIL_POSITIONS 32 -#define LAVA_TRAIL_INTERPOSITIONS 1 -void Particles_LavaTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(LAVA_TRAIL_POSITIONS); -} -void Particles_LavaTrail(CEntity *pen) -{ - CLastPositions *plp = pen->GetLastPositions(LAVA_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - CTextureData *pTD = (CTextureData *) _toLavaTrailGradient.GetData(); - Particle_PrepareTexture(&_toLavaTrailSmoke, PBT_BLEND); - //Particle_PrepareTexture(&_toLavaTrailSmoke, PBT_MULTIPLY); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(0); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*LAVA_TRAIL_INTERPOSITIONS; - for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); - Particle_RenderSquare( vPos, fSize, fAngle, col); - iParticle++; - } - } - // all done - Particle_Flush(); -} - -#define LAVA_BOMB_TRAIL_POSITIONS 16 -#define LAVA_BOMB_TRAIL_INTERPOSITIONS 1 -void Particles_LavaBombTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(LAVA_BOMB_TRAIL_POSITIONS); -} - -void Particles_LavaBombTrail(CEntity *pen, FLOAT fSizeMultiplier) -{ - CLastPositions *plp = pen->GetLastPositions(LAVA_BOMB_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - CTextureData *pTD = (CTextureData *) _toLavaBombTrailGradient.GetData(); - Particle_PrepareTexture(&_toLavaBombTrailSmoke, PBT_BLEND); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(0); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*LAVA_BOMB_TRAIL_INTERPOSITIONS; - for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) - { - INDEX iRnd = ((ULONG)fSeconds+iPos)%CT_MAX_PARTICLES_TABLE; - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - if( *pvPos1 == *pvPos2) continue; - for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); - Particle_RenderSquare( vPos, fSize, fAngle, col); - iParticle++; - } - } - // all done - Particle_Flush(); -} - -#define BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS 8 -#define BEAST_PROJECTILE_DEBRIS_TRAIL_INTERPOSITIONS 1 -void Particles_BeastProjectileDebrisTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS); -} - -void Particles_BeastProjectileDebrisTrail(CEntity *pen, FLOAT fSizeMultiplier) -{ - CLastPositions *plp = pen->GetLastPositions(BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - CTextureData *pTD = (CTextureData *) _toBeastDebrisTrailGradient.GetData(); - Particle_PrepareTexture(&_toBeastDebrisTrailTexture, PBT_BLEND); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(0); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*BEAST_PROJECTILE_DEBRIS_TRAIL_INTERPOSITIONS; - for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); - Particle_RenderSquare( vPos, fSize, fAngle, col); - iParticle++; - } - } - // all done - Particle_Flush(); -} - -#define BEAST_PROJECTILE_TRAIL_POSITIONS 32 -#define BEAST_PROJECTILE_TRAIL_INTERPOSITIONS 1 -void Particles_BeastProjectileTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(BEAST_PROJECTILE_TRAIL_POSITIONS); -} - -#define BEAST_PROJECTILE_LINE_PARTICLES 0.4f -#define BEAST_PROJECTILE_FADE_OUT 0.3f -#define BEAST_PROJECTILE_TOTAL_TIME 0.6f -void Particles_BeastProjectileTrail( CEntity *pen, FLOAT fSize, FLOAT fHeight, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toBeastProjectileTrailTexture, PBT_BLEND); - Particle_SetTexturePart( 512, 2048, 0, 0); - - CTextureData *pTD = (CTextureData *) _toBeastProjectileTrailGradient.GetData(); - - CPlacement3D pl = pen->GetLerpedPlacement(); - FLOATmatrix3D m; - MakeRotationMatrixFast(m, pl.pl_OrientationAngle); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( -m(1,3), -m(2,3), -m(3,3)); - FLOAT3D vZ( m(1,2), m(2,2), m(3,2)); - FLOAT3D vCenter = pl.pl_PositionVector+vY*fHeight; - - for( INDEX iStar=0; iStar(1.0f-BEAST_PROJECTILE_FADE_OUT)) fFade=(1-fT)*(1/BEAST_PROJECTILE_FADE_OUT); - //else fFade=1.0f; - -#define GET_POS( time) vCenter + \ - vX*(afStarsPositions[iStar][0]*time*fSize*1.5) +\ - vY*(-time*time*10.0f+(afStarsPositions[iStar][1]*2+2.0f)*1.2f*time) +\ - vZ*(afStarsPositions[iStar][2]*time*fSize*1.5); - - FLOAT3D vPos = GET_POS( fT); - COLOR colStar = pTD->GetTexel( FloatToInt(fT*8192), 0); - - if( fT>BEAST_PROJECTILE_LINE_PARTICLES) - { - FLOAT fTimeOld = fT-0.25f; - FLOAT3D vOldPos = GET_POS( fTimeOld); - Particle_RenderLine( vOldPos, vPos, 0.4f, colStar); - } - else - { - Particle_RenderSquare( vPos, 0.5f, fT*360.0f, colStar); - } - } - // all done - Particle_Flush(); -} - -#define BEAST_BIG_PROJECTILE_TRAIL_POSITIONS 32 -#define BEAST_BIG_PROJECTILE_TRAIL_INTERPOSITIONS 1 -void Particles_BeastBigProjectileTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(BEAST_BIG_PROJECTILE_TRAIL_POSITIONS); -} - -#define BIG_BEAST_PROJECTILE_LINE_PARTICLES 0.4f -#define BIG_BEAST_PROJECTILE_FADE_OUT 0.4f -#define BIG_BEAST_PROJECTILE_TOTAL_TIME 0.6f -void Particles_BeastBigProjectileTrail( CEntity *pen, FLOAT fSize, FLOAT fZOffset, FLOAT fYOffset, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toBeastBigProjectileTrailTexture, PBT_BLEND); - Particle_SetTexturePart( 512, 2048, 0, 0); - - CTextureData *pTD = (CTextureData *) _toBeastBigProjectileTrailGradient.GetData(); - - CPlacement3D pl = pen->GetLerpedPlacement(); - FLOATmatrix3D m; - MakeRotationMatrixFast(m, pl.pl_OrientationAngle); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( -m(1,3), -m(2,3), -m(3,3)); - FLOAT3D vZ( m(1,2), m(2,2), m(3,2)); - FLOAT3D vCenter = pl.pl_PositionVector+vY*fZOffset+vZ*fYOffset; - - for( INDEX iStar=0; iStar(1.0f-BIG_BEAST_PROJECTILE_FADE_OUT)) fFade=(1-fT)*(1/BIG_BEAST_PROJECTILE_FADE_OUT); - else fFade=1.0f; - -#define GET_POS_BIG( time) vCenter + \ - vX*(afStarsPositions[iStar][0]*time*fSize*1.5) +\ - vY*(time*time*-15.0f+(afStarsPositions[iStar][1]*2+3.0f)*1.2f*time) +\ - vZ*(afStarsPositions[iStar][2]*time*fSize*1.5); - - FLOAT3D vPos = GET_POS_BIG( fT); - COLOR colStar = pTD->GetTexel( FloatToInt(fT*8192), 0); - - if( fT>BIG_BEAST_PROJECTILE_LINE_PARTICLES) - { - FLOAT fTimeOld = fT-0.125f; - FLOAT3D vOldPos = GET_POS_BIG( fTimeOld); - Particle_RenderLine( vOldPos, vPos, 0.6f*fFade, colStar); - } - else - { - Particle_RenderSquare( vPos, 0.5, fT*360.0f, colStar); - } - } - // all done - Particle_Flush(); -} - -#define ROCKET_TRAIL_POSITIONS 16 -#define ROCKET_TRAIL_INTERPOSITIONS 3 -void Particles_RocketTrail_Prepare(CEntity *pen) -{ - pen->GetLastPositions(ROCKET_TRAIL_POSITIONS); -} -void Particles_RocketTrail(CEntity *pen, FLOAT fStretch) -{ - CLastPositions *plp = pen->GetLastPositions(ROCKET_TRAIL_POSITIONS); - //FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toRocketTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D *pvPos1; - const FLOAT3D *pvPos2 = &plp->GetPosition(1); - INDEX iParticle = 0; - INDEX iParticlesLiving = plp->lp_ctUsed*ROCKET_TRAIL_INTERPOSITIONS; - for( INDEX iPos=2; iPoslp_ctUsed; iPos++) - { - pvPos1 = pvPos2; - pvPos2 = &plp->GetPosition(iPos); - if( (*pvPos2 - *pvPos1).Length() == 0.0f) - { - continue; - } - for (INDEX iInter=0; iInterGetPosition(1); - for( INDEX iPos=2; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - if( (vPos - vOldPos).Length() == 0.0f) - { - continue; - } - UBYTE ub = UBYTE(255-iPos*256/plp->lp_ctUsed); - FLOAT fSize = iPos*0.01f*fStretch+0.005f; - Particle_RenderLine( vPos, vOldPos, fSize, RGBToColor(ub,ub,ub)|ub); - vOldPos=vPos; - } - // all done - Particle_Flush(); -} - - -#define BLOOD01_TRAIL_POSITIONS 15 -void Particles_BloodTrail(CEntity *pen) -{ - // get blood type - const INDEX iBloodType = GetSP()->sp_iBlood; - if( iBloodType<1) return; - COLOR col; - if( iBloodType==3) Particle_PrepareTexture( &_toFlowerSprayTexture, PBT_BLEND); - else Particle_PrepareTexture( &_toBloodSprayTexture, PBT_BLEND); - - CLastPositions *plp = pen->GetLastPositions(BLOOD01_TRAIL_POSITIONS); - FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; - FLOAT3D vGDir = ((CMovableEntity *)pen)->en_vGravityDir; - - for( INDEX iPos=0; iPoslp_ctUsed; iPos++) - { - Particle_SetTexturePart( 256, 256, iPos%8, 0); - FLOAT3D vPos = plp->GetPosition(iPos); - //FLOAT fRand = rand()/FLOAT(RAND_MAX); - FLOAT fAngle = iPos*2.0f*PI/BLOOD01_TRAIL_POSITIONS; - //FLOAT fSin = FLOAT(sin(fAngle)); - FLOAT fT = iPos*_pTimer->TickQuantum; - vPos += vGDir*fGA*fT*fT/8.0f; - FLOAT fSize = 0.2f-iPos*0.15f/BLOOD01_TRAIL_POSITIONS; - UBYTE ub = 255-iPos*255/BLOOD01_TRAIL_POSITIONS; - if( iBloodType==3) col = C_WHITE|ub; - else if( iBloodType==2) col = RGBAToColor(ub,20,20,ub); - else col = RGBAToColor(0,ub,0,ub); - Particle_RenderSquare( vPos, fSize, fAngle, col); - } - // all done - Particle_Flush(); -} - - -INDEX Particles_FireBreath(CEntity *pen, FLOAT3D vSource, FLOAT3D vTarget, FLOAT tmStart, FLOAT tmStop) -{ - Particle_PrepareTexture( &_toFlamethrowerTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fFlameLife = 2; - INDEX ctFlames = 32; - INDEX ctRendered = 0; - FLOAT tmFlameDelta = 0.25f; - FLOAT3D vFocus = Lerp( vSource, vTarget, 0.25f); - for( INDEX iFlame=0; iFlamefFlameLife || tmFakeStart>tmStop) continue; - // calculate fraction part - FLOAT fT=fPassedTime/fFlameLife; - fT=fT-INDEX(fT); - // lerp position - FLOAT3D vRnd = FLOAT3D( afStarsPositions[iFlame][0],afStarsPositions[iFlame][1], - afStarsPositions[iFlame][2])*10; - FLOAT3D vPos = Lerp( vSource, vFocus+vRnd, fT); - FLOAT fSize = 5.0f*fT+5.0f; - UBYTE ub = CalculateRatio( fT, 0.0f, 1.0f, 0.1f, 0.2f)*255; - Particle_RenderSquare( vPos, fSize, fT*(1.0f+afStarsPositions[iFlame*3][1])*360.0f, RGBToColor(ub,ub,ub)|0xFF); - ctRendered++; - } - // all done - Particle_Flush(); - return ctRendered; -} - -INDEX Particles_Regeneration(CEntity *pen, FLOAT tmStart, FLOAT tmStop, FLOAT fYFactor, BOOL bDeath) -{ - Particle_PrepareTexture( &_toElectricitySparks, PBT_BLEND); - Particle_SetTexturePart( 512, 1024, 0, 0); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fLife = 1.5; - INDEX ctRendered = 0; - FLOAT tmDelta = 0.001f; - for( INDEX iVtx=0; iVtx<1024*4; iVtx++) - { - FLOAT tmFakeStart = tmStart+iVtx*tmDelta; - FLOAT fPassedTime = fNow-tmFakeStart; - if(fPassedTime<0.0f || fPassedTime>fLife || tmFakeStart>tmStop) continue; - // calculate fraction part - FLOAT fT=fPassedTime/fLife; - fT=fT-INDEX(fT); - - INDEX iRnd = iVtx%CT_MAX_PARTICLES_TABLE; - FLOAT3D vRnd= FLOAT3D(afStarsPositions[iRnd][0],afStarsPositions[iRnd][1]+0.5f,afStarsPositions[iRnd][2]); - vRnd(1) *= 800.0f; - vRnd(2) *= 400.0f; - vRnd(3) *= 800.0f; - FLOAT3D vSource = vCenter+vRnd; - FLOAT3D vDestination = vCenter+vRnd*0.05f; - vDestination(2) += 40.0f*fYFactor+vRnd(2)/8.0f*fYFactor; - FLOAT3D vPos, vPos2; - // lerp position - if(bDeath) { - vPos = Lerp( vSource, vDestination, 1.0f-fT); - } else { - vPos = Lerp( vSource, vDestination, fT); - } - FLOAT fT2 = Clamp(fT-0.025f-fT*fT*0.025f, 0.0f, 1.0f); - - if(bDeath) { - vPos2 = Lerp( vSource, vDestination, 1.0f-fT2); - } else { - vPos2 = Lerp( vSource, vDestination, fT2); - } - - UBYTE ubR = 192+afStarsPositions[iRnd][0]*64; - UBYTE ubG = 192+afStarsPositions[iRnd][1]*64; - UBYTE ubB = 192+afStarsPositions[iRnd][2]*64; - UBYTE ubA = CalculateRatio( fT, 0.0f, 1.0f, 0.4f, 0.01f)*255; - COLOR colLine = RGBToColor( ubR, ubG, ubB) | ubA; - - FLOAT fSize = 1.0f; - Particle_RenderLine( vPos2, vPos, fSize, colLine); - ctRendered++; - } - - // flush array - avVertices.PopAll(); - // all done - Particle_Flush(); - return ctRendered; -} - -#define SECONDS_PER_PARTICLE 0.01f -void Particles_FlameThrower(const CPlacement3D &plEnd, const CPlacement3D &plStart, - FLOAT fEndElapsed, FLOAT fStartElapsed) -{ - Particle_PrepareTexture( &_toFlamethrowerTrail, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - const FLOAT3D &vStart = plStart.pl_PositionVector; - const FLOAT3D &vEnd = plEnd.pl_PositionVector; - FLOAT3D vDelta = (vEnd-vStart)/(fEndElapsed-fStartElapsed); - FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); - - for(FLOAT fTime = ceil(fStartElapsed/SECONDS_PER_PARTICLE)*SECONDS_PER_PARTICLE; - fTime0.75f) ub = 0; - else if( fTime>0.5f) ub = (-4*fTime+3)*96; - - ASSERT(fTime>=0.0f); - ASSERT(fSize>=0.0f); - FLOAT3D vPos = vStart+vDelta*(fTime-fStartElapsed)+FLOAT3D(0.0f, fRise, 0.0f); - Particle_RenderSquare( vPos, fSize, fAngle, RGBToColor(ub,ub,ub)|0xFF); - } - // all done - Particle_Flush(); -} - -void SetupParticleTexture(enum ParticleTexture ptTexture) -{ - switch(ptTexture) { - case PT_STAR01: Particle_PrepareTexture(&_toStar01, PBT_ADD); break; - case PT_STAR02: Particle_PrepareTexture(&_toStar02, PBT_ADD); break; - case PT_STAR03: Particle_PrepareTexture(&_toStar03, PBT_ADD); break; - case PT_STAR04: Particle_PrepareTexture(&_toStar04, PBT_ADD); break; - case PT_STAR05: Particle_PrepareTexture(&_toStar05, PBT_ADD); break; - case PT_STAR06: Particle_PrepareTexture(&_toStar06, PBT_ADD); break; - case PT_STAR07: Particle_PrepareTexture(&_toStar07, PBT_ADD); break; - case PT_STAR08: Particle_PrepareTexture(&_toStar08, PBT_ADD); break; - case PT_BOUBBLE01: Particle_PrepareTexture(&_toBoubble01, PBT_ADD); break; - case PT_BOUBBLE02: Particle_PrepareTexture(&_toBoubble02, PBT_ADD); break; - case PT_WATER01: Particle_PrepareTexture(&_toBoubble03, PBT_BLEND); break; - case PT_WATER02: Particle_PrepareTexture(&_toBoubble03, PBT_BLEND); break; - case PT_SANDFLOW: Particle_PrepareTexture(&_toSand, PBT_BLEND); break; - case PT_WATERFLOW: Particle_PrepareTexture(&_toWater, PBT_BLEND); break; - case PT_LAVAFLOW: Particle_PrepareTexture(&_toLava, PBT_BLEND); break; - default: ASSERT(FALSE); - } - Particle_SetTexturePart( 512, 512, 0, 0); -} - -void InitParticleTables(void) -{ - for( INDEX iStar=0; iStar7.0f) return; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - CPlacement3D plSource = pen->GetLerpedPlacement(); - FLOAT3D vCenter = plSource.pl_PositionVector+vY*fHeight; - - for( INDEX iStar=0; iStarSTARDUST_EXIST_TIME) continue; - FLOAT fFade = -2.0f * Abs(fT*(1.0f/STARDUST_EXIST_TIME)-0.5f)+1.0f; - - INDEX iRandomFromPlacement = - (ULONG)(plSource.pl_PositionVector(1)+plSource.pl_PositionVector(3))&(ctOffsetSpace-1); - INDEX iMemeber = iStar+iRandomFromPlacement; - const FLOAT3D vPos = vCenter+FLOAT3D( afStarsPositions[iMemeber][0], - afStarsPositions[iMemeber][1], - afStarsPositions[iMemeber][2])*fSize; - COLOR colStar = RGBToColor( auStarsColors[iMemeber][0]*fFade, - auStarsColors[iMemeber][1]*fFade, - auStarsColors[iMemeber][2]*fFade); - Particle_RenderSquare( vPos, 0.15f, 0, colStar|0xFF); - } - // all done - Particle_Flush(); -} - -#define RISING_TOTAL_TIME 5.0f -#define RISING_EXIST_TIME 3.0f -#define RISING_FADE_IN 0.3f -#define RISING_FADE_OUT 0.3f - -void Particles_Rising(CEntity *pen, FLOAT fStartTime, FLOAT fStopTime, FLOAT fStretchAll, - FLOAT fStretchX, FLOAT fStretchY, FLOAT fStretchZ, FLOAT fSize, - enum ParticleTexture ptTexture, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - if( Particle_GetMipFactor()>7.0f) return; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fStretchY; - - FLOAT fPowerFactor = Clamp((fNow - fStartTime)/5.0f,0.0f,1.0f); - fPowerFactor *= Clamp(1+(fStopTime-fNow)/5.0f,0.0f,1.0f); - //ctParticles = FLOAT(ctParticles) * fPowerFactor; - - for( INDEX iStar=0; iStar1) continue; - FLOAT fFade; - if(fF<(RISING_FADE_IN*fPowerFactor)) fFade=fF*(1/(RISING_FADE_IN*fPowerFactor)); - else if (fF>(1.0f-RISING_FADE_OUT)) fFade=(1-fF)*(1/RISING_FADE_OUT); - else fFade=1.0f; - - FLOAT3D vPos = vCenter+FLOAT3D( - afStarsPositions[iStar][0]*fStretchX, - afStarsPositions[iStar][1]*fStretchY, - afStarsPositions[iStar][2]*fStretchZ)*fStretchAll+vY*(fF*fStretchAll*0.5f); - vPos(1)+=sin(fF*4.0f)*0.05f*fStretchAll; - vPos(3)+=cos(fF*4.0f)*0.05f*fStretchAll; - - UBYTE ub = NormFloatToByte( fFade); - COLOR colStar = RGBToColor( ub, ub, ub>>1); - Particle_RenderSquare( vPos, fSize*fPowerFactor, 0, colStar|(UBYTE(0xFF*fPowerFactor))); - } - // all done - Particle_Flush(); -} - -#define CT_SPIRAL_PARTICLES 4 -#define CT_SPIRAL_TRAIL 10 -void Particles_Spiral( CEntity *pen, FLOAT fSize, FLOAT fHeight, - enum ParticleTexture ptTexture, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - - FLOAT fMipFactor = Particle_GetMipFactor(); - if( fMipFactor>7.0f) return; - fMipFactor = 2.5f-fMipFactor*0.3f; - fMipFactor = Clamp( fMipFactor, 0.0f, 1.0f); - INDEX ctSpiralTrail = fMipFactor*CT_SPIRAL_TRAIL; - if( ctSpiralTrail<=0) return; - FLOAT fTrailDelta = 0.1f/fMipFactor; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; - - for( INDEX iStar=0; iStar>1); - Particle_RenderSquare( vPos, 0.2f, 0, colStar|0xFF); - } - } - // all done - Particle_Flush(); -} - -#define EMANATE_FADE_IN 0.2f -#define EMANATE_FADE_OUT 0.6f -#define EMANATE_TOTAL_TIME 1.0f -#define EMANATE_EXIST_TIME 0.5f -void Particles_Emanate( CEntity *pen, FLOAT fSize, FLOAT fHeight, - enum ParticleTexture ptTexture, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - if( Particle_GetMipFactor()>7.0f) return; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; - - for( INDEX iStar=0; iStar1) continue; - FLOAT fFade; - if(fF(1.0f-EMANATE_FADE_OUT)) fFade=(1-fF)*(1/EMANATE_FADE_OUT); - else fFade=1.0f; - - FLOAT3D vPos = vCenter+FLOAT3D( - afStarsPositions[iStar][0], - afStarsPositions[iStar][1], - afStarsPositions[iStar][2])*fSize*(fF+0.4f); - - UBYTE ub = NormFloatToByte( fFade); - COLOR colStar = RGBToColor( ub, ub, ub>>1); - Particle_RenderSquare( vPos, 0.1f, 0, colStar|0xFF); - } - // all done - Particle_Flush(); -} - -#define WATERFALL_FOAM_FADE_IN 0.1f -#define WATERFALL_FOAM_FADE_OUT 0.4f -void Particles_WaterfallFoam(CEntity *pen, FLOAT fSizeX, FLOAT fSizeY, FLOAT fSizeZ, - FLOAT fParticleSize, FLOAT fSpeed, FLOAT fSpeedY, FLOAT fLife, INDEX ctParticles) -{ - if(fLife<=0) return; - - Particle_PrepareTexture( &_toWaterfallFoam, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - for( INDEX iFoam=0; iFoam7.0f) return; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - for( INDEX iStar=0; iStar1) continue; - FLOAT fFade; - if(fF(1.0f-EMANATE_FADE_OUT)) fFade=(1-fF)*(1/EMANATE_FADE_OUT); - else fFade=1.0f; - - FLOAT fX = (afStarsPositions[iStar][0]+0.5f)*fSizeX*(1+fF*fAway); - FLOAT fY = fSizeY*fF; - FLOAT fZ = (afStarsPositions[iStar][2]+0.5f)*fSizeZ*(1+fF*fAway); - FLOAT3D vPos = vCenter + vX*fX + vY*fY + vZ*fZ; - - UBYTE ub = NormFloatToByte( fFade); - COLOR colStar = RGBToColor( ub, ub, ub); - Particle_RenderSquare( vPos, fParticleSize, 0, colStar|0xFF); - } - // all done - Particle_Flush(); -} - -#define CT_FOUNTAIN_TRAIL 3 -#define FOUNTAIN_FADE_IN 0.6f -#define FOUNTAIN_FADE_OUT 0.4f -#define FOUNTAIN_TOTAL_TIME 0.6f -void Particles_Fountain( CEntity *pen, FLOAT fSize, FLOAT fHeight, - enum ParticleTexture ptTexture, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - SetupParticleTexture( ptTexture); - CTextureData *pTD = (CTextureData *) _toWaterfallGradient.GetData(); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; - - for( INDEX iStar=0; iStar(1.0f-FOUNTAIN_FADE_OUT)) fFade=(1-fT)*(1/FOUNTAIN_FADE_OUT); - else fFade=1.0f; - fFade *= (CT_FOUNTAIN_TRAIL-iTrail)*(1.0f/CT_FOUNTAIN_TRAIL); - - FLOAT3D vPos = vCenter + - vX*(afStarsPositions[iStar][0]*fT*fSize) + - vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*2+4.0f)*1.2f*fT) + - vZ*(afStarsPositions[iStar][2]*fT*fSize); - - COLOR colStar = pTD->GetTexel( FloatToInt(fFade*2048), 0); - ULONG ulA = FloatToInt( ((colStar&CT_AMASK)>>CT_ASHIFT) * fFade); - colStar = (colStar&~CT_AMASK) | (ulA<en_ulID)%CT_MAX_PARTICLES_TABLE; - Particle_SetTexturePart( 512, 512, iRnd1%3, 0); - - FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; - FLOAT fBoxSize = boxOwner.Size().Length(); - for(INDEX iSmoke=0; iSmoke<2+fDamage*2; iSmoke++) - { - INDEX iRnd2 = INDEX(tmStarted*12345.0f+iSmoke+fDamage*10.0f)%(CT_MAX_PARTICLES_TABLE/2); - FLOAT fLifeTime = 2.0f+(afStarsPositions[iRnd2][0]+0.5f)*2.0f; - FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.4f, 0.6f); - - FLOAT fRndAppearX = afStarsPositions[iRnd2][0]*fBoxSize*0.125f; - FLOAT fRndAppearZ = afStarsPositions[iRnd2][2]*fBoxSize*0.125f; - FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; - vPos(1) += fRndAppearX; - vPos(3) += fRndAppearZ; - vPos(2) += ((afStarsPositions[iRnd2+4][1]+0.5f)*2.0f+1.5f)*fT+boxOwner.Size()(2)*0.0025f; - - COLOR col = C_dGRAY|UBYTE(64.0f*fRatio); - FLOAT fRotation = afStarsPositions[iRnd2+5][0]*360+fT*200.0f*afStarsPositions[iRnd2+3][0]; - FLOAT fSize = - 0.025f*fDamage+ - (afStarsPositions[iRnd2+6][2]+0.5f)*0.075 + - (0.15f+(afStarsPositions[iRnd2+2][1]+0.5f)*0.075f*fBoxSize)*fT; - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - - // all done - Particle_Flush(); -} - -#define RUNNING_DUST_TRAIL_POSITIONS 3*20 -void Particles_RunningDust_Prepare(CEntity *pen) -{ - pen->GetLastPositions(RUNNING_DUST_TRAIL_POSITIONS); -} -void Particles_RunningDust(CEntity *pen) -{ - Particle_PrepareTexture( &_toBulletSmoke, PBT_BLEND); - CLastPositions *plp = pen->GetLastPositions(RUNNING_DUST_TRAIL_POSITIONS); - FLOAT3D vOldPos = plp->GetPosition(1); - for(INDEX iPos = 2; iPoslp_ctUsed; iPos++) - { - FLOAT3D vPos = plp->GetPosition(iPos); - if( (vPos-vOldPos).Length()<1.0f) continue; - FLOAT tmStarted = _pTimer->CurrentTick()-iPos*_pTimer->TickQuantum; - INDEX iRnd = INDEX(Abs(vPos(1)*1234.234f+vPos(2)*9834.123f+vPos(3)*543.532f+pen->en_ulID))%(CT_MAX_PARTICLES_TABLE/2); - if( iRnd&3) continue; - - INDEX iRndTex = iRnd*324561+pen->en_ulID; - Particle_SetTexturePart( 512, 512, iRndTex%3, 0); - - FLOAT fLifeTime = 2.8f-(afStarsPositions[iRnd][1]+0.5f)*1.0f; - - FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; - FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.1f, 0.25f); - - FLOAT fRndAppearX = afStarsPositions[iRnd][0]*1.0f; - FLOAT fRndSpeedY = (afStarsPositions[iRnd][1]+0.5f)*0.5f; - FLOAT fRndAppearZ = afStarsPositions[iRnd][2]*1.0f; - vPos(1) += fRndAppearX; - vPos(2) += (0.5f+fRndSpeedY)*fT; - vPos(3) += fRndAppearZ; - - FLOAT fRndBlend = 8.0f+(afStarsPositions[iRnd*2][1]+0.5f)*64.0f; - UBYTE ubRndH = UBYTE( (afStarsPositions[iRnd][0]+0.5f)*64); - UBYTE ubRndS = UBYTE( (afStarsPositions[iRnd][1]+0.5f)*32); - UBYTE ubRndV = UBYTE( 128+afStarsPositions[iRnd][0]*64.0f); - COLOR col = HSVToColor(ubRndH,ubRndS,ubRndV)|UBYTE(fRndBlend*fRatio); - //col=C_RED|CT_OPAQUE; - FLOAT fRotation = afStarsPositions[iRnd+5][0]*360+fT*50.0f*afStarsPositions[iRnd+3][0]; - FLOAT fSize = - 0.75f+(afStarsPositions[iRnd+6][2]+0.5f)*0.25 + // static size - (0.4f+(afStarsPositions[iRnd+2][1]+0.5f)*0.4f)*fT; // dinamic size - Particle_RenderSquare( vPos, fSize, fRotation, col); - vOldPos=vPos; - } - // all done - Particle_Flush(); -} - -void Particles_MetalParts( CEntity *pen, FLOAT tmStarted, FLOATaabbox3D boxOwner, FLOAT fDamage) -{ - Particle_PrepareTexture( &_toMetalSprayTexture, PBT_BLEND); - FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; - FLOAT fGA = 30.0f; - - FLOAT fBoxSize = boxOwner.Size().Length(); - for(INDEX iPart=0; iPart<6+fDamage*3.0f; iPart++) - { - INDEX iRnd = INDEX(tmStarted*12345.0f+iPart)%CT_MAX_PARTICLES_TABLE; - FLOAT fLifeTime = 2.0f+(afStarsPositions[iRnd][0]+0.5f)*2.0f; - FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.1f, 0.1f); - Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iPart)%8, 0); - - FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; - vPos(1) += afStarsPositions[iRnd][0]*fT*15; - vPos(2) += afStarsPositions[iRnd][1]*fT*15-fGA/2.0f*fT*fT+boxOwner.Size()(2)*0.25f; - vPos(3) += afStarsPositions[iRnd][2]*fT*15; - - UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 12+(afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1])*8); - UBYTE ubRndV = UBYTE( 192+(afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - //ubRndS = 0; - ubRndV = 255; - COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|UBYTE(255.0f*fRatio); - FLOAT fRotation = fT*400.0f*afStarsPositions[iRnd][0]; - FLOAT fSize = fBoxSize*0.005f+0.125f+afStarsPositions[iRnd][1]*0.025f; - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - - // all done - Particle_Flush(); -} - -#define ELECTRICITY_SPARKS_FADE_OUT_TIME 0.4f -#define ELECTRICITY_SPARKS_TOTAL_TIME 1.0f -void Particles_ElectricitySparks( CEntity *pen, FLOAT fTimeAppear, FLOAT fSize, FLOAT fHeight, INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE/2); - FLOAT fT = _pTimer->GetLerpedCurrentTick()-fTimeAppear; - - Particle_PrepareTexture( &_toElectricitySparks, PBT_BLEND); - Particle_SetTexturePart( 512, 1024, 0, 0); - - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; - - for( INDEX iSpark=0; iSparkELECTRICITY_SPARKS_TOTAL_TIME) - { - fFade=0; - } - else if(fT>ELECTRICITY_SPARKS_FADE_OUT_TIME) - { - fFade=-1.0f/(ELECTRICITY_SPARKS_TOTAL_TIME-ELECTRICITY_SPARKS_FADE_OUT_TIME)*(fT-ELECTRICITY_SPARKS_TOTAL_TIME); - } - else - { - fFade=1.0f; - } - - FLOAT fTold = fT-0.05f; - -#define SPARK_CURVE( time) \ - vCenter + \ - vX*(afStarsPositions[iSpark][0]*time*fSize*3) + \ - vY*(afStarsPositions[iSpark][1]*10.0f*time-(15.0f+afStarsPositions[iSpark*2][1]*15.0f)*time*time) + \ - vZ*(afStarsPositions[iSpark][2]*time*fSize*3); - - FLOAT3D vPosOld = SPARK_CURVE( fTold); - FLOAT3D vPosNew = SPARK_CURVE( fT); - - UBYTE ubR = 224+(afStarsPositions[iSpark][2]+0.5f)*32; - UBYTE ubG = 224+(afStarsPositions[iSpark][2]+0.5f)*32; - UBYTE ubB = 160; - UBYTE ubA = FloatToInt( 255 * fFade); - COLOR colStar = RGBToColor( ubR, ubG, ubB) | ubA; - Particle_RenderLine( vPosOld, vPosNew, 0.075f, colStar); - } - // all done - Particle_Flush(); -} - -void Particles_LavaErupting(CEntity *pen, FLOAT fStretchAll, FLOAT fSize, - FLOAT fStretchX, FLOAT fStretchY, FLOAT fStretchZ, - FLOAT fActivateTime) -{ - FLOAT fT = _pTimer->GetLerpedCurrentTick()-fActivateTime; - if( fT>10.0f) return; - - Particle_PrepareTexture( &_toLavaEruptingTexture, PBT_ADD); - INDEX iTexture = ((ULONG)fActivateTime)%3; - Particle_SetTexturePart( 512, 512, iTexture, 0); - FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; - - INDEX iRnd1 = ((ULONG)fActivateTime)%CT_MAX_PARTICLES_TABLE; - INDEX iRnd2 = (~(ULONG)fActivateTime)%CT_MAX_PARTICLES_TABLE; - - FLOAT fRndAppearX = afStarsPositions[iRnd2][0]*fStretchAll; - FLOAT fRndAppearZ = afStarsPositions[iRnd2][1]*fStretchAll; - FLOAT fRndRotation = afStarsPositions[iRnd2][2]; - - FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; - vPos(1) += fRndAppearX+afStarsPositions[iRnd1][0]*fT*fStretchX*10; - vPos(2) += (fStretchY+(fStretchY*0.25f*afStarsPositions[iRnd1][1]))*fT-fGA/2.0f*fT*fT; - vPos(3) += fRndAppearZ+afStarsPositions[iRnd1][2]*fT*fStretchZ*10; - - Particle_RenderSquare( vPos, fSize+afStarsPositions[iRnd2][2]*fSize*0.5f, fRndRotation*300*fT, C_WHITE|CT_OPAQUE); - - // all done - Particle_Flush(); -} - -#define CT_ATOMIC_TRAIL 32 -void Particles_Atomic( CEntity *pen, FLOAT fSize, FLOAT fHeight, - enum ParticleTexture ptTexture, INDEX ctEllipses) -{ - ASSERT( ctEllipses<=CT_MAX_PARTICLES_TABLE); - FLOAT fMipFactor = Particle_GetMipFactor(); - if( fMipFactor>7.0f) return; - fMipFactor = 2.5f-fMipFactor*0.3f; - fMipFactor = Clamp(fMipFactor, 0.0f ,1.0f); - INDEX ctAtomicTrail = fMipFactor*CT_ATOMIC_TRAIL; - if( ctAtomicTrail<=0) return; - FLOAT fTrailDelta = 0.075f/fMipFactor; - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - SetupParticleTexture( ptTexture); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; - - for( INDEX iEllipse=0; iEllipse>3, ub>>3, ub>>2); - Particle_RenderSquare( vPos, 0.2f, 0, colStar|0xFF); - } - } - // all done - Particle_Flush(); -} - -#define CT_LIGHTNINGS 8 -void Particles_Ghostbuster(const FLOAT3D &vSrc, const FLOAT3D &vDst, INDEX ctRays, FLOAT fSize, FLOAT fPower, - FLOAT fKneeDivider/*=33.3333333f*/) -{ - Particle_PrepareTexture(&_toGhostbusterBeam, PBT_ADD); - Particle_SetTexturePart( 512, 512, 0, 0); - // get direction vector - FLOAT3D vZ = vDst-vSrc; - FLOAT fLen = vZ.Length(); - vZ.Normalize(); - - // get two normal vectors - FLOAT3D vX; - if (Abs(vZ(2))>0.5) { - vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vZ; - } else { - vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vZ; - } - FLOAT3D vY = vZ*vX; - const FLOAT fStep = fLen/fKneeDivider; - - for(INDEX iRay = 0; iRayGetLerpedCurrentTick()/1.5f; - FLOAT fDT = fT-INDEX(fT); - FLOAT fFade = 1-fDT*4.0f; - - if( fFade>1 || fFade<=0) continue; - UBYTE ubFade = NormFloatToByte(fFade*fPower); - COLOR colFade = RGBToColor( ubFade, ubFade, ubFade); - for(FLOAT fPos=fStep; fPosGetLerpedPlacement().pl_PositionVector; - - vPos(1) -= fGridSize*ctGrids/2; - vPos(3) -= fGridSize*ctGrids/2; - - SnapFloat( vPos(1), fGridSize); - SnapFloat( vPos(2), fGridSize); - SnapFloat( vPos(3), fGridSize); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toRaindrop, PBT_BLEND); - Particle_SetTexturePart( 512, 4096, 0, 0); - - FLOAT fMinX = boxRainMap.Min()(1); - FLOAT fMinY = boxRainMap.Min()(2); - FLOAT fMinZ = boxRainMap.Min()(3); - FLOAT fSizeX = boxRainMap.Size()(1); - FLOAT fSizeY = boxRainMap.Size()(2); - FLOAT fSizeZ = boxRainMap.Size()(3); - PIX pixRainMapW = 1; - PIX pixRainMapH = 1; - - if( ptdRainMap != NULL) - { - pixRainMapW = ptdRainMap->GetPixWidth(); - pixRainMapH = ptdRainMap->GetPixHeight(); - } - - //INDEX ctDiscarded=0; - for( INDEX iZ=0; iZ=0 && pixX=0 && pixZGetTexel( pixX, pixZ); - FLOAT fRainMapY = fMinY+((col>>8)&0xFF)/255.0f*fSizeY; - - FLOAT fRainY = vRender(2); - // if tested raindrop is below ceiling - if( fRainY<=fRainMapY) - { - // don't render it - continue; - } else if (fRainY-fSizeGetLerpedPlacement().pl_PositionVector; - - vPos(1) -= fGridSize*ctGrids/2; - vPos(3) -= fGridSize*ctGrids/2; - - SnapFloat( vPos(1), fGridSize); - SnapFloat( vPos(2), fGridSize); - SnapFloat( vPos(3), fGridSize); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - Particle_PrepareTexture(&_toSnowdrop, PBT_BLEND); - Particle_SetTexturePart( 512, 512, 0, 0); - - for( INDEX iZ=0; iZ0.5) - { - vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vZ; - } - else - { - vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vZ; - } - // we found ortonormal vectors - FLOAT3D vY = vZ*vX; - - FLOAT fAllowRnd = 4.0f/fRandomDivider; - fRandomDivider+=1.0f; - vRenderDest = vSrc+ - vZ*fKneeLen + - vX*(fAllowRnd*afStarsPositions[iRnd][0]*fKneeLen) + - vY*(fAllowRnd*afStarsPositions[iRnd][1]*fKneeLen); - // get new rnd index - iRnd = (iRnd+1) % CT_MAX_PARTICLES_TABLE; - // see if we will spawn new branch of lightning - FLOAT fRnd = ((1-ctBranches/ctMaxBranches)*ctKnees)*afStarsPositions[iRnd][0]; - if( (fRnd < 2.0f) && (fPower>0.25f) ) - { - ctBranches++; - FLOAT3D vNewDirection = (vRenderDest-vSrc).Normalize(); - FLOAT3D vNewDst = vSrc + vNewDirection*fLen; - // recurse into new branch - RenderOneLightningBranch( vSrc, vNewDst, fPath, fTimeStart, fTimeNow, fPower/3.0f, iRnd); - } - } - - // calculate color - UBYTE ubA = UBYTE(fPower*255*fTimeKiller); - // render line - Particle_RenderLine( vSrc, vRenderDest, fPower*2, C_WHITE|ubA); - // add traveled path - fPath += (vRenderDest-vSrc).Length(); - if( fPath/LIGHTNING_SPEED > fPassedTime) - { - bRenderInProgress = FALSE; - } - vSrc = vRenderDest; - } -} - -void Particles_Lightning( FLOAT3D vSrc, FLOAT3D vDst, FLOAT fTimeStart) -{ - Particle_PrepareTexture(&_toLightning, PBT_ADDALPHA); - Particle_SetTexturePart( 512, 512, 0, 0); - - FLOAT fTimeNow = _pTimer->GetLerpedCurrentTick(); - // get rnd index - INDEX iRnd = (INDEX( fTimeStart*100))%CT_MAX_PARTICLES_TABLE; - RenderOneLightningBranch( vSrc, vDst, 0, fTimeStart, fTimeNow, 1.0f, iRnd); - - // all done - Particle_Flush(); -} - -#define CT_SANDFLOW_TRAIL 3 -#define SANDFLOW_FADE_OUT 0.25f -#define SANDFLOW_TOTAL_TIME 1.0f -void Particles_SandFlow( CEntity *pen, FLOAT fStretchAll, FLOAT fSize, FLOAT fHeight, FLOAT fStartTime, FLOAT fStopTime, - INDEX ctParticles) -{ - ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - SetupParticleTexture( PT_SANDFLOW); - CTextureData *pTD = (CTextureData *) _toSandFlowGradient.GetData(); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); - fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); - ctParticles = FLOAT(ctParticles) * fPowerFactor; - fHeight *= fPowerFactor; - for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; - FLOAT fFade; - if (fT>(1.0f-SANDFLOW_FADE_OUT)) fFade=(1-fT)*(1/SANDFLOW_FADE_OUT); - else fFade=1.0f; - fFade *= (CT_SANDFLOW_TRAIL-iTrail)*(1.0f/CT_SANDFLOW_TRAIL); - - FLOAT3D vPos = vCenter + - vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + - vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + - vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); - - COLOR colSand = pTD->GetTexel( FloatToInt(fT*2048), 0); - ULONG ulA = FloatToInt( ((colSand&CT_AMASK)>>CT_ASHIFT) * fFade); - colSand = (colSand&~CT_AMASK) | (ulA<GetLerpedCurrentTick(); - - SetupParticleTexture( PT_WATERFLOW); - CTextureData *pTD = (CTextureData *) _toWaterFlowGradient.GetData(); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); - fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); - ctParticles = FLOAT(ctParticles) * fPowerFactor; - fHeight *= fPowerFactor; - for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; - FLOAT fFade; - if (fT>(1.0f-WATER_FLOW_FADE_OUT)) fFade=(1-fT)*(1/WATER_FLOW_FADE_OUT); - else fFade=1.0f; - fFade *= (CT_WATER_FLOW_TRAIL-iTrail)*(1.0f/CT_WATER_FLOW_TRAIL); - - FLOAT3D vPos = vCenter + - vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + - vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + - vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); - - COLOR colWater = pTD->GetTexel( FloatToInt(fT*2048), 0); - ULONG ulA = FloatToInt( ((colWater&CT_AMASK)>>CT_ASHIFT) * fFade); - colWater = (colWater&~CT_AMASK) | (ulA<GetLerpedCurrentTick(); - - SetupParticleTexture( PT_LAVAFLOW); - CTextureData *pTD = (CTextureData *) _toLavaFlowGradient.GetData(); - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); - fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); - ctParticles = FLOAT(ctParticles) * fPowerFactor; - fHeight *= fPowerFactor; - for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; - FLOAT fFade; - if (fT>(1.0f-LAVA_FLOW_FADE_OUT)) fFade=(1-fT)*(1/LAVA_FLOW_FADE_OUT); - else fFade=1.0f; - fFade *= (CT_LAVA_FLOW_TRAIL-iTrail)*(1.0f/CT_LAVA_FLOW_TRAIL); - - FLOAT3D vPos = vCenter + - vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + - vY*(fT*fT*-4.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + - vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); - - COLOR colLava = pTD->GetTexel( FloatToInt(fT*2048), 0); - ULONG ulA = FloatToInt( ((colLava&CT_AMASK)>>CT_ASHIFT) * fFade); - colLava = (colLava&~CT_AMASK) | (ulA<GetLerpedPlacement().pl_PositionVector; - FLOAT fFadeStart = BULLET_SPRAY_FADEOUT_START; - FLOAT fLifeTotal = BULLET_SPRAY_TOTAL_TIME; - FLOAT fFadeLen = fLifeTotal-fFadeStart; - COLOR colStones = C_WHITE; - - FLOAT fMipFactor = Particle_GetMipFactor(); - FLOAT fDisappear = 1.0f; - if( fMipFactor>8.0f) return; - if( fMipFactor>6.0f) - { - fDisappear = 1.0f-(fMipFactor-6.0f)/2.0f; - } - - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fT=(fNow-tmSpawn); - if( fT>fLifeTotal) return; - INDEX iRnd = INDEX( (tmSpawn*1000.0f)+pen->en_ulID) &63; - FLOAT fSizeStart; - FLOAT fSpeedStart; - FLOAT fConeMultiplier = 1.0f; - COLOR colSmoke; - - switch( eptType) - { - case EPT_BULLET_WATER: - { - Particle_PrepareTexture(&_toBulletWater, PBT_BLEND); - fSizeStart = 0.08f; - fSpeedStart = 1.75f; - fConeMultiplier = 0.125f; - - //FLOAT fFadeStart = BULLET_SPRAY_WATER_FADEOUT_START; - //FLOAT fLifeTotal = BULLET_SPRAY_WATER_TOTAL_TIME; - //FLOAT fFadeLen = fLifeTotal-fFadeStart; - - break; - } - case EPT_BULLET_SAND: - { - colSmoke = 0xFFE8C000; - Particle_PrepareTexture(&_toBulletSand, PBT_BLEND); - fSizeStart = 0.15f; - fSpeedStart = 0.75f; - break; - } - case EPT_BULLET_RED_SAND: - { - colSmoke = 0xA0402000; - colStones = 0x80503000; - Particle_PrepareTexture(&_toBulletSand, PBT_BLEND); - fSizeStart = 0.15f; - fSpeedStart = 0.75f; - break; - } - default: - { - colSmoke = C_WHITE; - Particle_PrepareTexture(&_toBulletStone, PBT_BLEND); - fSizeStart = 0.05f; - fSpeedStart = 1.5f; - } - } - - FLOAT fGA = 10.0f; - - // render particles - for( INDEX iSpray=0; iSpray<12*fDisappear; iSpray++) - { - Particle_SetTexturePart( 512, 512, iSpray&3, 0); - - FLOAT3D vRandomAngle = FLOAT3D( - afStarsPositions[ iSpray+iRnd][0]*3.0f* fConeMultiplier, - (afStarsPositions[ iSpray+iRnd][1]+1.0f)*3.0f, - afStarsPositions[ iSpray+iRnd][2]*3.0f* fConeMultiplier); - FLOAT fSpeedRnd = fSpeedStart+afStarsPositions[ iSpray+iRnd*2][2]; - FLOAT3D vPos = vEntity + (vDirection+vRandomAngle)*(fT*fSpeedRnd)+vGDir*(fT*fT*fGA); - - if( (eptType == EPT_BULLET_WATER) && (vPos(2) < vEntity(2)) ) - { - continue; - } - - FLOAT fSize = fSizeStart + afStarsPositions[ iSpray*2+iRnd*3][0]/20.0f; - FLOAT fRotation = fT*500.0f; - FLOAT fColorFactor = 1.0f; - if( fT>=fFadeStart) - { - fColorFactor = 1-fFadeLen*(fT-fFadeStart); - } - UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); - COLOR col = colStones|ubColor; - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - Particle_Flush(); - - //--------------------------------------- - if( (fT=BULLET_SPARK_FADEOUT_START) - { - fColorFactor = 1-BULLET_SPARK_FADEOUT_LEN*(fT-BULLET_SPARK_FADEOUT_START); - } - UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); - COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; - Particle_RenderLine( vPos0, vPos1, 0.05f, col); - } - Particle_Flush(); - } - - //--------------------------------------- - if( (fT0.5) { - // use cross product of +x axis and plane normal as +s axis - vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vY; - // if the plane is mostly vertical - } else { - // use cross product of +y axis and plane normal as +s axis - vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vY; - } - // make +s axis normalized - vX.Normalize(); - - // use cross product of plane normal and +s axis as +t axis - vZ = vX*vY; - vZ.Normalize(); -} - -void Particles_EmptyShells( CEntity *pen, ShellLaunchData *asldData) -{ - FLOAT tmNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; - FLOAT3D vGDir = ((CMovableEntity *)pen)->en_vGravityDir; - INDEX iRow, iColumn; - - for( INDEX iShell=0; iShell (tmLaunch+fLife) ) continue; - FLOAT fTRatio = fT/fLife; - INDEX iFrame = INDEX( fTRatio*16*8)%16; - iRow = iFrame/4; - iColumn = iFrame%4; - Particle_SetTexturePart( 256, 256, iColumn, iRow); - FLOAT3D vPos = (sld.sld_vPos)+(sld.sld_vSpeed*fT)+(vGDir*(fT*fT*fGA/2.0f)); - Particle_RenderSquare( vPos, 0.05f, 0, C_WHITE|CT_OPAQUE); - break; - } - case ESL_SHOTGUN: - { - FLOAT fLife = 1.5f; - if( tmNow > (tmLaunch+fLife) ) continue; - FLOAT fTRatio = fT/fLife; - INDEX iFrame = INDEX( fTRatio*16*8)%16; - iRow = 4+iFrame/4; - iColumn = iFrame%4; - Particle_SetTexturePart( 256, 256, iColumn, iRow); - FLOAT3D vPos = (sld.sld_vPos)+(sld.sld_vSpeed*fT)+(vGDir*(fT*fT*fGA/2.0f)); - Particle_RenderSquare( vPos, 0.05f, 0, C_WHITE|CT_OPAQUE); - break; - } - case ESL_BUBBLE: - { - INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; - FLOAT fLife = 4.0f; - if( tmNow > (tmLaunch+fLife) ) continue; - Particle_SetTexturePart( 512, 512, 2, 0); - - FLOAT3D vX, vZ; - MakeBaseFromVector( sld.sld_vUp, vX, vZ); - - FLOAT fZF = sin( afStarsPositions[iRnd+2][0]*PI); - FLOAT fXF = cos( afStarsPositions[iRnd+2][0]*PI); - - FLOAT fAmpl = ClampUp( fT+afStarsPositions[iRnd+1][1]+0.5f, 2.0f)/64; - FLOAT fFormulae = fAmpl * sin(afStarsPositions[iRnd][1]+fT*afStarsPositions[iRnd][2]*2); - - FLOAT fColorFactor = 1.0f; - if( fT>fLife/2) - { - fColorFactor = -fT+fLife; - } - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fColorFactor); - ubAlpha = CT_OPAQUE; - FLOAT3D vSpeedPower = sld.sld_vSpeed/(1.0f+fT*fT); - - FLOAT3D vPos = sld.sld_vPos + - vX*fFormulae*fXF+ - vZ*fFormulae*fZF+ - sld.sld_vUp*fT/4.0f*(0.8f+afStarsPositions[iRnd][1]/8.0f)+ - vSpeedPower*fT; - FLOAT fSize = 0.02f + afStarsPositions[iRnd+3][1]*0.01f; - Particle_RenderSquare( vPos, fSize, 0, C_WHITE|ubAlpha); - break; - } - case ESL_SHOTGUN_SMOKE: - { - FLOAT fLife = 1.0f; - if( fT0.0f) - { - // render smoke - INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; - //FLOAT fTRatio = fT/fLife; - INDEX iColumn = 4+INDEX( iShell)%4; - Particle_SetTexturePart( 256, 256, iColumn, 2); - - FLOAT3D vPos = sld.sld_vPos + sld.sld_vUp*(afStarsPositions[iRnd][0]/2.0f+0.5f)*fT + sld.sld_vSpeed*fT/(1+fT*fT); - FLOAT fColorFactor = (fLife-fT)/fLife/(afStarsPositions[iRnd+1][0]*2+4.0f); - FLOAT fRotation = afStarsPositions[iShell][1]*200*fT; - FLOAT fSize = (0.0125f+fT/(5.0f+afStarsPositions[iRnd+1][0]*2.0f))*sld.sld_fSize; - UBYTE ubAlpha = UBYTE(CT_OPAQUE*ClampUp(fColorFactor*sld.sld_fSize, 1.0f)); - COLOR colSmoke = C_WHITE; - Particle_RenderSquare( vPos, fSize, fRotation, colSmoke|ubAlpha); - } - break; - } - case ESL_COLT_SMOKE: - { - FLOAT fLife = 1.0f; - if( fT0.0f) - { - CPlayer &plr = (CPlayer&)*pen; - CPlacement3D plPipe; - plr.GetLerpedWeaponPosition(sld.sld_vPos, plPipe); - FLOATmatrix3D m; - MakeRotationMatrixFast(m, plPipe.pl_OrientationAngle); - FLOAT3D vUp( m(1,2), m(2,2), m(3,2)); - - INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; - //FLOAT fTRatio = fT/fLife; - INDEX iColumn = 4+INDEX( iShell)%4; - Particle_SetTexturePart( 256, 256, iColumn, 2); - - FLOAT3D vPos = plPipe.pl_PositionVector+vUp*(afStarsPositions[iRnd][0]/4.0f+0.3f)*fT; - FLOAT fColorFactor = (fLife-fT)/fLife/(afStarsPositions[iRnd+1][0]*2+4.0f); - FLOAT fRotation = afStarsPositions[iShell][1]*500*fT; - FLOAT fSize = 0.0025f+fT/(10.0f+(afStarsPositions[iRnd+1][0]+0.5f)*10.0f); - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fColorFactor); - COLOR colSmoke = C_WHITE; - Particle_RenderSquare( vPos, fSize, fRotation, colSmoke|ubAlpha); - } - break; - } - } - } - Particle_Flush(); -} - -#define FADE_IN_LENGHT 1.0f -#define FADE_OUT_LENGHT 1.5f -#define FADE_IN_START 0.0f -#define SPIRIT_SPIRAL_START 1.0f -#define FADE_OUT_START 1.75f - -#define FADE_IN_END (FADE_IN_START+FADE_IN_LENGHT) -#define FADE_OUT_END (FADE_OUT_START+FADE_OUT_LENGHT) - -void Particles_Death(CEntity *pen, TIME tmStart) -{ - FLOAT fMipFactor = Particle_GetMipFactor(); - BOOL bVisible = pen->en_pmoModelObject->IsModelVisible( fMipFactor); - if( !bVisible) return; - - FLOAT fTime = _pTimer->GetLerpedCurrentTick()-tmStart; - // don't render particles before fade in and after fadeout - if( (fTimeFADE_OUT_END)) { - return; - } - FLOAT fPowerTime = pow(fTime-SPIRIT_SPIRAL_START, 2.5f); - - // fill array with absolute vertices of entity's model and its attached models - pen->GetModelVerticesAbsolute(avVertices, 0.05f, fMipFactor); - - // get entity position and orientation - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - SetupParticleTexture( PT_STAR07); - - // calculate color factor (for fade in/out) - FLOAT fColorFactor = 1.0f; - if( (fTime>=FADE_IN_START) && (fTime<=FADE_IN_END)) - { - fColorFactor = 1/FADE_IN_LENGHT*(fTime-FADE_IN_START); - } - else if( (fTime>=FADE_OUT_START) && (fTime<=FADE_OUT_END)) - { - fColorFactor = -1/FADE_OUT_LENGHT*(fTime-FADE_OUT_END); - } - - UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); - COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; - - INDEX ctVtx = avVertices.Count(); - FLOAT fSpeedFactor = 1.0f/ctVtx; - - // get corp size - FLOATaabbox3D box; - pen->en_pmoModelObject->GetCurrentFrameBBox(box); - FLOAT fHeightStretch = box.Size()(2); - - FLOAT fStep = ClampDn( fMipFactor, 1.0f); - for( FLOAT fVtx=0.0f; fVtxen_pmoModelObject->IsModelVisible( fMipFactor); - if( !bVisible) return; - - FLOAT fTime = _pTimer->GetLerpedCurrentTick()-tmStart; - // don't render particles before fade in and after fadeout - if( (fTimeAPPEAR_OUT_END)) { - return; - } - //FLOAT fPowerTime = pow(fTime-SPIRIT_SPIRAL_START, 2.5f); - - // fill array with absolute vertices of entity's model and its attached models - pen->GetModelVerticesAbsolute(avVertices, 0.05f, fMipFactor); - - // get entity position and orientation - const FLOATmatrix3D &m = pen->GetRotationMatrix(); - FLOAT3D vX( m(1,1), m(2,1), m(3,1)); - FLOAT3D vY( m(1,2), m(2,2), m(3,2)); - FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); - //FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; - - SetupParticleTexture( PT_STAR07); - - // calculate color factor (for fade in/out) - FLOAT fColorFactor = 1.0f; - if( (fTime>=APPEAR_IN_START) && (fTime<=APPEAR_IN_END)) - { - fColorFactor = 1/APPEAR_IN_LENGHT*(fTime-APPEAR_IN_START); - } - else if( (fTime>=APPEAR_OUT_START) && (fTime<=APPEAR_OUT_END)) - { - fColorFactor = -1/APPEAR_OUT_LENGHT*(fTime-APPEAR_OUT_END); - } - - UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); - COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; - - INDEX ctVtx = avVertices.Count(); - //FLOAT fSpeedFactor = 1.0f/ctVtx; - - // get corp size - FLOATaabbox3D box; - pen->en_pmoModelObject->GetCurrentFrameBBox(box); - //FLOAT fHeightStretch = box.Size()(2); - - FLOAT fStep = ClampDn( fMipFactor, 1.0f); - for( FLOAT fVtx=0.0f; fVtxGetLerpedPlacement().pl_PositionVector; - FLOAT fBoxSize = boxOwner.Size().Length()*0.1f; - FLOAT fEnemySizeModifier = (fBoxSize-0.2)/1.0f+1.0f; - FLOAT fRotation = 0.0f; - - // readout blood type - const INDEX iBloodType = GetSP()->sp_iBlood; - - // determine time difference - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - - // prepare texture - switch(sptType) { - case SPT_BLOOD: - case SPT_SLIME: - { - if( iBloodType<1) return; - if( iBloodType==3) Particle_PrepareTexture( &_toFlowerSprayTexture, PBT_BLEND); - else Particle_PrepareTexture( &_toBloodSprayTexture, PBT_BLEND); - break; - } - case SPT_BONES: - { - Particle_PrepareTexture( &_toBonesSprayTexture, PBT_BLEND); - break; - } - case SPT_FEATHER: - { - Particle_PrepareTexture( &_toFeatherSprayTexture, PBT_BLEND); - fDamagePower*=2.0f; - break; - } - case SPT_STONES: - { - Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); - fDamagePower*=3.0f; - break; - } - case SPT_WOOD: - { - Particle_PrepareTexture( &_toWoodSprayTexture, PBT_BLEND); - fDamagePower*=5.0f; - break; - } - case SPT_SMALL_LAVA_STONES: - { - Particle_PrepareTexture( &_toLavaSprayTexture, PBT_BLEND); - fDamagePower *= 0.75f; - break; - } - case SPT_LAVA_STONES: - { - Particle_PrepareTexture( &_toLavaSprayTexture, PBT_BLEND); - fDamagePower *=3.0f; - break; - } - case SPT_BEAST_PROJECTILE_SPRAY: - { - Particle_PrepareTexture( &_toBeastProjectileSprayTexture, PBT_BLEND); - fDamagePower*=3.0f; - break; - } - case SPT_ELECTRICITY_SPARKS: - { - Particle_PrepareTexture( &_toMetalSprayTexture, PBT_BLEND); - break; - } - default: ASSERT(FALSE); - return; - } - - FLOAT fT=(fNow-tmStarted); - for( INDEX iSpray=0; iSprayBLOOD_SPRAY_FADE_OUT_START) - { - fSize=(-1/(BLOOD_SPRAY_TOTAL_TIME-BLOOD_SPRAY_FADE_OUT_START))*(fT-BLOOD_SPRAY_TOTAL_TIME); - fFade = fSize; - } - else if( fT>BLOOD_SPRAY_TOTAL_TIME) - { - fSize=0.0f; - fFade =0.0f; - } - else - { - fSize=1.0f; - fFade = fSize; - } - FLOAT fMipFactor = Particle_GetMipFactor(); - FLOAT fMipSizeAffector = Clamp( fMipFactor/4.0f, 0.05f, 1.0f); - fSize *= fMipSizeAffector*fDamagePower*fEnemySizeModifier; - - FLOAT3D vRandomAngle = FLOAT3D( - afStarsPositions[ iSpray][0]*1.75f, - (afStarsPositions[ iSpray][1]+1.0f)*1.0f, - afStarsPositions[ iSpray][2]*1.75f); - FLOAT fSpeedModifier = afStarsPositions[ iSpray+BLOOD_SPRAYS][0]*0.5f; - - FLOAT fSpeed = BLOOD_SPRAY_SPEED_MIN+(BLOOD_SPRAY_TOTAL_TIME-fT)/BLOOD_SPRAY_TOTAL_TIME; - FLOAT3D vPos = vWoundPos + (vSpilDirection+vRandomAngle)*(fT*(fSpeed+fSpeedModifier))+vGDir*(fT*fT*fGA/4.0f); - - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); - FLOAT fSizeModifier = afStarsPositions[ int(iSpray+tmStarted*50)%CT_MAX_PARTICLES_TABLE][1]*0.5+1.0f; - - COLOR col = C_WHITE|CT_OPAQUE; - // prepare texture - switch(sptType) { - case SPT_BLOOD: - { - UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); - if( iBloodType==2) col = RGBAToColor( ubRndCol, 0, 0, ubAlpha); - if( iBloodType==1) col = RGBAToColor( 0, ubRndCol, 0, ubAlpha); - break; - } - case SPT_SLIME: - { - UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); - if( iBloodType!=3) col = RGBAToColor(0, ubRndCol, 0, ubAlpha); - break; - } - case SPT_BONES: - { - UBYTE ubRndH = UBYTE( 8+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); - UBYTE ubRndV = UBYTE( 64+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - fSize/=1.5f; - break; - } - case SPT_FEATHER: - { - if(iSpray>=BLOOD_SPRAYS/2) - { - UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); - if( iBloodType==2) col = RGBAToColor( ubRndCol, 0, 0, ubAlpha); - if( iBloodType==1) col = RGBAToColor( 0, ubRndCol, 0, ubAlpha); - } - else - { - UBYTE ubRndH = UBYTE( 32+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - //UBYTE ubRndS = UBYTE( 127+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*128); - UBYTE ubRndV = UBYTE( 159+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*192); - col = HSVToColor(ubRndH, 0, ubRndV)|ubAlpha; - fSize/=2.0f; - fRotation = fT*200.0f; - } - break; - } - case SPT_STONES: - { - UBYTE ubRndH = UBYTE( 24+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 32+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); - UBYTE ubRndV = UBYTE( 196+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*128); - col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - fSize*=0.10f; - fRotation = fT*200.0f; - break; - } - case SPT_WOOD: - { - UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*32); - UBYTE ubRndV = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*96); - col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - fSize*=0.15f; - fRotation = fT*300.0f; - break; - } - case SPT_LAVA_STONES: - case SPT_SMALL_LAVA_STONES: - { - col = C_WHITE|ubAlpha; - fSize/=12.0f; - fRotation = fT*200.0f; - break; - } - case SPT_BEAST_PROJECTILE_SPRAY: - { - col = C_WHITE|ubAlpha; - fSize/=12.0f; - fRotation = fT*200.0f; - break; - } - case SPT_ELECTRICITY_SPARKS: - { - UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 32+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*16); - UBYTE ubRndV = UBYTE( 192+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - ubRndS = 0; - ubRndV = 255; - col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - fSize/=32.0f; - fRotation = fT*200.0f; - break; - } - } - Particle_RenderSquare( vPos, 0.25f*fSize*fSizeModifier, fRotation, col); - } - - // all done - Particle_Flush(); -} - -// spray some stones along obelisk -void Particles_DestroyingObelisk(CEntity *penSpray, FLOAT tmStarted) -{ - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fT=(fNow-tmStarted); - Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); - - FLOAT fTotalTime = 10.0f; - FLOAT fFadeOutStart = 7.5f; - FLOAT fFadeInEnd = 1.0f; - FLOAT3D vG = FLOAT3D(0.0f,-20.0f,0.0f); - - for( INDEX iStone=0; iStone<128; iStone++) - { - INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; - FLOAT3D vSpeed = FLOAT3D( - afStarsPositions[ idx][0], - afStarsPositions[ idx][1], - afStarsPositions[ idx][2]); - vSpeed(2) += 0.25f; - vSpeed *= 50.0f; - - // calculate position - FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + - vSpeed*fT + - vG*fT*fT; - vPos(2) += (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][1]+0.5)*116.0f; - - FLOAT fFade; - // apply fade - if( fTfFadeOutStart) - { - fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); - } - else if( fT>fTotalTime) - { - fFade =0.0f; - } - else - { - fFade = 1.0f; - } - - UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); - UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); - UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); - COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - - FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*1.5f; - FLOAT fRotation = fT*200.0f; - - Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - // all done - Particle_Flush(); -} - -// spray some stones along pylon -void Particles_DestroyingPylon(CEntity *penSpray, FLOAT3D vDamageDir, FLOAT tmStarted) -{ - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fT=(fNow-tmStarted); - Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); - - FLOAT fTotalTime = 10.0f; - FLOAT fFadeOutStart = 7.5f; - FLOAT fFadeInEnd = 1.0f; - FLOAT3D vG = FLOAT3D(0.0f,-20.0f,0.0f); - const FLOATmatrix3D &m = penSpray->GetRotationMatrix(); - - for( INDEX iStone=0; iStone<128; iStone++) - { - INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; - FLOAT3D vSpeed = vDamageDir+FLOAT3D( - afStarsPositions[ idx][0], - afStarsPositions[ idx][1], - afStarsPositions[ idx][2]); - vSpeed *= 50.0f; - - // calculate position - FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + - vSpeed*fT*m + - vG*fT*fT; - FLOAT3D vOffset = FLOAT3D(0.0f,0.0f,0.0f); - vOffset(1) = (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][1])*32.0f; - vOffset(2) = (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+0.5)*56.0f; - vPos += vOffset*m; - - FLOAT fFade; - // apply fade - if( fTfFadeOutStart) - { - fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); - } - else if( fT>fTotalTime) - { - fFade =0.0f; - } - else - { - fFade = 1.0f; - } - - UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); - UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); - UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); - COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - - FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*1.5f; - FLOAT fRotation = fT*200.0f; - - Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - // all done - Particle_Flush(); -} - -// spray some stones in the air -void Particles_HitGround(CEntity *penSpray, FLOAT tmStarted, FLOAT fSizeMultiplier) -{ - FLOAT fNow = _pTimer->GetLerpedCurrentTick(); - FLOAT fT=(fNow-tmStarted); - Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); - - FLOAT fTotalTime = 10.0f; - FLOAT fFadeOutStart = 7.5f; - FLOAT fFadeInEnd = 1.0f; - FLOAT3D vG = FLOAT3D(0.0f,-30.0f,0.0f); - - for( INDEX iStone=0; iStone<64; iStone++) - { - INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; - FLOAT3D vSpeed = FLOAT3D( - afStarsPositions[ idx][0]*1.5f, - (afStarsPositions[ idx][1]+0.5f)*3, - afStarsPositions[ idx][2]*1.5f); - FLOAT fSpeedMultiplier = (fSizeMultiplier-1)*(0.5f-1.0f)/(0.025f-1.0f)+1.0f; - vSpeed *= 50.0f*fSpeedMultiplier; - - // calculate position - FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + - vSpeed*fT + - vG*fT*fT; - - FLOAT fFade; - // apply fade - if( fTfFadeOutStart) - { - fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); - } - else if( fT>fTotalTime) - { - fFade =0.0f; - } - else - { - fFade = 1.0f; - } - - UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); - UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); - UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); - COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; - - FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*4.0f*fSizeMultiplier; - FLOAT fRotation = fT*200.0f; - - Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); - Particle_RenderSquare( vPos, fSize, fRotation, col); - } - // all done - Particle_Flush(); -} +#include "../StdH/StdH.h" +#include "Entities/BloodSpray.h" +#include "Entities/PlayerWeapons.h" +#include "Entities/WorldSettingsController.h" +#include "Entities/BackgroundViewer.h" + +static CTextureObject _toRomboidTrail; +static CTextureObject _toBombTrail; +static CTextureObject _toFirecrackerTrail; +static CTextureObject _toSpiralTrail; +static CTextureObject _toColoredStarsTrail; +static CTextureObject _toFireball01Trail; +static CTextureObject _toGrenadeTrail; +static CTextureObject _toCannonBall; +static CTextureObject _toRocketTrail; +static CTextureObject _toVerticalGradient; +static CTextureObject _toVerticalGradientAlpha; +static CTextureObject _toBlood01Trail; +static CTextureObject _toLavaTrailGradient; +static CTextureObject _toLavaTrailSmoke; +static CTextureObject _toFlamethrowerTrail; +static CTextureObject _toBoubble01; +static CTextureObject _toBoubble02; +static CTextureObject _toBoubble03; +static CTextureObject _toStar01; +static CTextureObject _toStar02; +static CTextureObject _toStar03; +static CTextureObject _toStar04; +static CTextureObject _toStar05; +static CTextureObject _toStar06; +static CTextureObject _toStar07; +static CTextureObject _toStar08; +static CTextureObject _toBlood; +static CTextureObject _toWaterfallGradient; +static CTextureObject _toGhostbusterBeam; +static CTextureObject _toLightning; +static CTextureObject _toSand; +static CTextureObject _toSandFlowGradient; +static CTextureObject _toWater; +static CTextureObject _toWaterFlowGradient; +static CTextureObject _toLava; +static CTextureObject _toLavaFlowGradient; +static CTextureObject _toBloodSprayTexture; +static CTextureObject _toFlowerSprayTexture; +static CTextureObject _toBonesSprayTexture; +static CTextureObject _toFeatherSprayTexture; +static CTextureObject _toStonesSprayTexture; +static CTextureObject _toLavaSprayTexture; +static CTextureObject _toBeastProjectileSprayTexture; +static CTextureObject _toLavaEruptingTexture; +static CTextureObject _toWoodSprayTexture; +static CTextureObject _toLavaBombTrailSmoke; +static CTextureObject _toLavaBombTrailGradient; +static CTextureObject _toElectricitySparks; +static CTextureObject _toBeastProjectileTrailTexture; +static CTextureObject _toBeastProjectileTrailGradient; +static CTextureObject _toBeastBigProjectileTrailTexture; +static CTextureObject _toBeastBigProjectileTrailGradient; +static CTextureObject _toBeastDebrisTrailGradient; +static CTextureObject _toBeastDebrisTrailTexture; +static CTextureObject _toRaindrop; +static CTextureObject _toSnowdrop; +static CTextureObject _toBulletStone; +static CTextureObject _toBulletSand; +static CTextureObject _toBulletSpark; +static CTextureObject _toBulletSmoke; +static CTextureObject _toBulletWater; +static CTextureObject _toPlayerParticles; +static CTextureObject _toWaterfallFoam; +static CTextureObject _toMetalSprayTexture; + +// array for model vertices in absolute space +CStaticStackArray avVertices; + +#define CT_MAX_PARTICLES_TABLE 512 + +FLOAT afTimeOffsets[CT_MAX_PARTICLES_TABLE]; +FLOAT afStarsPositions[CT_MAX_PARTICLES_TABLE][3]; +UBYTE auStarsColors[CT_MAX_PARTICLES_TABLE][3]; + +void InitParticleTables(void); + +// init particle effects +void InitParticles(void) +{ + try + { + _toRomboidTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Romboid.tex")); + _toBombTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WhiteBubble.tex")); + _toFirecrackerTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FireCracker.tex")); + _toSpiralTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke01.tex")); + _toColoredStarsTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Star01.tex")); + _toFireball01Trail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Fireball01.tex")); + _toGrenadeTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke02.tex")); + _toCannonBall.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\CannonBall.tex")); + _toRocketTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Smoke06.tex")); + _toVerticalGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\VerticalGradient.tex")); + _toVerticalGradientAlpha.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\VerticalGradientAlpha.tex")); + _toBlood01Trail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Blood02.tex")); + _toLavaTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaTrailGradient.tex")); + _toLavaTrailSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaTrailSmoke.tex")); + _toFlamethrowerTrail.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FlameThrower01.tex")); + _toBoubble01.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble01.tex")); + _toBoubble02.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble02.tex")); + _toBoubble03.SetData_t(CTFILENAME("Models\\Items\\Particles\\Boubble03.tex")); + _toStar01.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star01.tex")); + _toStar02.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star02.tex")); + _toStar03.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star03.tex")); + _toStar04.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star04.tex")); + _toStar05.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star05.tex")); + _toStar06.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star06.tex")); + _toStar07.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star07.tex")); + _toStar08.SetData_t(CTFILENAME("Models\\Items\\Particles\\Star08.tex")); + _toWaterfallGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\Waterfall08.tex")); + _toGhostbusterBeam.SetData_t(CTFILENAME("Models\\Weapons\\GhostBuster\\Projectile\\Ray.tex")); + _toLightning.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Lightning.tex")); + _toSand.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Sand.tex")); + _toSandFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\SandFlow01.tex")); + _toWater.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Water.tex")); + _toWaterFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\WaterFlow01.tex")); + _toLava.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Lava.tex")); + _toLavaFlowGradient.SetData_t(CTFILENAME("Models\\Effects\\Heatmaps\\LavaFlow01.tex")); + _toBloodSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Blood03.tex")); + _toFlowerSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Flowers.tex")); + _toBonesSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BonesSpill01.tex")); + _toFeatherSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\FeatherSpill01.tex")); + _toStonesSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\StonesSpill01.tex")); + _toLavaSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaSpill01.tex")); + _toBeastProjectileSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileSpill.tex")); + _toLavaEruptingTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaErupting.tex")); + _toWoodSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WoodSpill01.tex")); + _toLavaBombTrailSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaBomb.tex")); + _toLavaBombTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\LavaBombGradient.tex")); + _toBeastDebrisTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastDebrisTrailGradient.tex")); + _toBeastProjectileTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileTrail.tex")); + _toBeastProjectileTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastProjectileTrailGradient.tex")); + _toBeastBigProjectileTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastBigProjectileTrail.tex")); + _toBeastBigProjectileTrailGradient.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastBigProjectileTrailGradient.tex")); + _toBeastDebrisTrailTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BeastDebrisTrail.tex")); + _toElectricitySparks.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\ElectricitySparks.tex")); + _toRaindrop.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Raindrop.tex")); + _toSnowdrop.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\Snowdrop.tex")); + _toBulletStone.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpray.tex")); + _toBulletWater.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSprayWater.tex")); + _toBulletSand.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpraySand.tex")); + _toBulletSpark.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\BulletSpark.tex")); + _toBulletSmoke.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\SmokeAnim01.tex")); + _toPlayerParticles.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\PlayerParticles.tex")); + _toWaterfallFoam.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\WaterfallFoam.tex")); + _toMetalSprayTexture.SetData_t(CTFILENAME("Textures\\Effects\\Particles\\MetalSpill.tex")); + + ((CTextureData*)_toLavaTrailGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toLavaBombTrailGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toBeastDebrisTrailGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toBeastProjectileTrailGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toBeastBigProjectileTrailGradient.GetData())->Force(TEX_STATIC); + ((CTextureData*)_toWaterfallGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toSandFlowGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toWaterFlowGradient .GetData())->Force(TEX_STATIC); + ((CTextureData*)_toLavaFlowGradient .GetData())->Force(TEX_STATIC); + } + catch(char *strError) + { + FatalError(TRANS("Unable to obtain texture: %s"), strError); + } + InitParticleTables(); +} + +// close particle effects +void CloseParticles(void) +{ + _toRomboidTrail.SetData(NULL); + _toBombTrail.SetData(NULL); + _toFirecrackerTrail.SetData(NULL); + _toSpiralTrail.SetData(NULL); + _toColoredStarsTrail.SetData(NULL); + _toFireball01Trail.SetData(NULL); + _toRocketTrail.SetData(NULL); + _toGrenadeTrail.SetData(NULL); + _toCannonBall.SetData(NULL); + _toVerticalGradient.SetData(NULL); + _toVerticalGradientAlpha.SetData(NULL); + _toBlood01Trail.SetData(NULL); + _toLavaTrailGradient.SetData(NULL); + _toWaterfallGradient.SetData(NULL); + _toGhostbusterBeam.SetData( NULL); + _toLightning.SetData( NULL); + _toLavaTrailSmoke.SetData(NULL); + _toFlamethrowerTrail.SetData(NULL); + _toBoubble01.SetData(NULL); + _toBoubble02.SetData(NULL); + _toBoubble03.SetData(NULL); + _toStar01.SetData(NULL); + _toStar02.SetData(NULL); + _toStar03.SetData(NULL); + _toStar04.SetData(NULL); + _toStar05.SetData(NULL); + _toStar06.SetData(NULL); + _toStar07.SetData(NULL); + _toStar08.SetData(NULL); + _toSand.SetData(NULL); + _toSandFlowGradient.SetData(NULL); + _toWater.SetData(NULL); + _toWaterFlowGradient.SetData(NULL); + _toLava.SetData(NULL); + _toLavaFlowGradient.SetData(NULL); + _toLavaBombTrailSmoke.SetData(NULL); + _toLavaBombTrailGradient.SetData(NULL); + _toBloodSprayTexture.SetData(NULL); + _toFlowerSprayTexture.SetData(NULL); + _toBonesSprayTexture.SetData(NULL); + _toFeatherSprayTexture.SetData(NULL); + _toStonesSprayTexture.SetData(NULL); + _toLavaSprayTexture.SetData(NULL); + _toBeastProjectileSprayTexture.SetData(NULL); + _toLavaEruptingTexture.SetData(NULL); + _toWoodSprayTexture.SetData(NULL); + _toElectricitySparks.SetData(NULL); + _toBeastDebrisTrailGradient.SetData(NULL); + _toBeastProjectileTrailTexture.SetData(NULL); + _toBeastProjectileTrailGradient.SetData(NULL); + _toBeastBigProjectileTrailTexture.SetData(NULL); + _toBeastBigProjectileTrailGradient.SetData(NULL); + _toBeastDebrisTrailTexture.SetData(NULL); + _toRaindrop.SetData(NULL); + _toSnowdrop.SetData(NULL); + _toBulletStone.SetData(NULL); + _toBulletWater.SetData(NULL); + _toBulletSand.SetData(NULL); + _toBulletSpark.SetData(NULL); + _toBulletSmoke.SetData(NULL); + _toPlayerParticles.SetData(NULL); + _toWaterfallFoam.SetData(NULL); + _toMetalSprayTexture.SetData(NULL); +} + +void Particles_ViewerLocal(CEntity *penView) +{ + ASSERT(penView!=NULL); + + // ----------- Obtain world settings controller + CWorldSettingsController *pwsc = NULL; + // obtain bcg viewer + CBackgroundViewer *penBcgViewer = (CBackgroundViewer *) penView->GetWorld()->GetBackgroundViewer(); + if( penBcgViewer != NULL) + { + // obtain world settings controller + pwsc = (CWorldSettingsController *) &*penBcgViewer->m_penWorldSettingsController; + } + + // ***** Storm appearing effects + // if world settings controller is valid + if( (pwsc != NULL) && (pwsc->m_tmStormStart != -1)) + { + FLOAT fStormFactor = pwsc->GetStormFactor(); + if( fStormFactor != 0.0f) + { + FLOATaabbox3D boxRainMap; + CTextureData *ptdRainMap; + pwsc->GetHeightMapData( ptdRainMap, boxRainMap); + Particles_Rain( penView, 1.25f, 32, fStormFactor, ptdRainMap, boxRainMap); + } + } +} + +// different particle effects +#define ROMBOID_TRAIL_POSITIONS 16 +void Particles_RomboidTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(ROMBOID_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toRomboidTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + //FLOAT fRand = rand()/FLOAT(RAND_MAX); + FLOAT fAngle = fSeconds*256+iPos*2.0f*PI/ROMBOID_TRAIL_POSITIONS; + FLOAT fSin = FLOAT(sin(fAngle)); + vPos(2) += fSin*iPos/ROMBOID_TRAIL_POSITIONS; + FLOAT fSize = (ROMBOID_TRAIL_POSITIONS-iPos)*0.5f/ROMBOID_TRAIL_POSITIONS+0.1f; + UBYTE ub = 255-iPos*255/ROMBOID_TRAIL_POSITIONS; + Particle_RenderSquare( vPos, fSize, fAngle, RGBToColor(255-ub,ub,255-ub)|ub); + } + // all done + Particle_Flush(); +} + +#define BOMB_TRAIL_POSITIONS 8 +#define BOMB_TRAIL_INTERPOSITIONS 4 +void Particles_BombTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(BOMB_TRAIL_POSITIONS); +} +void Particles_BombTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(BOMB_TRAIL_POSITIONS); + + Particle_PrepareTexture(&_toBombTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); + for(INDEX iPos = plp->lp_ctUsed-1; iPos>=1; iPos--) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + for (INDEX iInter=0; iInterGetLastPositions(FIRECRACKER_TRAIL_POSITIONS); +} +void Particles_FirecrackerTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(FIRECRACKER_TRAIL_POSITIONS); + Particle_PrepareTexture(&_toFirecrackerTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + if( plp->lp_ctUsed<2) return; + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); + INDEX iParticle = plp->lp_ctUsed*FIRECRACKER_TRAIL_INTERPOSITIONS; + for(INDEX iPos = plp->lp_ctUsed-2; iPos>=0; iPos--) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + for (INDEX iInter=0; iInterGetLastPositions(SPIRAL_TRAIL_POSITIONS); + + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + Particle_PrepareTexture(&_toSpiralTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + FLOAT fAngle = fSeconds*32.0f+iPos*2*PI/SPIRAL_TRAIL_POSITIONS; + FLOAT fSin = FLOAT(sin(fAngle)); + FLOAT fCos = FLOAT(cos(fAngle)); + + vPos(1) += fSin*iPos*1.0f/SPIRAL_TRAIL_POSITIONS; + vPos(2) += fCos*iPos*1.0f/SPIRAL_TRAIL_POSITIONS; + + UBYTE ub = iPos*SPIRAL_TRAIL_POSITIONS; + Particle_RenderSquare( vPos, 0.2f, fAngle, RGBToColor(ub,ub,ub)|ub); + } + // all done + Particle_Flush(); +} + +static COLOR _aColors[] = { C_WHITE, C_GRAY, + C_RED, C_GREEN, C_BLUE, C_CYAN, C_MAGENTA, C_YELLOW, C_ORANGE, C_BROWN, C_PINK, + C_lRED, C_lGREEN, C_lBLUE, C_lCYAN, C_lMAGENTA, C_lYELLOW, C_lORANGE, C_lBROWN, C_lPINK +}; + +#define COLORED_STARS_TRAIL_POSITIONS 16 +void Particles_ColoredStarsTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(COLORED_STARS_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toColoredStarsTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + for(INDEX iPos = 0; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos1 = plp->GetPosition(iPos); + //FLOAT3D vPos2 = vPos1; + + FLOAT fAngle = fSeconds*64.0f+iPos*2*PI/COLORED_STARS_TRAIL_POSITIONS; + FLOAT fSin = FLOAT(sin(fAngle)); + //FLOAT fCos = FLOAT(cos(fAngle)); + + FLOAT fDeltaY = fSin/2.0f; + vPos1(2) += fDeltaY; + //vPos2(2) -= fDeltaY; + + FLOAT fRand = rand()/FLOAT(RAND_MAX); + INDEX iRandColor = INDEX(fRand*sizeof(_aColors)/sizeof(COLOR)); + COLOR colColor1 = _aColors[ iRandColor]; + Particle_RenderSquare( vPos1, 0.4f, fAngle, colColor1); + } + // all done + Particle_Flush(); +} + +#define WHITE_LINE_TRAIL_POSITIONS 8 +void Particles_WhiteLineTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(WHITE_LINE_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toSpiralTrail, PBT_ADD); + Particle_SetTexturePart( 1, 1, 256, 256); + + FLOAT3D vOldPos = plp->GetPosition(0); + for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + FLOAT fAngle = fSeconds*4.0f+iPos*PI/WHITE_LINE_TRAIL_POSITIONS; + FLOAT fSin = FLOAT(sin(fAngle)); + FLOAT fCos = FLOAT(cos(fAngle)); + + vPos(1) += fSin*iPos*1.0f/WHITE_LINE_TRAIL_POSITIONS; + vPos(2) += fCos*iPos*1.0f/WHITE_LINE_TRAIL_POSITIONS; + + //UBYTE ub = 255-iPos*256/WHITE_LINE_TRAIL_POSITIONS; + FLOAT fLerpFactor = FLOAT(iPos)/WHITE_LINE_TRAIL_POSITIONS; + COLOR colColor = LerpColor( C_YELLOW, C_dRED, fLerpFactor); + Particle_RenderLine( vPos, vOldPos, 0.05f, colColor); + vOldPos =vPos; + } + // all done + Particle_Flush(); +} + + +#define FIREBALL01_TRAIL_POSITIONS 8 +#define FIREBALL01_TRAIL_INTERPOSITIONS 4 +#define FIREBALL01_TRAIL_PARTICLES (FIREBALL01_TRAIL_INTERPOSITIONS*FIREBALL01_TRAIL_POSITIONS) +void Particles_Fireball01Trail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(FIREBALL01_TRAIL_POSITIONS); +} +void Particles_Fireball01Trail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(FIREBALL01_TRAIL_POSITIONS); + Particle_PrepareTexture(&_toFireball01Trail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(plp->lp_ctUsed-1); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*FIREBALL01_TRAIL_INTERPOSITIONS; + for(INDEX iPos = plp->lp_ctUsed-2; iPos>=0; iPos--) { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + COLOR colColor; + for (INDEX iInter=0; iInterGetLastPositions(GRENADE_TRAIL_POSITIONS); +} +void Particles_GrenadeTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(GRENADE_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toGrenadeTrail, PBT_MULTIPLY); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(0); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*GRENADE_TRAIL_INTERPOSITIONS; + for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + for (INDEX iInter=0; iInterGetLastPositions(CANNON_TRAIL_POSITIONS); +} +void Particles_CannonBall(CEntity *pen, FLOAT fSpeedRatio) +{ + CLastPositions *plp = pen->GetLastPositions(CANNON_TRAIL_POSITIONS); + // FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toCannonBall, PBT_BLEND); + Particle_SetTexturePart( 512, 512, 0, 0); + + FLOAT3D vOldPos = plp->GetPosition(1); + for( INDEX iPos=2; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + UBYTE ub = UBYTE((255-iPos*256/plp->lp_ctUsed)*fSpeedRatio); + FLOAT fSize = (CANNON_TRAIL_POSITIONS-iPos)*0.04f+0.04f; + Particle_RenderLine( vPos, vOldPos, fSize, RGBToColor(ub,ub,ub)|ub); + vOldPos=vPos; + } + // all done + Particle_Flush(); +} + +#define LAVA_TRAIL_POSITIONS 32 +#define LAVA_TRAIL_INTERPOSITIONS 1 +void Particles_LavaTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(LAVA_TRAIL_POSITIONS); +} +void Particles_LavaTrail(CEntity *pen) +{ + CLastPositions *plp = pen->GetLastPositions(LAVA_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + CTextureData *pTD = (CTextureData *) _toLavaTrailGradient.GetData(); + Particle_PrepareTexture(&_toLavaTrailSmoke, PBT_BLEND); + //Particle_PrepareTexture(&_toLavaTrailSmoke, PBT_MULTIPLY); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(0); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*LAVA_TRAIL_INTERPOSITIONS; + for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); + Particle_RenderSquare( vPos, fSize, fAngle, col); + iParticle++; + } + } + // all done + Particle_Flush(); +} + +#define LAVA_BOMB_TRAIL_POSITIONS 16 +#define LAVA_BOMB_TRAIL_INTERPOSITIONS 1 +void Particles_LavaBombTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(LAVA_BOMB_TRAIL_POSITIONS); +} + +void Particles_LavaBombTrail(CEntity *pen, FLOAT fSizeMultiplier) +{ + CLastPositions *plp = pen->GetLastPositions(LAVA_BOMB_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + CTextureData *pTD = (CTextureData *) _toLavaBombTrailGradient.GetData(); + Particle_PrepareTexture(&_toLavaBombTrailSmoke, PBT_BLEND); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(0); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*LAVA_BOMB_TRAIL_INTERPOSITIONS; + for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) + { + INDEX iRnd = ((ULONG)fSeconds+iPos)%CT_MAX_PARTICLES_TABLE; + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + if( *pvPos1 == *pvPos2) continue; + for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); + Particle_RenderSquare( vPos, fSize, fAngle, col); + iParticle++; + } + } + // all done + Particle_Flush(); +} + +#define BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS 8 +#define BEAST_PROJECTILE_DEBRIS_TRAIL_INTERPOSITIONS 1 +void Particles_BeastProjectileDebrisTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS); +} + +void Particles_BeastProjectileDebrisTrail(CEntity *pen, FLOAT fSizeMultiplier) +{ + CLastPositions *plp = pen->GetLastPositions(BEAST_PROJECTILE_DEBRIS_TRAIL_POSITIONS); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + CTextureData *pTD = (CTextureData *) _toBeastDebrisTrailGradient.GetData(); + Particle_PrepareTexture(&_toBeastDebrisTrailTexture, PBT_BLEND); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(0); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*BEAST_PROJECTILE_DEBRIS_TRAIL_INTERPOSITIONS; + for(INDEX iPos = 1; iPoslp_ctUsed; iPos++) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + for (INDEX iInter=0; iInterGetTexel(PIX(FLOAT(iParticle)/iParticlesLiving*8*1024), 0); + Particle_RenderSquare( vPos, fSize, fAngle, col); + iParticle++; + } + } + // all done + Particle_Flush(); +} + +#define BEAST_PROJECTILE_TRAIL_POSITIONS 32 +#define BEAST_PROJECTILE_TRAIL_INTERPOSITIONS 1 +void Particles_BeastProjectileTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(BEAST_PROJECTILE_TRAIL_POSITIONS); +} + +#define BEAST_PROJECTILE_LINE_PARTICLES 0.4f +#define BEAST_PROJECTILE_FADE_OUT 0.3f +#define BEAST_PROJECTILE_TOTAL_TIME 0.6f +void Particles_BeastProjectileTrail( CEntity *pen, FLOAT fSize, FLOAT fHeight, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toBeastProjectileTrailTexture, PBT_BLEND); + Particle_SetTexturePart( 512, 2048, 0, 0); + + CTextureData *pTD = (CTextureData *) _toBeastProjectileTrailGradient.GetData(); + + CPlacement3D pl = pen->GetLerpedPlacement(); + FLOATmatrix3D m; + MakeRotationMatrixFast(m, pl.pl_OrientationAngle); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( -m(1,3), -m(2,3), -m(3,3)); + FLOAT3D vZ( m(1,2), m(2,2), m(3,2)); + FLOAT3D vCenter = pl.pl_PositionVector+vY*fHeight; + + for( INDEX iStar=0; iStar(1.0f-BEAST_PROJECTILE_FADE_OUT)) fFade=(1-fT)*(1/BEAST_PROJECTILE_FADE_OUT); + //else fFade=1.0f; + +#define GET_POS( time) vCenter + \ + vX*(afStarsPositions[iStar][0]*time*fSize*1.5) +\ + vY*(-time*time*10.0f+(afStarsPositions[iStar][1]*2+2.0f)*1.2f*time) +\ + vZ*(afStarsPositions[iStar][2]*time*fSize*1.5); + + FLOAT3D vPos = GET_POS( fT); + COLOR colStar = pTD->GetTexel( FloatToInt(fT*8192), 0); + + if( fT>BEAST_PROJECTILE_LINE_PARTICLES) + { + FLOAT fTimeOld = fT-0.25f; + FLOAT3D vOldPos = GET_POS( fTimeOld); + Particle_RenderLine( vOldPos, vPos, 0.4f, colStar); + } + else + { + Particle_RenderSquare( vPos, 0.5f, fT*360.0f, colStar); + } + } + // all done + Particle_Flush(); +} + +#define BEAST_BIG_PROJECTILE_TRAIL_POSITIONS 32 +#define BEAST_BIG_PROJECTILE_TRAIL_INTERPOSITIONS 1 +void Particles_BeastBigProjectileTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(BEAST_BIG_PROJECTILE_TRAIL_POSITIONS); +} + +#define BIG_BEAST_PROJECTILE_LINE_PARTICLES 0.4f +#define BIG_BEAST_PROJECTILE_FADE_OUT 0.4f +#define BIG_BEAST_PROJECTILE_TOTAL_TIME 0.6f +void Particles_BeastBigProjectileTrail( CEntity *pen, FLOAT fSize, FLOAT fZOffset, FLOAT fYOffset, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toBeastBigProjectileTrailTexture, PBT_BLEND); + Particle_SetTexturePart( 512, 2048, 0, 0); + + CTextureData *pTD = (CTextureData *) _toBeastBigProjectileTrailGradient.GetData(); + + CPlacement3D pl = pen->GetLerpedPlacement(); + FLOATmatrix3D m; + MakeRotationMatrixFast(m, pl.pl_OrientationAngle); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( -m(1,3), -m(2,3), -m(3,3)); + FLOAT3D vZ( m(1,2), m(2,2), m(3,2)); + FLOAT3D vCenter = pl.pl_PositionVector+vY*fZOffset+vZ*fYOffset; + + for( INDEX iStar=0; iStar(1.0f-BIG_BEAST_PROJECTILE_FADE_OUT)) fFade=(1-fT)*(1/BIG_BEAST_PROJECTILE_FADE_OUT); + else fFade=1.0f; + +#define GET_POS_BIG( time) vCenter + \ + vX*(afStarsPositions[iStar][0]*time*fSize*1.5) +\ + vY*(time*time*-15.0f+(afStarsPositions[iStar][1]*2+3.0f)*1.2f*time) +\ + vZ*(afStarsPositions[iStar][2]*time*fSize*1.5); + + FLOAT3D vPos = GET_POS_BIG( fT); + COLOR colStar = pTD->GetTexel( FloatToInt(fT*8192), 0); + + if( fT>BIG_BEAST_PROJECTILE_LINE_PARTICLES) + { + FLOAT fTimeOld = fT-0.125f; + FLOAT3D vOldPos = GET_POS_BIG( fTimeOld); + Particle_RenderLine( vOldPos, vPos, 0.6f*fFade, colStar); + } + else + { + Particle_RenderSquare( vPos, 0.5, fT*360.0f, colStar); + } + } + // all done + Particle_Flush(); +} + +#define ROCKET_TRAIL_POSITIONS 16 +#define ROCKET_TRAIL_INTERPOSITIONS 3 +void Particles_RocketTrail_Prepare(CEntity *pen) +{ + pen->GetLastPositions(ROCKET_TRAIL_POSITIONS); +} +void Particles_RocketTrail(CEntity *pen, FLOAT fStretch) +{ + CLastPositions *plp = pen->GetLastPositions(ROCKET_TRAIL_POSITIONS); + //FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toRocketTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D *pvPos1; + const FLOAT3D *pvPos2 = &plp->GetPosition(1); + INDEX iParticle = 0; + INDEX iParticlesLiving = plp->lp_ctUsed*ROCKET_TRAIL_INTERPOSITIONS; + for( INDEX iPos=2; iPoslp_ctUsed; iPos++) + { + pvPos1 = pvPos2; + pvPos2 = &plp->GetPosition(iPos); + if( (*pvPos2 - *pvPos1).Length() == 0.0f) + { + continue; + } + for (INDEX iInter=0; iInterGetPosition(1); + for( INDEX iPos=2; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + if( (vPos - vOldPos).Length() == 0.0f) + { + continue; + } + UBYTE ub = UBYTE(255-iPos*256/plp->lp_ctUsed); + FLOAT fSize = iPos*0.01f*fStretch+0.005f; + Particle_RenderLine( vPos, vOldPos, fSize, RGBToColor(ub,ub,ub)|ub); + vOldPos=vPos; + } + // all done + Particle_Flush(); +} + + +#define BLOOD01_TRAIL_POSITIONS 15 +void Particles_BloodTrail(CEntity *pen) +{ + // get blood type + const INDEX iBloodType = GetSP()->sp_iBlood; + if( iBloodType<1) return; + COLOR col; + if( iBloodType==3) Particle_PrepareTexture( &_toFlowerSprayTexture, PBT_BLEND); + else Particle_PrepareTexture( &_toBloodSprayTexture, PBT_BLEND); + + CLastPositions *plp = pen->GetLastPositions(BLOOD01_TRAIL_POSITIONS); + FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; + FLOAT3D vGDir = ((CMovableEntity *)pen)->en_vGravityDir; + + for( INDEX iPos=0; iPoslp_ctUsed; iPos++) + { + Particle_SetTexturePart( 256, 256, iPos%8, 0); + FLOAT3D vPos = plp->GetPosition(iPos); + //FLOAT fRand = rand()/FLOAT(RAND_MAX); + FLOAT fAngle = iPos*2.0f*PI/BLOOD01_TRAIL_POSITIONS; + //FLOAT fSin = FLOAT(sin(fAngle)); + FLOAT fT = iPos*_pTimer->TickQuantum; + vPos += vGDir*fGA*fT*fT/8.0f; + FLOAT fSize = 0.2f-iPos*0.15f/BLOOD01_TRAIL_POSITIONS; + UBYTE ub = 255-iPos*255/BLOOD01_TRAIL_POSITIONS; + if( iBloodType==3) col = C_WHITE|ub; + else if( iBloodType==2) col = RGBAToColor(ub,20,20,ub); + else col = RGBAToColor(0,ub,0,ub); + Particle_RenderSquare( vPos, fSize, fAngle, col); + } + // all done + Particle_Flush(); +} + + +INDEX Particles_FireBreath(CEntity *pen, FLOAT3D vSource, FLOAT3D vTarget, FLOAT tmStart, FLOAT tmStop) +{ + Particle_PrepareTexture( &_toFlamethrowerTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fFlameLife = 2; + INDEX ctFlames = 32; + INDEX ctRendered = 0; + FLOAT tmFlameDelta = 0.25f; + FLOAT3D vFocus = Lerp( vSource, vTarget, 0.25f); + for( INDEX iFlame=0; iFlamefFlameLife || tmFakeStart>tmStop) continue; + // calculate fraction part + FLOAT fT=fPassedTime/fFlameLife; + fT=fT-INDEX(fT); + // lerp position + FLOAT3D vRnd = FLOAT3D( afStarsPositions[iFlame][0],afStarsPositions[iFlame][1], + afStarsPositions[iFlame][2])*10; + FLOAT3D vPos = Lerp( vSource, vFocus+vRnd, fT); + FLOAT fSize = 5.0f*fT+5.0f; + UBYTE ub = CalculateRatio( fT, 0.0f, 1.0f, 0.1f, 0.2f)*255; + Particle_RenderSquare( vPos, fSize, fT*(1.0f+afStarsPositions[iFlame*3][1])*360.0f, RGBToColor(ub,ub,ub)|0xFF); + ctRendered++; + } + // all done + Particle_Flush(); + return ctRendered; +} + +INDEX Particles_Regeneration(CEntity *pen, FLOAT tmStart, FLOAT tmStop, FLOAT fYFactor, BOOL bDeath) +{ + Particle_PrepareTexture( &_toElectricitySparks, PBT_BLEND); + Particle_SetTexturePart( 512, 1024, 0, 0); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fLife = 1.5; + INDEX ctRendered = 0; + FLOAT tmDelta = 0.001f; + for( INDEX iVtx=0; iVtx<1024*4; iVtx++) + { + FLOAT tmFakeStart = tmStart+iVtx*tmDelta; + FLOAT fPassedTime = fNow-tmFakeStart; + if(fPassedTime<0.0f || fPassedTime>fLife || tmFakeStart>tmStop) continue; + // calculate fraction part + FLOAT fT=fPassedTime/fLife; + fT=fT-INDEX(fT); + + INDEX iRnd = iVtx%CT_MAX_PARTICLES_TABLE; + FLOAT3D vRnd= FLOAT3D(afStarsPositions[iRnd][0],afStarsPositions[iRnd][1]+0.5f,afStarsPositions[iRnd][2]); + vRnd(1) *= 800.0f; + vRnd(2) *= 400.0f; + vRnd(3) *= 800.0f; + FLOAT3D vSource = vCenter+vRnd; + FLOAT3D vDestination = vCenter+vRnd*0.05f; + vDestination(2) += 40.0f*fYFactor+vRnd(2)/8.0f*fYFactor; + FLOAT3D vPos, vPos2; + // lerp position + if(bDeath) { + vPos = Lerp( vSource, vDestination, 1.0f-fT); + } else { + vPos = Lerp( vSource, vDestination, fT); + } + FLOAT fT2 = Clamp(fT-0.025f-fT*fT*0.025f, 0.0f, 1.0f); + + if(bDeath) { + vPos2 = Lerp( vSource, vDestination, 1.0f-fT2); + } else { + vPos2 = Lerp( vSource, vDestination, fT2); + } + + UBYTE ubR = 192+afStarsPositions[iRnd][0]*64; + UBYTE ubG = 192+afStarsPositions[iRnd][1]*64; + UBYTE ubB = 192+afStarsPositions[iRnd][2]*64; + UBYTE ubA = CalculateRatio( fT, 0.0f, 1.0f, 0.4f, 0.01f)*255; + COLOR colLine = RGBToColor( ubR, ubG, ubB) | ubA; + + FLOAT fSize = 1.0f; + Particle_RenderLine( vPos2, vPos, fSize, colLine); + ctRendered++; + } + + // flush array + avVertices.PopAll(); + // all done + Particle_Flush(); + return ctRendered; +} + +#define SECONDS_PER_PARTICLE 0.01f +void Particles_FlameThrower(const CPlacement3D &plEnd, const CPlacement3D &plStart, + FLOAT fEndElapsed, FLOAT fStartElapsed) +{ + Particle_PrepareTexture( &_toFlamethrowerTrail, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + const FLOAT3D &vStart = plStart.pl_PositionVector; + const FLOAT3D &vEnd = plEnd.pl_PositionVector; + FLOAT3D vDelta = (vEnd-vStart)/(fEndElapsed-fStartElapsed); + FLOAT fSeconds = _pTimer->GetLerpedCurrentTick(); + + for(FLOAT fTime = ceil(fStartElapsed/SECONDS_PER_PARTICLE)*SECONDS_PER_PARTICLE; + fTime0.75f) ub = 0; + else if( fTime>0.5f) ub = (-4*fTime+3)*96; + + ASSERT(fTime>=0.0f); + ASSERT(fSize>=0.0f); + FLOAT3D vPos = vStart+vDelta*(fTime-fStartElapsed)+FLOAT3D(0.0f, fRise, 0.0f); + Particle_RenderSquare( vPos, fSize, fAngle, RGBToColor(ub,ub,ub)|0xFF); + } + // all done + Particle_Flush(); +} + +void SetupParticleTexture(enum ParticleTexture ptTexture) +{ + switch(ptTexture) { + case PT_STAR01: Particle_PrepareTexture(&_toStar01, PBT_ADD); break; + case PT_STAR02: Particle_PrepareTexture(&_toStar02, PBT_ADD); break; + case PT_STAR03: Particle_PrepareTexture(&_toStar03, PBT_ADD); break; + case PT_STAR04: Particle_PrepareTexture(&_toStar04, PBT_ADD); break; + case PT_STAR05: Particle_PrepareTexture(&_toStar05, PBT_ADD); break; + case PT_STAR06: Particle_PrepareTexture(&_toStar06, PBT_ADD); break; + case PT_STAR07: Particle_PrepareTexture(&_toStar07, PBT_ADD); break; + case PT_STAR08: Particle_PrepareTexture(&_toStar08, PBT_ADD); break; + case PT_BOUBBLE01: Particle_PrepareTexture(&_toBoubble01, PBT_ADD); break; + case PT_BOUBBLE02: Particle_PrepareTexture(&_toBoubble02, PBT_ADD); break; + case PT_WATER01: Particle_PrepareTexture(&_toBoubble03, PBT_BLEND); break; + case PT_WATER02: Particle_PrepareTexture(&_toBoubble03, PBT_BLEND); break; + case PT_SANDFLOW: Particle_PrepareTexture(&_toSand, PBT_BLEND); break; + case PT_WATERFLOW: Particle_PrepareTexture(&_toWater, PBT_BLEND); break; + case PT_LAVAFLOW: Particle_PrepareTexture(&_toLava, PBT_BLEND); break; + default: ASSERT(FALSE); + } + Particle_SetTexturePart( 512, 512, 0, 0); +} + +void InitParticleTables(void) +{ + for( INDEX iStar=0; iStar7.0f) return; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + CPlacement3D plSource = pen->GetLerpedPlacement(); + FLOAT3D vCenter = plSource.pl_PositionVector+vY*fHeight; + + for( INDEX iStar=0; iStarSTARDUST_EXIST_TIME) continue; + FLOAT fFade = -2.0f * Abs(fT*(1.0f/STARDUST_EXIST_TIME)-0.5f)+1.0f; + + INDEX iRandomFromPlacement = + (ULONG)(plSource.pl_PositionVector(1)+plSource.pl_PositionVector(3))&(ctOffsetSpace-1); + INDEX iMemeber = iStar+iRandomFromPlacement; + const FLOAT3D vPos = vCenter+FLOAT3D( afStarsPositions[iMemeber][0], + afStarsPositions[iMemeber][1], + afStarsPositions[iMemeber][2])*fSize; + COLOR colStar = RGBToColor( auStarsColors[iMemeber][0]*fFade, + auStarsColors[iMemeber][1]*fFade, + auStarsColors[iMemeber][2]*fFade); + Particle_RenderSquare( vPos, 0.15f, 0, colStar|0xFF); + } + // all done + Particle_Flush(); +} + +#define RISING_TOTAL_TIME 5.0f +#define RISING_EXIST_TIME 3.0f +#define RISING_FADE_IN 0.3f +#define RISING_FADE_OUT 0.3f + +void Particles_Rising(CEntity *pen, FLOAT fStartTime, FLOAT fStopTime, FLOAT fStretchAll, + FLOAT fStretchX, FLOAT fStretchY, FLOAT fStretchZ, FLOAT fSize, + enum ParticleTexture ptTexture, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + if( Particle_GetMipFactor()>7.0f) return; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fStretchY; + + FLOAT fPowerFactor = Clamp((fNow - fStartTime)/5.0f,0.0f,1.0f); + fPowerFactor *= Clamp(1+(fStopTime-fNow)/5.0f,0.0f,1.0f); + //ctParticles = FLOAT(ctParticles) * fPowerFactor; + + for( INDEX iStar=0; iStar1) continue; + FLOAT fFade; + if(fF<(RISING_FADE_IN*fPowerFactor)) fFade=fF*(1/(RISING_FADE_IN*fPowerFactor)); + else if (fF>(1.0f-RISING_FADE_OUT)) fFade=(1-fF)*(1/RISING_FADE_OUT); + else fFade=1.0f; + + FLOAT3D vPos = vCenter+FLOAT3D( + afStarsPositions[iStar][0]*fStretchX, + afStarsPositions[iStar][1]*fStretchY, + afStarsPositions[iStar][2]*fStretchZ)*fStretchAll+vY*(fF*fStretchAll*0.5f); + vPos(1)+=sin(fF*4.0f)*0.05f*fStretchAll; + vPos(3)+=cos(fF*4.0f)*0.05f*fStretchAll; + + UBYTE ub = NormFloatToByte( fFade); + COLOR colStar = RGBToColor( ub, ub, ub>>1); + Particle_RenderSquare( vPos, fSize*fPowerFactor, 0, colStar|(UBYTE(0xFF*fPowerFactor))); + } + // all done + Particle_Flush(); +} + +#define CT_SPIRAL_PARTICLES 4 +#define CT_SPIRAL_TRAIL 10 +void Particles_Spiral( CEntity *pen, FLOAT fSize, FLOAT fHeight, + enum ParticleTexture ptTexture, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + + FLOAT fMipFactor = Particle_GetMipFactor(); + if( fMipFactor>7.0f) return; + fMipFactor = 2.5f-fMipFactor*0.3f; + fMipFactor = Clamp( fMipFactor, 0.0f, 1.0f); + INDEX ctSpiralTrail = fMipFactor*CT_SPIRAL_TRAIL; + if( ctSpiralTrail<=0) return; + FLOAT fTrailDelta = 0.1f/fMipFactor; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; + + for( INDEX iStar=0; iStar>1); + Particle_RenderSquare( vPos, 0.2f, 0, colStar|0xFF); + } + } + // all done + Particle_Flush(); +} + +#define EMANATE_FADE_IN 0.2f +#define EMANATE_FADE_OUT 0.6f +#define EMANATE_TOTAL_TIME 1.0f +#define EMANATE_EXIST_TIME 0.5f +void Particles_Emanate( CEntity *pen, FLOAT fSize, FLOAT fHeight, + enum ParticleTexture ptTexture, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + if( Particle_GetMipFactor()>7.0f) return; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; + + for( INDEX iStar=0; iStar1) continue; + FLOAT fFade; + if(fF(1.0f-EMANATE_FADE_OUT)) fFade=(1-fF)*(1/EMANATE_FADE_OUT); + else fFade=1.0f; + + FLOAT3D vPos = vCenter+FLOAT3D( + afStarsPositions[iStar][0], + afStarsPositions[iStar][1], + afStarsPositions[iStar][2])*fSize*(fF+0.4f); + + UBYTE ub = NormFloatToByte( fFade); + COLOR colStar = RGBToColor( ub, ub, ub>>1); + Particle_RenderSquare( vPos, 0.1f, 0, colStar|0xFF); + } + // all done + Particle_Flush(); +} + +#define WATERFALL_FOAM_FADE_IN 0.1f +#define WATERFALL_FOAM_FADE_OUT 0.4f +void Particles_WaterfallFoam(CEntity *pen, FLOAT fSizeX, FLOAT fSizeY, FLOAT fSizeZ, + FLOAT fParticleSize, FLOAT fSpeed, FLOAT fSpeedY, FLOAT fLife, INDEX ctParticles) +{ + if(fLife<=0) return; + + Particle_PrepareTexture( &_toWaterfallFoam, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + for( INDEX iFoam=0; iFoam7.0f) return; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + for( INDEX iStar=0; iStar1) continue; + FLOAT fFade; + if(fF(1.0f-EMANATE_FADE_OUT)) fFade=(1-fF)*(1/EMANATE_FADE_OUT); + else fFade=1.0f; + + FLOAT fX = (afStarsPositions[iStar][0]+0.5f)*fSizeX*(1+fF*fAway); + FLOAT fY = fSizeY*fF; + FLOAT fZ = (afStarsPositions[iStar][2]+0.5f)*fSizeZ*(1+fF*fAway); + FLOAT3D vPos = vCenter + vX*fX + vY*fY + vZ*fZ; + + UBYTE ub = NormFloatToByte( fFade); + COLOR colStar = RGBToColor( ub, ub, ub); + Particle_RenderSquare( vPos, fParticleSize, 0, colStar|0xFF); + } + // all done + Particle_Flush(); +} + +#define CT_FOUNTAIN_TRAIL 3 +#define FOUNTAIN_FADE_IN 0.6f +#define FOUNTAIN_FADE_OUT 0.4f +#define FOUNTAIN_TOTAL_TIME 0.6f +void Particles_Fountain( CEntity *pen, FLOAT fSize, FLOAT fHeight, + enum ParticleTexture ptTexture, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + SetupParticleTexture( ptTexture); + CTextureData *pTD = (CTextureData *) _toWaterfallGradient.GetData(); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; + + for( INDEX iStar=0; iStar(1.0f-FOUNTAIN_FADE_OUT)) fFade=(1-fT)*(1/FOUNTAIN_FADE_OUT); + else fFade=1.0f; + fFade *= (CT_FOUNTAIN_TRAIL-iTrail)*(1.0f/CT_FOUNTAIN_TRAIL); + + FLOAT3D vPos = vCenter + + vX*(afStarsPositions[iStar][0]*fT*fSize) + + vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*2+4.0f)*1.2f*fT) + + vZ*(afStarsPositions[iStar][2]*fT*fSize); + + COLOR colStar = pTD->GetTexel( FloatToInt(fFade*2048), 0); + ULONG ulA = FloatToInt( ((colStar&CT_AMASK)>>CT_ASHIFT) * fFade); + colStar = (colStar&~CT_AMASK) | (ulA<en_ulID)%CT_MAX_PARTICLES_TABLE; + Particle_SetTexturePart( 512, 512, iRnd1%3, 0); + + FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; + FLOAT fBoxSize = boxOwner.Size().Length(); + for(INDEX iSmoke=0; iSmoke<2+fDamage*2; iSmoke++) + { + INDEX iRnd2 = INDEX(tmStarted*12345.0f+iSmoke+fDamage*10.0f)%(CT_MAX_PARTICLES_TABLE/2); + FLOAT fLifeTime = 2.0f+(afStarsPositions[iRnd2][0]+0.5f)*2.0f; + FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.4f, 0.6f); + + FLOAT fRndAppearX = afStarsPositions[iRnd2][0]*fBoxSize*0.125f; + FLOAT fRndAppearZ = afStarsPositions[iRnd2][2]*fBoxSize*0.125f; + FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; + vPos(1) += fRndAppearX; + vPos(3) += fRndAppearZ; + vPos(2) += ((afStarsPositions[iRnd2+4][1]+0.5f)*2.0f+1.5f)*fT+boxOwner.Size()(2)*0.0025f; + + COLOR col = C_dGRAY|UBYTE(64.0f*fRatio); + FLOAT fRotation = afStarsPositions[iRnd2+5][0]*360+fT*200.0f*afStarsPositions[iRnd2+3][0]; + FLOAT fSize = + 0.025f*fDamage+ + (afStarsPositions[iRnd2+6][2]+0.5f)*0.075 + + (0.15f+(afStarsPositions[iRnd2+2][1]+0.5f)*0.075f*fBoxSize)*fT; + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + + // all done + Particle_Flush(); +} + +#define RUNNING_DUST_TRAIL_POSITIONS 3*20 +void Particles_RunningDust_Prepare(CEntity *pen) +{ + pen->GetLastPositions(RUNNING_DUST_TRAIL_POSITIONS); +} +void Particles_RunningDust(CEntity *pen) +{ + Particle_PrepareTexture( &_toBulletSmoke, PBT_BLEND); + CLastPositions *plp = pen->GetLastPositions(RUNNING_DUST_TRAIL_POSITIONS); + FLOAT3D vOldPos = plp->GetPosition(1); + for(INDEX iPos = 2; iPoslp_ctUsed; iPos++) + { + FLOAT3D vPos = plp->GetPosition(iPos); + if( (vPos-vOldPos).Length()<1.0f) continue; + FLOAT tmStarted = _pTimer->CurrentTick()-iPos*_pTimer->TickQuantum; + INDEX iRnd = INDEX(Abs(vPos(1)*1234.234f+vPos(2)*9834.123f+vPos(3)*543.532f+pen->en_ulID))%(CT_MAX_PARTICLES_TABLE/2); + if( iRnd&3) continue; + + INDEX iRndTex = iRnd*324561+pen->en_ulID; + Particle_SetTexturePart( 512, 512, iRndTex%3, 0); + + FLOAT fLifeTime = 2.8f-(afStarsPositions[iRnd][1]+0.5f)*1.0f; + + FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; + FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.1f, 0.25f); + + FLOAT fRndAppearX = afStarsPositions[iRnd][0]*1.0f; + FLOAT fRndSpeedY = (afStarsPositions[iRnd][1]+0.5f)*0.5f; + FLOAT fRndAppearZ = afStarsPositions[iRnd][2]*1.0f; + vPos(1) += fRndAppearX; + vPos(2) += (0.5f+fRndSpeedY)*fT; + vPos(3) += fRndAppearZ; + + FLOAT fRndBlend = 8.0f+(afStarsPositions[iRnd*2][1]+0.5f)*64.0f; + UBYTE ubRndH = UBYTE( (afStarsPositions[iRnd][0]+0.5f)*64); + UBYTE ubRndS = UBYTE( (afStarsPositions[iRnd][1]+0.5f)*32); + UBYTE ubRndV = UBYTE( 128+afStarsPositions[iRnd][0]*64.0f); + COLOR col = HSVToColor(ubRndH,ubRndS,ubRndV)|UBYTE(fRndBlend*fRatio); + //col=C_RED|CT_OPAQUE; + FLOAT fRotation = afStarsPositions[iRnd+5][0]*360+fT*50.0f*afStarsPositions[iRnd+3][0]; + FLOAT fSize = + 0.75f+(afStarsPositions[iRnd+6][2]+0.5f)*0.25 + // static size + (0.4f+(afStarsPositions[iRnd+2][1]+0.5f)*0.4f)*fT; // dinamic size + Particle_RenderSquare( vPos, fSize, fRotation, col); + vOldPos=vPos; + } + // all done + Particle_Flush(); +} + +void Particles_MetalParts( CEntity *pen, FLOAT tmStarted, FLOATaabbox3D boxOwner, FLOAT fDamage) +{ + Particle_PrepareTexture( &_toMetalSprayTexture, PBT_BLEND); + FLOAT fT = _pTimer->GetLerpedCurrentTick()-tmStarted; + FLOAT fGA = 30.0f; + + FLOAT fBoxSize = boxOwner.Size().Length(); + for(INDEX iPart=0; iPart<6+fDamage*3.0f; iPart++) + { + INDEX iRnd = INDEX(tmStarted*12345.0f+iPart)%CT_MAX_PARTICLES_TABLE; + FLOAT fLifeTime = 2.0f+(afStarsPositions[iRnd][0]+0.5f)*2.0f; + FLOAT fRatio = CalculateRatio(fT, 0, fLifeTime, 0.1f, 0.1f); + Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iPart)%8, 0); + + FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; + vPos(1) += afStarsPositions[iRnd][0]*fT*15; + vPos(2) += afStarsPositions[iRnd][1]*fT*15-fGA/2.0f*fT*fT+boxOwner.Size()(2)*0.25f; + vPos(3) += afStarsPositions[iRnd][2]*fT*15; + + UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + UBYTE ubRndS = UBYTE( 12+(afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1])*8); + //ubRndS = 0; + UBYTE ubRndV = 255; + COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|UBYTE(255.0f*fRatio); + FLOAT fRotation = fT*400.0f*afStarsPositions[iRnd][0]; + FLOAT fSize = fBoxSize*0.005f+0.125f+afStarsPositions[iRnd][1]*0.025f; + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + + // all done + Particle_Flush(); +} + +#define ELECTRICITY_SPARKS_FADE_OUT_TIME 0.4f +#define ELECTRICITY_SPARKS_TOTAL_TIME 1.0f +void Particles_ElectricitySparks( CEntity *pen, FLOAT fTimeAppear, FLOAT fSize, FLOAT fHeight, INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE/2); + FLOAT fT = _pTimer->GetLerpedCurrentTick()-fTimeAppear; + + Particle_PrepareTexture( &_toElectricitySparks, PBT_BLEND); + Particle_SetTexturePart( 512, 1024, 0, 0); + + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; + + for( INDEX iSpark=0; iSparkELECTRICITY_SPARKS_TOTAL_TIME) + { + fFade=0; + } + else if(fT>ELECTRICITY_SPARKS_FADE_OUT_TIME) + { + fFade=-1.0f/(ELECTRICITY_SPARKS_TOTAL_TIME-ELECTRICITY_SPARKS_FADE_OUT_TIME)*(fT-ELECTRICITY_SPARKS_TOTAL_TIME); + } + else + { + fFade=1.0f; + } + + FLOAT fTold = fT-0.05f; + +#define SPARK_CURVE( time) \ + vCenter + \ + vX*(afStarsPositions[iSpark][0]*time*fSize*3) + \ + vY*(afStarsPositions[iSpark][1]*10.0f*time-(15.0f+afStarsPositions[iSpark*2][1]*15.0f)*time*time) + \ + vZ*(afStarsPositions[iSpark][2]*time*fSize*3); + + FLOAT3D vPosOld = SPARK_CURVE( fTold); + FLOAT3D vPosNew = SPARK_CURVE( fT); + + UBYTE ubR = 224+(afStarsPositions[iSpark][2]+0.5f)*32; + UBYTE ubG = 224+(afStarsPositions[iSpark][2]+0.5f)*32; + UBYTE ubB = 160; + UBYTE ubA = FloatToInt( 255 * fFade); + COLOR colStar = RGBToColor( ubR, ubG, ubB) | ubA; + Particle_RenderLine( vPosOld, vPosNew, 0.075f, colStar); + } + // all done + Particle_Flush(); +} + +void Particles_LavaErupting(CEntity *pen, FLOAT fStretchAll, FLOAT fSize, + FLOAT fStretchX, FLOAT fStretchY, FLOAT fStretchZ, + FLOAT fActivateTime) +{ + FLOAT fT = _pTimer->GetLerpedCurrentTick()-fActivateTime; + if( fT>10.0f) return; + + Particle_PrepareTexture( &_toLavaEruptingTexture, PBT_ADD); + INDEX iTexture = ((ULONG)fActivateTime)%3; + Particle_SetTexturePart( 512, 512, iTexture, 0); + FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; + + INDEX iRnd1 = ((ULONG)fActivateTime)%CT_MAX_PARTICLES_TABLE; + INDEX iRnd2 = (~(ULONG)fActivateTime)%CT_MAX_PARTICLES_TABLE; + + FLOAT fRndAppearX = afStarsPositions[iRnd2][0]*fStretchAll; + FLOAT fRndAppearZ = afStarsPositions[iRnd2][1]*fStretchAll; + FLOAT fRndRotation = afStarsPositions[iRnd2][2]; + + FLOAT3D vPos = pen->GetLerpedPlacement().pl_PositionVector; + vPos(1) += fRndAppearX+afStarsPositions[iRnd1][0]*fT*fStretchX*10; + vPos(2) += (fStretchY+(fStretchY*0.25f*afStarsPositions[iRnd1][1]))*fT-fGA/2.0f*fT*fT; + vPos(3) += fRndAppearZ+afStarsPositions[iRnd1][2]*fT*fStretchZ*10; + + Particle_RenderSquare( vPos, fSize+afStarsPositions[iRnd2][2]*fSize*0.5f, fRndRotation*300*fT, C_WHITE|CT_OPAQUE); + + // all done + Particle_Flush(); +} + +#define CT_ATOMIC_TRAIL 32 +void Particles_Atomic( CEntity *pen, FLOAT fSize, FLOAT fHeight, + enum ParticleTexture ptTexture, INDEX ctEllipses) +{ + ASSERT( ctEllipses<=CT_MAX_PARTICLES_TABLE); + FLOAT fMipFactor = Particle_GetMipFactor(); + if( fMipFactor>7.0f) return; + fMipFactor = 2.5f-fMipFactor*0.3f; + fMipFactor = Clamp(fMipFactor, 0.0f ,1.0f); + INDEX ctAtomicTrail = fMipFactor*CT_ATOMIC_TRAIL; + if( ctAtomicTrail<=0) return; + FLOAT fTrailDelta = 0.075f/fMipFactor; + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + SetupParticleTexture( ptTexture); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector+vY*fHeight; + + for( INDEX iEllipse=0; iEllipse>3, ub>>3, ub>>2); + Particle_RenderSquare( vPos, 0.2f, 0, colStar|0xFF); + } + } + // all done + Particle_Flush(); +} + +#define CT_LIGHTNINGS 8 +void Particles_Ghostbuster(const FLOAT3D &vSrc, const FLOAT3D &vDst, INDEX ctRays, FLOAT fSize, FLOAT fPower, + FLOAT fKneeDivider/*=33.3333333f*/) +{ + Particle_PrepareTexture(&_toGhostbusterBeam, PBT_ADD); + Particle_SetTexturePart( 512, 512, 0, 0); + // get direction vector + FLOAT3D vZ = vDst-vSrc; + FLOAT fLen = vZ.Length(); + vZ.Normalize(); + + // get two normal vectors + FLOAT3D vX; + if (Abs(vZ(2))>0.5) { + vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vZ; + } else { + vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vZ; + } + FLOAT3D vY = vZ*vX; + const FLOAT fStep = fLen/fKneeDivider; + + for(INDEX iRay = 0; iRayGetLerpedCurrentTick()/1.5f; + FLOAT fDT = fT-INDEX(fT); + FLOAT fFade = 1-fDT*4.0f; + + if( fFade>1 || fFade<=0) continue; + UBYTE ubFade = NormFloatToByte(fFade*fPower); + COLOR colFade = RGBToColor( ubFade, ubFade, ubFade); + for(FLOAT fPos=fStep; fPosGetLerpedPlacement().pl_PositionVector; + + vPos(1) -= fGridSize*ctGrids/2; + vPos(3) -= fGridSize*ctGrids/2; + + SnapFloat( vPos(1), fGridSize); + SnapFloat( vPos(2), fGridSize); + SnapFloat( vPos(3), fGridSize); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toRaindrop, PBT_BLEND); + Particle_SetTexturePart( 512, 4096, 0, 0); + + FLOAT fMinX = boxRainMap.Min()(1); + FLOAT fMinY = boxRainMap.Min()(2); + FLOAT fMinZ = boxRainMap.Min()(3); + FLOAT fSizeX = boxRainMap.Size()(1); + FLOAT fSizeY = boxRainMap.Size()(2); + FLOAT fSizeZ = boxRainMap.Size()(3); + PIX pixRainMapW = 1; + PIX pixRainMapH = 1; + + if( ptdRainMap != NULL) + { + pixRainMapW = ptdRainMap->GetPixWidth(); + pixRainMapH = ptdRainMap->GetPixHeight(); + } + + //INDEX ctDiscarded=0; + for( INDEX iZ=0; iZ=0 && pixX=0 && pixZGetTexel( pixX, pixZ); + FLOAT fRainMapY = fMinY+((col>>8)&0xFF)/255.0f*fSizeY; + + FLOAT fRainY = vRender(2); + // if tested raindrop is below ceiling + if( fRainY<=fRainMapY) + { + // don't render it + continue; + } else if (fRainY-fSizeGetLerpedPlacement().pl_PositionVector; + + vPos(1) -= fGridSize*ctGrids/2; + vPos(3) -= fGridSize*ctGrids/2; + + SnapFloat( vPos(1), fGridSize); + SnapFloat( vPos(2), fGridSize); + SnapFloat( vPos(3), fGridSize); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + Particle_PrepareTexture(&_toSnowdrop, PBT_BLEND); + Particle_SetTexturePart( 512, 512, 0, 0); + + for( INDEX iZ=0; iZ0.5) + { + vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vZ; + } + else + { + vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vZ; + } + // we found ortonormal vectors + FLOAT3D vY = vZ*vX; + + FLOAT fAllowRnd = 4.0f/fRandomDivider; + fRandomDivider+=1.0f; + vRenderDest = vSrc+ + vZ*fKneeLen + + vX*(fAllowRnd*afStarsPositions[iRnd][0]*fKneeLen) + + vY*(fAllowRnd*afStarsPositions[iRnd][1]*fKneeLen); + // get new rnd index + iRnd = (iRnd+1) % CT_MAX_PARTICLES_TABLE; + // see if we will spawn new branch of lightning + FLOAT fRnd = ((1-ctBranches/ctMaxBranches)*ctKnees)*afStarsPositions[iRnd][0]; + if( (fRnd < 2.0f) && (fPower>0.25f) ) + { + ctBranches++; + FLOAT3D vNewDirection = (vRenderDest-vSrc).Normalize(); + FLOAT3D vNewDst = vSrc + vNewDirection*fLen; + // recurse into new branch + RenderOneLightningBranch( vSrc, vNewDst, fPath, fTimeStart, fTimeNow, fPower/3.0f, iRnd); + } + } + + // calculate color + UBYTE ubA = UBYTE(fPower*255*fTimeKiller); + // render line + Particle_RenderLine( vSrc, vRenderDest, fPower*2, C_WHITE|ubA); + // add traveled path + fPath += (vRenderDest-vSrc).Length(); + if( fPath/LIGHTNING_SPEED > fPassedTime) + { + bRenderInProgress = FALSE; + } + vSrc = vRenderDest; + } +} + +void Particles_Lightning( FLOAT3D vSrc, FLOAT3D vDst, FLOAT fTimeStart) +{ + Particle_PrepareTexture(&_toLightning, PBT_ADDALPHA); + Particle_SetTexturePart( 512, 512, 0, 0); + + FLOAT fTimeNow = _pTimer->GetLerpedCurrentTick(); + // get rnd index + INDEX iRnd = (INDEX( fTimeStart*100))%CT_MAX_PARTICLES_TABLE; + RenderOneLightningBranch( vSrc, vDst, 0, fTimeStart, fTimeNow, 1.0f, iRnd); + + // all done + Particle_Flush(); +} + +#define CT_SANDFLOW_TRAIL 3 +#define SANDFLOW_FADE_OUT 0.25f +#define SANDFLOW_TOTAL_TIME 1.0f +void Particles_SandFlow( CEntity *pen, FLOAT fStretchAll, FLOAT fSize, FLOAT fHeight, FLOAT fStartTime, FLOAT fStopTime, + INDEX ctParticles) +{ + ASSERT( ctParticles<=CT_MAX_PARTICLES_TABLE); + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + SetupParticleTexture( PT_SANDFLOW); + CTextureData *pTD = (CTextureData *) _toSandFlowGradient.GetData(); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); + fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); + ctParticles = FLOAT(ctParticles) * fPowerFactor; + fHeight *= fPowerFactor; + for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; + FLOAT fFade; + if (fT>(1.0f-SANDFLOW_FADE_OUT)) fFade=(1-fT)*(1/SANDFLOW_FADE_OUT); + else fFade=1.0f; + fFade *= (CT_SANDFLOW_TRAIL-iTrail)*(1.0f/CT_SANDFLOW_TRAIL); + + FLOAT3D vPos = vCenter + + vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + + vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + + vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); + + COLOR colSand = pTD->GetTexel( FloatToInt(fT*2048), 0); + ULONG ulA = FloatToInt( ((colSand&CT_AMASK)>>CT_ASHIFT) * fFade); + colSand = (colSand&~CT_AMASK) | (ulA<GetLerpedCurrentTick(); + + SetupParticleTexture( PT_WATERFLOW); + CTextureData *pTD = (CTextureData *) _toWaterFlowGradient.GetData(); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); + fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); + ctParticles = FLOAT(ctParticles) * fPowerFactor; + fHeight *= fPowerFactor; + for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; + FLOAT fFade; + if (fT>(1.0f-WATER_FLOW_FADE_OUT)) fFade=(1-fT)*(1/WATER_FLOW_FADE_OUT); + else fFade=1.0f; + fFade *= (CT_WATER_FLOW_TRAIL-iTrail)*(1.0f/CT_WATER_FLOW_TRAIL); + + FLOAT3D vPos = vCenter + + vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + + vY*(fT*fT*-5.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + + vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); + + COLOR colWater = pTD->GetTexel( FloatToInt(fT*2048), 0); + ULONG ulA = FloatToInt( ((colWater&CT_AMASK)>>CT_ASHIFT) * fFade); + colWater = (colWater&~CT_AMASK) | (ulA<GetLerpedCurrentTick(); + + SetupParticleTexture( PT_LAVAFLOW); + CTextureData *pTD = (CTextureData *) _toLavaFlowGradient.GetData(); + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + FLOAT fPowerFactor = Clamp((fNow - fStartTime)/2.0f,0.0f,1.0f); + fPowerFactor *= Clamp(1+(fStopTime-fNow)/2.0f,0.0f,1.0f); + ctParticles = FLOAT(ctParticles) * fPowerFactor; + fHeight *= fPowerFactor; + for( INDEX iStar=0; iStarfStopTime+2.0f) ) continue; + FLOAT fFade; + if (fT>(1.0f-LAVA_FLOW_FADE_OUT)) fFade=(1-fT)*(1/LAVA_FLOW_FADE_OUT); + else fFade=1.0f; + fFade *= (CT_LAVA_FLOW_TRAIL-iTrail)*(1.0f/CT_LAVA_FLOW_TRAIL); + + FLOAT3D vPos = vCenter + + vX*(afStarsPositions[iStar][0]*fStretchAll*fPowerFactor+fHeight*fT) + + vY*(fT*fT*-4.0f+(afStarsPositions[iStar][1]*fPowerFactor*0.1)) + + vZ*(afStarsPositions[iStar][2]*fPowerFactor*fT*fStretchAll); + + COLOR colLava = pTD->GetTexel( FloatToInt(fT*2048), 0); + ULONG ulA = FloatToInt( ((colLava&CT_AMASK)>>CT_ASHIFT) * fFade); + colLava = (colLava&~CT_AMASK) | (ulA<GetLerpedPlacement().pl_PositionVector; + FLOAT fFadeStart = BULLET_SPRAY_FADEOUT_START; + FLOAT fLifeTotal = BULLET_SPRAY_TOTAL_TIME; + FLOAT fFadeLen = fLifeTotal-fFadeStart; + COLOR colStones = C_WHITE; + + FLOAT fMipFactor = Particle_GetMipFactor(); + FLOAT fDisappear = 1.0f; + if( fMipFactor>8.0f) return; + if( fMipFactor>6.0f) + { + fDisappear = 1.0f-(fMipFactor-6.0f)/2.0f; + } + + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fT=(fNow-tmSpawn); + if( fT>fLifeTotal) return; + INDEX iRnd = INDEX( (tmSpawn*1000.0f)+pen->en_ulID) &63; + FLOAT fSizeStart; + FLOAT fSpeedStart; + FLOAT fConeMultiplier = 1.0f; + COLOR colSmoke; + + switch( eptType) + { + case EPT_BULLET_WATER: + { + Particle_PrepareTexture(&_toBulletWater, PBT_BLEND); + fSizeStart = 0.08f; + fSpeedStart = 1.75f; + fConeMultiplier = 0.125f; + + //FLOAT fFadeStart = BULLET_SPRAY_WATER_FADEOUT_START; + //FLOAT fLifeTotal = BULLET_SPRAY_WATER_TOTAL_TIME; + //FLOAT fFadeLen = fLifeTotal-fFadeStart; + + break; + } + case EPT_BULLET_SAND: + { + colSmoke = 0xFFE8C000; + Particle_PrepareTexture(&_toBulletSand, PBT_BLEND); + fSizeStart = 0.15f; + fSpeedStart = 0.75f; + break; + } + case EPT_BULLET_RED_SAND: + { + colSmoke = 0xA0402000; + colStones = 0x80503000; + Particle_PrepareTexture(&_toBulletSand, PBT_BLEND); + fSizeStart = 0.15f; + fSpeedStart = 0.75f; + break; + } + default: + { + colSmoke = C_WHITE; + Particle_PrepareTexture(&_toBulletStone, PBT_BLEND); + fSizeStart = 0.05f; + fSpeedStart = 1.5f; + } + } + + FLOAT fGA = 10.0f; + + // render particles + for( INDEX iSpray=0; iSpray<12*fDisappear; iSpray++) + { + Particle_SetTexturePart( 512, 512, iSpray&3, 0); + + FLOAT3D vRandomAngle = FLOAT3D( + afStarsPositions[ iSpray+iRnd][0]*3.0f* fConeMultiplier, + (afStarsPositions[ iSpray+iRnd][1]+1.0f)*3.0f, + afStarsPositions[ iSpray+iRnd][2]*3.0f* fConeMultiplier); + FLOAT fSpeedRnd = fSpeedStart+afStarsPositions[ iSpray+iRnd*2][2]; + FLOAT3D vPos = vEntity + (vDirection+vRandomAngle)*(fT*fSpeedRnd)+vGDir*(fT*fT*fGA); + + if( (eptType == EPT_BULLET_WATER) && (vPos(2) < vEntity(2)) ) + { + continue; + } + + FLOAT fSize = fSizeStart + afStarsPositions[ iSpray*2+iRnd*3][0]/20.0f; + FLOAT fRotation = fT*500.0f; + FLOAT fColorFactor = 1.0f; + if( fT>=fFadeStart) + { + fColorFactor = 1-fFadeLen*(fT-fFadeStart); + } + UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); + COLOR col = colStones|ubColor; + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + Particle_Flush(); + + //--------------------------------------- + if( (fT=BULLET_SPARK_FADEOUT_START) + { + fColorFactor = 1-BULLET_SPARK_FADEOUT_LEN*(fT-BULLET_SPARK_FADEOUT_START); + } + UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); + COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; + Particle_RenderLine( vPos0, vPos1, 0.05f, col); + } + Particle_Flush(); + } + + //--------------------------------------- + if( (fT0.5) { + // use cross product of +x axis and plane normal as +s axis + vX = FLOAT3D(1.0f, 0.0f, 0.0f)*vY; + // if the plane is mostly vertical + } else { + // use cross product of +y axis and plane normal as +s axis + vX = FLOAT3D(0.0f, 1.0f, 0.0f)*vY; + } + // make +s axis normalized + vX.Normalize(); + + // use cross product of plane normal and +s axis as +t axis + vZ = vX*vY; + vZ.Normalize(); +} + +void Particles_EmptyShells( CEntity *pen, ShellLaunchData *asldData) +{ + FLOAT tmNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fGA = ((CMovableEntity *)pen)->en_fGravityA; + FLOAT3D vGDir = ((CMovableEntity *)pen)->en_vGravityDir; + INDEX iRow, iColumn; + + for( INDEX iShell=0; iShell (tmLaunch+fLife) ) continue; + FLOAT fTRatio = fT/fLife; + INDEX iFrame = INDEX( fTRatio*16*8)%16; + iRow = iFrame/4; + iColumn = iFrame%4; + Particle_SetTexturePart( 256, 256, iColumn, iRow); + FLOAT3D vPos = (sld.sld_vPos)+(sld.sld_vSpeed*fT)+(vGDir*(fT*fT*fGA/2.0f)); + Particle_RenderSquare( vPos, 0.05f, 0, C_WHITE|CT_OPAQUE); + break; + } + case ESL_SHOTGUN: + { + FLOAT fLife = 1.5f; + if( tmNow > (tmLaunch+fLife) ) continue; + FLOAT fTRatio = fT/fLife; + INDEX iFrame = INDEX( fTRatio*16*8)%16; + iRow = 4+iFrame/4; + iColumn = iFrame%4; + Particle_SetTexturePart( 256, 256, iColumn, iRow); + FLOAT3D vPos = (sld.sld_vPos)+(sld.sld_vSpeed*fT)+(vGDir*(fT*fT*fGA/2.0f)); + Particle_RenderSquare( vPos, 0.05f, 0, C_WHITE|CT_OPAQUE); + break; + } + case ESL_BUBBLE: + { + INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; + FLOAT fLife = 4.0f; + if( tmNow > (tmLaunch+fLife) ) continue; + Particle_SetTexturePart( 512, 512, 2, 0); + + FLOAT3D vX, vZ; + MakeBaseFromVector( sld.sld_vUp, vX, vZ); + + FLOAT fZF = sin( afStarsPositions[iRnd+2][0]*PI); + FLOAT fXF = cos( afStarsPositions[iRnd+2][0]*PI); + + FLOAT fAmpl = ClampUp( fT+afStarsPositions[iRnd+1][1]+0.5f, 2.0f)/64; + FLOAT fFormulae = fAmpl * sin(afStarsPositions[iRnd][1]+fT*afStarsPositions[iRnd][2]*2); + + FLOAT fColorFactor = 1.0f; + if( fT>fLife/2) + { + fColorFactor = -fT+fLife; + } + UBYTE ubAlpha = CT_OPAQUE; + FLOAT3D vSpeedPower = sld.sld_vSpeed/(1.0f+fT*fT); + + FLOAT3D vPos = sld.sld_vPos + + vX*fFormulae*fXF+ + vZ*fFormulae*fZF+ + sld.sld_vUp*fT/4.0f*(0.8f+afStarsPositions[iRnd][1]/8.0f)+ + vSpeedPower*fT; + FLOAT fSize = 0.02f + afStarsPositions[iRnd+3][1]*0.01f; + Particle_RenderSquare( vPos, fSize, 0, C_WHITE|ubAlpha); + break; + } + case ESL_SHOTGUN_SMOKE: + { + FLOAT fLife = 1.0f; + if( fT0.0f) + { + // render smoke + INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; + //FLOAT fTRatio = fT/fLife; + INDEX iColumn = 4+INDEX( iShell)%4; + Particle_SetTexturePart( 256, 256, iColumn, 2); + + FLOAT3D vPos = sld.sld_vPos + sld.sld_vUp*(afStarsPositions[iRnd][0]/2.0f+0.5f)*fT + sld.sld_vSpeed*fT/(1+fT*fT); + FLOAT fColorFactor = (fLife-fT)/fLife/(afStarsPositions[iRnd+1][0]*2+4.0f); + FLOAT fRotation = afStarsPositions[iShell][1]*200*fT; + FLOAT fSize = (0.0125f+fT/(5.0f+afStarsPositions[iRnd+1][0]*2.0f))*sld.sld_fSize; + UBYTE ubAlpha = UBYTE(CT_OPAQUE*ClampUp(fColorFactor*sld.sld_fSize, 1.0f)); + COLOR colSmoke = C_WHITE; + Particle_RenderSquare( vPos, fSize, fRotation, colSmoke|ubAlpha); + } + break; + } + case ESL_COLT_SMOKE: + { + FLOAT fLife = 1.0f; + if( fT0.0f) + { + CPlayer &plr = (CPlayer&)*pen; + CPlacement3D plPipe; + plr.GetLerpedWeaponPosition(sld.sld_vPos, plPipe); + FLOATmatrix3D m; + MakeRotationMatrixFast(m, plPipe.pl_OrientationAngle); + FLOAT3D vUp( m(1,2), m(2,2), m(3,2)); + + INDEX iRnd = (INDEX(tmLaunch*1234))%CT_MAX_PARTICLES_TABLE; + //FLOAT fTRatio = fT/fLife; + INDEX iColumn = 4+INDEX( iShell)%4; + Particle_SetTexturePart( 256, 256, iColumn, 2); + + FLOAT3D vPos = plPipe.pl_PositionVector+vUp*(afStarsPositions[iRnd][0]/4.0f+0.3f)*fT; + FLOAT fColorFactor = (fLife-fT)/fLife/(afStarsPositions[iRnd+1][0]*2+4.0f); + FLOAT fRotation = afStarsPositions[iShell][1]*500*fT; + FLOAT fSize = 0.0025f+fT/(10.0f+(afStarsPositions[iRnd+1][0]+0.5f)*10.0f); + UBYTE ubAlpha = UBYTE(CT_OPAQUE*fColorFactor); + COLOR colSmoke = C_WHITE; + Particle_RenderSquare( vPos, fSize, fRotation, colSmoke|ubAlpha); + } + break; + } + } + } + Particle_Flush(); +} + +#define FADE_IN_LENGHT 1.0f +#define FADE_OUT_LENGHT 1.5f +#define FADE_IN_START 0.0f +#define SPIRIT_SPIRAL_START 1.0f +#define FADE_OUT_START 1.75f + +#define FADE_IN_END (FADE_IN_START+FADE_IN_LENGHT) +#define FADE_OUT_END (FADE_OUT_START+FADE_OUT_LENGHT) + +void Particles_Death(CEntity *pen, TIME tmStart) +{ + FLOAT fMipFactor = Particle_GetMipFactor(); + BOOL bVisible = pen->en_pmoModelObject->IsModelVisible( fMipFactor); + if( !bVisible) return; + + FLOAT fTime = _pTimer->GetLerpedCurrentTick()-tmStart; + // don't render particles before fade in and after fadeout + if( (fTimeFADE_OUT_END)) { + return; + } + FLOAT fPowerTime = pow(fTime-SPIRIT_SPIRAL_START, 2.5f); + + // fill array with absolute vertices of entity's model and its attached models + pen->GetModelVerticesAbsolute(avVertices, 0.05f, fMipFactor); + + // get entity position and orientation + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + SetupParticleTexture( PT_STAR07); + + // calculate color factor (for fade in/out) + FLOAT fColorFactor = 1.0f; + if( (fTime>=FADE_IN_START) && (fTime<=FADE_IN_END)) + { + fColorFactor = 1/FADE_IN_LENGHT*(fTime-FADE_IN_START); + } + else if( (fTime>=FADE_OUT_START) && (fTime<=FADE_OUT_END)) + { + fColorFactor = -1/FADE_OUT_LENGHT*(fTime-FADE_OUT_END); + } + + UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); + COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; + + INDEX ctVtx = avVertices.Count(); + FLOAT fSpeedFactor = 1.0f/ctVtx; + + // get corp size + FLOATaabbox3D box; + pen->en_pmoModelObject->GetCurrentFrameBBox(box); + FLOAT fHeightStretch = box.Size()(2); + + FLOAT fStep = ClampDn( fMipFactor, 1.0f); + for( FLOAT fVtx=0.0f; fVtxen_pmoModelObject->IsModelVisible( fMipFactor); + if( !bVisible) return; + + FLOAT fTime = _pTimer->GetLerpedCurrentTick()-tmStart; + // don't render particles before fade in and after fadeout + if( (fTimeAPPEAR_OUT_END)) { + return; + } + //FLOAT fPowerTime = pow(fTime-SPIRIT_SPIRAL_START, 2.5f); + + // fill array with absolute vertices of entity's model and its attached models + pen->GetModelVerticesAbsolute(avVertices, 0.05f, fMipFactor); + + // get entity position and orientation + const FLOATmatrix3D &m = pen->GetRotationMatrix(); + FLOAT3D vX( m(1,1), m(2,1), m(3,1)); + FLOAT3D vY( m(1,2), m(2,2), m(3,2)); + FLOAT3D vZ( m(1,3), m(2,3), m(3,3)); + //FLOAT3D vCenter = pen->GetLerpedPlacement().pl_PositionVector; + + SetupParticleTexture( PT_STAR07); + + // calculate color factor (for fade in/out) + FLOAT fColorFactor = 1.0f; + if( (fTime>=APPEAR_IN_START) && (fTime<=APPEAR_IN_END)) + { + fColorFactor = 1/APPEAR_IN_LENGHT*(fTime-APPEAR_IN_START); + } + else if( (fTime>=APPEAR_OUT_START) && (fTime<=APPEAR_OUT_END)) + { + fColorFactor = -1/APPEAR_OUT_LENGHT*(fTime-APPEAR_OUT_END); + } + + UBYTE ubColor = UBYTE(CT_OPAQUE*fColorFactor); + COLOR col = RGBToColor(ubColor,ubColor,ubColor)|CT_OPAQUE; + + INDEX ctVtx = avVertices.Count(); + //FLOAT fSpeedFactor = 1.0f/ctVtx; + + // get corp size + FLOATaabbox3D box; + pen->en_pmoModelObject->GetCurrentFrameBBox(box); + //FLOAT fHeightStretch = box.Size()(2); + + FLOAT fStep = ClampDn( fMipFactor, 1.0f); + for( FLOAT fVtx=0.0f; fVtxGetLerpedPlacement().pl_PositionVector; + FLOAT fBoxSize = boxOwner.Size().Length()*0.1f; + FLOAT fEnemySizeModifier = (fBoxSize-0.2)/1.0f+1.0f; + FLOAT fRotation = 0.0f; + + // readout blood type + const INDEX iBloodType = GetSP()->sp_iBlood; + + // determine time difference + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + + // prepare texture + switch(sptType) { + case SPT_BLOOD: + case SPT_SLIME: + { + if( iBloodType<1) return; + if( iBloodType==3) Particle_PrepareTexture( &_toFlowerSprayTexture, PBT_BLEND); + else Particle_PrepareTexture( &_toBloodSprayTexture, PBT_BLEND); + break; + } + case SPT_BONES: + { + Particle_PrepareTexture( &_toBonesSprayTexture, PBT_BLEND); + break; + } + case SPT_FEATHER: + { + Particle_PrepareTexture( &_toFeatherSprayTexture, PBT_BLEND); + fDamagePower*=2.0f; + break; + } + case SPT_STONES: + { + Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); + fDamagePower*=3.0f; + break; + } + case SPT_WOOD: + { + Particle_PrepareTexture( &_toWoodSprayTexture, PBT_BLEND); + fDamagePower*=5.0f; + break; + } + case SPT_SMALL_LAVA_STONES: + { + Particle_PrepareTexture( &_toLavaSprayTexture, PBT_BLEND); + fDamagePower *= 0.75f; + break; + } + case SPT_LAVA_STONES: + { + Particle_PrepareTexture( &_toLavaSprayTexture, PBT_BLEND); + fDamagePower *=3.0f; + break; + } + case SPT_BEAST_PROJECTILE_SPRAY: + { + Particle_PrepareTexture( &_toBeastProjectileSprayTexture, PBT_BLEND); + fDamagePower*=3.0f; + break; + } + case SPT_ELECTRICITY_SPARKS: + { + Particle_PrepareTexture( &_toMetalSprayTexture, PBT_BLEND); + break; + } + default: ASSERT(FALSE); + return; + } + + FLOAT fT=(fNow-tmStarted); + for( INDEX iSpray=0; iSprayBLOOD_SPRAY_FADE_OUT_START) + { + fSize=(-1/(BLOOD_SPRAY_TOTAL_TIME-BLOOD_SPRAY_FADE_OUT_START))*(fT-BLOOD_SPRAY_TOTAL_TIME); + fFade = fSize; + } + else if( fT>BLOOD_SPRAY_TOTAL_TIME) + { + fSize=0.0f; + fFade =0.0f; + } + else + { + fSize=1.0f; + fFade = fSize; + } + FLOAT fMipFactor = Particle_GetMipFactor(); + FLOAT fMipSizeAffector = Clamp( fMipFactor/4.0f, 0.05f, 1.0f); + fSize *= fMipSizeAffector*fDamagePower*fEnemySizeModifier; + + FLOAT3D vRandomAngle = FLOAT3D( + afStarsPositions[ iSpray][0]*1.75f, + (afStarsPositions[ iSpray][1]+1.0f)*1.0f, + afStarsPositions[ iSpray][2]*1.75f); + FLOAT fSpeedModifier = afStarsPositions[ iSpray+BLOOD_SPRAYS][0]*0.5f; + + FLOAT fSpeed = BLOOD_SPRAY_SPEED_MIN+(BLOOD_SPRAY_TOTAL_TIME-fT)/BLOOD_SPRAY_TOTAL_TIME; + FLOAT3D vPos = vWoundPos + (vSpilDirection+vRandomAngle)*(fT*(fSpeed+fSpeedModifier))+vGDir*(fT*fT*fGA/4.0f); + + UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); + FLOAT fSizeModifier = afStarsPositions[ int(iSpray+tmStarted*50)%CT_MAX_PARTICLES_TABLE][1]*0.5+1.0f; + + COLOR col = C_WHITE|CT_OPAQUE; + // prepare texture + switch(sptType) { + case SPT_BLOOD: + { + UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); + if( iBloodType==2) col = RGBAToColor( ubRndCol, 0, 0, ubAlpha); + if( iBloodType==1) col = RGBAToColor( 0, ubRndCol, 0, ubAlpha); + break; + } + case SPT_SLIME: + { + UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); + if( iBloodType!=3) col = RGBAToColor(0, ubRndCol, 0, ubAlpha); + break; + } + case SPT_BONES: + { + UBYTE ubRndH = UBYTE( 8+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); + UBYTE ubRndV = UBYTE( 64+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); + col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + fSize/=1.5f; + break; + } + case SPT_FEATHER: + { + if(iSpray>=BLOOD_SPRAYS/2) + { + UBYTE ubRndCol = UBYTE( 128+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*64); + if( iBloodType==2) col = RGBAToColor( ubRndCol, 0, 0, ubAlpha); + if( iBloodType==1) col = RGBAToColor( 0, ubRndCol, 0, ubAlpha); + } + else + { + UBYTE ubRndH = UBYTE( 32+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + //UBYTE ubRndS = UBYTE( 127+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*128); + UBYTE ubRndV = UBYTE( 159+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*192); + col = HSVToColor(ubRndH, 0, ubRndV)|ubAlpha; + fSize/=2.0f; + fRotation = fT*200.0f; + } + break; + } + case SPT_STONES: + { + UBYTE ubRndH = UBYTE( 24+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + UBYTE ubRndS = UBYTE( 32+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); + UBYTE ubRndV = UBYTE( 196+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*128); + col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + fSize*=0.10f; + fRotation = fT*200.0f; + break; + } + case SPT_WOOD: + { + UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*32); + UBYTE ubRndV = UBYTE( 96+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*96); + col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + fSize*=0.15f; + fRotation = fT*300.0f; + break; + } + case SPT_LAVA_STONES: + case SPT_SMALL_LAVA_STONES: + { + col = C_WHITE|ubAlpha; + fSize/=12.0f; + fRotation = fT*200.0f; + break; + } + case SPT_BEAST_PROJECTILE_SPRAY: + { + col = C_WHITE|ubAlpha; + fSize/=12.0f; + fRotation = fT*200.0f; + break; + } + case SPT_ELECTRICITY_SPARKS: + { + UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); + UBYTE ubRndS = 0; + UBYTE ubRndV = 255; + col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + fSize/=32.0f; + fRotation = fT*200.0f; + break; + } + } + Particle_RenderSquare( vPos, 0.25f*fSize*fSizeModifier, fRotation, col); + } + + // all done + Particle_Flush(); +} + +// spray some stones along obelisk +void Particles_DestroyingObelisk(CEntity *penSpray, FLOAT tmStarted) +{ + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fT=(fNow-tmStarted); + Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); + + FLOAT fTotalTime = 10.0f; + FLOAT fFadeOutStart = 7.5f; + FLOAT fFadeInEnd = 1.0f; + FLOAT3D vG = FLOAT3D(0.0f,-20.0f,0.0f); + + for( INDEX iStone=0; iStone<128; iStone++) + { + INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; + FLOAT3D vSpeed = FLOAT3D( + afStarsPositions[ idx][0], + afStarsPositions[ idx][1], + afStarsPositions[ idx][2]); + vSpeed(2) += 0.25f; + vSpeed *= 50.0f; + + // calculate position + FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + + vSpeed*fT + + vG*fT*fT; + vPos(2) += (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][1]+0.5)*116.0f; + + FLOAT fFade; + // apply fade + if( fTfFadeOutStart) + { + fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); + } + else if( fT>fTotalTime) + { + fFade =0.0f; + } + else + { + fFade = 1.0f; + } + + UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); + UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); + UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); + UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); + COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + + FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*1.5f; + FLOAT fRotation = fT*200.0f; + + Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + // all done + Particle_Flush(); +} + +// spray some stones along pylon +void Particles_DestroyingPylon(CEntity *penSpray, FLOAT3D vDamageDir, FLOAT tmStarted) +{ + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fT=(fNow-tmStarted); + Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); + + FLOAT fTotalTime = 10.0f; + FLOAT fFadeOutStart = 7.5f; + FLOAT fFadeInEnd = 1.0f; + FLOAT3D vG = FLOAT3D(0.0f,-20.0f,0.0f); + const FLOATmatrix3D &m = penSpray->GetRotationMatrix(); + + for( INDEX iStone=0; iStone<128; iStone++) + { + INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; + FLOAT3D vSpeed = vDamageDir+FLOAT3D( + afStarsPositions[ idx][0], + afStarsPositions[ idx][1], + afStarsPositions[ idx][2]); + vSpeed *= 50.0f; + + // calculate position + FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + + vSpeed*fT*m + + vG*fT*fT; + FLOAT3D vOffset = FLOAT3D(0.0f,0.0f,0.0f); + vOffset(1) = (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][1])*32.0f; + vOffset(2) = (afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+0.5)*56.0f; + vPos += vOffset*m; + + FLOAT fFade; + // apply fade + if( fTfFadeOutStart) + { + fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); + } + else if( fT>fTotalTime) + { + fFade =0.0f; + } + else + { + fFade = 1.0f; + } + + UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); + UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); + UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); + UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); + COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + + FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*1.5f; + FLOAT fRotation = fT*200.0f; + + Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + // all done + Particle_Flush(); +} + +// spray some stones in the air +void Particles_HitGround(CEntity *penSpray, FLOAT tmStarted, FLOAT fSizeMultiplier) +{ + FLOAT fNow = _pTimer->GetLerpedCurrentTick(); + FLOAT fT=(fNow-tmStarted); + Particle_PrepareTexture( &_toStonesSprayTexture, PBT_BLEND); + + FLOAT fTotalTime = 10.0f; + FLOAT fFadeOutStart = 7.5f; + FLOAT fFadeInEnd = 1.0f; + FLOAT3D vG = FLOAT3D(0.0f,-30.0f,0.0f); + + for( INDEX iStone=0; iStone<64; iStone++) + { + INDEX idx = int(iStone+tmStarted*33)%CT_MAX_PARTICLES_TABLE; + FLOAT3D vSpeed = FLOAT3D( + afStarsPositions[ idx][0]*1.5f, + (afStarsPositions[ idx][1]+0.5f)*3, + afStarsPositions[ idx][2]*1.5f); + FLOAT fSpeedMultiplier = (fSizeMultiplier-1)*(0.5f-1.0f)/(0.025f-1.0f)+1.0f; + vSpeed *= 50.0f*fSpeedMultiplier; + + // calculate position + FLOAT3D vPos = penSpray->GetPlacement().pl_PositionVector + + vSpeed*fT + + vG*fT*fT; + + FLOAT fFade; + // apply fade + if( fTfFadeOutStart) + { + fFade = (-1/(fTotalTime-fFadeOutStart))*(fT-fTotalTime); + } + else if( fT>fTotalTime) + { + fFade =0.0f; + } + else + { + fFade = 1.0f; + } + + UBYTE ubRndH = UBYTE( 16+afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*8); + UBYTE ubRndS = UBYTE( 96+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*64); + UBYTE ubRndV = UBYTE( 128+(afStarsPositions[ int(iStone+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); + UBYTE ubAlpha = UBYTE(CT_OPAQUE*fFade); + COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; + + FLOAT fSize=(afStarsPositions[ int(iStone+tmStarted*100)%CT_MAX_PARTICLES_TABLE][2]+1.0f)*4.0f*fSizeMultiplier; + FLOAT fRotation = fT*200.0f; + + Particle_SetTexturePart( 256, 256, ((int(tmStarted*100.0f))%8+iStone)%8, 0); + Particle_RenderSquare( vPos, fSize, fRotation, col); + } + // all done + Particle_Flush(); +} diff --git a/Sources/Entities/Common/PathFinding.cpp b/Sources/Entities/Common/PathFinding.cpp index 91742a694..50966e872 100644 --- a/Sources/Entities/Common/PathFinding.cpp +++ b/Sources/Entities/Common/PathFinding.cpp @@ -1,282 +1,275 @@ -#include "../StdH/StdH.h" -#include "Entities/Common/PathFinding.h" -#include "Entities/NavigationMarker.h" - -#define PRINTOUT(_dummy) -//#define PRINTOUT(something) something - -// open and closed lists of nodes -static CListHead _lhOpen; -static CListHead _lhClosed; - -FLOAT NodeDistance(CPathNode *ppn0, CPathNode *ppn1) -{ - return ( - ppn0->pn_pnmMarker->GetPlacement().pl_PositionVector - - ppn1->pn_pnmMarker->GetPlacement().pl_PositionVector).Length(); -} - -CPathNode::CPathNode(class CNavigationMarker *penMarker) -{ - pn_pnmMarker = penMarker; - pn_ppnParent = NULL; - pn_fG = 0.0f; - pn_fH = 0.0f; - pn_fF = 0.0f; -} - -CPathNode::~CPathNode(void) -{ - // detach from marker when deleting - ASSERT(pn_pnmMarker!=NULL); - pn_pnmMarker->m_ppnNode = NULL; -} - -// get name of this node -const CTString &CPathNode::GetName(void) -{ +#include "../StdH/StdH.h" +#include "Entities/Common/PathFinding.h" +#include "Entities/NavigationMarker.h" + +#define PRINTOUT(_dummy) +//#define PRINTOUT(something) something + +// open and closed lists of nodes +static CListHead _lhOpen; +static CListHead _lhClosed; + +FLOAT NodeDistance(CPathNode *ppn0, CPathNode *ppn1) +{ + return ( + ppn0->pn_pnmMarker->GetPlacement().pl_PositionVector - + ppn1->pn_pnmMarker->GetPlacement().pl_PositionVector).Length(); +} + +CPathNode::CPathNode(class CNavigationMarker *penMarker): pn_pnmMarker(penMarker), pn_ppnParent(NULL), pn_fG(0.0f), pn_fH(0.0f), pn_fF(0.0f){} + +CPathNode::~CPathNode(void) +{ + // detach from marker when deleting + ASSERT(pn_pnmMarker!=NULL); + pn_pnmMarker->m_ppnNode = NULL; +} + +// get name of this node +const CTString &CPathNode::GetName(void) +{ ASSERT(this!=NULL); - static CTString strNone=""; - if (pn_pnmMarker==NULL) { - return strNone; - } else { - return pn_pnmMarker->GetName(); - } -} - -// get link with given index or null if no more (for iteration along the graph) -CPathNode *CPathNode::GetLink(INDEX i) -{ - ASSERT(this!=NULL); - if (pn_pnmMarker==NULL) { - ASSERT(FALSE); - return NULL; - } - CNavigationMarker *pnm = pn_pnmMarker->GetLink(i); - if (pnm==NULL) { - return NULL; - } - return pnm->GetPathNode(); -} - -// add given node to open list, sorting best first -static void SortIntoOpenList(CPathNode *ppnLink) -{ - // start at head of the open list - LISTITER(CPathNode, pn_lnInOpen) itpn(_lhOpen); - // while the given node is further than the one in list - while(ppnLink->pn_fF>itpn->pn_fF && !itpn.IsPastEnd()) { - // move to next node - itpn.MoveToNext(); - } - - // if past the end of list - if (itpn.IsPastEnd()) { - // add to the end of list - _lhOpen.AddTail(ppnLink->pn_lnInOpen); - // if not past end of list - } else { - // add before current node - itpn.InsertBeforeCurrent(ppnLink->pn_lnInOpen); - } -} - -// find shortest path from one marker to another -static BOOL FindPath(CNavigationMarker *pnmSrc, CNavigationMarker *pnmDst) -{ - - ASSERT(pnmSrc!=pnmDst); - CPathNode *ppnSrc = pnmSrc->GetPathNode(); - CPathNode *ppnDst = pnmDst->GetPathNode(); - - PRINTOUT(CPrintF("--------------------\n")); - PRINTOUT(CPrintF("FindPath(%s, %s)\n", ppnSrc->GetName(), ppnDst->GetName())); - - // start with empty open and closed lists - ASSERT(_lhOpen.IsEmpty()); - ASSERT(_lhClosed.IsEmpty()); - - // add the start node to open list - ppnSrc->pn_fG = 0.0f; - ppnSrc->pn_fH = NodeDistance(ppnSrc, ppnDst); - ppnSrc->pn_fF = ppnSrc->pn_fG +ppnSrc->pn_fH; - _lhOpen.AddTail(ppnSrc->pn_lnInOpen); - PRINTOUT(CPrintF("StartState: %s\n", ppnSrc->GetName())); - - // while the open list is not empty - while (!_lhOpen.IsEmpty()) { - // get the first node from open list (that is, the one with lowest F) - CPathNode *ppnNode = LIST_HEAD(_lhOpen, CPathNode, pn_lnInOpen); - ppnNode->pn_lnInOpen.Remove(); - _lhClosed.AddTail(ppnNode->pn_lnInClosed); - PRINTOUT(CPrintF("Node: %s - moved from OPEN to CLOSED\n", ppnNode->GetName())); - - // if this is the goal - if (ppnNode==ppnDst) { - PRINTOUT(CPrintF("PATH FOUND!\n")); - // the path is found - return TRUE; - } - - // for each link of current node - CPathNode *ppnLink = NULL; - for(INDEX i=0; (ppnLink=ppnNode->GetLink(i))!=NULL; i++) { - PRINTOUT(CPrintF(" Link %d: %s\n", i, ppnLink->GetName())); - // get cost to get to this node if coming from current node - FLOAT fNewG = ppnLink->pn_fG+NodeDistance(ppnNode, ppnLink); - // if a shorter path already exists - if ((ppnLink->pn_lnInOpen.IsLinked() || ppnLink->pn_lnInClosed.IsLinked()) && fNewG>=ppnLink->pn_fG) { - PRINTOUT(CPrintF(" shorter path exists through: %s\n", ppnLink->pn_ppnParent->GetName())); - // skip this link - continue; - } - // remember this path - ppnLink->pn_ppnParent = ppnNode; - ppnLink->pn_fG = fNewG; - ppnLink->pn_fH = NodeDistance(ppnLink, ppnDst); - ppnLink->pn_fF = ppnLink->pn_fG + ppnLink->pn_fH; - // remove from closed list, if in it - if (ppnLink->pn_lnInClosed.IsLinked()) { - ppnLink->pn_lnInClosed.Remove(); - PRINTOUT(CPrintF(" %s removed from CLOSED\n", ppnLink->GetName())); - } - // add to open if not in it - if (!ppnLink->pn_lnInOpen.IsLinked()) { - SortIntoOpenList(ppnLink); - PRINTOUT(CPrintF(" %s added to OPEN\n", ppnLink->GetName())); - } - } - } - - // if we get here, there is no path - PRINTOUT(CPrintF("PATH NOT FOUND!\n")); - return FALSE; -} - -// clear all temporary structures used for path finding -static void ClearPath(CEntity *penThis) -{ - {FORDELETELIST(CPathNode, pn_lnInOpen, _lhOpen, itpn) { - delete &itpn.Current(); - }} - {FORDELETELIST(CPathNode, pn_lnInClosed, _lhClosed, itpn) { - delete &itpn.Current(); - }} - -#ifndef NDEBUG - // for each navigation marker in the world - {FOREACHINDYNAMICCONTAINER(penThis->en_pwoWorld->wo_cenEntities, CEntity, iten) { - if (!IsOfClass(iten, "NavigationMarker")) { - continue; - } - CNavigationMarker &nm = (CNavigationMarker&)*iten; - ASSERT(nm.m_ppnNode==NULL); - }} -#endif -} - -// find marker closest to a given position -static void FindClosestMarker( - CEntity *penThis, const FLOAT3D &vSrc, CEntity *&penMarker, FLOAT3D &vPath) -{ - CNavigationMarker *pnmMin = NULL; - FLOAT fMinDist = UpperLimit(0.0f); - // for each sector this entity is in - {FOREACHSRCOFDST(penThis->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc) - // for each navigation marker in that sector - {FOREACHDSTOFSRC(pbsc->bsc_rsEntities, CEntity, en_rdSectors, pen) - if (!IsOfClass(pen, "NavigationMarker")) { - continue; - } - CNavigationMarker &nm = (CNavigationMarker&)*pen; - - // get distance from source - FLOAT fDist = (vSrc-nm.GetPlacement().pl_PositionVector).Length(); - // if closer than best found - if(fDistGetPlacement().pl_PositionVector; - penMarker = pnmMin; -} - -// find first marker for path navigation -void PATH_FindFirstMarker(CEntity *penThis, const FLOAT3D &vSrc, const FLOAT3D &vDst, CEntity *&penMarker, FLOAT3D &vPath) -{ - // find closest markers to source and destination positions - CNavigationMarker *pnmSrc; - FLOAT3D vSrcPath; - FindClosestMarker(penThis, vSrc, (CEntity*&)pnmSrc, vSrcPath); - CNavigationMarker *pnmDst; - FLOAT3D vDstPath; - FindClosestMarker(penThis, vDst, (CEntity*&)pnmDst, vDstPath); - - // if at least one is not found, or if they are same - if (pnmSrc==NULL || pnmDst==NULL || pnmSrc==pnmDst) { - // fail - penMarker = NULL; - vPath = vSrc; - return; - } - - // go to the source marker position - vPath = vSrcPath; - penMarker = pnmSrc; -} - -// find next marker for path navigation -void PATH_FindNextMarker(CEntity *penThis, const FLOAT3D &vSrc, const FLOAT3D &vDst, CEntity *&penMarker, FLOAT3D &vPath) -{ - // find closest marker to destination position - CNavigationMarker *pnmDst; - FLOAT3D vDstPath; - FindClosestMarker(penThis, vDst, (CEntity*&)pnmDst, vDstPath); - - // if at not found, or if same as current - if (pnmDst==NULL || penMarker==pnmDst) { - // fail - penMarker = NULL; - vPath = vSrc; - return; - } - - // try to find shortest path to the destination - BOOL bFound = FindPath((CNavigationMarker*)penMarker, pnmDst); - - // if not found - if (!bFound) { - // just clean up and fail - delete pnmDst->GetPathNode(); - ClearPath(penThis); - penMarker = NULL; - vPath = vSrc; - return; - } - - // find the first marker position after current - CPathNode *ppn = pnmDst->GetPathNode(); - while (ppn->pn_ppnParent!=NULL && ppn->pn_ppnParent->pn_pnmMarker!=penMarker) { - ppn = ppn->pn_ppnParent; - } - penMarker = ppn->pn_pnmMarker; - - // go there - vPath = penMarker->GetPlacement().pl_PositionVector; - - // clean up - ClearPath(penThis); -} \ No newline at end of file + static CTString strNone=""; + if (pn_pnmMarker==NULL) { + return strNone; + } else { + return pn_pnmMarker->GetName(); + } +} + +// get link with given index or null if no more (for iteration along the graph) +CPathNode *CPathNode::GetLink(INDEX i) +{ + ASSERT(this!=NULL); + if (pn_pnmMarker==NULL) { + ASSERT(FALSE); + return NULL; + } + CNavigationMarker *pnm = pn_pnmMarker->GetLink(i); + if (pnm==NULL) { + return NULL; + } + return pnm->GetPathNode(); +} + +// add given node to open list, sorting best first +static void SortIntoOpenList(CPathNode *ppnLink) +{ + // start at head of the open list + LISTITER(CPathNode, pn_lnInOpen) itpn(_lhOpen); + // while the given node is further than the one in list + while(ppnLink->pn_fF>itpn->pn_fF && !itpn.IsPastEnd()) { + // move to next node + itpn.MoveToNext(); + } + + // if past the end of list + if (itpn.IsPastEnd()) { + // add to the end of list + _lhOpen.AddTail(ppnLink->pn_lnInOpen); + // if not past end of list + } else { + // add before current node + itpn.InsertBeforeCurrent(ppnLink->pn_lnInOpen); + } +} + +// find shortest path from one marker to another +static BOOL FindPath(CNavigationMarker *pnmSrc, CNavigationMarker *pnmDst) +{ + + ASSERT(pnmSrc!=pnmDst); + CPathNode *ppnSrc = pnmSrc->GetPathNode(); + CPathNode *ppnDst = pnmDst->GetPathNode(); + + PRINTOUT(CPrintF("--------------------\n")); + PRINTOUT(CPrintF("FindPath(%s, %s)\n", ppnSrc->GetName(), ppnDst->GetName())); + + // start with empty open and closed lists + ASSERT(_lhOpen.IsEmpty()); + ASSERT(_lhClosed.IsEmpty()); + + // add the start node to open list + ppnSrc->pn_fG = 0.0f; + ppnSrc->pn_fH = NodeDistance(ppnSrc, ppnDst); + ppnSrc->pn_fF = ppnSrc->pn_fG +ppnSrc->pn_fH; + _lhOpen.AddTail(ppnSrc->pn_lnInOpen); + PRINTOUT(CPrintF("StartState: %s\n", ppnSrc->GetName())); + + // while the open list is not empty + while (!_lhOpen.IsEmpty()) { + // get the first node from open list (that is, the one with lowest F) + CPathNode *ppnNode = LIST_HEAD(_lhOpen, CPathNode, pn_lnInOpen); + ppnNode->pn_lnInOpen.Remove(); + _lhClosed.AddTail(ppnNode->pn_lnInClosed); + PRINTOUT(CPrintF("Node: %s - moved from OPEN to CLOSED\n", ppnNode->GetName())); + + // if this is the goal + if (ppnNode==ppnDst) { + PRINTOUT(CPrintF("PATH FOUND!\n")); + // the path is found + return TRUE; + } + + // for each link of current node + CPathNode *ppnLink = NULL; + for(INDEX i=0; (ppnLink=ppnNode->GetLink(i))!=NULL; i++) { + PRINTOUT(CPrintF(" Link %d: %s\n", i, ppnLink->GetName())); + // get cost to get to this node if coming from current node + FLOAT fNewG = ppnLink->pn_fG+NodeDistance(ppnNode, ppnLink); + // if a shorter path already exists + if ((ppnLink->pn_lnInOpen.IsLinked() || ppnLink->pn_lnInClosed.IsLinked()) && fNewG>=ppnLink->pn_fG) { + PRINTOUT(CPrintF(" shorter path exists through: %s\n", ppnLink->pn_ppnParent->GetName())); + // skip this link + continue; + } + // remember this path + ppnLink->pn_ppnParent = ppnNode; + ppnLink->pn_fG = fNewG; + ppnLink->pn_fH = NodeDistance(ppnLink, ppnDst); + ppnLink->pn_fF = ppnLink->pn_fG + ppnLink->pn_fH; + // remove from closed list, if in it + if (ppnLink->pn_lnInClosed.IsLinked()) { + ppnLink->pn_lnInClosed.Remove(); + PRINTOUT(CPrintF(" %s removed from CLOSED\n", ppnLink->GetName())); + } + // add to open if not in it + if (!ppnLink->pn_lnInOpen.IsLinked()) { + SortIntoOpenList(ppnLink); + PRINTOUT(CPrintF(" %s added to OPEN\n", ppnLink->GetName())); + } + } + } + + // if we get here, there is no path + PRINTOUT(CPrintF("PATH NOT FOUND!\n")); + return FALSE; +} + +// clear all temporary structures used for path finding +static void ClearPath(CEntity *penThis) +{ + {FORDELETELIST(CPathNode, pn_lnInOpen, _lhOpen, itpn) { + delete &itpn.Current(); + }} + {FORDELETELIST(CPathNode, pn_lnInClosed, _lhClosed, itpn) { + delete &itpn.Current(); + }} + +#ifndef NDEBUG + // for each navigation marker in the world + {FOREACHINDYNAMICCONTAINER(penThis->en_pwoWorld->wo_cenEntities, CEntity, iten) { + if (!IsOfClass(iten, "NavigationMarker")) { + continue; + } + CNavigationMarker &nm = (CNavigationMarker&)*iten; + ASSERT(nm.m_ppnNode==NULL); + }} +#endif +} + +// find marker closest to a given position +static void FindClosestMarker( + CEntity *penThis, const FLOAT3D &vSrc, CEntity *&penMarker, FLOAT3D &vPath) +{ + CNavigationMarker *pnmMin = NULL; + FLOAT fMinDist = UpperLimit(0.0f); + // for each sector this entity is in + {FOREACHSRCOFDST(penThis->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc) + // for each navigation marker in that sector + {FOREACHDSTOFSRC(pbsc->bsc_rsEntities, CEntity, en_rdSectors, pen) + if (!IsOfClass(pen, "NavigationMarker")) { + continue; + } + CNavigationMarker &nm = (CNavigationMarker&)*pen; + + // get distance from source + FLOAT fDist = (vSrc-nm.GetPlacement().pl_PositionVector).Length(); + // if closer than best found + if(fDistGetPlacement().pl_PositionVector; + penMarker = pnmMin; +} + +// find first marker for path navigation +void PATH_FindFirstMarker(CEntity *penThis, const FLOAT3D &vSrc, const FLOAT3D &vDst, CEntity *&penMarker, FLOAT3D &vPath) +{ + // find closest markers to source and destination positions + CNavigationMarker *pnmSrc; + FLOAT3D vSrcPath; + FindClosestMarker(penThis, vSrc, (CEntity*&)pnmSrc, vSrcPath); + CNavigationMarker *pnmDst; + FLOAT3D vDstPath; + FindClosestMarker(penThis, vDst, (CEntity*&)pnmDst, vDstPath); + + // if at least one is not found, or if they are same + if (pnmSrc==NULL || pnmDst==NULL || pnmSrc==pnmDst) { + // fail + penMarker = NULL; + vPath = vSrc; + return; + } + + // go to the source marker position + vPath = vSrcPath; + penMarker = pnmSrc; +} + +// find next marker for path navigation +void PATH_FindNextMarker(CEntity *penThis, const FLOAT3D &vSrc, const FLOAT3D &vDst, CEntity *&penMarker, FLOAT3D &vPath) +{ + // find closest marker to destination position + CNavigationMarker *pnmDst; + FLOAT3D vDstPath; + FindClosestMarker(penThis, vDst, (CEntity*&)pnmDst, vDstPath); + + // if at not found, or if same as current + if (pnmDst==NULL || penMarker==pnmDst) { + // fail + penMarker = NULL; + vPath = vSrc; + return; + } + + // try to find shortest path to the destination + BOOL bFound = FindPath((CNavigationMarker*)penMarker, pnmDst); + + // if not found + if (!bFound) { + // just clean up and fail + delete pnmDst->GetPathNode(); + ClearPath(penThis); + penMarker = NULL; + vPath = vSrc; + return; + } + + // find the first marker position after current + CPathNode *ppn = pnmDst->GetPathNode(); + while (ppn->pn_ppnParent!=NULL && ppn->pn_ppnParent->pn_pnmMarker!=penMarker) { + ppn = ppn->pn_ppnParent; + } + penMarker = ppn->pn_pnmMarker; + + // go there + vPath = penMarker->GetPlacement().pl_PositionVector; + + // clean up + ClearPath(penThis); +} diff --git a/Sources/Entities/GhostBusterRay.cpp b/Sources/Entities/GhostBusterRay.cpp deleted file mode 100644 index 4e57b8fda..000000000 --- a/Sources/Entities/GhostBusterRay.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98 - */ - -#line 2 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" - -#include "Entities/StdH/StdH.h" - -#include -#include -CEntityEvent *EGhostBusterRay::MakeCopy(void) { CEntityEvent *peeCopy = new EGhostBusterRay(*this); return peeCopy;} -EGhostBusterRay::EGhostBusterRay() : CEntityEvent(EVENTCODE_EGhostBusterRay) {; - ClearToDefault(penOwner); -}; -#line 16 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" - -#define HIT_DISTANCE 50.0f // ray hit distance -#define HIT_DAMAGE 15.0f // hit damage for every lerping bullet - -void CGhostBusterRay_OnPrecache(CDLLEntityClass *pdec, INDEX iUser) -{ - pdec->PrecacheClass(CLASS_BULLET); - pdec->PrecacheModel(MODEL_RAY); - pdec->PrecacheTexture(TEXTURE_RAY); -} - -void CGhostBusterRay::SetDefaultProperties(void) { - m_penOwner = NULL; - m_bRender = FALSE ; - m_vSrcOld = FLOAT3D(0.0f , 0.0f , 0.0f); - m_vDstOld = FLOAT3D(0.0f , 0.0f , 0.0f); - m_vSrc = FLOAT3D(0.0f , 0.0f , 0.0f); - m_vDst = FLOAT3D(0.0f , 0.0f , 0.0f); - m_iLastBulletPosition = FLOAT3D(32000.0f , 32000.0f , 32000.0f); - m_aoLightAnim.SetData(NULL); - - m_ctPasses = 0; - m_penPrediction = NULL; - CMovableModelEntity::SetDefaultProperties(); -} - -#line 61 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::AddDependentsToPrediction(void) -#line 62 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -{ -#line 63 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_penOwner -> AddToPrediction (); -#line 64 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 66 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::RenderParticles(void) -#line 67 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -{ -#line 68 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -if(m_ctPasses < 2){ -#line 69 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -return ; -#line 70 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} -#line 71 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -FLOAT3D vLerpedSrc = Lerp (m_vSrcOld , m_vSrc , _pTimer -> GetLerpFactor ()); -#line 72 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -FLOAT3D vLerpedDst = Lerp (m_vDstOld , m_vDst , _pTimer -> GetLerpFactor ()); -#line 73 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Particles_Ghostbuster (vLerpedSrc , vLerpedDst , 32 , 1.0f); -#line 74 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 77 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::Read_t(CTStream * istr) -#line 78 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -{ -#line 79 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CMovableModelEntity :: Read_t (istr ); -#line 80 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetupLightSource (); -#line 81 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 84 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CLightSource * CGhostBusterRay::GetLightSource(void) -#line 85 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -{ -#line 86 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -if(! IsPredictor ()){ -#line 87 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -return & m_lsLightSource ; -#line 88 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -}else { -#line 89 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -return NULL ; -#line 90 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} -#line 91 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 94 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::SetupLightSource(void) -#line 95 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -{ -#line 97 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CLightSource lsNew ; -#line 98 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_ulFlags = LSF_NONPERSISTENT | LSF_DYNAMIC ; -#line 99 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_colColor = RGBToColor (134 , 238 , 255); -#line 100 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_rFallOff = 10.0f; -#line 101 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_rHotSpot = 1.0f; -#line 102 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_plftLensFlare = NULL ; -#line 103 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_ubPolygonalMask = 0; -#line 104 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -lsNew . ls_paoLightAnimation = & m_aoLightAnim ; -#line 106 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_lsLightSource . ls_penEntity = this ; -#line 107 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_lsLightSource . SetLightSource (lsNew ); -#line 108 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 115 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::DoMoving(void) { -#line 116 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -en_plLastPlacement = GetPlacement (); -#line 117 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 119 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::PostMoving(void) { -#line 120 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -if(! IsOfClass (m_penOwner , "Player Weapons")){return ;} -#line 123 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CPlacement3D plSource ; -#line 124 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CPlayerWeapons &) * m_penOwner ) . GetGhostBusterSourcePlacement (plSource ); -#line 125 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -FLOAT3D vDirection , vDesired ; -#line 126 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -AnglesToDirectionVector (plSource . pl_OrientationAngle , vDirection ); -#line 127 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -vDesired = vDirection * HIT_DISTANCE ; -#line 128 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -vDesired = plSource . pl_PositionVector + vDesired ; -#line 131 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CCastRay crRay (((CPlayerWeapons &) * m_penOwner ) . m_penPlayer , plSource . pl_PositionVector , vDesired ); -#line 132 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_vSrcOld = m_vSrc ; -#line 133 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_vSrc = plSource . pl_PositionVector ; -#line 134 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -crRay . cr_bHitTranslucentPortals = FALSE ; -#line 135 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -crRay . cr_ttHitModels = CCastRay :: TT_COLLISIONBOX ; -#line 136 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -GetWorld () -> CastRay (crRay ); -#line 139 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -if(crRay . cr_penHit != NULL ){ -#line 140 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -vDesired = crRay . cr_vHit ; -#line 141 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} -#line 142 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -vDesired -= vDirection / 10.0f; -#line 144 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_vDstOld = m_vDst ; -#line 145 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_vDst = vDesired ; -#line 148 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -FLOAT fStretch = (plSource . pl_PositionVector - vDesired ) . Length (); -#line 150 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -GetModelObject () -> mo_Stretch (3) = 0.001f; -#line 152 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CPlacement3D plSet ; -#line 153 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -plSet . pl_PositionVector = vDesired ; -#line 154 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -plSet . pl_OrientationAngle = plSource . pl_OrientationAngle ; -#line 155 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetPlacement (plSet ); -#line 156 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_ctPasses ++; -#line 157 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 165 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::PrepareBullet(const CPlacement3D & plBullet) { -#line 167 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -penBullet = CreateEntity (plBullet , CLASS_BULLET ); -#line 169 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -EBulletInit eInit ; -#line 170 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -eInit . penOwner = ((CPlayerWeapons &) * m_penOwner ) . m_penPlayer ; -#line 171 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -eInit . fDamage = HIT_DAMAGE ; -#line 172 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -penBullet -> Initialize (eInit ); -#line 173 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . m_EdtDamage = DMT_BULLET ; -#line 174 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 177 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::Fire(const CPlacement3D & plSource) { -#line 178 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -if(! IsOfClass (m_penOwner , "Player Weapons")){return ;} -#line 181 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -PrepareBullet (plSource ); -#line 182 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . CalcTarget (HIT_DISTANCE ); -#line 183 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . m_fBulletSize = 0.5f; -#line 184 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . CalcJitterTarget (0.02f * HIT_DISTANCE ); -#line 185 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . LaunchBullet (TRUE , FALSE , TRUE ); -#line 186 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -((CBullet &) * penBullet ) . DestroyBullet (); -#line 187 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} - -#line 190 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void CGhostBusterRay::DestroyGhostBusterRay(void) { -#line 191 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Destroy (); -#line 192 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} -BOOL CGhostBusterRay:: -#line 201 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Main(const CEntityEvent &__eeInput) { -#undef STATE_CURRENT -#define STATE_CURRENT STATE_CGhostBusterRay_Main - ASSERTMSG(__eeInput.ee_slEvent==EVENTCODE_EGhostBusterRay, "CGhostBusterRay::Main expects 'EGhostBusterRay' as input!"); const EGhostBusterRay &egbr = (const EGhostBusterRay &)__eeInput; -#line 203 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -ASSERT (egbr . penOwner != NULL ); -#line 204 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_penOwner = egbr . penOwner ; -#line 207 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -InitAsModel (); -#line 208 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetPhysicsFlags (EPF_MODEL_IMMATERIAL ); -#line 209 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetCollisionFlags (ECF_IMMATERIAL ); -#line 210 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetModel (MODEL_RAY ); -#line 211 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetModelMainTexture (TEXTURE_RAY ); -#line 213 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -try { -#line 214 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_aoLightAnim . SetData_t (CTFILENAME ("Animations\\GhostbusterLightning.ani")); -#line 215 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_aoLightAnim . PlayAnim (0 , AOF_LOOPING ); -#line 216 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -}catch (char * strError ){ -#line 217 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CPrintF ("%s" , strError ); -#line 218 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -} -#line 221 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -SetupLightSource (); -#line 224 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -AddToMovers (); -#line 225 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -m_ctPasses = 0; -#line 227 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Return(STATE_CURRENT,EVoid()); -#line 227 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -return TRUE; ASSERT(FALSE); return TRUE;}; \ No newline at end of file diff --git a/Sources/Entities/GhostBusterRay.h b/Sources/Entities/GhostBusterRay.h deleted file mode 100644 index 77ae4a60d..000000000 --- a/Sources/Entities/GhostBusterRay.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98 - */ - -#ifndef _Entities_GhostBusterRay_INCLUDED -#define _Entities_GhostBusterRay_INCLUDED 1 -#include -#include -#include -#include -#define EVENTCODE_EGhostBusterRay 0x01f90000 -class DECL_DLL EGhostBusterRay : public CEntityEvent { -public: -EGhostBusterRay(); -CEntityEvent *MakeCopy(void); -CEntityPointer penOwner; -}; -DECL_DLL inline void ClearToDefault(EGhostBusterRay &e) { e = EGhostBusterRay(); } ; -extern "C" DECL_DLL CDLLEntityClass CGhostBusterRay_DLLClass; -class CGhostBusterRay : public CMovableModelEntity { -public: -virtual CEntity *GetPredictionPair(void) { return m_penPrediction; }; -virtual void SetPredictionPair(CEntity *penPair) { m_penPrediction = penPair; }; - DECL_DLL virtual void SetDefaultProperties(void); - CEntityPointer m_penOwner; - BOOL m_bRender; - FLOAT3D m_vSrcOld; - FLOAT3D m_vDstOld; - FLOAT3D m_vSrc; - FLOAT3D m_vDst; - FLOAT3D m_iLastBulletPosition; - CAnimObject m_aoLightAnim; - INDEX m_ctPasses; - CEntityPointer m_penPrediction; -CLightSource m_lsLightSource; -CEntity * penBullet; -const CPlacement3D * pplSource; - -#line 61 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void AddDependentsToPrediction(void); - -#line 66 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void RenderParticles(void); - -#line 77 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void Read_t(CTStream * istr); - -#line 84 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -CLightSource * GetLightSource(void); - -#line 94 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void SetupLightSource(void); - -#line 115 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void DoMoving(void); - -#line 119 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void PostMoving(void); - -#line 165 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void PrepareBullet(const CPlacement3D & plBullet); - -#line 177 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void Fire(const CPlacement3D & plSource); - -#line 190 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -void DestroyGhostBusterRay(void); -#define STATE_CGhostBusterRay_Main 1 - BOOL -#line 201 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Main(const CEntityEvent &__eeInput); -}; -#endif // _Entities_GhostBusterRay_INCLUDED diff --git a/Sources/Entities/GhostBusterRay_tables.h b/Sources/Entities/GhostBusterRay_tables.h deleted file mode 100644 index fe1645c58..000000000 --- a/Sources/Entities/GhostBusterRay_tables.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98 - */ - -#define ENTITYCLASS CGhostBusterRay - -CEntityProperty CGhostBusterRay_properties[] = { - CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x000001f9<<8)+1, _offsetof(CGhostBusterRay, m_penOwner), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_BOOL, NULL, (0x000001f9<<8)+2, _offsetof(CGhostBusterRay, m_bRender), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_FLOAT3D, NULL, (0x000001f9<<8)+3, _offsetof(CGhostBusterRay, m_vSrcOld), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_FLOAT3D, NULL, (0x000001f9<<8)+4, _offsetof(CGhostBusterRay, m_vDstOld), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_FLOAT3D, NULL, (0x000001f9<<8)+5, _offsetof(CGhostBusterRay, m_vSrc), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_FLOAT3D, NULL, (0x000001f9<<8)+6, _offsetof(CGhostBusterRay, m_vDst), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_FLOAT3D, NULL, (0x000001f9<<8)+10, _offsetof(CGhostBusterRay, m_iLastBulletPosition), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_ANIMOBJECT, NULL, (0x000001f9<<8)+11, _offsetof(CGhostBusterRay, m_aoLightAnim), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_INDEX, NULL, (0x000001f9<<8)+12, _offsetof(CGhostBusterRay, m_ctPasses), "", 0, 0, 0), - CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x000001f9<<8)+255, _offsetof(CGhostBusterRay, m_penPrediction), "", 0, 0, 0), -}; -#define CGhostBusterRay_propertiesct ARRAYCOUNT(CGhostBusterRay_properties) - -CEntityComponent CGhostBusterRay_components[] = { -#define CLASS_LIGHT ((0x000001f9<<8)+1) - CEntityComponent(ECT_CLASS, CLASS_LIGHT, "EFNM" "Classes\\Light.ecl"), -#define CLASS_BULLET ((0x000001f9<<8)+2) - CEntityComponent(ECT_CLASS, CLASS_BULLET, "EFNM" "Classes\\Bullet.ecl"), -#define MODEL_RAY ((0x000001f9<<8)+10) - CEntityComponent(ECT_MODEL, MODEL_RAY, "EFNM" "Models\\Weapons\\GhostBuster\\Projectile\\Ray.mdl"), -#define TEXTURE_RAY ((0x000001f9<<8)+11) - CEntityComponent(ECT_TEXTURE, TEXTURE_RAY, "EFNM" "Models\\Weapons\\GhostBuster\\Projectile\\Ray.tex"), -}; -#define CGhostBusterRay_componentsct ARRAYCOUNT(CGhostBusterRay_components) - -CEventHandlerEntry CGhostBusterRay_handlers[] = { - {1, -1, CEntity::pEventHandler(&CGhostBusterRay:: -#line 201 "/home/seb/git/Serious-Seb/Sources/Entities/GhostBusterRay.es" -Main),DEBUGSTRING("CGhostBusterRay::Main")}, -}; -#define CGhostBusterRay_handlersct ARRAYCOUNT(CGhostBusterRay_handlers) - -CEntity *CGhostBusterRay_New(void) { return new CGhostBusterRay; }; -void CGhostBusterRay_OnInitClass(void) {}; -void CGhostBusterRay_OnEndClass(void) {}; -void CGhostBusterRay_OnPrecache(CDLLEntityClass *pdec, INDEX iUser); -void CGhostBusterRay_OnWorldEnd(CWorld *pwo) {}; -void CGhostBusterRay_OnWorldInit(CWorld *pwo) {}; -void CGhostBusterRay_OnWorldTick(CWorld *pwo) {}; -void CGhostBusterRay_OnWorldRender(CWorld *pwo) {}; -ENTITY_CLASSDEFINITION(CGhostBusterRay, CMovableModelEntity, "GhostBusterRay", "", 0x000001f9); -DECLARE_CTFILENAME(_fnmCGhostBusterRay_tbn, ""); diff --git a/Sources/Entities/Player.es b/Sources/Entities/Player.es index e62c7f38d..d1356e7b1 100644 --- a/Sources/Entities/Player.es +++ b/Sources/Entities/Player.es @@ -1280,10 +1280,10 @@ functions: for(INDEX iMsg=0; iMsgWrite_t(&m_psLevelStats, sizeof(m_psLevelStats)); - ostr->Write_t(&m_psLevelTotal, sizeof(m_psLevelTotal)); - ostr->Write_t(&m_psGameStats , sizeof(m_psGameStats )); - ostr->Write_t(&m_psGameTotal , sizeof(m_psGameTotal )); + (*ostr)<Read_t(&m_psLevelStats, sizeof(m_psLevelStats)); - istr->Read_t(&m_psLevelTotal, sizeof(m_psLevelTotal)); - istr->Read_t(&m_psGameStats , sizeof(m_psGameStats )); - istr->Read_t(&m_psGameTotal , sizeof(m_psGameTotal )); + (*istr)>>m_psLevelStats; + (*istr)>>m_psLevelTotal; + (*istr)>>m_psGameStats; + (*istr)>>m_psGameTotal; // set your real appearance if possible ValidateCharacter(); @@ -5864,7 +5864,7 @@ procedures: // if any found if (penNextPlayer!=NULL) { // transfer keys to that player - CPrintF(TRANS("%s leaving, all keys transfered to %s\n"), + CPrintF(TRANS("%s leaving, all keys transferred to %s\n"), (const char*)m_strName, (const char*)penNextPlayer->GetPlayerName()); penNextPlayer->m_ulKeys |= m_ulKeys; } diff --git a/Sources/Entities/PlayerWeapons.es b/Sources/Entities/PlayerWeapons.es index 92266b9d9..4e1db9e6e 100644 --- a/Sources/Entities/PlayerWeapons.es +++ b/Sources/Entities/PlayerWeapons.es @@ -559,7 +559,7 @@ components: 2 class CLASS_BULLET "Classes\\Bullet.ecl", 3 class CLASS_WEAPONEFFECT "Classes\\PlayerWeaponsEffects.ecl", 4 class CLASS_PIPEBOMB "Classes\\Pipebomb.ecl", - 5 class CLASS_GHOSTBUSTERRAY "Classes\\GhostBusterRay.ecl", +// 5 class CLASS_GHOSTBUSTERRAY "Classes\\GhostBusterRay.ecl", 6 class CLASS_CANNONBALL "Classes\\CannonBall.ecl", 7 class CLASS_WEAPONITEM "Classes\\WeaponItem.ecl", diff --git a/Sources/Entities/WorldBase.es b/Sources/Entities/WorldBase.es index a66dc1918..af905111f 100644 --- a/Sources/Entities/WorldBase.es +++ b/Sources/Entities/WorldBase.es @@ -266,19 +266,19 @@ void SetPyramidMorphRoomAlpha(CWorld *pwo, INDEX iBlending, TIME tmActivated) void CWorldBase_OnWorldInit(CWorld *pwo) { pwo->wo_attTextureTransformations[0].tt_strName = "None"; - pwo->wo_attTextureTransformations[1].tt_strName = "R Extremly Slow"; + pwo->wo_attTextureTransformations[1].tt_strName = "R Extremely Slow"; pwo->wo_attTextureTransformations[2].tt_strName = "R Very Slow"; pwo->wo_attTextureTransformations[3].tt_strName = "R Slow"; pwo->wo_attTextureTransformations[4].tt_strName = "R Medium"; pwo->wo_attTextureTransformations[5].tt_strName = "R Fast"; pwo->wo_attTextureTransformations[6].tt_strName = "R Very Fast"; - pwo->wo_attTextureTransformations[7].tt_strName = "R Extremly Fast"; + pwo->wo_attTextureTransformations[7].tt_strName = "R Extremely Fast"; pwo->wo_attTextureTransformations[8].tt_strName = "Dummy 1"; pwo->wo_attTextureTransformations[9].tt_strName = "Dummy 2"; pwo->wo_attTextureTransformations[10].tt_strName = "Dummy 3"; - pwo->wo_attTextureTransformations[11].tt_strName = "Water movement extremly slow"; + pwo->wo_attTextureTransformations[11].tt_strName = "Water movement Extremely slow"; pwo->wo_attTextureTransformations[12].tt_strName = "Water movement very slow"; pwo->wo_attTextureTransformations[13].tt_strName = "Water movement slow"; pwo->wo_attTextureTransformations[14].tt_strName = "Water movement normal"; @@ -308,15 +308,15 @@ void CWorldBase_OnWorldInit(CWorld *pwo) pwo->wo_attTextureTransformations[35].tt_strName = "Rotation Right 9"; pwo->wo_attTextureTransformations[36].tt_strName = "Rotation Right 10"; - pwo->wo_attTextureTransformations[37].tt_strName = "D Extremly Slow"; + pwo->wo_attTextureTransformations[37].tt_strName = "D Extremely Slow"; pwo->wo_attTextureTransformations[38].tt_strName = "D Very Slow"; pwo->wo_attTextureTransformations[39].tt_strName = "D Slow"; pwo->wo_attTextureTransformations[40].tt_strName = "D Medium"; pwo->wo_attTextureTransformations[41].tt_strName = "D Fast"; pwo->wo_attTextureTransformations[42].tt_strName = "D Very Fast"; - pwo->wo_attTextureTransformations[43].tt_strName = "D Extremly Fast"; + pwo->wo_attTextureTransformations[43].tt_strName = "D Extremely Fast"; pwo->wo_attTextureTransformations[44].tt_strName = "D Super Fast"; - pwo->wo_attTextureTransformations[45].tt_strName = "D Abnormaly Fast"; + pwo->wo_attTextureTransformations[45].tt_strName = "D Abnormally Fast"; // static pwo->wo_atbTextureBlendings[0].tb_strName = "Opaque"; diff --git a/Sources/EntitiesMP/BloodSpray.es b/Sources/EntitiesMP/BloodSpray.es index 09075b36f..4b94e1565 100644 --- a/Sources/EntitiesMP/BloodSpray.es +++ b/Sources/EntitiesMP/BloodSpray.es @@ -23,7 +23,7 @@ event ESpawnSpray { enum SprayParticlesType sptType, // type of particles FLOAT fDamagePower, // factor saying how powerfull damage has been FLOAT fSizeMultiplier, // stretch factor - FLOAT3D vDirection, // dammage direction + FLOAT3D vDirection, // damage direction CEntityPointer penOwner, // who spawned the spray COLOR colCentralColor, // central color of particles that is randomized a little FLOAT fLaunchPower, @@ -39,7 +39,7 @@ properties: 1 enum SprayParticlesType m_sptType = SPT_NONE, // type of particles 2 FLOAT m_tmStarted = 0.0f, // time when spawned - 3 FLOAT3D m_vDirection = FLOAT3D(0,0,0), // dammage direction + 3 FLOAT3D m_vDirection = FLOAT3D(0,0,0), // damage direction 5 CEntityPointer m_penOwner, // who spawned the spray 6 FLOAT m_fDamagePower = 1.0f, // power of inflicted damage 8 FLOATaabbox3D m_boxSizedOwner = FLOATaabbox3D(FLOAT3D(0,0,0), 0.01f), // bounding box of blood spray's owner diff --git a/Sources/EntitiesMP/Camera.es b/Sources/EntitiesMP/Camera.es index be6cf664a..3464ecd03 100644 --- a/Sources/EntitiesMP/Camera.es +++ b/Sources/EntitiesMP/Camera.es @@ -75,7 +75,7 @@ properties: 65 FLOAT m_fRotateSpeed "AR Rotate speed" 'S' = 180.0f, 66 FLOAT m_fRotateTime "AR Rotate time" 'I' = 8.0f, 67 FLOAT m_fRadX "AR Radius X" 'X' = 8.0f, - 68 FLOAT m_fHeight "AR Height (controlls pitch)" 'H' = 4.0f, + 68 FLOAT m_fHeight "AR Height (controls pitch)" 'H' = 4.0f, 69 FLOAT m_fRadZ "AR Radius Z" 'Z' = 8.0f, 70 CEntityPointer m_penAutoCameraEndTarget "Auto camera end target", diff --git a/Sources/EntitiesMP/Common/Common.h b/Sources/EntitiesMP/Common/Common.h index f68dee81c..304081ab1 100644 --- a/Sources/EntitiesMP/Common/Common.h +++ b/Sources/EntitiesMP/Common/Common.h @@ -156,14 +156,7 @@ struct DECL_DLL PlayerStats { INDEX ps_iSecrets; TIME ps_tmTime; - PlayerStats(void) - { - ps_iScore = 0; - ps_iKills = 0; - ps_iDeaths = 0; - ps_iSecrets = 0; - ps_tmTime = 0.0f; - } + PlayerStats(void): ps_iScore(0), ps_iKills(0), ps_iDeaths(0), ps_iSecrets(0), ps_tmTime(0.0f){} }; static inline CTStream &operator>>(CTStream &strm, PlayerStats &ps) diff --git a/Sources/EntitiesMP/Common/HUD.cpp b/Sources/EntitiesMP/Common/HUD.cpp old mode 100644 new mode 100755 index e4360d67d..60a9756d1 --- a/Sources/EntitiesMP/Common/HUD.cpp +++ b/Sources/EntitiesMP/Common/HUD.cpp @@ -519,18 +519,18 @@ static void HUD_DrawBar( FLOAT fCenterX, FLOAT fCenterY, PIX pixSizeX, PIX pixSi // determine bar position and inner size switch( eBarOrientation) { case BO_UP: - pixSizeJ *= (PIX) fNormValue; + pixSizeJ = (PIX) (pixSizeJ*fNormValue); break; case BO_DOWN: pixUpper = pixUpper + (PIX)ceil(pixSizeJ * (1.0f-fNormValue)); - pixSizeJ *= (PIX) fNormValue; + pixSizeJ = (PIX) (pixSizeJ*fNormValue); break; case BO_LEFT: - pixSizeI *= (PIX) fNormValue; + pixSizeI = (PIX) (pixSizeI*fNormValue); break; case BO_RIGHT: pixLeft = pixLeft + (PIX)ceil(pixSizeI * (1.0f-fNormValue)); - pixSizeI *= (PIX) fNormValue; + pixSizeI = (PIX) (pixSizeI*fNormValue); break; } // done @@ -562,8 +562,7 @@ static void DrawAspectCorrectTextureCentered( class CTextureObject *_pTO, FLOAT CTextureData *ptd = (CTextureData*)_pTO->GetData(); FLOAT fTexSizeI = ptd->GetPixWidth(); FLOAT fTexSizeJ = ptd->GetPixHeight(); - FLOAT fHeight = fWidth*fTexSizeJ/fTexSizeJ; // FIXME: not fTexSizeJ/fTexSizeI ?? - STUBBED("fWidth*fTexSizeJ/fTexSizeJ is most likely not intended!"); + FLOAT fHeight = fWidth*fTexSizeJ/fTexSizeI; _pDP->InitTexture( _pTO); _pDP->AddTexture( fX-fWidth*0.5f, fY-fHeight*0.5f, fX+fWidth*0.5f, fY+fHeight*0.5f, 0, 0, 1, 1, col); @@ -1181,7 +1180,7 @@ extern void DrawHUD( const CPlayer *penPlayerCurrent, CDrawPort *pdpCurrent, BOO if( iHealth>25) colHealth = _colHUD; if( iArmor >25) colArmor = _colHUD; // eventually print it out - if( hud_iShowPlayers==1 || (hud_iShowPlayers==-1 && !bSinglePlay)) { + if( hud_iShowPlayers==1 || hud_iShowPlayers==-1) { // printout location and info aren't the same for deathmatch and coop play const FLOAT fCharWidth = (PIX)((_pfdDisplayFont->GetWidth()-2) *fTextScale); if( bCooperative) { diff --git a/Sources/EntitiesMP/Common/Particles.cpp b/Sources/EntitiesMP/Common/Particles.cpp index d8ad616d3..4a0841e40 100755 --- a/Sources/EntitiesMP/Common/Particles.cpp +++ b/Sources/EntitiesMP/Common/Particles.cpp @@ -2284,9 +2284,8 @@ void Particles_MetalParts( CEntity *pen, FLOAT tmStarted, FLOATaabbox3D boxOwner UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); UBYTE ubRndS = UBYTE( 12+(afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1])*8); - UBYTE ubRndV = UBYTE( 192+(afStarsPositions[ int(iPart+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); //ubRndS = 0; - ubRndV = 255; + UBYTE ubRndV = 255; COLOR col = HSVToColor(ubRndH, ubRndS, ubRndV)|UBYTE(255.0f*fRatio); FLOAT fRotation = fT*400.0f*afStarsPositions[iRnd][0]; FLOAT fSize = fBoxSize*0.005f+0.125f+afStarsPositions[iRnd][1]*0.025f; @@ -4502,10 +4501,8 @@ void Particles_BloodSpray(enum SprayParticlesType sptType, FLOAT3D vSource, FLOA case SPT_ELECTRICITY_SPARKS: { UBYTE ubRndH = UBYTE( 180+afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][0]*16); - UBYTE ubRndS = UBYTE( 32+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][1]+0.5)*16); - UBYTE ubRndV = UBYTE( 192+(afStarsPositions[ int(iSpray+tmStarted*10)%CT_MAX_PARTICLES_TABLE][2])*64); - ubRndS = 0; - ubRndV = 255; + UBYTE ubRndS = 0; + UBYTE ubRndV = 255; col = HSVToColor(ubRndH, ubRndS, ubRndV)|ubAlpha; fSize/=32.0f; fRotation = fT*200.0f; diff --git a/Sources/EntitiesMP/ModelHolder2.es b/Sources/EntitiesMP/ModelHolder2.es index 21df4ec8c..0bd90cd33 100644 --- a/Sources/EntitiesMP/ModelHolder2.es +++ b/Sources/EntitiesMP/ModelHolder2.es @@ -105,7 +105,7 @@ properties: 80 COLOR m_colBurning = COLOR(C_WHITE|CT_OPAQUE), // color applied when burning 90 enum DamageType m_dmtLastDamageType=DMT_CHAINSAW, - 91 FLOAT m_fChainSawCutDamage "Chain saw cut dammage" 'C' = 300.0f, + 91 FLOAT m_fChainSawCutDamage "Chain saw cut damage" 'C' = 300.0f, 93 INDEX m_iFirstRandomAnimation "First random animation" 'R' = -1, 100 FLOAT m_fMaxTessellationLevel "Max tessellation level" = 0.0f, @@ -227,7 +227,7 @@ functions: { EDeath eDeath; // we don't need any extra parameters SendEvent(eDeath); - //remember last dammage type + //remember last damage type m_dmtLastDamageType=dmtType; } } @@ -290,7 +290,7 @@ functions: { EDeath eDeath; // we don't need any extra parameters SendEvent(eDeath); - //remember last dammage type + //remember last damage type m_dmtLastDamageType=dmtType; } } diff --git a/Sources/EntitiesMP/ModelHolder3.es b/Sources/EntitiesMP/ModelHolder3.es index 394258869..2dfe93e39 100644 --- a/Sources/EntitiesMP/ModelHolder3.es +++ b/Sources/EntitiesMP/ModelHolder3.es @@ -106,7 +106,7 @@ properties: // 80 COLOR m_colBurning = COLOR(C_WHITE|CT_OPAQUE), // color applied when burning // 90 enum DamageType m_dmtLastDamageType=DMT_CHAINSAW, -// 91 FLOAT m_fChainSawCutDamage "Chain saw cut dammage" 'C' = 300.0f, +// 91 FLOAT m_fChainSawCutDamage "Chain saw cut damage" 'C' = 300.0f, // 93 INDEX m_iFirstRandomAnimation "First random animation" 'R' = -1, 100 FLOAT m_fMaxTessellationLevel "Max tessellation level" = 0.0f, @@ -239,7 +239,7 @@ functions: { EDeath eDeath; // we don't need any extra parameters SendEvent(eDeath); - //remember last dammage type + //remember last damage type m_dmtLastDamageType=dmtType; } } @@ -302,7 +302,7 @@ functions: { EDeath eDeath; // we don't need any extra parameters SendEvent(eDeath); - //remember last dammage type + //remember last damage type m_dmtLastDamageType=dmtType; } } diff --git a/Sources/EntitiesMP/Player.es b/Sources/EntitiesMP/Player.es index 505a27025..c972df4d9 100755 --- a/Sources/EntitiesMP/Player.es +++ b/Sources/EntitiesMP/Player.es @@ -1530,10 +1530,10 @@ functions: for(INDEX iMsg=0; iMsgWrite_t(&m_psLevelStats, sizeof(m_psLevelStats)); - ostr->Write_t(&m_psLevelTotal, sizeof(m_psLevelTotal)); - ostr->Write_t(&m_psGameStats , sizeof(m_psGameStats )); - ostr->Write_t(&m_psGameTotal , sizeof(m_psGameTotal )); + (*ostr)<GetPlayerName()); penNextPlayer->m_ulKeys |= m_ulKeys; } diff --git a/Sources/EntitiesMP/PlayerView.es b/Sources/EntitiesMP/PlayerView.es index cf9efa6ff..25b76530f 100755 --- a/Sources/EntitiesMP/PlayerView.es +++ b/Sources/EntitiesMP/PlayerView.es @@ -103,7 +103,7 @@ functions: // 3rd person view FLOAT fDistance = 1.0f; CPlacement3D pl = ((CPlayerEntity&) *m_penOwner).en_plViewpoint; - BOOL bFollowCrossHair; + BOOL bFollowCrossHair = TRUE; if (m_iViewType == VT_3RDPERSONVIEW) { // little above player eyes so it can be seen where he is firing diff --git a/Sources/EntitiesMP/PlayerWeapons.es b/Sources/EntitiesMP/PlayerWeapons.es index 0ebc4eb28..e4d7b5667 100755 --- a/Sources/EntitiesMP/PlayerWeapons.es +++ b/Sources/EntitiesMP/PlayerWeapons.es @@ -645,7 +645,7 @@ components: 2 class CLASS_BULLET "Classes\\Bullet.ecl", 3 class CLASS_WEAPONEFFECT "Classes\\PlayerWeaponsEffects.ecl", 4 class CLASS_PIPEBOMB "Classes\\Pipebomb.ecl", - 5 class CLASS_GHOSTBUSTERRAY "Classes\\GhostBusterRay.ecl", +// 5 class CLASS_GHOSTBUSTERRAY "Classes\\GhostBusterRay.ecl", 6 class CLASS_CANNONBALL "Classes\\CannonBall.ecl", 7 class CLASS_WEAPONITEM "Classes\\WeaponItem.ecl", 8 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl", diff --git a/Sources/EntitiesMP/WorldBase.es b/Sources/EntitiesMP/WorldBase.es index 8cbfb8fff..a2ba23945 100644 --- a/Sources/EntitiesMP/WorldBase.es +++ b/Sources/EntitiesMP/WorldBase.es @@ -302,19 +302,19 @@ void SetPyramidMorphRoomAlpha(CWorld *pwo, INDEX iBlending, TIME tmActivated) void CWorldBase_OnWorldInit(CWorld *pwo) { pwo->wo_attTextureTransformations[0].tt_strName = "None"; - pwo->wo_attTextureTransformations[1].tt_strName = "R Extremly Slow"; + pwo->wo_attTextureTransformations[1].tt_strName = "R Extremely Slow"; pwo->wo_attTextureTransformations[2].tt_strName = "R Very Slow"; pwo->wo_attTextureTransformations[3].tt_strName = "R Slow"; pwo->wo_attTextureTransformations[4].tt_strName = "R Medium"; pwo->wo_attTextureTransformations[5].tt_strName = "R Fast"; pwo->wo_attTextureTransformations[6].tt_strName = "R Very Fast"; - pwo->wo_attTextureTransformations[7].tt_strName = "R Extremly Fast"; + pwo->wo_attTextureTransformations[7].tt_strName = "R Extremely Fast"; pwo->wo_attTextureTransformations[8].tt_strName = "Dummy 1"; pwo->wo_attTextureTransformations[9].tt_strName = "Dummy 2"; pwo->wo_attTextureTransformations[10].tt_strName = "Dummy 3"; - pwo->wo_attTextureTransformations[11].tt_strName = "Water movement extremly slow"; + pwo->wo_attTextureTransformations[11].tt_strName = "Water movement Extremely slow"; pwo->wo_attTextureTransformations[12].tt_strName = "Water movement very slow"; pwo->wo_attTextureTransformations[13].tt_strName = "Water movement slow"; pwo->wo_attTextureTransformations[14].tt_strName = "Water movement normal"; @@ -344,15 +344,15 @@ void CWorldBase_OnWorldInit(CWorld *pwo) pwo->wo_attTextureTransformations[35].tt_strName = "Rotation Right 9"; pwo->wo_attTextureTransformations[36].tt_strName = "Rotation Right 10"; - pwo->wo_attTextureTransformations[37].tt_strName = "D Extremly Slow"; + pwo->wo_attTextureTransformations[37].tt_strName = "D Extremely Slow"; pwo->wo_attTextureTransformations[38].tt_strName = "D Very Slow"; pwo->wo_attTextureTransformations[39].tt_strName = "D Slow"; pwo->wo_attTextureTransformations[40].tt_strName = "D Medium"; pwo->wo_attTextureTransformations[41].tt_strName = "D Fast"; pwo->wo_attTextureTransformations[42].tt_strName = "D Very Fast"; - pwo->wo_attTextureTransformations[43].tt_strName = "D Extremly Fast"; + pwo->wo_attTextureTransformations[43].tt_strName = "D Extremely Fast"; pwo->wo_attTextureTransformations[44].tt_strName = "D Super Fast"; - pwo->wo_attTextureTransformations[45].tt_strName = "D Abnormaly Fast"; + pwo->wo_attTextureTransformations[45].tt_strName = "D Abnormally Fast"; // static pwo->wo_atbTextureBlendings[0].tb_strName = "Opaque"; diff --git a/Sources/GameMP/Game.cpp b/Sources/GameMP/Game.cpp index 0b9a2dd13..f3322b6a5 100755 --- a/Sources/GameMP/Game.cpp +++ b/Sources/GameMP/Game.cpp @@ -188,8 +188,7 @@ class CEnableUserBreak { ~CEnableUserBreak(); }; -CEnableUserBreak::CEnableUserBreak() { - bOld = _bUserBreakEnabled; +CEnableUserBreak::CEnableUserBreak(): bOld(_bUserBreakEnabled){ _bUserBreakEnabled = TRUE; } CEnableUserBreak::~CEnableUserBreak() { @@ -1535,7 +1534,7 @@ void CGame::UnpackHighScoreTable(SLONG slSize) gm_ahseHighScores[i].hse_strPlayer = (const char*)pub; pub += MAX_HIGHSCORENAME+1; memcpy(&gm_ahseHighScores[i].hse_gdDifficulty, pub, sizeof(INDEX)); - BYTESWAP(gm_ahseHighScores[i].hse_gdDifficulty); + BYTESWAP((int&)gm_ahseHighScores[i].hse_gdDifficulty); pub += sizeof(INDEX); memcpy(&gm_ahseHighScores[i].hse_tmTime , pub, sizeof(FLOAT)); BYTESWAP(gm_ahseHighScores[i].hse_tmTime); @@ -1903,6 +1902,7 @@ static void PrintStats( CDrawPort *pdpDrawPort) // display nothing _iCheckNow = 0; _iCheckMax = 0; + STAT_Enable(FALSE); return; } @@ -1943,6 +1943,7 @@ static void PrintStats( CDrawPort *pdpDrawPort) if( hud_iStats==2 && hud_iEnableStats) { // display extensive statistics CTString strReport; + STAT_Enable(TRUE); STAT_Report(strReport); STAT_Reset(); @@ -1958,6 +1959,7 @@ static void PrintStats( CDrawPort *pdpDrawPort) pdpDrawPort->PutText( strFPS, 0, 40, C_WHITE|CT_OPAQUE); pdpDrawPort->PutText( strReport, 4, 65, C_GREEN|CT_OPAQUE); } + else STAT_Enable(FALSE); } @@ -2802,11 +2804,13 @@ void CGame::GameMainLoop(void) static CTextureObject _toPointer; static CTextureObject _toBcgClouds; static CTextureObject _toBcgGrid; +#ifndef FIRST_ENCOUNTER static CTextureObject _toBackdrop; static CTextureObject _toSamU; static CTextureObject _toSamD; static CTextureObject _toLeftU; static CTextureObject _toLeftD; +#endif static PIXaabbox2D _boxScreen_SE; static PIX _pixSizeI_SE; @@ -2838,20 +2842,24 @@ void CGame::LCDInit(void) _toBcgGrid.SetData_t(CTFILENAME("TexturesMP\\General\\grid.tex")); #endif // thoses are not in original TFE datas and must be added externaly (with SE1_10.gro or a minimal versio of it) +#ifndef FIRST_ENCOUNTER _toBackdrop.SetData_t(CTFILENAME("TexturesMP\\General\\MenuBack.tex")); _toSamU.SetData_t(CTFILENAME("TexturesMP\\General\\SamU.tex")); _toSamD.SetData_t(CTFILENAME("TexturesMP\\General\\SamD.tex")); _toLeftU.SetData_t(CTFILENAME("TexturesMP\\General\\LeftU.tex")); _toLeftD.SetData_t(CTFILENAME("TexturesMP\\General\\LeftD.tex")); +#endif // force constant textures ((CTextureData*)_toBcgClouds.GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toPointer .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toBcgGrid .GetData())->Force(TEX_CONSTANT); +#ifndef FIRST_ENCOUNTER ((CTextureData*)_toBackdrop .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toSamU .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toSamD .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toLeftU .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toLeftD .GetData())->Force(TEX_CONSTANT); +#endif } catch (char *strError) { FatalError("%s\n", strError); @@ -2911,6 +2919,7 @@ void CGame::LCDScreenBoxOpenRight(COLOR col) } void CGame::LCDRenderClouds1(void) { +#ifndef FIRST_ENCOUNTER _pdp_SE->PutTexture(&_toBackdrop, _boxScreen_SE, C_WHITE|255); if (!_bPopup) { @@ -2924,7 +2933,7 @@ void CGame::LCDRenderClouds1(void) INDEX iYB = iYM + iSize; INDEX iXL = 420; INDEX iXR = (INDEX) (iXL + iSize*_pdp_SE->dp_fWideAdjustment); - + box = PIXaabbox2D( PIX2D( iXL*_pdp_SE->GetWidth()/640, iYU*_pdp_SE->GetHeight()/480) , PIX2D( iXR*_pdp_SE->GetWidth()/640, iYM*_pdp_SE->GetHeight()/480)); _pdp_SE->PutTexture(&_toSamU, box, SE_COL_BLUE_NEUTRAL|255); @@ -2957,7 +2966,9 @@ void CGame::LCDRenderClouds1(void) _pdp_SE->PutTexture(&_toLeftD, box, SE_COL_BLUE_NEUTRAL|200); } - +#else + _pdp_SE->Fill(SE_COL_BLUE_DARK_HV | 255); +#endif MEXaabbox2D boxBcgClouds1; TiledTextureSE(_boxScreen_SE, 1.2f*_pdp_SE->GetWidth()/640.0f, MEX2D(sin(_tmNow_SE*0.5f)*35,sin(_tmNow_SE*0.7f+1)*21), boxBcgClouds1); diff --git a/Sources/GameMP/Game.h b/Sources/GameMP/Game.h index 5821ae243..0d6198797 100644 --- a/Sources/GameMP/Game.h +++ b/Sources/GameMP/Game.h @@ -139,10 +139,8 @@ class CLocalPlayer CPlayerSource *lp_pplsPlayerSource; UBYTE lp_ubPlayerControlsState[2048]; // current state of player controls that are local to the player // Construction - CLocalPlayer( void) + CLocalPlayer(void): lp_pplsPlayerSource(NULL), lp_bActive(FALSE) { - lp_pplsPlayerSource = NULL; - lp_bActive = FALSE; memset(lp_ubPlayerControlsState, 0, sizeof(lp_ubPlayerControlsState)) ; }; }; diff --git a/Sources/GameMP/Map.cpp b/Sources/GameMP/Map.cpp index f46bdf2e7..c617425c8 100644 --- a/Sources/GameMP/Map.cpp +++ b/Sources/GameMP/Map.cpp @@ -427,6 +427,7 @@ PIX aPathDotsFE[][10][2] = BOOL ObtainMapData(void) { try { + if(!map_bIsFirstEncounter) { // the second encounter atoIconsSE[ 0].SetData_t(CTFILENAME("TexturesMP\\Computer\\Map\\Book.tex")); atoIconsSE[ 1].SetData_t(CTFILENAME("TexturesMP\\Computer\\Map\\Level00.tex")); @@ -465,7 +466,7 @@ BOOL ObtainMapData(void) ((CTextureData*)_toMapBcgLUSE .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgRDSE .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgRUSE .GetData())->Force(TEX_CONSTANT); - + } else { // the first encounter atoIconsFE[ 0].SetData_t(CTFILENAME("Textures\\Computer\\Map\\Level00.tex")); atoIconsFE[ 1].SetData_t(CTFILENAME("Textures\\Computer\\Map\\Level01.tex")); @@ -482,6 +483,7 @@ BOOL ObtainMapData(void) atoIconsFE[12].SetData_t(CTFILENAME("Textures\\Computer\\Map\\Level12.tex")); atoIconsFE[13].SetData_t(CTFILENAME("Textures\\Computer\\Map\\Level13.tex")); atoIconsFE[14].SetData_t(CTFILENAME("Textures\\Computer\\Map\\Level14.tex")); + _toPathDot .SetData_t(CTFILENAME("Textures\\Computer\\Map\\PathDot.tex")); _toMapBcgLDFE .SetData_t(CTFILENAME("Textures\\Computer\\Map\\MapBcgLD.tex")); _toMapBcgLUFE .SetData_t(CTFILENAME("Textures\\Computer\\Map\\MapBcgLU.tex")); _toMapBcgRDFE .SetData_t(CTFILENAME("Textures\\Computer\\Map\\MapBcgRD.tex")); @@ -502,10 +504,12 @@ BOOL ObtainMapData(void) ((CTextureData*)atoIconsFE[12].GetData())->Force(TEX_CONSTANT); ((CTextureData*)atoIconsFE[13].GetData())->Force(TEX_CONSTANT); ((CTextureData*)atoIconsFE[14].GetData())->Force(TEX_CONSTANT); + ((CTextureData*)_toPathDot .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgLDFE .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgLUFE .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgRDFE .GetData())->Force(TEX_CONSTANT); ((CTextureData*)_toMapBcgRUFE .GetData())->Force(TEX_CONSTANT); + } } catch (char *strError) { CPrintF("%s\n", strError); diff --git a/Sources/GameMP/SEColors.h b/Sources/GameMP/SEColors.h index a1921bc6d..745fc9c53 100644 --- a/Sources/GameMP/SEColors.h +++ b/Sources/GameMP/SEColors.h @@ -16,16 +16,39 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef __SECOLORS_H #define __SECOLORS_H 1 +#ifdef FIRST_ENCOUNTER + +// names of defines are incorrect, should be white/green +#define SE_COL_ORANGE_LIGHT 0xFAFAFF00 +#define SE_COL_ORANGE_NEUTRAL 0x00F20000 +#define SE_COL_ORANGE_DARK 0x007F0000 +#define SE_COL_ORANGE_DARK_LT 0x00BF0000 + +#define SE_COL_BLUE_DARK_HV 0x01160400 +#define SE_COL_BLUE_DARK 0x255F2400 +#define SE_COL_BLUE_DARK_LT 0x29702D00 +#define SE_COL_BLUE_NEUTRAL 0x349D3A00 +#define SE_COL_BLUE_NEUTRAL_LT 0x3AAD3600 +#define SE_COL_BLUE_LIGHT 0x6AF53E00 + +#else + #define SE_COL_ORANGE_LIGHT 0xffd70000 #define SE_COL_ORANGE_NEUTRAL 0xee9c0000 #define SE_COL_ORANGE_DARK 0x9b4b0000 #define SE_COL_ORANGE_DARK_LT 0xbc6a0000 + #define SE_COL_BLUE_DARK_HV 0x151c2300 #define SE_COL_BLUE_DARK 0x2a384600 #define SE_COL_BLUE_DARK_LT 0x43596f00 #define SE_COL_BLUE_NEUTRAL 0x5c7a9900 #define SE_COL_BLUE_NEUTRAL_LT 0x6097cc00 #define SE_COL_BLUE_LIGHT 0x64b4ff00 + +#endif + + #define SE_COL_BLUEGREEN_LT 0x6cff6c00 + #endif diff --git a/Sources/SeriousSam/Menu.cpp b/Sources/SeriousSam/Menu.cpp index a2f992dea..f45a7c941 100644 --- a/Sources/SeriousSam/Menu.cpp +++ b/Sources/SeriousSam/Menu.cpp @@ -4357,7 +4357,7 @@ void CLoadSaveMenu::StartMenu(void) // list the directory CDynamicStackArray afnmDir; - MakeDirList(afnmDir, gm_fnmDirectory, CTString(""), 0); + MakeDirList(afnmDir, gm_fnmDirectory, CTString(""), DLI_SEARCHCD); gm_iLastFile = -1; // for each file in the directory @@ -5633,7 +5633,7 @@ void CNetworkStartMenu::Initialize_t(void) // server visible trigger TRIGGER_MG(mgNetworkVisible, 7, mgNetworkMaxPlayers, mgNetworkGameOptions, TRANS("Server visible:"), astrNoYes); - mgNetworkVisible.mg_strTip = TRANS("invisible servers are not listed, cleints have to join manually"); + mgNetworkVisible.mg_strTip = TRANS("invisible servers are not listed, clients have to join manually"); // options button mgNetworkGameOptions.mg_strText = TRANS("Game options"); diff --git a/Sources/SeriousSam/SeriousSam.cpp b/Sources/SeriousSam/SeriousSam.cpp index c7ffa5647..6dd64c147 100755 --- a/Sources/SeriousSam/SeriousSam.cpp +++ b/Sources/SeriousSam/SeriousSam.cpp @@ -33,7 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #define DECL_DLL +#ifdef FIRST_ENCOUNTER +#include +#else #include +#endif #include "resource.h" #include "SplashScreen.h" #include "MainWindow.h" @@ -282,7 +286,7 @@ static void UpdatePauseState(void) void LimitFrameRate(void) { // do not limit FPS on the Pandora, it's not powerfull enough and doesn't "iconise" games either - #ifndef PLATFORM_PANDORA + #if !defined(PLATFORM_PANDORA) && !defined(PLATFORM_PYRA) // measure passed time for each loop static CTimerValue tvLast(-1.0f); CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); @@ -362,6 +366,10 @@ void StartNextDemo(void) } } + if (_lhAutoDemos.Count()==1){ + _bInAutoPlayLoop = FALSE; + } + if (_gmRunningGameMode==GM_NONE) { _bInAutoPlayLoop = FALSE; } @@ -473,6 +481,17 @@ BOOL Init( HINSTANCE hInstance, int nCmdShow, CTString strCmdLine) SDL_Init(SDL_INIT_JOYSTICK); // don't care if this fails. #endif +#ifdef PLATFORM_PANDORA + // enable Cortex A8 RunFast + int v = 0; + __asm__ __volatile__ ( + "vmrs %0, fpscr\n" + "orr %0, #((1<<25)|(1<<24))\n" // default NaN, flush-to-zero + "vmsr fpscr, %0\n" + //"vmrs %0, fpscr\n" + : "=&r"(v)); +#endif + _hInstance = hInstance; ShowSplashScreen(hInstance); @@ -1009,15 +1028,41 @@ int SubMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int } } #else - STUBBED("SDL2 can handle these events"); + if( msg.message==SDL_WINDOWEVENT) + { + switch( msg.wParam) { + case SDL_WINDOWEVENT_MINIMIZED: + if( _bWindowChanging) break; + _bWindowChanging = TRUE; + _bReconsiderInput = TRUE; + // if allowed, not already paused and only in single player game mode + if( sam_bPauseOnMinimize && !_pNetwork->IsPaused() && _gmRunningGameMode==GM_SINGLE_PLAYER) { + // pause game + _pNetwork->TogglePause(); + } + break; + } + } #endif // toggle full-screen on alt-enter if( msg.message==WM_SYSKEYDOWN && msg.wParam==VK_RETURN && !IsIconic(_hwndMain)) { - // !!! FIXME: SDL doesn't need to rebuild the GL context here to toggle fullscreen. - STUBBED("SDL doesn't need to rebuild the GL context here..."); +#ifdef PLATFORM_WIN32 StartNewMode( (GfxAPIType)sam_iGfxAPI, sam_iDisplayAdapter, sam_iScreenSizeI, sam_iScreenSizeJ, (enum DisplayDepth)sam_iDisplayDepth, !sam_bFullScreenActive); +#else + int res = SDL_SetWindowFullscreen((SDL_Window *) _hwndMain, sam_bFullScreenActive ? 0 : SDL_WINDOW_FULLSCREEN); + if (res == 0) { + sam_bFullScreenActive = !sam_bFullScreenActive; + char achWindowTitle[256]; + if (sam_bFullScreenActive) + SDL_snprintf( achWindowTitle, sizeof (achWindowTitle), TRANS("Serious Sam (FullScreen %dx%d)"), sam_iScreenSizeI, sam_iScreenSizeJ); + else + SDL_snprintf( achWindowTitle, sizeof (achWindowTitle), TRANS("Serious Sam (Window %dx%d)"), sam_iScreenSizeI, sam_iScreenSizeJ); + SDL_SetWindowTitle((SDL_Window *) _hwndMain, achWindowTitle); + } else + CPrintF("Can't toggle full-screen : %s\n", SDL_GetError()); +#endif if (_pInput != NULL) // rcg02042003 hack for SDL vs. Win32. _pInput->ClearRelativeMouseMotion(); @@ -1319,8 +1364,11 @@ int SubMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int void CheckModReload(void) { -#ifdef PLATFORM_WIN32 if (_fnmModToLoad!="") { + CTString strMod = _fnmModToLoad.FileName(); + const char *argv[9]; + int i = 0; +#ifdef PLATFORM_WIN32 #ifndef NDEBUG CTString strDebug = "Debug\\"; #else @@ -1328,25 +1376,33 @@ void CheckModReload(void) #endif CTString strCommand = _fnmApplicationPath+"Bin\\"+strDebug+"SeriousSam.exe"; //+mod "+_fnmModToLoad.FileName()+"\""; - CTString strMod = _fnmModToLoad.FileName(); - const char *argv[7]; - argv[0] = strCommand; - argv[1] = "+game"; - argv[2] = strMod; - argv[3] = NULL; + argv[i++] = strCommand; +#else + argv[i++] = argv0; +#endif + argv[i++] = "+game"; + argv[i++] = strMod; + argv[i] = NULL; + if (_fnmCDPath!="") { + argv[i++] = "+cdpath"; + argv[i++] = _fnmCDPath; + argv[i] = NULL; + } if (_strModServerJoin!="") { - argv[3] = "+connect"; - argv[4] = _strModServerJoin; - argv[5] = "+quickjoin"; - argv[6] = NULL; + argv[i++] = "+connect"; + argv[i++] = _strModServerJoin; + argv[i++] = "+quickjoin"; + argv[i] = NULL; } +#ifdef PLATFORM_WIN32 _execv(strCommand, argv); MessageBoxA(0, "Error launching the Mod!\n", "Serious Sam", MB_OK|MB_ICONERROR); - } #else - STUBBED("reload ourself?"); + execv(argv0, (char* const*)argv); + fprintf(stderr, "Error launching Mod '%s'! execv(%s, ...)\n", strMod, argv0); #endif + } } void CheckTeaser(void) @@ -1357,8 +1413,6 @@ void CheckTeaser(void) Sleep(500); _execl(fnmTeaser, "\""+fnmTeaser+"\"", NULL); } -#else - STUBBED("load teaser"); #endif } diff --git a/Sources/SeriousSam/SplashScreen.cpp b/Sources/SeriousSam/SplashScreen.cpp index bd7d3bc73..52060cd04 100644 --- a/Sources/SeriousSam/SplashScreen.cpp +++ b/Sources/SeriousSam/SplashScreen.cpp @@ -131,9 +131,9 @@ static SDL_Texture *texture = NULL; void HideSplashScreen(void) { + if (window) { SDL_DestroyWindow(window); window = NULL; } if (texture) { SDL_DestroyTexture(texture); texture = NULL; } if (renderer) { SDL_DestroyRenderer(renderer); renderer = NULL; } - if (window) { SDL_DestroyWindow(window); window = NULL; } } void ShowSplashScreen(HINSTANCE hInstance) diff --git a/Sources/SeriousSam/StdH.h b/Sources/SeriousSam/StdH.h index c36b058f7..5f13c2b71 100644 --- a/Sources/SeriousSam/StdH.h +++ b/Sources/SeriousSam/StdH.h @@ -34,11 +34,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #define DECL_DLL #endif +#ifdef FIRST_ENCOUNTER +#include +#include +#include +#include +#include +#else #include #include #include #include #include +#endif #undef DECL_DLL #include "SeriousSam.h" diff --git a/Sources/build-linux32.sh b/Sources/build-linux32.sh index f7bf3fa64..b1690fb85 100755 --- a/Sources/build-linux32.sh +++ b/Sources/build-linux32.sh @@ -17,7 +17,7 @@ cd $_ #cmake -DCMAKE_BUILD_TYPE=Debug .. # Right now we force x86, though... -cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DUSE_I386_NASM_ASM=TRUE .. +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DUSE_I386_NASM_ASM=TRUE .. $1 make -j$NCPU diff --git a/Sources/build-linux64.sh b/Sources/build-linux64.sh index 44fe793a2..ef88670a9 100755 --- a/Sources/build-linux64.sh +++ b/Sources/build-linux64.sh @@ -14,10 +14,12 @@ cd $_ #ninja # This is the eventual path for amd64. -cmake -DCMAKE_BUILD_TYPE=Debug .. +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. $1 # Right now we force x86, though... #cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 .. - +echo "ECC first" +make ecc +echo "Then the rest..." make -j$NCPU diff --git a/Sources/build-mac.sh b/Sources/build-mac.sh index 1f0125554..cba53b8ce 100755 --- a/Sources/build-mac.sh +++ b/Sources/build-mac.sh @@ -9,6 +9,6 @@ set -x rm -rf cmake-build mkdir $_ cd $_ -cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_ARCHITECTURES=i386 -DUSE_I386_NASM_ASM=TRUE -DUSE_SYSTEM_SDL2=FALSE .. +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_ARCHITECTURES=i386 -DUSE_I386_NASM_ASM=TRUE -DUSE_SYSTEM_SDL2=FALSE .. $1 make -j$NCPU diff --git a/Sources/build-mac64.sh b/Sources/build-mac64.sh index 5265cdc5c..9838430d0 100755 --- a/Sources/build-mac64.sh +++ b/Sources/build-mac64.sh @@ -9,6 +9,6 @@ set -x rm -rf cmake-build mkdir $_ cd $_ -cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_ARCHITECTURES=x86_64 .. +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_ARCHITECTURES=x86_64 .. $1 make -j$NCPU diff --git a/Sources/build-macarm.sh b/Sources/build-macarm.sh new file mode 100755 index 000000000..f15b07210 --- /dev/null +++ b/Sources/build-macarm.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +NCPU=`sysctl -n hw.ncpu` +echo "Will build with 'make -j$NCPU' ... please edit this script if incorrect." + +set -e +set -x + +rm -rf cmake-build +mkdir $_ +cd $_ +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_ARCHITECTURES=arm64 .. $1 +make -j$NCPU + diff --git a/Sources/cmake/FindSDL2.cmake b/Sources/cmake/FindSDL2.cmake index 236d6b4b9..118174e33 100644 --- a/Sources/cmake/FindSDL2.cmake +++ b/Sources/cmake/FindSDL2.cmake @@ -68,6 +68,7 @@ SET(SDL2_SEARCH_PATHS ~/Library/Frameworks /Library/Frameworks + /usr/include/x86_64-linux-gnu/SDL2 /usr/local /usr /sw # Fink diff --git a/Sources/cmake/ParserAndScanner.cmake b/Sources/cmake/ParserAndScanner.cmake new file mode 100644 index 000000000..a2051ed53 --- /dev/null +++ b/Sources/cmake/ParserAndScanner.cmake @@ -0,0 +1,25 @@ +macro(add_parser_and_scanner _PARSER _SCANNER) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_SCANNER}.cpp" + MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_SCANNER}.l" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND flex + ARGS -o${_SCANNER}.cpp ${_SCANNER}.l + ) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.hpp" + MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.y" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND bison + ARGS -o${_PARSER}.cpp ${_PARSER}.y -d + ) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.h" + MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${_PARSER}.hpp" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND ${CMAKE_COMMAND} + ARGS -E copy ${_PARSER}.hpp ${_PARSER}.h + ) +endmacro()