diff --git a/CMakeLists.txt b/CMakeLists.txt index b8abe511d42f3bbbf01fd80f525f0978cbb573ca..0fb5cb28fbd6eacb2459c848e91b2ba7ae86943b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,10 @@ project(SRB2 VERSION 2.1.14 LANGUAGES C) +if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) + message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.") +endif() + # Set up CMAKE path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") @@ -44,7 +48,7 @@ macro(copy_files_to_build_dir target dlllist_var) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dlllist_item} - ${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/${dllname} + $<TARGET_FILE_DIR:${target}>/${dllname} ) endforeach() endif() @@ -58,10 +62,6 @@ else() set(SRB2_SYSTEM_BITS 32) endif() -if(MSVC) - message(WARNING "!! MSVC BUILDS OF SRB2 CANNOT PLAY MULTIPLAYER !! You're more than welcome to try and fix this!") -endif() - # OS macros if (UNIX) add_definitions(-DUNIXCOMMON) @@ -85,6 +85,9 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin") endif() endif() +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + # Set EXE names so the assets CMakeLists can refer to its target set(SRB2_SDL2_EXE_NAME srb2) set(SRB2_WIN_EXE_NAME srb2dd) @@ -98,7 +101,9 @@ add_subdirectory(assets) ## config.h generation set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary") include(GitUtilities) -git_describe(SRB2_COMP_REVISION "${CMAKE_CURRENT_SOURCE_DIR}") +git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}") +git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}") +set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}-<${SRB2_GIT_BRANCH}>") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) ##### PACKAGE CONFIGURATION ##### diff --git a/SRB2.cbp b/SRB2.cbp index 4834563ec842f1d4386a0a0f745f080bef189381..5a03955b8dc036d688497e7fa0018796423b00e4 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -154,8 +154,8 @@ HW3SOUND for 3D hardware sound support <Add directory="libs/gme/include" /> </Compiler> <Linker> - <Add library="SDL" /> - <Add library="SDL_mixer" /> + <Add library="SDL2" /> + <Add library="SDL2_mixer" /> <Add library="advapi32" /> <Add library="kernel32" /> <Add library="msvcrt" /> @@ -200,8 +200,8 @@ HW3SOUND for 3D hardware sound support <Add directory="libs/gme/include" /> </Compiler> <Linker> - <Add library="SDL" /> - <Add library="SDL_mixer" /> + <Add library="SDL2" /> + <Add library="SDL2_mixer" /> <Add library="advapi32" /> <Add library="kernel32" /> <Add library="msvcrt" /> @@ -4141,283 +4141,170 @@ HW3SOUND for 3D hardware sound support <Option target="Debug Mingw64/DirectX" /> <Option target="Release Mingw64/DirectX" /> </Unit> - <Unit filename="src/sdl/IMG_xpm.c"> + <Unit filename="src/sdl2/IMG_xpm.c"> <Option compilerVar="CC" /> - <Option compile="0" /> - <Option link="0" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/dosstr.c"> - <Option compilerVar="CC" /> + <Unit filename="src/sdl2/SDL_icon.xpm"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/endtxt.c"> + <Unit filename="src/sdl2/dosstr.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> - </Unit> - <Unit filename="src/sdl/endtxt.h"> - <Option target="Debug Native/SDL" /> - <Option target="Release Native/SDL" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> </Unit> - <Unit filename="src/sdl/filter/filters.c"> + <Unit filename="src/sdl2/endtxt.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/filter/filters.h"> + <Unit filename="src/sdl2/endtxt.h"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/filter/hq2x.c"> + <Unit filename="src/sdl2/hwsym_sdl.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> - </Unit> - <Unit filename="src/sdl/filter/hq2x.h"> - <Option target="Debug Native/SDL" /> - <Option target="Release Native/SDL" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> </Unit> - <Unit filename="src/sdl/filter/interp.h"> + <Unit filename="src/sdl2/hwsym_sdl.h"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/filter/lq2x.c"> + <Unit filename="src/sdl2/i_cdmus.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> - </Unit> - <Unit filename="src/sdl/filter/lq2x.h"> - <Option target="Debug Native/SDL" /> - <Option target="Release Native/SDL" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> </Unit> - <Unit filename="src/sdl/filter/main.c"> + <Unit filename="src/sdl2/i_main.c"> <Option compilerVar="CC" /> - <Option compile="0" /> - <Option link="0" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/hwsym_sdl.c"> + <Unit filename="src/sdl2/i_net.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> - </Unit> - <Unit filename="src/sdl/hwsym_sdl.h"> - <Option target="Debug Native/SDL" /> - <Option target="Release Native/SDL" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> </Unit> - <Unit filename="src/sdl/i_cdmus.c"> + <Unit filename="src/sdl2/i_system.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/i_main.c"> + <Unit filename="src/sdl2/i_ttf.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/i_net.c"> - <Option compilerVar="CC" /> + <Unit filename="src/sdl2/i_ttf.h"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/i_system.c"> + <Unit filename="src/sdl2/i_video.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/i_video.c"> + <Unit filename="src/sdl2/mixer_sound.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> - </Unit> - <Unit filename="src/sdl/mixer_sound.c"> - <Option compilerVar="CC" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> </Unit> - <Unit filename="src/sdl/ogl_sdl.c"> + <Unit filename="src/sdl2/ogl_sdl.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/ogl_sdl.h"> + <Unit filename="src/sdl2/ogl_sdl.h"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/sdl_sound.c"> + <Unit filename="src/sdl2/sdl_sound.c"> <Option compilerVar="CC" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> <Option target="Debug Mingw/SDL" /> <Option target="Release Mingw/SDL" /> </Unit> - <Unit filename="src/sdl/sdlmain.h"> + <Unit filename="src/sdl2/sdlmain.h"> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Any/Dummy" /> - <Option target="Release Any/Dummy" /> <Option target="Debug Linux/SDL" /> <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw64/SDL" /> - <Option target="Release Mingw64/SDL" /> + <Option target="Debug Mingw/SDL" /> + <Option target="Release Mingw/SDL" /> </Unit> <Unit filename="src/sounds.c"> <Option compilerVar="CC" /> @@ -4590,13 +4477,13 @@ HW3SOUND for 3D hardware sound support </Unit> <Unit filename="src/vid_copy.s"> <Option compilerVar="CC" /> - <Option compiler="avrgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> + <Option compiler="gcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> + <Option compiler="ppcgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> <Option compiler="gnu_gcc_compiler_for_mingw32" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="gnu_gcc_compiler_for_mingw64" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> <Option compiler="armelfgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> <Option compiler="tricoregcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="ppcgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="gcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> + <Option compiler="avrgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> + <Option compiler="gnu_gcc_compiler_for_mingw64" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> <Option target="Debug Native/SDL" /> <Option target="Release Native/SDL" /> <Option target="Debug Linux/SDL" /> diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 3ce133c6a67fde3d3ea55170bc7b8b24938fa8a6..292e184c72d20a3d2e2b5295de8dc818d6826a58 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -26,7 +26,7 @@ endforeach() # Installation if(CLANG) - get_target_property(outname ${SRB2_SDL2_EXE_NAME} OUTPUT_NAME) + get_target_property(outname SRB2SDL2 OUTPUT_NAME) install(FILES ${SRB2_ASSET_ALL} DESTINATION "${outname}.app/Contents/Resources" ) diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake index faa556a883aae61ac482c304f32200a996b982de..9e789e19cc85e547bca49e7d23810421ba48dc1f 100644 --- a/cmake/Modules/FindSDL2.cmake +++ b/cmake/Modules/FindSDL2.cmake @@ -27,7 +27,6 @@ find_library(SDL2_LIBRARY "/usr/local/lib" ) - # set include dir variables set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR) set(SDL2_PROCESS_LIBS SDL2_LIBRARY) diff --git a/cmake/Modules/GitUtilities.cmake b/cmake/Modules/GitUtilities.cmake index de4015b0d1e45be3afd1c858c373db4b3d36277c..683cf9b6b505e788bd3139bf0513b433a3190a2e 100644 --- a/cmake/Modules/GitUtilities.cmake +++ b/cmake/Modules/GitUtilities.cmake @@ -14,9 +14,18 @@ function(git_describe variable path) ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) - #if(NOT result EQUAL 0) - # set(${variable} "GITERROR-${result}-NOTFOUND" CACHE STRING "revision" FORCE) - #endif() set(${variable} "${output}" PARENT_SCOPE) endfunction() + +function(git_current_branch variable path) + execute_process(COMMAND ${GIT_EXECUTABLE} "symbolic-ref" "--short" "HEAD" + WORKING_DIRECTORY "${path}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + set(${variable} "${output}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 74f97048b3f5332070a14b05cf6f167f79267797..bb4f9a4a6f514ed1a098c2e5f38b4f8c08fd6917 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,32 +34,6 @@ set(SRB2_CORE_SOURCES m_random.c md5.c mserv.c - p_ceilng.c - p_enemy.c - p_fab.c - p_floor.c - p_inter.c - p_lights.c - p_map.c - p_maputl.c - p_mobj.c - p_polyobj.c - p_saveg.c - p_setup.c - p_sight.c - p_spec.c - p_telept.c - p_tick.c - p_user.c - r_bsp.c - r_data.c - r_draw.c - r_main.c - r_plane.c - r_segs.c - r_sky.c - r_splats.c - r_things.c s_sound.c screen.c sounds.c @@ -124,15 +98,30 @@ set(SRB2_CORE_HEADERS md5.h mserv.h p5prof.h - p_local.h - p_maputl.h - p_mobj.h - p_polyobj.h - p_pspr.h - p_saveg.h - p_setup.h - p_spec.h - p_tick.h + s_sound.h + screen.h + sounds.h + st_stuff.h + tables.h + v_video.h + w_wad.h + y_inter.h + z_zone.h + + config.h.in +) + +set(SRB2_CORE_RENDER_SOURCES + r_bsp.c + r_data.c + r_draw.c + r_main.c + r_plane.c + r_segs.c + r_sky.c + r_splats.c + r_things.c + r_bsp.h r_data.h r_defs.h @@ -145,82 +134,78 @@ set(SRB2_CORE_HEADERS r_splats.h r_state.h r_things.h - s_sound.h - screen.h - sounds.h - st_stuff.h - tables.h - v_video.h - w_wad.h - y_inter.h - z_zone.h ) -prepend_sources(SRB2_CORE_SOURCES) -prepend_sources(SRB2_CORE_HEADERS) - -set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -set(SRB2_HWRENDER_SOURCES - hardware/hw_bsp.c - hardware/hw_cache.c - hardware/hw_draw.c - hardware/hw_light.c - hardware/hw_main.c - hardware/hw_md2.c - hardware/hw_trick.c -) +set(SRB2_CORE_GAME_SOURCES + p_ceilng.c + p_enemy.c + p_fab.c + p_floor.c + p_inter.c + p_lights.c + p_map.c + p_maputl.c + p_mobj.c + p_polyobj.c + p_saveg.c + p_setup.c + p_sight.c + p_slopes.c + p_spec.c + p_telept.c + p_tick.c + p_user.c -set (SRB2_HWRENDER_HEADERS - hardware/hw_data.h - hardware/hw_defs.h - hardware/hw_dll.h - hardware/hw_drv.h - hardware/hw_glide.h - hardware/hw_glob.h - hardware/hw_light.h - hardware/hw_main.h - hardware/hw_md2.h + p_local.h + p_maputl.h + p_mobj.h + p_polyobj.h + p_pspr.h + p_saveg.h + p_setup.h + p_slopes.h + p_spec.h + p_tick.h ) -prepend_sources(SRB2_HWRENDER_SOURCES) -prepend_sources(SRB2_HWRENDER_HEADERS) +if(NOT CLANG) + set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) +endif() -set(SRB2_R_OPENGL_SOURCES - hardware/r_opengl/r_opengl.c -) +prepend_sources(SRB2_CORE_SOURCES) +prepend_sources(SRB2_CORE_HEADERS) +prepend_sources(SRB2_CORE_RENDER_SOURCES) +prepend_sources(SRB2_CORE_GAME_SOURCES) -set(SRB2_R_OPENGL_HEADERS - hardware/r_opengl/r_opengl.h -) +set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h) +source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) +source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) +source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) -prepend_sources(SRB2_R_OPENGL_SOURCES) -prepend_sources(SRB2_R_OPENGL_HEADERS) set(SRB2_ASM_SOURCES - vid_copy.s + ${CMAKE_CURRENT_SOURCE_DIR}/vid_copy.s ) set(SRB2_NASM_SOURCES - tmap_mmx.nas - tmap.nas + ${CMAKE_CURRENT_SOURCE_DIR}/tmap_mmx.nas + ${CMAKE_CURRENT_SOURCE_DIR}/tmap.nas ) if(MSVC) - list(APPEND SRB2_NASM_SOURCES tmap_vc.nas) + list(APPEND SRB2_NASM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tmap_vc.nas) endif() set(SRB2_NASM_OBJECTS - tmap_mmx.obj - tmap.obj + ${CMAKE_CURRENT_BINARY_DIR}/tmap_mmx.obj + ${CMAKE_CURRENT_BINARY_DIR}/tmap.obj ) if(MSVC) - list(APPEND SRB2_NASM_OBJECTS tmap_vc.obj) + list(APPEND SRB2_NASM_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/tmap_vc.obj) endif() -prepend_sources(SRB2_ASM_SOURCES) -prepend_sources(SRB2_NASM_SOURCES) +source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) ### Configuration @@ -229,11 +214,11 @@ set(SRB2_CONFIG_HAVE_BLUA ON CACHE BOOL set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL "Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.") set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL - "Enable zlib support") + "Enable zlib support.") set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL - "Enable GME support") + "Enable GME support.") set(SRB2_CONFIG_HWRENDER ON CACHE BOOL - "Enable hardware rendering through OpenGL") + "Enable hardware rendering through OpenGL.") set(SRB2_CONFIG_USEASM OFF CACHE BOOL "Enable NASM tmap implementation for software mode speedup.") set(SRB2_CONFIG_YASM OFF CACHE BOOL @@ -267,6 +252,8 @@ if(${SRB2_CONFIG_HAVE_BLUA}) prepend_sources(SRB2_LUA_SOURCES) prepend_sources(SRB2_LUA_HEADERS) + source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) + set(SRB2_BLUA_SOURCES blua/lapi.c blua/lauxlib.c @@ -318,8 +305,11 @@ if(${SRB2_CONFIG_HAVE_BLUA}) blua/lvm.h blua/lzio.h ) + prepend_sources(SRB2_BLUA_SOURCES) prepend_sources(SRB2_BLUA_HEADERS) + + source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) endif() if(${SRB2_CONFIG_HAVE_GME}) @@ -355,6 +345,36 @@ endif() if(${SRB2_CONFIG_HWRENDER}) add_definitions(-DHWRENDER) + set(SRB2_HWRENDER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c + ) + + set (SRB2_HWRENDER_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glide.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h + ) + + set(SRB2_R_OPENGL_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.c + ) + + set(SRB2_R_OPENGL_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.h + ) + endif() if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL}) @@ -384,10 +404,6 @@ endif() # Targets -if(${CMAKE_SYSTEM} MATCHES Windows) - add_subdirectory(win32) -endif() - # Compatibility flag with later versions of GCC # We should really fix our code to not need this if(NOT CLANG AND NOT MSVC) @@ -396,4 +412,23 @@ endif() add_definitions(-DCMAKECONFIG) +#add_library(SRB2Core STATIC +# ${SRB2_CORE_SOURCES} +# ${SRB2_CORE_HEADERS} +# ${SRB2_CORE_RENDER_SOURCES} +# ${SRB2_CORE_GAME_SOURCES} +# ${SRB2_LUA_SOURCES} +# ${SRB2_LUA_HEADERS} +# ${SRB2_BLUA_SOURCES} +# ${SRB2_BLUA_HEADERS} +#) + add_subdirectory(sdl) + +if(${CMAKE_SYSTEM} MATCHES Windows) + add_subdirectory(win32) +endif() + +if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE}) + message(FATAL_ERROR "There are no targets available to build an SRB2 executable. :(") +endif() \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index d4cc64a4b6ff79da6672ee10df9ef30f574aca40..bee60804720da1dcbee09065c29f616e145848f0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/p_telept.o \ $(OBJDIR)/p_tick.o \ $(OBJDIR)/p_user.o \ + $(OBJDIR)/p_slopes.o \ $(OBJDIR)/tables.o \ $(OBJDIR)/r_bsp.o \ $(OBJDIR)/r_data.o \ diff --git a/src/config.h.in b/src/config.h.in index 7c5b299cfe375b67453121b30f5063c4d70f1e88..2ed7aec3e88d914abcf87843b1d025d23a04b2ae 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -3,6 +3,12 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +/* DO NOT MODIFY config.h DIRECTLY! It will be overwritten by cmake. + * If you want to change a configuration option here, modify it in + * your CMakeCache.txt. config.h.in is used as a template for CMake + * variables, so you can insert them here too. + */ + #ifdef CMAKECONFIG #define ASSET_HASH_SRB2_SRB "${SRB2_ASSET_srb2.srb_HASH}" @@ -12,6 +18,8 @@ #define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}" #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" +#define SRB2_GIT_DESCRIBE "${SRB2_GIT_DESCRIBE}" +#define SRB2_GIT_BRANCH "${SRB2_GIT_BRANCH}" #define CMAKE_ASSETS_DIR "${CMAKE_SOURCE_DIR}/assets" diff --git a/src/d_main.c b/src/d_main.c index a959a86328e09d4a501c3c9b2eea52e197ed478d..61255e2722574bc6e28a6acd2fa461913c4fd67b 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -943,9 +943,9 @@ void D_SRB2Main(void) #endif #if defined (_WIN32_WCE) //|| defined (_DEBUG) || defined (GP2X) - devparm = !M_CheckParm("-nodebug"); + devparm = M_CheckParm("-nodebug") == 0; #else - devparm = M_CheckParm("-debug"); + devparm = M_CheckParm("-debug") != 0; #endif // for dedicated server @@ -1118,7 +1118,7 @@ void D_SRB2Main(void) #endif D_CleanFile(); -#if 1 // md5s last updated 12/14/14 +#ifndef DEVELOP // md5s last updated 12/14/14 // Check MD5s of autoloaded files W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e410713e0848f8589d15b8943b1cc1e6aae42a34..772b98c82738c1c762e8734c6e9f0f88e89be34f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3193,7 +3193,27 @@ static void Command_ModDetails_f(void) // static void Command_ShowGametype_f(void) { - CONS_Printf(M_GetText("Current gametype is %d\n"), gametype); + INT32 j; + const char *gametypestr = NULL; + + if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op" + { + CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player")); + return; + } + // find name string for current gametype + for (j = 0; gametype_cons_t[j].strvalue; j++) + { + if (gametype_cons_t[j].value == gametype) + { + gametypestr = gametype_cons_t[j].strvalue; + break; + } + } + if (gametypestr) + CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr); + else // string for current gametype was not found above (should never happen) + CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); } /** Plays the intro. diff --git a/src/dehacked.c b/src/dehacked.c index fc01bafddc1d116237086a1d0ca0e6b4d4f9d483..dfa90cd547b49b517ec3e57b5c9d194d5f895985 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -473,6 +473,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; + PlayerMenu[num].status = IT_CALL; for (i = 0; i < MAXLINELEN-3; i++) { @@ -545,6 +546,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); + PlayerMenu[num].status = IT_CALL; strncpy(description[num].picname, word2, 8); } else if (fastcmp(word, "STATUS")) @@ -576,6 +578,8 @@ static void readPlayer(MYFILE *f, INT32 num) if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); + PlayerMenu[num].status = IT_CALL; + strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlwr(description[num].skinname); } @@ -3883,7 +3887,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Blue Crawla "S_POSS_STND", - "S_POSS_STND2", "S_POSS_RUN1", "S_POSS_RUN2", "S_POSS_RUN3", @@ -3893,7 +3896,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Red Crawla "S_SPOS_STND", - "S_SPOS_STND2", "S_SPOS_RUN1", "S_SPOS_RUN2", "S_SPOS_RUN3", @@ -7248,7 +7250,6 @@ static const char *const MOBJFLAG2_LIST[] = { "EXPLOSION", // Thrown ring has explosive properties "SCATTER", // Thrown ring has scatter properties "BEYONDTHEGRAVE",// Source of this missile has died and has since respawned. - "PUSHED", // Mobj was already pushed this tic "SLIDEPUSH", // MF_PUSHABLE that pushes continuously. "CLASSICPUSH", // Drops straight down when object has negative Z. "STANDONME", // While not pushable, stand on me anyway. @@ -7277,6 +7278,8 @@ static const char *const MOBJEFLAG_LIST[] = { "JUSTSTEPPEDDOWN", // used for ramp sectors "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics "GOOWATER", // Goo water + "PUSHED", // Mobj was already pushed this tic + "SPRUNG", // Mobj was already sprung this tic NULL }; @@ -7379,6 +7382,7 @@ static const char *const ML_LIST[16] = { }; // This DOES differ from r_draw's Color_Names, unfortunately. +// Also includes Super colors static const char *COLOR_ENUMS[] = { "NONE", // SKINCOLOR_NONE "WHITE", // SKINCOLOR_WHITE @@ -7405,7 +7409,25 @@ static const char *COLOR_ENUMS[] = { "ZIM", // SKINCOLOR_ZIM "OLIVE", // SKINCOLOR_OLIVE "YELLOW", // SKINCOLOR_YELLOW - "GOLD" // SKINCOLOR_GOLD + "GOLD", // SKINCOLOR_GOLD + // Super special awesome Super flashing colors! + "SUPER1", // SKINCOLOR_SUPER1 + "SUPER2", // SKINCOLOR_SUPER2, + "SUPER3", // SKINCOLOR_SUPER3, + "SUPER4", // SKINCOLOR_SUPER4, + "SUPER5", // SKINCOLOR_SUPER5, + // Super Tails + "TSUPER1", // SKINCOLOR_TSUPER1, + "TSUPER2", // SKINCOLOR_TSUPER2, + "TSUPER3", // SKINCOLOR_TSUPER3, + "TSUPER4", // SKINCOLOR_TSUPER4, + "TSUPER5", // SKINCOLOR_TSUPER5, + // Super Knuckles + "KSUPER1", // SKINCOLOR_KSUPER1, + "KSUPER2", // SKINCOLOR_KSUPER2, + "KSUPER3", // SKINCOLOR_KSUPER3, + "KSUPER4", // SKINCOLOR_KSUPER4, + "KSUPER5" // SKINCOLOR_KSUPER5, }; static const char *const POWERS_LIST[] = { @@ -7612,8 +7634,9 @@ struct { {"EMERALD6",EMERALD6}, {"EMERALD7",EMERALD7}, - // SKINCOLOR_ doesn't include this..! + // SKINCOLOR_ doesn't include these..! {"MAXSKINCOLORS",MAXSKINCOLORS}, + {"MAXTRANSLATIONS",MAXTRANSLATIONS}, // Precipitation {"PRECIP_NONE",PRECIP_NONE}, @@ -8236,7 +8259,7 @@ static fixed_t find_const(const char **rword) } else if (fastncmp("SKINCOLOR_",word,10)) { char *p = word+10; - for (i = 0; i < MAXSKINCOLORS; i++) + for (i = 0; i < MAXTRANSLATIONS; i++) if (fastcmp(p, COLOR_ENUMS[i])) { free(word); return i; @@ -8295,8 +8318,8 @@ void DEH_Check(void) if (dehpowers != NUMPOWERS) I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); - if (dehcolors != MAXSKINCOLORS) - I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXSKINCOLORS, sizeu1(dehcolors)); + if (dehcolors != MAXTRANSLATIONS) + I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors)); #endif } @@ -8661,7 +8684,7 @@ static inline int lib_getenum(lua_State *L) } else if (fastncmp("SKINCOLOR_",word,10)) { p = word+10; - for (i = 0; i < MAXSKINCOLORS; i++) + for (i = 0; i < MAXTRANSLATIONS; i++) if (fastcmp(p, COLOR_ENUMS[i])) { lua_pushinteger(L, i); return 1; @@ -8786,7 +8809,7 @@ static inline int lib_getenum(lua_State *L) lua_pushinteger(L, mapmusic); return 1; } else if (fastcmp(word,"server")) { - if (!playeringame[serverplayer]) + if ((!multiplayer || !netgame) && !playeringame[serverplayer]) return 0; LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); return 1; diff --git a/src/doomdef.h b/src/doomdef.h index 4a6d6e5764bc48198d034f2e2e98ce8c5ac9ab26..bfa5ee0ceed8bad5a8eba5a18128a0cc16f024dc 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -138,10 +138,12 @@ extern FILE *logstream; #endif -#if 0 +//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 +#ifdef DEVELOP #define VERSION 0 // Game version #define SUBVERSION 0 // more precise version number #define VERSIONSTRING "Trunk" +#define VERSIONSTRINGW L"Trunk" #else #define VERSION 201 // Game version #define SUBVERSION 14 // more precise version number @@ -437,6 +439,13 @@ extern const char *compdate, *comptime, *comprevision; /// Fun experimental slope stuff! //#define SLOPENESS +/// Kalaron/Eternity Engine slope code (SRB2CB ported) +/// Depends on NEED_FIXED_VECTORS? for a few functions. +#define ESLOPE + +/// Fixed and float point types +//#define NEED_FIXED_VECTOR + /// Delete file while the game is running. /// \note EXTREMELY buggy, tends to crash game. //#define DELFILE diff --git a/src/g_game.c b/src/g_game.c index c59f23c0787f23de3a7cfe58c1393a638d4b9e4d..917a86165684250ac5dd11693da0e2b3b52a3773 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2180,8 +2180,7 @@ void G_PlayerReborn(INT32 player) p->health = 1; // 0 rings p->panim = PA_IDLE; // standing animation - if ((netgame || multiplayer) && !p->spectator - && gametype != GT_RACE) + if ((netgame || multiplayer) && !p->spectator) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent if (p-players == consoleplayer) @@ -4330,20 +4329,10 @@ void G_GhostTicker(void) switch(g->color) { case GHC_SUPER: // Super Sonic (P_DoSuperStuff) - // Yousa yellow now! - g->mo->color = SKINCOLOR_SUPER1 + (leveltime/2) % 5; - if (g->mo->skin) - switch (((skin_t*)g->mo->skin)-skins) - { - case 1: // Golden orange supertails. - g->mo->color = SKINCOLOR_TSUPER1 + (leveltime/2) % 5; - break; - case 2: // Pink superknux. - g->mo->color = SKINCOLOR_KSUPER1 + (leveltime/2) % 5; - break; - default: - break; - } + if (leveltime % 9 < 5) + g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; + else + g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9; break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e898d274d56a73c066f3d518f785632c957d2d0a..e54d303958d48c8741e81a5b33cf16c3b9126f66 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3527,6 +3527,184 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; } +static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale) +{ + UINT8 i; + float tr_x, tr_y; + FOutVector *wv; + FOutVector swallVerts[4]; + FSurfaceInfo sSurf; + fixed_t floorheight, mobjfloor; + + mobjfloor = HWR_OpaqueFloorAtPos( + spr->mobj->x, spr->mobj->y, + spr->mobj->z, spr->mobj->height); + if (cv_shadowoffs.value) + { + angle_t shadowdir; + + // Set direction + if (splitscreen && stplyr != &players[displayplayer]) + shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); + else + shadowdir = localangle + FixedAngle(cv_cam_rotate.value); + + // Find floorheight + floorheight = HWR_OpaqueFloorAtPos( + spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), + spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), + spr->mobj->z, spr->mobj->height); + + // The shadow is falling ABOVE it's mobj? + // Don't draw it, then! + if (spr->mobj->z < floorheight) + return; + else + { + fixed_t floorz; + floorz = HWR_OpaqueFloorAtPos( + spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight), + spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight), + spr->mobj->z, spr->mobj->height); + // The shadow would be falling on a wall? Don't draw it, then. + // Would draw midair otherwise. + if (floorz < floorheight) + return; + } + + floorheight = FixedInt(spr->mobj->z - floorheight); + } + else + floorheight = FixedInt(spr->mobj->z - mobjfloor); + + // create the sprite billboard + // + // 3--2 + // | /| + // |/ | + // 0--1 + + // x1/x2 were already scaled in HWR_ProjectSprite + swallVerts[0].x = swallVerts[3].x = spr->x1; + swallVerts[2].x = swallVerts[1].x = spr->x2; + + if (spr->mobj && this_scale != 1.0f) + { + // Always a pixel above the floor, perfectly flat. + swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); + + swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale; + swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale; + } + else + { + // Always a pixel above the floor, perfectly flat. + swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); + + // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.) + swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset); + swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset; + } + + // transform + wv = swallVerts; + + for (i = 0; i < 4; i++,wv++) + { + // Offset away from the camera based on height from floor. + if (cv_shadowoffs.value) + wv->z += floorheight; + wv->z += 3; + + //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + tr_x = wv->z; + tr_y = wv->y; + wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); + wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); + // ---------------------- mega lame test ---------------------------------- + + //scale y before frustum so that frustum can be scaled to screen height + wv->y *= ORIGINAL_ASPECT * gr_fovlud; + wv->x *= gr_fovlud; + } + + if (spr->flip) + { + swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; + swallVerts[2].sow = swallVerts[1].sow = 0; + } + else + { + swallVerts[0].sow = swallVerts[3].sow = 0; + swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; + } + + // flip the texture coords (look familiar?) + if (spr->vflip) + { + swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; + swallVerts[0].tow = swallVerts[1].tow = 0; + } + else + { + swallVerts[3].tow = swallVerts[2].tow = 0; + swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; + } + + sSurf.FlatColor.s.red = 0x00; + sSurf.FlatColor.s.blue = 0x00; + sSurf.FlatColor.s.green = 0x00; + + /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) + { + sector_t *sector = spr->mobj->subsector->sector; + UINT8 lightlevel = 255; + extracolormap_t *colormap = sector->extra_colormap; + + if (sector->numlights) + { + INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false); + + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *sector->lightlist[light].lightlevel; + + if (sector->lightlist[light].extra_colormap) + colormap = sector->lightlist[light].extra_colormap; + } + else + { + lightlevel = sector->lightlevel; + + if (sector->extra_colormap) + colormap = sector->extra_colormap; + } + + if (colormap) + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); + else + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); + }*/ + + // shadow is always half as translucent as the sprite itself + if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency) + sSurf.FlatColor.s.alpha = 0x80; // default + else if (spr->mobj->flags2 & MF2_SHADOW) + sSurf.FlatColor.s.alpha = 0x20; + else if (spr->mobj->frame & FF_TRANSMASK) + { + HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); + sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! + } + else + sSurf.FlatColor.s.alpha = 0x80; // default + + if (sSurf.FlatColor.s.alpha > floorheight/4) + { + sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); + HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + } +} + // -----------------+ // HWR_DrawSprite : Draw flat sprites // : (monsters, bonuses, weapons, lights, ...) @@ -3629,7 +3807,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // Draw shadow BEFORE sprite if (cv_shadow.value // Shadows enabled - && !(spr->mobj->flags & MF_SCENERY && spr->mobj->flags & MF_SPAWNCEILING && spr->mobj->flags & MF_NOGRAVITY) // Ceiling scenery have no shadow. + && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. #ifdef ALAM_LIGHTING && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. @@ -3640,187 +3818,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) //////////////////// // SHADOW SPRITE! // //////////////////// - FOutVector swallVerts[4]; - FSurfaceInfo sSurf; - fixed_t floorheight, mobjfloor; - - mobjfloor = HWR_OpaqueFloorAtPos( - spr->mobj->x, spr->mobj->y, - spr->mobj->z, spr->mobj->height); - if (cv_shadowoffs.value) - { - angle_t shadowdir; - - // Set direction - if (splitscreen && stplyr != &players[displayplayer]) - shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); - else - shadowdir = localangle + FixedAngle(cv_cam_rotate.value); - - // Find floorheight - floorheight = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->z, spr->mobj->height); - - // The shadow is falling ABOVE it's mobj? - // Don't draw it, then! - if (spr->mobj->z < floorheight) - goto noshadow; - else - { - fixed_t floorz; - floorz = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->z, spr->mobj->height); - // The shadow would be falling on a wall? Don't draw it, then. - // Would draw midair otherwise. - if (floorz < floorheight) - goto noshadow; - } - - floorheight = FixedInt(spr->mobj->z - floorheight); - } - else - floorheight = FixedInt(spr->mobj->z - mobjfloor); - - // create the sprite billboard - // - // 3--2 - // | /| - // |/ | - // 0--1 - - // x1/x2 were already scaled in HWR_ProjectSprite - swallVerts[0].x = swallVerts[3].x = spr->x1; - swallVerts[2].x = swallVerts[1].x = spr->x2; - - if (spr->mobj && this_scale != 1.0f) - { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); - - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale; - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale; - } - else - { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); - - // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.) - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset); - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset; - } - - // transform - wv = swallVerts; - - for (i = 0; i < 4; i++,wv++) - { - // Offset away from the camera based on height from floor. - if (cv_shadowoffs.value) - wv->z += floorheight; - wv->z += 3; - - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; - } - - if (spr->flip) - { - swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; - swallVerts[2].sow = swallVerts[1].sow = 0; - } - else - { - swallVerts[0].sow = swallVerts[3].sow = 0; - swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; - } - - // flip the texture coords (look familiar?) - if (spr->vflip) - { - swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; - swallVerts[0].tow = swallVerts[1].tow = 0; - } - else - { - swallVerts[3].tow = swallVerts[2].tow = 0; - swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; - } - - sSurf.FlatColor.s.red = 0x00; - sSurf.FlatColor.s.blue = 0x00; - sSurf.FlatColor.s.green = 0x00; - - /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) - { - sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = sector->lightlevel; - extracolormap_t *colormap = sector->extra_colormap; - - if (sector->numlights) - { - INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false); - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; - else - lightlevel = 255; - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else - { - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } - - if (colormap) - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); - else - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); - }*/ - - // shadow is always half as translucent as the sprite itself - if (!cv_translucency.value) - ; // translucency disabled - else if (spr->mobj->flags2 & MF2_SHADOW) - sSurf.FlatColor.s.alpha = 0x20; - else if (spr->mobj->frame & FF_TRANSMASK) - { - HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); - sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! - } - else - sSurf.FlatColor.s.alpha = 0x80; // default - - /// \todo do the test earlier - if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f) || (md2_models[spr->mobj->sprite].notfound = true) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound = true)) - { - if (sSurf.FlatColor.s.alpha > floorheight/4) - { - sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); - } - } + HWR_DrawSpriteShadow(spr, gpatch, this_scale); } -noshadow: - // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components /// \todo coloured @@ -3828,7 +3828,7 @@ noshadow: // colormap test { sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = sector->lightlevel; + UINT8 lightlevel = 255; extracolormap_t *colormap = sector->extra_colormap; if (sector->numlights) @@ -3839,8 +3839,6 @@ noshadow: if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *sector->lightlist[light].lightlevel; - else - lightlevel = 255; if (sector->lightlist[light].extra_colormap) colormap = sector->lightlist[light].extra_colormap; @@ -3849,27 +3847,25 @@ noshadow: { if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = sector->lightlevel; - else - lightlevel = 255; if (sector->extra_colormap) colormap = sector->extra_colormap; } - if (spr->mobj->frame & FF_FULLBRIGHT) - lightlevel = 255; - if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); else Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); } - /// \todo do the test earlier - if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f)) { FBITFIELD blend = 0; - if (spr->mobj->flags2 & MF2_SHADOW) + if (!cv_translucency.value) // translucency disabled + { + Surf.FlatColor.s.alpha = 0xFF; + blend = PF_Translucent|PF_Occlude; + } + else if (spr->mobj->flags2 & MF2_SHADOW) { Surf.FlatColor.s.alpha = 0x40; blend = PF_Translucent; @@ -4391,10 +4387,10 @@ static void HWR_DrawSprites(void) #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { - if (!cv_grmd2.value || (cv_grmd2.value && md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == true)) + if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) HWR_DrawSprite(spr); } - else if (!cv_grmd2.value || (cv_grmd2.value && md2_models[spr->mobj->sprite].notfound == true)) + else if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); } } @@ -4420,7 +4416,7 @@ static void HWR_DrawMD2S(void) #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { - if ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false) && (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f)) + if (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false && md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f) HWR_DrawMD2(spr); } else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f) @@ -4462,23 +4458,12 @@ static void HWR_AddSprites(sector_t *sec) // If a limit exists, handle things a tiny bit different. if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS)) { - if (!players[displayplayer].mo) - return; // Draw nothing if no player. - // todo: is this really the best option for this situation? - for (thing = sec->thinglist; thing; thing = thing->snext) { if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) continue; - approx_dist = P_AproxDistance( - players[displayplayer].mo->x - thing->x, - players[displayplayer].mo->y - thing->y); - - if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo) - approx_dist = P_AproxDistance( - players[secondarydisplayplayer].mo->x - thing->x, - players[secondarydisplayplayer].mo->y - thing->y); + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (approx_dist <= limit_dist) HWR_ProjectSprite(thing); @@ -4496,23 +4481,12 @@ static void HWR_AddSprites(sector_t *sec) // Someone seriously wants infinite draw distance for precipitation? if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { - if (!players[displayplayer].mo) - return; // Draw nothing if no player. - // todo: is this really the best option for this situation? - for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (precipthing->invisible) + if (precipthing->precipflags & PCF_INVISIBLE) continue; - approx_dist = P_AproxDistance( - players[displayplayer].mo->x - precipthing->x, - players[displayplayer].mo->y - precipthing->y); - - if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo) - approx_dist = P_AproxDistance( - players[secondarydisplayplayer].mo->x - precipthing->x, - players[secondarydisplayplayer].mo->y - precipthing->y); + approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); if (approx_dist <= limit_dist) HWR_ProjectPrecipitationSprite(precipthing); @@ -4522,7 +4496,7 @@ static void HWR_AddSprites(sector_t *sec) { // Draw everything in sector, no checks for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) - if (!precipthing->invisible) + if (!(precipthing->precipflags & PCF_INVISIBLE)) HWR_ProjectPrecipitationSprite(precipthing); } #endif @@ -4583,10 +4557,11 @@ static void HWR_ProjectSprite(mobj_t *thing) if (rot >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid sprite frame %s/%s for %s\n"), + CONS_Alert(CONS_ERROR, M_GetText("HWR_ProjectSprite: invalid sprite frame %s/%s for %s\n"), sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; + sprdef = &sprites[thing->sprite]; rot = thing->frame&FF_FRAMEMASK; thing->state->sprite = thing->sprite; thing->state->frame = thing->frame; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 02f5053515af59e01cd77c3543ab93d21e19eebf..de648f1b90eb6fabb9c1a25ccc081a5b93ad41ff 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -921,24 +921,25 @@ void HWR_InitMD2(void) } while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) { + if (stricmp(name, "PLAY") == 0) + { + CONS_Printf("MD2 for sprite PLAY detected in md2.dat, use a player skin instead!\n"); + continue; + } + for (i = 0; i < NUMSPRITES; i++) { if (stricmp(name, sprnames[i]) == 0) { - if (stricmp(name, "PLAY") == 0) - continue; + //if (stricmp(name, "PLAY") == 0) + //continue; //CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset); md2_models[i].scale = scale; md2_models[i].offset = offset; md2_models[i].notfound = false; strcpy(md2_models[i].filename, filename); - break; - } - if (i == NUMSPRITES) - { - CONS_Printf("MD2 for sprite %s not found\n", name); - md2_models[i].notfound = true; + goto md2found; } } @@ -952,15 +953,14 @@ void HWR_InitMD2(void) md2_playermodels[s].offset = offset; md2_playermodels[s].notfound = false; strcpy(md2_playermodels[s].filename, filename); - break; - } - if (s == MAXSKINS-1) - { - CONS_Printf("MD2 for player skin %s not found\n", name); - md2_playermodels[s].notfound = true; + goto md2found; } } - + // no sprite/player skin name found?!? + CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); +md2found: + // move on to next line... + continue; } fclose(f); } @@ -996,17 +996,14 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup md2_playermodels[skin].offset = offset; md2_playermodels[skin].notfound = false; strcpy(md2_playermodels[skin].filename, filename); - break; - } - if (skin == MAXSKINS-1) - { - CONS_Printf("MD2 for player skin %s not found\n", name); - md2_playermodels[skin].notfound = true; + goto playermd2found; } } + //CONS_Printf("MD2 for player skin %s not found\n", skins[skin].name); + md2_playermodels[skin].notfound = true; +playermd2found: fclose(f); - } @@ -1021,6 +1018,9 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu if (nomd2s) return; + if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check + return; + // Read the md2.dat file f = fopen("md2.dat", "rt"); @@ -1034,27 +1034,19 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu // Check for any MD2s that match the names of player skins! while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) { + if (stricmp(name, sprnames[spritenum]) == 0) { - if (stricmp(name, sprnames[spritenum]) == 0) - { - if (stricmp(name, "PLAY") == 0) // Handled already NEWMD2: Per sprite, per-skin check - continue; - - md2_models[spritenum].scale = scale; - md2_models[spritenum].offset = offset; - md2_models[spritenum].notfound = false; - strcpy(md2_models[spritenum].filename, filename); - break; - } - - if (spritenum == NUMSPRITES-1) - { - CONS_Printf("MD2 for sprite %s not found\n", name); - md2_models[spritenum].notfound = true; - } + md2_models[spritenum].scale = scale; + md2_models[spritenum].offset = offset; + md2_models[spritenum].notfound = false; + strcpy(md2_models[spritenum].filename, filename); + goto spritemd2found; } } + //CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]); + md2_models[spritenum].notfound = true; +spritemd2found: fclose(f); } @@ -1090,11 +1082,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2_t *md2; UINT8 color[4]; + if (!cv_grmd2.value) + return; + + if (!spr->precip) + return; + // MD2 colormap fix // colormap test { sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = sector->lightlevel; + UINT8 lightlevel = 255; extracolormap_t *colormap = sector->extra_colormap; if (sector->numlights) @@ -1105,8 +1103,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *sector->lightlist[light].lightlevel; - else - lightlevel = 255; if (sector->lightlist[light].extra_colormap) colormap = sector->lightlist[light].extra_colormap; @@ -1115,24 +1111,18 @@ void HWR_DrawMD2(gr_vissprite_t *spr) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = sector->lightlevel; - else - lightlevel = 255; if (sector->extra_colormap) colormap = sector->extra_colormap; } - if (spr->mobj->frame & FF_FULLBRIGHT) - lightlevel = 255; - if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); else Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); } - // Look at HWR_ProjetctSprite for more - if (cv_grmd2.value && ((md2_models[spr->mobj->sprite].scale > 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f)) && !spr->precip) + // Look at HWR_ProjectSprite for more { GLPatch_t *gpatch; INT32 *buff; @@ -1149,15 +1139,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) //durs = tics; if (spr->mobj->flags2 & MF2_SHADOW) - { Surf.FlatColor.s.alpha = 0x40; - } else if (spr->mobj->frame & FF_TRANSMASK) HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else - { Surf.FlatColor.s.alpha = 0xFF; - } // dont forget to enabled the depth test because we can't do this like // before: polygons models are not sorted @@ -1263,8 +1249,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.flip = false; HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color); - - } } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fd4261bcefd1a973343130c65217081795f3737e..f84b0e235f7b74fc376d51c87c7f9d7421828e7d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1919,6 +1919,13 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d } + // Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?! + if (color[3] < 255) + { + pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency + pglDepthMask(GL_FALSE); + } + val = *gl_cmd_buffer++; while (val != 0) diff --git a/src/info.c b/src/info.c index fb30258c31b2ab85a813a3cc9d21d29df3bd58d3..9e04b4e342f4027b0a319f6bcfaaaf35a8ea035b 100644 --- a/src/info.c +++ b/src/info.c @@ -150,8 +150,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, 34, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN // Blue Crawla - {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND2}, // S_POSS_STND - {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND2 + {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND {SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1 {SPR_POSS, 1, 3, {A_Chase}, 0, 0, S_POSS_RUN3}, // S_POSS_RUN2 {SPR_POSS, 2, 3, {A_Chase}, 0, 0, S_POSS_RUN4}, // S_POSS_RUN3 @@ -160,8 +159,7 @@ state_t states[NUMSTATES] = {SPR_POSS, 5, 3, {A_Chase}, 0, 0, S_POSS_RUN1}, // S_POSS_RUN6 // Red Crawla - {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND2}, // S_SPOS_STND - {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND}, // S_SPOS_STND2 + {SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND}, // S_SPOS_STND {SPR_SPOS, 0, 1, {A_Chase}, 0, 0, S_SPOS_RUN2}, // S_SPOS_RUN1 {SPR_SPOS, 1, 1, {A_Chase}, 0, 0, S_SPOS_RUN3}, // S_SPOS_RUN2 {SPR_SPOS, 2, 1, {A_Chase}, 0, 0, S_SPOS_RUN4}, // S_SPOS_RUN3 diff --git a/src/info.h b/src/info.h index 0c73281df34d7061803ac16f0aa23cd0d0c70dab..03726260b0b3261f83219951f1ae620306553598 100644 --- a/src/info.h +++ b/src/info.h @@ -663,7 +663,6 @@ typedef enum state // Blue Crawla S_POSS_STND, - S_POSS_STND2, S_POSS_RUN1, S_POSS_RUN2, S_POSS_RUN3, @@ -673,7 +672,6 @@ typedef enum state // Red Crawla S_SPOS_STND, - S_SPOS_STND2, S_SPOS_RUN1, S_SPOS_RUN2, S_SPOS_RUN3, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 19390d50df00d5b811b330b349949726399ac884..86ff11337a6fcd02e763da75ee612eb5ee789d1d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -126,8 +126,6 @@ static const char *const widtht_opt[] = { enum cameraf { camera_chase = 0, camera_aiming, - camera_viewheight, - camera_startangle, camera_x, camera_y, camera_z, @@ -137,7 +135,6 @@ enum cameraf { camera_ceilingz, camera_radius, camera_height, - camera_relativex, camera_momx, camera_momy, camera_momz @@ -147,8 +144,6 @@ enum cameraf { static const char *const camera_opt[] = { "chase", "aiming", - "viewheight", - "startangle", "x", "y", "z", @@ -158,7 +153,6 @@ static const char *const camera_opt[] = { "ceilingz", "radius", "height", - "relativex", "momx", "momy", "momz", @@ -279,12 +273,6 @@ static int camera_get(lua_State *L) case camera_aiming: lua_pushinteger(L, cam->aiming); break; - case camera_viewheight: - lua_pushinteger(L, cam->viewheight); - break; - case camera_startangle: - lua_pushinteger(L, cam->startangle); - break; case camera_x: lua_pushinteger(L, cam->x); break; @@ -312,9 +300,6 @@ static int camera_get(lua_State *L) case camera_height: lua_pushinteger(L, cam->height); break; - case camera_relativex: - lua_pushinteger(L, cam->relativex); - break; case camera_momx: lua_pushinteger(L, cam->momx); break; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 80f66ed60543c3607e184594c25b705c82d5a30a..e5cc30c12571a3ce8f047f257add6fb0bf062841 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -60,7 +60,6 @@ enum subsector_e { subsector_sector, subsector_numlines, subsector_firstline, - subsector_validcount }; static const char *const subsector_opt[] = { @@ -68,7 +67,6 @@ static const char *const subsector_opt[] = { "sector", "numlines", "firstline", - "validcount", NULL}; enum line_e { @@ -86,7 +84,6 @@ enum line_e { line_slopetype, line_frontsector, line_backsector, - line_validcount, line_firsttag, line_nexttag, line_text, @@ -108,7 +105,6 @@ static const char *const line_opt[] = { "slopetype", "frontsector", "backsector", - "validcount", "firsttag", "nexttag", "text", @@ -476,9 +472,6 @@ static int subsector_get(lua_State *L) case subsector_firstline: lua_pushinteger(L, subsector->firstline); return 1; - case subsector_validcount: - lua_pushinteger(L, subsector->validcount); - return 1; } return 0; } @@ -564,9 +557,6 @@ static int line_get(lua_State *L) case line_backsector: LUA_PushUserdata(L, line->backsector, META_SECTOR); return 1; - case line_validcount: - lua_pushinteger(L, line->validcount); - return 1; case line_firsttag: lua_pushinteger(L, line->firsttag); return 1; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index f455edf1fe79ded82228a4b3b03e859b4986e3ce..cf4db8f398aee2e765f51560a47001eabcd31202 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -500,7 +500,7 @@ static int mobj_set(lua_State *L) return luaL_error(L, "mobj.skin '%s' not found!", skin); } case mobj_color: - mo->color = ((UINT8)luaL_checkinteger(L, 3)) % MAXSKINCOLORS; + mo->color = ((UINT8)luaL_checkinteger(L, 3)) % MAXTRANSLATIONS; break; case mobj_bnext: return NOSETPOS; diff --git a/src/m_cheat.c b/src/m_cheat.c index 8cea4c6ae1ea743e6d998792c550977d1252a70d..bc32e6cfab9b964e7c5cd974805de75d18fe7e61 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -91,6 +91,33 @@ static UINT8 cheatf_warp(void) return 1; } +#ifdef DEVELOP +static UINT8 cheatf_devmode(void) +{ + UINT8 i; + + if (modifiedgame) + return 0; + + if (menuactive && currentMenu != &MainDef) + return 0; // Only on the main menu! + + S_StartSound(0, sfx_itemup); + + // Just unlock all the things and turn on -debug and console devmode. + G_SetGameModified(false); + for (i = 0; i < MAXUNLOCKABLES; i++) + unlockables[i].unlocked = true; + devparm = TRUE; + cv_debug |= 0x8000; + + // Refresh secrets menu existing. + M_ClearMenus(true); + M_StartControlPanel(); + return 1; +} +#endif + static cheatseq_t cheat_ultimate = { 0, cheatf_ultimate, { SCRAMBLE('u'), SCRAMBLE('l'), SCRAMBLE('t'), SCRAMBLE('i'), SCRAMBLE('m'), SCRAMBLE('a'), SCRAMBLE('t'), SCRAMBLE('e'), 0xff } @@ -115,6 +142,14 @@ static cheatseq_t cheat_warp_joy = { SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_ENTER), 0xff } }; + +#ifdef DEVELOP +static cheatseq_t cheat_devmode = { + 0, cheatf_devmode, + { SCRAMBLE('d'), SCRAMBLE('e'), SCRAMBLE('v'), SCRAMBLE('m'), SCRAMBLE('o'), SCRAMBLE('d'), SCRAMBLE('e'), 0xff } +}; +#endif + // ========================================================================== // CHEAT SEQUENCE PACKAGE // ========================================================================== @@ -221,6 +256,9 @@ boolean cht_Responder(event_t *ev) ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch); ret += cht_CheckCheat(&cheat_warp, (char)ch); ret += cht_CheckCheat(&cheat_warp_joy, (char)ch); +#ifdef DEVELOP + ret += cht_CheckCheat(&cheat_devmode, (char)ch); +#endif return (ret != 0); } diff --git a/src/m_fixed.c b/src/m_fixed.c index 25a25a96695dd8c7d020d22f6af57bdd2452be7f..739265aa272c9aa9179fa58840111b6e03f249a9 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -119,7 +119,7 @@ fixed_t FixedHypot(fixed_t x, fixed_t y) return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) { diff --git a/src/m_fixed.h b/src/m_fixed.h index e68de03080fb4a3de8342ff6f0d8d1c4fab953c8..53962269be8d92f087ddc4ba9fe8a7015f3e111f 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -357,7 +357,8 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } -#ifdef NEED_FIXED_VECTOR + +#if 1//#ifdef NEED_FIXED_VECTOR typedef struct { diff --git a/src/p_enemy.c b/src/p_enemy.c index 18a4ec5ff415be7bee7f5b828fca47ece86ac247..369b6f0c8fcb88f55c7ae5a8b472a9f3ada18869 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -363,12 +363,12 @@ boolean P_CheckMissileRange(mobj_t *actor) if (!actor->target) return false; - if (!P_CheckSight(actor, actor->target)) - return false; - if (actor->reactiontime) return false; // do not attack yet + if (!P_CheckSight(actor, actor->target)) + return false; + // OPTIMIZE: get this from a global checksight dist = P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale); @@ -652,6 +652,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed player = &players[actor->lastlook]; + if ((netgame || multiplayer) && player->spectator) + continue; + if (player->health <= 0) continue; // dead @@ -661,12 +664,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if (!player->mo || P_MobjWasRemoved(player->mo)) continue; - if (!P_CheckSight(actor, player->mo)) - continue; // out of sight - - if ((netgame || multiplayer) && player->spectator) - continue; - if (dist > 0 && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away @@ -683,6 +680,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed } } + if (!P_CheckSight(actor, player->mo)) + continue; // out of sight + if (tracer) P_SetTarget(&actor->tracer, player->mo); else @@ -5024,7 +5024,7 @@ void A_MaceRotate(mobj_t *actor) actor->movecount += actor->target->lastlook; actor->movecount &= FINEMASK; - actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook); + actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS); v[0] = FRACUNIT; v[1] = 0; @@ -5032,7 +5032,7 @@ void A_MaceRotate(mobj_t *actor) v[3] = FRACUNIT; // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold << FRACBITS))); + res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold))); M_Memcpy(&v, res, sizeof(v)); res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); M_Memcpy(&v, res, sizeof(v)); @@ -5606,8 +5606,13 @@ void A_MixUp(mobj_t *actor) P_SetThingPosition(players[i].mo); +#ifdef ESLOPE + players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); + players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); +#else players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; +#endif P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); } @@ -5660,6 +5665,11 @@ void A_RecyclePowers(mobj_t *actor) if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE && !players[i].exiting && !((netgame || multiplayer) && players[i].spectator)) { +#ifndef WEIGHTEDRECYCLER + if (players[i].powers[pw_super]) + continue; // Ignore super players +#endif + numplayers++; postscramble[j] = playerslist[j] = (UINT8)i; diff --git a/src/p_floor.c b/src/p_floor.c index f798174ad83850e9664e781bc43f94116234812d..b8d3f7b5e0098605bb44dd37e4e25dfca6d4d81b 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1174,12 +1174,15 @@ void T_SpikeSector(levelspecthink_t *spikes) if (affectsec == spikes->sector) // Applied to an actual sector { + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec); + if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->floorheight) + if (thing->z == affectfloor) dothepain = true; } @@ -1188,18 +1191,20 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->ceilingheight) + if (thing->z + thing->height == affectceil) dothepain = true; } } else { + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector); if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->ceilingheight) + if (thing->z == affectceil) dothepain = true; } @@ -1208,7 +1213,7 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->floorheight) + if (thing->z + thing->height == affectfloor) dothepain = true; } } @@ -1968,51 +1973,71 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies) { size_t i; fixed_t upperbound, lowerbound; - INT32 s; - sector_t *checksector; + sector_t *sec = NULL; + sector_t *targetsec = NULL; + INT32 secnum = -1; msecnode_t *node; mobj_t *thing; - boolean exists = false; + boolean FOFsector = false; - for (i = 0; i < nobaddies->sector->linecount; i++) + while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) { - if (nobaddies->sector->lines[i]->special == 223) + sec = §ors[secnum]; + + FOFsector = false; + + // Check the lines of this sector, to see if it is a FOF control sector. + for (i = 0; i < sec->linecount; i++) { + INT32 targetsecnum = -1; + + if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) + continue; - upperbound = nobaddies->sector->ceilingheight; - lowerbound = nobaddies->sector->floorheight; + FOFsector = true; - for (s = -1; (s = P_FindSectorFromLineTag(nobaddies->sector->lines[i], s)) >= 0 ;) + while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) { - checksector = §ors[s]; + targetsec = §ors[targetsecnum]; - node = checksector->touching_thinglist; // things touching this sector + upperbound = targetsec->ceilingheight; + lowerbound = targetsec->floorheight; + node = targetsec->touching_thinglist; // things touching this sector while (node) { thing = node->m_thing; if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 - && thing->z < upperbound && thing->z+thing->height > lowerbound) - { - exists = true; - goto foundenemy; - } + && thing->z < upperbound && thing->z+thing->height > lowerbound) + return; node = node->m_snext; } } } - } -foundenemy: - if (exists) - return; - s = P_AproxDistance(nobaddies->sourceline->dx, nobaddies->sourceline->dy)>>FRACBITS; + if (!FOFsector) + { + upperbound = sec->ceilingheight; + lowerbound = sec->floorheight; + node = sec->touching_thinglist; // things touching this sector + while (node) + { + thing = node->m_thing; - CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", s); + if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 + && thing->z < upperbound && thing->z+thing->height > lowerbound) + return; + + node = node->m_snext; + } + } + } + + CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag); - // Otherwise, run the linedef exec and terminate this thinker - P_LinedefExecute((INT16)s, NULL, NULL); + // No enemies found, run the linedef exec and terminate this thinker + P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL); P_RemoveThinker(&nobaddies->thinker); } @@ -2067,6 +2092,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) boolean FOFsector = false; boolean inAndOut = false; boolean floortouch = false; + fixed_t bottomheight, topheight; for (i = 0; i < MAXPLAYERS; i++) { @@ -2131,10 +2157,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (players[j].mo->subsector->sector != targetsec) continue; - if (players[j].mo->z > sec->ceilingheight) + topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec); + bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec); + + if (players[j].mo->z > topheight) continue; - if (players[j].mo->z + players[j].mo->height < sec->floorheight) + if (players[j].mo->z + players[j].mo->height < bottomheight) continue; if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) @@ -2217,7 +2246,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) oldPlayersArea = oldPlayersInArea; } - if ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1) + while ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1) { if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3) { @@ -2250,6 +2279,8 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (!eachtime->sourceline->special) // this happens only for "Trigger on X calls" linedefs P_RemoveThinker(&eachtime->thinker); + + oldPlayersArea[affectPlayer]=playersArea[affectPlayer]; } } @@ -2292,7 +2323,7 @@ void T_RaiseSector(levelspecthink_t *raise) if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) continue; - if (!(thing->z == raise->sector->ceilingheight)) + if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) continue; playeronme = true; diff --git a/src/p_local.h b/src/p_local.h index 0b27c40f307732e6d3dc4b66b99c02885ad64e7c..543d800cd101326f53734ea3e97917f1bcdcff42 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -38,6 +38,9 @@ #define MAPBMASK (MAPBLOCKSIZE-1) #define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) +// Convenience macro to fix issue with collision along bottom/left edges of blockmap -Red +#define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;} + // player radius used only in am_map.c #define PLAYERRADIUS (16*FRACUNIT) @@ -214,6 +217,23 @@ boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); + +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) +#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true) +#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true) + +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) + boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); @@ -273,9 +293,13 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed extern boolean floatok; extern fixed_t tmfloorz; extern fixed_t tmceilingz; -extern boolean tmsprung; extern mobj_t *tmfloorthing, *tmthing; extern camera_t *mapcampointer; +extern fixed_t tmx; +extern fixed_t tmy; +#ifdef ESLOPE +extern pslope_t *tmfloorslope, *tmceilingslope; +#endif /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index 62cbf7b77635b8604cd7ecf0ad7f01628e5c976f..eeff412d811e6c29f4df1e165d1f24ae70472ba8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -27,6 +27,10 @@ #include "r_splats.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif + #include "z_zone.h" #include "lua_hook.h" @@ -34,8 +38,8 @@ fixed_t tmbbox[4]; mobj_t *tmthing; static INT32 tmflags; -static fixed_t tmx; -static fixed_t tmy; +fixed_t tmx; +fixed_t tmy; static precipmobj_t *tmprecipthing; static fixed_t preciptmbbox[4]; @@ -48,9 +52,9 @@ fixed_t tmfloorz, tmceilingz; static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector static mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) - -// turned on or off in PIT_CheckThing -boolean tmsprung; +#ifdef ESLOPE +pslope_t *tmfloorslope, *tmceilingslope; +#endif // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -111,7 +115,9 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) fixed_t offx, offy; fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; - fixed_t origvertispeed = vertispeed; // for vertical flipping + + if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic + return; // Spectators don't trigger springs. if (object->player && object->player->spectator) @@ -123,6 +129,7 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) return; } + object->eflags |= MFE_SPRUNG; // apply this flag asap! spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify if (horizspeed && vertispeed) // Mimic SA @@ -191,9 +198,9 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED); // I still need these. P_ResetPlayer(object->player); - if (origvertispeed > 0) + if (P_MobjFlip(object)*vertispeed > 0) P_SetPlayerMobjState(object, S_PLAY_SPRING); - else if (origvertispeed < 0) + else if (P_MobjFlip(object)*vertispeed < 0) P_SetPlayerMobjState(object, S_PLAY_FALL1); else // horizontal spring { @@ -367,10 +374,11 @@ static boolean PIT_CheckThing(mobj_t *thing) fixed_t blockdist; // don't clip against self - tmsprung = false; + if (thing == tmthing) + return true; // Ignore... things. - if (!tmthing || !thing) + if (!tmthing || !thing || P_MobjWasRemoved(thing)) return true; I_Assert(!P_MobjWasRemoved(tmthing)); @@ -438,9 +446,6 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE))) return true; - if (!tmthing || !thing || thing == tmthing || P_MobjWasRemoved(thing)) - return true; - // Don't collide with your buddies while NiGHTS-flying. if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) && ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) @@ -549,7 +554,6 @@ static boolean PIT_CheckThing(mobj_t *thing) if ((tmznext <= thzh && tmz > thzh) || (tmznext > thzh - sprarea && tmznext < thzh)) { P_DoSpring(thing, tmthing); - tmsprung = true; return true; } else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down @@ -818,15 +822,11 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (thing->type == MT_FAN || thing->type == MT_STEAM) P_DoFanAndGasJet(thing, tmthing); - - if ((!(thing->eflags & MFE_VERTICALFLIP) && (tmthing->z <= (thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)) && (tmthing->z + tmthing->height) >= thing->z)) - || ((thing->eflags & MFE_VERTICALFLIP) && (tmthing->z + tmthing->height >= (thing->z - FixedMul(FRACUNIT, thing->scale)) && tmthing->z <= (thing->z + thing->height)))) + else if (thing->flags & MF_SPRING) { - if (thing->flags & MF_SPRING) - { + if ( thing->z <= tmthing->z + tmthing->height + && tmthing->z <= thing->z + thing->height) P_DoSpring(thing, tmthing); - tmsprung = true; - } } } @@ -875,7 +875,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { // Doesn't matter what gravity player's following! Just do your stuff in YOUR direction only if (tmthing->eflags & MFE_VERTICALFLIP - && (tmthing->z + tmthing->height + tmthing->momz > thing->z + && (tmthing->z + tmthing->height + tmthing->momz < thing->z || tmthing->z + tmthing->height + tmthing->momz >= thing->z + thing->height)) ; else if (!(tmthing->eflags & MFE_VERTICALFLIP) @@ -909,17 +909,17 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_FAN || thing->type == MT_STEAM) P_DoFanAndGasJet(thing, tmthing); - + else if (thing->flags & MF_SPRING) + { + if ( thing->z <= tmthing->z + tmthing->height + && tmthing->z <= thing->z + thing->height) + P_DoSpring(thing, tmthing); + } // Are you touching the side of the object you're interacting with? - if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height + else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) { - if (thing->flags & MF_SPRING) - { - P_DoSpring(thing, tmthing); - tmsprung = true; - } - else if (thing->flags & MF_MONITOR + if (thing->flags & MF_MONITOR && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) { SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. @@ -932,14 +932,12 @@ static boolean PIT_CheckThing(mobj_t *thing) *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. return false; } -/* - else if ((thing->flags & (MF_SOLID|MF_NOCLIP|MF_PUSHABLE)) == MF_SOLID) - return false; // this fixes both monitors and non-pushable solids being walked through on bobbing FOFs... for now! -*/ } } + if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)); + else // Monitors are not treated as solid to players who are jumping, spinning or gliding, // unless it's a CTF team monitor and you're on the wrong team if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING) @@ -962,6 +960,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > tmfloorz) { tmfloorz = thing->z + thing->height; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif } return true; } @@ -980,6 +981,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) { tmceilingz = topz; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -993,6 +997,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z < tmceilingz) { tmceilingz = thing->z; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif } return true; } @@ -1010,6 +1017,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz > tmfloorz && tmthing->z >= thing->z) { tmfloorz = topz; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -1132,11 +1142,13 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; + tmceilingslope = opentopslope; } if (openbottom > tmfloorz) { tmfloorz = openbottom; + tmfloorslope = openbottomslope; } if (highceiling > tmdrpoffceilz) @@ -1213,8 +1225,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // that contains the point. // Any contacted lines the step closer together // will adjust them. - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; + tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; +#ifdef ESLOPE + tmfloorslope = newsubsec->sector->f_slope; + tmceilingslope = newsubsec->sector->c_slope; +#endif // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1228,32 +1244,43 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (!(rover->flags & FF_EXISTS)) continue; + fixed_t topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); + fixed_t bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); + if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) { // If you're inside goowater and slowing down fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t minspeed = FixedMul(thing->info->height/12, thing->scale); - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop + if (thing->z < topheight && bottomheight < thingtop && abs(thing->momz) < minspeed) { // Oh no! The object is stick in between the surface of the goo and sinklevel! help them out! - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel && thing->momz >= 0 && thing->momz < (minspeed>>2)) thing->momz += minspeed>>2; - else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel + else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel && thing->momz <= 0 && thing->momz > -(minspeed>>2)) thing->momz -= minspeed>>2; // Land on the top or the bottom, depending on gravity flip. - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0) + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0) { - if (tmfloorz < *rover->topheight - sinklevel) - tmfloorz = *rover->topheight - sinklevel; + if (tmfloorz < topheight - sinklevel) { + tmfloorz = topheight - sinklevel; +#ifdef ESLOPE + tmfloorslope = *rover->t_slope; +#endif + } } - else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0) + else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) { - if (tmceilingz > *rover->bottomheight + sinklevel) - tmceilingz = *rover->bottomheight + sinklevel; + if (tmceilingz > bottomheight + sinklevel) { + tmceilingz = bottomheight + sinklevel; +#ifdef ESLOPE + tmceilingslope = *rover->b_slope; +#endif + } } } continue; @@ -1270,30 +1297,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (rover->flags & FF_QUICKSAND) { - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop) + if (thing->z < topheight && bottomheight < thingtop) { - if (tmfloorz < thing->z) + if (tmfloorz < thing->z) { tmfloorz = thing->z; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } } // Quicksand blocks never change heights otherwise. continue; } - delta1 = thing->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); + delta1 = thing->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2) + if (topheight > tmfloorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; +#ifdef ESLOPE + tmfloorslope = *rover->t_slope; +#endif } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; +#ifdef ESLOPE + tmceilingslope = *rover->b_slope; +#endif } } } @@ -1308,6 +1345,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + #ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { @@ -1364,11 +1403,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) delta1 = thing->z - (polybottom + ((polytop - polybottom)/2)); delta2 = thingtop - (polybottom + ((polytop - polybottom)/2)); - if (polytop > tmfloorz && abs(delta1) < abs(delta2)) + if (polytop > tmfloorz && abs(delta1) < abs(delta2)) { tmfloorz = tmdropoffz = polytop; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } - if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) + if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { tmceilingz = tmdrpoffceilz = polybottom; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } } plink = (polymaplink_t *)(plink->link.next); } @@ -1470,8 +1517,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) // that contains the point. // Any contacted lines the step closer together // will adjust them. - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL); + + tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL); // Cameras use the heightsec's heights rather then the actual sector heights. // If you can see through it, why not move the camera through it too? @@ -1500,17 +1548,20 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = thiscam->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)) + fixed_t topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL); + fixed_t bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL); + + delta1 = thiscam->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); + if (topheight > tmfloorz && abs(delta1) < abs(delta2)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; } } } @@ -1525,6 +1576,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + #ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { @@ -1703,8 +1756,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) } else { - tmfloorz = thiscam->subsector->sector->floorheight; - tmceilingz = thiscam->subsector->sector->ceilingheight; + tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL); + tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL); } // the move is ok, @@ -1766,11 +1819,14 @@ boolean PIT_PushableMoved(mobj_t *thing) boolean oldfltok = floatok; fixed_t oldflrz = tmfloorz; fixed_t oldceilz = tmceilingz; - boolean oldsprung = tmsprung; mobj_t *oldflrthing = tmfloorthing; mobj_t *oldthing = tmthing; line_t *oldceilline = ceilingline; line_t *oldblockline = blockingline; +#ifdef ESLOPE + pslope_t *oldfslope = tmfloorslope; + pslope_t *oldcslope = tmceilingslope; +#endif // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -1779,11 +1835,14 @@ boolean PIT_PushableMoved(mobj_t *thing) floatok = oldfltok; tmfloorz = oldflrz; tmceilingz = oldceilz; - tmsprung = oldsprung; tmfloorthing = oldflrthing; P_SetTarget(&tmthing, oldthing); ceilingline = oldceilline; blockingline = oldblockline; +#ifdef ESLOPE + tmfloorslope = oldfslope; + tmceilingslope = oldcslope; +#endif thing->momz = stand->momz; } else @@ -1805,6 +1864,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t tryy = thing->y; fixed_t radius = thing->radius; fixed_t thingtop = thing->z + thing->height; +#ifdef ESLOPE + fixed_t startingonground = P_IsObjectOnGround(thing); +#endif floatok = false; if (radius < MAXRADIUS/2) @@ -1893,13 +1955,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) { - thing->z = tmceilingz - thing->height; + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) + { + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { - thing->z = tmfloorz; + thing->z = thing->floorz = tmfloorz; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) + { + thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } @@ -1954,6 +2026,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) xh = (unsigned)(thing->x + MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; xl = (unsigned)(thing->x - MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + stand = thing; standx = x; standy = y; @@ -1968,6 +2042,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + +#ifdef ESLOPE + // Assign thing's standingslope if needed + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmfloorslope) + P_HandleSlopeLanding(thing, tmfloorslope); + + if (thing->momz <= 0) + thing->standingslope = tmfloorslope; + } + else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmceilingslope) + P_HandleSlopeLanding(thing, tmceilingslope); + + if (thing->momz >= 0) + thing->standingslope = tmceilingslope; + } +#endif + thing->x = x; thing->y = y; @@ -1983,6 +2076,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) { fixed_t tryx, tryy; + tryx = thing->x; tryy = thing->y; do { @@ -2308,15 +2402,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) { fixed_t platx, platy; subsector_t *glidesector; + fixed_t floorz, ceilingz; platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); +#ifdef ESLOPE + floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; + ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; +#else + floorz = glidesector->sector->floorheight; + ceilingz = glidesector->sector->ceilingheight; +#endif + if (glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; + fixed_t topheight, bottomheight; if (glidesector->sector->ffloors) { @@ -2326,34 +2430,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) continue; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); +#endif + floorclimb = true; if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight)) + if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) { floorclimb = true; } - if (*rover->topheight < player->mo->z) // Waaaay below the ledge. + if (topheight < player->mo->z) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } } else { - if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight)) + if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) { floorclimb = true; } - if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. + if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } @@ -2366,30 +2480,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight)) + if ((floorz <= player->mo->z + player->mo->height) + && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) floorclimb = true; - if ((glidesector->sector->floorheight > player->mo->z) + if ((floorz > player->mo->z) && glidesector->sector->floorpic == skyflatnum) return false; - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight) - || (player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) + || (player->mo->z + player->mo->height <= floorz)) floorclimb = true; } else { - if ((glidesector->sector->ceilingheight >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight)) + if ((ceilingz >= player->mo->z) + && ((player->mo->z - player->mo->momz) >= ceilingz)) floorclimb = true; - if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height) + if ((ceilingz < player->mo->z+player->mo->height) && glidesector->sector->ceilingpic == skyflatnum) return false; - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight) - || (player->mo->z >= glidesector->sector->ceilingheight)) + if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz) + || (player->mo->z >= ceilingz)) floorclimb = true; } @@ -2461,6 +2575,7 @@ isblocking: line_t *checkline = li; sector_t *checksector; ffloor_t *rover; + fixed_t topheight, bottomheight; boolean fofline = false; INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); @@ -2476,13 +2591,23 @@ isblocking: if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight < slidemo->z) + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); +#endif + + if (topheight < slidemo->z) continue; - if (*rover->bottomheight > slidemo->z + slidemo->height) + if (bottomheight > slidemo->z + slidemo->height) continue; - // Got this far, so I guess it's climbable. + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? if (rover->master->flags & ML_TFERLINE) { size_t linenum = li-checksector->lines[0]; @@ -3040,6 +3165,8 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist) xh = (unsigned)(spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT; xl = (unsigned)(spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + bombspot = spot; bombsource = source; bombdamage = FixedMul(damagedist, spot->scale); @@ -3100,6 +3227,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) { ffloor_t *rover; + fixed_t topheight, bottomheight; fixed_t delta1, delta2; INT32 thingtop = thing->z + thing->height; @@ -3109,9 +3237,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) continue; - delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2; - delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2; - if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y); +#endif*/ + + delta1 = thing->z - (bottomheight + topheight)/2; + delta2 = thingtop - (bottomheight + topheight)/2; + if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { if (thing->flags & MF_PUSHABLE) { @@ -3661,6 +3799,8 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y) yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) P_BlockLinesIterator(bx, by, PIT_GetSectors); @@ -3738,6 +3878,8 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y) yl = (unsigned)(preciptmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(preciptmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) P_BlockLinesIterator(bx, by, PIT_GetPrecipSectors); @@ -3785,7 +3927,7 @@ void P_MapEnd(void) } // P_FloorzAtPos -// Returns the floorz of the XYZ position +// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too // Tails 05-26-2003 fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { @@ -3806,9 +3948,19 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, x, y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, x, y); +#endif + if (rover->flags & FF_QUICKSAND) { - if (z < *rover->topheight && *rover->bottomheight < thingtop) + if (z < topheight && bottomheight < thingtop) { if (floorz < z) floorz = z; @@ -3816,10 +3968,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) continue; } - delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; + delta1 = z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > floorz && abs(delta1) < abs(delta2)) + floorz = topheight; } } diff --git a/src/p_maputl.c b/src/p_maputl.c index 48dd54e8da8efbcebfc6183d9fa817698a2f54e8..c9a42bd4348b1603094c47bc0ef8cebc8bd05735 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -17,6 +17,7 @@ #include "p_local.h" #include "r_main.h" +#include "r_data.h" #include "p_maputl.h" #include "p_polyobj.h" #include "z_zone.h" @@ -321,6 +322,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) // OPTIMIZE: keep this precalculated // fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +pslope_t *opentopslope, *openbottomslope; +#endif // P_CameraLineOpening // P_LineOpening, but for camera @@ -347,31 +351,56 @@ void P_CameraLineOpening(line_t *linedef) { frontfloor = sectors[front->camsec].floorheight; frontceiling = sectors[front->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y); + if (sectors[front->camsec].c_slope) + frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); +#endif + } else if (front->heightsec >= 0) { frontfloor = sectors[front->heightsec].floorheight; frontceiling = sectors[front->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y); + if (sectors[front->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y); +#endif } else { - frontfloor = front->floorheight; - frontceiling = front->ceilingheight; + frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); + frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); } if (back->camsec >= 0) { backfloor = sectors[back->camsec].floorheight; backceiling = sectors[back->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y); + if (sectors[back->camsec].c_slope) + frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y); +#endif } else if (back->heightsec >= 0) { backfloor = sectors[back->heightsec].floorheight; backceiling = sectors[back->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y); + if (sectors[back->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y); +#endif } else { - backfloor = back->floorheight; - backceiling = back->ceilingheight; + backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef); + backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef); } { @@ -416,17 +445,20 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; - - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; + fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef); + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } // Check for backsectors fake floors @@ -436,17 +468,20 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; - - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; + fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef); + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } if (highestceiling < highceiling) @@ -494,32 +529,91 @@ void P_LineOpening(line_t *linedef) I_Assert(front != NULL); I_Assert(back != NULL); - if (front->ceilingheight < back->ceilingheight) - { - opentop = front->ceilingheight; - highceiling = back->ceilingheight; - } - else - { - opentop = back->ceilingheight; - highceiling = front->ceilingheight; - } + { // Set open and high/low values here + fixed_t frontheight, backheight; - if (front->floorheight > back->floorheight) - { - openbottom = front->floorheight; - lowfloor = back->floorheight; - } - else - { - openbottom = back->floorheight; - lowfloor = front->floorheight; + frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef); + + if (frontheight < backheight) + { + opentop = frontheight; + highceiling = backheight; + opentopslope = front->c_slope; + } + else + { + opentop = backheight; + highceiling = frontheight; + opentopslope = back->c_slope; + } + + frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef); + + if (frontheight > backheight) + { + openbottom = frontheight; + lowfloor = backheight; + openbottomslope = front->f_slope; + } + else + { + openbottom = backheight; + lowfloor = frontheight; + openbottomslope = back->f_slope; + } } if (tmthing) { fixed_t thingtop = tmthing->z + tmthing->height; + // Check for collision with front side's midtexture if Effect 4 is set + if (linedef->flags & ML_EFFECT4) { + side_t *side = &sides[linedef->sidenum[0]]; + fixed_t textop, texbottom, texheight; + fixed_t texmid, delta1, delta2; + + // Get the midtexture's height + texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS; + + // Set texbottom and textop to the Z coordinates of the texture's boundaries +#ifdef POLYOBJECTS + if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { + if (linedef->flags & ML_DONTPEGBOTTOM) { + texbottom = back->floorheight + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = back->ceilingheight - side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } + } else +#endif + { + if (linedef->flags & ML_DONTPEGBOTTOM) { + texbottom = openbottom + side->rowoffset; + textop = texbottom + texheight*(side->repeatcnt+1); + } else { + textop = opentop - side->rowoffset; + texbottom = textop - texheight*(side->repeatcnt+1); + } + } + + texmid = texbottom+(textop-texbottom)/2; + + delta1 = abs(tmthing->z - texmid); + delta2 = abs(thingtop - texmid); + + if (delta1 > delta2) { // Below + if (opentop > texbottom) + opentop = texbottom; + } else { // Above + if (openbottom < textop) + openbottom = textop; + } + } + // Check for fake floors in the sector. if (front->ffloors || back->ffloors #ifdef POLYOBJECTS @@ -534,6 +628,10 @@ void P_LineOpening(line_t *linedef) fixed_t highestfloor = openbottom; fixed_t lowestfloor = lowfloor; fixed_t delta1, delta2; +#ifdef ESLOPE + pslope_t *ceilingslope = opentopslope; + pslope_t *floorslope = openbottomslope; +#endif // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) @@ -547,23 +645,34 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + fixed_t topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef); + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) { + lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) { + highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } + else if (topheight > lowestfloor) + lowestfloor = topheight; } } @@ -579,23 +688,34 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + fixed_t topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef); + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) { + lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) { + highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } + else if (topheight > lowestfloor) + lowestfloor = topheight; } } @@ -607,13 +727,21 @@ void P_LineOpening(line_t *linedef) delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); - if (polysec->floorheight < lowestceiling && delta1 >= delta2) + if (polysec->floorheight < lowestceiling && delta1 >= delta2) { lowestceiling = polysec->floorheight; +#ifdef ESLOPE + ceilingslope = NULL; +#endif + } else if (polysec->floorheight < highestceiling && delta1 >= delta2) highestceiling = polysec->floorheight; - if (polysec->ceilingheight > highestfloor && delta1 < delta2) + if (polysec->ceilingheight > highestfloor && delta1 < delta2) { highestfloor = polysec->ceilingheight; +#ifdef ESLOPE + floorslope = NULL; +#endif + } else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) lowestfloor = polysec->ceilingheight; } @@ -621,11 +749,19 @@ void P_LineOpening(line_t *linedef) if (highestceiling < highceiling) highceiling = highestceiling; - if (highestfloor > openbottom) + if (highestfloor > openbottom) { openbottom = highestfloor; +#ifdef ESLOPE + openbottomslope = floorslope; +#endif + } - if (lowestceiling < opentop) + if (lowestceiling < opentop) { opentop = lowestceiling; +#ifdef ESLOPE + opentopslope = ceilingslope; +#endif + } if (lowestfloor > lowfloor) lowfloor = lowestfloor; @@ -723,6 +859,7 @@ void P_SetThingPosition(mobj_t *thing) { // link into subsector subsector_t *ss; sector_t *oldsec = NULL; + fixed_t tfloorz, tceilz; I_Assert(thing != NULL); I_Assert(!P_MobjWasRemoved(thing)); @@ -792,12 +929,15 @@ void P_SetThingPosition(mobj_t *thing) // sector's floor is the same height. if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector) { + tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL); + tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL); + if (thing->eflags & MFE_VERTICALFLIP) { - if (thing->z + thing->height >= thing->subsector->sector->ceilingheight) + if (thing->z + thing->height >= tceilz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thing->z <= thing->subsector->sector->floorheight) + else if (thing->z <= tfloorz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } diff --git a/src/p_maputl.h b/src/p_maputl.h index 66f7db2dbaeb30e215e231b0ca256fc450eb164a..7471899cc5bb0bc88e34b7e197621231e99eb289 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -55,6 +55,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +extern pslope_t *opentopslope, *openbottomslope; +#endif void P_LineOpening(line_t *plinedef); diff --git a/src/p_mobj.c b/src/p_mobj.c index cac4bc24bc4b326b18ff79f21107f53a7419b205..7d48ca60c6fd7348fbd30ba0a66e81d4e91e478d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -31,6 +31,9 @@ #include "i_video.h" #include "lua_hook.h" #include "b_bot.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif // protos. static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; @@ -700,15 +703,441 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) return false; - if (mobj->z > *rover->topheight) + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + + if (mobj->z > topheight) return false; - if (mobj->z + mobj->height < *rover->bottomheight) + if (mobj->z + mobj->height < bottomheight) return false; return true; } +// P_GetFloorZ (and its ceiling counterpart) +// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] +// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line +// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate). +// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking +// usage will handle that later. +static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest) +{ + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + if (actuallylowest) + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + else + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); +} + +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the floor height +#endif + return sector->floorheight; +} + +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height +#endif + return sector->ceilingheight; +} + +// Now do the same as all above, but for cameras because apparently cameras are special? +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the floor height +#endif + return sector->floorheight; +} + +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height +#endif + return sector->ceilingheight; +} static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -975,7 +1404,11 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) } else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) - && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))) + && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) +#ifdef ESLOPE + && !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) { // if in a walking frame, stop moving if (player->panim == PA_WALK) @@ -1119,6 +1552,11 @@ void P_XYMovement(mobj_t *mo) fixed_t xmove, ymove; fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; +#ifdef ESLOPE + pslope_t *oldslope = NULL; + vector3_t slopemom; + fixed_t predictedz = 0; +#endif I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1150,11 +1588,35 @@ void P_XYMovement(mobj_t *mo) oldx = mo->x; oldy = mo->y; +#ifdef ESLOPE + // adjust various things based on slope + if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { + if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! + P_SlopeLaunch(mo); + xmove = mo->momx; + ymove = mo->momy; + } else { // Still on the ground. + slopemom.x = xmove; + slopemom.y = ymove; + slopemom.z = 0; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + xmove = slopemom.x; + ymove = slopemom.y; + + predictedz = mo->z + slopemom.z; // We'll use this later... + + oldslope = mo->standingslope; + } + } else if (P_IsObjectOnGround(mo) && !mo->momz) + predictedz = mo->z; +#endif + // Pushables can break some blocks if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); - if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !tmsprung) + if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) { // blocked move @@ -1270,6 +1732,54 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; +#ifdef ESLOPE + if (moved && oldslope) { // Check to see if we ran off + + if (oldslope != mo->standingslope) { // First, compare different slopes + angle_t oldangle, newangle; + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + + oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); + + if (mo->standingslope) + newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + else + newangle = 0; + + // Now compare the Zs of the different quantizations + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later + mo->standingslope = oldslope; + P_SlopeLaunch(mo); + + //CONS_Printf("launched off of slope - "); + } + + /*CONS_Printf("old angle %f - new angle %f = %f\n", + FIXED_TO_FLOAT(AngleFixed(oldangle)), + FIXED_TO_FLOAT(AngleFixed(newangle)), + FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) + );*/ + } else if (predictedz-mo->z > abs(slopemom.z/2)) { // Now check if we were supposed to stick to this slope + //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); + P_SlopeLaunch(mo); + } + } else if (moved && mo->standingslope && predictedz) { + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + + /*CONS_Printf("flat to angle %f - predicted z of %f\n", + FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), + FIXED_TO_FLOAT(predictedz) + );*/ + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { + mo->momz = P_MobjFlip(mo)*FRACUNIT/2; + mo->z = predictedz + P_MobjFlip(mo); + mo->standingslope = NULL; + //CONS_Printf("Launched off of flat surface running into downward slope\n"); + } + } +#endif + // Check the gravity status. P_CheckGravity(mo, false); @@ -1316,6 +1826,12 @@ void P_XYMovement(mobj_t *mo) if (player && player->homing) // no friction for homing return; +#ifdef ESLOPE + if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) + && (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)) // Special exception for tumbleweeds on slopes + return; +#endif + if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) && !(player && player->pflags & PF_SLIDING)) return; // no friction when airborne @@ -1372,6 +1888,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp { ffloor_t *rover; fixed_t delta1, delta2, thingtop; + fixed_t topheight, bottomheight; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1383,6 +1900,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp if (!(rover->flags & FF_EXISTS)) continue; + topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); + bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); + if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only @@ -1397,14 +1917,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp switch (motype) { case 2: // scenery does things differently for some reason - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { mo->floorz = mo->z; continue; } break; default: - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { if (mo->floorz < mo->z) mo->floorz = mo->z; @@ -1413,17 +1933,17 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp } } - delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2) + delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - mo->floorz = *rover->topheight; + mo->floorz = topheight; } - if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM)) { - mo->ceilingz = *rover->bottomheight; + mo->ceilingz = bottomheight; } } } @@ -1555,6 +2075,11 @@ static boolean P_ZMovement(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -1742,14 +2267,31 @@ static boolean P_ZMovement(mobj_t *mo) || (mo->z + mo->height >= mo->ceilingz && mo->eflags & MFE_VERTICALFLIP)) && !(mo->flags & MF_NOCLIPHEIGHT)) { + vector3_t mom; + mom.x = mo->momx; + mom.y = mo->momy; + mom.z = mo->momz; + if (mo->eflags & MFE_VERTICALFLIP) mo->z = mo->ceilingz - mo->height; else mo->z = mo->floorz; +#ifdef ESLOPE + P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly + if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) { + mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; + + // Reverse quantizing might could use its own function later + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + } +#endif + // hit the floor if (mo->type == MT_FIREBALL) // special case for the fireball - mo->momz = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); + mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here ; else if (mo->flags & MF_MISSILE) @@ -1764,12 +2306,12 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->flags & MF_GRENADEBOUNCE) { // Going down? (Or up in reverse gravity?) - if (P_MobjFlip(mo)*mo->momz < 0) + if (P_MobjFlip(mo)*mom.z < 0) { // If going slower than a fracunit, just stop. - if (abs(mo->momz) < FixedMul(FRACUNIT, mo->scale)) + if (abs(mom.z) < FixedMul(FRACUNIT, mo->scale)) { - mo->momx = mo->momy = mo->momz = 0; + mom.x = mom.y = mom.z = 0; // Napalm hack if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse) @@ -1777,7 +2319,7 @@ static boolean P_ZMovement(mobj_t *mo) } // Otherwise bounce up at half speed. else - mo->momz = -mo->momz/2; + mom.z = -mom.z/2; S_StartSound(mo, mo->info->activesound); } } @@ -1800,14 +2342,14 @@ static boolean P_ZMovement(mobj_t *mo) } } - if (P_MobjFlip(mo)*mo->momz < 0) // falling + if (P_MobjFlip(mo)*mom.z < 0) // falling { if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) mo->eflags |= MFE_JUSTHITFLOOR; if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something - mo->momz = -mo->momz; + mom.z = -mom.z; else // Flingrings bounce if (mo->type == MT_FLINGRING @@ -1820,35 +2362,42 @@ static boolean P_ZMovement(mobj_t *mo) || mo->type == MT_FALLINGROCK) { if (maptol & TOL_NIGHTS) - mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT); + mom.z = -FixedDiv(mom.z, 10*FRACUNIT); else - mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT)); + mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT)); if (mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) { - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (!(mo->flags & MF_AMBUSH)) - { - mo->momx = mo->momy = mo->momz = 0; - P_SetMobjState(mo, mo->info->spawnstate); - } - else + if (mo->flags & MF_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. - mo->momz += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); + mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momx += FixedMul(6*FRACUNIT, mo->scale); + mom.x += FixedMul(6*FRACUNIT, mo->scale); else - mo->momx -= FixedMul(6*FRACUNIT, mo->scale); + mom.x -= FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momy += FixedMul(6*FRACUNIT, mo->scale); + mom.y += FixedMul(6*FRACUNIT, mo->scale); else - mo->momy -= FixedMul(6*FRACUNIT, mo->scale); + mom.y -= FixedMul(6*FRACUNIT, mo->scale); + } +#ifdef ESLOPE + else if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) + { + // Pop the object up a bit to encourage bounciness + //mom.z = P_MobjFlip(mo)*mo->scale; + } +#endif + else + { + mom.x = mom.y = mom.z = 0; + P_SetMobjState(mo, mo->info->spawnstate); } } @@ -1858,14 +2407,14 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_FALLINGROCK) { - if (P_MobjFlip(mo)*mo->momz > FixedMul(2*FRACUNIT, mo->scale)) + if (P_MobjFlip(mo)*mom.z > FixedMul(2*FRACUNIT, mo->scale)) S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->mass)); - mo->momz /= 2; // Rocks not so bouncy + mom.z /= 2; // Rocks not so bouncy - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { P_RemoveMobj(mo); return false; @@ -1873,20 +2422,30 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_CANNONBALLDECOR) { - mo->momz /= 2; - if (abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) - mo->momz = 0; + mom.z /= 2; + if (abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) + mom.z = 0; } } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; else if (!tmfloorthing) - mo->momz = 0; + mom.z = 0; } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; + +#ifdef ESLOPE + if (mo->standingslope) { + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + } +#endif + + mo->momx = mom.x; + mo->momy = mom.y; + mo->momz = mom.z; if (mo->type == MT_STEAM) return true; @@ -2000,6 +2559,11 @@ static void P_PlayerZMovement(mobj_t *mo) || mo->player->playerstate == PST_REBORN) return; +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // clip movement if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) { @@ -2021,6 +2585,13 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->state == &states[mo->info->painstate] || mo->state == &states[S_PLAY_SUPERHIT]) P_SetPlayerMobjState(mo, S_PLAY_STND); +#ifdef ESLOPE + if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { + // Handle landing on slope during Z movement + P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); + } +#endif + if (P_MobjFlip(mo)*mo->momz < 0) // falling { // Squat down. Decrease viewheight for a moment after hitting the ground (hard), @@ -2429,7 +3000,7 @@ void P_MobjCheckWater(mobj_t *mobj) player_t *p = mobj->player; // Will just be null if not a player. // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // Reset water state. mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER); @@ -2441,34 +3012,45 @@ void P_MobjCheckWater(mobj_t *mobj) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + if (mobj->eflags & MFE_VERTICALFLIP) { - if (*rover->topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) - || *rover->bottomheight > thingtop) + if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) + || bottomheight > thingtop) continue; } else { - if (*rover->topheight < mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) + if (topheight < mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) continue; } // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; // Just touching the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)) { mobj->eflags |= MFE_TOUCHWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } // Actually in the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight)) { mobj->eflags |= MFE_UNDERWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -2647,7 +3229,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) sector_t *sector; // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // see if we are in water, and set some flags for later sector = mobj->subsector->sector; @@ -2655,6 +3237,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) if (sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER); @@ -2662,20 +3245,32 @@ static void P_SceneryCheckWater(mobj_t *mobj) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (*rover->topheight <= mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + + if (topheight <= mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) continue; - if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight) mobj->eflags |= MFE_TOUCHWATER; else mobj->eflags &= ~MFE_TOUCHWATER; // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; - if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight) mobj->eflags |= MFE_UNDERWATER; else mobj->eflags &= ~MFE_UNDERWATER; @@ -2705,7 +3300,15 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (!(rover->flags & FF_EXISTS)) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) @@ -2733,7 +3336,15 @@ static boolean P_CameraCheckWater(camera_t *thiscam) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; return true; @@ -2903,6 +3514,10 @@ static void P_PlayerMobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); +#ifdef ESLOPE + P_ButteredSlope(mobj); +#endif + // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; @@ -2941,6 +3556,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Crumbling platforms for (node = mobj->touching_sectorlist; node; node = node->m_snext) { + fixed_t topheight, bottomheight; ffloor_t *rover; for (rover = node->m_sector->ffloors; rover; rover = rover->next) @@ -2948,8 +3564,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) continue; - if ((*rover->topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (*rover->bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. + topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector); + + if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) + || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); } } @@ -5448,7 +6067,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) P_SetTarget(&mobj->tracer, NULL); - mobj->flags2 &= ~MF2_PUSHED; + mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG); // 970 allows ANY mobj to trigger a linedef exec if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) @@ -6658,6 +7277,21 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s mobj->eflags &= ~MFE_JUSTHITFLOOR; } +#ifdef ESLOPE // Sliding physics for slidey mobjs! + if (mobj->type == MT_FLINGRING + || mobj->type == MT_FLINGCOIN + || P_WeaponOrPanel(mobj->type) + || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_BIGTUMBLEWEED + || mobj->type == MT_LITTLETUMBLEWEED + || mobj->type == MT_CANNONBALLDECOR + || mobj->type == MT_FALLINGROCK) { + P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly + //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); + P_ButteredSlope(mobj); + } +#endif + if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { @@ -6931,8 +7565,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Make sure scale matches destscale immediately when spawned P_SetScale(mobj, mobj->destscale); - mobj->floorz = mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->ceilingheight; + mobj->floorz = +#ifdef ESLOPE + mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : +#endif + mobj->subsector->sector->floorheight; + mobj->ceilingz = +#ifdef ESLOPE + mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : +#endif + mobj->subsector->sector->ceilingheight; // Tells MobjCheckWater that the water height was not set. mobj->watertop = INT32_MAX; @@ -7989,7 +8631,11 @@ void P_SpawnMapThing(mapthing_t *mthing) return; ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); - mthing->z = (INT16)((ss->sector->floorheight>>FRACBITS) + (mthing->options >> ZSHIFT)); + mthing->z = (INT16)((( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) : +#endif + ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT)); if (numhuntemeralds < MAXHUNTEMERALDS) huntemeralds[numhuntemeralds++] = mthing; @@ -8107,14 +8753,22 @@ void P_SpawnMapThing(mapthing_t *mthing) ss = R_PointInSubsector(x, y); if (i == MT_NIGHTSBUMPER) - z = ss->sector->floorheight + ((mthing->options >> ZSHIFT) << FRACBITS); + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) z = ONFLOORZ; else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY) { if (mthing->options & MTF_OBJECTFLIP) { - z = ss->sector->ceilingheight; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z -= 24*FRACUNIT; @@ -8125,7 +8779,11 @@ void P_SpawnMapThing(mapthing_t *mthing) } else { - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z += 24*FRACUNIT; @@ -8145,9 +8803,17 @@ void P_SpawnMapThing(mapthing_t *mthing) // base positions if (flip) - z = ss->sector->ceilingheight - mobjinfo[i].height; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - mobjinfo[i].height; else - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); // offsetting if (mthing->options >> ZSHIFT) @@ -8661,7 +9327,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Screw these damn hoops, I need this thinker. //hoopcenter->flags |= MF_NOTHINK; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; @@ -8794,7 +9464,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; P_UnsetThingPosition(hoopcenter); @@ -8906,7 +9580,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Wing logo item. else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -8958,13 +9636,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Set proper height if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9018,13 +9704,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) { if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - dist*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - dist*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + dist*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + dist*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9070,13 +9764,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9107,7 +9809,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) size = 192*FRACUNIT; } - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); diff --git a/src/p_mobj.h b/src/p_mobj.h index 6d120c4733b1f54ff25cbeab05b691891722c108..d7a370c38800e77c0422f4e88bd4c0e0d99672cd 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -175,24 +175,23 @@ typedef enum MF2_EXPLOSION = 1<<7, // Thrown ring has explosive properties MF2_SCATTER = 1<<8, // Thrown ring has scatter properties MF2_BEYONDTHEGRAVE = 1<<9, // Source of this missile has died and has since respawned. - MF2_PUSHED = 1<<10, // Mobj was already pushed this tic - MF2_SLIDEPUSH = 1<<11, // MF_PUSHABLE that pushes continuously. - MF2_CLASSICPUSH = 1<<12, // Drops straight down when object has negative Z. - MF2_STANDONME = 1<<13, // While not pushable, stand on me anyway. - MF2_INFLOAT = 1<<14, // Floating to a height for a move, don't auto float to target's height. - MF2_DEBRIS = 1<<15, // Splash ring from explosion ring - MF2_NIGHTSPULL = 1<<16, // Attracted from a paraloop - MF2_JUSTATTACKED = 1<<17, // can be pushed by other moving mobjs - MF2_FIRING = 1<<18, // turret fire - MF2_SUPERFIRE = 1<<19, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. - MF2_SHADOW = 1<<20, // Fuzzy draw, makes targeting harder. - MF2_STRONGBOX = 1<<21, // Flag used for "strong" random monitors. - MF2_OBJECTFLIP = 1<<22, // Flag for objects that always have flipped gravity. - MF2_SKULLFLY = 1<<23, // Special handling: skull in flight. - MF2_FRET = 1<<24, // Flashing from a previous hit - MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss - MF2_BOSSFLEE = 1<<26, // Boss is fleeing! - MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + MF2_SLIDEPUSH = 1<<10, // MF_PUSHABLE that pushes continuously. + MF2_CLASSICPUSH = 1<<11, // Drops straight down when object has negative Z. + MF2_STANDONME = 1<<12, // While not pushable, stand on me anyway. + MF2_INFLOAT = 1<<13, // Floating to a height for a move, don't auto float to target's height. + MF2_DEBRIS = 1<<14, // Splash ring from explosion ring + MF2_NIGHTSPULL = 1<<15, // Attracted from a paraloop + MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs + MF2_FIRING = 1<<17, // turret fire + MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. + MF2_SHADOW = 1<<19, // Fuzzy draw, makes targeting harder. + MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors. + MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity. + MF2_SKULLFLY = 1<<22, // Special handling: skull in flight. + MF2_FRET = 1<<23, // Flashing from a previous hit + MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss + MF2_BOSSFLEE = 1<<25, // Boss is fleeing! + MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) // free: to and including 1<<31 } mobjflag2_t; @@ -232,7 +231,11 @@ typedef enum MFE_VERTICALFLIP = 1<<5, // Goo water MFE_GOOWATER = 1<<6, - // free: to and including 1<<7 + // Mobj was already pushed this tic + MFE_PUSHED = 1<<7, + // Mobj was already sprung this tic + MFE_SPRUNG = 1<<8, + // free: to and including 1<<15 } mobjeflag_t; // @@ -286,7 +289,7 @@ typedef struct mobj_s state_t *state; UINT32 flags; // flags from mobjinfo tables UINT32 flags2; // MF2_ flags - UINT8 eflags; // extra flags + UINT16 eflags; // extra flags void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin) // Player and mobj sprites in multiplayer modes are modified @@ -349,6 +352,10 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; +#ifdef ESLOPE + struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) +#endif + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 9c955c97beeb30af6f0a341bf46fc998869c5c29..f790fa768533574960a1a9621ed9f40333538e32 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1043,9 +1043,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) mo->lastlook = pomovecount; - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1097,9 +1098,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) for (; mo; mo = mo->bnext) { - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1259,6 +1262,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, { static INT32 pomovecount = 10000; INT32 x, y; + angle_t deltafine = delta >> ANGLETOFINESHIFT; pomovecount++; @@ -1283,9 +1287,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, mo->lastlook = pomovecount; - // always push players even if not solid - if (!((mo->flags & MF_SOLID) || mo->player)) + // Don't scroll objects that aren't affected by gravity + if (mo->flags & MF_NOGRAVITY) continue; + // (The above check used to only move MF_SOLID objects, but that's inconsistent with conveyor behavior. -Red) if (mo->flags & MF_NOCLIP) continue; @@ -1300,21 +1305,28 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, continue; { - fixed_t newxoff, newyoff; - angle_t angletoobj = R_PointToAngle2(origin.x, origin.y, mo->x, mo->y); - fixed_t disttoobj = R_PointToDist2(origin.x, origin.y, mo->x, mo->y); + fixed_t oldxoff, oldyoff, newxoff, newyoff; + fixed_t c, s; + + c = FINECOSINE(deltafine); + s = FINESINE(deltafine); + + oldxoff = mo->x-origin.x; + oldyoff = mo->y-origin.y; if (mo->player) // Hack to fix players sliding off of spinning polys -Red { - disttoobj = FixedMul(disttoobj, 0xfe40); + fixed_t temp; + + temp = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); + oldyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); + oldxoff = temp; } - angletoobj += delta; - angletoobj >>= ANGLETOFINESHIFT; - newxoff = FixedMul(FINECOSINE(angletoobj), disttoobj); - newyoff = FixedMul(FINESINE(angletoobj), disttoobj); + newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); + newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); - Polyobj_slideThing(mo, origin.x+newxoff-mo->x, origin.y+newyoff-mo->y); + Polyobj_slideThing(mo, newxoff-oldxoff, newyoff-oldyoff); if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; @@ -2491,6 +2503,10 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) return 0; } + // Hotfix to not crash on single-waypoint sequences -Red + if (!last) + last = first; + // Set diffx, diffy, diffz // Put these at 0 for now...might not be needed after all. th->diffx = 0;//first->x - po->centerPt.x; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 71cf965e3b7c990ca937331da5f2c32bb8e6bc31..3d6576cc6d9c59aa5fbf57b26c4d35663852f038 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -100,6 +100,8 @@ typedef struct polyobj_s UINT8 isBad; // a bad polyobject: should not be rendered/manipulated INT32 translucency; // index to translucency tables + struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later + // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with } polyobj_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index 851d653fa2c2736d8a59a720f9a493b4f7ee5ffb..eec3dbf3eb27f7ff39e023da9e381f116a8f3ee5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1174,7 +1174,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff & MD_FRAME) WRITEUINT32(save_p, mobj->frame); if (diff & MD_EFLAGS) - WRITEUINT8(save_p, mobj->eflags); + WRITEUINT16(save_p, mobj->eflags); if (diff & MD_PLAYER) WRITEUINT8(save_p, mobj->player-players); if (diff & MD_MOVEDIR) @@ -2000,7 +2000,7 @@ static void LoadMobjThinker(actionf_p1 thinker) else mobj->frame = mobj->state->frame; if (diff & MD_EFLAGS) - mobj->eflags = READUINT8(save_p); + mobj->eflags = READUINT16(save_p); if (diff & MD_PLAYER) { i = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d84c3a1222308e130a539eff55a8cd670..c836d601c60cc21a454974f8cb2657ef4671149b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -72,6 +72,10 @@ #include "hardware/hw_light.h" #endif +#ifdef ESLOPE +#include "p_slopes.h" +#endif + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -888,9 +892,14 @@ static void P_LoadThings(lumpnum_t lumpnum) numhuntemeralds = 0; for (i = 0; i < nummapthings; i++, mt++) { + sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; + // Z for objects - mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) - ->sector->floorheight>>FRACBITS); + mt->z = (INT16)( +#ifdef ESLOPE + mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : +#endif + mtsector->floorheight)>>FRACBITS; if (mt->type == 1700 // MT_AXIS || mt->type == 1701 // MT_AXISTRANSFER @@ -2531,6 +2540,10 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); +#ifdef ESLOPE + P_ResetDynamicSlopes(); +#endif + P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_SpawnSecretItems(loademblems); diff --git a/src/p_slopes.c b/src/p_slopes.c new file mode 100644 index 0000000000000000000000000000000000000000..d0b20216822a63f1fd6c6a224519e4cde54e3387 --- /dev/null +++ b/src/p_slopes.c @@ -0,0 +1,922 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron +// +//----------------------------------------------------------------------------- + + +#include "doomdef.h" +#include "r_defs.h" +#include "r_state.h" +#include "m_bbox.h" +#include "z_zone.h" +#include "p_spec.h" +#include "p_slopes.h" +#include "r_main.h" +#include "p_maputl.h" +#include "w_wad.h" + +#ifdef ESLOPE + +static pslope_t *dynslopes = NULL; + +// Calculate line normal +void P_CalculateSlopeNormal(pslope_t *slope) { + slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); + slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); + slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); +} + +// Recalculate dynamic slopes +void P_RunDynamicSlopes(void) { + pslope_t *slope; + + for (slope = dynslopes; slope; slope = slope->next) { + fixed_t zdelta; + + switch(slope->refpos) { + case 1: // front floor + zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; + slope->o.z = slope->sourceline->frontsector->floorheight; + break; + case 2: // front ceiling + zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight; + slope->o.z = slope->sourceline->frontsector->ceilingheight; + break; + case 3: // back floor + zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight; + slope->o.z = slope->sourceline->backsector->floorheight; + break; + case 4: // back ceiling + zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; + slope->o.z = slope->sourceline->backsector->ceilingheight; + break; + + default: + I_Error("P_RunDynamicSlopes: slope has invalid type!"); + } + + if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { + slope->zdelta = FixedDiv(zdelta, slope->extent); + slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta); + P_CalculateSlopeNormal(slope); + } + } +} + +// +// P_MakeSlope +// +// Alocates and fill the contents of a slope structure. +// +static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, + const fixed_t zdelta, boolean dynamic) +{ + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + ret->o.x = o->x; + ret->o.y = o->y; + ret->o.z = o->z; + + ret->d.x = d->x; + ret->d.y = d->y; + + ret->zdelta = zdelta; + + if (dynamic) { // Add to the dynamic slopes list + ret->next = dynslopes; + dynslopes = ret; + } + + return ret; +} + +// +// P_GetExtent +// +// Returns the distance to the first line within the sector that +// is intersected by a line parallel to the plane normal with the point (ox, oy) +// +static fixed_t P_GetExtent(sector_t *sector, line_t *line) +{ + // ZDoom code reference: v3float_t = vertex_t + fixed_t fardist = -FRACUNIT; + size_t i; + + // Find furthest vertex from the reference line. It, along with the two ends + // of the line, will define the plane. + // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep + for(i = 0; i < sector->linecount; i++) + { + line_t *li = sector->lines[i]; + vertex_t tempv; + fixed_t dist; + + // Don't compare to the slope line. + if(li == line) + continue; + + P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y); + if(dist > fardist) + fardist = dist; + + // Okay, maybe do it for v2 as well? + P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y); + if(dist > fardist) + fardist = dist; + } + + return fardist; +} + + +// +// P_SpawnSlope_Line +// +// Creates one or more slopes based on the given line type and front/back +// sectors. +// Kalaron: Check if dynamic slopes need recalculation +// +void P_SpawnSlope_Line(int linenum) +{ + // With dynamic slopes, it's fine to just leave this function as normal, + // because checking to see if a slope had changed will waste more memory than + // if the slope was just updated when called + line_t *line = lines + linenum; + INT16 special = line->special; + pslope_t *fslope = NULL, *cslope = NULL; + vector3_t origin, point; + vector2_t direction; + fixed_t nx, ny, dz, extent; + + boolean frontfloor = (special == 700 || special == 702 || special == 703); + boolean backfloor = (special == 710 || special == 712 || special == 713); + boolean frontceil = (special == 701 || special == 702 || special == 713); + boolean backceil = (special == 711 || special == 712 || special == 703); + + if(!frontfloor && !backfloor && !frontceil && !backceil) + { + CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); + return; + } + + if(!line->frontsector || !line->backsector) + { + CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); + return; + } + + { + fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); + nx = FixedDiv(line->dy, len); + ny = -FixedDiv(line->dx, len); + } + + // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF + origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; + origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; + + // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! + if(frontfloor || frontceil) + { + line->frontsector->hasslope = true; // Tell the software renderer that we're sloped + + origin.z = line->backsector->floorheight; + direction.x = nx; + direction.y = ny; + + extent = P_GetExtent(line->frontsector, line); + + if(extent < 0) + { + CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); + direction.x = -direction.x; + direction.y = -direction.y; + + // TODO: We take origin and point 's xy values and translate them to the center of an FOF! + + if(frontfloor) + { + + point.z = line->frontsector->floorheight; // Startz + dz = FixedDiv(origin.z - point.z, extent); // Destinationz + + // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef + + fslope = line->frontsector->f_slope = + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 1; + + // Now remember that f_slope IS a vector + // fslope->o = origin 3D point 1 of the vector + // fslope->d = destination 3D point 2 of the vector + // fslope->normal is a 3D line perpendicular to the 3D vector + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + fslope->sourceline = line; + + // To find the real highz/lowz of a slope, you need to check all the vertexes + // in the slope's sector with P_GetZAt to get the REAL lowz & highz + // Although these slopes are set by floorheights the ANGLE is what a slope is, + // so technically any slope can extend on forever (they are just bound by sectors) + // *You can use sourceline as a reference to see if two slopes really are the same + + // Default points for high and low + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + + // Now check to see what the REAL high and low points of the slope inside the sector + // TODO: Is this really needed outside of FOFs? -Red + size_t l; + + for (l = 0; l < line->frontsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // Sets extra clipping data for the frontsector's slope + fslope->highz = highest; + fslope->lowz = lowest; + + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); + } + if(frontceil) + { + origin.z = line->backsector->ceilingheight; + point.z = line->frontsector->ceilingheight; + dz = FixedDiv(origin.z - point.z, extent); + + cslope = line->frontsector->c_slope = + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + + // Set up some shit + cslope->extent = extent; + cslope->refpos = 2; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + cslope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + size_t l; + + for (l = 0; l < line->frontsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the frontsector's slope + cslope->highz = highest; + cslope->lowz = lowest; + + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); + } + } + if(backfloor || backceil) + { + line->backsector->hasslope = true; // Tell the software renderer that we're sloped + + origin.z = line->frontsector->floorheight; + // Backsector + direction.x = -nx; + direction.y = -ny; + + extent = P_GetExtent(line->backsector, line); + + if(extent < 0) + { + CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); + direction.x = -direction.x; + direction.y = -direction.y; + + if(backfloor) + { + point.z = line->backsector->floorheight; + dz = FixedDiv(origin.z - point.z, extent); + + fslope = line->backsector->f_slope = + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 3; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + fslope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + size_t l; + + for (l = 0; l < line->backsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the frontsector's slope + fslope->highz = highest; + fslope->lowz = lowest; + + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); + } + if(backceil) + { + origin.z = line->frontsector->ceilingheight; + point.z = line->backsector->ceilingheight; + dz = FixedDiv(origin.z - point.z, extent); + + cslope = line->backsector->c_slope = + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + + // Set up some shit + cslope->extent = extent; + cslope->refpos = 4; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + cslope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + + size_t l; + + for (l = 0; l < line->backsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the backsector's slope + cslope->highz = highest; + cslope->lowz = lowest; + + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); + } + } + + if(!line->tag) + return; +} + + + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line) +{ + sector_t *fsec = line->frontsector; + int i, special = line->special; + + // Check for copy linedefs + for(i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + { + sector_t *srcsec = sectors + i; + + if((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope) + fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); + if((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope) + fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); + } + + fsec->hasslope = true; + + line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef +} + +#ifdef SPRINGCLEAN +#include "byteptr.h" + +#include "p_setup.h" +#include "p_local.h" + +//========================================================================== +// +// P_SetSlopesFromVertexHeights +// +//========================================================================== +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) +{ + mapthing_t *mt; + boolean vt_found = false; + size_t i, j, k, l, q; + + //size_t i; + //mapthing_t *mt; + char *data; + char *datastart; + + // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10 + // anything else seems to make a map not load properly, + // but this hard-coded value MUST have some reason for being what it is + size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short)); + mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL); + fixed_t x, y; + sector_t *sector; + // Spawn axis points first so they are + // at the front of the list for fast searching. + data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL); + mt = smapthings; + for (i = 0; i < snummapthings; i++, mt++) + { + mt->x = READINT16(data); + mt->y = READINT16(data); + mt->angle = READINT16(data); + mt->type = READINT16(data); + mt->options = READINT16(data); + // mt->z hasn't been set yet! + //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types + + //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!! + x = mt->x*FRACUNIT; + y = mt->y*FRACUNIT; + sector = R_PointInSubsector(x, y)->sector; + // Z for objects +#ifdef ESLOPE + if (sector->f_slope) + mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS); + else +#endif + mt->z = (short)(sector->floorheight>>FRACBITS); + + mt->z = mt->z + (mt->options >> ZSHIFT); + + if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ + { + for(l = 0; l < numvertexes; l++) + { + if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT) + { + if (mt->type == THING_VertexFloorZ) + { + vertexes[l].z = mt->z*FRACUNIT; + //I_Error("Z value: %i", vertexes[l].z/FRACUNIT); + + } + else + { + vertexes[l].z = mt->z*FRACUNIT; // celing floor + } + vt_found = true; + } + } + //mt->type = 0; // VPHYSICS: Dynamic slopes + + + + + + + if (vt_found) + { + for (k = 0; k < numsectors; k++) + { + sector_t *sec = §ors[k]; + if (sec->linecount != 3) continue; // only works with triangular sectors + + v3float_t vt1, vt2, vt3; // cross = ret->normalf + v3float_t vec1, vec2; + + int vi1, vi2, vi3; + + vi1 = (int)(sec->lines[0]->v1 - vertexes); + vi2 = (int)(sec->lines[0]->v2 - vertexes); + vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? + (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes); + + //if (vertexes[vi1].z) + // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT); + //if (vertexes[vi2].z) + // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT); + //if (vertexes[vi3].z) + // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT); + + //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z); + + //I_Error("%i, %i, %i", mt->x, mt->y, mt->z); + //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING); + + // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the + // triangle sector to setup the real vertex slopes + // Check for the vertexes of all sectors + for(q = 0; q < numvertexes; q++) + { + if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT) + { + //I_Error("yeah %i", vertexes[q].z); + P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING); +#if 0 + if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING); + else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV); + else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)) + P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1); + else +#endif + continue; + } + } + + vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x); + vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y); + vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x); + vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y); + vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x); + vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y); + + for(j = 0; j < 2; j++) + { + + fixed_t z3; + //I_Error("Lo hicimos"); + + vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight); + vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight); + z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height + vt3.z = FIXED_TO_FLOAT(z3); + + if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) + { + vec1.x = vt2.x - vt3.x; + vec1.y = vt2.y - vt3.y; + vec1.z = vt2.z - vt3.z; + + vec2.x = vt1.x - vt3.x; + vec2.y = vt1.y - vt3.y; + vec2.z = vt1.z - vt3.z; + } + else + { + vec1.x = vt1.x - vt3.x; + vec1.y = vt1.y - vt3.y; + vec1.z = vt1.z - vt3.z; + + vec2.x = vt2.x - vt3.x; + vec2.y = vt2.y - vt3.y; + vec2.z = vt2.z - vt3.z; + } + + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + { + M_CrossProduct3f(&ret->normalf, &vec1, &vec2); + + // Cross product length + float len = (float)sqrt(ret->normalf.x * ret->normalf.x + + ret->normalf.y * ret->normalf.y + + ret->normalf.z * ret->normalf.z); + + if (len == 0) + { + // Only happens when all vertices in this sector are on the same line. + // Let's just ignore this case. + //CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16)); + return; + } + // cross/len + ret->normalf.x /= len; + ret->normalf.y /= len; + ret->normalf.z /= len; + + // ZDoom cross = ret->normalf + // Fix backward normals + if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1)) + { + // cross = -cross + ret->normalf.x = -ret->normalf.x; + ret->normalf.y = -ret->normalf.x; + ret->normalf.z = -ret->normalf.x; + } + } + + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + + srcplane->a = FLOAT_TO_FIXED (ret->normalf.x); + srcplane->b = FLOAT_TO_FIXED (ret->normalf.y); + srcplane->c = FLOAT_TO_FIXED (ret->normalf.z); + //srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); + srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, + srcplane->b, vertexes[vi3].y, + srcplane->c, z3); + + if (j == 0) + { + sec->f_slope = ret; + sec->f_slope->secplane = *srcplane; + } + else if (j == 1) + { + sec->c_slope = ret; + sec->c_slope->secplane = *srcplane; + } + } + } + } + + + + + + + + + } + } + Z_Free(datastart); + + + + +} +#endif + +// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes +void P_ResetDynamicSlopes(void) { + size_t i; +#if 1 // Rewrite old specials to new ones, and give a console warning + boolean warned = false; +#endif + + dynslopes = NULL; + + // We'll handle copy slopes later, after all the tag lists have been made. + // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. + for (i = 0; i < numlines; i++) + { + switch (lines[i].special) + { +#if 1 // Rewrite old specials to new ones, and give a console warning +#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} + case 386: + case 387: + case 388: + lines[i].special += 700-386; + WARNME + P_SpawnSlope_Line(i); + break; + + case 389: + case 390: + case 391: + case 392: + lines[i].special += 710-389; + WARNME + P_SpawnSlope_Line(i); + break; + + case 393: + lines[i].special = 703; + WARNME + P_SpawnSlope_Line(i); + break; + + case 394: + case 395: + case 396: + lines[i].special += 720-394; + WARNME + break; + +#endif + + case 700: + case 701: + case 702: + case 703: + case 710: + case 711: + case 712: + case 713: + P_SpawnSlope_Line(i); + break; + + default: + break; + } + } +} + + + + +// ============================================================================ +// +// Various utilities related to slopes +// + +// +// P_GetZAt +// +// Returns the height of the sloped plane at (x, y) as a fixed_t +// +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) +{ + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + + FixedMul(y - slope->o.y, slope->d.y); + + return slope->o.z + FixedMul(dist, slope->zdelta); +} + + +// +// P_QuantizeMomentumToSlope +// +// When given a vector, rotates it and aligns it to a slope +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) +{ + vector3_t axis; + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT); +} + +// +// P_SlopeLaunch +// +// Handles slope ejection for objects +void P_SlopeLaunch(mobj_t *mo) +{ + // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the + // vertical launch given from slopes while increasing the horizontal launch + // given. Good for SRB2's gravity and horizontal speeds. + vector3_t slopemom; + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = mo->momz*2; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + mo->momx = slopemom.x; + mo->momy = slopemom.y; + mo->momz = slopemom.z/2; + + //CONS_Printf("Launched off of slope.\n"); + mo->standingslope = NULL; +} + +// Function to help handle landing on slopes +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) +{ + vector3_t mom; + mom.x = thing->momx; + mom.y = thing->momy; + mom.z = thing->momz*2; + + //CONS_Printf("langing on slope\n"); + + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&mom, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + + if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope + thing->momx = mom.x; + thing->momy = mom.y; + thing->momz = -P_MobjFlip(thing); + + thing->standingslope = slope; + } +} + +// https://yourlogicalfallacyis.com/slippery-slope +// Handles sliding down slopes, like if they were made of butter :) +void P_ButteredSlope(mobj_t *mo) +{ + fixed_t thrust; + + if (!mo->standingslope) + return; + + if (mo->player) { + if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) + return; // Don't slide on non-steep slopes unless spinning + + if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy)) + return; // Allow the player to stand still on slopes below a certain steepness + } + + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + + if (mo->player && (mo->player->pflags & PF_SPINNING)) { + fixed_t mult = 0; + if (mo->momx || mo->momy) { + angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; + + if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) + angle ^= ANGLE_180; + + mult = FINECOSINE(angle >> ANGLETOFINESHIFT); + } + + //CONS_Printf("%d\n", mult); + + thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); + } + + if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed + thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); + // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down + + // Multiply by gravity + thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this + + P_Thrust(mo, mo->standingslope->xydirection, thrust); +} + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/p_slopes.h b/src/p_slopes.h new file mode 100644 index 0000000000000000000000000000000000000000..52988c18ff44064cb94a83a0603ec510899bec7d --- /dev/null +++ b/src/p_slopes.h @@ -0,0 +1,79 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// +//----------------------------------------------------------------------------- + +#ifndef P_SLOPES_H__ +#define P_SLOPES_H__ + +#ifdef ESLOPE +void P_ResetDynamicSlopes(void); +void P_RunDynamicSlopes(void); +// P_SpawnSlope_Line +// Creates one or more slopes based on the given line type and front/back +// sectors. +void P_SpawnSlope_Line(int linenum); + +#ifdef SPRINGCLEAN +// Loads just map objects that make slopes, +// terrain affecting objects have to be spawned first +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum); + +typedef enum +{ + THING_SlopeFloorPointLine = 9500, + THING_SlopeCeilingPointLine = 9501, + THING_SetFloorSlope = 9502, + THING_SetCeilingSlope = 9503, + THING_CopyFloorPlane = 9510, + THING_CopyCeilingPlane = 9511, + THING_VavoomFloor=1500, + THING_VavoomCeiling=1501, + THING_VertexFloorZ=1504, + THING_VertexCeilingZ=1505, +} slopething_e; +#endif + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line); + +// Returns the height of the sloped plane at (x, y) as a fixed_t +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); + +// Lots of physics-based bullshit +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); +void P_SlopeLaunch(mobj_t *mo); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); +void P_ButteredSlope(mobj_t *mo); + +#endif + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/p_spec.c b/src/p_spec.c index 8228c60b3e5e085276d9a0ca23a420798b5adbcb..694893502e503db48c978e0cd2dfb568763fb77f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1890,6 +1890,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 304 // Ring count - Once || specialtype == 307 // Character ability - Once || specialtype == 308 // Race only - Once + || specialtype == 313 // No More Enemies - Once || specialtype == 315 // No of pushables - Once || specialtype == 318 // Unlockable trigger - Once || specialtype == 320 // Unlockable - Once @@ -3364,6 +3365,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec) { ffloor_t *rover; + fixed_t top, bottom; if (!mo->player) // should NEVER happen return false; @@ -3380,6 +3382,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar //if (!(rover->flags & FF_EXISTS)) // return false; + top = P_GetSpecialTopZ(mo, sector, targetsec); + bottom = P_GetSpecialBottomZ(mo, sector, targetsec); + // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { @@ -3387,27 +3392,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top) return false; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(mo->eflags & MFE_VERTICALFLIP) - || mo->z + mo->height != *rover->bottomheight) + || mo->z + mo->height != bottom) return false; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top))) return false; } } else { // Water and intangible FOFs - if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight) + if (mo->z > top || (mo->z + mo->height) < bottom) return false; } @@ -3425,9 +3430,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) { if (mo->eflags & MFE_VERTICALFLIP) - return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING); + return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING); else - return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR); + return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR); } /** Applies a sector special to a player. @@ -4388,27 +4393,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight) + if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != *rover->bottomheight) + || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight))) + if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) + || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight) + if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } @@ -4518,6 +4523,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) { boolean nofloorneeded = false; + fixed_t f_affectpoint, c_affectpoint; if (!sector->special) // nothing special, exit return; @@ -4580,16 +4586,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } + f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector); + c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector); + // Only go further if on the ground - if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight) + if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) return; - if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight) + if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint) return; if ((sector->flags & SF_FLIPSPECIAL_BOTH) - && player->mo->z != sector->floorheight - && player->mo->z + player->mo->height != sector->ceilingheight) + && player->mo->z != f_affectpoint + && player->mo->z + player->mo->height != c_affectpoint) return; P_ProcessSpecialSector(player, sector, NULL); @@ -4750,6 +4759,9 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); + // Dynamic slopeness + P_RunDynamicSlopes(); + // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) { @@ -4893,6 +4905,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f ffloor->topyoffs = &sec2->ceiling_yoffs; ffloor->topangle = &sec2->ceilingpic_angle; +#ifdef ESLOPE + // Add slopes + ffloor->t_slope = &sec2->c_slope; + ffloor->b_slope = &sec2->f_slope; +#endif + if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only flags &= ~FF_BLOCKOTHERS; @@ -5326,6 +5344,7 @@ void T_LaserFlash(laserthink_t *flash) sector_t *sourcesec; ffloor_t *ffloor = flash->ffloor; sector_t *sector = flash->sector; + fixed_t top, bottom; if (!ffloor || !(ffloor->flags & FF_EXISTS)) return; @@ -5349,8 +5368,11 @@ void T_LaserFlash(laserthink_t *flash) && thing->flags & MF_BOSS) continue; // Don't hurt bosses - if (thing->z >= sourcesec->ceilingheight - || thing->z + thing->height <= sourcesec->floorheight) + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + + if (thing->z >= top + || thing->z + thing->height <= bottom) continue; if (thing->flags & MF_SHOOTABLE) @@ -6429,6 +6451,14 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].midmap = lines[i].frontsector->midmap; break; +#ifdef ESLOPE // Slope copy specials. Handled here for sanity. + case 720: + case 721: + case 722: + P_CopySectorSlope(&lines[i]); + break; +#endif + default: break; } @@ -6526,7 +6556,7 @@ static void P_DoScrollMove(mobj_t *thing, fixed_t dx, fixed_t dy, INT32 exclusiv thing->momy += dy; if (exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; } /** Processes an active scroller. @@ -6630,9 +6660,11 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) // Already pushed this tic by an exclusive pusher. + if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. continue; + height = P_GetSpecialBottomZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height { @@ -6650,9 +6682,11 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialBottomZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z > height))) { @@ -6689,9 +6723,11 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height { @@ -6709,9 +6745,11 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))) { @@ -7005,7 +7043,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 */ void T_Friction(friction_t *f) { - sector_t *sec; + sector_t *sec, *referrer; mobj_t *thing; msecnode_t *node; @@ -7014,7 +7052,7 @@ void T_Friction(friction_t *f) // Make sure the sector type hasn't changed if (f->roverfriction) { - sector_t *referrer = sectors + f->referrer; + referrer = sectors + f->referrer; if (!(GETSECSPECIAL(referrer->special, 3) == 1 || GETSECSPECIAL(referrer->special, 3) == 3)) @@ -7046,9 +7084,7 @@ void T_Friction(friction_t *f) { if (f->roverfriction) { - sector_t *referrer = §ors[f->referrer]; - - if (thing->floorz != referrer->ceilingheight) + if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec)) { node = node->m_snext; continue; @@ -7061,7 +7097,7 @@ void T_Friction(friction_t *f) thing->movefactor = f->movefactor; } } - else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? + else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) { thing->friction = f->friction; @@ -7192,7 +7228,7 @@ static pusher_t *tmpusher; // pusher structure for blockmap searches */ static inline boolean PIT_PushThing(mobj_t *thing) { - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) return false; if (thing->player && thing->player->pflags & PF_ROPEHANG) @@ -7322,7 +7358,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) } if (tmpusher->exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; return true; } @@ -7335,7 +7371,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) */ void T_Pusher(pusher_t *p) { - sector_t *sec; + sector_t *sec, *referrer; mobj_t *thing; msecnode_t *node; INT32 xspeed = 0,yspeed = 0; @@ -7344,7 +7380,6 @@ void T_Pusher(pusher_t *p) //INT32 ht = 0; boolean inFOF; boolean touching; - boolean foundfloor = false; boolean moved; xspeed = yspeed = 0; @@ -7356,19 +7391,16 @@ void T_Pusher(pusher_t *p) if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; + referrer = §ors[p->referrer]; - if (GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3) - foundfloor = true; + if (!(GETSECSPECIAL(referrer->special, 3) == 2 + || GETSECSPECIAL(referrer->special, 3) == 3)) + return; } else if (!(GETSECSPECIAL(sec->special, 3) == 2 || GETSECSPECIAL(sec->special, 3) == 3)) return; - if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK. - return; - // For constant pushers (wind/current) there are 3 situations: // // 1) Affected Thing is above the floor. @@ -7429,7 +7461,7 @@ void T_Pusher(pusher_t *p) || thing->type == MT_BIGTUMBLEWEED)) continue; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; if (thing->player && thing->player->pflags & PF_ROPEHANG) @@ -7443,41 +7475,38 @@ void T_Pusher(pusher_t *p) // Find the area that the 'thing' is in if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; - INT32 special; + fixed_t top, bottom; - special = GETSECSPECIAL(referrer->special, 3); - - if (!(special == 2 || special == 3)) - return; + top = P_GetSpecialTopZ(thing, referrer, sec); + bottom = P_GetSpecialBottomZ(thing, referrer, sec); if (thing->eflags & MFE_VERTICALFLIP) { - if (referrer->floorheight > thing->z + thing->height - || referrer->ceilingheight < (thing->z + (thing->height >> 1))) + if (bottom > thing->z + thing->height + || top < (thing->z + (thing->height >> 1))) continue; - if (thing->z < referrer->floorheight) + if (thing->z < bottom) touching = true; - if (thing->z + (thing->height >> 1) > referrer->floorheight) + if (thing->z + (thing->height >> 1) > bottom) inFOF = true; } else { - if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) + if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) continue; - if (thing->z + thing->height > referrer->ceilingheight) + if (thing->z + thing->height > top) touching = true; - if (thing->z + (thing->height >> 1) < referrer->ceilingheight) + if (thing->z + (thing->height >> 1) < top) inFOF = true; } } else // Treat the entire sector as one big FOF { - if (thing->z == thing->subsector->sector->floorheight) + if (thing->z == P_GetSpecialBottomZ(thing, sec, sec)) touching = true; else if (p->type != p_current) inFOF = true; @@ -7599,7 +7628,7 @@ void T_Pusher(pusher_t *p) } if (p->exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; } } } diff --git a/src/p_user.c b/src/p_user.c index 6844d2cba37560905f15a2ab13b99ab3df7e0081..d57d5cb99771b18adfeb100bfe62958197a15238 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1212,7 +1212,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) if (mo->eflags & MFE_VERTICALFLIP) { // Detect if the player is on the ceiling. - if (mo->z+mo->height >= sec->ceilingheight) + if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the bottom of a FOF. else @@ -1236,7 +1236,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z+mo->height == *rover->bottomheight) + if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec)) return true; } } @@ -1245,7 +1245,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) else { // Detect if the player is on the floor. - if (mo->z <= sec->floorheight) + if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the top of a FOF. else @@ -1269,7 +1269,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z == *rover->topheight) + if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec)) return true; } } @@ -1789,6 +1789,9 @@ static void P_CheckBouncySectors(player_t *player) fixed_t oldx; fixed_t oldy; fixed_t oldz; +#ifdef ESLOPE + vector3_t momentum; +#endif oldx = player->mo->x; oldy = player->mo->y; @@ -1809,16 +1812,21 @@ static void P_CheckBouncySectors(player_t *player) { ffloor_t *rover; boolean top = true; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (player->mo->z > *rover->topheight) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (player->mo->z > topheight) continue; - if (player->mo->z + player->mo->height < *rover->bottomheight) + if (player->mo->z + player->mo->height < bottomheight) continue; - if (oldz < *rover->topheight && oldz > *rover->bottomheight) + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) top = false; if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) @@ -1833,7 +1841,29 @@ static void P_CheckBouncySectors(player_t *player) { fixed_t newmom; +#ifdef ESLOPE + pslope_t *slope; + if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top + slope = *rover->t_slope; + } else { // Hit bottom + slope = *rover->b_slope; + } + + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; + + if (slope) { + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&momentum, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + } + + newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; +#else newmom = -FixedMul(player->mo->momz,linedist); +#endif if (abs(newmom) < (linedist*2)) { @@ -1856,7 +1886,18 @@ static void P_CheckBouncySectors(player_t *player) else if (newmom < -P_GetPlayerHeight(player)/2) newmom = -P_GetPlayerHeight(player)/2; +#ifdef ESLOPE + momentum.z = newmom*2; + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z/2; +#else player->mo->momz = newmom; +#endif if (player->pflags & PF_SPINNING) { @@ -2280,10 +2321,23 @@ static void P_DoClimbing(player_t *player) floorclimb = false; boostup = false; skyclimber = false; + fixed_t floorheight, ceilingheight; // ESLOPE + +#ifdef ESLOPE + floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) + : glidesector->sector->floorheight; + ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) + : glidesector->sector->ceilingheight; +#else + floorheight = glidesector->sector->floorheight; + ceilingheight = glidesector->sector->ceilingheight; +#endif if (glidesector->sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; // ESLOPE + for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) @@ -2291,13 +2345,21 @@ static void P_DoClimbing(player_t *player) floorclimb = true; +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; +#else + bottomheight = *rover->bottomheight; + topheight = *rover->topheight; +#endif + // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) { - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height) - && (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) - || ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z) - && (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height) + && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) + || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z) + && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) { if (cmd->forwardmove != 0) player->mo->momz += rover->master->frontsector->floorspeed; @@ -2313,8 +2375,9 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the bottom of the FOF - if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight)) + if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight)) { + fixed_t bottomheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2329,7 +2392,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; +#else + bottomheight2 = *roverbelow->bottomheight; +#endif + + if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2338,7 +2407,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->topheight <= player->mo->z) + if (topheight <= player->mo->z) { floorclimb = false; boostup = false; @@ -2346,7 +2415,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2356,8 +2425,9 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the bottom of a FOF - if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight)) + if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight)) { + fixed_t topheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2372,7 +2442,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; +#else + topheight2 = *roverbelow->topheight; +#endif + + if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2381,7 +2457,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->bottomheight >= player->mo->z + player->mo->height) + if (bottomheight >= player->mo->z + player->mo->height) { floorclimb = false; boostup = false; @@ -2389,7 +2465,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2410,7 +2486,7 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the upper texture area - if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight)) + if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight)) { boolean foundfof = false; floorclimb = true; @@ -2418,13 +2494,20 @@ static void P_DoClimbing(player_t *player) // Is there a FOF directly below that we can move onto? if (glidesector->sector->ffloors) { + fixed_t bottomheight; ffloor_t *rover; for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; +#else + bottomheight = *rover->bottomheight; +#endif + + if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2437,8 +2520,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2448,7 +2531,7 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the upper texture area - if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight)) + if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight)) { boolean foundfof = false; floorclimb = true; @@ -2462,7 +2545,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2475,7 +2558,7 @@ static void P_DoClimbing(player_t *player) } // Allow climbing from a FOF or lower texture onto the upper texture and vice versa. - if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = true; thrust = false; @@ -2483,8 +2566,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2493,14 +2576,14 @@ static void P_DoClimbing(player_t *player) } // Trying to climb on the sky - if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) + if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) { skyclimber = true; } // Climbing on the lower texture area? - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight)) { floorclimb = true; @@ -2516,8 +2599,8 @@ static void P_DoClimbing(player_t *player) } } // Climbing on the upper texture area? - else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight)) + else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight)) { floorclimb = true; @@ -2963,6 +3046,8 @@ static void P_DoTeeter(player_t *player) xh = (unsigned)(player->mo->x + player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT; xl = (unsigned)(player->mo->x - player->mo->radius - bmaporgx)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + // Polyobjects #ifdef POLYOBJECTS validcount++; @@ -3330,6 +3415,7 @@ firenormal: // static void P_DoSuperStuff(player_t *player) { + mobj_t *spark; ticcmd_t *cmd = &player->cmd; if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9]) return; // don't do anything right now, we're in the middle of transforming! @@ -3384,19 +3470,32 @@ static void P_DoSuperStuff(player_t *player) switch (player->skin) { case 1: // Golden orange supertails. - player->mo->color = SKINCOLOR_TSUPER1 + (leveltime/2) % 5; + if (leveltime % 9 < 5) + player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9; + else + player->mo->color = SKINCOLOR_TSUPER1 + 9 - leveltime % 9; break; case 2: // Pink superknux. - player->mo->color = SKINCOLOR_KSUPER1 + (leveltime/2) % 5; + if (leveltime % 9 < 5) + player->mo->color = SKINCOLOR_KSUPER1 + leveltime % 9; + else + player->mo->color = SKINCOLOR_KSUPER1 + 9 - leveltime % 9; break; default: // Yousa yellow now! - player->mo->color = SKINCOLOR_SUPER1 + (leveltime/2) % 5; + if (leveltime % 9 < 5) + player->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; + else + player->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9; break; } if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) - P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); + { + spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); + spark->destscale = player->mo->scale; + P_SetScale(spark, player->mo->scale); + } G_GhostAddColor(GHC_SUPER); @@ -3661,7 +3760,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting && !P_PlayerInPain(player)) // subsequent revs { - if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; @@ -3690,7 +3793,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) - && !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<<FRACBITS, player->mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale) +#ifdef ESLOPE + || (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); @@ -3702,7 +3809,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // Rolling normally if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) - && player->speed < FixedMul(5*FRACUNIT,player->mo->scale)) + && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); @@ -4406,12 +4517,16 @@ static void P_3dMovement(player_t *player) angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; -#ifndef OLD_MOVEMENT_CODE fixed_t oldMagnitude, newMagnitude; +#ifdef ESLOPE + vector3_t totalthrust; + + totalthrust.x = totalthrust.y = 0; // I forget if this is needed + totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes +#endif // ESLOPE // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); -#endif analogmove = P_AnalogMove(player); @@ -4588,17 +4703,10 @@ static void P_3dMovement(player_t *player) } movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mforward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mbackward && cmd->forwardmove > 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (!mforward && !mbackward) - P_Thrust(player->mo, movepushangle, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); #else P_Thrust(player->mo, movepushangle, movepushforward); #endif @@ -4617,33 +4725,12 @@ static void P_3dMovement(player_t *player) if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) { angle_t controldirection; -#ifdef OLD_MOVEMENT_CODE - angle_t controlplayerdirection; - boolean cforward; // controls pointing forward from the player - boolean cbackward; // controls pointing backward from the player - angle_t dangle; - cforward = cbackward = false; -#endif // Calculate the angle at which the controls are pointing // to figure out the proper mforward and mbackward. // (Why was it so complicated before? ~Red) controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; -#ifdef OLD_MOVEMENT_CODE - controlplayerdirection = player->mo->angle; - - dangle = controldirection - controlplayerdirection; - - if (dangle > ANGLE_180) //flip to keep to one side - dangle = InvAngle(dangle); - - if (dangle > ANGLE_90) - cbackward = true; // Controls pointing backwards from player - else - cforward = true; // Controls pointing in player's general direction -#endif - movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); // allow very small movement while in air for gameplay @@ -4666,13 +4753,10 @@ static void P_3dMovement(player_t *player) movepushsideangle = controldirection; movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mforward) && (cbackward)) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mbackward) && (cforward)) - P_Thrust(player->mo, controldirection, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward); #else P_Thrust(player->mo, controldirection, movepushforward); #endif @@ -4680,29 +4764,6 @@ static void P_3dMovement(player_t *player) } else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) { -#ifdef OLD_MOVEMENT_CODE - boolean mright = 0; - boolean mleft = 0; - angle_t sideangle; - - sideangle = player->mo->angle - ANGLE_90; - - // Monster Iestyn - 04-11-13 - // Quadrants are stupid, excessive and broken, let's do this a much simpler way! - // Get delta angle from rmom angle and player angle first - dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle; - if (dangle > ANGLE_180) - dangle = InvAngle(dangle); - - // now use it to determine direction! - if (dangle <= ANGLE_45) // angles 0-45 or 315-360 - mright = 1; // going right - else if (dangle >= ANGLE_135) // angles 135-225 - mleft = 1; // going left - - // anything else will leave both at 0, so no need to do anything else -#endif - movepushside = cmd->sidemove * (thrustfactor * acceleration); if (!onground) @@ -4725,19 +4786,37 @@ static void P_3dMovement(player_t *player) // Finally move the player now that his speed/direction has been decided. movepushside = FixedMul(movepushside, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mright && cmd->sidemove < 0) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mleft && cmd->sidemove > 0) - P_Thrust(player->mo, movepushsideangle, movepushside); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside); + totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside); #else P_Thrust(player->mo, movepushsideangle, movepushside); #endif } -#ifndef OLD_MOVEMENT_CODE +#ifdef ESLOPE + if ((totalthrust.x || totalthrust.y) + && player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { + // Factor thrust to slope, but only for the part pushing up it! + // The rest is unaffected. + angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; + + if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward + if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } else { // Direction goes up, so thrustangle needs to face away + if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } + } + + player->mo->momx += totalthrust.x; + player->mo->momy += totalthrust.y; +#endif + // Time to ask three questions: // 1) Are we over topspeed? // 2) If "yes" to 1, were we moving over topspeed to begin with? @@ -4771,7 +4850,6 @@ static void P_3dMovement(player_t *player) player->mo->momy = tempmomy + player->cmomy; } } -#endif } // @@ -7769,24 +7847,24 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle_t angle = 0, focusangle = 0, focusaiming = 0; fixed_t x, y, z, dist, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; INT32 camrotate; - boolean camstill, forceon = false, cameranoclip; + boolean camstill, cameranoclip; mobj_t *mo; subsector_t *newsubsec; fixed_t f1, f2; cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! - if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD) - forceon = true; - - if (!forceon && player->spectator) // force cam off for spectators - return true; + if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)) + { + if (player->spectator) // force cam off for spectators + return true; - if (!forceon && !cv_chasecam.value && thiscam == &camera) - return true; + if (!cv_chasecam.value && thiscam == &camera) + return true; - if (!forceon && !cv_chasecam2.value && thiscam == &camera2) - return true; + if (!cv_chasecam2.value && thiscam == &camera2) + return true; + } if (!thiscam->chase && !resetcalled) { @@ -8085,6 +8163,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; + BMBOUNDFIX(xl, xh, yl, yh); + for (by = yl; by <= yh; by++) for (bx = xl; bx <= xh; bx++) { @@ -9077,7 +9157,7 @@ void P_PlayerAfterThink(player_t *player) { ticcmd_t *cmd; INT32 oldweapon = player->currentweapon; - camera_t *thiscam; + camera_t *thiscam = NULL; // if not one of the displayed players, just don't bother #ifdef PARANOIA if (!player->mo) @@ -9091,7 +9171,7 @@ void P_PlayerAfterThink(player_t *player) if (splitscreen && player == &players[secondarydisplayplayer]) thiscam = &camera2; - else + else if (player == &players[displayplayer]) thiscam = &camera; if (player->playerstate == PST_DEAD) @@ -9099,7 +9179,7 @@ void P_PlayerAfterThink(player_t *player) // camera may still move when guy is dead //if (!netgame) { - if (((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer]) && thiscam->chase) + if (thiscam && thiscam->chase) P_MoveChaseCamera(player, thiscam, false); } return; @@ -9354,7 +9434,7 @@ void P_PlayerAfterThink(player_t *player) } } - if ((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer]) + if (thiscam) { if (!thiscam->chase) // bob view only if looking through the player's eyes { diff --git a/src/r_bsp.c b/src/r_bsp.c index e967e28cef3e194ebb5e43dcf652f9e2f91061e5..5474a4345f8a38f06299a2b387ac68183336490a 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line) doorclosed = 0; // Closed door. +#ifdef ESLOPE + // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than + // random renderer stopping around slopes... + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) { @@ -487,6 +492,10 @@ static void R_AddLine(seg_t *line) #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic +#ifdef ESLOPE + && backsector->f_slope == frontsector->f_slope + && backsector->c_slope == frontsector->c_slope +#endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! @@ -842,11 +851,19 @@ static void R_Subsector(size_t num) sub->sector->moved = frontsector->moved = false; } - light = R_GetPlaneLight(frontsector, frontsector->floorheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; floorcolormap = frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilingcolormap = frontsector->lightlist[light].extra_colormap; @@ -854,32 +871,52 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1 + if ((( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) < viewz || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef ESLOPE + , frontsector->f_slope +#endif + ); } else floorplane = NULL; - if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum + if ((( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL); + ceilingcolormap, NULL +#ifdef ESLOPE + , frontsector->c_slope +#endif + ); } else ceilingplane = NULL; numffloors = 0; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; if (frontsector->ffloors) { ffloor_t *rover; + fixed_t heightcheck; for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { @@ -897,18 +934,47 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; + + heightcheck = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; if (*rover->bottomheight <= frontsector->ceilingheight && *rover->bottomheight >= frontsector->floorheight - && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) { +#ifdef ESLOPE + light = R_GetPlaneLight(frontsector, + *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight, + viewz < heightcheck); +#else light = R_GetPlaneLight(frontsector, *rover->bottomheight, viewz < *rover->bottomheight); +#endif ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover); + *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , *rover->b_slope +#endif + ); + +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->b_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; - ffloor[numffloors].height = *rover->bottomheight; ffloor[numffloors].ffloor = rover; numffloors++; } @@ -916,16 +982,46 @@ static void R_Subsector(size_t num) break; ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; + + heightcheck = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; if (*rover->topheight >= frontsector->floorheight && *rover->topheight <= frontsector->ceilingheight - && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) { +#ifdef ESLOPE + light = R_GetPlaneLight(frontsector, + *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight, + viewz < heightcheck); +#else light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); +#endif ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - frontsector->lightlist[light].extra_colormap, rover); - ffloor[numffloors].height = *rover->topheight; + frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , *rover->t_slope +#endif + ); + +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->t_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; + ffloor[numffloors].ffloor = rover; numffloors++; } @@ -977,12 +1073,20 @@ static void R_Subsector(size_t num) polysec->lightlevel, xoff, yoff, polysec->floorpic_angle-po->angle, NULL, - NULL); - ffloor[numffloors].plane->polyobj = po; + NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); + //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; + po->visplane = ffloor[numffloors].plane; numffloors++; } @@ -1013,12 +1117,20 @@ static void R_Subsector(size_t num) light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL); - ffloor[numffloors].plane->polyobj = po; + NULL, NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); + //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; + po->visplane = ffloor[numffloors].plane; numffloors++; } @@ -1075,6 +1187,11 @@ void R_Prep3DFloors(sector_t *sector) fixed_t bestheight, maxheight; INT32 count, i, mapnum; sector_t *sec; +#ifdef ESLOPE + pslope_t *bestslope; + fixed_t heighttest; // I think it's better to check the Z height at the sector's center + // than assume unsloped heights are accurate indicators of order in sloped sectors. -Red +#endif count = 1; for (rover = sector->ffloors; rover; rover = rover->next) @@ -1097,7 +1214,13 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); +#ifdef ESLOPE + heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; + + sector->lightlist[0].height = heighttest + 1; +#else sector->lightlist[0].height = sector->ceilingheight + 1; +#endif sector->lightlist[0].lightlevel = §or->lightlevel; sector->lightlist[0].caster = NULL; sector->lightlist[0].extra_colormap = sector->extra_colormap; @@ -1115,6 +1238,29 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; +#ifdef ESLOPE + heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; + + if (heighttest > bestheight && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->t_slope; + continue; + } + if (rover->flags & FF_DOUBLESHADOW) { + heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; + + if (heighttest > bestheight + && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->b_slope; + continue; + } + } +#else if (*rover->topheight > bestheight && *rover->topheight < maxheight) { best = rover; @@ -1128,6 +1274,7 @@ void R_Prep3DFloors(sector_t *sector) bestheight = *rover->bottomheight; continue; } +#endif } if (!best) { @@ -1138,6 +1285,9 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].caster = best; sector->lightlist[i].flags = best->flags; +#ifdef ESLOPE + sector->lightlist[i].slope = bestslope; +#endif sec = §ors[best->secnum]; mapnum = sec->midmap; if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) @@ -1163,7 +1313,12 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { +#ifdef ESLOPE + heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; + if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red +#else if (bestheight == *best->bottomheight) +#endif { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].extra_colormap = diff --git a/src/r_defs.h b/src/r_defs.h index 7f8bd7e1d1ee6f99a7542adf8eb9aec392a7e3fe..9f35af7e5f2a7bc2ea3c49b30060d26836c4407e 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -155,6 +155,12 @@ typedef struct ffloor_s fixed_t *bottomyoffs; angle_t *bottomangle; +#ifdef ESLOPE + // Pointers to pointers. Yup. + struct pslope_s **t_slope; + struct pslope_s **b_slope; +#endif + size_t secnum; ffloortype_e flags; struct line_s *master; @@ -184,6 +190,9 @@ typedef struct lightlist_s extracolormap_t *extra_colormap; INT32 flags; ffloor_t *caster; +#ifdef ESLOPE + struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. +#endif } lightlist_t; @@ -224,6 +233,41 @@ typedef struct secplane_t fixed_t a, b, c, d, ic; } secplane_t; +// Kalaron Slopes +#ifdef ESLOPE + +typedef struct pslope_s +{ + // --- Information used in clipping/projection --- + // Origin vector for the plane + vector3_t o; + + // 2-Dimentional vector (x, y) normalized. Used to determine distance from + // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle) + vector2_t d; + + // The rate at which z changes based on distance from the origin plane. + fixed_t zdelta; + + // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red + vector3_t normal; + + // For comparing when a slope should be rendered + fixed_t lowz; + fixed_t highz; + + // This values only check and must be updated if the slope itself is modified + angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees) + angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) + + struct line_s *sourceline; // The line that generated the slope + fixed_t extent; // Distance value used for recalculating zdelta + UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) 0=disabled + + struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later +} pslope_t; +#endif + typedef enum { SF_FLIPSPECIAL_FLOOR = 1, @@ -337,6 +381,13 @@ typedef struct sector_s precipmobj_t *preciplist; struct mprecipsecnode_s *touching_preciplist; +#ifdef ESLOPE + // Eternity engine slope + pslope_t *f_slope; // floor slope + pslope_t *c_slope; // ceiling slope + boolean hasslope; // The sector, or one of its visible FOFs, contains a slope +#endif + // these are saved for netgames, so do not let Lua touch these! // offsets sector spawned with (via linedef type 7) @@ -612,6 +663,12 @@ typedef struct drawseg_s INT16 *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; + +#ifdef ESLOPE + fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures + + vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes +#endif } drawseg_t; typedef enum diff --git a/src/r_draw.c b/src/r_draw.c index cd219c15f624cf9726148ac6d42124f2f40eef99..766e0428e09844b2f32d96ca00d257c3a4bc8f23 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf, zeroheight; +#endif + /** \brief Variable flat sizes */ diff --git a/src/r_draw.h b/src/r_draw.h index 061a271b15be4d466d108b2b313f9e389a738792..e1818545b71ef8e25473dec8d91f2b04ae42c03a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -60,6 +60,16 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; +#ifdef ESLOPE +typedef struct { + float x, y, z; +} floatv3_t; + +pslope_t *ds_slope; // Current slope being used +floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf, zeroheight; +#endif + // Variable flat sizes extern UINT32 nflatxshift; extern UINT32 nflatyshift; @@ -141,6 +151,10 @@ void ASMCALL R_DrawSpan_8_MMX(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); +#ifdef ESLOPE +void R_DrawTiltedSpan_8(void); +void R_DrawTiltedTranslucentSpan_8(void); +#endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index e0264ba921a1b2ee3ec7824ba86ffe17a5a86db9..279690492c5a4ba6b7a59ab5030d939c5b0517f1 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -526,6 +526,297 @@ void R_DrawSpan_8 (void) } } +#ifdef ESLOPE +// R_CalcTiltedLighting +// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. +static size_t tiltlighting[MAXVIDWIDTH]; +void R_CalcTiltedLighting(fixed_t start, fixed_t end) +{ + // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version + // of this function. Here's my own. + INT32 left = ds_x1, right = ds_x2; + fixed_t step = (end-start)/(ds_x2-ds_x1+1); + size_t i; + + // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, + // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... + + for (i = left; i <= right; i++) { + tiltlighting[i] = (start += step) >> FRACBITS; + if (tiltlighting[i] < 0) + tiltlighting[i] = 0; + else if (tiltlighting[i] >= MAXLIGHTSCALE) + tiltlighting[i] = MAXLIGHTSCALE-1; + } +} + + +/** \brief The R_DrawTiltedSpan_8 function + Draw slopes! Holy sheit! +*/ +void R_DrawTiltedSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (UINT32)(uz*z) + viewx; + v = (UINT32)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (UINT32)(startu); + v = (UINT32)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + + +/** \brief The R_DrawTiltedTranslucentSpan_8 function + Like DrawTiltedSpan, but translucent +*/ +void R_DrawTiltedTranslucentSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (UINT32)(uz*z) + viewx; + v = (UINT32)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (UINT32)(startu); + v = (UINT32)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} +#endif // ESLOPE + /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ diff --git a/src/r_main.c b/src/r_main.c index ffd4d5d504c3b6c98e9c02894c41ec1ca0340d7c..127801598703014296efae0a08170b1adc329f15 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -527,6 +527,8 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(centerxfrac, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallengthf = FIXED_TO_FLOAT(focallength); + for (i = 0; i < FINEANGLES/2; i++) { if (FINETANGENT(i) > FRACUNIT*2) @@ -1026,34 +1028,31 @@ void R_SetupFrame(player_t *player, boolean skybox) { INT32 dy = 0; camera_t *thiscam; - boolean forcechase = false; + boolean chasecam = false; if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]) { thiscam = &camera2; + chasecam = (cv_chasecam2.value != 0); } else + { thiscam = &camera; + chasecam = (cv_chasecam.value != 0); + } if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD) - forcechase = true; + chasecam = true; // force chasecam on + else if (player->spectator) // no spectator chasecam + chasecam = false; // force chasecam off - if (!forcechase && player->spectator) // no spectator chasecam - thiscam->chase = false; - else if ((cv_chasecam.value || forcechase) && !player->spectator && thiscam == &camera && !thiscam->chase) + if (chasecam && !thiscam->chase) { - P_ResetCamera(player, &camera); + P_ResetCamera(player, thiscam); thiscam->chase = true; } - else if ((cv_chasecam2.value || forcechase) && !player->spectator && thiscam == &camera2 && !thiscam->chase) - { - P_ResetCamera(player, &camera2); - thiscam->chase = true; - } - else if (!(cv_chasecam.value || forcechase) && thiscam == &camera) - thiscam->chase = false; - else if (!(cv_chasecam2.value || forcechase) && thiscam == &camera2) + else if (!chasecam) thiscam->chase = false; viewsky = !skybox; @@ -1066,9 +1065,7 @@ void R_SetupFrame(player_t *player, boolean skybox) aimingangle = player->awayviewaiming; viewangle = viewmobj->angle; } - else if (!player->spectator && (forcechase - || (cv_chasecam.value && thiscam == &camera) - || (cv_chasecam2.value && thiscam == &camera2))) + else if (!player->spectator && chasecam) // use outside cam view { viewmobj = NULL; @@ -1105,8 +1102,7 @@ void R_SetupFrame(player_t *player, boolean skybox) viewplayer = player; - if ((forcechase || (cv_chasecam.value && thiscam == &camera) || (cv_chasecam2.value && thiscam == &camera2)) - && !player->awayviewtics && !player->spectator) + if (chasecam && !player->awayviewtics && !player->spectator) { viewx = thiscam->x; viewy = thiscam->y; diff --git a/src/r_plane.c b/src/r_plane.c index dcff25c1304fd45deba11b9845cdaa40f23c7658..6aae1e250b1d1b29e61a7b1503f9a6b15ec01e08 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -74,7 +74,7 @@ static INT32 spanstart[MAXVIDHEIGHT]; // // texture mapping // -static lighttable_t **planezlight; +lighttable_t **planezlight; static fixed_t planeheight; //added : 10-02-98: yslopetab is what yslope used to be, @@ -327,6 +327,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (pindex >= MAXLIGHTZ) pindex = MAXLIGHTZ - 1; +#ifdef ESLOPE + if (currentplane->slope) + ds_colormap = colormaps; + else +#endif ds_colormap = planezlight[pindex]; if (currentplane->extra_colormap) @@ -423,11 +428,18 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor) + ffloor_t *pfloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ) { visplane_t *check; unsigned hash; +#ifdef ESLOPE + if (slope); else // Don't mess with this right now if a slope is involved +#endif if (plangle != 0) { // Add the view offset, rotated by the plane angle. @@ -462,7 +474,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && xoff == check->xoffs && yoff == check->yoffs && planecolormap == check->extra_colormap && !pfloor && !check->ffloor && check->viewz == viewz - && check->viewangle == viewangle) + && check->viewangle == viewangle +#ifdef ESLOPE + && check->slope == slope +#endif + ) { return check; } @@ -485,6 +501,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES check->polyobj = NULL; #endif +#ifdef ESLOPE + check->slope = slope; +#endif memset(check->top, 0xff, sizeof (check->top)); memset(check->bottom, 0x00, sizeof (check->bottom)); @@ -551,6 +570,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->plangle = pl->plangle; #ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; +#endif +#ifdef ESLOPE + new_pl->slope = pl->slope; #endif pl = new_pl; pl->minx = start; @@ -842,6 +864,9 @@ void R_DrawSinglePlane(visplane_t *pl) } else light = (pl->lightlevel >> LIGHTSEGSHIFT); +#ifdef ESLOPE + if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later +#endif if (viewangle != pl->viewangle) { memset(cachedheight, 0, sizeof (cachedheight)); @@ -915,6 +940,97 @@ void R_DrawSinglePlane(visplane_t *pl) if (light < 0) light = 0; +#ifdef ESLOPE + if (pl->slope) { + // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! + // I copied ZDoom's code and adapted it to SRB2... -Red + floatv3_t p, m, n; + float ang; + float vx, vy, vz; + float fudge; + + xoffs &= ((1 << (32-nflatshiftup))-1); + yoffs &= ((1 << (32-nflatshiftup))-1); + + xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup); + + xoffs *= fudge; + yoffs /= fudge; + + vx = FIXED_TO_FLOAT(viewx+xoffs); + vy = FIXED_TO_FLOAT(viewy-yoffs); + vz = FIXED_TO_FLOAT(viewz); + + zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); + +#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180) + + // p is the texture origin in view space + // Don't add in the offsets at this stage, because doing so can result in + // errors if the flat is rotated. + ang = ANG2RAD(ANGLE_270 - viewangle); + p.x = vx * cos(ang) - vy * sin(ang); + p.z = vx * sin(ang) + vy * cos(ang); + p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, -xoffs, yoffs)) - vz; + + // m is the v direction vector in view space + ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle); + m.x = cos(ang); + m.z = sin(ang); + + // n is the u direction vector in view space + n.x = sin(ang); + n.z = -cos(ang); + + ang = ANG2RAD(pl->plangle); + m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang)))) - zeroheight; + n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang)))) - zeroheight; + + m.x /= fudge; + m.y /= fudge; + m.z /= fudge; + + n.x *= fudge; + n.y *= fudge; + n.z *= fudge; + + // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. +#define CROSS(d, v1, v2) \ + d.x = (v1.y * v2.z) - (v1.z * v2.y);\ + d.y = (v1.z * v2.x) - (v1.x * v2.z);\ + d.z = (v1.x * v2.y) - (v1.y * v2.x) + CROSS(ds_su, p, m); + CROSS(ds_sv, p, n); + CROSS(ds_sz, m, n); +#undef CROSS + + ds_su.z *= focallengthf; + ds_sv.z *= focallengthf; + ds_sz.z *= focallengthf; + + // Premultiply the texture vectors with the scale factors +#define SFMULT 65536.f*(1<<nflatshiftup) + ds_su.x *= SFMULT; + ds_su.y *= SFMULT; + ds_su.z *= SFMULT; + ds_sv.x *= SFMULT; + ds_sv.y *= SFMULT; + ds_sv.z *= SFMULT; +#undef SFMULT + + if (spanfunc == R_DrawTranslucentSpan_8) + spanfunc = R_DrawTiltedTranslucentSpan_8; + else + spanfunc = R_DrawTiltedSpan_8; + + planezlight = scalelight[light]; + } else +#endif // ESLOPE + planezlight = zlight[light]; // set the maximum value for unsigned diff --git a/src/r_plane.h b/src/r_plane.h index f3a7f573fe90c0201f944430953327f29c999e17..239723ed1d6316c33efa6a44ab97c719df330ea8 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -61,6 +61,9 @@ typedef struct visplane_s #ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; #endif +#ifdef ESLOPE + pslope_t *slope; +#endif } visplane_t; extern visplane_t *floorplane; @@ -79,6 +82,8 @@ extern fixed_t cachedxstep[MAXVIDHEIGHT]; extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t basexscale, baseyscale; +extern lighttable_t **planezlight; + extern fixed_t *yslope; extern fixed_t distscale[MAXVIDWIDTH]; @@ -91,7 +96,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor); + extracolormap_t *planecolormap, ffloor_t *ffloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); @@ -110,6 +119,14 @@ typedef struct planemgr_s INT16 f_clip[MAXVIDWIDTH]; INT16 c_clip[MAXVIDWIDTH]; +#ifdef ESLOPE + // For slope rendering; the height at the other end + fixed_t f_pos_slope; + fixed_t b_pos_slope; + + struct pslope_s *slope; +#endif + struct ffloor_s *ffloor; #ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; diff --git a/src/r_segs.c b/src/r_segs.c index 7467f532472ae35d9eca14373ee9faf95e2e7b45..2d41d702c2161e11a03406d843a59fc081e1d1da 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -50,12 +50,20 @@ static fixed_t rw_offset2; // for splats static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; +#ifdef ESLOPE +static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope +static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes +static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation +#endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; static INT16 *maskedtexturecol; +#ifdef ESLOPE +static fixed_t *maskedtextureheight = NULL; +#endif // ========================================================================== // R_Splats Wall Splats Drawer @@ -474,6 +482,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; } + +#ifndef ESLOPE if (curline->linedef->flags & ML_DONTPEGBOTTOM) { dc_texturemid = front->floorheight > back->floorheight @@ -492,12 +502,21 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times; else dc_texturemid -= (textureheight[texnum])*times; +#endif dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif // calculate lighting if (maskedtexturecol[dc_x] != INT16_MAX) { @@ -679,6 +698,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) r_lightlist_t *rlight; fixed_t lheight; line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + fixed_t top_frac, top_step, bottom_frac, bottom_step; +#endif void (*colfunc_2s) (column_t *); @@ -853,6 +876,34 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) column2s_length = textures[texnum]->height; } +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t left_top, right_top, left_bottom, right_bottom; + + left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight; + right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight; + left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight; + right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight; + + left_top -= viewz; + right_top -= viewz; + left_bottom -= viewz; + right_bottom -= viewz; + + top_frac = centeryfrac - FixedMul(left_top, ds->scale1); + bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1); + top_step = centeryfrac - FixedMul(right_top, ds->scale2); + bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2); + + top_step = (top_step-top_frac)/(ds->x2-ds->x1+1); + bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { @@ -868,8 +919,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 solid = 0; INT32 lighteffect = 0; +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif // SoM: If column is out of range, why bother with it?? if (windowbottom < topbounds || windowtop > bottombounds) @@ -1011,11 +1070,24 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) || ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale))) { spryscale += rw_scalestep; +#ifdef ESLOPE + top_frac += top_step; + bottom_frac += bottom_step; +#endif continue; } +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + dc_iscale = 0xffffffffu / (unsigned)spryscale; // draw the texture @@ -1061,6 +1133,7 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; + fixed_t oldtexturecolumn = -1; INT32 top; INT32 bottom; INT32 i; @@ -1197,6 +1270,17 @@ static void R_RenderSegLoop (void) // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + +#ifdef ESLOPE + if (oldtexturecolumn != -1) { + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + } + oldtexturecolumn = texturecolumn; +#endif + texturecolumn >>= FRACBITS; // texturecolumn and lighting are independent of wall tiers @@ -1345,6 +1429,14 @@ static void R_RenderSegLoop (void) // save texturecol // for backdrawing of masked mid texture maskedtexturecol[rw_x] = (INT16)texturecolumn; + +#ifdef ESLOPE + if (maskedtextureheight != NULL) { + maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + max(rw_midtexturemid, rw_midtextureback) : + min(rw_midtexturemid, rw_midtextureback)); + } +#endif } if (dc_numlights) @@ -1402,8 +1494,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) INT32 i, p; lightlist_t *light; r_lightlist_t *rlight; +#ifdef ESLOPE + vertex_t segleft, segright; + fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif static size_t maxdrawsegs = 0; + maskedtextureheight = NULL; + if (ds_p == drawsegs+maxdrawsegs) { size_t pos = ds_p - drawsegs; @@ -1502,8 +1600,80 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate texture boundaries // and decide if floor / ceiling marks are needed - worldtop = frontsector->ceilingheight - viewz; - worldbottom = frontsector->floorheight - viewz; +#ifdef ESLOPE + // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit + if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red + { + angle_t temp; + + // left + temp = xtoviewangle[start]+viewangle; + + { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + + // right + temp = xtoviewangle[stop]+viewangle; + + { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + } + + if (frontsector->c_slope) { + worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz; + worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldtopslope = +#else + { +#endif + worldtop = frontsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (frontsector->f_slope) { + worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; + worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldbottomslope = +#else + { +#endif + worldbottom = frontsector->floorheight - viewz; + } midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; @@ -1524,27 +1694,72 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; #endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif ffloor[i].f_pos = ffloor[i].height - viewz; } } +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; + + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + if (!backsector) { // single sided line midtexture = texturetranslation[sidedef->midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; - +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; + else + rw_midtexturemid = frontsector->ceilingheight; + } +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { +#ifdef ESLOPE + rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture]; + rw_midtextureslide = floorfrontslide; +#else vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; // bottom of texture at bottom rw_midtexturemid = vtop - viewz; +#endif } else { // top of texture at top rw_midtexturemid = worldtop; +#ifdef ESLOPE + rw_midtextureslide = ceilingfrontslide; +#endif } rw_midtexturemid += sidedef->rowoffset; @@ -1557,47 +1772,120 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line + +#ifdef ESLOPE + if (backsector->c_slope) { + worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; + worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldhighslope = +#else + { +#endif + worldhigh = backsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (backsector->f_slope) { + worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; + worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldlowslope = +#else + { +#endif + worldlow = backsector->floorheight - viewz; + } + + + // hack to allow height changes in outdoor areas + if (frontsector->ceilingpic == skyflatnum + && backsector->ceilingpic == skyflatnum) + { +#ifdef ESLOPE + worldtopslope = worldhighslope = +#endif + worldtop = worldhigh; + } + ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0; - if (frontsector->floorheight > backsector->floorheight) + if ( +#ifdef ESLOPE + worldbottomslope > worldlowslope || +#endif + worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; +#ifdef ESLOPE + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); +#else ds_p->bsilheight = frontsector->floorheight; +#endif } +#ifdef ESLOPE + else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) +#else else if (backsector->floorheight > viewz) +#endif { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; // ds_p->sprbottomclip = negonearray; } - if (frontsector->ceilingheight < backsector->ceilingheight) + if ( +#ifdef ESLOPE + worldtopslope < worldhighslope || +#endif + worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; +#ifdef ESLOPE + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); +#else ds_p->tsilheight = frontsector->ceilingheight; +#endif } +#ifdef ESLOPE + else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) +#else else if (backsector->ceilingheight < viewz) +#endif { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; // ds_p->sprtopclip = screenheightarray; } - if (backsector->ceilingheight <= frontsector->floorheight) +#ifdef ESLOPE + if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) +#else + if (worldhigh <= worldbottom) +#endif { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } - if (backsector->floorheight >= frontsector->ceilingheight) +#ifdef ESLOPE + if (worldlow >= worldtop && worldlowslope >= worldtopslope) +#else + if (worldlow >= worldtop) +#endif { ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; ds_p->silhouette |= SIL_TOP; } +#ifdef ESLOPE + // This causes issues with slopes. + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif //SoM: 3/25/2000: This code fixes an automap bug that didn't check // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. @@ -1616,17 +1904,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - worldhigh = backsector->ceilingheight - viewz; - worldlow = backsector->floorheight - viewz; - - // hack to allow height changes in outdoor areas - if (frontsector->ceilingpic == skyflatnum - && backsector->ceilingpic == skyflatnum) - { - worldtop = worldhigh; - } - if (worldlow != worldbottom +#ifdef ESLOPE + || worldlowslope != worldbottomslope + || backsector->f_slope != frontsector->f_slope +#endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1649,6 +1931,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (worldhigh != worldtop +#ifdef ESLOPE + || worldhighslope != worldtopslope + || backsector->c_slope != frontsector->c_slope +#endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1678,7 +1964,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // check TOP TEXTURE - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + ) { // top texture if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) @@ -1691,49 +1981,100 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!toptexture) //Second side has no texture, use the first side's instead. toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[def->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[def->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } else { toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } } // check BOTTOM TEXTURE - if (worldlow > worldbottom) //seulement si VISIBLE!!! + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + ) //seulement si VISIBLE!!! { // bottom texture bottomtexture = texturetranslation[sidedef->bottomtexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom // top of texture at top - rw_bottomtexturemid = worldtop; + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif } - else // top of texture at top + else { // top of texture at top rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } } rw_toptexturemid += sidedef->rowoffset; @@ -1745,6 +2086,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor_t *rover; ffloor_t *r2; fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif //markceiling = markfloor = true; maskedtexture = true; @@ -1752,8 +2099,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; lastopening += rw_stopx - rw_x; - lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight; - highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight; + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif if (frontsector->ffloors && backsector->ffloors) { @@ -1764,16 +2115,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = frontsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -1793,8 +2161,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -1811,16 +2195,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (!(rover->flags & FF_ALLSIDES)) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = backsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -1840,8 +2241,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -1858,11 +2275,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; +#endif + ds_p->thicksides[i] = rover; i++; } @@ -1873,12 +2300,27 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) continue; if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) continue; - if (rover->norender == leveltime) - continue; +#endif ds_p->thicksides[i] = rover; i++; @@ -1898,6 +2340,32 @@ void R_StoreWallRange(INT32 start, INT32 stop) else ds_p->maskedtexturecol = ds_p->thicksidecol; +#ifdef ESLOPE + maskedtextureheight = &(ds_p->maskedtextureheight[0]); // ???? + + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + maskedtexture = true; } } @@ -1950,13 +2418,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorheight >= viewz) + if (( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingheight <= viewz && + if (( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz && frontsector->ceilingpic != skyflatnum) { // below view plane @@ -1967,6 +2443,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; +#ifdef ESLOPE + worldtopslope >>= 4; + worldbottomslope >>= 4; +#endif topstep = -FixedMul (rw_scalestep, worldtop); topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); @@ -1974,6 +2454,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) bottomstep = -FixedMul (rw_scalestep,worldbottom); bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); +#ifdef ESLOPE + if (frontsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); + topstep = (topfracend-topfrac)/(stop-start+1); + } + if (frontsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); + bottomstep = (bottomfracend-bottomfrac)/(stop-start+1); + } +#endif + dc_numlights = 0; if (frontsector->numlights) @@ -1987,26 +2478,83 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = p = 0; i < dc_numlights; i++) { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); + rightheight = P_GetZAt(light->slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; +#endif + if (i != 0) { +#ifdef ESLOPE + if (leftheight < worldbottom && rightheight < worldbottomslope) + continue; + + if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) + continue; +#else if (light->height < frontsector->floorheight) continue; if (light->height > frontsector->ceilingheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; +#endif } +#ifdef ESLOPE + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1); +#else rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); +#endif rlight->flags = light->flags; if (light->caster && light->caster->flags & FF_SOLID) { +#ifdef ESLOPE + if (*light->caster->b_slope) { + leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); + rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = *light->caster->bottomheight; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; + + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1); + +#else rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); +#endif } rlight->lightlevel = *light->lightlevel; @@ -2027,8 +2575,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1); +#else ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif } } @@ -2036,22 +2590,51 @@ void R_StoreWallRange(INT32 start, INT32 stop) { worldhigh >>= 4; worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#endif - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope <= worldtopslope +#endif + ) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(stop-start+1); + } +#endif } - if (worldlow > worldbottom) + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope >= worldbottomslope +#endif + ) { pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(stop-start+1); + } +#endif } { ffloor_t * rover; i = 0; +#ifdef ESLOPE + fixed_t rovertest; + fixed_t planevistest; +#endif if (backsector->ffloors) { @@ -2062,6 +2645,52 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= backsector->ceilingheight && *rover->bottomheight >= backsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2073,8 +2702,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } + if (i >= MAXFFLOORS) break; + if (*rover->topheight >= backsector->floorheight && *rover->topheight <= backsector->ceilingheight && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2086,6 +2717,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } else if (frontsector && frontsector->ffloors) @@ -2097,6 +2729,53 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= frontsector->ceilingheight && *rover->bottomheight >= frontsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2121,6 +2800,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } #ifdef POLYOBJECTS_PLANES @@ -2137,6 +2817,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->floorheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); @@ -2153,6 +2836,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->ceilingheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); diff --git a/src/r_things.c b/src/r_things.c index 9a8b1319bd1ee226c5f238fae706233152d28483..3a38eb482238be4af7bfcf6ee565cb49b55a1dff 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -950,12 +950,22 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) for (i = 1; i < sector->numlights; i++) { - if (sector->lightlist[i].height >= sprite->gzt || !(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) + fixed_t testheight = sector->lightlist[i].height; + + if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; - if (sector->lightlist[i].height <= sprite->gz) + +#ifdef ESLOPE + if (sector->lightlist[i].slope) + testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); +#endif + + if (testheight >= sprite->gzt) + continue; + if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(sector->lightlist[i].height - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > vid.height) @@ -966,15 +976,15 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); sprite->cut |= SC_BOTTOM; - sprite->gz = sector->lightlist[i].height; + sprite->gz = testheight; newsprite->gzt = sprite->gz; sprite->sz = cutfrac; newsprite->szt = (INT16)(sprite->sz - 1); - if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz) - sprite->pz = newsprite->pzt = sector->lightlist[i].height; + if (testheight < sprite->pzt && testheight > sprite->pz) + sprite->pz = newsprite->pzt = testheight; else { newsprite->pz = newsprite->gz; @@ -1191,7 +1201,20 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) { INT32 lightnum; +#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! + light = thing->subsector->sector->numlights - 1; + + for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { + fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) + : thing->subsector->sector->lightlist[lightnum].height; + if (h <= gzt) { + light = lightnum - 1; + break; + } + } +#else light = R_GetPlaneLight(thing->subsector->sector, gzt, false); +#endif lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) @@ -1546,23 +1569,12 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // If a limit exists, handle things a tiny bit different. if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS)) { - if (!players[displayplayer].mo) - return; // Draw nothing if no player. - // todo: is this really the best option for this situation? - for (thing = sec->thinglist; thing; thing = thing->snext) { if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) continue; - approx_dist = P_AproxDistance( - players[displayplayer].mo->x - thing->x, - players[displayplayer].mo->y - thing->y); - - if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo) - approx_dist = P_AproxDistance( - players[secondarydisplayplayer].mo->x - thing->x, - players[secondarydisplayplayer].mo->y - thing->y); + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (approx_dist <= limit_dist) R_ProjectSprite(thing); @@ -1579,23 +1591,12 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // Someone seriously wants infinite draw distance for precipitation? if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { - if (!players[displayplayer].mo) - return; // Draw nothing if no player. - // todo: is this really the best option for this situation? - for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { if (precipthing->precipflags & PCF_INVISIBLE) continue; - approx_dist = P_AproxDistance( - players[displayplayer].mo->x - precipthing->x, - players[displayplayer].mo->y - precipthing->y); - - if (splitscreen && approx_dist > limit_dist && players[secondarydisplayplayer].mo) - approx_dist = P_AproxDistance( - players[secondarydisplayplayer].mo->x - precipthing->x, - players[secondarydisplayplayer].mo->y - precipthing->y); + approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); if (approx_dist <= limit_dist) R_ProjectPrecipitationSprite(precipthing); @@ -1704,6 +1705,19 @@ static void R_CreateDrawNodes(void) } if (ds->maskedtexturecol) { +#ifdef POLYOBJECTS_PLANES + // Check for a polyobject plane, but only if this is a front line + if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { + // Put it in! + + entry = R_CreateDrawNode(&nodehead); + entry->plane = ds->curline->polyseg->visplane; + entry->seg = ds; + ds->curline->polyseg->visplane->polyobj = ds->curline->polyseg; + ds->curline->polyseg->visplane = NULL; + } +#endif + entry = R_CreateDrawNode(&nodehead); entry->seg = ds; } @@ -1720,7 +1734,7 @@ static void R_CreateDrawNodes(void) plane = ds->ffloorplanes[p]; R_PlaneBounds(plane); - if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low) + if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low || plane->polyobj) { ds->ffloorplanes[p] = NULL; continue; @@ -1761,24 +1775,34 @@ static void R_CreateDrawNodes(void) { if (r2->plane) { + fixed_t planeobjectz, planecameraz; if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) continue; if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) continue; +#ifdef ESLOPE + // Effective height may be different for each comparison in the case of slopes + if (r2->plane->slope) { + planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); + planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); + } else +#endif + planeobjectz = planecameraz = r2->plane->height; + if (rover->mobjflags & MF_NOCLIPHEIGHT) { //Objects with NOCLIPHEIGHT can appear halfway in. - if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= r2->plane->height) + if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height) + if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } else { - if (r2->plane->height < viewz && rover->pz >= r2->plane->height) + if (planecameraz < viewz && rover->pz >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt <= r2->plane->height) + if (planecameraz > viewz && rover->pzt <= planeobjectz) continue; } @@ -1808,6 +1832,7 @@ static void R_CreateDrawNodes(void) } else if (r2->thickseg) { + fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -1818,9 +1843,25 @@ static void R_CreateDrawNodes(void) if (scale <= rover->scale) continue; - if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) || - (*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) || - (*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)) +#ifdef ESLOPE + if (*r2->ffloor->t_slope) { + topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); + topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); + } else +#endif + topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; + +#ifdef ESLOPE + if (*r2->ffloor->b_slope) { + botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); + botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); + } else +#endif + botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; + + if ((topplanecameraz > viewz && botplanecameraz < viewz) || + (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || + (botplanecameraz > viewz && rover->gz > botplaneobjectz)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -1831,7 +1872,7 @@ static void R_CreateDrawNodes(void) } else if (r2->seg) { -#ifdef POLYOBJECTS_PLANES +#if 0 //#ifdef POLYOBJECTS_PLANES if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) { // Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where // polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red @@ -2039,21 +2080,21 @@ void R_ClipSprites(void) if (spr->gzt <= ds->tsilheight) silhouette &= ~SIL_TOP; - if (silhouette == 1) + if (silhouette == SIL_BOTTOM) { // bottom sil for (x = r1; x <= r2; x++) if (spr->clipbot[x] == -2) spr->clipbot[x] = ds->sprbottomclip[x]; } - else if (silhouette == 2) + else if (silhouette == SIL_TOP) { // top sil for (x = r1; x <= r2; x++) if (spr->cliptop[x] == -2) spr->cliptop[x] = ds->sprtopclip[x]; } - else if (silhouette == 3) + else if (silhouette == (SIL_TOP|SIL_BOTTOM)) { // both for (x = r1; x <= r2; x++) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index b4eeeeb5fb1c0e778be6a6a16758e0c116d9ad53..b3fa5390c50a748d60e87920073f46f5c28ff117 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -39,8 +39,7 @@ set(SRB2_SDL2_HEADERS sdlmain.h ) -prepend_sources(SRB2_SDL2_SOURCES) -prepend_sources(SRB2_SDL2_HEADERS) +source_group("Interface Code" FILES ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS}) # Dependency find_package(SDL2) @@ -49,9 +48,22 @@ if(${SDL2_FOUND}) set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} + ${SRB2_CORE_RENDER_SOURCES} + ${SRB2_CORE_GAME_SOURCES} + ${SRB2_LUA_SOURCES} + ${SRB2_LUA_HEADERS} + ${SRB2_BLUA_SOURCES} + ${SRB2_BLUA_HEADERS} ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS} ) + + source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) + source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) + source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) + source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) + source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) + source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) if(${SRB2_CONFIG_HWRENDER}) set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} @@ -60,15 +72,9 @@ if(${SDL2_FOUND}) ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS} ) - endif() - if(${SRB2_CONFIG_HAVE_BLUA}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_LUA_SOURCES} - ${SRB2_LUA_HEADERS} - ${SRB2_BLUA_SOURCES} - ${SRB2_BLUA_HEADERS} - ) + source_group("Hardware" FILES ${SRB2_HWRENDER_SOURCES} ${SRB2_HWRENDER_HEADERS}) + source_group("Hardware\\OpenGL Renderer" FILES ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS}) endif() if(${SRB2_USEASM}) @@ -85,7 +91,6 @@ if(${SDL2_FOUND}) set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") endif() - endif() if(${CMAKE_SYSTEM} MATCHES Windows) @@ -94,39 +99,36 @@ if(${SDL2_FOUND}) ${CMAKE_SOURCE_DIR}/src/win32/Srb2win.rc ) endif() - if(NOT CLANG) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${CMAKE_SOURCE_DIR}/src/string.c - ) - endif() if(${CMAKE_SYSTEM} MATCHES Darwin) set(MACOSX_BUNDLE_ICON_FILE Srb2mac.icns) set_source_files_properties(macosx/Srb2mac.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} + set(SRB2_SDL2_MAC_SOURCES macosx/mac_alert.c macosx/mac_alert.h macosx/mac_resources.c macosx/mac_resources.h macosx/Srb2mac.icns ) + source_group("Interface Code\\OSX Compatibility" FILES ${SRB2_SDL2_MAC_SOURCES}) + set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} ${SRB2_SDL2_MAC_SOURCES}) endif() + add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME}) + if(CLANG) - add_executable(${SRB2_SDL2_EXE_NAME} MACOSX_BUNDLE ${SRB2_SDL2_TOTAL_SOURCES}) - add_framework(CoreFoundation ${SRB2_SDL2_EXE_NAME}) - add_framework(SDL2 ${SRB2_SDL2_EXE_NAME}) - add_framework(SDL2_mixer ${SRB2_SDL2_EXE_NAME}) - target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE + add_framework(CoreFoundation SRB2SDL2) + add_framework(SDL2 SRB2SDL2) + add_framework(SDL2_mixer SRB2SDL2) + target_link_libraries(SRB2SDL2 PRIVATE ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} ) - set_target_properties(${SRB2_SDL2_EXE_NAME} PROPERTIES OUTPUT_NAME "Sonic Robo Blast 2") + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "Sonic Robo Blast 2") else() - add_executable(${SRB2_SDL2_EXE_NAME} WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) - - target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE + target_link_libraries(SRB2SDL2 PRIVATE ${SDL2_LIBRARIES} ${SDL2_MIXER_LIBRARIES} ${PNG_LIBRARIES} @@ -135,14 +137,15 @@ if(${SDL2_FOUND}) ) if(${CMAKE_SYSTEM} MATCHES Linux) - target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE + target_link_libraries(SRB2SDL2 PRIVATE m rt ) endif() - endif() + #target_link_libraries(SRB2SDL2 PRIVATE SRB2Core) + if(${SRB2_USEASM}) if(${SRB2_CONFIG_YASM}) set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER}) @@ -159,7 +162,7 @@ if(${SDL2_FOUND}) foreach(ASMFILE ${SRB2_NASM_SOURCES}) get_filename_component(ASMFILE_NAME ${ASMFILE} NAME_WE) set(ASMFILE_NAME ${ASMFILE_NAME}.obj) - add_custom_command(TARGET ${SRB2_SDL2_EXE_NAME} PRE_LINK + add_custom_command(TARGET SRB2SDL2 PRE_LINK COMMAND ${ASM_ASSEMBLER_TEMP} ARGS -f ${ASM_ASSEMBLER_OBJFORMAT} -o ${CMAKE_CURRENT_BINARY_DIR}/${ASMFILE_NAME} ${ASMFILE} COMMENT "assemble ${ASMFILE_NAME}." ) @@ -167,23 +170,23 @@ if(${SDL2_FOUND}) endif() endif() - set_target_properties(${SRB2_SDL2_EXE_NAME} PROPERTIES VERSION ${SRB2_VERSION}) + set_target_properties(SRB2SDL2 PROPERTIES VERSION ${SRB2_VERSION}) if(${CMAKE_SYSTEM} MATCHES Windows) - target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE + target_link_libraries(SRB2SDL2 PRIVATE ws2_32 ) - target_compile_options(${SRB2_SDL2_EXE_NAME} PRIVATE + target_compile_options(SRB2SDL2 PRIVATE -U_WINDOWS ) endif() if(MSVC) find_package(SDL2_MAIN REQUIRED) - target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE + target_link_libraries(SRB2SDL2 PRIVATE ${SDL2_MAIN_LIBRARIES} ) - target_compile_options(${SRB2_SDL2_EXE_NAME} PRIVATE + target_compile_options(SRB2SDL2 PRIVATE /Umain /D_CRT_SECURE_NO_WARNINGS # something about string functions. /D_CRT_NONSTDC_NO_DEPRECATE @@ -192,7 +195,7 @@ if(${SDL2_FOUND}) ) endif() - target_include_directories(${SRB2_SDL2_EXE_NAME} PRIVATE + target_include_directories(SRB2SDL2 PRIVATE ${SDL2_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} @@ -201,10 +204,10 @@ if(${SDL2_FOUND}) ) if(${SRB2_HAVE_MIXER}) - target_compile_definitions(${SRB2_SDL2_EXE_NAME} PRIVATE -DHAVE_MIXER -DSOUND=SOUND_MIXER) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXER -DSOUND=SOUND_MIXER) endif() - target_compile_definitions(${SRB2_SDL2_EXE_NAME} PRIVATE + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_SDL ) @@ -212,21 +215,21 @@ if(${SDL2_FOUND}) if(CMAKE_COMPILER_IS_GNUCC) if(${CMAKE_BUILD_TYPE} MATCHES Debug) message(STATUS "Will make separate debug symbols in *.debug") - add_custom_command(TARGET ${SRB2_SDL2_EXE_NAME} POST_BUILD - COMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}> $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}>.debug - COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}> - COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE_NAME:${SRB2_SDL2_EXE_NAME}>.debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}> + add_custom_command(TARGET SRB2SDL2 POST_BUILD + COMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug + COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:SRB2SDL2> + COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE_NAME:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2> ) endif() endif() #### Installation #### if (CLANG) - install(TARGETS ${SRB2_SDL2_EXE_NAME} + install(TARGETS SRB2SDL2 BUNDLE DESTINATION . ) else() - install(TARGETS ${SRB2_SDL2_EXE_NAME} ${SRB2_SDL2_EXE_NAME} + install(TARGETS SRB2SDL2 SRB2SDL2 RUNTIME DESTINATION . ) endif() @@ -257,10 +260,10 @@ if(${SDL2_FOUND}) # We also want to copy those DLLs to build directories on MSVC. # So we'll add a post_build step. - copy_files_to_build_dir(${SRB2_SDL2_EXE_NAME} win_extra_dll_list) + copy_files_to_build_dir(SRB2SDL2 win_extra_dll_list) endif() - + # Mac bundle fixup if(CLANG) install(CODE " @@ -271,6 +274,9 @@ if(${SDL2_FOUND}) )" ) endif() + + set(SRB2_SDL2_AVAILABLE YES PARENT_SCOPE) else() - message(WARNING "SDL2 wasn't found, so ${SRB2_SDL2_EXE_NAME} won't be available") -endif() + message(WARNING "SDL2 was not found, so the SDL2 target will not be available.") + set(SRB2_SDL2_AVAILABLE NO PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/src/sdl/SDL_icon.xpm b/src/sdl/SDL_icon.xpm index 70bb02d3c97a0ffe37a5e890c4736386779bcbb1..cf72960dfc9048d1ab23b3c59ed4d29d65f4c404 100644 --- a/src/sdl/SDL_icon.xpm +++ b/src/sdl/SDL_icon.xpm @@ -1,80 +1,425 @@ /* XPM */ -static const char * SDL_icon_xpm[] = { -"32 32 45 1", -" c None", -". c #6B6BFF", -"+ c #3D00B9", -"@ c #4848FF", -"# c #2525FF", -"$ c #310096", -"% c #003196", -"& c #003DB9", -"* c #620096", -"= c #6E6E6E", -"- c #966200", -"; c #250073", -"> c #626262", -", c #FF8F6B", -"' c #FFC66B", -") c #FFAB8E", -"! c #000080", -"~ c #B6B6B6", -"{ c #929292", -"] c #FFD48E", -"^ c #0000B9", -"/ c #565656", -"( c #868686", -"_ c #808080", -": c #C0C0C0", -"< c #DADADA", -"[ c #F2F2F2", -"} c #FFFFFF", -"| c #CECECE", -"1 c #AAAAAA", -"2 c #E6E6E6", -"3 c #000096", -"4 c #AB8EFF", -"5 c #190050", -"6 c #000000", -"7 c #8E8EFF", -"8 c #3E3E3E", -"9 c #7A7A7A", -"0 c #0E0E0E", -"a c #9E9E9E", -"b c #001950", -"c c #C2C2C2", -"d c #323232", -"e c #002573", -"f c #A0A0A4", -" ", -" ", -" ", -" .+@##@. ", -" @@.@#######@ ", -" @@....######### ", -" .. .@.....@+##$%%%&&% ", -" ..@# @@....@+#*=-;%%%%% ", -" ..@#@......@>,')!%%%$ ", -" ~..$#.........{])^#+%/ ", -" +##@.........()^@@@@@_ ", -" $####@........#=#######+ ", -" +######....@@##^#########_ ", -" +#####=:<<:+##############/ ", -"[<=####{<}}}}|###############= ", -" }1###=2}}}}}}.############### ", -" }<3#3~}}}}}}}4################ ", -" }<5#6:}}}}}}}7################/", -" }:6861}}}}}}}.########$$ 9 .@$", -" }:0a6~}}}}}}}@######5b ", -"22cd262}}}}}}2######5b$ ", -" 2>1a}}}}}}}{(*###%be## ", -" 860)1<[22c1)]]+##be### ", -" ~)]]]))))]]]]]=#bb#### ", -" )]]]]]]]]](]]=eb$#### ", -" :]]]]]]]]]'9bbb$##### ", -" ),'''''( >db+### ", -" =##f ", -" { ", -" ", -" ", -" "}; +static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = { +"32 32 390 2", +" c None", +". c #4F4F70", +"+ c #4D4D87", +"@ c #4D4D84", +"# c #4E4E6C", +"$ c #6C6C95", +"% c #5E5EB2", +"& c #6B6BE7", +"* c #7373F9", +"= c #7C7CFF", +"- c #6F70E7", +"; c #494BB2", +"> c #4F4FA3", +", c #6464D4", +"' c #7979F5", +") c #5F5FCA", +"! c #5D5D93", +"~ c #3A3A9F", +"{ c #6060AC", +"] c #777793", +"^ c #5C5CB3", +"/ c #7373EA", +"( c #7A7AFF", +"_ c #7575FF", +": c #7979FF", +"< c #6264DD", +"[ c #47478C", +"} c #564567", +"| c #4647D0", +"1 c #5C5CAE", +"2 c #5E5EFF", +"3 c #2929FF", +"4 c #1D1DFF", +"5 c #1919D1", +"6 c #4F4F90", +"7 c #1E1ECE", +"8 c #5858FF", +"9 c #6767A8", +"0 c #4949A0", +"a c #7070FB", +"b c #7D7DFF", +"c c #7777FF", +"d c #7373FF", +"e c #7272FF", +"f c #7878FF", +"g c #6465D8", +"h c #363886", +"i c #9F7655", +"j c #C89B5C", +"k c #1D1CB7", +"l c #3031B1", +"m c #1919F4", +"n c #1111FF", +"o c #1818FF", +"p c #1B1BFF", +"q c #1C1CFF", +"r c #2626B3", +"s c #1E1EC8", +"t c #1A1AE8", +"u c #24249F", +"v c #2F2FD2", +"w c #7676FF", +"x c #6869E2", +"y c #414290", +"z c #8C6751", +"A c #FCBA68", +"B c #E9BD7D", +"C c #201EB8", +"D c #090AB8", +"E c #1616EB", +"F c #1818FD", +"G c #1414EE", +"H c #1010E1", +"I c #0E0EE2", +"J c #0E0EF4", +"K c #0606B2", +"L c #7A7A89", +"M c #0C0C9A", +"N c #0A0AA7", +"O c #2424E4", +"P c #6669E6", +"Q c #4F4A8F", +"R c #BF853B", +"S c #FFD98D", +"T c #CDAB76", +"U c #1717C4", +"V c #0F10BA", +"W c #0909B6", +"X c #0505C3", +"Y c #0000B6", +"Z c #0000BE", +"` c #0000AD", +" . c #1D1D83", +".. c #63638E", +"+. c #090975", +"@. c #1414F3", +"#. c #5B5BFF", +"$. c #7B7BFF", +"%. c #7070FF", +"&. c #6E6EFF", +"*. c #7172F6", +"=. c #625DAF", +"-. c #BA9E6C", +";. c #887167", +">. c #090DF2", +",. c #1313BE", +"'. c #000085", +"). c #0000AC", +"!. c #0202AA", +"~. c #242488", +"{. c #1414C7", +"]. c #1717FF", +"^. c #5959FF", +"/. c #7F7FFF", +"(. c #7474FF", +"_. c #7171FF", +":. c #8686FF", +"<. c #7574FF", +"[. c #797CFF", +"}. c #5756B8", +"|. c #1C19A4", +"1. c #1617FF", +"2. c #1212BD", +"3. c #040485", +"4. c #0707A4", +"5. c #1B1B71", +"6. c #373797", +"7. c #1616FF", +"8. c #5050FF", +"9. c #8080FF", +"0. c #AAAAFF", +"a. c #AEAEF6", +"b. c #8A8AEF", +"c. c #6969FB", +"d. c #2728FF", +"e. c #1314FF", +"f. c #1919FF", +"g. c #1313E8", +"h. c #1F1FF4", +"i. c #5454FF", +"j. c #6D6DF0", +"k. c #6868B5", +"l. c #0B0BB8", +"m. c #1212C5", +"n. c #1616FC", +"o. c #1515FF", +"p. c #1212FF", +"q. c #2323FF", +"r. c #3636FF", +"s. c #4040FF", +"t. c #4343F9", +"u. c #5D5DB8", +"v. c #7F7F92", +"w. c #878793", +"x. c #4B4B94", +"y. c #0B0CE2", +"z. c #1313FF", +"A. c #4C4CFF", +"B. c #8282FF", +"C. c #7171ED", +"D. c #636394", +"E. c #575785", +"F. c #A9A99C", +"G. c #1414BC", +"H. c #1414FF", +"I. c #0707FD", +"J. c #2525AA", +"K. c #A8A8A4", +"L. c #EBEBE2", +"M. c #F9F9F2", +"N. c #E1E1CC", +"O. c #4D4D9F", +"P. c #0B0BF7", +"Q. c #2121FF", +"R. c #3232FF", +"S. c #5555FF", +"T. c #6161B4", +"U. c #B5B5B2", +"V. c #FFFFF8", +"W. c #4F4F9A", +"X. c #0B0BF5", +"Y. c #1616C5", +"Z. c #A8A8A1", +"`. c #FFFFFC", +" + c #FFFFFF", +".+ c #C0C0C4", +"++ c #1212D4", +"@+ c #4444FF", +"#+ c #6464FF", +"$+ c #8383FF", +"%+ c #6767C3", +"&+ c #E4E4E4", +"*+ c #9494AE", +"=+ c #0808DF", +"-+ c #0D0DF2", +";+ c #61619A", +">+ c #F1F1E0", +",+ c #E8E8DD", +"'+ c #2424BB", +")+ c #1010FF", +"!+ c #3434FF", +"~+ c #6161FF", +"{+ c #6969D2", +"]+ c #EFEFF0", +"^+ c #C2C2BA", +"/+ c #1010B6", +"(+ c #0909AC", +"_+ c #A4A49A", +":+ c #EAEADE", +"<+ c #2525B8", +"[+ c #2F2FFF", +"}+ c #3C3CB5", +"|+ c #EEEEEE", +"1+ c #BBBBAD", +"2+ c #0B0B56", +"3+ c #0B0BFC", +"4+ c #1212EF", +"5+ c #0C0C3E", +"6+ c #919187", +"7+ c #DEDED6", +"8+ c #1F1FC0", +"9+ c #1A1AFF", +"0+ c #1717FA", +"a+ c #1515F8", +"b+ c #1111FC", +"c+ c #494992", +"d+ c #999998", +"e+ c #3E3E3B", +"f+ c #3C3C99", +"g+ c #535397", +"h+ c #5A5A4D", +"i+ c #6F6F70", +"j+ c #BFBFC9", +"k+ c #1111D6", +"l+ c #1515F1", +"m+ c #0F0FE2", +"n+ c #0D0DD9", +"o+ c #0909CD", +"p+ c #0808C7", +"q+ c #0505C7", +"r+ c #0303CB", +"s+ c #0101C0", +"t+ c #0202AF", +"u+ c #0606AC", +"v+ c #121283", +"w+ c #BBBBBB", +"x+ c #BEBEBE", +"y+ c #2F2F2E", +"z+ c #C7C8BB", +"A+ c #D8DAD1", +"B+ c #272828", +"C+ c #929292", +"D+ c #8688C7", +"E+ c #0506F6", +"F+ c #1616F5", +"G+ c #0B0BD3", +"H+ c #0202B6", +"I+ c #0000AF", +"J+ c #0000B4", +"K+ c #0000BD", +"L+ c #0000BB", +"M+ c #00009E", +"N+ c #2C2C7E", +"O+ c #6A6A8B", +"P+ c #959595", +"Q+ c #F0F0F1", +"R+ c #E1E1E1", +"S+ c #8C8E90", +"T+ c #BEBEBF", +"U+ c #C9C7C5", +"V+ c #939699", +"W+ c #E7EAED", +"X+ c #CBCBC7", +"Y+ c #413B9B", +"Z+ c #0607DD", +"`+ c #0C0CE2", +" @ c #0303B9", +".@ c #0000A8", +"+@ c #181888", +"@@ c #6A6A6A", +"#@ c #626263", +"$@ c #4B4B4C", +"%@ c #3E3B36", +"&@ c #9B805C", +"*@ c #D9B07D", +"=@ c #C9AE89", +"-@ c #B9AF9E", +";@ c #C7C5C4", +">@ c #CBCCCF", +",@ c #C7C6C6", +"'@ c #AEA59A", +")@ c #B69974", +"!@ c #D8B87F", +"~@ c #9B8272", +"{@ c #0E0B9B", +"]@ c #0000B7", +"^@ c #0000B8", +"/@ c #000082", +"(@ c #00007A", +"_@ c #636379", +":@ c #62533E", +"<@ c #B59B6C", +"[@ c #DEB07B", +"}@ c #FECC90", +"|@ c #FFCE92", +"1@ c #FEC98C", +"2@ c #F1BD82", +"3@ c #D1A979", +"4@ c #BC9E73", +"5@ c #CCA777", +"6@ c #EAB980", +"7@ c #FFCD90", +"8@ c #FFD595", +"9@ c #FDD782", +"0@ c #413678", +"a@ c #0000AE", +"b@ c #000077", +"c@ c #010193", +"d@ c #0C0CE4", +"e@ c #38389E", +"f@ c #EEC585", +"g@ c #FFDA9D", +"h@ c #FFC992", +"i@ c #FFC88F", +"j@ c #FFC990", +"k@ c #FFCE93", +"l@ c #FFD094", +"m@ c #FFCC92", +"n@ c #C9A174", +"o@ c #EDBD88", +"p@ c #FAD287", +"q@ c #3A2F7F", +"r@ c #0000BA", +"s@ c #0000B0", +"t@ c #0101B2", +"u@ c #1111ED", +"v@ c #1919C1", +"w@ c #95887C", +"x@ c #DCAC6E", +"y@ c #FFD393", +"z@ c #FFCD94", +"A@ c #FFCA93", +"B@ c #FFC991", +"C@ c #FFC78E", +"D@ c #FFCB91", +"E@ c #E0B581", +"F@ c #BB9A6F", +"G@ c #FFDC97", +"H@ c #C1A173", +"I@ c #0E0B9A", +"J@ c #0000B5", +"K@ c #0101B6", +"L@ c #1010E0", +"M@ c #1616EC", +"N@ c #A68156", +"O@ c #E7AC6B", +"P@ c #FFC582", +"Q@ c #FFCF8F", +"R@ c #FFD195", +"S@ c #FFD296", +"T@ c #FFD396", +"U@ c #FFD193", +"V@ c #FFD28F", +"W@ c #D2A96B", +"X@ c #2F2482", +"Y@ c #0000C1", +"Z@ c #0000C0", +"`@ c #0000BF", +" # c #0101BF", +".# c #1212F0", +"+# c #767698", +"@# c #9C866E", +"## c #A9865D", +"$# c #C0915D", +"%# c #C89760", +"&# c #C29360", +"*# c #AD8A61", +"=# c #9D8971", +"-# c #7F7A7A", +";# c #70708F", +"># c #6F6F91", +",# c #575788", +"'# c #464687", +")# c #2F2F87", +"!# c #15158F", +"~# c #0101A8", +"{# c #1313FB", +"]# c #57579F", +"^# c #343487", +"/# c #434388", +" ", +" ", +" ", +" . + @ # ", +" $ % & * = - ; > , ' ) ! ", +" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ", +" 7 8 9 0 a b c d e f g h i j k l m n o p q r ", +" s t u v _ f d d d w x y z A B C D E F G H I J K L ", +" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ", +" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ", +" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ", +" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ", +" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ", +" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ", +" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ", +" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ", +" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ", +" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ", +" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ", +" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ", +" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ", +" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ", +" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ", +" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ", +" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ", +" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ", +" @###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]# ", +" ^#/# ", +" ", +" ", +" ", +" "}; diff --git a/src/sdl/Srb2SDL.ico b/src/sdl/Srb2SDL.ico index 5ab791af37f815c0164e6053c34879ecf0c3fff0..700276fd4b9ac2810a6981eb054921f3708c702b 100644 Binary files a/src/sdl/Srb2SDL.ico and b/src/sdl/Srb2SDL.ico differ diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index fa09dc343cdea0e5e054a0dc6c6a2b102d58b429..66e1ece1863887f21f6b07678542da6fde715b75 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2759,8 +2759,8 @@ static const char *locateWad(void) if (isWadPathOk(returnWadPath)) return NULL; #endif - - + + #ifdef CMAKECONFIG #ifndef NDEBUG I_OutputMsg(","CMAKE_ASSETS_DIR); @@ -2771,7 +2771,7 @@ static const char *locateWad(void) } #endif #endif - + #ifdef __APPLE__ OSX_GetResourcesPath(returnWadPath); I_OutputMsg(",%s", returnWadPath); @@ -2779,7 +2779,7 @@ static const char *locateWad(void) { return returnWadPath; } - + #endif // examine default dirs diff --git a/src/sdl12/SDL_icon.xpm b/src/sdl12/SDL_icon.xpm index 70bb02d3c97a0ffe37a5e890c4736386779bcbb1..cf72960dfc9048d1ab23b3c59ed4d29d65f4c404 100644 --- a/src/sdl12/SDL_icon.xpm +++ b/src/sdl12/SDL_icon.xpm @@ -1,80 +1,425 @@ /* XPM */ -static const char * SDL_icon_xpm[] = { -"32 32 45 1", -" c None", -". c #6B6BFF", -"+ c #3D00B9", -"@ c #4848FF", -"# c #2525FF", -"$ c #310096", -"% c #003196", -"& c #003DB9", -"* c #620096", -"= c #6E6E6E", -"- c #966200", -"; c #250073", -"> c #626262", -", c #FF8F6B", -"' c #FFC66B", -") c #FFAB8E", -"! c #000080", -"~ c #B6B6B6", -"{ c #929292", -"] c #FFD48E", -"^ c #0000B9", -"/ c #565656", -"( c #868686", -"_ c #808080", -": c #C0C0C0", -"< c #DADADA", -"[ c #F2F2F2", -"} c #FFFFFF", -"| c #CECECE", -"1 c #AAAAAA", -"2 c #E6E6E6", -"3 c #000096", -"4 c #AB8EFF", -"5 c #190050", -"6 c #000000", -"7 c #8E8EFF", -"8 c #3E3E3E", -"9 c #7A7A7A", -"0 c #0E0E0E", -"a c #9E9E9E", -"b c #001950", -"c c #C2C2C2", -"d c #323232", -"e c #002573", -"f c #A0A0A4", -" ", -" ", -" ", -" .+@##@. ", -" @@.@#######@ ", -" @@....######### ", -" .. .@.....@+##$%%%&&% ", -" ..@# @@....@+#*=-;%%%%% ", -" ..@#@......@>,')!%%%$ ", -" ~..$#.........{])^#+%/ ", -" +##@.........()^@@@@@_ ", -" $####@........#=#######+ ", -" +######....@@##^#########_ ", -" +#####=:<<:+##############/ ", -"[<=####{<}}}}|###############= ", -" }1###=2}}}}}}.############### ", -" }<3#3~}}}}}}}4################ ", -" }<5#6:}}}}}}}7################/", -" }:6861}}}}}}}.########$$ 9 .@$", -" }:0a6~}}}}}}}@######5b ", -"22cd262}}}}}}2######5b$ ", -" 2>1a}}}}}}}{(*###%be## ", -" 860)1<[22c1)]]+##be### ", -" ~)]]]))))]]]]]=#bb#### ", -" )]]]]]]]]](]]=eb$#### ", -" :]]]]]]]]]'9bbb$##### ", -" ),'''''( >db+### ", -" =##f ", -" { ", -" ", -" ", -" "}; +static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = { +"32 32 390 2", +" c None", +". c #4F4F70", +"+ c #4D4D87", +"@ c #4D4D84", +"# c #4E4E6C", +"$ c #6C6C95", +"% c #5E5EB2", +"& c #6B6BE7", +"* c #7373F9", +"= c #7C7CFF", +"- c #6F70E7", +"; c #494BB2", +"> c #4F4FA3", +", c #6464D4", +"' c #7979F5", +") c #5F5FCA", +"! c #5D5D93", +"~ c #3A3A9F", +"{ c #6060AC", +"] c #777793", +"^ c #5C5CB3", +"/ c #7373EA", +"( c #7A7AFF", +"_ c #7575FF", +": c #7979FF", +"< c #6264DD", +"[ c #47478C", +"} c #564567", +"| c #4647D0", +"1 c #5C5CAE", +"2 c #5E5EFF", +"3 c #2929FF", +"4 c #1D1DFF", +"5 c #1919D1", +"6 c #4F4F90", +"7 c #1E1ECE", +"8 c #5858FF", +"9 c #6767A8", +"0 c #4949A0", +"a c #7070FB", +"b c #7D7DFF", +"c c #7777FF", +"d c #7373FF", +"e c #7272FF", +"f c #7878FF", +"g c #6465D8", +"h c #363886", +"i c #9F7655", +"j c #C89B5C", +"k c #1D1CB7", +"l c #3031B1", +"m c #1919F4", +"n c #1111FF", +"o c #1818FF", +"p c #1B1BFF", +"q c #1C1CFF", +"r c #2626B3", +"s c #1E1EC8", +"t c #1A1AE8", +"u c #24249F", +"v c #2F2FD2", +"w c #7676FF", +"x c #6869E2", +"y c #414290", +"z c #8C6751", +"A c #FCBA68", +"B c #E9BD7D", +"C c #201EB8", +"D c #090AB8", +"E c #1616EB", +"F c #1818FD", +"G c #1414EE", +"H c #1010E1", +"I c #0E0EE2", +"J c #0E0EF4", +"K c #0606B2", +"L c #7A7A89", +"M c #0C0C9A", +"N c #0A0AA7", +"O c #2424E4", +"P c #6669E6", +"Q c #4F4A8F", +"R c #BF853B", +"S c #FFD98D", +"T c #CDAB76", +"U c #1717C4", +"V c #0F10BA", +"W c #0909B6", +"X c #0505C3", +"Y c #0000B6", +"Z c #0000BE", +"` c #0000AD", +" . c #1D1D83", +".. c #63638E", +"+. c #090975", +"@. c #1414F3", +"#. c #5B5BFF", +"$. c #7B7BFF", +"%. c #7070FF", +"&. c #6E6EFF", +"*. c #7172F6", +"=. c #625DAF", +"-. c #BA9E6C", +";. c #887167", +">. c #090DF2", +",. c #1313BE", +"'. c #000085", +"). c #0000AC", +"!. c #0202AA", +"~. c #242488", +"{. c #1414C7", +"]. c #1717FF", +"^. c #5959FF", +"/. c #7F7FFF", +"(. c #7474FF", +"_. c #7171FF", +":. c #8686FF", +"<. c #7574FF", +"[. c #797CFF", +"}. c #5756B8", +"|. c #1C19A4", +"1. c #1617FF", +"2. c #1212BD", +"3. c #040485", +"4. c #0707A4", +"5. c #1B1B71", +"6. c #373797", +"7. c #1616FF", +"8. c #5050FF", +"9. c #8080FF", +"0. c #AAAAFF", +"a. c #AEAEF6", +"b. c #8A8AEF", +"c. c #6969FB", +"d. c #2728FF", +"e. c #1314FF", +"f. c #1919FF", +"g. c #1313E8", +"h. c #1F1FF4", +"i. c #5454FF", +"j. c #6D6DF0", +"k. c #6868B5", +"l. c #0B0BB8", +"m. c #1212C5", +"n. c #1616FC", +"o. c #1515FF", +"p. c #1212FF", +"q. c #2323FF", +"r. c #3636FF", +"s. c #4040FF", +"t. c #4343F9", +"u. c #5D5DB8", +"v. c #7F7F92", +"w. c #878793", +"x. c #4B4B94", +"y. c #0B0CE2", +"z. c #1313FF", +"A. c #4C4CFF", +"B. c #8282FF", +"C. c #7171ED", +"D. c #636394", +"E. c #575785", +"F. c #A9A99C", +"G. c #1414BC", +"H. c #1414FF", +"I. c #0707FD", +"J. c #2525AA", +"K. c #A8A8A4", +"L. c #EBEBE2", +"M. c #F9F9F2", +"N. c #E1E1CC", +"O. c #4D4D9F", +"P. c #0B0BF7", +"Q. c #2121FF", +"R. c #3232FF", +"S. c #5555FF", +"T. c #6161B4", +"U. c #B5B5B2", +"V. c #FFFFF8", +"W. c #4F4F9A", +"X. c #0B0BF5", +"Y. c #1616C5", +"Z. c #A8A8A1", +"`. c #FFFFFC", +" + c #FFFFFF", +".+ c #C0C0C4", +"++ c #1212D4", +"@+ c #4444FF", +"#+ c #6464FF", +"$+ c #8383FF", +"%+ c #6767C3", +"&+ c #E4E4E4", +"*+ c #9494AE", +"=+ c #0808DF", +"-+ c #0D0DF2", +";+ c #61619A", +">+ c #F1F1E0", +",+ c #E8E8DD", +"'+ c #2424BB", +")+ c #1010FF", +"!+ c #3434FF", +"~+ c #6161FF", +"{+ c #6969D2", +"]+ c #EFEFF0", +"^+ c #C2C2BA", +"/+ c #1010B6", +"(+ c #0909AC", +"_+ c #A4A49A", +":+ c #EAEADE", +"<+ c #2525B8", +"[+ c #2F2FFF", +"}+ c #3C3CB5", +"|+ c #EEEEEE", +"1+ c #BBBBAD", +"2+ c #0B0B56", +"3+ c #0B0BFC", +"4+ c #1212EF", +"5+ c #0C0C3E", +"6+ c #919187", +"7+ c #DEDED6", +"8+ c #1F1FC0", +"9+ c #1A1AFF", +"0+ c #1717FA", +"a+ c #1515F8", +"b+ c #1111FC", +"c+ c #494992", +"d+ c #999998", +"e+ c #3E3E3B", +"f+ c #3C3C99", +"g+ c #535397", +"h+ c #5A5A4D", +"i+ c #6F6F70", +"j+ c #BFBFC9", +"k+ c #1111D6", +"l+ c #1515F1", +"m+ c #0F0FE2", +"n+ c #0D0DD9", +"o+ c #0909CD", +"p+ c #0808C7", +"q+ c #0505C7", +"r+ c #0303CB", +"s+ c #0101C0", +"t+ c #0202AF", +"u+ c #0606AC", +"v+ c #121283", +"w+ c #BBBBBB", +"x+ c #BEBEBE", +"y+ c #2F2F2E", +"z+ c #C7C8BB", +"A+ c #D8DAD1", +"B+ c #272828", +"C+ c #929292", +"D+ c #8688C7", +"E+ c #0506F6", +"F+ c #1616F5", +"G+ c #0B0BD3", +"H+ c #0202B6", +"I+ c #0000AF", +"J+ c #0000B4", +"K+ c #0000BD", +"L+ c #0000BB", +"M+ c #00009E", +"N+ c #2C2C7E", +"O+ c #6A6A8B", +"P+ c #959595", +"Q+ c #F0F0F1", +"R+ c #E1E1E1", +"S+ c #8C8E90", +"T+ c #BEBEBF", +"U+ c #C9C7C5", +"V+ c #939699", +"W+ c #E7EAED", +"X+ c #CBCBC7", +"Y+ c #413B9B", +"Z+ c #0607DD", +"`+ c #0C0CE2", +" @ c #0303B9", +".@ c #0000A8", +"+@ c #181888", +"@@ c #6A6A6A", +"#@ c #626263", +"$@ c #4B4B4C", +"%@ c #3E3B36", +"&@ c #9B805C", +"*@ c #D9B07D", +"=@ c #C9AE89", +"-@ c #B9AF9E", +";@ c #C7C5C4", +">@ c #CBCCCF", +",@ c #C7C6C6", +"'@ c #AEA59A", +")@ c #B69974", +"!@ c #D8B87F", +"~@ c #9B8272", +"{@ c #0E0B9B", +"]@ c #0000B7", +"^@ c #0000B8", +"/@ c #000082", +"(@ c #00007A", +"_@ c #636379", +":@ c #62533E", +"<@ c #B59B6C", +"[@ c #DEB07B", +"}@ c #FECC90", +"|@ c #FFCE92", +"1@ c #FEC98C", +"2@ c #F1BD82", +"3@ c #D1A979", +"4@ c #BC9E73", +"5@ c #CCA777", +"6@ c #EAB980", +"7@ c #FFCD90", +"8@ c #FFD595", +"9@ c #FDD782", +"0@ c #413678", +"a@ c #0000AE", +"b@ c #000077", +"c@ c #010193", +"d@ c #0C0CE4", +"e@ c #38389E", +"f@ c #EEC585", +"g@ c #FFDA9D", +"h@ c #FFC992", +"i@ c #FFC88F", +"j@ c #FFC990", +"k@ c #FFCE93", +"l@ c #FFD094", +"m@ c #FFCC92", +"n@ c #C9A174", +"o@ c #EDBD88", +"p@ c #FAD287", +"q@ c #3A2F7F", +"r@ c #0000BA", +"s@ c #0000B0", +"t@ c #0101B2", +"u@ c #1111ED", +"v@ c #1919C1", +"w@ c #95887C", +"x@ c #DCAC6E", +"y@ c #FFD393", +"z@ c #FFCD94", +"A@ c #FFCA93", +"B@ c #FFC991", +"C@ c #FFC78E", +"D@ c #FFCB91", +"E@ c #E0B581", +"F@ c #BB9A6F", +"G@ c #FFDC97", +"H@ c #C1A173", +"I@ c #0E0B9A", +"J@ c #0000B5", +"K@ c #0101B6", +"L@ c #1010E0", +"M@ c #1616EC", +"N@ c #A68156", +"O@ c #E7AC6B", +"P@ c #FFC582", +"Q@ c #FFCF8F", +"R@ c #FFD195", +"S@ c #FFD296", +"T@ c #FFD396", +"U@ c #FFD193", +"V@ c #FFD28F", +"W@ c #D2A96B", +"X@ c #2F2482", +"Y@ c #0000C1", +"Z@ c #0000C0", +"`@ c #0000BF", +" # c #0101BF", +".# c #1212F0", +"+# c #767698", +"@# c #9C866E", +"## c #A9865D", +"$# c #C0915D", +"%# c #C89760", +"&# c #C29360", +"*# c #AD8A61", +"=# c #9D8971", +"-# c #7F7A7A", +";# c #70708F", +"># c #6F6F91", +",# c #575788", +"'# c #464687", +")# c #2F2F87", +"!# c #15158F", +"~# c #0101A8", +"{# c #1313FB", +"]# c #57579F", +"^# c #343487", +"/# c #434388", +" ", +" ", +" ", +" . + @ # ", +" $ % & * = - ; > , ' ) ! ", +" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ", +" 7 8 9 0 a b c d e f g h i j k l m n o p q r ", +" s t u v _ f d d d w x y z A B C D E F G H I J K L ", +" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ", +" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ", +" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ", +" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ", +" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ", +" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ", +" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ", +" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ", +" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ", +" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ", +" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ", +" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ", +" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ", +" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ", +" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ", +" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ", +" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ", +" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ", +" @###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]# ", +" ^#/# ", +" ", +" ", +" ", +" "}; diff --git a/src/sdl12/Srb2SDL.ico b/src/sdl12/Srb2SDL.ico index 5ab791af37f815c0164e6053c34879ecf0c3fff0..700276fd4b9ac2810a6981eb054921f3708c702b 100644 Binary files a/src/sdl12/Srb2SDL.ico and b/src/sdl12/Srb2SDL.ico differ diff --git a/src/st_stuff.c b/src/st_stuff.c index a9bdacf7152f3a7683345ccd2ece8c0ed1b3e523..6e19b92ff05a3fe436c4e7ab5010ecb942ec12cf 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1590,7 +1590,7 @@ static void ST_drawSpecialStageHUD(void) if (sstimer) { V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT")); - ST_DrawNightsOverlayNum(SCX(hudinfo[HUD_TIMELEFTNUM].x), SCY(hudinfo[HUD_TIMELEFTNUM].y), V_HUDTRANS, sstimer/TICRATE, tallnum, SKINCOLOR_WHITE); + ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE); } else ST_DrawPatchFromHud(HUD_TIMEUP, timeup); diff --git a/src/tables.c b/src/tables.c index fa71effef44bd50761014a2db52580f672421f56..3ee2685c893117a419cc7bcc073f0b4d9e85af03 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2226,7 +2226,7 @@ angle_t tantoangle[2049] = }; -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, diff --git a/src/tables.h b/src/tables.h index 219d668b9dac5bb01af79de80adb7d5106de78bc..b1de1a428cae1a032bf3bf0652c10f9562266187 100644 --- a/src/tables.h +++ b/src/tables.h @@ -97,7 +97,7 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR /// The FixedAcos function FUNCMATH angle_t FixedAcos(fixed_t x); diff --git a/src/w_wad.c b/src/w_wad.c index 79ed1f478b67741dd625418e10ef1ece6813c556..9d6a11fb5c9f863def81c261a5893aa4aded98a8 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -413,6 +413,7 @@ UINT16 W_LoadWadFile(const char *filename) lump_p->disksize -= 4; } else lump_p->compressed = 0; + memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); } free(fileinfov); diff --git a/src/win32/CMakeLists.txt b/src/win32/CMakeLists.txt index 94c198299add6162c63a69324207ba048d73cf01..39b01588b28c622a65f40ea63f9b2e541df220ec 100644 --- a/src/win32/CMakeLists.txt +++ b/src/win32/CMakeLists.txt @@ -1,11 +1,18 @@ -add_executable(${SRB2_WIN_EXE_NAME} EXCLUDE_FROM_ALL - ${SRB2_CORE_SOURCES} - ${SRB2_CORE_HEADERS} - ${SRB2_LUA_SOURCES} - ${SRB2_LUA_HEADERS} - ${SRB2_BLUA_SOURCES} - ${SRB2_BLUA_HEADERS}) - -target_compile_definitions(${SRB2_WIN_EXE_NAME} PRIVATE +file(GLOB SRB2_WIN_SOURCES *.c *.h *.rc) + +if(${SRB2_CONFIG_HWRENDER}) + set(SRB2_WIN_SOURCES ${SRB2_WIN_SOURCES} ${SRB2_HWRENDER_SOURCES} ${SRB2_HWRENDER_HEADERS}) + set(SRB2_WIN_SOURCES ${SRB2_WIN_SOURCES} ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS}) +endif() + +add_executable(SRB2DD EXCLUDE_FROM_ALL WIN32 + ${SRB2_WIN_SOURCES} +) + +target_compile_definitions(SRB2DD PRIVATE -D_WINDOWS -) \ No newline at end of file +) + +set_target_properties(SRB2DD PROPERTIES OUTPUT_NAME ${SRB2_WIN_EXE_NAME}) + +target_link_libraries(SRB2DD PRIVATE SRB2Core) diff --git a/src/win32/Srb2win.ico b/src/win32/Srb2win.ico index e369735effcaec2be38a084c3ce7e89b94c9ee86..700276fd4b9ac2810a6981eb054921f3708c702b 100644 Binary files a/src/win32/Srb2win.ico and b/src/win32/Srb2win.ico differ diff --git a/src/win32ce/Srb2win.ico b/src/win32ce/Srb2win.ico index 0036a827a4625745397da1631e48101879a4f212..700276fd4b9ac2810a6981eb054921f3708c702b 100644 Binary files a/src/win32ce/Srb2win.ico and b/src/win32ce/Srb2win.ico differ