Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 622-teamlives-hud
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • alien-breed-3d
  • appveyor
  • bbox
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bosszero
  • bustablemobjzfix
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • cmake-clang-tidy
  • cmake-enable-cxx
  • cmake-valgrind
  • crawlacommander-sprites
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • few-kart-lua-changes
  • ffloorclip
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • flipfuncpointers
  • floorsprite-and-shadow-fake-planes-fix
  • fof-lightlist-fixes
  • font-FUCK
  • font_drawer
  • frictionrefactor
  • fuck-macros-1
  • fullscreen-toggle
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-packet-tics
  • increasemaxunlockables
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-command-netids
  • lua-local
  • lua-minmax-plus-bruh-moments
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • master
  • menu-edits
  • mobj-dispoffset
  • models-plus-final
  • more-cleanup
  • multithread
  • musicdef-lua
  • net-test
  • netcode-refactor
  • netcode-tests
  • netxcmd-refactor
  • next
  • next-test
  • next-test-2021-7-11
  • nextmapspecialoverride
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
139 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
117 results
Select Git revision
  • 1392-2-2-15-attempting-to-draw-a-hud-graphic-with-the-same-lump-name-as-a-lua-script-crashes-the
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results
Show changes
Commits on Source (18)
...@@ -154,8 +154,8 @@ HW3SOUND for 3D hardware sound support ...@@ -154,8 +154,8 @@ HW3SOUND for 3D hardware sound support
<Add directory="libs/gme/include" /> <Add directory="libs/gme/include" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="SDL" /> <Add library="SDL2" />
<Add library="SDL_mixer" /> <Add library="SDL2_mixer" />
<Add library="advapi32" /> <Add library="advapi32" />
<Add library="kernel32" /> <Add library="kernel32" />
<Add library="msvcrt" /> <Add library="msvcrt" />
...@@ -200,8 +200,8 @@ HW3SOUND for 3D hardware sound support ...@@ -200,8 +200,8 @@ HW3SOUND for 3D hardware sound support
<Add directory="libs/gme/include" /> <Add directory="libs/gme/include" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="SDL" /> <Add library="SDL2" />
<Add library="SDL_mixer" /> <Add library="SDL2_mixer" />
<Add library="advapi32" /> <Add library="advapi32" />
<Add library="kernel32" /> <Add library="kernel32" />
<Add library="msvcrt" /> <Add library="msvcrt" />
...@@ -4141,283 +4141,170 @@ HW3SOUND for 3D hardware sound support ...@@ -4141,283 +4141,170 @@ HW3SOUND for 3D hardware sound support
<Option target="Debug Mingw64/DirectX" /> <Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" /> <Option target="Release Mingw64/DirectX" />
</Unit> </Unit>
<Unit filename="src/sdl/IMG_xpm.c"> <Unit filename="src/sdl2/IMG_xpm.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/dosstr.c"> <Unit filename="src/sdl2/SDL_icon.xpm">
<Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/endtxt.c"> <Unit filename="src/sdl2/dosstr.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release 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="Debug Mingw/SDL" />
<Option target="Release 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>
<Unit filename="src/sdl/filter/filters.c"> <Unit filename="src/sdl2/endtxt.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/filter/filters.h"> <Unit filename="src/sdl2/endtxt.h">
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/filter/hq2x.c"> <Unit filename="src/sdl2/hwsym_sdl.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release 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="Debug Mingw/SDL" />
<Option target="Release 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>
<Unit filename="src/sdl/filter/interp.h"> <Unit filename="src/sdl2/hwsym_sdl.h">
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/filter/lq2x.c"> <Unit filename="src/sdl2/i_cdmus.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release 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="Debug Mingw/SDL" />
<Option target="Release 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>
<Unit filename="src/sdl/filter/main.c"> <Unit filename="src/sdl2/i_main.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/hwsym_sdl.c"> <Unit filename="src/sdl2/i_net.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release 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="Debug Mingw/SDL" />
<Option target="Release 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>
<Unit filename="src/sdl/i_cdmus.c"> <Unit filename="src/sdl2/i_system.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/i_main.c"> <Unit filename="src/sdl2/i_ttf.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/i_net.c"> <Unit filename="src/sdl2/i_ttf.h">
<Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/i_system.c"> <Unit filename="src/sdl2/i_video.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/i_video.c"> <Unit filename="src/sdl2/mixer_sound.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release 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="Debug Mingw/SDL" />
<Option target="Release 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>
<Unit filename="src/sdl/ogl_sdl.c"> <Unit filename="src/sdl2/ogl_sdl.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/ogl_sdl.h"> <Unit filename="src/sdl2/ogl_sdl.h">
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/sdl_sound.c"> <Unit filename="src/sdl2/sdl_sound.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" />
<Option target="Release Mingw64/SDL" />
<Option target="Debug Mingw/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sdl/sdlmain.h"> <Unit filename="src/sdl2/sdlmain.h">
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />
<Option target="Release 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="Debug Linux/SDL" />
<Option target="Release Linux/SDL" /> <Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" /> <Option target="Debug Mingw/SDL" />
<Option target="Release Mingw64/SDL" /> <Option target="Release Mingw/SDL" />
</Unit> </Unit>
<Unit filename="src/sounds.c"> <Unit filename="src/sounds.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
...@@ -4590,13 +4477,13 @@ HW3SOUND for 3D hardware sound support ...@@ -4590,13 +4477,13 @@ HW3SOUND for 3D hardware sound support
</Unit> </Unit>
<Unit filename="src/vid_copy.s"> <Unit filename="src/vid_copy.s">
<Option compilerVar="CC" /> <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_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="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="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="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="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="Debug Native/SDL" />
<Option target="Release Native/SDL" /> <Option target="Release Native/SDL" />
<Option target="Debug Linux/SDL" /> <Option target="Debug Linux/SDL" />
......
...@@ -27,7 +27,6 @@ find_library(SDL2_LIBRARY ...@@ -27,7 +27,6 @@ find_library(SDL2_LIBRARY
"/usr/local/lib" "/usr/local/lib"
) )
# set include dir variables # set include dir variables
set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR) set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR)
set(SDL2_PROCESS_LIBS SDL2_LIBRARY) set(SDL2_PROCESS_LIBS SDL2_LIBRARY)
......
...@@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES ...@@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES
p_saveg.c p_saveg.c
p_setup.c p_setup.c
p_sight.c p_sight.c
p_slopes.c
p_spec.c p_spec.c
p_telept.c p_telept.c
p_tick.c p_tick.c
...@@ -162,6 +163,7 @@ set(SRB2_CORE_GAME_SOURCES ...@@ -162,6 +163,7 @@ set(SRB2_CORE_GAME_SOURCES
p_pspr.h p_pspr.h
p_saveg.h p_saveg.h
p_setup.h p_setup.h
p_slopes.h
p_spec.h p_spec.h
p_tick.h p_tick.h
) )
......
...@@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \ ...@@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/p_telept.o \ $(OBJDIR)/p_telept.o \
$(OBJDIR)/p_tick.o \ $(OBJDIR)/p_tick.o \
$(OBJDIR)/p_user.o \ $(OBJDIR)/p_user.o \
$(OBJDIR)/p_slopes.o \
$(OBJDIR)/tables.o \ $(OBJDIR)/tables.o \
$(OBJDIR)/r_bsp.o \ $(OBJDIR)/r_bsp.o \
$(OBJDIR)/r_data.o \ $(OBJDIR)/r_data.o \
......
...@@ -11,6 +11,13 @@ ...@@ -11,6 +11,13 @@
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#ifdef _MSC_VER
#define INT32 __int32
#else
#include <stdint.h>
#define INT32 int32_t
#endif
/* /*
** ================================================================== ** ==================================================================
...@@ -140,7 +147,7 @@ ...@@ -140,7 +147,7 @@
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.) ** machines, ptrdiff_t gives a good choice between int or long.)
*/ */
#define LUA_INTEGER ptrdiff_t #define LUA_INTEGER INT32
/* /*
...@@ -502,13 +509,13 @@ ...@@ -502,13 +509,13 @@
*/ */
//#define LUA_NUMBER_DOUBLE //#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER ptrdiff_t #define LUA_NUMBER INT32
/* /*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number. @* over a number.
*/ */
#define LUAI_UACNUMBER ptrdiff_t #define LUAI_UACNUMBER INT32
/* /*
...@@ -519,14 +526,14 @@ ...@@ -519,14 +526,14 @@
@@ lua_str2number converts a string to a number. @@ lua_str2number converts a string to a number.
*/ */
#ifdef LUA_WIN #ifdef LUA_WIN
#define LUA_NUMBER_SCAN "%Ii" #define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%Ii" #define LUA_NUMBER_FMT "%d"
#else #else
#define LUA_NUMBER_SCAN "%ti" #define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%ti" #define LUA_NUMBER_FMT "%d"
#endif #endif
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ #define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */
#define lua_str2number(s,p) strtol((s), (p), 10) #define lua_str2number(s,p) strtol((s), (p), 10)
......
...@@ -96,6 +96,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); ...@@ -96,6 +96,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
#endif #endif
#ifdef HAVE_BLUA
#include "lua_script.h"
#endif
// platform independant focus loss // platform independant focus loss
UINT8 window_notinfocus = false; UINT8 window_notinfocus = false;
...@@ -634,6 +638,10 @@ void D_SRB2Loop(void) ...@@ -634,6 +638,10 @@ void D_SRB2Loop(void)
#ifdef HW3SOUND #ifdef HW3SOUND
HW3S_EndFrameUpdate(); HW3S_EndFrameUpdate();
#endif #endif
#ifdef HAVE_BLUA
LUA_Step();
#endif
} }
} }
...@@ -836,6 +844,10 @@ static void IdentifyVersion(void) ...@@ -836,6 +844,10 @@ static void IdentifyVersion(void)
// Add our crappy patches to fix our bugs // Add our crappy patches to fix our bugs
// D_AddFile(va(pandf,srb2waddir,"patch.dta")); // D_AddFile(va(pandf,srb2waddir,"patch.dta"));
// Add the thokker WAD
if (M_CheckParm("-nothokker") == 0)
D_AddFile(va(pandf,srb2waddir,"thokker.thk"));
#if !defined (HAVE_SDL) || defined (HAVE_MIXER) #if !defined (HAVE_SDL) || defined (HAVE_MIXER)
{ {
#if defined (DC) && 0 #if defined (DC) && 0
...@@ -943,9 +955,9 @@ void D_SRB2Main(void) ...@@ -943,9 +955,9 @@ void D_SRB2Main(void)
#endif #endif
#if defined (_WIN32_WCE) //|| defined (_DEBUG) || defined (GP2X) #if defined (_WIN32_WCE) //|| defined (_DEBUG) || defined (GP2X)
devparm = !M_CheckParm("-nodebug"); devparm = M_CheckParm("-nodebug") == 0;
#else #else
devparm = M_CheckParm("-debug"); devparm = M_CheckParm("-debug") != 0;
#endif #endif
// for dedicated server // for dedicated server
...@@ -1118,7 +1130,7 @@ void D_SRB2Main(void) ...@@ -1118,7 +1130,7 @@ void D_SRB2Main(void)
#endif #endif
D_CleanFile(); D_CleanFile();
#if 1 // md5s last updated 12/14/14 #ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files // Check MD5s of autoloaded files
W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "lua_hook.h" #include "lua_hook.h"
#include "m_cond.h" #include "m_cond.h"
#include "m_anigif.h" #include "m_anigif.h"
#include "m_argv.h"
#ifdef NETGAME_DEVMODE #ifdef NETGAME_DEVMODE
#define CV_RESTRICT CV_NETVAR #define CV_RESTRICT CV_NETVAR
...@@ -1618,7 +1619,10 @@ static void Command_Map_f(void) ...@@ -1618,7 +1619,10 @@ static void Command_Map_f(void)
// new gametype value // new gametype value
// use current one by default // use current one by default
i = COM_CheckParm("-gametype"); i = COM_CheckParm("-gametype");
if (i)
if (M_CheckParm("-nothokker") == 0)
newgametype = GT_TEAMMATCH;
else if (i)
{ {
if (!multiplayer) if (!multiplayer)
{ {
...@@ -3193,7 +3197,27 @@ static void Command_ModDetails_f(void) ...@@ -3193,7 +3197,27 @@ static void Command_ModDetails_f(void)
// //
static void Command_ShowGametype_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. /** Plays the intro.
...@@ -3351,8 +3375,13 @@ void D_GameTypeChanged(INT32 lastgametype) ...@@ -3351,8 +3375,13 @@ void D_GameTypeChanged(INT32 lastgametype)
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{ {
// default settings for match: timelimit 10 mins, no pointlimit // default settings for match: timelimit 10 mins, no pointlimit
CV_SetValue(&cv_pointlimit, 0); if (M_CheckParm("-nothokker") != 0) {
CV_SetValue(&cv_timelimit, 10); CV_SetValue(&cv_pointlimit, 0);
CV_SetValue(&cv_timelimit, 10);
} else {
CV_SetValue(&cv_pointlimit, 3);
CV_SetValue(&cv_timelimit, 0);
}
} }
if (!cv_itemrespawntime.changed) if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
......
...@@ -473,6 +473,7 @@ static void readPlayer(MYFILE *f, INT32 num) ...@@ -473,6 +473,7 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
PlayerMenu[num].status = IT_CALL;
for (i = 0; i < MAXLINELEN-3; i++) for (i = 0; i < MAXLINELEN-3; i++)
{ {
...@@ -545,6 +546,7 @@ static void readPlayer(MYFILE *f, INT32 num) ...@@ -545,6 +546,7 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
PlayerMenu[num].status = IT_CALL;
strncpy(description[num].picname, word2, 8); strncpy(description[num].picname, word2, 8);
} }
else if (fastcmp(word, "STATUS")) else if (fastcmp(word, "STATUS"))
...@@ -576,6 +578,8 @@ static void readPlayer(MYFILE *f, INT32 num) ...@@ -576,6 +578,8 @@ static void readPlayer(MYFILE *f, INT32 num)
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
PlayerMenu[num].status = IT_CALL;
strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
strlwr(description[num].skinname); strlwr(description[num].skinname);
} }
...@@ -1023,6 +1027,9 @@ static void readlevelheader(MYFILE *f, INT32 num) ...@@ -1023,6 +1027,9 @@ static void readlevelheader(MYFILE *f, INT32 num)
if (s == tmp) if (s == tmp)
continue; // Skip comment lines, but don't break. continue; // Skip comment lines, but don't break.
// Set / reset word, because some things (Lua.) move it
//word = s;
// Get the part before the " = " // Get the part before the " = "
tmp = strchr(s, '='); tmp = strchr(s, '=');
*(tmp-1) = '\0'; *(tmp-1) = '\0';
...@@ -3807,7 +3814,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit ...@@ -3807,7 +3814,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Blue Crawla // Blue Crawla
"S_POSS_STND", "S_POSS_STND",
"S_POSS_STND2",
"S_POSS_RUN1", "S_POSS_RUN1",
"S_POSS_RUN2", "S_POSS_RUN2",
"S_POSS_RUN3", "S_POSS_RUN3",
...@@ -3817,7 +3823,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit ...@@ -3817,7 +3823,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Red Crawla // Red Crawla
"S_SPOS_STND", "S_SPOS_STND",
"S_SPOS_STND2",
"S_SPOS_RUN1", "S_SPOS_RUN1",
"S_SPOS_RUN2", "S_SPOS_RUN2",
"S_SPOS_RUN3", "S_SPOS_RUN3",
...@@ -7172,7 +7177,6 @@ static const char *const MOBJFLAG2_LIST[] = { ...@@ -7172,7 +7177,6 @@ static const char *const MOBJFLAG2_LIST[] = {
"EXPLOSION", // Thrown ring has explosive properties "EXPLOSION", // Thrown ring has explosive properties
"SCATTER", // Thrown ring has scatter properties "SCATTER", // Thrown ring has scatter properties
"BEYONDTHEGRAVE",// Source of this missile has died and has since respawned. "BEYONDTHEGRAVE",// Source of this missile has died and has since respawned.
"PUSHED", // Mobj was already pushed this tic
"SLIDEPUSH", // MF_PUSHABLE that pushes continuously. "SLIDEPUSH", // MF_PUSHABLE that pushes continuously.
"CLASSICPUSH", // Drops straight down when object has negative Z. "CLASSICPUSH", // Drops straight down when object has negative Z.
"STANDONME", // While not pushable, stand on me anyway. "STANDONME", // While not pushable, stand on me anyway.
...@@ -7201,6 +7205,9 @@ static const char *const MOBJEFLAG_LIST[] = { ...@@ -7201,6 +7205,9 @@ static const char *const MOBJEFLAG_LIST[] = {
"JUSTSTEPPEDDOWN", // used for ramp sectors "JUSTSTEPPEDDOWN", // used for ramp sectors
"VERTICALFLIP", // Vertically flip sprite/allow upside-down physics "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics
"GOOWATER", // Goo water "GOOWATER", // Goo water
"PUSHED", // Mobj was already pushed this tic
"SPRUNG", // Mobj was already sprung this tic
"APPLYPMOMZ", // Platform movement
NULL NULL
}; };
...@@ -7303,6 +7310,7 @@ static const char *const ML_LIST[16] = { ...@@ -7303,6 +7310,7 @@ static const char *const ML_LIST[16] = {
}; };
// This DOES differ from r_draw's Color_Names, unfortunately. // This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
static const char *COLOR_ENUMS[] = { static const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE "NONE", // SKINCOLOR_NONE
"WHITE", // SKINCOLOR_WHITE "WHITE", // SKINCOLOR_WHITE
...@@ -7329,7 +7337,25 @@ static const char *COLOR_ENUMS[] = { ...@@ -7329,7 +7337,25 @@ static const char *COLOR_ENUMS[] = {
"ZIM", // SKINCOLOR_ZIM "ZIM", // SKINCOLOR_ZIM
"OLIVE", // SKINCOLOR_OLIVE "OLIVE", // SKINCOLOR_OLIVE
"YELLOW", // SKINCOLOR_YELLOW "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[] = { static const char *const POWERS_LIST[] = {
...@@ -7536,8 +7562,9 @@ struct { ...@@ -7536,8 +7562,9 @@ struct {
{"EMERALD6",EMERALD6}, {"EMERALD6",EMERALD6},
{"EMERALD7",EMERALD7}, {"EMERALD7",EMERALD7},
// SKINCOLOR_ doesn't include this..! // SKINCOLOR_ doesn't include these..!
{"MAXSKINCOLORS",MAXSKINCOLORS}, {"MAXSKINCOLORS",MAXSKINCOLORS},
{"MAXTRANSLATIONS",MAXTRANSLATIONS},
// Precipitation // Precipitation
{"PRECIP_NONE",PRECIP_NONE}, {"PRECIP_NONE",PRECIP_NONE},
...@@ -7730,36 +7757,36 @@ struct { ...@@ -7730,36 +7757,36 @@ struct {
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
// Angles // Angles
{"ANG1",ANG1}, {"ANG1",ANG1>>0},
{"ANG2",ANG2}, {"ANG2",ANG2>>0},
{"ANG10",ANG10}, {"ANG10",ANG10>>0},
{"ANG15",ANG15}, {"ANG15",ANG15>>0},
{"ANG20",ANG20}, {"ANG20",ANG20>>0},
{"ANG30",ANG30}, {"ANG30",ANG30>>0},
{"ANG60",ANG60}, {"ANG60",ANG60>>0},
{"ANG64h",ANG64h}, {"ANG64h",ANG64h>>0},
{"ANG105",ANG105}, {"ANG105",ANG105>>0},
{"ANG210",ANG210}, {"ANG210",ANG210>>0},
{"ANG255",ANG255}, {"ANG255",ANG255>>0},
{"ANG340",ANG340}, {"ANG340",ANG340>>0},
{"ANG350",ANG350}, {"ANG350",ANG350>>0},
{"ANGLE_11hh",ANGLE_11hh}, {"ANGLE_11hh",ANGLE_11hh>>0},
{"ANGLE_22h",ANGLE_22h}, {"ANGLE_22h",ANGLE_22h>>0},
{"ANGLE_45",ANGLE_45}, {"ANGLE_45",ANGLE_45>>0},
{"ANGLE_67h",ANGLE_67h}, {"ANGLE_67h",ANGLE_67h>>0},
{"ANGLE_90",ANGLE_90}, {"ANGLE_90",ANGLE_90>>0},
{"ANGLE_112h",ANGLE_112h}, {"ANGLE_112h",ANGLE_112h>>0},
{"ANGLE_135",ANGLE_135}, {"ANGLE_135",ANGLE_135>>0},
{"ANGLE_157h",ANGLE_157h}, {"ANGLE_157h",ANGLE_157h>>0},
{"ANGLE_180",ANGLE_180}, {"ANGLE_180",ANGLE_180>>0},
{"ANGLE_202h",ANGLE_202h}, {"ANGLE_202h",ANGLE_202h>>0},
{"ANGLE_225",ANGLE_225}, {"ANGLE_225",ANGLE_225>>0},
{"ANGLE_247h",ANGLE_247h}, {"ANGLE_247h",ANGLE_247h>>0},
{"ANGLE_270",ANGLE_270}, {"ANGLE_270",ANGLE_270>>0},
{"ANGLE_292h",ANGLE_292h}, {"ANGLE_292h",ANGLE_292h>>0},
{"ANGLE_315",ANGLE_315}, {"ANGLE_315",ANGLE_315>>0},
{"ANGLE_337h",ANGLE_337h}, {"ANGLE_337h",ANGLE_337h>>0},
{"ANGLE_MAX",ANGLE_MAX}, {"ANGLE_MAX",ANGLE_MAX>>0},
// P_Chase directions (dirtype_t) // P_Chase directions (dirtype_t)
{"DI_NODIR",DI_NODIR}, {"DI_NODIR",DI_NODIR},
...@@ -8158,7 +8185,7 @@ static fixed_t find_const(const char **rword) ...@@ -8158,7 +8185,7 @@ static fixed_t find_const(const char **rword)
} }
else if (fastncmp("SKINCOLOR_",word,10)) { else if (fastncmp("SKINCOLOR_",word,10)) {
char *p = word+10; char *p = word+10;
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) { if (fastcmp(p, COLOR_ENUMS[i])) {
free(word); free(word);
return i; return i;
...@@ -8217,8 +8244,8 @@ void DEH_Check(void) ...@@ -8217,8 +8244,8 @@ void DEH_Check(void)
if (dehpowers != NUMPOWERS) 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)); 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) 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", MAXSKINCOLORS, sizeu1(dehcolors)); 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 #endif
} }
...@@ -8572,7 +8599,7 @@ static inline int lib_getenum(lua_State *L) ...@@ -8572,7 +8599,7 @@ static inline int lib_getenum(lua_State *L)
} }
else if (fastncmp("SKINCOLOR_",word,10)) { else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10; p = word+10;
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) { if (fastcmp(p, COLOR_ENUMS[i])) {
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
...@@ -8697,7 +8724,7 @@ static inline int lib_getenum(lua_State *L) ...@@ -8697,7 +8724,7 @@ static inline int lib_getenum(lua_State *L)
lua_pushinteger(L, mapmusic); lua_pushinteger(L, mapmusic);
return 1; return 1;
} else if (fastcmp(word,"server")) { } else if (fastcmp(word,"server")) {
if (!playeringame[serverplayer]) if ((!multiplayer || !netgame) && !playeringame[serverplayer])
return 0; return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1; return 1;
......
...@@ -138,15 +138,17 @@ ...@@ -138,15 +138,17 @@
extern FILE *logstream; extern FILE *logstream;
#endif #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 VERSION 0 // Game version
#define SUBVERSION 0 // more precise version number #define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "Trunk" #define VERSIONSTRING "Trunk"
#define VERSIONSTRINGW L"Trunk"
#else #else
#define VERSION 201 // Game version #define VERSION 165 // Game version
#define SUBVERSION 14 // more precise version number #define SUBVERSION 1
#define VERSIONSTRING "v2.1.14" #define VERSIONSTRING "v2.1.14 (Thokker 1.0.1)"
#define VERSIONSTRINGW L"v2.1.14" #define VERSIONSTRINGW L"v2.1.14 (Thokker 1.0.1)"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
...@@ -162,8 +164,8 @@ extern FILE *logstream; ...@@ -162,8 +164,8 @@ extern FILE *logstream;
// The string used in the alert that pops up in the event of an update being available. // The string used in the alert that pops up in the event of an update being available.
// Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!). // Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!).
#define UPDATE_ALERT_STRING \ #define UPDATE_ALERT_STRING \
"A new update is available for SRB2.\n"\ "A new update is available for SRB2 Thokker.\n"\
"Please visit SRB2.org to download it.\n"\ "Please visit the SRB2MB to download it.\n"\
"\n"\ "\n"\
"You are using version: %s\n"\ "You are using version: %s\n"\
"The newest version is: %s\n"\ "The newest version is: %s\n"\
...@@ -179,8 +181,8 @@ extern FILE *logstream; ...@@ -179,8 +181,8 @@ extern FILE *logstream;
// The string used in the I_Error alert upon trying to host through command line parameters. // The string used in the I_Error alert upon trying to host through command line parameters.
// Generally less filled with newlines, since Windows gives you lots more room to work with. // Generally less filled with newlines, since Windows gives you lots more room to work with.
#define UPDATE_ALERT_STRING_CONSOLE \ #define UPDATE_ALERT_STRING_CONSOLE \
"A new update is available for SRB2.\n"\ "A new update is available for SRB2 Thokker.\n"\
"Please visit SRB2.org to download it.\n"\ "Please visit the SRB2MB to download it.\n"\
"\n"\ "\n"\
"You are using version: %s\n"\ "You are using version: %s\n"\
"The newest version is: %s\n"\ "The newest version is: %s\n"\
...@@ -197,14 +199,14 @@ extern FILE *logstream; ...@@ -197,14 +199,14 @@ extern FILE *logstream;
// The Modification ID; must be obtained from Inuyasha ( http://mb.srb2.org/private.php?do=newpm&u=2604 ). // The Modification ID; must be obtained from Inuyasha ( http://mb.srb2.org/private.php?do=newpm&u=2604 ).
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
// "12" is the default mod ID for version 2.1 // "13" is the default mod ID for Thokker
#define MODID 12 #define MODID 13
// The Modification Version, starting from 1. Do not follow your version string for this, // The Modification Version, starting from 1. Do not follow your version string for this,
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 19 #define MODVERSION 2
...@@ -437,6 +439,9 @@ extern const char *compdate, *comptime, *comprevision; ...@@ -437,6 +439,9 @@ extern const char *compdate, *comptime, *comprevision;
/// Fun experimental slope stuff! /// Fun experimental slope stuff!
//#define SLOPENESS //#define SLOPENESS
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
/// Delete file while the game is running. /// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game. /// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE //#define DELFILE
......
...@@ -982,6 +982,7 @@ static const char *credits[] = { ...@@ -982,6 +982,7 @@ static const char *credits[] = {
"", "",
"\1Programming", "\1Programming",
"\1Assistance", "\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "Gregor \"Oogaland\" Dick",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
......
...@@ -2180,8 +2180,7 @@ void G_PlayerReborn(INT32 player) ...@@ -2180,8 +2180,7 @@ void G_PlayerReborn(INT32 player)
p->health = 1; // 0 rings p->health = 1; // 0 rings
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation
if ((netgame || multiplayer) && !p->spectator if ((netgame || multiplayer) && !p->spectator)
&& gametype != GT_RACE)
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
if (p-players == consoleplayer) if (p-players == consoleplayer)
...@@ -4330,20 +4329,10 @@ void G_GhostTicker(void) ...@@ -4330,20 +4329,10 @@ void G_GhostTicker(void)
switch(g->color) switch(g->color)
{ {
case GHC_SUPER: // Super Sonic (P_DoSuperStuff) case GHC_SUPER: // Super Sonic (P_DoSuperStuff)
// Yousa yellow now! if (leveltime % 9 < 5)
g->mo->color = SKINCOLOR_SUPER1 + (leveltime/2) % 5; g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9;
if (g->mo->skin) else
switch (((skin_t*)g->mo->skin)-skins) g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
{
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;
}
break; break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS);
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
#include "../st_stuff.h" #include "../st_stuff.h"
#include "../i_system.h" #include "../i_system.h"
#include "../m_cheat.h" #include "../m_cheat.h"
#ifdef ESLOPE
#include "../p_slopes.h"
#endif
#include "hw_md2.h" #include "hw_md2.h"
#define R_FAKEFLOORS #define R_FAKEFLOORS
...@@ -519,7 +521,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // L ...@@ -519,7 +521,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // L
// -----------------+ // -----------------+
// HWR_RenderPlane : Render a floor or ceiling convex polygon // HWR_RenderPlane : Render a floor or ceiling convex polygon
// -----------------+ // -----------------+
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fixedheight, static void HWR_RenderPlane(sector_t *shittyUnusedVariable, extrasubsector_t *xsub, fixed_t fixedheight,
FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
{ {
polyvertex_t * pv; polyvertex_t * pv;
...@@ -535,14 +537,42 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi ...@@ -535,14 +537,42 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
angle_t angle = 0; angle_t angle = 0;
FSurfaceInfo Surf; FSurfaceInfo Surf;
fixed_t tempxsow, tempytow; fixed_t tempxsow, tempytow;
#ifdef ESLOPE
pslope_t *slope = NULL;
#endif
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
(void)shittyUnusedVariable; ///@TODO remove shitty unused variable
// no convex poly were generated for this subsector // no convex poly were generated for this subsector
if (!xsub->planepoly) if (!xsub->planepoly)
return; return;
#ifdef ESLOPE
// Get the slope pointer to simplify future code
if (FOFsector)
{
if (FOFsector->f_slope && FOFsector->floorheight == fixedheight)
slope = FOFsector->f_slope;
else if (FOFsector->c_slope && FOFsector->ceilingheight == fixedheight)
slope = FOFsector->c_slope;
}
else
{
// Use fixedheight to determine whether to check floor or ceiling because I hate my life
if (gr_frontsector->f_slope && gr_frontsector->floorheight == fixedheight)
slope = gr_frontsector->f_slope;
else if (gr_frontsector->c_slope && gr_frontsector->ceilingheight == fixedheight)
slope = gr_frontsector->c_slope;
}
// Set fixedheight to the slope's height from our viewpoint, if we have a slope
if (slope)
fixedheight = P_GetZAt(slope, viewx, viewy);
#endif
height = FIXED_TO_FLOAT(fixedheight); height = FIXED_TO_FLOAT(fixedheight);
pv = xsub->planepoly->pts; pv = xsub->planepoly->pts;
...@@ -608,7 +638,12 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi ...@@ -608,7 +638,12 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
if (FOFsector != NULL) if (FOFsector != NULL)
{ {
#ifdef ESLOPE
if ((slope && slope == FOFsector->f_slope)
|| fixedheight == FOFsector->floorheight) // it's a floor
#else
if (fixedheight == FOFsector->floorheight) // it's a floor if (fixedheight == FOFsector->floorheight) // it's a floor
#endif
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
...@@ -623,7 +658,12 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi ...@@ -623,7 +658,12 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
} }
else if (gr_frontsector) else if (gr_frontsector)
{ {
#ifdef ESLOPE
if ((slope && slope == gr_frontsector->f_slope)
|| fixedheight == gr_frontsector->floorheight) // it's a floor
#else
if (fixedheight < dup_viewz) // it's a floor if (fixedheight < dup_viewz) // it's a floor
#endif
{ {
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
...@@ -678,24 +718,13 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi ...@@ -678,24 +718,13 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
v3d->x = pv->x; v3d->x = pv->x;
v3d->y = height; v3d->y = height;
v3d->z = pv->y; v3d->z = pv->y;
#ifdef SLOPENESS
if (sector && sector->special == 65535) #ifdef ESLOPE
if (slope)
{ {
size_t q; fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y));
for (q = 0; q < sector->linecount; q++) v3d->y = FIXED_TO_FLOAT(fixedheight);
{
if (v3d->x == sector->lines[q]->v1->x>>FRACBITS)
{
if (v3d->z == sector->lines[q]->v1->y>>FRACBITS)
{
v3d->y += sector->lines[q]->v1->z>>FRACBITS;
break;
}
}
}
} }
#else
(void)sector;
#endif #endif
} }
...@@ -714,6 +743,11 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi ...@@ -714,6 +743,11 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
{ {
sector_t *psector = gr_frontsector; sector_t *psector = gr_frontsector;
#ifdef ESLOPE
if (slope)
fixedheight = P_GetZAt(slope, psector->soundorg.x, psector->soundorg.y);
#endif
if (psector->ffloors) if (psector->ffloors)
{ {
ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster; ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster;
...@@ -1050,23 +1084,50 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1050,23 +1084,50 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
lightlist. This may also include leaving out parts lightlist. This may also include leaving out parts
of the wall that can't be seen */ of the wall that can't be seen */
GLTexture_t * glTex; GLTexture_t * glTex;
float realtop, realbot, top, bot; float realtop, realbot, top, bot;
float pegt, pegb, pegmul; float pegt, pegb, pegmul;
float height = 0.0f, bheight = 0.0f; float height = 0.0f, bheight = 0.0f;
#ifdef ESLOPE
float endrealtop, endrealbot, endtop, endbot;
float endpegt, endpegb, endpegmul;
float endheight = 0.0f, endbheight = 0.0f;
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].y);
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].y);
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
#endif
INT32 solid, i; INT32 solid, i;
lightlist_t * list = sector->lightlist; lightlist_t * list = sector->lightlist;
const UINT8 alpha = Surf->FlatColor.s.alpha; const UINT8 alpha = Surf->FlatColor.s.alpha;
FUINT lightnum; FUINT lightnum;
extracolormap_t *colormap; extracolormap_t *colormap;
realtop = top = wallVerts[2].y; realtop = top = wallVerts[3].y;
realbot = bot = wallVerts[0].y; realbot = bot = wallVerts[0].y;
pegt = wallVerts[2].t; pegt = wallVerts[3].t;
pegb = wallVerts[0].t; pegb = wallVerts[0].t;
pegmul = (pegb - pegt) / (top - bot); pegmul = (pegb - pegt) / (top - bot);
#ifdef ESLOPE
endrealtop = endtop = wallVerts[2].y;
endrealbot = endbot = wallVerts[1].y;
endpegt = wallVerts[2].t;
endpegb = wallVerts[1].t;
endpegmul = (endpegb - endpegt) / (endtop - endbot);
#endif
for (i = 1; i < sector->numlights; i++) for (i = 1; i < sector->numlights; i++)
{ {
#ifdef ESLOPE
if (endtop < endrealbot)
#endif
if (top < realbot) if (top < realbot)
return; return;
...@@ -1099,14 +1160,45 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1099,14 +1160,45 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
if (cutflag == FF_CUTSOLIDS) // These are regular walls sent in from StoreWallRange, they shouldn't be cut from this if (cutflag == FF_CUTSOLIDS) // These are regular walls sent in from StoreWallRange, they shouldn't be cut from this
solid = false; solid = false;
#ifdef ESLOPE
if (list[i].slope)
{
temp = P_GetZAt(list[i].slope, v1x, v1y);
height = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(list[i].slope, v2x, v2y);
endheight = FIXED_TO_FLOAT(temp);
}
else
height = endheight = FIXED_TO_FLOAT(list[i].height);
if (solid)
{
if (*list[i].caster->b_slope)
{
temp = P_GetZAt(*list[i].caster->b_slope, v1x, v1y);
bheight = FIXED_TO_FLOAT(temp);
temp = P_GetZAt(*list[i].caster->b_slope, v2x, v2y);
endbheight = FIXED_TO_FLOAT(temp);
}
else
bheight = endbheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight);
}
#else
height = FIXED_TO_FLOAT(list[i].height); height = FIXED_TO_FLOAT(list[i].height);
if (solid) if (solid)
bheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight); bheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight);
#endif
#ifdef ESLOPE
if (endheight >= endtop)
#endif
if (height >= top) if (height >= top)
{ {
if (solid && top > bheight) if (solid && top > bheight)
top = bheight; top = bheight;
#ifdef ESLOPE
if (solid && endtop > endbheight)
endtop = endbheight;
#endif
continue; continue;
} }
...@@ -1116,6 +1208,13 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1116,6 +1208,13 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
if (bot < realbot) if (bot < realbot)
bot = realbot; bot = realbot;
#ifdef ESLOPE
endbot = endheight;
if (endbot < endrealbot)
endbot = endrealbot;
#endif
// colormap test // colormap test
if (list[i-1].caster) if (list[i-1].caster)
{ {
...@@ -1130,13 +1229,25 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1130,13 +1229,25 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
Surf->FlatColor.s.alpha = alpha; Surf->FlatColor.s.alpha = alpha;
#ifdef ESLOPE
wallVerts[3].t = pegt + ((realtop - top) * pegmul);
wallVerts[2].t = endpegt + ((endrealtop - endtop) * endpegmul);
wallVerts[0].t = pegt + ((realtop - bot) * pegmul);
wallVerts[1].t = endpegt + ((endrealtop - endbot) * endpegmul);
// set top/bottom coords
wallVerts[3].y = top;
wallVerts[2].y = endtop;
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
#else
wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul);
wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul);
// set top/bottom coords // set top/bottom coords
wallVerts[2].y = wallVerts[3].y = top; wallVerts[2].y = wallVerts[3].y = top;
wallVerts[0].y = wallVerts[1].y = bot; wallVerts[0].y = wallVerts[1].y = bot;
#endif
glTex = HWR_GetTexture(texnum); glTex = HWR_GetTexture(texnum);
if (cutflag & FF_TRANSLUCENT) if (cutflag & FF_TRANSLUCENT)
...@@ -1150,9 +1261,19 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1150,9 +1261,19 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
top = bheight; top = bheight;
else else
top = height; top = height;
#ifdef ESLOPE
if (solid)
endtop = endbheight;
else
endtop = endheight;
#endif
} }
bot = realbot; bot = realbot;
#ifdef ESLOPE
endbot = endrealbot;
if (endtop <= endrealbot)
#endif
if (top <= realbot) if (top <= realbot)
return; return;
...@@ -1168,12 +1289,25 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, ...@@ -1168,12 +1289,25 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
} }
Surf->FlatColor.s.alpha = alpha; Surf->FlatColor.s.alpha = alpha;
wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); #ifdef ESLOPE
wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); wallVerts[3].t = pegt + ((realtop - top) * pegmul);
wallVerts[2].t = endpegt + ((endrealtop - endtop) * endpegmul);
wallVerts[0].t = pegt + ((realtop - bot) * pegmul);
wallVerts[1].t = endpegt + ((endrealtop - endbot) * endpegmul);
// set top/bottom coords // set top/bottom coords
wallVerts[2].y = wallVerts[3].y = top; wallVerts[3].y = top;
wallVerts[0].y = wallVerts[1].y = bot; wallVerts[2].y = endtop;
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
#else
wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul);
wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul);
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = top;
wallVerts[0].y = wallVerts[1].y = bot;
#endif
glTex = HWR_GetTexture(texnum); glTex = HWR_GetTexture(texnum);
if (cutflag & FF_TRANSLUCENT) if (cutflag & FF_TRANSLUCENT)
...@@ -1321,11 +1455,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1321,11 +1455,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
fixed_t worldtop, worldbottom; fixed_t worldtop, worldbottom;
fixed_t worldhigh = 0, worldlow = 0; fixed_t worldhigh = 0, worldlow = 0;
#ifdef ESLOPE
fixed_t worldtopslope, worldbottomslope;
fixed_t worldhighslope = 0, worldlowslope = 0;
fixed_t v1x, v1y, v2x, v2y;
#endif
GLTexture_t *grTex = NULL; GLTexture_t *grTex = NULL;
float cliplow = 0.0f, cliphigh = 0.0f; float cliplow = 0.0f, cliphigh = 0.0f;
INT32 gr_midtexture; INT32 gr_midtexture;
fixed_t h, l; // 3D sides and 2s middle textures fixed_t h, l; // 3D sides and 2s middle textures
#ifdef ESLOPE
fixed_t hS, lS;
#endif
FUINT lightnum = 0; // shut up compiler FUINT lightnum = 0; // shut up compiler
extracolormap_t *colormap; extracolormap_t *colormap;
...@@ -1337,22 +1479,56 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1337,22 +1479,56 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
gr_sidedef = gr_curline->sidedef; gr_sidedef = gr_curline->sidedef;
gr_linedef = gr_curline->linedef; gr_linedef = gr_curline->linedef;
vs.x = ((polyvertex_t *)gr_curline->v1)->x;
vs.y = ((polyvertex_t *)gr_curline->v1)->y;
ve.x = ((polyvertex_t *)gr_curline->v2)->x;
ve.y = ((polyvertex_t *)gr_curline->v2)->y;
#ifdef ESLOPE
v1x = FLOAT_TO_FIXED(vs.x);
v1y = FLOAT_TO_FIXED(vs.y);
v2x = FLOAT_TO_FIXED(ve.x);
v2y = FLOAT_TO_FIXED(ve.y);
#endif
if (gr_frontsector->heightsec != -1) if (gr_frontsector->heightsec != -1)
{ {
#ifdef ESLOPE
worldtop = worldtopslope = sectors[gr_frontsector->heightsec].ceilingheight;
worldbottom = worldbottomslope = sectors[gr_frontsector->heightsec].floorheight;
#else
worldtop = sectors[gr_frontsector->heightsec].ceilingheight; worldtop = sectors[gr_frontsector->heightsec].ceilingheight;
worldbottom = sectors[gr_frontsector->heightsec].floorheight; worldbottom = sectors[gr_frontsector->heightsec].floorheight;
#endif
} }
else else
{ {
#ifdef ESLOPE
if (gr_frontsector->c_slope)
{
worldtop = P_GetZAt(gr_frontsector->c_slope, v1x, v1y);
worldtopslope = P_GetZAt(gr_frontsector->c_slope, v2x, v2y);
}
else
{
worldtop = worldtopslope = gr_frontsector->ceilingheight;
}
if (gr_frontsector->f_slope)
{
worldbottom = P_GetZAt(gr_frontsector->f_slope, v1x, v1y);
worldbottomslope = P_GetZAt(gr_frontsector->f_slope, v2x, v2y);
}
else
{
worldbottom = worldbottomslope = gr_frontsector->floorheight;
}
#else
worldtop = gr_frontsector->ceilingheight; worldtop = gr_frontsector->ceilingheight;
worldbottom = gr_frontsector->floorheight; worldbottom = gr_frontsector->floorheight;
#endif
} }
vs.x = ((polyvertex_t *)gr_curline->v1)->x;
vs.y = ((polyvertex_t *)gr_curline->v1)->y;
ve.x = ((polyvertex_t *)gr_curline->v2)->x;
ve.y = ((polyvertex_t *)gr_curline->v2)->y;
// remember vertices ordering // remember vertices ordering
// 3--2 // 3--2
// | /| // | /|
...@@ -1396,13 +1572,40 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1396,13 +1572,40 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// two sided line // two sided line
if (gr_backsector->heightsec != -1) if (gr_backsector->heightsec != -1)
{ {
#ifdef ESLOPE
worldhigh = worldhighslope = sectors[gr_backsector->heightsec].ceilingheight;
worldlow = worldlowslope = sectors[gr_backsector->heightsec].floorheight;
#else
worldhigh = sectors[gr_backsector->heightsec].ceilingheight; worldhigh = sectors[gr_backsector->heightsec].ceilingheight;
worldlow = sectors[gr_backsector->heightsec].floorheight; worldlow = sectors[gr_backsector->heightsec].floorheight;
#endif
} }
else else
{ {
#ifdef ESLOPE
if (gr_backsector->c_slope)
{
worldhigh = P_GetZAt(gr_backsector->c_slope, v1x, v1y);
worldhighslope = P_GetZAt(gr_backsector->c_slope, v2x, v2y);
}
else
{
worldhigh = worldhighslope = gr_backsector->ceilingheight;
}
if (gr_backsector->f_slope)
{
worldlow = P_GetZAt(gr_backsector->f_slope, v1x, v1y);
worldlowslope = P_GetZAt(gr_backsector->f_slope, v2x, v2y);
}
else
{
worldlow = worldlowslope = gr_backsector->floorheight;
}
#else
worldhigh = gr_backsector->ceilingheight; worldhigh = gr_backsector->ceilingheight;
worldlow = gr_backsector->floorheight; worldlow = gr_backsector->floorheight;
#endif
} }
// hack to allow height changes in outdoor areas // hack to allow height changes in outdoor areas
...@@ -1411,10 +1614,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1411,10 +1614,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
gr_backsector->ceilingpic == skyflatnum) gr_backsector->ceilingpic == skyflatnum)
{ {
worldtop = worldhigh; worldtop = worldhigh;
#ifdef ESLOPE
worldtopslope = worldhighslope;
#endif
} }
// check TOP TEXTURE // check TOP TEXTURE
if (worldhigh < worldtop && texturetranslation[gr_sidedef->toptexture]) if ((
#ifdef ESLOPE
worldhighslope < worldtopslope ||
#endif
worldhigh < worldtop
) && texturetranslation[gr_sidedef->toptexture])
{ {
if (drawtextured) if (drawtextured)
{ {
...@@ -1425,8 +1636,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1425,8 +1636,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// PEGGING // PEGGING
if (gr_linedef->flags & ML_DONTPEGTOP) if (gr_linedef->flags & ML_DONTPEGTOP)
texturevpegtop = 0; texturevpegtop = 0;
else #ifdef ESLOPE
else if (gr_linedef->flags & ML_EFFECT1)
texturevpegtop = worldhigh + textureheight[gr_sidedef->toptexture] - worldtop; texturevpegtop = worldhigh + textureheight[gr_sidedef->toptexture] - worldtop;
else
texturevpegtop = gr_backsector->ceilingheight + textureheight[gr_sidedef->toptexture] - gr_frontsector->ceilingheight;
#else
else
texturevpegtop = worldhigh + textureheight[gr_sidedef->toptexture] - worldtop;
#endif
texturevpegtop += gr_sidedef->rowoffset; texturevpegtop += gr_sidedef->rowoffset;
...@@ -1434,14 +1652,46 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1434,14 +1652,46 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texturevpegtop %= SHORT(textures[texturetranslation[gr_sidedef->toptexture]]->height)<<FRACBITS; texturevpegtop %= SHORT(textures[texturetranslation[gr_sidedef->toptexture]]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
#ifdef ESLOPE
// Adjust t value for sloped walls
if (!(gr_linedef->flags & ML_EFFECT1))
{
// Unskewed
wallVerts[3].t -= (worldtop - gr_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[2].t -= (worldtopslope - gr_frontsector->ceilingheight) * grTex->scaleY;
wallVerts[0].t -= (worldhigh - gr_backsector->ceilingheight) * grTex->scaleY;
wallVerts[1].t -= (worldhighslope - gr_backsector->ceilingheight) * grTex->scaleY;
}
else if (gr_linedef->flags & ML_DONTPEGTOP)
{
// Skewed by top
wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY;
}
else
{
// Skewed by bottom
wallVerts[0].t = (texturevpegtop + worldhigh - worldtop) * grTex->scaleY;
wallVerts[2].t = wallVerts[3].t - (worldhighslope - worldhigh) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldhighslope - worldtopslope) * grTex->scaleY;
}
#endif
} }
// set top/bottom coords // set top/bottom coords
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
#else
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh);
#endif
if (gr_frontsector->numlights) if (gr_frontsector->numlights)
HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->toptexture], &Surf, FF_CUTSOLIDS); HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->toptexture], &Surf, FF_CUTSOLIDS);
...@@ -1452,7 +1702,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1452,7 +1702,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if (worldlow > worldbottom && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!! if ((
#ifdef ESLOPE
worldlowslope > worldbottomslope ||
#endif
worldlow > worldbottom) && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!!
{ {
if (drawtextured) if (drawtextured)
{ {
...@@ -1461,10 +1715,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1461,10 +1715,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
grTex = HWR_GetTexture(texturetranslation[gr_sidedef->bottomtexture]); grTex = HWR_GetTexture(texturetranslation[gr_sidedef->bottomtexture]);
// PEGGING // PEGGING
if (gr_linedef->flags & ML_DONTPEGBOTTOM) #ifdef ESLOPE
if (!(gr_linedef->flags & ML_DONTPEGBOTTOM))
texturevpegbottom = 0;
else if (gr_linedef->flags & ML_EFFECT1)
texturevpegbottom = worldtop - worldlow; texturevpegbottom = worldtop - worldlow;
else else
texturevpegbottom = 0; texturevpegbottom = gr_frontsector->ceilingheight - gr_backsector->floorheight;
#else
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
texturevpegbottom = worldtop - worldlow;
else
texturevpegbottom = 0;
#endif
texturevpegbottom += gr_sidedef->rowoffset; texturevpegbottom += gr_sidedef->rowoffset;
...@@ -1472,14 +1735,46 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1472,14 +1735,46 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texturevpegbottom %= SHORT(textures[texturetranslation[gr_sidedef->bottomtexture]]->height)<<FRACBITS; texturevpegbottom %= SHORT(textures[texturetranslation[gr_sidedef->bottomtexture]]->height)<<FRACBITS;
wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
#ifdef ESLOPE
// Adjust t value for sloped walls
if (!(gr_linedef->flags & ML_EFFECT1))
{
// Unskewed
wallVerts[0].t -= (worldbottom - gr_frontsector->floorheight) * grTex->scaleY;
wallVerts[1].t -= (worldbottomslope - gr_frontsector->floorheight) * grTex->scaleY;
wallVerts[3].t -= (worldlow - gr_backsector->floorheight) * grTex->scaleY;
wallVerts[2].t -= (worldlowslope - gr_backsector->floorheight) * grTex->scaleY;
}
else if (gr_linedef->flags & ML_DONTPEGBOTTOM)
{
// Skewed by bottom
wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
wallVerts[2].t = wallVerts[3].t - (worldlowslope - worldlow) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldbottomslope - worldlowslope) * grTex->scaleY;
}
else
{
// Skewed by top
wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY;
}
#endif
} }
// set top/bottom coords // set top/bottom coords
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
#else
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldlow); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom);
#endif
if (gr_frontsector->numlights) if (gr_frontsector->numlights)
HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->bottomtexture], &Surf, FF_CUTSOLIDS); HWR_SplitWall(gr_frontsector, wallVerts, texturetranslation[gr_sidedef->bottomtexture], &Surf, FF_CUTSOLIDS);
...@@ -1546,14 +1841,36 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1546,14 +1841,36 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
popentop = back->ceilingheight; popentop = back->ceilingheight;
popenbottom = back->floorheight; popenbottom = back->floorheight;
} }
#endif
else else
{ #endif
popentop = front->ceilingheight < back->ceilingheight ? front->ceilingheight : back->ceilingheight; {
popenbottom = front->floorheight > back->floorheight ? front->floorheight : back->floorheight; #ifdef ESLOPE
popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow);
#else
popentop = min(front->ceilingheight, back->ceilingheight);
popenbottom = max(front->floorheight, back->floorheight);
#endif
} }
if (gr_linedef->flags & ML_DONTPEGBOTTOM) #ifdef ESLOPE
if (gr_linedef->flags & ML_EFFECT2)
{
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
{
polybottom = max(front->floorheight, back->floorheight) + gr_sidedef->rowoffset;
polytop = polybottom + textureheight[gr_midtexture]*repeats;
}
else
{
polytop = min(front->ceilingheight, back->ceilingheight) + gr_sidedef->rowoffset;
polybottom = polytop - textureheight[gr_midtexture]*repeats;
}
}
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
#else
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
#endif
{ {
polybottom = popenbottom + gr_sidedef->rowoffset; polybottom = popenbottom + gr_sidedef->rowoffset;
polytop = polybottom + textureheight[gr_midtexture]*repeats; polytop = polybottom + textureheight[gr_midtexture]*repeats;
...@@ -1576,17 +1893,21 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1576,17 +1893,21 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else else
{ {
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
lowcut = front->floorheight > back->floorheight ? front->floorheight : back->floorheight; lowcut = popenbottom;
highcut = front->ceilingheight < back->ceilingheight ? front->ceilingheight : back->ceilingheight; highcut = popentop;
} }
h = polytop > highcut ? highcut : polytop; h = min(highcut, polytop);
l = polybottom < lowcut ? lowcut : polybottom; l = max(polybottom, lowcut);
if (drawtextured) if (drawtextured)
{ {
// PEGGING // PEGGING
#ifdef ESLOPE
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
#else
if (gr_linedef->flags & ML_DONTPEGBOTTOM) if (gr_linedef->flags & ML_DONTPEGBOTTOM)
#endif
texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom; texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom;
else else
texturevpeg = polytop - h; texturevpeg = polytop - h;
...@@ -1605,6 +1926,52 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1605,6 +1926,52 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
#ifdef ESLOPE
// Correct to account for slopes
{
fixed_t midtextureslant;
if (gr_linedef->flags & ML_EFFECT2)
midtextureslant = 0;
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
midtextureslant = worldlow < worldbottom
? worldbottomslope-worldbottom
: worldlowslope-worldlow;
else
midtextureslant = worldtop < worldhigh
? worldtopslope-worldtop
: worldhighslope-worldhigh;
polytop += midtextureslant;
polybottom += midtextureslant;
highcut += worldtop < worldhigh
? worldtopslope-worldtop
: worldhighslope-worldhigh;
lowcut += worldlow < worldbottom
? worldbottomslope-worldbottom
: worldlowslope-worldlow;
// Texture stuff
h = min(highcut, polytop);
l = max(polybottom, lowcut);
if (drawtextured)
{
// PEGGING
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
}
wallVerts[2].y = FIXED_TO_FLOAT(h);
wallVerts[1].y = FIXED_TO_FLOAT(l);
}
#endif
// set alpha for transparent walls (new boom and legacy linedef types) // set alpha for transparent walls (new boom and legacy linedef types)
// ooops ! this do not work at all because render order we should render it in backtofront order // ooops ! this do not work at all because render order we should render it in backtofront order
switch (gr_linedef->special) switch (gr_linedef->special)
...@@ -1785,6 +2152,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1785,6 +2152,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
{ {
fixed_t texturevpeg; fixed_t texturevpeg;
// PEGGING // PEGGING
#ifdef ESLOPE
if ((gr_linedef->flags & (ML_DONTPEGBOTTOM|ML_EFFECT2)) == (ML_DONTPEGBOTTOM|ML_EFFECT2))
texturevpeg = gr_frontsector->floorheight + textureheight[gr_sidedef->midtexture] - gr_frontsector->ceilingheight + gr_sidedef->rowoffset;
else
#endif
if (gr_linedef->flags & ML_DONTPEGBOTTOM) if (gr_linedef->flags & ML_DONTPEGBOTTOM)
texturevpeg = worldbottom + textureheight[gr_sidedef->midtexture] - worldtop + gr_sidedef->rowoffset; texturevpeg = worldbottom + textureheight[gr_sidedef->midtexture] - worldtop + gr_sidedef->rowoffset;
else else
...@@ -1794,14 +2166,37 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1794,14 +2166,37 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
grTex = HWR_GetTexture(gr_midtexture); grTex = HWR_GetTexture(gr_midtexture);
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldbottom) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gr_frontsector->ceilingheight - gr_frontsector->floorheight) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
#ifdef ESLOPE
// Texture correction for slopes
if (gr_linedef->flags & ML_EFFECT2) {
wallVerts[3].t += (gr_frontsector->ceilingheight - worldtop) * grTex->scaleY;
wallVerts[2].t += (gr_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
wallVerts[0].t += (gr_frontsector->floorheight - worldbottom) * grTex->scaleY;
wallVerts[1].t += (gr_frontsector->floorheight - worldbottomslope) * grTex->scaleY;
} else if (gr_linedef->flags & ML_DONTPEGBOTTOM) {
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY;
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY;
} else {
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY;
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY;
}
#endif
} }
#ifdef ESLOPE
//Set textures properly on single sided walls that are sloped
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
#else
// set top/bottom coords // set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom);
#endif
// I don't think that solid walls can use translucent linedef types... // I don't think that solid walls can use translucent linedef types...
if (gr_frontsector->numlights) if (gr_frontsector->numlights)
HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS);
...@@ -1834,6 +2229,8 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1834,6 +2229,8 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
INT32 texnum; INT32 texnum;
line_t * newline = NULL; // Multi-Property FOF line_t * newline = NULL; // Multi-Property FOF
///TODO add slope support (fixing cutoffs, proper wall clipping) - maybe just disable highcut/lowcut if either sector or FOF has a slope
/// to allow fun plane intersecting in OGL? But then people would abuse that and make software look bad. :C
highcut = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; highcut = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
lowcut = gr_frontsector->floorheight > gr_backsector->floorheight ? gr_frontsector->floorheight : gr_backsector->floorheight; lowcut = gr_frontsector->floorheight > gr_backsector->floorheight ? gr_frontsector->floorheight : gr_backsector->floorheight;
...@@ -1855,6 +2252,24 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1855,6 +2252,24 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; texnum = texturetranslation[sides[newline->sidenum[0]].midtexture];
} }
#ifdef ESLOPE
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight;
hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight;
l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight;
lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight;
if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut)
h = hS = highcut;
if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut)
l = lS = lowcut;
//Hurdler: HW code starts here
//FIXME: check if peging is correct
// set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
#else
h = *rover->topheight; h = *rover->topheight;
l = *rover->bottomheight; l = *rover->bottomheight;
if (h > highcut) if (h > highcut)
...@@ -1866,6 +2281,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1866,6 +2281,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// set top/bottom coords // set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
#endif
if (rover->flags & FF_FOG) if (rover->flags & FF_FOG)
{ {
wallVerts[3].t = wallVerts[2].t = 0; wallVerts[3].t = wallVerts[2].t = 0;
...@@ -1875,6 +2291,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1875,6 +2291,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
} }
else if (drawtextured) else if (drawtextured)
{ {
#ifdef ESLOPE // P.S. this is better-organized than the old version
fixed_t offs = sides[(newline ?: rover->master)->sidenum[0]].rowoffset;
grTex = HWR_GetTexture(texnum);
wallVerts[3].t = (*rover->topheight - h + offs) * grTex->scaleY;
wallVerts[2].t = (*rover->topheight - hS + offs) * grTex->scaleY;
wallVerts[0].t = (*rover->topheight - l + offs) * grTex->scaleY;
wallVerts[1].t = (*rover->topheight - lS + offs) * grTex->scaleY;
#else
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum);
if (newline) if (newline)
...@@ -1887,6 +2312,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1887,6 +2312,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * grTex->scaleY;
} }
#endif
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
...@@ -1959,7 +2385,24 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1959,7 +2385,24 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
newline = rover->master->frontsector->lines[0] + linenum; newline = rover->master->frontsector->lines[0] + linenum;
texnum = texturetranslation[sides[newline->sidenum[0]].midtexture]; texnum = texturetranslation[sides[newline->sidenum[0]].midtexture];
} }
#ifdef ESLOPE //backsides
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight;
hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight;
l = *rover->b_slope ? P_GetZAt(*rover->b_slope, v1x, v1y) : *rover->bottomheight;
lS = *rover->b_slope ? P_GetZAt(*rover->b_slope, v2x, v2y) : *rover->bottomheight;
if (!(*rover->t_slope) && !gr_frontsector->c_slope && !gr_backsector->c_slope && h > highcut)
h = hS = highcut;
if (!(*rover->b_slope) && !gr_frontsector->f_slope && !gr_backsector->f_slope && l < lowcut)
l = lS = lowcut;
//Hurdler: HW code starts here
//FIXME: check if peging is correct
// set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
#else
h = *rover->topheight; h = *rover->topheight;
l = *rover->bottomheight; l = *rover->bottomheight;
if (h > highcut) if (h > highcut)
...@@ -1971,7 +2414,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) ...@@ -1971,7 +2414,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// set top/bottom coords // set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h); wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
#endif
if (rover->flags & FF_FOG) if (rover->flags & FF_FOG)
{ {
wallVerts[3].t = wallVerts[2].t = 0; wallVerts[3].t = wallVerts[2].t = 0;
...@@ -2465,13 +2908,17 @@ static void HWR_AddLine(seg_t * line) ...@@ -2465,13 +2908,17 @@ static void HWR_AddLine(seg_t * line)
// and no middle texture. // and no middle texture.
if ( if (
#ifdef POLYOBJECTS #ifdef POLYOBJECTS
!line->polyseg !line->polyseg &&
#endif
gr_backsector->ceilingpic == gr_frontsector->ceilingpic
&& gr_backsector->floorpic == gr_frontsector->floorpic
#ifdef ESLOPE
&& gr_backsector->f_slope == gr_frontsector->f_slope
&& gr_backsector->c_slope == gr_frontsector->c_slope
#endif #endif
&& gr_backsector->ceilingpic == gr_frontsector->ceilingpic
&& gr_backsector->floorpic == gr_frontsector->floorpic
&& gr_backsector->lightlevel == gr_frontsector->lightlevel && gr_backsector->lightlevel == gr_frontsector->lightlevel
&& gr_curline->sidedef->midtexture == 0 && gr_curline->sidedef->midtexture == 0
&& !gr_backsector->ffloors && !gr_frontsector->ffloors) && !gr_backsector->ffloors && !gr_frontsector->ffloors)
// SoM: For 3D sides... Boris, would you like to take a // SoM: For 3D sides... Boris, would you like to take a
// crack at rendering 3D sides? You would need to add the // crack at rendering 3D sides? You would need to add the
// above check and add code to HWR_StoreWallRange... // above check and add code to HWR_StoreWallRange...
...@@ -2865,6 +3312,7 @@ static void HWR_Subsector(size_t num) ...@@ -2865,6 +3312,7 @@ static void HWR_Subsector(size_t num)
INT32 floorlightlevel; INT32 floorlightlevel;
INT32 ceilinglightlevel; INT32 ceilinglightlevel;
INT32 locFloorHeight, locCeilingHeight; INT32 locFloorHeight, locCeilingHeight;
INT32 cullFloorHeight, cullCeilingHeight;
INT32 light = 0; INT32 light = 0;
extracolormap_t *floorcolormap; extracolormap_t *floorcolormap;
extracolormap_t *ceilingcolormap; extracolormap_t *ceilingcolormap;
...@@ -2921,26 +3369,41 @@ static void HWR_Subsector(size_t num) ...@@ -2921,26 +3369,41 @@ static void HWR_Subsector(size_t num)
// ----- for special tricks with HW renderer ----- // ----- for special tricks with HW renderer -----
if (gr_frontsector->pseudoSector) if (gr_frontsector->pseudoSector)
{ {
locFloorHeight = gr_frontsector->virtualFloorheight; cullFloorHeight = locFloorHeight = gr_frontsector->virtualFloorheight;
locCeilingHeight = gr_frontsector->virtualCeilingheight; cullCeilingHeight = locCeilingHeight = gr_frontsector->virtualCeilingheight;
} }
else if (gr_frontsector->virtualFloor) else if (gr_frontsector->virtualFloor)
{ {
locFloorHeight = gr_frontsector->virtualFloorheight; ///@TODO Is this whole virtualFloor mess even useful? I don't think it even triggers ever.
cullFloorHeight = locFloorHeight = gr_frontsector->virtualFloorheight;
if (gr_frontsector->virtualCeiling) if (gr_frontsector->virtualCeiling)
locCeilingHeight = gr_frontsector->virtualCeilingheight; cullCeilingHeight = locCeilingHeight = gr_frontsector->virtualCeilingheight;
else else
locCeilingHeight = gr_frontsector->ceilingheight; cullCeilingHeight = locCeilingHeight = gr_frontsector->ceilingheight;
} }
else if (gr_frontsector->virtualCeiling) else if (gr_frontsector->virtualCeiling)
{ {
locCeilingHeight = gr_frontsector->virtualCeilingheight; cullCeilingHeight = locCeilingHeight = gr_frontsector->virtualCeilingheight;
locFloorHeight = gr_frontsector->floorheight; cullFloorHeight = locFloorHeight = gr_frontsector->floorheight;
} }
else else
{ {
locFloorHeight = gr_frontsector->floorheight; cullFloorHeight = locFloorHeight = gr_frontsector->floorheight;
locCeilingHeight = gr_frontsector->ceilingheight; cullCeilingHeight = locCeilingHeight = gr_frontsector->ceilingheight;
#ifdef ESLOPE
if (gr_frontsector->f_slope)
{
cullFloorHeight = P_GetZAt(gr_frontsector->f_slope, viewx, viewy);
locFloorHeight = P_GetZAt(gr_frontsector->f_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
if (gr_frontsector->c_slope)
{
cullCeilingHeight = P_GetZAt(gr_frontsector->c_slope, viewx, viewy);
locCeilingHeight = P_GetZAt(gr_frontsector->c_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
#endif
} }
// ----- end special tricks ----- // ----- end special tricks -----
...@@ -2971,14 +3434,18 @@ static void HWR_Subsector(size_t num) ...@@ -2971,14 +3434,18 @@ static void HWR_Subsector(size_t num)
// render floor ? // render floor ?
#ifdef DOPLANES #ifdef DOPLANES
// yeah, easy backface cull! :) // yeah, easy backface cull! :)
if (locFloorHeight < dup_viewz) if (cullFloorHeight < dup_viewz)
{ {
if (gr_frontsector->floorpic != skyflatnum) if (gr_frontsector->floorpic != skyflatnum)
{ {
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum); HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum);
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], locFloorHeight, PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap); HWR_RenderPlane(gr_frontsector, &extrasubsectors[num],
// Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap);
} }
} }
else else
...@@ -2989,14 +3456,18 @@ static void HWR_Subsector(size_t num) ...@@ -2989,14 +3456,18 @@ static void HWR_Subsector(size_t num)
} }
} }
if (locCeilingHeight > dup_viewz) if (cullCeilingHeight > dup_viewz)
{ {
if (gr_frontsector->ceilingpic != skyflatnum) if (gr_frontsector->ceilingpic != skyflatnum)
{ {
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum); HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum);
HWR_RenderPlane(NULL, &extrasubsectors[num], locCeilingHeight, PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap); HWR_RenderPlane(NULL, &extrasubsectors[num],
// Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap);
} }
} }
else else
...@@ -3025,22 +3496,34 @@ static void HWR_Subsector(size_t num) ...@@ -3025,22 +3496,34 @@ static void HWR_Subsector(size_t num)
for (rover = gr_frontsector->ffloors; for (rover = gr_frontsector->ffloors;
rover; rover = rover->next) rover; rover = rover->next)
{ {
fixed_t cullHeight, centerHeight;
// bottom plane
#ifdef ESLOPE
if (*rover->b_slope)
{
cullHeight = P_GetZAt(*rover->b_slope, viewx, viewy);
centerHeight = P_GetZAt(*rover->b_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
else
#endif
cullHeight = centerHeight = *rover->bottomheight;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
continue; continue;
if (sub->validcount == validcount) if (sub->validcount == validcount)
continue; continue;
if (*rover->bottomheight <= gr_frontsector->ceilingheight && if (centerHeight <= locCeilingHeight &&
*rover->bottomheight >= gr_frontsector->floorheight && centerHeight >= locFloorHeight &&
((dup_viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || ((dup_viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
(dup_viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) (dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{ {
if (rover->flags & FF_FOG) if (rover->flags & FF_FOG)
{ {
UINT8 alpha; UINT8 alpha;
light = R_GetPlaneLight(gr_frontsector, *rover->bottomheight, dup_viewz < *rover->bottomheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
if (rover->master->frontsector->extra_colormap) if (rover->master->frontsector->extra_colormap)
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba);
...@@ -3056,7 +3539,7 @@ static void HWR_Subsector(size_t num) ...@@ -3056,7 +3539,7 @@ static void HWR_Subsector(size_t num)
} }
else if (rover->flags & FF_TRANSLUCENT) // SoM: Flags are more efficient else if (rover->flags & FF_TRANSLUCENT) // SoM: Flags are more efficient
{ {
light = R_GetPlaneLight(gr_frontsector, *rover->bottomheight, dup_viewz < *rover->bottomheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
#ifndef SORTING #ifndef SORTING
HWR_Add3DWater(levelflats[*rover->bottompic].lumpnum, HWR_Add3DWater(levelflats[*rover->bottompic].lumpnum,
&extrasubsectors[num], &extrasubsectors[num],
...@@ -3075,21 +3558,33 @@ static void HWR_Subsector(size_t num) ...@@ -3075,21 +3558,33 @@ static void HWR_Subsector(size_t num)
else else
{ {
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum); HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, *rover->bottomheight, dup_viewz < *rover->bottomheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
} }
} }
if (*rover->topheight >= gr_frontsector->floorheight &&
*rover->topheight <= gr_frontsector->ceilingheight && // top plane
((dup_viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || #ifdef ESLOPE
(dup_viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) if (*rover->t_slope)
{
cullHeight = P_GetZAt(*rover->t_slope, viewx, viewy);
centerHeight = P_GetZAt(*rover->t_slope, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y);
}
else
#endif
cullHeight = centerHeight = *rover->topheight;
if (centerHeight >= locFloorHeight &&
centerHeight <= locCeilingHeight &&
((dup_viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
(dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{ {
if (rover->flags & FF_FOG) if (rover->flags & FF_FOG)
{ {
UINT8 alpha; UINT8 alpha;
light = R_GetPlaneLight(gr_frontsector, *rover->topheight, dup_viewz < *rover->topheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
if (rover->master->frontsector->extra_colormap) if (rover->master->frontsector->extra_colormap)
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba);
...@@ -3105,7 +3600,7 @@ static void HWR_Subsector(size_t num) ...@@ -3105,7 +3600,7 @@ static void HWR_Subsector(size_t num)
} }
else if (rover->flags & FF_TRANSLUCENT) else if (rover->flags & FF_TRANSLUCENT)
{ {
light = R_GetPlaneLight(gr_frontsector, *rover->topheight, dup_viewz < *rover->topheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
#ifndef SORTING #ifndef SORTING
HWR_Add3DWater(levelflats[*rover->toppic].lumpnum, HWR_Add3DWater(levelflats[*rover->toppic].lumpnum,
&extrasubsectors[num], &extrasubsectors[num],
...@@ -3125,7 +3620,7 @@ static void HWR_Subsector(size_t num) ...@@ -3125,7 +3620,7 @@ static void HWR_Subsector(size_t num)
else else
{ {
HWR_GetFlat(levelflats[*rover->toppic].lumpnum); HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, *rover->topheight, dup_viewz < *rover->topheight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
} }
...@@ -3505,6 +4000,184 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v ...@@ -3505,6 +4000,184 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
return false; 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 // HWR_DrawSprite : Draw flat sprites
// : (monsters, bonuses, weapons, lights, ...) // : (monsters, bonuses, weapons, lights, ...)
...@@ -3607,7 +4280,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) ...@@ -3607,7 +4280,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
// Draw shadow BEFORE sprite // Draw shadow BEFORE sprite
if (cv_shadow.value // Shadows enabled 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. && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
...@@ -3618,187 +4291,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) ...@@ -3618,187 +4291,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
//////////////////// ////////////////////
// SHADOW SPRITE! // // SHADOW SPRITE! //
//////////////////// ////////////////////
FOutVector swallVerts[4]; HWR_DrawSpriteShadow(spr, gpatch, this_scale);
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);
}
}
} }
noshadow:
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components // sprite lighting by modulating the RGB components
/// \todo coloured /// \todo coloured
...@@ -3806,7 +4301,7 @@ noshadow: ...@@ -3806,7 +4301,7 @@ noshadow:
// colormap test // colormap test
{ {
sector_t *sector = spr->mobj->subsector->sector; sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = sector->lightlevel; UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap; extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights) if (sector->numlights)
...@@ -3817,8 +4312,6 @@ noshadow: ...@@ -3817,8 +4312,6 @@ noshadow:
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel; lightlevel = *sector->lightlist[light].lightlevel;
else
lightlevel = 255;
if (sector->lightlist[light].extra_colormap) if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap; colormap = sector->lightlist[light].extra_colormap;
...@@ -3827,27 +4320,25 @@ noshadow: ...@@ -3827,27 +4320,25 @@ noshadow:
{ {
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel; lightlevel = sector->lightlevel;
else
lightlevel = 255;
if (sector->extra_colormap) if (sector->extra_colormap)
colormap = sector->extra_colormap; colormap = sector->extra_colormap;
} }
if (spr->mobj->frame & FF_FULLBRIGHT)
lightlevel = 255;
if (colormap) if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); 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; 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; Surf.FlatColor.s.alpha = 0x40;
blend = PF_Translucent; blend = PF_Translucent;
...@@ -4006,10 +4497,10 @@ static void HWR_SortVisSprites(void) ...@@ -4006,10 +4497,10 @@ static void HWR_SortVisSprites(void)
gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead; gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead;
for (i = 0; i < gr_visspritecount; i++) for (i = 0; i < gr_visspritecount; i++)
{ {
bestdist = ZCLIP_PLANE-1; best = NULL;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next) for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{ {
if (ds->tz > bestdist) if (!best || ds->tz > bestdist)
{ {
bestdist = ds->tz; bestdist = ds->tz;
best = ds; best = ds;
...@@ -4368,10 +4859,10 @@ static void HWR_DrawSprites(void) ...@@ -4368,10 +4859,10 @@ static void HWR_DrawSprites(void)
#endif #endif
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) 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); 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); HWR_DrawSprite(spr);
} }
} }
...@@ -4397,7 +4888,7 @@ static void HWR_DrawMD2S(void) ...@@ -4397,7 +4888,7 @@ static void HWR_DrawMD2S(void)
#endif #endif
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) 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); HWR_DrawMD2(spr);
} }
else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f) else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f)
...@@ -4439,23 +4930,12 @@ static void HWR_AddSprites(sector_t *sec) ...@@ -4439,23 +4930,12 @@ static void HWR_AddSprites(sector_t *sec)
// If a limit exists, handle things a tiny bit different. // 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 ((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) for (thing = sec->thinglist; thing; thing = thing->snext)
{ {
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
continue; continue;
approx_dist = P_AproxDistance( approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
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);
if (approx_dist <= limit_dist) if (approx_dist <= limit_dist)
HWR_ProjectSprite(thing); HWR_ProjectSprite(thing);
...@@ -4473,23 +4953,12 @@ static void HWR_AddSprites(sector_t *sec) ...@@ -4473,23 +4953,12 @@ static void HWR_AddSprites(sector_t *sec)
// Someone seriously wants infinite draw distance for precipitation? // Someone seriously wants infinite draw distance for precipitation?
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) 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) for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
{ {
if (precipthing->invisible) if (precipthing->precipflags & PCF_INVISIBLE)
continue; continue;
approx_dist = P_AproxDistance( approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
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);
if (approx_dist <= limit_dist) if (approx_dist <= limit_dist)
HWR_ProjectPrecipitationSprite(precipthing); HWR_ProjectPrecipitationSprite(precipthing);
...@@ -4499,7 +4968,7 @@ static void HWR_AddSprites(sector_t *sec) ...@@ -4499,7 +4968,7 @@ static void HWR_AddSprites(sector_t *sec)
{ {
// Draw everything in sector, no checks // Draw everything in sector, no checks
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
if (!precipthing->invisible) if (!(precipthing->precipflags & PCF_INVISIBLE))
HWR_ProjectPrecipitationSprite(precipthing); HWR_ProjectPrecipitationSprite(precipthing);
} }
#endif #endif
...@@ -4539,7 +5008,7 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -4539,7 +5008,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
// thing is behind view plane? // thing is behind view plane?
if (tz < ZCLIP_PLANE) if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
return; return;
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
...@@ -4560,10 +5029,11 @@ static void HWR_ProjectSprite(mobj_t *thing) ...@@ -4560,10 +5029,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (rot >= sprdef->numframes) 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]); sizeu1(rot), sizeu2(sprdef->numframes), sprnames[thing->sprite]);
thing->sprite = states[S_UNKNOWN].sprite; thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame; thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
rot = thing->frame&FF_FRAMEMASK; rot = thing->frame&FF_FRAMEMASK;
thing->state->sprite = thing->sprite; thing->state->sprite = thing->sprite;
thing->state->frame = thing->frame; thing->state->frame = thing->frame;
......
...@@ -975,24 +975,25 @@ void HWR_InitMD2(void) ...@@ -975,24 +975,25 @@ void HWR_InitMD2(void)
} }
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) 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++) for (i = 0; i < NUMSPRITES; i++)
{ {
if (stricmp(name, sprnames[i]) == 0) if (stricmp(name, sprnames[i]) == 0)
{ {
if (stricmp(name, "PLAY") == 0) //if (stricmp(name, "PLAY") == 0)
continue; //continue;
//CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset); //CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset);
md2_models[i].scale = scale; md2_models[i].scale = scale;
md2_models[i].offset = offset; md2_models[i].offset = offset;
md2_models[i].notfound = false; md2_models[i].notfound = false;
strcpy(md2_models[i].filename, filename); strcpy(md2_models[i].filename, filename);
break; goto md2found;
}
if (i == NUMSPRITES)
{
CONS_Printf("MD2 for sprite %s not found\n", name);
md2_models[i].notfound = true;
} }
} }
...@@ -1006,15 +1007,14 @@ void HWR_InitMD2(void) ...@@ -1006,15 +1007,14 @@ void HWR_InitMD2(void)
md2_playermodels[s].offset = offset; md2_playermodels[s].offset = offset;
md2_playermodels[s].notfound = false; md2_playermodels[s].notfound = false;
strcpy(md2_playermodels[s].filename, filename); strcpy(md2_playermodels[s].filename, filename);
break; goto md2found;
}
if (s == MAXSKINS-1)
{
CONS_Printf("MD2 for player skin %s not found\n", name);
md2_playermodels[s].notfound = true;
} }
} }
// 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); fclose(f);
} }
...@@ -1050,17 +1050,14 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup ...@@ -1050,17 +1050,14 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
md2_playermodels[skin].offset = offset; md2_playermodels[skin].offset = offset;
md2_playermodels[skin].notfound = false; md2_playermodels[skin].notfound = false;
strcpy(md2_playermodels[skin].filename, filename); strcpy(md2_playermodels[skin].filename, filename);
break; goto playermd2found;
}
if (skin == MAXSKINS-1)
{
CONS_Printf("MD2 for player skin %s not found\n", name);
md2_playermodels[skin].notfound = true;
} }
} }
//CONS_Printf("MD2 for player skin %s not found\n", skins[skin].name);
md2_playermodels[skin].notfound = true;
playermd2found:
fclose(f); fclose(f);
} }
...@@ -1075,6 +1072,9 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu ...@@ -1075,6 +1072,9 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
if (nomd2s) if (nomd2s)
return; return;
if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check
return;
// Read the md2.dat file // Read the md2.dat file
f = fopen("md2.dat", "rt"); f = fopen("md2.dat", "rt");
...@@ -1088,27 +1088,19 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu ...@@ -1088,27 +1088,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! // Check for any MD2s that match the names of player skins!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{ {
if (stricmp(name, sprnames[spritenum]) == 0)
{ {
if (stricmp(name, sprnames[spritenum]) == 0) md2_models[spritenum].scale = scale;
{ md2_models[spritenum].offset = offset;
if (stricmp(name, "PLAY") == 0) // Handled already NEWMD2: Per sprite, per-skin check md2_models[spritenum].notfound = false;
continue; strcpy(md2_models[spritenum].filename, filename);
goto spritemd2found;
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;
}
} }
} }
//CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]);
md2_models[spritenum].notfound = true;
spritemd2found:
fclose(f); fclose(f);
} }
...@@ -1386,11 +1378,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr) ...@@ -1386,11 +1378,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
md2_t *md2; md2_t *md2;
UINT8 color[4]; UINT8 color[4];
if (!cv_grmd2.value)
return;
if (spr->precip)
return;
// MD2 colormap fix // MD2 colormap fix
// colormap test // colormap test
{ {
sector_t *sector = spr->mobj->subsector->sector; sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = sector->lightlevel; UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap; extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights) if (sector->numlights)
...@@ -1401,8 +1399,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) ...@@ -1401,8 +1399,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel; lightlevel = *sector->lightlist[light].lightlevel;
else
lightlevel = 255;
if (sector->lightlist[light].extra_colormap) if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap; colormap = sector->lightlist[light].extra_colormap;
...@@ -1411,24 +1407,18 @@ void HWR_DrawMD2(gr_vissprite_t *spr) ...@@ -1411,24 +1407,18 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
{ {
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel; lightlevel = sector->lightlevel;
else
lightlevel = 255;
if (sector->extra_colormap) if (sector->extra_colormap)
colormap = sector->extra_colormap; colormap = sector->extra_colormap;
} }
if (spr->mobj->frame & FF_FULLBRIGHT)
lightlevel = 255;
if (colormap) if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
} }
// Look at HWR_ProjetctSprite for more // Look at HWR_ProjectSprite 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)
{ {
GLPatch_t *gpatch; GLPatch_t *gpatch;
INT32 *buff; INT32 *buff;
...@@ -1445,15 +1435,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) ...@@ -1445,15 +1435,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
//durs = tics; //durs = tics;
if (spr->mobj->flags2 & MF2_SHADOW) if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.FlatColor.s.alpha = 0x40; Surf.FlatColor.s.alpha = 0x40;
}
else if (spr->mobj->frame & FF_TRANSMASK) else if (spr->mobj->frame & FF_TRANSMASK)
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else else
{
Surf.FlatColor.s.alpha = 0xFF; Surf.FlatColor.s.alpha = 0xFF;
}
// dont forget to enabled the depth test because we can't do this like // dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted // before: polygons models are not sorted
...@@ -1571,8 +1557,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) ...@@ -1571,8 +1557,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.flip = false; p.flip = false;
HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color); HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color);
} }
} }
......
...@@ -1910,6 +1910,13 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d ...@@ -1910,6 +1910,13 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency //pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// 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++; val = *gl_cmd_buffer++;
while (val != 0) while (val != 0)
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#pragma warning(disable : 4214 4244) #pragma warning(disable : 4214 4244)
#endif #endif
#include "SDL_opengl.h" //Alam_GBC: Simple, yes? #include <SDL2/SDL_opengl.h> //Alam_GBC: Simple, yes?
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(default : 4214 4244) #pragma warning(default : 4214 4244)
......
...@@ -150,8 +150,7 @@ state_t states[NUMSTATES] = ...@@ -150,8 +150,7 @@ state_t states[NUMSTATES] =
{SPR_PLAY, 34, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN {SPR_PLAY, 34, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
   
// Blue Crawla // 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_STND
{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND2
{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1 {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, 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 {SPR_POSS, 2, 3, {A_Chase}, 0, 0, S_POSS_RUN4}, // S_POSS_RUN3
...@@ -160,8 +159,7 @@ state_t states[NUMSTATES] = ...@@ -160,8 +159,7 @@ state_t states[NUMSTATES] =
{SPR_POSS, 5, 3, {A_Chase}, 0, 0, S_POSS_RUN1}, // S_POSS_RUN6 {SPR_POSS, 5, 3, {A_Chase}, 0, 0, S_POSS_RUN1}, // S_POSS_RUN6
   
// Red Crawla // 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_STND
{SPR_SPOS, 0, 5, {A_Look}, 0, 0, S_SPOS_STND}, // S_SPOS_STND2
{SPR_SPOS, 0, 1, {A_Chase}, 0, 0, S_SPOS_RUN2}, // S_SPOS_RUN1 {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, 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 {SPR_SPOS, 2, 1, {A_Chase}, 0, 0, S_SPOS_RUN4}, // S_SPOS_RUN3
......
...@@ -663,7 +663,6 @@ typedef enum state ...@@ -663,7 +663,6 @@ typedef enum state
// Blue Crawla // Blue Crawla
S_POSS_STND, S_POSS_STND,
S_POSS_STND2,
S_POSS_RUN1, S_POSS_RUN1,
S_POSS_RUN2, S_POSS_RUN2,
S_POSS_RUN3, S_POSS_RUN3,
...@@ -673,7 +672,6 @@ typedef enum state ...@@ -673,7 +672,6 @@ typedef enum state
// Red Crawla // Red Crawla
S_SPOS_STND, S_SPOS_STND,
S_SPOS_STND2,
S_SPOS_RUN1, S_SPOS_RUN1,
S_SPOS_RUN2, S_SPOS_RUN2,
S_SPOS_RUN3, S_SPOS_RUN3,
......
...@@ -85,13 +85,6 @@ static int lib_print(lua_State *L) ...@@ -85,13 +85,6 @@ static int lib_print(lua_State *L)
return 0; return 0;
} }
static int lib_evalMath(lua_State *L)
{
const char *word = luaL_checkstring(L, 1);
lua_pushinteger(L, LUA_EvalMath(word));
return 1;
}
// M_RANDOM // M_RANDOM
////////////// //////////////
...@@ -138,25 +131,25 @@ static int lib_pRandomRange(lua_State *L) ...@@ -138,25 +131,25 @@ static int lib_pRandomRange(lua_State *L)
static int lib_pAproxDistance(lua_State *L) static int lib_pAproxDistance(lua_State *L)
{ {
fixed_t dx = (fixed_t)luaL_checkinteger(L, 1); fixed_t dx = luaL_checkfixed(L, 1);
fixed_t dy = (fixed_t)luaL_checkinteger(L, 2); fixed_t dy = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, P_AproxDistance(dx, dy)); lua_pushfixed(L, P_AproxDistance(dx, dy));
return 1; return 1;
} }
static int lib_pClosestPointOnLine(lua_State *L) static int lib_pClosestPointOnLine(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE)); line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE));
vertex_t result; vertex_t result;
//HUDSAFE //HUDSAFE
if (!line) if (!line)
return LUA_ErrInvalid(L, "line_t"); return LUA_ErrInvalid(L, "line_t");
P_ClosestPointOnLine(x, y, line, &result); P_ClosestPointOnLine(x, y, line, &result);
lua_pushinteger(L, result.x); lua_pushfixed(L, result.x);
lua_pushinteger(L, result.y); lua_pushfixed(L, result.y);
return 2; return 2;
} }
...@@ -241,9 +234,9 @@ static int lib_pLookForPlayers(lua_State *L) ...@@ -241,9 +234,9 @@ static int lib_pLookForPlayers(lua_State *L)
static int lib_pSpawnMobj(lua_State *L) static int lib_pSpawnMobj(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
fixed_t z = (fixed_t)luaL_checkinteger(L, 3); fixed_t z = luaL_checkfixed(L, 3);
mobjtype_t type = luaL_checkinteger(L, 4); mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD NOHUD
if (type > MT_LASTFREESLOT) if (type > MT_LASTFREESLOT)
...@@ -283,9 +276,9 @@ static int lib_pSpawnXYZMissile(lua_State *L) ...@@ -283,9 +276,9 @@ static int lib_pSpawnXYZMissile(lua_State *L)
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *dest = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobj_t *dest = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 3); mobjtype_t type = luaL_checkinteger(L, 3);
fixed_t x = (fixed_t)luaL_checkinteger(L, 4); fixed_t x = luaL_checkfixed(L, 4);
fixed_t y = (fixed_t)luaL_checkinteger(L, 5); fixed_t y = luaL_checkfixed(L, 5);
fixed_t z = (fixed_t)luaL_checkinteger(L, 6); fixed_t z = luaL_checkfixed(L, 6);
NOHUD NOHUD
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -298,13 +291,13 @@ static int lib_pSpawnXYZMissile(lua_State *L) ...@@ -298,13 +291,13 @@ static int lib_pSpawnXYZMissile(lua_State *L)
static int lib_pSpawnPointMissile(lua_State *L) static int lib_pSpawnPointMissile(lua_State *L)
{ {
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t xa = (fixed_t)luaL_checkinteger(L, 2); fixed_t xa = luaL_checkfixed(L, 2);
fixed_t ya = (fixed_t)luaL_checkinteger(L, 3); fixed_t ya = luaL_checkfixed(L, 3);
fixed_t za = (fixed_t)luaL_checkinteger(L, 4); fixed_t za = luaL_checkfixed(L, 4);
mobjtype_t type = luaL_checkinteger(L, 5); mobjtype_t type = luaL_checkinteger(L, 5);
fixed_t x = (fixed_t)luaL_checkinteger(L, 6); fixed_t x = luaL_checkfixed(L, 6);
fixed_t y = (fixed_t)luaL_checkinteger(L, 7); fixed_t y = luaL_checkfixed(L, 7);
fixed_t z = (fixed_t)luaL_checkinteger(L, 8); fixed_t z = luaL_checkfixed(L, 8);
NOHUD NOHUD
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -318,9 +311,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L) ...@@ -318,9 +311,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
{ {
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 2); mobjtype_t type = luaL_checkinteger(L, 2);
fixed_t x = (fixed_t)luaL_checkinteger(L, 3); fixed_t x = luaL_checkfixed(L, 3);
fixed_t y = (fixed_t)luaL_checkinteger(L, 4); fixed_t y = luaL_checkfixed(L, 4);
fixed_t z = (fixed_t)luaL_checkinteger(L, 5); fixed_t z = luaL_checkfixed(L, 5);
INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5);
NOHUD NOHUD
if (!source) if (!source)
...@@ -348,7 +341,7 @@ static int lib_pSPMAngle(lua_State *L) ...@@ -348,7 +341,7 @@ static int lib_pSPMAngle(lua_State *L)
{ {
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobjtype_t type = luaL_checkinteger(L, 2); mobjtype_t type = luaL_checkinteger(L, 2);
angle_t angle = (angle_t)luaL_checkinteger(L, 3); angle_t angle = luaL_checkangle(L, 3);
UINT8 allowaim = (UINT8)luaL_optinteger(L, 4, 0); UINT8 allowaim = (UINT8)luaL_optinteger(L, 4, 0);
UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0);
NOHUD NOHUD
...@@ -418,13 +411,13 @@ static int lib_pGetClosestAxis(lua_State *L) ...@@ -418,13 +411,13 @@ static int lib_pGetClosestAxis(lua_State *L)
static int lib_pSpawnParaloop(lua_State *L) static int lib_pSpawnParaloop(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
fixed_t z = (fixed_t)luaL_checkinteger(L, 3); fixed_t z = luaL_checkfixed(L, 3);
fixed_t radius = (fixed_t)luaL_checkinteger(L, 4); fixed_t radius = luaL_checkfixed(L, 4);
INT32 number = (INT32)luaL_checkinteger(L, 5); INT32 number = (INT32)luaL_checkinteger(L, 5);
mobjtype_t type = luaL_checkinteger(L, 6); mobjtype_t type = luaL_checkinteger(L, 6);
angle_t rotangle = (angle_t)luaL_checkinteger(L, 7); angle_t rotangle = luaL_checkangle(L, 7);
statenum_t nstate = luaL_optinteger(L, 8, S_NULL); statenum_t nstate = luaL_optinteger(L, 8, S_NULL);
boolean spawncenter = lua_optboolean(L, 9); boolean spawncenter = lua_optboolean(L, 9);
NOHUD NOHUD
...@@ -458,7 +451,7 @@ static int lib_pSupermanLook4Players(lua_State *L) ...@@ -458,7 +451,7 @@ static int lib_pSupermanLook4Players(lua_State *L)
static int lib_pSetScale(lua_State *L) static int lib_pSetScale(lua_State *L)
{ {
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t newscale = (fixed_t)luaL_checkinteger(L, 2); fixed_t newscale = luaL_checkfixed(L, 2);
NOHUD NOHUD
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -526,7 +519,7 @@ static int lib_pGetPlayerHeight(lua_State *L) ...@@ -526,7 +519,7 @@ static int lib_pGetPlayerHeight(lua_State *L)
//HUDSAFE //HUDSAFE
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, P_GetPlayerHeight(player)); lua_pushfixed(L, P_GetPlayerHeight(player));
return 1; return 1;
} }
...@@ -536,7 +529,7 @@ static int lib_pGetPlayerSpinHeight(lua_State *L) ...@@ -536,7 +529,7 @@ static int lib_pGetPlayerSpinHeight(lua_State *L)
//HUDSAFE //HUDSAFE
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, P_GetPlayerSpinHeight(player)); lua_pushfixed(L, P_GetPlayerSpinHeight(player));
return 1; return 1;
} }
...@@ -639,7 +632,7 @@ static int lib_pInQuicksand(lua_State *L) ...@@ -639,7 +632,7 @@ static int lib_pInQuicksand(lua_State *L)
static int lib_pSetObjectMomZ(lua_State *L) static int lib_pSetObjectMomZ(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t value = (fixed_t)luaL_checkinteger(L, 2); fixed_t value = luaL_checkfixed(L, 2);
boolean relative = lua_optboolean(L, 3); boolean relative = lua_optboolean(L, 3);
NOHUD NOHUD
if (!mo) if (!mo)
...@@ -753,8 +746,8 @@ static int lib_pDoPlayerExit(lua_State *L) ...@@ -753,8 +746,8 @@ static int lib_pDoPlayerExit(lua_State *L)
static int lib_pInstaThrust(lua_State *L) static int lib_pInstaThrust(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
angle_t angle = (angle_t)luaL_checkinteger(L, 2); angle_t angle = luaL_checkangle(L, 2);
fixed_t move = (fixed_t)luaL_checkinteger(L, 3); fixed_t move = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!mo) if (!mo)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -768,10 +761,10 @@ static int lib_pReturnThrustX(lua_State *L) ...@@ -768,10 +761,10 @@ static int lib_pReturnThrustX(lua_State *L)
fixed_t move; fixed_t move;
if (lua_isnil(L, 1) || lua_isuserdata(L, 1)) if (lua_isnil(L, 1) || lua_isuserdata(L, 1))
lua_remove(L, 1); // ignore mobj as arg1 lua_remove(L, 1); // ignore mobj as arg1
angle = (angle_t)luaL_checkinteger(L, 1); angle = luaL_checkangle(L, 1);
move = (fixed_t)luaL_checkinteger(L, 2); move = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, P_ReturnThrustX(NULL, angle, move)); lua_pushfixed(L, P_ReturnThrustX(NULL, angle, move));
return 1; return 1;
} }
...@@ -781,10 +774,10 @@ static int lib_pReturnThrustY(lua_State *L) ...@@ -781,10 +774,10 @@ static int lib_pReturnThrustY(lua_State *L)
fixed_t move; fixed_t move;
if (lua_isnil(L, 1) || lua_isuserdata(L, 1)) if (lua_isnil(L, 1) || lua_isuserdata(L, 1))
lua_remove(L, 1); // ignore mobj as arg1 lua_remove(L, 1); // ignore mobj as arg1
angle = (angle_t)luaL_checkinteger(L, 1); angle = luaL_checkangle(L, 1);
move = (fixed_t)luaL_checkinteger(L, 2); move = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, P_ReturnThrustY(NULL, angle, move)); lua_pushfixed(L, P_ReturnThrustY(NULL, angle, move));
return 1; return 1;
} }
...@@ -802,7 +795,7 @@ static int lib_pNukeEnemies(lua_State *L) ...@@ -802,7 +795,7 @@ static int lib_pNukeEnemies(lua_State *L)
{ {
mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
fixed_t radius = (fixed_t)luaL_checkinteger(L, 3); fixed_t radius = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!inflictor || !source) if (!inflictor || !source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -868,8 +861,8 @@ static int lib_pSpawnSpinMobj(lua_State *L) ...@@ -868,8 +861,8 @@ static int lib_pSpawnSpinMobj(lua_State *L)
static int lib_pTelekinesis(lua_State *L) static int lib_pTelekinesis(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
fixed_t thrust = (fixed_t)luaL_checkinteger(L, 2); fixed_t thrust = luaL_checkfixed(L, 2);
fixed_t range = (fixed_t)luaL_checkinteger(L, 3); fixed_t range = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
...@@ -884,8 +877,8 @@ static int lib_pCheckPosition(lua_State *L) ...@@ -884,8 +877,8 @@ static int lib_pCheckPosition(lua_State *L)
{ {
mobj_t *ptmthing = tmthing; mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = (fixed_t)luaL_checkinteger(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = (fixed_t)luaL_checkinteger(L, 3); fixed_t y = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!thing) if (!thing)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -899,8 +892,8 @@ static int lib_pTryMove(lua_State *L) ...@@ -899,8 +892,8 @@ static int lib_pTryMove(lua_State *L)
{ {
mobj_t *ptmthing = tmthing; mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = (fixed_t)luaL_checkinteger(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = (fixed_t)luaL_checkinteger(L, 3); fixed_t y = luaL_checkfixed(L, 3);
boolean allowdropoff = lua_optboolean(L, 4); boolean allowdropoff = lua_optboolean(L, 4);
NOHUD NOHUD
if (!thing) if (!thing)
...@@ -915,7 +908,7 @@ static int lib_pMove(lua_State *L) ...@@ -915,7 +908,7 @@ static int lib_pMove(lua_State *L)
{ {
mobj_t *ptmthing = tmthing; mobj_t *ptmthing = tmthing;
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t speed = (fixed_t)luaL_checkinteger(L, 2); fixed_t speed = luaL_checkfixed(L, 2);
NOHUD NOHUD
if (!actor) if (!actor)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -929,9 +922,9 @@ static int lib_pTeleportMove(lua_State *L) ...@@ -929,9 +922,9 @@ static int lib_pTeleportMove(lua_State *L)
{ {
mobj_t *ptmthing = tmthing; mobj_t *ptmthing = tmthing;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = (fixed_t)luaL_checkinteger(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = (fixed_t)luaL_checkinteger(L, 3); fixed_t y = luaL_checkfixed(L, 3);
fixed_t z = (fixed_t)luaL_checkinteger(L, 4); fixed_t z = luaL_checkfixed(L, 4);
NOHUD NOHUD
if (!thing) if (!thing)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -975,10 +968,10 @@ static int lib_pCheckSight(lua_State *L) ...@@ -975,10 +968,10 @@ static int lib_pCheckSight(lua_State *L)
static int lib_pCheckHoopPosition(lua_State *L) static int lib_pCheckHoopPosition(lua_State *L)
{ {
mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = (fixed_t)luaL_checkinteger(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = (fixed_t)luaL_checkinteger(L, 3); fixed_t y = luaL_checkfixed(L, 3);
fixed_t z = (fixed_t)luaL_checkinteger(L, 4); fixed_t z = luaL_checkfixed(L, 4);
fixed_t radius = (fixed_t)luaL_checkinteger(L, 5); fixed_t radius = luaL_checkfixed(L, 5);
NOHUD NOHUD
if (!hoopthing) if (!hoopthing)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -990,7 +983,7 @@ static int lib_pRadiusAttack(lua_State *L) ...@@ -990,7 +983,7 @@ static int lib_pRadiusAttack(lua_State *L)
{ {
mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
fixed_t damagedist = (fixed_t)luaL_checkinteger(L, 3); fixed_t damagedist = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!spot || !source) if (!spot || !source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -1000,12 +993,12 @@ static int lib_pRadiusAttack(lua_State *L) ...@@ -1000,12 +993,12 @@ static int lib_pRadiusAttack(lua_State *L)
static int lib_pFloorzAtPos(lua_State *L) static int lib_pFloorzAtPos(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
fixed_t z = (fixed_t)luaL_checkinteger(L, 3); fixed_t z = luaL_checkfixed(L, 3);
fixed_t height = (fixed_t)luaL_checkinteger(L, 4); fixed_t height = luaL_checkfixed(L, 4);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, P_FloorzAtPos(x, y, z, height)); lua_pushfixed(L, P_FloorzAtPos(x, y, z, height));
return 1; return 1;
} }
...@@ -1016,8 +1009,8 @@ static int lib_pDoSpring(lua_State *L) ...@@ -1016,8 +1009,8 @@ static int lib_pDoSpring(lua_State *L)
NOHUD NOHUD
if (!spring || !object) if (!spring || !object)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
P_DoSpring(spring, object); lua_pushboolean(L, P_DoSpring(spring, object));
return 0; return 1;
} }
// P_INTER // P_INTER
...@@ -1209,8 +1202,8 @@ static int lib_pDoNightsScore(lua_State *L) ...@@ -1209,8 +1202,8 @@ static int lib_pDoNightsScore(lua_State *L)
static int lib_pThrust(lua_State *L) static int lib_pThrust(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
angle_t angle = (angle_t)luaL_checkinteger(L, 2); angle_t angle = luaL_checkangle(L, 2);
fixed_t move = (fixed_t)luaL_checkinteger(L, 3); fixed_t move = luaL_checkfixed(L, 3);
NOHUD NOHUD
if (!mo) if (!mo)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
...@@ -1485,48 +1478,48 @@ static int lib_evCrumbleChain(lua_State *L) ...@@ -1485,48 +1478,48 @@ static int lib_evCrumbleChain(lua_State *L)
static int lib_rPointToAngle(lua_State *L) static int lib_rPointToAngle(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, R_PointToAngle(x, y)); lua_pushangle(L, R_PointToAngle(x, y));
return 1; return 1;
} }
static int lib_rPointToAngle2(lua_State *L) static int lib_rPointToAngle2(lua_State *L)
{ {
fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1); fixed_t px2 = luaL_checkfixed(L, 1);
fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2); fixed_t py2 = luaL_checkfixed(L, 2);
fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3); fixed_t px1 = luaL_checkfixed(L, 3);
fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4); fixed_t py1 = luaL_checkfixed(L, 4);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, R_PointToAngle2(px2, py2, px1, py1)); lua_pushangle(L, R_PointToAngle2(px2, py2, px1, py1));
return 1; return 1;
} }
static int lib_rPointToDist(lua_State *L) static int lib_rPointToDist(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, R_PointToDist(x, y)); lua_pushfixed(L, R_PointToDist(x, y));
return 1; return 1;
} }
static int lib_rPointToDist2(lua_State *L) static int lib_rPointToDist2(lua_State *L)
{ {
fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1); fixed_t px2 = luaL_checkfixed(L, 1);
fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2); fixed_t py2 = luaL_checkfixed(L, 2);
fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3); fixed_t px1 = luaL_checkfixed(L, 3);
fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4); fixed_t py1 = luaL_checkfixed(L, 4);
//HUDSAFE //HUDSAFE
lua_pushinteger(L, R_PointToDist2(px2, py2, px1, py1)); lua_pushfixed(L, R_PointToDist2(px2, py2, px1, py1));
return 1; return 1;
} }
static int lib_rPointInSubsector(lua_State *L) static int lib_rPointInSubsector(lua_State *L)
{ {
fixed_t x = (fixed_t)luaL_checkinteger(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = (fixed_t)luaL_checkinteger(L, 2); fixed_t y = luaL_checkfixed(L, 2);
//HUDSAFE //HUDSAFE
LUA_PushUserdata(L, R_PointInSubsector(x, y), META_SUBSECTOR); LUA_PushUserdata(L, R_PointInSubsector(x, y), META_SUBSECTOR);
return 1; return 1;
...@@ -1660,7 +1653,7 @@ static int lib_sChangeMusic(lua_State *L) ...@@ -1660,7 +1653,7 @@ static int lib_sChangeMusic(lua_State *L)
static int lib_sSpeedMusic(lua_State *L) static int lib_sSpeedMusic(lua_State *L)
{ {
fixed_t fixedspeed = (fixed_t)luaL_checkinteger(L, 1); fixed_t fixedspeed = luaL_checkfixed(L, 1);
float speed = FIXED_TO_FLOAT(fixedspeed); float speed = FIXED_TO_FLOAT(fixedspeed);
player_t *player = NULL; player_t *player = NULL;
NOHUD NOHUD
...@@ -1861,7 +1854,6 @@ static int lib_gTicsToMilliseconds(lua_State *L) ...@@ -1861,7 +1854,6 @@ static int lib_gTicsToMilliseconds(lua_State *L)
static luaL_Reg lib[] = { static luaL_Reg lib[] = {
{"print", lib_print}, {"print", lib_print},
{"EvalMath", lib_evalMath},
// m_random // m_random
{"P_Random",lib_pRandom}, {"P_Random",lib_pRandom},
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "r_defs.h" #include "r_defs.h"
#include "d_player.h" #include "d_player.h"
#include "blua/lua.h"
enum hook { enum hook {
hook_NetVars=0, hook_NetVars=0,
...@@ -41,12 +42,13 @@ enum hook { ...@@ -41,12 +42,13 @@ enum hook {
hook_BotAI, hook_BotAI,
hook_LinedefExecute, hook_LinedefExecute,
hook_PlayerMsg, hook_PlayerMsg,
hook_DeathMsg, hook_HurtMsg,
hook_MAX // last hook hook_MAX // last hook
}; };
extern const char *const hookNames[]; extern const char *const hookNames[];
void LUAh_NetArchiveHook(lua_CFunction archFunc);
void LUAh_MapChange(void); // Hook for map change (before load) void LUAh_MapChange(void); // Hook for map change (before load)
void LUAh_MapLoad(void); // Hook for map load void LUAh_MapLoad(void); // Hook for map load
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
...@@ -54,8 +56,9 @@ void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) ...@@ -54,8 +56,9 @@ void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers)
boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_MobjHook(mobj_t *mo, enum hook which);
boolean LUAh_PlayerHook(player_t *plr, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which);
#define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type
UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (thing) mobj type UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which);
UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (tmthing) mobj type #define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type
#define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type
#define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type
#define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type #define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type
...@@ -73,6 +76,6 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd ...@@ -73,6 +76,6 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
#endif #endif
...@@ -56,23 +56,40 @@ const char *const hookNames[hook_MAX+1] = { ...@@ -56,23 +56,40 @@ const char *const hookNames[hook_MAX+1] = {
NULL NULL
}; };
// Hook metadata
struct hook_s
{
struct hook_s *next;
enum hook type;
UINT16 id;
union {
mobjtype_t mt;
char *skinname;
char *funcname;
} s;
boolean error;
};
typedef struct hook_s* hook_p;
#define FMT_HOOKID "hook_%d"
hook_p roothook;
// Takes hook, function, and additional arguments (mobj type to act on, etc.) // Takes hook, function, and additional arguments (mobj type to act on, etc.)
static int lib_addHook(lua_State *L) static int lib_addHook(lua_State *L)
{ {
UINT16 hook; static struct hook_s hook = {NULL, 0, 0, {0}, false};
boolean notable = false; hook_p hookp, *lastp;
boolean subtable = false;
UINT32 subindex = 0; hook.type = luaL_checkoption(L, 1, NULL, hookNames);
char *subfield = NULL; lua_remove(L, 1);
const char *lsubfield = NULL;
hook = (UINT16)luaL_checkoption(L, 1, NULL, hookNames); luaL_checktype(L, 1, LUA_TFUNCTION);
luaL_checktype(L, 2, LUA_TFUNCTION);
if (hud_running) if (hud_running)
return luaL_error(L, "HUD rendering code should not call this function!"); return luaL_error(L, "HUD rendering code should not call this function!");
switch(hook) switch(hook.type)
{ {
// Take a mobjtype enum which this hook is specifically for. // Take a mobjtype enum which this hook is specifically for.
case hook_MobjSpawn: case hook_MobjSpawn:
...@@ -87,918 +104,696 @@ static int lib_addHook(lua_State *L) ...@@ -87,918 +104,696 @@ static int lib_addHook(lua_State *L)
case hook_MobjDeath: case hook_MobjDeath:
case hook_BossDeath: case hook_BossDeath:
case hook_MobjRemoved: case hook_MobjRemoved:
subtable = true; case hook_HurtMsg:
if (lua_isnumber(L, 3)) hook.s.mt = MT_NULL;
subindex = (UINT32)luaL_checkinteger(L, 3); if (lua_isnumber(L, 2))
else hook.s.mt = lua_tonumber(L, 2);
lsubfield = "a";
lua_settop(L, 2);
break; break;
case hook_BotAI: // Only one AI function per skin, please! case hook_BotAI:
notable = true; hook.s.skinname = NULL;
subtable = true; if (lua_isstring(L, 2))
subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1);
{ // lowercase copy { // lowercase copy
char *p = subfield; const char *s = lua_tostring(L, 2);
const char *s = luaL_checkstring(L, 3); char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1);
do { do {
*p = tolower(*s); *p = tolower(*s);
++p; ++p;
} while(*(++s)); } while(*(++s));
*p = 0; *p = 0;
} }
lua_settop(L, 3);
break; break;
case hook_LinedefExecute: // Get one linedef executor function by name case hook_LinedefExecute: // Linedef executor functions
notable = true;
subtable = true;
subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1);
{ // uppercase copy { // uppercase copy
char *p = subfield; const char *s = luaL_checkstring(L, 2);
const char *s = luaL_checkstring(L, 3); char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1);
do { do {
*p = toupper(*s); *p = toupper(*s);
++p; ++p;
} while(*(++s)); } while(*(++s));
*p = 0; *p = 0;
} }
lua_settop(L, 3);
break; break;
default: default:
lua_settop(L, 2);
break; break;
} }
lua_settop(L, 1); // lua stack contains only the function now.
lua_getfield(L, LUA_REGISTRYINDEX, "hook"); hooksAvailable[hook.type/8] |= 1<<(hook.type%8);
I_Assert(lua_istable(L, -1));
// This hook type only allows one entry, not an array of hooks. // iterate the hook metadata structs
// New hooks will overwrite the previous ones, and the stack is one table shorter. // set hook.id to the highest id + 1
if (notable) // set lastp to the last hook struct's "next" pointer.
lastp = &roothook;
hook.id = 0;
for (hookp = roothook; hookp; hookp = hookp->next)
{ {
if (subtable) if (hookp->id >= hook.id)
{ hook.id = hookp->id+1;
lua_rawgeti(L, -1, hook); lastp = &hookp->next;
lua_remove(L, -2); // pop "hook"
I_Assert(lua_istable(L, -1));
lua_pushvalue(L, 2);
if (subfield)
lua_setfield(L, -2, subfield);
else if (lsubfield)
lua_setfield(L, -2, lsubfield);
else
lua_rawseti(L, -2, subindex);
} else {
lua_pushvalue(L, 2);
lua_rawseti(L, -2, hook);
}
hooksAvailable[hook/8] |= 1<<(hook%8);
return 0;
} }
// Fetch the hook's table from the registry. // allocate a permanent memory struct to stuff hook.
// It should always exist, since LUA_HookLib creates a table for every hook. hookp = ZZ_Alloc(sizeof(struct hook_s));
lua_rawgeti(L, -1, hook); memcpy(hookp, &hook, sizeof(struct hook_s));
lua_remove(L, -2); // pop "hook" // tack it onto the end of the linked list.
I_Assert(lua_istable(L, -1)); *lastp = hookp;
if (subtable)
{ // set the hook function in the registry.
// Fetch a subtable based on index lua_pushfstring(L, FMT_HOOKID, hook.id);
if (subfield) lua_pushvalue(L, 1);
lua_getfield(L, -1, subfield); lua_settable(L, LUA_REGISTRYINDEX);
else if (lsubfield)
lua_getfield(L, -1, lsubfield);
else
lua_rawgeti(L, -1, subindex);
// Subtable doesn't exist, make one now.
if (lua_isnil(L, -1))
{
lua_pop(L, 1);
lua_newtable(L);
// Store a link to the subtable for later.
lua_pushvalue(L, -1);
if (subfield)
lua_setfield(L, -3, subfield);
else if (lsubfield)
lua_setfield(L, -3, lsubfield);
else
lua_rawseti(L, -3, subindex);
} }
// Add function to the table.
lua_pushvalue(L, 2);
lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1));
if (subfield)
Z_Free(subfield);
hooksAvailable[hook/8] |= 1<<(hook%8);
return 0; return 0;
} }
int LUA_HookLib(lua_State *L) int LUA_HookLib(lua_State *L)
{ {
// Create all registry tables
enum hook i;
memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1])); memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1]));
roothook = NULL;
lua_newtable(L);
for (i = 0; i < hook_MAX; i++)
{
lua_newtable(L);
switch(i)
{
default:
break;
case hook_MobjSpawn:
case hook_MobjCollide:
case hook_MobjMoveCollide:
case hook_TouchSpecial:
case hook_MobjFuse:
case hook_MobjThinker:
case hook_BossThinker:
case hook_ShouldDamage:
case hook_MobjDamage:
case hook_MobjDeath:
case hook_BossDeath:
case hook_MobjRemoved:
lua_pushstring(L, "a");
lua_newtable(L);
lua_rawset(L, -3);
break;
}
lua_rawseti(L, -2, i);
}
lua_setfield(L, LUA_REGISTRYINDEX, "hook");
lua_register(L, "addHook", lib_addHook); lua_register(L, "addHook", lib_addHook);
return 0; return 0;
} }
boolean LUAh_MobjHook(mobj_t *mo, enum hook which) void LUAh_NetArchiveHook(lua_CFunction archFunc)
{ {
boolean hooked = false; int TABLESINDEX;
if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) hook_p hookp;
return false;
// clear the stack (just in case) if (!gL)
lua_pop(gL, -1); return;
// hook table TABLESINDEX = lua_gettop(gL);
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, which);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// generic subtable lua_settop(gL, 0);
lua_pushstring(gL, "a");
lua_rawget(gL, -2);
I_Assert(lua_istable(gL, -1));
LUA_PushUserdata(gL, mo, META_MOBJ); lua_pushvalue(gL, TABLESINDEX);
lua_pushcclosure(gL, archFunc, 1);
lua_pushnil(gL); lua_pushnil(gL);
while (lua_next(gL, -3)) {
CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for generic mobj types\n", hookNames[which]); for (hookp = roothook; hookp; hookp = hookp->next)
lua_pushvalue(gL, -3); // mo if (hookp->type == hook_NetVars)
// stack is: hook_Mobj table, subtable "a", mobj, i, function, mobj
if (lua_pcall(gL, 1, 1, 0)) {
// A run-time error occurred.
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL, 1);
// Remove this function from the hook table to prevent further errors.
lua_pushvalue(gL, -1); // key
lua_pushnil(gL); // value
lua_rawset(gL, -5); // table
CONS_Printf("Hook removed.\n");
}
else
{ {
if (lua_toboolean(gL, -1)) lua_pushfstring(gL, FMT_HOOKID, hookp->id);
hooked = true; lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pop(gL, 1); lua_pushvalue(gL, -2);
LUA_Call(gL, 1);
} }
}
// stack is: hook_Mobj table, subtable "a", mobj lua_pop(gL, 2);
lua_remove(gL, -2); // pop subtable, leave mobj }
// mobjtype subtable boolean LUAh_MobjHook(mobj_t *mo, enum hook which)
// stack is: hook_Mobj table, mobj {
lua_rawgeti(gL, -2, mo->type); hook_p hookp;
if (lua_isnil(gL, -1)) { boolean hooked = false;
lua_pop(gL, 3); // pop hook_Mobj table, mobj, and nil if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
// the stack should now be empty.
return false; return false;
}
lua_remove(gL, -3); // remove hook table
// stack is: mobj, mobjtype subtable
lua_insert(gL, lua_gettop(gL)-1); // swap subtable with mobj
// stack is: mobjtype subtable, mobj
lua_pushnil(gL); lua_settop(gL, 0);
while (lua_next(gL, -3)) {
CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for mobj type %d\n", hookNames[which], mo->type); for (hookp = roothook; hookp; hookp = hookp->next)
lua_pushvalue(gL, -3); // mo if (hookp->type == which
// stack is: mobjtype subtable, mobj, i, function, mobj && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type))
if (lua_pcall(gL, 1, 1, 0)) {
// A run-time error occurred.
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL, 1);
// Remove this function from the hook table to prevent further errors.
lua_pushvalue(gL, -1); // key
lua_pushnil(gL); // value
lua_rawset(gL, -5); // table
CONS_Printf("Hook removed.\n");
}
else
{ {
if (lua_gettop(gL) == 0)
LUA_PushUserdata(gL, mo, META_MOBJ);
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -2);
if (lua_pcall(gL, 1, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1)) if (lua_toboolean(gL, -1))
hooked = true; hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
} }
}
lua_pop(gL, 2); // pop mobj and subtable lua_settop(gL, 0);
// the stack should now be empty.
lua_gc(gL, LUA_GCSTEP, 3);
return hooked; return hooked;
} }
boolean LUAh_PlayerHook(player_t *plr, enum hook which) boolean LUAh_PlayerHook(player_t *plr, enum hook which)
{ {
hook_p hookp;
boolean hooked = false; boolean hooked = false;
if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
return false; return false;
// clear the stack (just in case) lua_settop(gL, 0);
lua_pop(gL, -1);
// hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, which);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
LUA_PushUserdata(gL, plr, META_PLAYER);
lua_pushnil(gL); for (hookp = roothook; hookp; hookp = hookp->next)
while (lua_next(gL, -3) != 0) { if (hookp->type == which)
lua_pushvalue(gL, -3); // player {
if (lua_pcall(gL, 1, 1, 0)) { // pops hook function, player, pushes 1 return result if (lua_gettop(gL) == 0)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); LUA_PushUserdata(gL, plr, META_PLAYER);
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -2);
if (lua_pcall(gL, 1, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1)) // if return true,
hooked = true; // override vanilla behavior
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, -1); lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
return hooked; return hooked;
} }
// Hook for map change (before load) // Hook for map change (before load)
void LUAh_MapChange(void) void LUAh_MapChange(void)
{ {
hook_p hookp;
if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8)))) if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8))))
return; return;
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); lua_settop(gL, 0);
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_MapChange);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
lua_pushinteger(gL, gamemap); lua_pushinteger(gL, gamemap);
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) { for (hookp = roothook; hookp; hookp = hookp->next)
lua_pushvalue(gL, -3); // gamemap if (hookp->type == hook_MapChange)
LUA_Call(gL, 1); {
} lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_pop(gL, 1); lua_gettable(gL, LUA_REGISTRYINDEX);
lua_gc(gL, LUA_GCSTEP, 1); lua_pushvalue(gL, -2);
LUA_Call(gL, 1);
}
lua_settop(gL, 0);
} }
// Hook for map load // Hook for map load
void LUAh_MapLoad(void) void LUAh_MapLoad(void)
{ {
hook_p hookp;
if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8)))) if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8))))
return; return;
lua_pop(gL, -1); lua_settop(gL, 0);
lua_pushinteger(gL, gamemap);
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); for (hookp = roothook; hookp; hookp = hookp->next)
I_Assert(lua_istable(gL, -1)); if (hookp->type == hook_MapLoad)
lua_rawgeti(gL, -1, hook_MapLoad); {
lua_remove(gL, -2); lua_pushfstring(gL, FMT_HOOKID, hookp->id);
I_Assert(lua_istable(gL, -1)); lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -2);
LUA_Call(gL, 1);
}
lua_pushinteger(gL, gamemap); lua_settop(gL, 0);
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // gamemap
LUA_Call(gL, 1);
}
lua_pop(gL, -1);
lua_gc(gL, LUA_GCCOLLECT, 0);
} }
// Hook for Got_AddPlayer // Hook for Got_AddPlayer
void LUAh_PlayerJoin(int playernum) void LUAh_PlayerJoin(int playernum)
{ {
hook_p hookp;
if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8)))) if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8))))
return; return;
lua_pop(gL, -1); lua_settop(gL, 0);
lua_pushinteger(gL, playernum);
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); for (hookp = roothook; hookp; hookp = hookp->next)
I_Assert(lua_istable(gL, -1)); if (hookp->type == hook_PlayerJoin)
lua_rawgeti(gL, -1, hook_PlayerJoin); {
lua_remove(gL, -2); lua_pushfstring(gL, FMT_HOOKID, hookp->id);
I_Assert(lua_istable(gL, -1)); lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -2);
LUA_Call(gL, 1);
}
lua_pushinteger(gL, playernum); lua_settop(gL, 0);
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // playernum
LUA_Call(gL, 1);
}
lua_pop(gL, -1);
lua_gc(gL, LUA_GCCOLLECT, 0);
} }
// Hook for frame (after mobj and player thinkers) // Hook for frame (after mobj and player thinkers)
void LUAh_ThinkFrame(void) void LUAh_ThinkFrame(void)
{ {
hook_p hookp;
if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8))))
return; return;
lua_pop(gL, -1); for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_ThinkFrame)
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_ThinkFrame);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
lua_pushnil(gL);
while (lua_next(gL, -2) != 0)
{
//LUA_Call(gL, 0);
if (lua_pcall(gL, 0, 0, 0))
{ {
// A run-time error occurred. lua_pushfstring(gL, FMT_HOOKID, hookp->id);
CONS_Alert(CONS_WARNING,"%s\n", lua_tostring(gL, -1)); lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pop(gL, 1); if (lua_pcall(gL, 0, 0, 0)) {
// Remove this function from the hook table to prevent further errors. if (!hookp->error || cv_debug & DBG_LUA)
lua_pushvalue(gL, -1); // key CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pushnil(gL); // value lua_pop(gL, 1);
lua_rawset(gL, -4); // table hookp->error = true;
CONS_Printf("Hook removed.\n"); }
}
}
lua_pop(gL, -1);
lua_gc(gL, LUA_GCCOLLECT, 0);
}
// Hook for PIT_CheckThing by (thing) mobj type (thing1 = thing, thing2 = tmthing)
UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2)
{
UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_MobjCollide/8] & (1<<(hook_MobjCollide%8))))
return 0;
// clear the stack
lua_pop(gL, -1);
// hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_MobjCollide);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// mobjtype subtable
lua_rawgeti(gL, -1, thing1->type);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return 0;
}
lua_remove(gL, -2); // remove hook table
LUA_PushUserdata(gL, thing1, META_MOBJ);
LUA_PushUserdata(gL, thing2, META_MOBJ);
lua_pushnil(gL);
while (lua_next(gL, -4)) {
lua_pushvalue(gL, -4); // thing1
lua_pushvalue(gL, -4); // thing2
if (lua_pcall(gL, 2, 1, 0)) {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL, 1);
continue;
} }
if (!lua_isnil(gL, -1))
{ // if nil, leave shouldCollide = 0.
if (lua_toboolean(gL, -1))
shouldCollide = 1; // Force yes
else
shouldCollide = 2; // Force no
}
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 3); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1);
return shouldCollide;
} }
// Hook for PIT_CheckThing by (tmthing) mobj type (thing1 = tmthing, thing2 = thing) // Hook for mobj collisions
UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2) UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which)
{ {
hook_p hookp;
UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_MobjMoveCollide/8] & (1<<(hook_MobjMoveCollide%8)))) if (!gL || !(hooksAvailable[which/8] & (1<<(which%8))))
return 0; return 0;
// clear the stack lua_settop(gL, 0);
lua_pop(gL, -1);
// hook table for (hookp = roothook; hookp; hookp = hookp->next)
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); if (hookp->type == which
I_Assert(lua_istable(gL, -1)); && (hookp->s.mt == MT_NULL || hookp->s.mt == thing1->type))
lua_rawgeti(gL, -1, hook_MobjMoveCollide); {
lua_remove(gL, -2); if (lua_gettop(gL) == 0)
I_Assert(lua_istable(gL, -1)); {
LUA_PushUserdata(gL, thing1, META_MOBJ);
// mobjtype subtable LUA_PushUserdata(gL, thing2, META_MOBJ);
lua_rawgeti(gL, -1, thing1->type); }
if (lua_isnil(gL, -1)) { lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_pop(gL, 2); lua_gettable(gL, LUA_REGISTRYINDEX);
return 0; lua_pushvalue(gL, -3);
} lua_pushvalue(gL, -3);
lua_remove(gL, -2); // remove hook table if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
LUA_PushUserdata(gL, thing1, META_MOBJ); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
LUA_PushUserdata(gL, thing2, META_MOBJ); lua_pop(gL, 1);
lua_pushnil(gL); hookp->error = true;
while (lua_next(gL, -4)) { continue;
lua_pushvalue(gL, -4); // thing1 }
lua_pushvalue(gL, -4); // thing2 if (!lua_isnil(gL, -1))
if (lua_pcall(gL, 2, 1, 0)) { { // if nil, leave shouldCollide = 0.
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); if (lua_toboolean(gL, -1))
shouldCollide = 1; // Force yes
else
shouldCollide = 2; // Force no
}
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (!lua_isnil(gL, -1))
{ // if nil, leave shouldCollide = 0.
if (lua_toboolean(gL, -1))
shouldCollide = 1; // Force yes
else
shouldCollide = 2; // Force no
}
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 3); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return shouldCollide; return shouldCollide;
} }
// Hook for P_TouchSpecialThing by mobj type // Hook for P_TouchSpecialThing by mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher)
{ {
hook_p hookp;
boolean hooked = false; boolean hooked = false;
if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8)))) if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8))))
return false; return 0;
// clear the stack
lua_pop(gL, -1);
// get hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_TouchSpecial);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// get mobjtype subtable
lua_pushinteger(gL, special->type);
lua_rawget(gL, 1);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return false;
}
lua_remove(gL, 1); // pop hook table off the stack
LUA_PushUserdata(gL, special, META_MOBJ); lua_settop(gL, 0);
LUA_PushUserdata(gL, toucher, META_MOBJ);
lua_pushnil(gL); for (hookp = roothook; hookp; hookp = hookp->next)
while (lua_next(gL, 1) != 0) { if (hookp->type == hook_TouchSpecial
lua_pushvalue(gL, 2); // special && (hookp->s.mt == MT_NULL || hookp->s.mt == special->type))
lua_pushvalue(gL, 3); // toucher {
if (lua_pcall(gL, 2, 1, 0)) { // pops hook function, special, toucher, pushes 1 return result if (lua_gettop(gL) == 0)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); {
LUA_PushUserdata(gL, special, META_MOBJ);
LUA_PushUserdata(gL, toucher, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1)) // if return true,
hooked = true; // override vanilla behavior
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, -1); lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
return hooked; return hooked;
} }
// Hook for P_DamageMobj by mobj type (Should mobj take damage?) // Hook for P_DamageMobj by mobj type (Should mobj take damage?)
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{ {
hook_p hookp;
UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8)))) if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8))))
return 0; return 0;
// clear the stack lua_settop(gL, 0);
lua_pop(gL, -1);
// hook table for (hookp = roothook; hookp; hookp = hookp->next)
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); if (hookp->type == hook_ShouldDamage
I_Assert(lua_istable(gL, -1)); && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
lua_rawgeti(gL, -1, hook_ShouldDamage); {
lua_remove(gL, -2); if (lua_gettop(gL) == 0)
I_Assert(lua_istable(gL, -1)); {
LUA_PushUserdata(gL, target, META_MOBJ);
// mobjtype subtable LUA_PushUserdata(gL, inflictor, META_MOBJ);
lua_rawgeti(gL, -1, target->type); LUA_PushUserdata(gL, source, META_MOBJ);
if (lua_isnil(gL, -1)) { lua_pushinteger(gL, damage);
lua_pop(gL, 2); }
return 0; lua_pushfstring(gL, FMT_HOOKID, hookp->id);
} lua_gettable(gL, LUA_REGISTRYINDEX);
lua_remove(gL, -2); // remove hook table lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
LUA_PushUserdata(gL, target, META_MOBJ); lua_pushvalue(gL, -5);
LUA_PushUserdata(gL, inflictor, META_MOBJ); lua_pushvalue(gL, -5);
LUA_PushUserdata(gL, source, META_MOBJ); if (lua_pcall(gL, 4, 1, 0)) {
lua_pushinteger(gL, damage); if (!hookp->error || cv_debug & DBG_LUA)
lua_pushnil(gL); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
while (lua_next(gL, -6)) { lua_pop(gL, 1);
lua_pushvalue(gL, -6); // target hookp->error = true;
lua_pushvalue(gL, -6); // inflictor continue;
lua_pushvalue(gL, -6); // source }
lua_pushvalue(gL, -6); // damage if (!lua_isnil(gL, -1))
if (lua_pcall(gL, 4, 1, 0)) { {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); if (lua_toboolean(gL, -1))
shouldDamage = 1; // Force yes
else
shouldDamage = 2; // Force no
}
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (!lua_isnil(gL, -1))
{ // if nil, leave shouldDamage = 0.
if (lua_toboolean(gL, -1))
shouldDamage = 1; // Force yes
else
shouldDamage = 2; // Force no
}
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 5); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return shouldDamage; return shouldDamage;
} }
// Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{ {
boolean handled = false; hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8)))) if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8))))
return false; return 0;
// clear the stack
lua_pop(gL, -1);
// hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_MobjDamage);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// mobjtype subtable lua_settop(gL, 0);
lua_rawgeti(gL, -1, target->type);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return false;
}
lua_remove(gL, -2); // remove hook table
LUA_PushUserdata(gL, target, META_MOBJ); for (hookp = roothook; hookp; hookp = hookp->next)
LUA_PushUserdata(gL, inflictor, META_MOBJ); if (hookp->type == hook_MobjDamage
LUA_PushUserdata(gL, source, META_MOBJ); && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
lua_pushinteger(gL, damage); {
lua_pushnil(gL); if (lua_gettop(gL) == 0)
while (lua_next(gL, -6)) { {
lua_pushvalue(gL, -6); // target LUA_PushUserdata(gL, target, META_MOBJ);
lua_pushvalue(gL, -6); // inflictor LUA_PushUserdata(gL, inflictor, META_MOBJ);
lua_pushvalue(gL, -6); // source LUA_PushUserdata(gL, source, META_MOBJ);
lua_pushvalue(gL, -6); // damage lua_pushinteger(gL, damage);
if (lua_pcall(gL, 4, 1, 0)) { }
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
if (lua_pcall(gL, 4, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1))
handled = true;
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 5); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return handled; return hooked;
} }
// Hook for P_KillMobj by mobj type // Hook for P_KillMobj by mobj type
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{ {
boolean handled = false; hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8)))) if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8))))
return false; return 0;
// clear the stack
lua_pop(gL, -1);
// hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_MobjDeath);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// mobjtype subtable lua_settop(gL, 0);
lua_rawgeti(gL, -1, target->type);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return false;
}
lua_remove(gL, -2); // remove hook table
LUA_PushUserdata(gL, target, META_MOBJ); for (hookp = roothook; hookp; hookp = hookp->next)
LUA_PushUserdata(gL, inflictor, META_MOBJ); if (hookp->type == hook_MobjDeath
LUA_PushUserdata(gL, source, META_MOBJ); && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type))
lua_pushnil(gL); {
while (lua_next(gL, -5)) { if (lua_gettop(gL) == 0)
lua_pushvalue(gL, -5); // target {
lua_pushvalue(gL, -5); // inflictor LUA_PushUserdata(gL, target, META_MOBJ);
lua_pushvalue(gL, -5); // source LUA_PushUserdata(gL, inflictor, META_MOBJ);
if (lua_pcall(gL, 3, 1, 0)) { LUA_PushUserdata(gL, source, META_MOBJ);
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); }
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
if (lua_pcall(gL, 3, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1))
handled = true;
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 4); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return handled; return hooked;
} }
// Hook for B_BuildTiccmd // Hook for B_BuildTiccmd
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd)
{ {
hook_p hookp;
boolean hooked = false; boolean hooked = false;
if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8)))) if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8))))
return false; return false;
// clear the stack lua_settop(gL, 0);
lua_pop(gL, -1);
// hook table for (hookp = roothook; hookp; hookp = hookp->next)
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); if (hookp->type == hook_BotTiccmd)
I_Assert(lua_istable(gL, -1)); {
lua_rawgeti(gL, -1, hook_BotTiccmd); if (lua_gettop(gL) == 0)
lua_remove(gL, -2); {
I_Assert(lua_istable(gL, -1)); LUA_PushUserdata(gL, bot, META_PLAYER);
LUA_PushUserdata(gL, cmd, META_TICCMD);
LUA_PushUserdata(gL, bot, META_PLAYER); }
LUA_PushUserdata(gL, cmd, META_TICCMD); lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushnil(gL); lua_pushvalue(gL, -3);
while (lua_next(gL, 1)) { lua_pushvalue(gL, -3);
lua_pushvalue(gL, 2); // bot if (lua_pcall(gL, 2, 1, 0)) {
lua_pushvalue(gL, 3); // cmd if (!hookp->error || cv_debug & DBG_LUA)
if (lua_pcall(gL, 2, 1, 0)) { CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, -1); lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
return hooked; return hooked;
} }
// Hook for B_BuildTailsTiccmd by skin name // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
{ {
if (!gL || !tails->skin || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) hook_p hookp;
return false; boolean hooked = false;
if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
// clear the stack
lua_pop(gL, -1);
// hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_BotAI);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// bot skin ai function
lua_getfield(gL, 1, ((skin_t *)tails->skin)->name);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return false;
}
lua_remove(gL, 1); // pop the hook table
// Takes sonic, tails
// Returns forward, backward, left, right, jump, spin
LUA_PushUserdata(gL, sonic, META_MOBJ);
LUA_PushUserdata(gL, tails, META_MOBJ);
if (lua_pcall(gL, 2, 8, 0)) {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL,-1);
return false; return false;
}
// This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. lua_settop(gL, 0);
if (lua_istable(gL, 1)) {
boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false;
for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_BotAI
&& (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name)))
{
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, sonic, META_MOBJ);
LUA_PushUserdata(gL, tails, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 8, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
// This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails.
if (lua_istable(gL, 2+1)) {
boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false;
#define CHECKFIELD(field) \ #define CHECKFIELD(field) \
lua_getfield(gL, 1, #field);\ lua_getfield(gL, 2+1, #field);\
if (lua_toboolean(gL, -1))\ if (lua_toboolean(gL, -1))\
field = true;\ field = true;\
lua_pop(gL, 1); lua_pop(gL, 1);
CHECKFIELD(forward) CHECKFIELD(forward)
CHECKFIELD(backward) CHECKFIELD(backward)
CHECKFIELD(left) CHECKFIELD(left)
CHECKFIELD(right) CHECKFIELD(right)
CHECKFIELD(strafeleft) CHECKFIELD(strafeleft)
CHECKFIELD(straferight) CHECKFIELD(straferight)
CHECKFIELD(jump) CHECKFIELD(jump)
CHECKFIELD(spin) CHECKFIELD(spin)
#undef CHECKFIELD #undef CHECKFIELD
B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin);
} else
B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8));
B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); lua_pop(gL, 8);
} else hooked = true;
B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 1), lua_toboolean(gL, 2), lua_toboolean(gL, 3), lua_toboolean(gL, 4), lua_toboolean(gL, 5), lua_toboolean(gL, 6), lua_toboolean(gL, 7), lua_toboolean(gL, 8)); }
lua_pop(gL, -1); lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1); return hooked;
return true;
} }
// Hook for linedef executors // Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{ {
hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8)))) if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8))))
return false; return 0;
// clear the stack
lua_pop(gL, -1);
// get hook table
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_LinedefExecute);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
// get function by line text lua_settop(gL, 0);
lua_getfield(gL, 1, line->text);
if (lua_isnil(gL, -1)) {
lua_pop(gL, 2);
return false;
}
lua_remove(gL, 1); // pop hook table off the stack
LUA_PushUserdata(gL, line, META_LINE); for (hookp = roothook; hookp; hookp = hookp->next)
LUA_PushUserdata(gL, mo, META_MOBJ); if (hookp->type == hook_LinedefExecute
LUA_PushUserdata(gL, sector, META_SECTOR); && !strcmp(hookp->s.funcname, line->text))
LUA_Call(gL, 3); // pops hook function, line, mo, sector {
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, line, META_LINE);
LUA_PushUserdata(gL, mo, META_MOBJ);
LUA_PushUserdata(gL, sector, META_SECTOR);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
LUA_Call(gL, 3);
hooked = true;
}
lua_pop(gL, -1); lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1); return hooked;
return true;
} }
// Hook for PlayerMsg -Red // Hook for player chat
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
{ {
boolean handled = false; hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8))))
return false; return false;
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); lua_settop(gL, 0);
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_PlayerMsg);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player
if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c
lua_pushinteger(gL, 3); // type
lua_pushnil(gL); // target
} else if (target == -1) { // sayteam
lua_pushinteger(gL, 1); // type
lua_pushnil(gL); // target
} else if (target == 0) { // say
lua_pushinteger(gL, 0); // type
lua_pushnil(gL); // target
} else { // sayto
lua_pushinteger(gL, 2); // type
LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
}
lua_pushstring(gL, msg); // msg for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_PlayerMsg)
lua_pushnil(gL); {
if (lua_gettop(gL) == 0)
while (lua_next(gL, -6)) { {
lua_pushvalue(gL, -6); // source LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player
lua_pushvalue(gL, -6); // type if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c
lua_pushvalue(gL, -6); // target lua_pushinteger(gL, 3); // type
lua_pushvalue(gL, -6); // msg lua_pushnil(gL); // target
if (lua_pcall(gL, 4, 1, 0)) { } else if (target == -1) { // sayteam
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pushinteger(gL, 1); // type
lua_pushnil(gL); // target
} else if (target == 0) { // say
lua_pushinteger(gL, 0); // type
lua_pushnil(gL); // target
} else { // sayto
lua_pushinteger(gL, 2); // type
LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
}
lua_pushstring(gL, msg); // msg
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
lua_pushvalue(gL, -5);
if (lua_pcall(gL, 4, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1))
handled = true;
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 4); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return handled; return hooked;
} }
// Hook for hurt messages -Red // Hook for hurt messages
// The internal name is DeathMsg, but the API name is "HurtMsg". Keep that in mind. (Should this be fixed at some point?) boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
// @TODO This hook should be fixed to take mobj type at the addHook parameter to compare to inflictor. (I couldn't get this to work without crashing)
boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
{ {
boolean handled = false; hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_DeathMsg/8] & (1<<(hook_DeathMsg%8)))) if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8))))
return false; return false;
lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); lua_settop(gL, 0);
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_DeathMsg);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
LUA_PushUserdata(gL, player, META_PLAYER); // Player
LUA_PushUserdata(gL, inflictor, META_MOBJ); // Inflictor
LUA_PushUserdata(gL, source, META_MOBJ); // Source
lua_pushnil(gL);
while (lua_next(gL, -5)) { for (hookp = roothook; hookp; hookp = hookp->next)
lua_pushvalue(gL, -5); // player if (hookp->type == hook_HurtMsg
lua_pushvalue(gL, -5); // inflictor && (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type)))
lua_pushvalue(gL, -5); // source {
if (lua_pcall(gL, 3, 1, 0)) { if (lua_gettop(gL) == 0)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); {
LUA_PushUserdata(gL, player, META_PLAYER);
LUA_PushUserdata(gL, inflictor, META_MOBJ);
LUA_PushUserdata(gL, source, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
lua_pushvalue(gL, -4);
if (lua_pcall(gL, 3, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (lua_toboolean(gL, -1))
hooked = true;
lua_pop(gL, 1); lua_pop(gL, 1);
continue;
} }
if (lua_toboolean(gL, -1))
handled = true;
lua_pop(gL, 1); // pop return value
}
lua_pop(gL, 3); // pop arguments and mobjtype table
lua_gc(gL, LUA_GCSTEP, 1); lua_settop(gL, 0);
return handled; return hooked;
} }
#endif #endif