From d7c9b7db0092060c5e2d0e13915ecc1b26db5c73 Mon Sep 17 00:00:00 2001 From: Plagman Date: Thu, 13 Apr 2006 20:34:38 +0000 Subject: [PATCH] git-svn-id: https://svn.eduke32.com/eduke32@2 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/build/ChangeLog | 495 + polymer/build/LICENSE | 7 + polymer/build/MakeDistributions | 47 + polymer/build/Makefile | 285 + polymer/build/Makefile.deps | 46 + polymer/build/Makefile.msvc | 166 + polymer/build/Makefile.shared | 160 + polymer/build/Makefile.watcom | 174 + polymer/build/NAMES.H | 49 + polymer/build/README | 141 + polymer/build/build.cfg | 104 + polymer/build/buildlic.txt | 71 + polymer/build/devcpp/Build.dev | 68 + polymer/build/devcpp/Game.dev | 98 + polymer/build/devcpp/engineinfo.c | 5 + polymer/build/devcpp/libEditor.dev | 79 + polymer/build/devcpp/libEngine.dev | 198 + polymer/build/game.cfg | 97 + polymer/build/include/a.h | 245 + polymer/build/include/baselayer.h | 126 + polymer/build/include/baselayer.h.r276 | 121 + polymer/build/include/baselayer.h.r277 | 126 + polymer/build/include/build.h | 516 + polymer/build/include/cache1d.h | 63 + polymer/build/include/compat.h | 432 + polymer/build/include/crc32.h | 20 + polymer/build/include/dxdidf.h | 332 + polymer/build/include/editor.h | 68 + polymer/build/include/engineinfo.h | 6 + polymer/build/include/game.h | 56 + polymer/build/include/glbuild.h | 211 + polymer/build/include/glext.h | 5545 ++++++++ polymer/build/include/gtkbits.h | 15 + polymer/build/include/kplib.h | 21 + polymer/build/include/lzf.h | 101 + polymer/build/include/lzwnew.h | 2 + polymer/build/include/md4.h | 38 + polymer/build/include/mmulti.h | 29 + polymer/build/include/mmultimsgs.h | 65 + polymer/build/include/names.h | 49 + polymer/build/include/osd.h | 77 + polymer/build/include/osxbits.h | 7 + polymer/build/include/pragmas.h | 3704 +++++ polymer/build/include/scriptfile.h | 26 + polymer/build/include/sdlayer.h | 21 + polymer/build/include/tmp/buildsound.h | 15 + polymer/build/include/tmp/pragmas-functions.h | 159 + polymer/build/include/winlayer.h | 54 + polymer/build/makegnu.bat | 1 + polymer/build/makemsc.bat | 1 + polymer/build/makew.bat | 1 + polymer/build/obj.gnu/keep.me | 0 polymer/build/obj.msc/keep.me | 0 polymer/build/obj.watcom/keep.me | 0 .../osx/engine/engine.xcode/project.pbxproj | 1539 +++ polymer/build/osx/engine/engineinfo.c | 5 + polymer/build/osx/engine/writeengineinfo.sh | 10 + polymer/build/osx/game/build.osxmain.h | 11 + polymer/build/osx/game/build.osxmain.m | 179 + polymer/build/osx/game/editor-Info.plist | 24 + polymer/build/osx/game/game-Info.plist | 24 + polymer/build/osx/game/game.osxmain.h | 11 + polymer/build/osx/game/game.osxmain.m | 179 + .../build/osx/game/game.xcode/project.pbxproj | 825 ++ .../build/osx/game/osxmain.nib/classes.nib | 7 + polymer/build/osx/game/osxmain.nib/info.nib | 21 + .../build/osx/game/osxmain.nib/objects.nib | Bin 0 -> 1683 bytes polymer/build/rsrc/build.bmp | Bin 0 -> 26774 bytes polymer/build/rsrc/build.xcf | Bin 0 -> 129379 bytes polymer/build/rsrc/build_icon.bmp | Bin 0 -> 3126 bytes polymer/build/rsrc/build_icon.c | 192 + polymer/build/rsrc/build_icon.ico | Bin 0 -> 2998 bytes polymer/build/rsrc/editor_banner.c | 2267 ++++ polymer/build/rsrc/game.bmp | Bin 0 -> 26774 bytes polymer/build/rsrc/game.xcf | Bin 0 -> 86377 bytes polymer/build/rsrc/game_banner.c | 2691 ++++ polymer/build/rsrc/game_icon.bmp | Bin 0 -> 3126 bytes polymer/build/rsrc/game_icon.c | 192 + polymer/build/rsrc/game_icon.ico | Bin 0 -> 2998 bytes polymer/build/src/a-c.c | 298 + polymer/build/src/a.masm | 2664 ++++ polymer/build/src/a.nasm | 2751 ++++ polymer/build/src/a.wasm | 2420 ++++ polymer/build/src/baselayer.c | 206 + polymer/build/src/bstub.c | 574 + polymer/build/src/build.c | 7422 ++++++++++ polymer/build/src/buildstartwin.c | 178 + polymer/build/src/cache1d.c | 1301 ++ polymer/build/src/compat.c | 716 + polymer/build/src/config.c | 307 + polymer/build/src/crc32.c | 104 + polymer/build/src/defs.c | 1072 ++ polymer/build/src/engine.c | 11240 ++++++++++++++++ polymer/build/src/game.c | 6297 +++++++++ polymer/build/src/gamestartwin.c | 144 + polymer/build/src/glbuild.c | 359 + polymer/build/src/gtkbits.c | 238 + polymer/build/src/hightile.c | 254 + polymer/build/src/jfaud_sound.cpp | 378 + polymer/build/src/kplib.c | 3117 +++++ polymer/build/src/lzfP.h | 157 + polymer/build/src/lzf_c.c | 242 + polymer/build/src/lzf_d.c | 116 + polymer/build/src/lzwnew.c | 116 + polymer/build/src/md4.c | 272 + polymer/build/src/mdsprite.c | 2561 ++++ polymer/build/src/misc/buildres.rc | 31 + polymer/build/src/misc/enumdisplay.c | 156 + polymer/build/src/misc/gameres.rc | 29 + polymer/build/src/misc/getdxdidf.c | 129 + polymer/build/src/misc/makesdlkeytrans.c | 163 + polymer/build/src/mmulti.c | 641 + polymer/build/src/mmulti_null.c | 79 + polymer/build/src/osd.c | 1015 ++ polymer/build/src/osxbits.m | 37 + polymer/build/src/polymost.c | 5103 +++++++ polymer/build/src/pragmas.c | 250 + polymer/build/src/scriptfile.c | 394 + polymer/build/src/sdlayer.c | 1510 +++ polymer/build/src/smalltextfont.c | 179 + polymer/build/src/sound.c | 358 + polymer/build/src/sound_stub.c | 39 + polymer/build/src/textfont.c | 179 + polymer/build/src/tmp/engineinfo.c | 5 + polymer/build/src/tmp/keep.me | 0 polymer/build/src/util/bin2c.cpp | 151 + polymer/build/src/util/cacheinfo.c | 90 + polymer/build/src/util/generateicon.c | 110 + polymer/build/src/util/kextract.c | 148 + polymer/build/src/util/kgroup.c | 171 + polymer/build/src/util/kmd2tool.c | 58 + polymer/build/src/util/transpal.c | 270 + polymer/build/src/util/vgafont.cpp | 139 + polymer/build/src/util/wad2art.c | 283 + polymer/build/src/util/wad2map.c | 1615 +++ polymer/build/src/winlayer.c | 3781 ++++++ polymer/eduke32/ChangeLog | 258 + polymer/eduke32/GNU.TXT | 87 + polymer/eduke32/MakeDistributions | 43 + polymer/eduke32/Makefile | 222 + polymer/eduke32/Makefile.deps | 60 + polymer/eduke32/Makefile.msvc | 151 + polymer/eduke32/Makefile.watcom | 143 + polymer/eduke32/SEHELP.HLP | 35 + polymer/eduke32/STHELP.HLP | 24 + polymer/eduke32/build.cfg | 104 + polymer/eduke32/duke3d.def.sample | 69 + polymer/eduke32/eduke32.exe | Bin 0 -> 1214976 bytes polymer/eduke32/eduke32.exe.map | 6059 +++++++++ polymer/eduke32/eduke32.sym.exe | Bin 0 -> 1392709 bytes polymer/eduke32/enhance.con.sample | 369 + polymer/eduke32/eobj/libbuild.a | Bin 0 -> 173342 bytes polymer/eduke32/eobj/libengine.a | Bin 0 -> 648916 bytes polymer/eduke32/jfduke_releasenotes.html | 511 + polymer/eduke32/makemsc.bat | 1 + polymer/eduke32/makew.bat | 1 + polymer/eduke32/mapster32.exe | Bin 0 -> 677888 bytes polymer/eduke32/mapster32.exe.map | 3591 +++++ polymer/eduke32/mapster32.sym.exe | Bin 0 -> 782273 bytes polymer/eduke32/rsrc/build.bmp | Bin 0 -> 29080 bytes polymer/eduke32/rsrc/build_icon.bmp | Bin 0 -> 2102 bytes polymer/eduke32/rsrc/build_icon.c | 192 + polymer/eduke32/rsrc/build_icon.ico | Bin 0 -> 37894 bytes polymer/eduke32/rsrc/editor_banner.c | 3310 +++++ polymer/eduke32/rsrc/game.bmp | Bin 0 -> 29080 bytes polymer/eduke32/rsrc/game_banner.c | 3681 +++++ polymer/eduke32/rsrc/game_icon.c | 192 + polymer/eduke32/rsrc/game_icon.ico | Bin 0 -> 37894 bytes polymer/eduke32/source/GNU.TXT | 87 + polymer/eduke32/source/_functio.h | 324 + polymer/eduke32/source/_rts.h | 55 + polymer/eduke32/source/actors.c | 7526 +++++++++++ polymer/eduke32/source/anim.c | 292 + polymer/eduke32/source/astub.c | 5588 ++++++++ polymer/eduke32/source/config.c | 794 ++ polymer/eduke32/source/config.h | 72 + polymer/eduke32/source/develop.h | 66 + polymer/eduke32/source/duke3d.h | 852 ++ polymer/eduke32/source/funct.h | 355 + polymer/eduke32/source/function.h | 105 + polymer/eduke32/source/game.c | 10479 ++++++++++++++ polymer/eduke32/source/gamedef.c | 5992 ++++++++ polymer/eduke32/source/gamedef.h | 715 + polymer/eduke32/source/gamedefs.h | 194 + polymer/eduke32/source/gameexec.c | 6602 +++++++++ polymer/eduke32/source/global.c | 180 + polymer/eduke32/source/jaudiolib/_midi.h | 281 + polymer/eduke32/source/jaudiolib/_multivc.h | 310 + .../source/jaudiolib/audiolib_fx_fmod.c | 737 + .../source/jaudiolib/audiolib_fxstub.c | 368 + .../source/jaudiolib/audiolib_musicstub.c | 510 + polymer/eduke32/source/jaudiolib/dsoundout.c | 585 + polymer/eduke32/source/jaudiolib/dsoundout.h | 62 + polymer/eduke32/source/jaudiolib/fx_man.c | 1074 ++ polymer/eduke32/source/jaudiolib/fx_man.h | 137 + .../eduke32/source/jaudiolib/fx_man_fmod.h | 78 + polymer/eduke32/source/jaudiolib/linklist.h | 119 + polymer/eduke32/source/jaudiolib/ll_man.c | 103 + polymer/eduke32/source/jaudiolib/ll_man.h | 75 + polymer/eduke32/source/jaudiolib/midi.c | 2048 +++ polymer/eduke32/source/jaudiolib/midi.h | 100 + polymer/eduke32/source/jaudiolib/mpu401.c | 475 + polymer/eduke32/source/jaudiolib/mpu401.h | 66 + polymer/eduke32/source/jaudiolib/multivoc.c | 2971 ++++ polymer/eduke32/source/jaudiolib/multivoc.h | 117 + polymer/eduke32/source/jaudiolib/music.c | 595 + polymer/eduke32/source/jaudiolib/music.h | 90 + polymer/eduke32/source/jaudiolib/mv_mix.masm | 487 + polymer/eduke32/source/jaudiolib/mv_mix.nasm | 524 + polymer/eduke32/source/jaudiolib/mv_mix.wasm | 491 + .../eduke32/source/jaudiolib/mv_mix16.masm | 507 + .../eduke32/source/jaudiolib/mv_mix16.nasm | 544 + .../eduke32/source/jaudiolib/mv_mix16.wasm | 511 + .../eduke32/source/jaudiolib/mvreverb.masm | 202 + .../eduke32/source/jaudiolib/mvreverb.nasm | 230 + .../eduke32/source/jaudiolib/mvreverb.wasm | 174 + polymer/eduke32/source/jaudiolib/pitch.c | 197 + polymer/eduke32/source/jaudiolib/pitch.h | 44 + polymer/eduke32/source/jaudiolib/sdlout.c | 266 + polymer/eduke32/source/jaudiolib/sdlout.h | 48 + polymer/eduke32/source/jaudiolib/standard.h | 73 + polymer/eduke32/source/jaudiolib/usrhooks.h | 56 + polymer/eduke32/source/jfaud_sounds.cpp | 681 + polymer/eduke32/source/jmact/_control.h | 271 + polymer/eduke32/source/jmact/_scrplib.h | 209 + polymer/eduke32/source/jmact/animlib.c | 368 + polymer/eduke32/source/jmact/animlib.h | 175 + polymer/eduke32/source/jmact/control.c | 982 ++ polymer/eduke32/source/jmact/control.h | 226 + polymer/eduke32/source/jmact/develop.h | 66 + polymer/eduke32/source/jmact/file_lib.c | 136 + polymer/eduke32/source/jmact/file_lib.h | 260 + polymer/eduke32/source/jmact/keyboard.c | 289 + polymer/eduke32/source/jmact/keyboard.h | 230 + polymer/eduke32/source/jmact/mathutil.c | 112 + polymer/eduke32/source/jmact/mathutil.h | 34 + polymer/eduke32/source/jmact/mouse.c | 88 + polymer/eduke32/source/jmact/mouse.h | 56 + polymer/eduke32/source/jmact/scriplib.c | 918 ++ polymer/eduke32/source/jmact/scriplib.h | 355 + polymer/eduke32/source/jmact/types.h | 112 + polymer/eduke32/source/jmact/util_lib.c | 153 + polymer/eduke32/source/jmact/util_lib.h | 67 + polymer/eduke32/source/keys.h | 135 + polymer/eduke32/source/mapster32.h | 163 + polymer/eduke32/source/menus.c | 4043 ++++++ polymer/eduke32/source/misc/buildres.rc | 30 + polymer/eduke32/source/misc/gameres.rc | 14 + polymer/eduke32/source/names.h | 766 ++ polymer/eduke32/source/namesdyn.c | 2421 ++++ polymer/eduke32/source/namesdyn.h | 1501 +++ polymer/eduke32/source/osdcmds.c | 654 + polymer/eduke32/source/osdcmds.h | 14 + polymer/eduke32/source/osdfuncs.c | 90 + polymer/eduke32/source/osdfuncs.h | 8 + polymer/eduke32/source/player.c | 5807 ++++++++ polymer/eduke32/source/premap.c | 1685 +++ polymer/eduke32/source/rts.c | 260 + polymer/eduke32/source/rts.h | 85 + polymer/eduke32/source/savegame.c | 646 + polymer/eduke32/source/savegame.what | 615 + polymer/eduke32/source/sector.c | 3522 +++++ polymer/eduke32/source/soundefs.h | 417 + polymer/eduke32/source/sounds.c | 632 + polymer/eduke32/source/sounds.h | 55 + polymer/eduke32/source/testcd.c | 75 + polymer/eduke32/source/winbits.c | 87 + 267 files changed, 189486 insertions(+) create mode 100644 polymer/build/ChangeLog create mode 100644 polymer/build/LICENSE create mode 100644 polymer/build/MakeDistributions create mode 100644 polymer/build/Makefile create mode 100644 polymer/build/Makefile.deps create mode 100644 polymer/build/Makefile.msvc create mode 100644 polymer/build/Makefile.shared create mode 100644 polymer/build/Makefile.watcom create mode 100644 polymer/build/NAMES.H create mode 100644 polymer/build/README create mode 100644 polymer/build/build.cfg create mode 100644 polymer/build/buildlic.txt create mode 100644 polymer/build/devcpp/Build.dev create mode 100644 polymer/build/devcpp/Game.dev create mode 100644 polymer/build/devcpp/engineinfo.c create mode 100644 polymer/build/devcpp/libEditor.dev create mode 100644 polymer/build/devcpp/libEngine.dev create mode 100644 polymer/build/game.cfg create mode 100644 polymer/build/include/a.h create mode 100644 polymer/build/include/baselayer.h create mode 100644 polymer/build/include/baselayer.h.r276 create mode 100644 polymer/build/include/baselayer.h.r277 create mode 100644 polymer/build/include/build.h create mode 100644 polymer/build/include/cache1d.h create mode 100644 polymer/build/include/compat.h create mode 100644 polymer/build/include/crc32.h create mode 100644 polymer/build/include/dxdidf.h create mode 100644 polymer/build/include/editor.h create mode 100644 polymer/build/include/engineinfo.h create mode 100644 polymer/build/include/game.h create mode 100644 polymer/build/include/glbuild.h create mode 100644 polymer/build/include/glext.h create mode 100644 polymer/build/include/gtkbits.h create mode 100644 polymer/build/include/kplib.h create mode 100644 polymer/build/include/lzf.h create mode 100644 polymer/build/include/lzwnew.h create mode 100644 polymer/build/include/md4.h create mode 100644 polymer/build/include/mmulti.h create mode 100644 polymer/build/include/mmultimsgs.h create mode 100644 polymer/build/include/names.h create mode 100644 polymer/build/include/osd.h create mode 100644 polymer/build/include/osxbits.h create mode 100644 polymer/build/include/pragmas.h create mode 100644 polymer/build/include/scriptfile.h create mode 100644 polymer/build/include/sdlayer.h create mode 100644 polymer/build/include/tmp/buildsound.h create mode 100644 polymer/build/include/tmp/pragmas-functions.h create mode 100644 polymer/build/include/winlayer.h create mode 100644 polymer/build/makegnu.bat create mode 100644 polymer/build/makemsc.bat create mode 100644 polymer/build/makew.bat create mode 100644 polymer/build/obj.gnu/keep.me create mode 100644 polymer/build/obj.msc/keep.me create mode 100644 polymer/build/obj.watcom/keep.me create mode 100644 polymer/build/osx/engine/engine.xcode/project.pbxproj create mode 100644 polymer/build/osx/engine/engineinfo.c create mode 100644 polymer/build/osx/engine/writeengineinfo.sh create mode 100644 polymer/build/osx/game/build.osxmain.h create mode 100644 polymer/build/osx/game/build.osxmain.m create mode 100644 polymer/build/osx/game/editor-Info.plist create mode 100644 polymer/build/osx/game/game-Info.plist create mode 100644 polymer/build/osx/game/game.osxmain.h create mode 100644 polymer/build/osx/game/game.osxmain.m create mode 100644 polymer/build/osx/game/game.xcode/project.pbxproj create mode 100644 polymer/build/osx/game/osxmain.nib/classes.nib create mode 100644 polymer/build/osx/game/osxmain.nib/info.nib create mode 100644 polymer/build/osx/game/osxmain.nib/objects.nib create mode 100644 polymer/build/rsrc/build.bmp create mode 100644 polymer/build/rsrc/build.xcf create mode 100644 polymer/build/rsrc/build_icon.bmp create mode 100644 polymer/build/rsrc/build_icon.c create mode 100644 polymer/build/rsrc/build_icon.ico create mode 100644 polymer/build/rsrc/editor_banner.c create mode 100644 polymer/build/rsrc/game.bmp create mode 100644 polymer/build/rsrc/game.xcf create mode 100644 polymer/build/rsrc/game_banner.c create mode 100644 polymer/build/rsrc/game_icon.bmp create mode 100644 polymer/build/rsrc/game_icon.c create mode 100644 polymer/build/rsrc/game_icon.ico create mode 100644 polymer/build/src/a-c.c create mode 100644 polymer/build/src/a.masm create mode 100644 polymer/build/src/a.nasm create mode 100644 polymer/build/src/a.wasm create mode 100644 polymer/build/src/baselayer.c create mode 100644 polymer/build/src/bstub.c create mode 100644 polymer/build/src/build.c create mode 100644 polymer/build/src/buildstartwin.c create mode 100644 polymer/build/src/cache1d.c create mode 100644 polymer/build/src/compat.c create mode 100644 polymer/build/src/config.c create mode 100644 polymer/build/src/crc32.c create mode 100644 polymer/build/src/defs.c create mode 100644 polymer/build/src/engine.c create mode 100644 polymer/build/src/game.c create mode 100644 polymer/build/src/gamestartwin.c create mode 100644 polymer/build/src/glbuild.c create mode 100644 polymer/build/src/gtkbits.c create mode 100644 polymer/build/src/hightile.c create mode 100644 polymer/build/src/jfaud_sound.cpp create mode 100644 polymer/build/src/kplib.c create mode 100644 polymer/build/src/lzfP.h create mode 100644 polymer/build/src/lzf_c.c create mode 100644 polymer/build/src/lzf_d.c create mode 100644 polymer/build/src/lzwnew.c create mode 100644 polymer/build/src/md4.c create mode 100644 polymer/build/src/mdsprite.c create mode 100644 polymer/build/src/misc/buildres.rc create mode 100644 polymer/build/src/misc/enumdisplay.c create mode 100644 polymer/build/src/misc/gameres.rc create mode 100644 polymer/build/src/misc/getdxdidf.c create mode 100644 polymer/build/src/misc/makesdlkeytrans.c create mode 100644 polymer/build/src/mmulti.c create mode 100644 polymer/build/src/mmulti_null.c create mode 100644 polymer/build/src/osd.c create mode 100644 polymer/build/src/osxbits.m create mode 100644 polymer/build/src/polymost.c create mode 100644 polymer/build/src/pragmas.c create mode 100644 polymer/build/src/scriptfile.c create mode 100644 polymer/build/src/sdlayer.c create mode 100644 polymer/build/src/smalltextfont.c create mode 100644 polymer/build/src/sound.c create mode 100644 polymer/build/src/sound_stub.c create mode 100644 polymer/build/src/textfont.c create mode 100644 polymer/build/src/tmp/engineinfo.c create mode 100644 polymer/build/src/tmp/keep.me create mode 100644 polymer/build/src/util/bin2c.cpp create mode 100644 polymer/build/src/util/cacheinfo.c create mode 100644 polymer/build/src/util/generateicon.c create mode 100644 polymer/build/src/util/kextract.c create mode 100644 polymer/build/src/util/kgroup.c create mode 100644 polymer/build/src/util/kmd2tool.c create mode 100644 polymer/build/src/util/transpal.c create mode 100644 polymer/build/src/util/vgafont.cpp create mode 100644 polymer/build/src/util/wad2art.c create mode 100644 polymer/build/src/util/wad2map.c create mode 100644 polymer/build/src/winlayer.c create mode 100644 polymer/eduke32/ChangeLog create mode 100644 polymer/eduke32/GNU.TXT create mode 100644 polymer/eduke32/MakeDistributions create mode 100644 polymer/eduke32/Makefile create mode 100644 polymer/eduke32/Makefile.deps create mode 100644 polymer/eduke32/Makefile.msvc create mode 100644 polymer/eduke32/Makefile.watcom create mode 100644 polymer/eduke32/SEHELP.HLP create mode 100644 polymer/eduke32/STHELP.HLP create mode 100644 polymer/eduke32/build.cfg create mode 100644 polymer/eduke32/duke3d.def.sample create mode 100644 polymer/eduke32/eduke32.exe create mode 100644 polymer/eduke32/eduke32.exe.map create mode 100644 polymer/eduke32/eduke32.sym.exe create mode 100644 polymer/eduke32/enhance.con.sample create mode 100644 polymer/eduke32/eobj/libbuild.a create mode 100644 polymer/eduke32/eobj/libengine.a create mode 100644 polymer/eduke32/jfduke_releasenotes.html create mode 100644 polymer/eduke32/makemsc.bat create mode 100644 polymer/eduke32/makew.bat create mode 100644 polymer/eduke32/mapster32.exe create mode 100644 polymer/eduke32/mapster32.exe.map create mode 100644 polymer/eduke32/mapster32.sym.exe create mode 100644 polymer/eduke32/rsrc/build.bmp create mode 100644 polymer/eduke32/rsrc/build_icon.bmp create mode 100644 polymer/eduke32/rsrc/build_icon.c create mode 100644 polymer/eduke32/rsrc/build_icon.ico create mode 100644 polymer/eduke32/rsrc/editor_banner.c create mode 100644 polymer/eduke32/rsrc/game.bmp create mode 100644 polymer/eduke32/rsrc/game_banner.c create mode 100644 polymer/eduke32/rsrc/game_icon.c create mode 100644 polymer/eduke32/rsrc/game_icon.ico create mode 100644 polymer/eduke32/source/GNU.TXT create mode 100644 polymer/eduke32/source/_functio.h create mode 100644 polymer/eduke32/source/_rts.h create mode 100644 polymer/eduke32/source/actors.c create mode 100644 polymer/eduke32/source/anim.c create mode 100644 polymer/eduke32/source/astub.c create mode 100644 polymer/eduke32/source/config.c create mode 100644 polymer/eduke32/source/config.h create mode 100644 polymer/eduke32/source/develop.h create mode 100644 polymer/eduke32/source/duke3d.h create mode 100644 polymer/eduke32/source/funct.h create mode 100644 polymer/eduke32/source/function.h create mode 100644 polymer/eduke32/source/game.c create mode 100644 polymer/eduke32/source/gamedef.c create mode 100644 polymer/eduke32/source/gamedef.h create mode 100644 polymer/eduke32/source/gamedefs.h create mode 100644 polymer/eduke32/source/gameexec.c create mode 100644 polymer/eduke32/source/global.c create mode 100644 polymer/eduke32/source/jaudiolib/_midi.h create mode 100644 polymer/eduke32/source/jaudiolib/_multivc.h create mode 100644 polymer/eduke32/source/jaudiolib/audiolib_fx_fmod.c create mode 100644 polymer/eduke32/source/jaudiolib/audiolib_fxstub.c create mode 100644 polymer/eduke32/source/jaudiolib/audiolib_musicstub.c create mode 100644 polymer/eduke32/source/jaudiolib/dsoundout.c create mode 100644 polymer/eduke32/source/jaudiolib/dsoundout.h create mode 100644 polymer/eduke32/source/jaudiolib/fx_man.c create mode 100644 polymer/eduke32/source/jaudiolib/fx_man.h create mode 100644 polymer/eduke32/source/jaudiolib/fx_man_fmod.h create mode 100644 polymer/eduke32/source/jaudiolib/linklist.h create mode 100644 polymer/eduke32/source/jaudiolib/ll_man.c create mode 100644 polymer/eduke32/source/jaudiolib/ll_man.h create mode 100644 polymer/eduke32/source/jaudiolib/midi.c create mode 100644 polymer/eduke32/source/jaudiolib/midi.h create mode 100644 polymer/eduke32/source/jaudiolib/mpu401.c create mode 100644 polymer/eduke32/source/jaudiolib/mpu401.h create mode 100644 polymer/eduke32/source/jaudiolib/multivoc.c create mode 100644 polymer/eduke32/source/jaudiolib/multivoc.h create mode 100644 polymer/eduke32/source/jaudiolib/music.c create mode 100644 polymer/eduke32/source/jaudiolib/music.h create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix.masm create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix.nasm create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix.wasm create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix16.masm create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix16.nasm create mode 100644 polymer/eduke32/source/jaudiolib/mv_mix16.wasm create mode 100644 polymer/eduke32/source/jaudiolib/mvreverb.masm create mode 100644 polymer/eduke32/source/jaudiolib/mvreverb.nasm create mode 100644 polymer/eduke32/source/jaudiolib/mvreverb.wasm create mode 100644 polymer/eduke32/source/jaudiolib/pitch.c create mode 100644 polymer/eduke32/source/jaudiolib/pitch.h create mode 100644 polymer/eduke32/source/jaudiolib/sdlout.c create mode 100644 polymer/eduke32/source/jaudiolib/sdlout.h create mode 100644 polymer/eduke32/source/jaudiolib/standard.h create mode 100644 polymer/eduke32/source/jaudiolib/usrhooks.h create mode 100644 polymer/eduke32/source/jfaud_sounds.cpp create mode 100644 polymer/eduke32/source/jmact/_control.h create mode 100644 polymer/eduke32/source/jmact/_scrplib.h create mode 100644 polymer/eduke32/source/jmact/animlib.c create mode 100644 polymer/eduke32/source/jmact/animlib.h create mode 100644 polymer/eduke32/source/jmact/control.c create mode 100644 polymer/eduke32/source/jmact/control.h create mode 100644 polymer/eduke32/source/jmact/develop.h create mode 100644 polymer/eduke32/source/jmact/file_lib.c create mode 100644 polymer/eduke32/source/jmact/file_lib.h create mode 100644 polymer/eduke32/source/jmact/keyboard.c create mode 100644 polymer/eduke32/source/jmact/keyboard.h create mode 100644 polymer/eduke32/source/jmact/mathutil.c create mode 100644 polymer/eduke32/source/jmact/mathutil.h create mode 100644 polymer/eduke32/source/jmact/mouse.c create mode 100644 polymer/eduke32/source/jmact/mouse.h create mode 100644 polymer/eduke32/source/jmact/scriplib.c create mode 100644 polymer/eduke32/source/jmact/scriplib.h create mode 100644 polymer/eduke32/source/jmact/types.h create mode 100644 polymer/eduke32/source/jmact/util_lib.c create mode 100644 polymer/eduke32/source/jmact/util_lib.h create mode 100644 polymer/eduke32/source/keys.h create mode 100644 polymer/eduke32/source/mapster32.h create mode 100644 polymer/eduke32/source/menus.c create mode 100644 polymer/eduke32/source/misc/buildres.rc create mode 100644 polymer/eduke32/source/misc/gameres.rc create mode 100644 polymer/eduke32/source/names.h create mode 100644 polymer/eduke32/source/namesdyn.c create mode 100644 polymer/eduke32/source/namesdyn.h create mode 100644 polymer/eduke32/source/osdcmds.c create mode 100644 polymer/eduke32/source/osdcmds.h create mode 100644 polymer/eduke32/source/osdfuncs.c create mode 100644 polymer/eduke32/source/osdfuncs.h create mode 100644 polymer/eduke32/source/player.c create mode 100644 polymer/eduke32/source/premap.c create mode 100644 polymer/eduke32/source/rts.c create mode 100644 polymer/eduke32/source/rts.h create mode 100644 polymer/eduke32/source/savegame.c create mode 100644 polymer/eduke32/source/savegame.what create mode 100644 polymer/eduke32/source/sector.c create mode 100644 polymer/eduke32/source/soundefs.h create mode 100644 polymer/eduke32/source/sounds.c create mode 100644 polymer/eduke32/source/sounds.h create mode 100644 polymer/eduke32/source/testcd.c create mode 100644 polymer/eduke32/source/winbits.c diff --git a/polymer/build/ChangeLog b/polymer/build/ChangeLog new file mode 100644 index 000000000..d04af939e --- /dev/null +++ b/polymer/build/ChangeLog @@ -0,0 +1,495 @@ +8 Jun 2004 + + * Transparency bug noticed by Usurper should now be fixed. + * MD2 definition problem noticed by Parkar should also be fixed too. + + +5 Jun 2004 + + * Some foolish bugs in my (JonoF) code in the MD2 stuff now fixed. + * Linux should be fine now. At least, it worked on my machine. + + +3 Jun 2004 + + * MD2 model support is official now. We've also added a script reader + for the new .DEF format. KenBuild uses KENBUILD.DEF for its stuff. + + +26 May 2004 + + * glusecds is set to 0 by default now. The glusecds console variable + can be set to 1 to enable the use of the ChangeDisplaySettings() + function which works better for Intel video chipsets. + + +22 May 2004 + + * Gave things a nice overhaul to cut back the insanity of the + classic/softpolymost/glpolymost stuff. It was beginning to scare + me. The underhanded and behind-the-back tricks are banished. + + The whole rendermethod thing is gone. Now, setgamemode() and + related paraphenalia all accept a 'bits-per-pixel' parameter. + Colour depths > 8 are forced to use GL polymost (naturally). + 8bpp modes can use the regular renderer, and the software polymost + stuff. This means switchrendermethod() is removed from the layers. + + SDLayer.c is back in sync too, so Build on Linux works again. + + +8 May 2004 + + * Finally remembered to add 33%/66% translucency support to hightile + tiles. + + +8 Mar 2004 + + * Added setpalettefadeclamps() to allow continual palette tinting + effects. + * Added back PCX format screenshot saving. The new screenshotformat + console variable selects whether to take PCX format (= 0, default) + or TGA format (= 1). + + +12 Feb 2004 + + * Greyscaling and inverting of tiles in hightile/polymost added. + This makes Duke's nightvision work better for Hightile textures + that use palette 6. + + +11 Feb 2004 + + * Broke out the non-OSD related commands from osd.c into baselayer.c. + * Added alternative display mode setting method using + ChangeDisplayMode() which can optionally be used for OpenGL mode + changes. Set the environment variable BUILD_USEGLCDS=TRUE to use. + * Added the glcolourdepth variable for selection of fullscreen GL + colour depth. + * Changed OSD_HandleKey() to not ignore releases, otherwise the game + world will always think its keys are held down. It ignores presses + though, which we want. + + +10 Feb 2004 + + * Added some protection to [k]?dfread() to indicate whether they + have failed to decompress some bytes so that the game doesn't + crash if a demo or savegame is fragged. + + +7 Feb 2004 + + * Hightile integration seems fine now. New functions to specify + replacement textures and palette tints can be seen in build.h. + * Joystick support is added. Seems to work. + * Hopefully a change I've made to the tile selector in Build when + using OpenGL mode has fixed the problem of the edges being + clipped off the screen... + + +22 Jan 2004 + + * Modified screencapture() to not overwrite existing screenshots. + + +19 Jan 2004 + + * loadboard() got a new second parameter inserted. This tells + kopen4load() where to seek out the map file. The values are: + 0 - anywhere + 1 - the first GRP file (same as setting strlen(fn)-1 to 0xff) + 2 - any grp file + + +17 Jan 2004 + + * Fixed Bcorrectfilename() to handle Win98's different operation + of GetFullPathName() when compared to Win2k. Now Build doesn't + ascend 2 directories at once when running on 98. + + +16 Jan 2004 + + * Undid some stuff which was a little braindamaged in winlayer.c. + I can't for the life of me remember why I was destroying the + window and recreating it when switching rendering modes when it + was entirely unnecessary and could potentially piss off other + services which aren't expecting their window handle to suddenly + be invalid, like DirectSound. + * In typical JonoF style of a couple of years ago, I made an error + when I did the gruntwork to port Build to Windows and as a + sideeffect of my unchecked amateurness I bent the point + highlighting in the editor. It's straightened now. :-( + + +12 Jan 2004 + + * sdlayer.c has been brought into line with winlayer.c. Now + everything that winlayer.c also works in SDL. + + +10 Jan 2004 + + * Added uninitsinglegroupfile() to unload a particular group file. + * Added a mechanism to do a "findfirst/next" over the group files. + * Modified Build.c to include maps inside the GRPs in the file + list. + + +2 Jan 2004 + + * Crash bug on starting Build editor fixed. See list of original + bugs for information. + + +1 Jan 2004 + + * Many Polymost bugs fixed. Mirrors now work. All kinds of funky + stuff. + + +29 Dec 2003 + + * Updated screencapture() to support GL modes. + * Modified 2D mode editor screen capture to keep the status bar + visible. Done with Ken's blessing. + + +23 Dec 2003 + + * Build mouse sensitivity has changed to use a floating point value + in the configuration file to specify the sen + * First public release of Ken's new "Polymost" renderer. 6 degrees + of freedom and full 3D rendering, including OpenGL. + * Palette handling has changed somewhat drastically. The engine now + supports palette fading natively, which means where games used + to manipulate a copy of the palette and send it to the video card, + this manipulation is now done by the engine via a function named + setpalettefade(). See the header for details. In adding this, + setbrightness() gained a third parameter, which is almost always + passed as 0 unless doing a palette fade and adjusting the game + palette immediately before it, in which case pass 1 so that + setbrightness() doesn't apply its base palette, otherwise weird + palette flashes will happen and we don't want that. + This was all necessary in order to let Ken's Polymost code have + access to the basic, unmodified palette for its own purposes. + + +20 Dec 2003 + + * Dynamic player collection has been cleaned up ever so slightly and + seems to work pretty well so far on just my LAN. No internet test + has been performed yet. + * Screen tilting in game.c now uses polymost's tilting abilities if + rendmode > 0 is used. + + +10 Dec 2003 + + * Dynamic player collection works at this stage. It's all implemented + in game-land because it's easier to do at this stage, but I + anticipate moving most of the general stuff into the engine if I + find it necessary. + + +6 Dec 2003 + + * Modified the checkvideomodes() function in winlayer.c to behave + slightly different and return 0x7fffffffl if the video mode passed + is not a recognized mode in windowed operation, otherwise it + returns the video mode index in validmode*[]. Sdlayer.c isn't + modified to do this yet. + * Applied Ken's fix for crashes which ensue when calling rotatesprite + inside drawrooms. See details in bug fixes list below. + + +5 Dec 2003 + + * At 2.50pm today jmulti.c achieved operational capacity and survived + a 15 minute 2-player network game with my father on our LAN. + + +25 Nov 2003 + + * Added a missing "CDECLENDSET 6" on line 504 of a.nasm. Without it + the registers are trashed upon return which made Win98 crash when + running GCC-built executables. + + +24 Nov 2003 + + * Silly typo fixed in winlayer.c. + + +23 Nov 2003 + + * Modified build.c and config.c to use integer arithmetic for mouse + sensitivity stuff. I don't like floating-point all that much out of + a general sense of prejudice. + + +19 Nov 2003 + + * Modified the Build editor such that it no longer is constrained to + 640x480 in 2D mode. It now defaults to using the same resolution + that is selected in 3D mode, but may be overridden by using a + new setting named '2dresolution' in the build.cfg file. It uses the + same mode numbers as the existing 'resolution' setting. + * Ctrl+A, Ctrl+Z, KP2, KP4, KP6, and KP8 in 3D mode, plus A and Z in + 2D mode are now speed limited. + + +19 Oct 2003 + + * Fixed some brain damaged error causing crashes when hitting enter + after entering a filename for Save As. I really am dumb sometimes. + * Added mouse sensitivity to Build editor. Add this to your build.cfg + ; Mouse sensitivity + ; 128 = 1:2 + ; 256 = 1:1 + ; 512 = 2:1 + mousesensitivity = 256 + + +4 Oct 2003 + + * Modified things to allow compilation with Microsoft C. Building + with MSC requires using the C-only configuration, which is how + the makefile is currently configured. + + +13 Sep 2003 + + * Added tab-completion of symbols into the OSD. + * Moved the "dumpbuildinfo" console function from the Duke source + into the OSD as a basic function. + + +11 Sep 2003 + + * Engine now able to build entirely from C source. Assembly + is entirely optional now. + * Engine now compiles with OpenWatcom 1.0. + + +22 May 2003 + + * Fixed a bug where the movement clipping lines array was being + overrun in extreme circumstances. Thanks to BlasterDRP for + pointing this out. See the epilogue for more details. + + +17 May 2003 + + * With Ken's help the rendering performance in 1024x768 is now + dramatically improved. By making scanlines odd lengths the CPU + cache issues associated with multiples of 4096 are now eliminated. + * Modified the 16-colour emulation functions since 640 bytes is no + longer the pitch of one line. + * Added auto-repainting of the frame if WM_PAINT is posted in the + winlayer. The repaint happens on a call to handleevents(); + + +15 May 2003 + + * Rewrote the map menu. + + +11 May 2003 + + * Rewrote the onscreen display. It's now a lot like Quake's console. + + +7 May 2003 + + * Changed CACHE1D.C to open the group file in read-only mode. Why it + was being opened in random-access is a mystery to me. This fixes + problems where the GRP file was read-only and the games would not + start. Thanks to Sean Magiera for this one. + * Added detection of input devices to winlayer.c (and made sdlayer.c + currently enable only keyboard and mouse without testing). Now the + Duke input code can grow a little more intelligent. + + +1 May 2003 + + * Made Ctrl+Tab show sprite stats in the way Alt+Tab does. + * Added task switching disabling to winlayer.c. + + +25 Apr 2003 + + * Modifications here and there, plus I've adjusted the Makefile to + allow code which links against the engine to compile its own copy + in its development tree. Duke uses this to compile the engine + without voxel support. + + +17 Apr 2003 + + * Various changes have been made in order to fully support my Duke3D + port. + + +7 Apr 2003 + + * Quite a few minor changes have been made here and there. + * Added support to the interface layers for game-defined input event + callbacks which are used with the jMACT library I have written for + Duke. + * Fixed a bug which was preventing screen-tilting and savegame screen- + shots from being drawn in Duke3D. Side-effect being windowed render + mode is now more similar to fullscreen in its behaviour, ie. the + frameplace variable is set to NULL when unlocked. + + +1 Apr 2003 + + * Thanks to a report by admin@combatgold1.co.uk these bugs are fixed: + - Alt-key combinations broken. Thankyou for nothing, DirectInput. + - Prompts for menu, 3d-mode quit, etc not being displayed. A little + short-sightedness on my part to blame here. + - Crash on changing palette to a palette mapping that is NULL. + This has been a bug from the very beginning in Ken's original DOS + version too, benign back then but turned malignant now thanks to + the great debugging tool known as the segmentation fault. Fixed now. + * Took a leaf from SDL's book and made the input code not suck anymore + by having buffered keyboard and mouse with event objects to tell when + there's data available. Very nice. Something I should have done from + the start had I had a brain. Mouse is now perfectly smooth. + * Made the flash speed of highlighted sprites and lines in Build derive + from the clock and not the speed at which the frames can be drawn to + the display. In DOS, locking to the display refresh worked fine, but + my haste in porting originally did not take this into account. Fixed + now. + * Fixed a problem in my very amateur DirectDraw code where I wasn't + restoring surfaces once they'd been lost (d'uh). We now have a picture + when Alt-tabbing back to the game/editor. + * Made operation on 8-bit desktops much more sane. It actually kinda + works reliably now. + + +Bugs present in Ken's original source +------------------------------------- + +This epilogue is here for those people wishing to do their own port of +the Build source and wish to save time tracking down bugs in Ken's source. +The bugs here are the ones I found during my travels and the list should +not be considered complete. Thankfully, Ken's code is very solid and the +bugs that do exist did not pose a serious threat under DOS, but they do +make life very interesting these days. + +(Line numbers refer to Ken's original source distribution) + +ENGINE.C (various locations): + Before this fix is applied you may notice crashes in game.exe + if you press Enter (main keyboard). In Ken's words: + + | It crashes in dorotatesprite because it accesses rx1[], ry1[], + | rx2[], and ry2[] - global arrays which were originally intended + | to be used only by drawrooms! When I wrote that code, I must have + | assumed rotatesprite would never be called INSIDE drawrooms... + | which makes sense because I wrote rotatesprite before I wrote + | all that faketimerhandler stuff. + + The solution is to place this line below somewhere, Ken suggests + immediately before clippoly4, but I chose to keep it with the rest + of static variables in ENGINE.C and put it on line 156: + + static long nrx1[8], nry1[8], nrx2[8], nry2[8]; + + Then, all references to rx1[], ry1[], rx2[], and ry2[] in + clippoly4 and dorotatesprite *ONLY* need to be prefixed with an + 'n'. Only those functions need patching, and nothing else. + + +ENGINE.C l1222, l1388, l7225: + palookup[] is accessed from the assembly functions to translate + palette indexes to alternate indexes for palette-shifting of + images. It contains pointers to tables which map the original + palette index to the new index. Unused lookup entries have their + pointer set to NULL. If a NULL palette lookup is referenced then + a null-pointer exception is raised. In DOS this just caused + garbage palette mappings. In Windows/Linux it causes segfaults. + A fix for this is to add a line after the specified ones like: + + if (!globalpalwritten) globalpalwritten = palookup[globalpal]; + + This remaps the NULL palette to the default one. + +ENGINE.C l5691, l5692, l5697, l5698: + drawline16() is used for the 2D map view in the BUILD editor. + In the clipping calculations it sometimes happens that the x- + coordinates are not properly clipped to the left or right of the + video memory and are offscreen by one or two pixels when clipping + against the very top or very bottom rows of video memory. Adding + these checks before the closing braces of the specified lines + makes sure the coordinate does not go negative and segfault. + + Line 5691 and 5698: if (x1 < 0) x1 = 0; + Line 5692 and 5697: if (x2 < 0) x2 = 0; + +ENGINE.C l88, l8326: + slopalookup[] is a table used for drawing sloped sector floors + and ceilings. It holds the palette shading indicies for each + scanline. Problem is, in high resolutions somewhere around + 1024x768, this array is too small and memory corruption happens + when the code writes past the end of this array. The way to fix + it is to rewrite the algorithm. Since that's an unattractive + proposition, increasing the size of this array will hold the + problem off for more typical cases. + + Line 88: long slopalookup[16384]; + Line 8326: ... else shoffs = ((16380-ydimen)<<15); + +ENGINE.C l6773: + The addclipline() macro appends a clipping line for the movement + clipping code to test, but it doesn't attempt to see if adding + the new line would overrun the buffer. Extreme cases exist where + the buffer overruns and the game crashes. The problem can be fixed + by testing if clipnum is less than MAXCLIPNUM before adding the + new line. + + #define addclipline(dax1, day1, dax2, day2, daoval) \ + { \ + if (clipnum < MAXCLIPNUM) { \ + clipit[clipnum].x1 = dax1; clipit[clipnum].y1 = day1; \ + clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2; \ + clipobjectval[clipnum] = daoval; \ + clipnum++; \ + } \ + } \ + + This change will increase the possibility of clipping bugs though + because not all possible sprites may being included in the test, + so increasing the MAXCLIPNUM constant on line 31 to 1024 will + decrease the chance of this happening. + +ENGINE.C l7880: + The for loop that reverses the rendered image of a mirror is + iterating one too many times. Change the for loop to read: + + for(dy=mirrorsy2-mirrorsy1-1;dy>=0;dy--) + +BUILD.C l2137: + gettile() sometimes gets handed a tile with an index of -1, and + doesn't adjust this to something safe before it tries to draw the + cursor for the selected tile. This is demonstrated by loading + nukeland.map in Build.exe, and making a 1-way wall on the ledge + to the left of the starting point, and then pressing 'V' on the + now grey-stone wall. Adding this line fixes the crash that ensues. + + Line 2137: if (tilenum < 0) tilenum = 0; + +BUILD.C l2495, l3444: + bstatus, local to overheadeditor() is not initialized to 0 on entry + to the function, which sometimes causes the sprite dragging code to + misfire resulting in a crash immediately on starting the editor. The + following changes will prevent this happening. + + Line 2495: "oldmousebstatus = 0;" should be changed to "bstatus = 0;" + Line 3444: append "if ((pointhighlight&0xc000) == 16384)" to "else" + diff --git a/polymer/build/LICENSE b/polymer/build/LICENSE new file mode 100644 index 000000000..8b16ceee0 --- /dev/null +++ b/polymer/build/LICENSE @@ -0,0 +1,7 @@ +The source code is covered by the terms of Ken's original license +which can be found in the file "buildlic.txt" or at +http://jonof.edgenetwk.com/buildport/buildlic.txt + +My additions and modifications are covered by the same license. + + -- Jonathon Fowler (10 March 2003) diff --git a/polymer/build/MakeDistributions b/polymer/build/MakeDistributions new file mode 100644 index 000000000..5b2d3a41c --- /dev/null +++ b/polymer/build/MakeDistributions @@ -0,0 +1,47 @@ +# GNU Makefile to prepare source and binary distributions. +# make -f MakeDistributions [source|binary] + +SOURCEFILES=build.cfg buildlic.txt ChangeLog game.cfg LICENSE \ + Makefile Makefile.deps Makefile.shared Makefile.msvc Makefile.watcom \ + MakeDistributions makegnu.bat makemsc.bat makew.bat NAMES.H README + +BINARYFILES=build.cfg build.exe buildlic.txt ChangeLog fmod.dll \ + game.cfg game.exe LICENSE NAMES.H neatsong.ogg README + +BINARYCHECKS=checkfmoddll checkneatsongogg + +.PHONY: source binary $(BINARYCHECKS) + +datenow=$(shell date +%Y%m%d) + +sourcedir=txbuild_src_$(datenow) +binarydir=txbuild_$(datenow) + +all: source binary + +source: + rm -rf $(sourcedir) $(sourcedir).zip + mkdir $(sourcedir) $(sourcedir)/obj.gnu $(sourcedir)/obj.watcom $(sourcedir)/obj.msc + touch $(sourcedir)/obj.gnu/keep.me $(sourcedir)/obj.watcom/keep.me $(sourcedir)/obj.msc/keep.me + cp $(SOURCEFILES) $(sourcedir) + find . -name "*~" -exec rm -rf '{}' ';'; + find . -name "*.orig" -exec rm -rf '{}' ';'; + find . -name "*.rej" -exec rm -rf '{}' ';'; + find . -name "*.mine" -exec rm -rf '{}' ';'; + find . -name "*.c.r*" -exec rm -rf '{}' ';'; + cp -R src rsrc include devcpp osx $(sourcedir) + find $(sourcedir) | grep -i svn | xargs rm -rf + rm -f $(sourcedir)/src/tmp/* + touch $(sourcedir)/src/tmp/keep.me + kzip -r $(sourcedir).zip $(sourcedir) + +binary: $(BINARYCHECKS) + make RELEASE=1 + upx --best build.exe game.exe + mkdir $(binarydir) + cp $(BINARYFILES) $(binarydir) + kzip -r $(binarydir).zip $(binarydir) + +# Binary checks +checkfmoddll: fmod.dll +checkneatsongogg: neatsong.ogg diff --git a/polymer/build/Makefile b/polymer/build/Makefile new file mode 100644 index 000000000..8bd6cb804 --- /dev/null +++ b/polymer/build/Makefile @@ -0,0 +1,285 @@ +# Build Makefile for GNU Make + +# Notes: +# As of 6 July 2005, the engine should handle optimisations being enabled. +# If things seem to be going wrong, lower or disable optimisations, then +# try again. If things are still going wrong, call me. +# + +# Engine options - these may be overridden by game makefiles +# SUPERBUILD - enables voxels +# POLYMOST - enables Polymost renderer +# USE_OPENGL - enables OpenGL support in Polymost +# DYNAMIC_OPENGL - enables run-time loading of OpenGL library +# USE_A_C - enables use of C version of classic renderer +# NOASM - disables the use of inline assembly pragmas +# +# SETSPRITEZ - set to 1 for Shadow Warrior +SUPERBUILD ?= 1 +POLYMOST ?= 1 +USE_OPENGL ?= 1 +DYNAMIC_OPENGL ?= 1 +USE_A_C ?= 0 +NOASM ?= 0 + +SETSPRITEZ ?= 0 + +# Debugging options +# RELEASE - 1 = no debugging +# EFENCE - 1 = compile with Electric Fence for malloc() debugging +RELEASE?=1 +EFENCE?=0 + +# SDK locations - adjust to match your setup +DXROOT=c:/sdks/msc/dx61 +FMODROOTWIN=c:/sdks/fmodapi374win/api + +# build locations - OBJ gets overridden to the game-specific objects dir +OBJ?=obj.gnu/ +SRC=src/ +RSRC=rsrc/ +INC=include/ + +# filename extensions - these won't need to change +o=o +res=o +asm=nasm + +# debugging and release +ifneq ($(RELEASE),0) + # debugging disabled + debug=-fomit-frame-pointer -O2 +else + # debugging enabled + debug=-ggdb -O0 -DDEBUGGINGAIDS -DNOSDLPARACHUTE +endif + +CC=gcc +CXX=gcc +AS=nasm +RC=windres +AR=ar +RANLIB=ranlib +OURCFLAGS=$(debug) -W -Wall -Wimplicit -Wno-char-subscripts -Wno-unused \ + -funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS \ + -DKSFORBUILD -I$(INC:/=) -I../jfaud/src +OURCXXFLAGS=-fno-exceptions -fno-rtti +LIBS= +GAMELIBS=../jfaud/libjfaud.a #../jfaud/mpadec/libmpadec/libmpadec.a +ASFLAGS=-s #-g +EXESUFFIX= + +include Makefile.shared + +ifneq (0,$(USE_A_C)) + ENGINEOBJS=$(OBJ)a-c.$o +else + ENGINEOBJS=$(OBJ)a.$o +endif + +ENGINEOBJS+= \ + $(OBJ)baselayer.$o \ + $(OBJ)cache1d.$o \ + $(OBJ)compat.$o \ + $(OBJ)crc32.$o \ + $(OBJ)defs.$o \ + $(OBJ)engine.$o \ + $(OBJ)engineinfo.$o \ + $(OBJ)glbuild.$o \ + $(OBJ)kplib.$o \ + $(OBJ)lzf_c.$o \ + $(OBJ)lzf_d.$o \ + $(OBJ)md4.$o \ + $(OBJ)mmulti.$o \ + $(OBJ)osd.$o \ + $(OBJ)pragmas.$o \ + $(OBJ)scriptfile.$o + +EDITOROBJS=$(OBJ)build.$o \ + $(OBJ)config.$o + +GAMEEXEOBJS=$(OBJ)game.$o \ + $(OBJ)jfaud_sound.$o \ + $(OBJ)config.$o \ + $(OBJ)$(ENGINELIB) + +EDITOREXEOBJS=$(OBJ)bstub.$o \ + $(OBJ)$(EDITORLIB) \ + $(OBJ)$(ENGINELIB) + +# detect the platform +ifeq ($(PLATFORM),LINUX) + ASFLAGS+= -f elf + LIBS+= -lm +endif +ifeq ($(PLATFORM),BSD) + ASFLAGS+= -f elf + OURCFLAGS+= -I/usr/X11R6/include + LIBS+= -lm +endif +ifeq ($(PLATFORM),WINDOWS) + OURCFLAGS+= -DUNDERSCORES -I$(DXROOT)/include -I$(FMODROOTWIN)/inc + LIBS+= -lm + GAMELIBS+= -L$(FMODROOTWIN)/lib + ASFLAGS+= -DUNDERSCORES -f win32 +endif +ifeq ($(PLATFORM),BEOS) + ASFLAGS+= -f elf + TARGETOPTS+= -DNOASM +endif +ifeq ($(PLATFORM),SUNOS) + LIBS+= -lm +endif +ifeq ($(PLATFORM),SYLLABLE) + ASFLAGS+= -f elf +endif + +ifeq ($(RENDERTYPE),SDL) + ENGINEOBJS+= $(OBJ)sdlayer.$o + OURCFLAGS+= $(subst -Dmain=SDL_main,,$(SDLCONFIG_CFLAGS)) + + ifeq (1,$(HAVE_GTK2)) + OURCFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0) + ENGINEOBJS+= $(OBJ)gtkbits.$o + GAMEEXEOBJS+= $(OBJ)game_banner.$o + EDITOREXEOBJS+= $(OBJ)editor_banner.$o + endif + + GAMEEXEOBJS+= $(OBJ)game_icon.$o + EDITOREXEOBJS+= $(OBJ)build_icon.$o +endif +ifeq ($(RENDERTYPE),WIN) + ENGINEOBJS+= $(OBJ)winlayer.$o + EDITOROBJS+= $(OBJ)buildstartwin.$o + GAMEEXEOBJS+= $(OBJ)gameres.$(res) $(OBJ)gamestartwin.$o + EDITOREXEOBJS+= $(OBJ)buildres.$(res) +endif + +ifneq (0,$(EFENCE)) + LIBS+= -lefence + OURCFLAGS+= -DEFENCE +endif + +OURCFLAGS+= $(BUILDCFLAGS) + +.PHONY: clean veryclean all utils writeengineinfo enginelib editorlib + +# TARGETS + +# Invoking Make from the terminal in OSX just chains the build on to xcode +ifeq ($(PLATFORM),DARWIN) +ifeq ($(RELEASE),0) +style=Development +else +style=Deployment +endif +.PHONY: alldarwin +alldarwin: + cd osx/engine && xcodebuild -target All -buildstyle $(style) + cd osx/game && xcodebuild -target All -buildstyle $(style) +endif + +UTILS=kextract$(EXESUFFIX) kgroup$(EXESUFFIX) transpal$(EXESUFFIX) wad2art$(EXESUFFIX) wad2map$(EXESUFFIX) + +all: game$(EXESUFFIX) build$(EXESUFFIX) $(OBJ)$(ENGINELIB) $(OBJ)$(EDITORLIB) +utils: $(UTILS) + +enginelib: $(OBJ)$(ENGINELIB) +$(OBJ)$(ENGINELIB): $(ENGINEOBJS) + $(AR) rc $@ $^ + $(RANLIB) $@ + +editorlib: $(OBJ)$(EDITORLIB) +$(OBJ)$(EDITORLIB): $(EDITOROBJS) + $(AR) rc $@ $^ + $(RANLIB) $@ + +game$(EXESUFFIX): $(GAMEEXEOBJS) + $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) $(GAMELIBS) $(STDCPPLIB) + +build$(EXESUFFIX): $(EDITOREXEOBJS) + $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) + +pragmacheck$(EXESUFFIX): $(OBJ)pragmacheck.$o $(OBJ)pragmas.$o + $(CC) $(subst -Dmain=app_main,,$(OURCFLAGS)) -o $@ $^ + +kextract$(EXESUFFIX): $(OBJ)kextract.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +kgroup$(EXESUFFIX): $(OBJ)kgroup.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +transpal$(EXESUFFIX): $(OBJ)transpal.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +wad2art$(EXESUFFIX): $(OBJ)wad2art.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +wad2map$(EXESUFFIX): $(OBJ)wad2map.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +generateicon$(EXESUFFIX): $(OBJ)generateicon.$o $(OBJ)kplib.$o + $(CC) -o $@ $^ +cacheinfo$(EXESUFFIX): $(OBJ)cacheinfo.$o $(OBJ)compat.$o + $(CC) -o $@ $^ +enumdisplay$(EXESUFFIX): src/misc/enumdisplay.c + $(CC) -g -Os -o $@ $^ -I$(DXROOT)/include -lgdi32 + +# DEPENDENCIES +include Makefile.deps + +.PHONY: $(OBJ)engineinfo.$o +$(OBJ)engineinfo.$o: + echo "const char _engine_cflags[] = \"$(CFLAGS) $(OURCFLAGS)\";" > $(SRC)tmp/engineinfo.c + echo "const char _engine_libs[] = \"$(LIBS)\";" >> $(SRC)tmp/engineinfo.c + echo "const char _engine_uname[] = \"$(shell uname -a)\";" >> $(SRC)tmp/engineinfo.c + echo "const char _engine_compiler[] = \"$(CC) $(shell $(CC) -dumpversion) $(shell $(CC) -dumpmachine)\";" >> $(SRC)tmp/engineinfo.c + echo "const char _engine_date[] = __DATE__ \" \" __TIME__;" >> $(SRC)tmp/engineinfo.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $(SRC)tmp/engineinfo.c -o $@ 2>&1 + +# RULES +$(OBJ)%.$o: $(SRC)%.nasm + $(AS) $(ASFLAGS) $< -o $@ + +$(OBJ)%.$o: $(SRC)%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(SRC)%.cpp + $(CXX) $(CXXFLAGS) $(OURCXXFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(SRC)tmp/%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(SRC)misc/%.rc + $(RC) -i $^ -o $@ + +$(OBJ)%.$o: $(SRC)util/%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(RSRC)%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)game_banner.$o: $(RSRC)game_banner.c +$(OBJ)editor_banner.$o: $(RSRC)editor_banner.c +$(RSRC)game_banner.c: $(RSRC)game.bmp + echo "#include " > $@ + gdk-pixbuf-csource --extern --struct --raw --name=startbanner_pixdata $^ | sed 's/load_inc//' >> $@ +$(RSRC)editor_banner.c: $(RSRC)build.bmp + echo "#include " > $@ + gdk-pixbuf-csource --extern --struct --raw --name=startbanner_pixdata $^ | sed 's/load_inc//' >> $@ + +# PHONIES +clean: +ifeq ($(PLATFORM),DARWIN) + cd osx/engine && xcodebuild -target All clean + cd osx/game && xcodebuild -target All clean +else + -rm -f $(OBJ)* +endif + +veryclean: clean +ifeq ($(PLATFORM),DARWIN) +else + -rm -f $(ENGINELIB) $(EDITORLIB) game$(EXESUFFIX) build$(EXESUFFIX) $(UTILS) +endif + +.PHONY: fixlineends +fixlineends: + for a in `find . -type f \( -name '*.c' -o -name '*.h' -o -name 'Makefile*' \) \! -path '*/.svn/*'`; do \ + echo Fixing $$a && tr -d "\015" < $$a > $$a.fix && mv $$a.fix $$a; \ + done diff --git a/polymer/build/Makefile.deps b/polymer/build/Makefile.deps new file mode 100644 index 000000000..6e93bfd35 --- /dev/null +++ b/polymer/build/Makefile.deps @@ -0,0 +1,46 @@ +# Build Engine dependencies +# +$(OBJ)a-c.$o: $(SRC)a-c.c $(INC)a.h +$(OBJ)a.$o: $(SRC)a.$(asm) +$(OBJ)baselayer.$o: $(SRC)baselayer.c $(INC)compat.h $(INC)baselayer.h $(INC)build.h $(INC)osd.h +$(OBJ)bstub.$o: $(SRC)bstub.c $(INC)compat.h $(INC)a.h $(INC)build.h $(INC)pragmas.h $(INC)baselayer.h $(INC)names.h $(INC)osd.h $(INC)cache1d.h $(INC)editor.h +$(OBJ)build.$o: $(SRC)build.c $(INC)build.h $(INC)pragmas.h $(INC)compat.h $(INC)baselayer.h $(INC)editor.h +$(OBJ)cache1d.$o: $(SRC)cache1d.c $(INC)compat.h $(INC)cache1d.h $(INC)pragmas.h $(INC)baselayer.h +$(OBJ)compat.$o: $(SRC)compat.c $(INC)compat.h +$(OBJ)config.$o: $(SRC)config.c $(INC)compat.h $(INC)osd.h $(INC)editor.h +$(OBJ)crc32.$o: $(SRC)crc32.c $(INC)crc32.h +$(OBJ)defs.$o: $(SRC)defs.c $(INC)build.h $(INC)baselayer.h $(INC)scriptfile.h $(INC)compat.h +$(OBJ)engine.$o: $(SRC)engine.c $(SRC)polymost.c $(INC)kplib.h $(SRC)hightile.c $(SRC)mdsprite.c $(INC)md4.h $(INC)lzf.h $(INC)lzwnew.h $(INC)compat.h $(INC)build.h $(INC)pragmas.h $(INC)cache1d.h $(INC)a.h $(INC)osd.h $(INC)baselayer.h +$(OBJ)game.$o: $(SRC)game.c $(INC)compat.h $(INC)build.h $(INC)names.h $(INC)pragmas.h $(INC)cache1d.h $(INC)game.h $(INC)osd.h $(INC)baselayer.h +$(OBJ)glbuild.$o: $(SRC)glbuild.c $(INC)glbuild.h $(INC)baselayer.h +$(OBJ)jfaud_sound.$o: $(SRC)jfaud_sound.cpp $(INC)osd.h $(INC)compat.h $(INC)cache1d.h +$(OBJ)kplib.$o: $(SRC)kplib.c $(INC)compat.h +$(OBJ)lzf_c.$o: $(SRC)lzf_c.c $(SRC)lzfP.h +$(OBJ)lzf_d.$o: $(SRC)lzf_d.c $(SRC)lzfP.h +$(OBJ)lzwnew.$o: $(SRC)lzwnew.c +$(OBJ)md4.$o: $(SRC)md4.c $(INC)md4.h $(INC)compat.h +$(OBJ)mmulti_null.$o: $(SRC)mmulti_null.c $(INC)mmulti.h +$(OBJ)mmulti.$o: $(SRC)mmulti.c +$(OBJ)osd.$o: $(SRC)osd.c $(INC)build.h $(INC)osd.h $(INC)compat.h $(INC)engineinfo.h $(INC)baselayer.h +$(OBJ)pragmas.$o: $(SRC)pragmas.c $(INC)compat.h +$(OBJ)scriptfile.$o: $(SRC)scriptfile.c $(INC)scriptfile.h $(INC)cache1d.h $(INC)compat.h +$(OBJ)sdlayer.$o: $(SRC)sdlayer.c $(INC)compat.h $(INC)sdlayer.h $(INC)baselayer.h $(INC)cache1d.h $(INC)pragmas.h $(INC)a.h $(INC)build.h $(INC)osd.h $(INC)glbuild.h +$(OBJ)sound.$o: $(SRC)sound.c $(INC)osd.h $(INC)compat.h $(INC)cache1d.h +$(OBJ)winlayer.$o: $(SRC)winlayer.c $(INC)compat.h $(INC)winlayer.h $(INC)baselayer.h $(INC)pragmas.h $(INC)build.h $(INC)a.h $(INC)osd.h $(INC)dxdidf.h $(INC)glbuild.h +$(OBJ)gtkbits.$o: $(SRC)gtkbits.c $(INC)baselayer.h $(INC)build.h + +$(OBJ)gameres.$(res): $(SRC)misc/gameres.rc +$(OBJ)buildres.$(res): $(SRC)misc/buildres.rc +$(OBJ)gamestartwin.$o: $(SRC)gamestartwin.c $(INC)winlayer.h $(INC)build.h $(INC)compat.h +$(OBJ)buildstartwin.$o: $(SRC)buildstartwin.c $(INC)winlayer.h $(INC)build.h $(INC)compat.h + +$(OBJ)game_icon.$o: $(RSRC)game_icon.c +$(OBJ)build_icon.$o: $(RSRC)build_icon.c + +$(OBJ)kextract.$o: $(SRC)util/kextract.c $(INC)compat.h +$(OBJ)kgroup.$o: $(SRC)util/kgroup.c $(INC)compat.h +$(OBJ)transpal.$o: $(SRC)util/transpal.c $(INC)compat.h $(INC)pragmas.h +$(OBJ)wad2art.$o: $(SRC)util/wad2art.c $(INC)compat.h $(INC)pragmas.h +$(OBJ)wad2map.$o: $(SRC)util/wad2map.c $(INC)compat.h $(INC)pragmas.h +$(OBJ)generateicon.$o: $(SRC)util/generateicon.c +$(OBJ)cacheinfo.$o: $(SRC)util/cacheinfo.c $(INC)compat.h diff --git a/polymer/build/Makefile.msvc b/polymer/build/Makefile.msvc new file mode 100644 index 000000000..49f882932 --- /dev/null +++ b/polymer/build/Makefile.msvc @@ -0,0 +1,166 @@ +# Build Makefile for Microsoft NMake +!ifdef OVERRIDES +!include $(OVERRIDES) +!endif + +SRC=src\ # +!ifndef OBJ +OBJ=obj.msc\ # +!endif +INC=include\ # +!ifndef CFLAGS +CFLAGS=/DSUPERBUILD /DPOLYMOST /DUSE_OPENGL /DDYNAMIC_OPENGL /DKSFORBUILD +!endif + +o=obj +res=res +asm=masm + +ENGINELIB=engine.lib +EDITORLIB=build.lib + +DXROOT=c:\sdks\msc\dx7 +FMODROOT=c:\sdks\fmodapi374win\api + +# /D these to enable certain features of the port's compile process +# USE_A_C This uses a C version of the classic renderer code rather +# than the assembly version in A.ASM. +# If this is defined, alter the $(OBJ)a.$o in the +# ENGINEOBJS declaration to be $(OBJ)a-c.$o +# NOASM When defined, uses C instead of Microsoft inline +# assembly for the features in PRAGMAS.H +TARGETOPTS=#/DUSE_A_C #/DNOASM + +!ifdef DEBUG +# debugging options +flags_cl=/G6 /Ot /Z7 +flags_link=/DEBUG +!else +# release options +#flags_cl=/G6Fy /Ox +flags_cl=/G6 /O2 +flags_link=/RELEASE +!endif + +CC=cl +AS=ml +RC=rc +LINK=link /opt:nowin98 /opt:ref /nologo +CFLAGS=$(CFLAGS) /nologo /MD /J $(flags_cl) $(TARGETOPTS) /I$(INC) /I$(DXROOT)\include /I$(FMODROOT)\inc +LIBS=fmodvc.lib #opengl32.lib +ASFLAGS=/nologo /coff +EXESUFFIX=.exe + +ENGINEOBJS=$(OBJ)a.$o \ + $(OBJ)baselayer.$o \ + $(OBJ)cache1d.$o \ + $(OBJ)compat.$o \ + $(OBJ)crc32.$o \ + $(OBJ)defs.$o \ + $(OBJ)engine.$o \ + $(OBJ)engineinfo.$o \ + $(OBJ)glbuild.$o \ + $(OBJ)kplib.$o \ + $(OBJ)lzf_c.$o \ + $(OBJ)lzf_d.$o \ + $(OBJ)lzwnew.$o \ + $(OBJ)md4.$o \ + $(OBJ)mmulti.$o \ + $(OBJ)osd.$o \ + $(OBJ)pragmas.$o \ + $(OBJ)scriptfile.$o \ + $(OBJ)winlayer.$o + +EDITOROBJS=$(OBJ)build.$o \ + $(OBJ)buildstartwin.$o \ + $(OBJ)config.$o + +GAMEEXEOBJS=$(OBJ)config.$o \ + $(OBJ)game.$o \ + $(OBJ)gameres.$(res) \ + $(OBJ)gamestartwin.$o \ + $(OBJ)sound.$o \ + $(OBJ)$(ENGINELIB) + +EDITOREXEOBJS=$(OBJ)bstub.$o \ + $(OBJ)buildres.$(res) \ + $(OBJ)$(EDITORLIB) \ + $(OBJ)$(ENGINELIB) + +RENDERTYPE=WIN +LIBS=$(LIBS) user32.lib gdi32.lib shell32.lib dxguid.lib wsock32.lib +CFLAGS=$(CFLAGS) /DRENDERTYPE$(RENDERTYPE)=1 + +# RULES +.SUFFIXES: .masm + +{$(SRC)}.masm{$(OBJ)}.$o: + $(AS) /c $(ASFLAGS) /Fo$@ $< + +{$(SRC)tmp}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)util}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)misc}.rc{$(OBJ)}.$(res): + $(RC) /fo$@ /r $< + +{$(SRC)}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +# TARGETS +UTILS=kextract$(EXESUFFIX) kgroup$(EXESUFFIX) transpal$(EXESUFFIX) wad2map$(EXESUFFIX) wad2map$(EXESUFFIX) + +all: game$(EXESUFFIX) build$(EXESUFFIX) $(OBJ)$(ENGINELIB) $(OBJ)$(EDITORLIB) ; +utils: $(UTILS) ; + +enginelib: $(OBJ)$(ENGINELIB) ; +$(OBJ)$(ENGINELIB): $(ENGINEOBJS) + lib /out:$@ /nologo $** + +editorlib: $(OBJ)$(EDITORLIB) ; +$(OBJ)$(EDITORLIB): $(EDITOROBJS) + lib /out:$@ /nologo $** + + +game$(EXESUFFIX): $(GAMEEXEOBJS) + $(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib /LIBPATH:$(FMODROOT)\lib $(flags_link) /MAP $** $(LIBS) msvcrt.lib + +build$(EXESUFFIX): $(EDITOREXEOBJS) + $(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib /LIBPATH:$(FMODROOT)\lib $(flags_link) /MAP $** $(LIBS) msvcrt.lib + +# the tools +kextract$(EXESUFFIX): $(OBJ)kextract.$o $(OBJ)compat.$o + $(LINK) /OUT:$@ /SUBSYSTEM:CONSOLE $(flags_link) /MAP $** msvcrt.lib + +kgroup$(EXESUFFIX): $(OBJ)kgroup.$o $(OBJ)compat.$o + $(LINK) /OUT:$@ /SUBSYSTEM:CONSOLE $(flags_link) /MAP $** msvcrt.lib + +transpal$(EXESUFFIX): $(OBJ)transpal.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(LINK) /OUT:$@ /SUBSYSTEM:CONSOLE $(flags_link) /MAP $** msvcrt.lib + +wad2map$(EXESUFFIX): $(OBJ)wad2map.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(LINK) /OUT:$@ /SUBSYSTEM:CONSOLE $(flags_link) /MAP $** msvcrt.lib + +wad2art$(EXESUFFIX): $(OBJ)wad2art.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + $(LINK) /OUT:$@ /SUBSYSTEM:CONSOLE $(flags_link) /MAP $** msvcrt.lib + +# DEPENDENCIES +!include Makefile.deps + +$(OBJ)engineinfo.$o: writeengineinfo $(SRC)tmp\engineinfo.c + +writeengineinfo: + echo const char _engine_cflags[] = "$(CFLAGS:\=\\)"; > $(SRC)tmp\engineinfo.c + echo const char _engine_libs[] = "$(LIBS)"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_uname[] = "unknown"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_compiler[] = "$(CC)"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_date[] = __DATE__ " " __TIME__; >> $(SRC)tmp\engineinfo.c + +# PHONIES +clean: + -del $(ENGINEOBJS) $(EDITOROBJS) $(GAMEEXEOBJS) $(EDITOREXEOBJS) +veryclean: clean + -del $(OBJ)$(ENGINELIB) $(OBJ)$(EDITORLIB) game$(EXESUFFIX) build$(EXESUFFIX) $(UTILS) + diff --git a/polymer/build/Makefile.shared b/polymer/build/Makefile.shared new file mode 100644 index 000000000..268e99b59 --- /dev/null +++ b/polymer/build/Makefile.shared @@ -0,0 +1,160 @@ +# Shared make information between Build engine and games + +ENGINELIB=libengine.a +EDITORLIB=libbuild.a + +# These are used when DYNAMIC_OPENGL is false +GLLIBWIN=-lopengl32 +GLLIBBSD=-lopengl32 +GLLIBLIN=-lGL + +SDLCONFIG=sdl-config +#SDLCONFIG=/usr/local/bin/sdl11-config + +# overridden for OSes that don't have the cutdown stdc++ that is supc++ +STDCPPLIB=-lsupc++ + +BUILDCFLAGS= + +# Detect the platform if it wasn't explicitly given to us from +# the outside world. This allows cross-compilation by overriding +# CC and giving us PLATFORM specifically. +ifndef PLATFORM + uname=$(strip $(shell uname -s)) + PLATFORM=UNKNOWN + ifeq ($(findstring Linux,$(uname)),Linux) + PLATFORM=LINUX + endif + ifeq ($(findstring BSD,$(uname)),BSD) + PLATFORM=BSD + endif + ifeq ($(findstring MINGW,$(uname)),MINGW) + PLATFORM=WINDOWS + endif + ifeq ($(findstring Darwin,$(uname)),Darwin) + PLATFORM=DARWIN + endif + ifeq ($(findstring BeOS,$(uname)),BeOS) + PLATFORM=BEOS + endif + ifeq ($(findstring skyos,$(uname)),skyos) + PLATFORM=SKYOS + endif + ifeq ($(findstring QNX,$(uname)),QNX) + PLATFORM=QNX + endif + ifeq ($(findstring SunOS,$(uname)),SunOS) + PLATFORM=SUNOS + endif + ifeq ($(findstring syllable,$(uname)),syllable) + PLATFORM=SYLLABLE + endif +endif + +ifeq ($(PLATFORM),LINUX) + RENDERTYPE=SDL + ifneq ($(DYNAMIC_OPENGL),1) + LIBS+= $(GLLIBLIN) + endif + ifeq ($(findstring x86_64,$(shell uname -m)),x86_64) + # on my 64bit Gentoo these are the 32bit emulation libs + LIBS+= -m32 -L/emul/linux/x86/usr/lib + BUILDCFLAGS+= -m32 + override WITHOUT_GTK=1 + endif +endif +ifeq ($(PLATFORM),WINDOWS) + RENDERTYPE ?= WIN + EXESUFFIX=.exe + LIBS+= -lmingwex -lwinmm -L$(DXROOT)/lib -lwsock32 #-lshfolder + ifneq ($(DYNAMIC_OPENGL),1) + LIBS+= $(GLLIBWIN) + endif +endif +ifeq ($(PLATFORM),BSD) + RENDERTYPE=SDL + ifneq ($(DYNAMIC_OPENGL),1) + LIBS+= $(GLLIBBSD) + endif +endif +ifeq ($(PLATFORM),BEOS) + RENDERTYPE=SDL + STDCPPLIB=-lstdc++ +endif +ifeq ($(PLATFORM),SKYOS) + RENDERTYPE=SDL + EXESUFFIX=.app + override USE_A_C=1 + BUILDCFLAGS+= -DUNDERSCORES + SDLCONFIG= + SDLCONFIG_CFLAGS=-I/boot/programs/sdk/include/sdl + LIBS+= -lSDL -lnet +endif +ifeq ($(PLATFORM),QNX) + RENDERTYPE=SDL + override USE_OPENGL=0 + override USE_A_C=1 + STDCPPLIB=-lstdc++ + LIBS+= -lsocket +endif +ifeq ($(PLATFORM),SUNOS) + RENDERTYPE=SDL + override USE_OPENGL=0 + override NOASM=1 + override USE_A_C=1 + STDCPPLIB=-lstdc++ + LIBS+= -lsocket -lnsl +endif +ifeq ($(PLATFORM),SYLLABLE) + RENDERTYPE=SDL + override USE_OPENGL=0 + override NOASM=1 +endif + +ifeq ($(RENDERTYPE),SDL) + ifneq ($(SDLCONFIG),) + LIBS+= $(shell $(SDLCONFIG) --libs) + SDLCONFIG_CFLAGS+=$(shell $(SDLCONFIG) --cflags) + endif + + ifeq (1,$(WITHOUT_GTK)) + HAVE_GTK2=0 + else + ifneq (No,$(shell pkg-config --exists gtk+-2.0 || echo No)) + HAVE_GTK2=1 + LIBS+= $(shell pkg-config --libs gtk+-2.0) + else + HAVE_GTK2=0 + endif + endif +else + ifeq ($(RENDERTYPE),WIN) + LIBS+= -mwindows -ldxguid + endif +endif + +BUILDCFLAGS+= -DRENDERTYPE$(RENDERTYPE)=1 + +ifneq (0,$(SUPERBUILD)) + BUILDCFLAGS+= -DSUPERBUILD +endif +ifneq (0,$(POLYMOST)) + BUILDCFLAGS+= -DPOLYMOST +endif +ifneq (0,$(USE_OPENGL)) + BUILDCFLAGS+= -DUSE_OPENGL + ifneq (0,$(DYNAMIC_OPENGL)) + BUILDCFLAGS+= -DDYNAMIC_OPENGL + endif +endif +ifneq (0,$(USE_A_C)) + BUILDCFLAGS+= -DUSE_A_C +endif +ifneq (0,$(NOASM)) + BUILDCFLAGS+= -DNOASM +endif +ifneq (0,$(SETSPRITEZ)) + BUILDCFLAGS+= -DSETSPRITEZ +endif + + diff --git a/polymer/build/Makefile.watcom b/polymer/build/Makefile.watcom new file mode 100644 index 000000000..ec7ed5e78 --- /dev/null +++ b/polymer/build/Makefile.watcom @@ -0,0 +1,174 @@ +# Build Makefile for Watcom Make + +!ifdef OVERRIDES +!include $(OVERRIDES) +!endif + +SRC=src\ +!ifndef OBJ +OBJ=obj.watcom\ +!endif +INC=include\ +!ifndef CFLAGS +CFLAGS=-dSUPERBUILD -dPOLYMOST -dUSE_OPENGL -dDYNAMIC_OPENGL -dKSFORBUILD +!endif + +o=obj +res=res +asm=wasm + +ENGINELIB=engine.lib +EDITORLIB=build.lib + +DXROOT=c:\sdks\msc\dx7 +FMODROOT=c:\sdks\fmodapi374win\api + +!ifdef __LOADDLL__ +! loaddll wcc386 wccd386 +!endif + +# -d these to enable certain features of the port's compile process +# USE_A_C This uses a C version of the classic renderer code rather +# than the assembly version in A.ASM. +# If this is defined, alter the $(OBJ)a.$o in the +# ENGINEOBJS declaration to be $(OBJ)a-c.$o +# NOASM When defined, uses C code instead of Watcom inline +# assembly for the features in PRAGMAS.H +TARGETOPTS=#-dUSE_A_C #-dNOASM + +CC=wcc386 +AS=wasm +RC=wrc +CFLAGS+= -5r -s -orb -fp5 $(TARGETOPTS) -d2 -dRENDERTYPEWIN=1 & + -i=$(INC) -i=$(DXROOT)\include -i=$(FMODROOT)\inc +LIBS=dxguid.lib wsock32.lib fmodwc.lib #opengl32.lib +ASFLAGS=# -d1 +EXESUFFIX=.exe + +ENGINEOBJS=$(OBJ)a.$o & + $(OBJ)baselayer.$o & + $(OBJ)cache1d.$o & + $(OBJ)compat.$o & + $(OBJ)crc32.$o & + $(OBJ)defs.$o & + $(OBJ)engine.$o & + $(OBJ)engineinfo.$o & + $(OBJ)glbuild.$o & + $(OBJ)kplib.$o & + $(OBJ)lzf_c.$o & + $(OBJ)lzf_d.$o & + $(OBJ)lzwnew.$o & + $(OBJ)md4.$o & + $(OBJ)mmulti.$o & + $(OBJ)osd.$o & + $(OBJ)pragmas.$o & + $(OBJ)scriptfile.$o & + $(OBJ)winlayer.$o + +EDITOROBJS=$(OBJ)build.$o & + $(OBJ)config.$o & + $(OBJ)buildstartwin.$o + +GAMEEXEOBJS=$(OBJ)game.$o & + $(OBJ)sound.$o & + $(OBJ)config.$o & + $(OBJ)gamestartwin.$o + +EDITOREXEOBJS=$(OBJ)bstub.$o + +# RULES +.EXTENSIONS: .wasm .res .rc + +.wasm: $(SRC) +.c: $(SRC) +.c: $(SRC)tmp/ +.c: $(SRC)util/ +.rc: $(SRC)misc/ + +.wasm.$o: + $(AS) $(ASFLAGS) -fo=$(OBJ).$o $[@ + +.c.$o: + $(CC) $(CFLAGS) -fo=$(OBJ).$o $[@ + +.rc.$(res): + $(RC) -fo=$^*.$(res) -r $[@ + +# TARGETS +UTILS=kextract$(EXESUFFIX) kgroup$(EXESUFFIX) transpal$(EXESUFFIX) wad2art$(EXESUFFIX) wad2map$(EXESUFFIX) + +all: game$(EXESUFFIX) build$(EXESUFFIX) $(OBJ)$(ENGINELIB) $(OBJ)$(EDITORLIB) .SYMBOLIC + %null + +utils: $(UTILS) .SYMBOLIC + %null + +enginelib: $(OBJ)$(ENGINELIB) .SYMBOLIC + %null + +$(OBJ)$(ENGINELIB): $(ENGINEOBJS) + %create $(OBJ)$(ENGINELIB).tmp + for %i in ($(ENGINEOBJS)) do %append $(OBJ)$(ENGINELIB).tmp +%i + wlib -b -n $^* @$(OBJ)$(ENGINELIB).tmp + erase $(OBJ)$(ENGINELIB).tmp + +editorlib: $(OBJ)$(EDITORLIB) .SYMBOLIC + %null + +$(OBJ)$(EDITORLIB): $(EDITOROBJS) + %create $(OBJ)$(EDITORLIB).tmp + for %i in ($(EDITOROBJS)) do %append $(OBJ)$(EDITORLIB).tmp +%i + wlib -b -n $^* @$(OBJ)$(EDITORLIB).tmp + erase $(OBJ)$(EDITORLIB).tmp + +game$(EXESUFFIX): $(GAMEEXEOBJS) $(OBJ)gameres.$(res) $(OBJ)$(ENGINELIB) + wlink NAME $@ & + SYSTEM WIN95 & + DEBUG ALL & + OPTION MAP & + FILE { $(GAMEEXEOBJS) } & + RESOURCE $(OBJ)gameres.$(res) & + LIBPATH $(DXROOT)\lib & + LIBPATH $(FMODROOT)\lib & + LIBPATH $(OBJ) & + LIBRARY { $(ENGINELIB) $(LIBS) } + +build$(EXESUFFIX): $(EDITOREXEOBJS) $(OBJ)buildres.$(res) $(OBJ)$(ENGINELIB) $(OBJ)$(EDITORLIB) + wlink NAME $@ & + SYSTEM WIN95 & + DEBUG ALL & + OPTION MAP & + FILE { $(EDITOREXEOBJS) } & + RESOURCE $(OBJ)buildres.$(res) & + LIBPATH $(DXROOT)\lib & + LIBPATH $(FMODROOT)\lib & + LIBPATH $(OBJ) & + LIBRARY { $(ENGINELIB) $(EDITORLIB) $(LIBS) } + +kextract$(EXESUFFIX): $(OBJ)kextract.$o $(OBJ)compat.$o + wlink NAME $@ SYSTEM 386 DEBUG ALL FILE { $< } +kgroup$(EXESUFFIX): $(OBJ)kgroup.$o $(OBJ)compat.$o + wlink NAME $@ SYSTEM 386 DEBUG ALL FILE { $< } +transpal$(EXESUFFIX): $(OBJ)transpal.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + wlink NAME $@ SYSTEM 386 DEBUG ALL FILE { $< } +wad2art$(EXESUFFIX): $(OBJ)wad2art.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + wlink NAME $@ SYSTEM 386 DEBUG ALL FILE { $< } +wad2map$(EXESUFFIX): $(OBJ)wad2map.$o $(OBJ)pragmas.$o $(OBJ)compat.$o + wlink NAME $@ SYSTEM 386 DEBUG ALL FILE { $< } + +# DEPENDENCIES +!include Makefile.deps + +$(OBJ)engineinfo.$o: writeengineinfo $(SRC)tmp\engineinfo.c + +writeengineinfo: .SYMBOLIC + echo const char _engine_cflags[] = "$(CFLAGS:\=\\)"; > $(SRC)tmp\engineinfo.c + echo const char _engine_libs[] = "$(LIBS:\=\\)"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_uname[] = "unknown"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_compiler[] = "$(CC)"; >> $(SRC)tmp\engineinfo.c + echo const char _engine_date[] = __DATE__ " " __TIME__; >> $(SRC)tmp\engineinfo.c + +# PHONIES +clean: .SYMBOLIC + -erase /q $(OBJ)* game$(EXESUFFIX) build$(EXESUFFIX) $(UTILS) *.err + diff --git a/polymer/build/NAMES.H b/polymer/build/NAMES.H new file mode 100644 index 000000000..d22fdaecd --- /dev/null +++ b/polymer/build/NAMES.H @@ -0,0 +1,49 @@ +//Be careful when changing this file - it is parsed by Editart and Build. +#define SWITCH1ON 15 +#define SLIME 34 +#define BACKGROUND 37 +#define KENPICTURE 48 +#define BUILDDISK 49 +#define SWITCH2ON 66 +#define SWITCH2OFF 69 +#define ALPHABET 73 +#define NO 74 +#define DEMOSIGN 75 +#define COIN 76 +#define COINSTACK 77 +#define GIFTBOX 78 +#define DIAMONDS 79 +#define EVILALGRAVE 83 +#define STATUSBAR 87 +#define DAYSKY 89 +#define WATERFOUNTAIN 90 +#define USEWATERFOUNTAIN 91 +#define NIGHTSKY 93 +#define BULLET 98 +#define BOMB 100 +#define CANNON 101 +#define GUNONBOTTOM 102 +#define BOMBEMITTER 103 +#define EXPLOSION 105 +#define SPLASH 106 +#define BROWNMONSTER 110 +#define SKELETON 113 +#define AL 114 +#define EVILAL 115 +#define PLAYER 120 +#define SWITCH3OFF 146 +#define SWITCH3ON 147 +#define AIRPLANE 148 +#define SPIRAL 149 +#define COMPASS 150 +#define FOOTPRINT 156 +#define STATUSBARFILL8 160 +#define STATUSBARFILL4 161 +#define BOUNCYMAT 162 +#define MIRROR 165 +#define FLOORMIRROR 166 +#define GRABBER 167 +#define GRABCANNON 168 +#define MISSILE 169 +#define LAUNCHER 171 +#define MIRRORLABEL 4000 diff --git a/polymer/build/README b/polymer/build/README new file mode 100644 index 000000000..fb7cac057 --- /dev/null +++ b/polymer/build/README @@ -0,0 +1,141 @@ +Build Source Port by Jonathon Fowler +With contributions by Ken Silverman + +ReadMe Information + + +First Source Release: 9 March 2003 +This Release: 9 October 2005 + + + +A Few Notes and Words +--------------------- + This is a release of the source code to my port of Ken +Silverman's Build game engine [1]. The port intends to bring the engine +source up to speed so that it may be used more easily with modern +operating systems on the x86 platform, like Microsoft Windows and *nix- +like ones such as Linux and BSD. + WinBuild is the name I give to the Windows target of this port. +It uses native Windows APIs like DirectX and the GDI to provide close +interaction with Windows for the sake of performance. + I have also developed a more platform-independant layer for +use on systems other than Windows by way of the Simple Direct-media +Layer (SDL) [2]. This layer should assist as a basis for further system +ports or for easier implementation on the platforms SDL supports. + Work on this port is a continuing process. I welcome the +contributions of programmers who have something they'd like to add (or +fix). + + +Configuration +------------- + Runtime settings for BUILD.EXE and GAME.EXE are set in build.cfg +and game.cfg respectively. These files are normal text files. The +original SETUP.DAT that is used in Ken's original code is not used in +this port. The config files are automatically created on the first run of +the game or editor. + + +Building the Source +------------------- + I build the Windows binaries using the following tools and libraries: + * MSYS ('Current' version) (http://www.mingw.org) + * MinGW ('Current' version) (http://www.mingw.org) + * NASM (http://nasm.sourceforge.net/) + * DirectX 6 or above headers and import libraries + DX6: (http://www.libsdl.org/extras/win32/common/directx-devel.tar.gz) + DX9: (http://www.microsoft.com/downloads/details.aspx?FamilyID=afc15f29-d7c9-4cf7-a8d5-8ab81f14ae1b&DisplayLang=en) + * SDL 1.2 (http://www.libsdl.org/download-1.2.php) + SDL is only used for the SDL interface layer and may be + omitted if building the DirectX version. + * FMOD (http://www.fmod.org) + + Some good MinGW guides and whatnot: + - http://www.libsdl.org/extras/win32/mingw32/README.txt + - http://www.spacejack.org/games/mingw/ + + The engine compiles under Linux, FreeBSD, and NetBSD with minimal/no +modification. + + Building the source involves just typing "make" in the directory +where you have unpacked the source. Windows users should make sure the +directory structure in the ZIP is maintained on extraction. The default +interface layer on Windows is the DirectX interface. This can be overriden +to the SDL one by using the command "make RENDERTYPE=SDL" instead. Linux +builds will always use SDL. + +For compilation on other operating systems, see the addendum "Other OSes". + + +Things Missing +-------------- + Nothing much is missing anymore. Networking is being improved as +time passes. + + +Bugs and Whatnot +---------------- + I'm sure during my hacking I've perhaps introduced a bug here or +there. I want to try and nail these as I can. If you think you've found +a bug I would certainly like to hear about it. If you get it to crash, +a crash dump would be extremely helpful. Contact me using the details +found below. + + +Points of Contact +----------------- + The official location for this port on the WWW is at +http://jonof.edgenetwork.org/?p=jfbuild where the latest binaries and +source may be found. You can contact me via email at jonof@edgenetwork.org + + +Credits and Thanks +------------------ +* Ken Silverman for his patience, help, and guidance in this. I +realise my rambling is taxing but your wisdom is invaluable. +* The folks at icculus.org for inspiring me to try and equal their +work done in the first public port of the engine. +* Do I dare mention myself? +* Pimping the edgenetwork (http://www.edgenetwk.com) who host my +site wouldn't go astray. +* Pär Karlsson for his contributions + + +Can't think of anything else at the moment, so, enjoy! + +Jonathon Fowler + + +[1] http://www.advsys.net/ken/buildsrc +[2] http://www.libsdl.org + + +Addendum: Other OSes +-------------------- + +QNX 6.2.1: + I got the engine compiling and running on QNX 6.2.1 on the + 23rd November 2005. The QNX 6.2.1 Non-commercial CDROM includes + the GCC 2.95-series compiler (though you do have to install the + package), and the only extra library you need to obtain and + install (probably from source like I did) is SDL 1.2.9 or newer. + You also have to disable linking to fmod and use the + sound_stub.$o in the Makefile. + +SkyOS 5 beta 8.5: + Disabling fmod and using sound_stub.$o in the Makefile will get + it running. + +Solaris 9: + Because of how Solaris seems to set itself up, you need to: + 1. Edit Makefile and change AR to be 'gar' and RANLIB to be + 'granlib' + 2. Edit Makefile.shared and add (I think) /opt/sfw/bin/ + to the start of SDLCONFIG's value + 3. Disable fmod and use sound_stub.$o in Makefile + +BSD: + Disable fmod and use sound_stub.$o in the Makefile. Use 'gmake' + to build. + diff --git a/polymer/build/build.cfg b/polymer/build/build.cfg new file mode 100644 index 000000000..fd0ff4ec4 --- /dev/null +++ b/polymer/build/build.cfg @@ -0,0 +1,104 @@ +; Build editor configuration + +; Video mode selection +; 0 - Windowed +; 1 - Fullscreen +fullscreen = 0 + +; Video resolution selection +; 0 - 320 x 200 +; 1 - 360 x 200 +; 2 - 320 x 240 +; 3 - 360 x 240 +; 4 - 320 x 400 +; 5 - 360 x 400 +; 6 - 640 x 350 +; 7 - 640 x 400 +; 8 - 640 x 480 +; 9 - 800 x 600 +; 10 - 1024 x 768 +; 11 - 1280 x 1024 +; 12 - 1600 x 1200 +; You can select a seperate 2D editor resolution by +; removing the semicolon from the second line below +; and selecting a mode number. The minimum 2D mode +; is 640x480 (mode #8) +resolution = 8 +;2dresolution = 8 + +; 3D-mode colour depth +bpp = 8 + +; Maximum OpenGL mode refresh rate (Windows only, in Hertz) +maxrefreshfreq = 60 + +; 3D mode brightness setting +; 0 - lowest +; 15 - highest +brightness = 0 + +; Sound sample frequency +; 0 - 6 KHz +; 1 - 8 KHz +; 2 - 11.025 KHz +; 3 - 16 KHz +; 4 - 22.05 KHz +; 5 - 32 KHz +; 6 - 44.1 KHz +samplerate = 4 + +; Music playback +; 0 - Off +; 1 - On +music = 1 + +; Enable mouse +; 0 - No +; 1 - Yes +mouse = 1 + +; Mouse sensitivity +mousesensitivity = 1.0 + +; Key Settings +; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex! +; +---------------------------------------------------------------------------------------------+ +; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 | +; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL | +; | | +; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A | +; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- | +; | | +; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E | +; |TAB Q W E R T Y U I O P [ ] \ DEL END PGDN KP7 KP8 KP9 KP+ | +; | | +; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D | +; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C | +; | KPENTER| +; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 | +; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 | +; | | +; | 1D 38 39 B8 9D CB D0 CD 52 53 | +; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. | +; +---------------------------------------------------------------------------------------------+ + +keyforward = C8 +keybackward = D0 +keyturnleft = CB +keyturnright = CD +keyrun = 2A +keystrafe = 9D +keyfire = 1D +keyuse = 39 +keystandhigh = 1E +keystandlow = 2C +keylookup = D1 +keylookdown = C9 +keystrafeleft = 33 +keystraferight = 34 +key2dmode = 9C +keyviewcycle = 1C +key2dzoomin = D +key2dzoomout = C +keychat = F + diff --git a/polymer/build/buildlic.txt b/polymer/build/buildlic.txt new file mode 100644 index 000000000..3a3985bb6 --- /dev/null +++ b/polymer/build/buildlic.txt @@ -0,0 +1,71 @@ +BUILD SOURCE CODE LICENSE TERMS: 06/20/2000 + +[1] I give you permission to make modifications to my Build source and + distribute it, BUT: + +[2] Any derivative works based on my Build source may be distributed ONLY + through the INTERNET. + +[3] Distribution of any derivative works MUST be done completely FREE of + charge - no commercial exploitation whatsoever. + +[4] Anything you distribute which uses a part of my Build Engine source + code MUST include: + + [A] The following message somewhere in the archive: + + // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman + // Ken Silverman's official web site: "http://www.advsys.net/ken" + // See the included license file "BUILDLIC.TXT" for license info. + + [B] This text file "BUILDLIC.TXT" along with it. + + [C] Any source files that you modify must include this message as well: + + // This file has been modified from Ken Silverman's original release + +[5] The use of the Build Engine for commercial purposes will require an + appropriate license arrangement with me. Contact information is + on my web site. + +[6] I take no responsibility for damage to your system. + +[7] Technical support: Before contacting me with questions, please read + and do ALL of the following! + + [A] Look through ALL of my text files. There are 7 of them (including this + one). I like to think that I wrote them for a reason. You will find + many of your answers in the history section of BUILD.TXT and + BUILD2.TXT (they're located inside SRC.ZIP). + + [B] If that doesn't satisfy you, then try going to: + + "http://www.advsys.net/ken/buildsrc" + + where I will maintain a Build Source Code FAQ (or perhaps I might + just provide a link to a good FAQ). + + [C] I am willing to respond to questions, but ONLY if they come at a rate + that I can handle. + + PLEASE TRY TO AVOID ASKING DUPLICATE QUESTIONS! + + As my line of defense, I will post my current policy about + answering Build source questions (right below the E-mail address + on my web site.) You can check there to see if I'm getting + overloaded with questions or not. + + If I'm too busy, it might say something like this: + + I'm too busy to answer Build source questions right now. + Sorry, but don't expect a reply from me any time soon. + + If I'm open for Build source questions, please state your question + clearly and don't include any unsolicited attachments unless + they're really small (like less than 50k). Assume that I have + a 28.8k modem. Also, don't leave out important details just + to make your question appear shorter - making me guess what + you're asking doesn't save me time! + +---------------------------------------------------------------------------- +-Ken S. (official web site: http://www.advsys.net/ken) diff --git a/polymer/build/devcpp/Build.dev b/polymer/build/devcpp/Build.dev new file mode 100644 index 000000000..6c9c7e729 --- /dev/null +++ b/polymer/build/devcpp/Build.dev @@ -0,0 +1,68 @@ +[Project] +FileName=Build.dev +Name=KenBuild Editor +UnitCount=2 +Type=0 +Ver=1 +ObjFiles= +Includes=..\include +Libs=C:\sdks\msc\dx7\include +PrivateResource=Build_private.rc +ResourceIncludes=..\ +MakeIncludes= +Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_ +CppCompiler= +Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_ +IsCpp=0 +Icon= +ExeOutput=..\devcpp +ObjectOutput=..\devcpp +OverrideOutput=0 +OverrideOutputName=libengine.a +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000100010000d0 + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit1] +FileName=..\src\bstub.c +CompileCpp=0 +Folder=KenBuild Editor +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\src\misc\buildres.rc +Folder=KenBuild Editor +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/polymer/build/devcpp/Game.dev b/polymer/build/devcpp/Game.dev new file mode 100644 index 000000000..b4b498a11 --- /dev/null +++ b/polymer/build/devcpp/Game.dev @@ -0,0 +1,98 @@ +[Project] +FileName=Game.dev +Name=KenBuild Game +UnitCount=5 +Type=0 +Ver=1 +ObjFiles= +Includes=..\include;C:\sdks\fmodapi373win\api\inc +Libs=C:\sdks\msc\dx7\include;C:\sdks\fmodapi373win\api\lib +PrivateResource=Game_private.rc +ResourceIncludes=..\ +MakeIncludes= +Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_ +CppCompiler= +Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_-lfmod_@@_ +IsCpp=0 +Icon= +ExeOutput=..\devcpp +ObjectOutput=..\devcpp +OverrideOutput=0 +OverrideOutputName=libengine.a +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000100010000d0 + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit3] +FileName=..\src\sound.c +CompileCpp=0 +Folder=KenBuild Editor +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\src\misc\gameres.rc +Folder=KenBuild Game +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=..\src\config.c +CompileCpp=0 +Folder=KenBuild Editor +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\src\game.c +CompileCpp=0 +Folder=KenBuild Editor +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\src\gamestartwin.c +CompileCpp=0 +Folder=KenBuild Game +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/polymer/build/devcpp/engineinfo.c b/polymer/build/devcpp/engineinfo.c new file mode 100644 index 000000000..71cd27509 --- /dev/null +++ b/polymer/build/devcpp/engineinfo.c @@ -0,0 +1,5 @@ +const char _engine_cflags[] = "Dev-C++ made this"; +const char _engine_libs[] = "Dev-C++ made this"; +const char _engine_uname[] = "Dev-C++"; +const char _engine_compiler[] = "Dev-C++"; +const char _engine_date[] = __DATE__ " " __TIME__; diff --git a/polymer/build/devcpp/libEditor.dev b/polymer/build/devcpp/libEditor.dev new file mode 100644 index 000000000..c297369be --- /dev/null +++ b/polymer/build/devcpp/libEditor.dev @@ -0,0 +1,79 @@ +[Project] +FileName=libEditor.dev +Name=Build Editor library +UnitCount=3 +Type=2 +Ver=1 +ObjFiles= +Includes=..\include;..\src +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_ +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput=..\devcpp +ObjectOutput=..\devcpp +OverrideOutput=1 +OverrideOutputName=libeditor.a +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000100010000d0 + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit3] +FileName=..\src\buildstartwin.c +CompileCpp=0 +Folder=KenBuild Editor +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=..\src\build.c +CompileCpp=0 +Folder=Build Editor library +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\src\config.c +CompileCpp=0 +Folder=Build Editor library +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/polymer/build/devcpp/libEngine.dev b/polymer/build/devcpp/libEngine.dev new file mode 100644 index 000000000..2e9adace8 --- /dev/null +++ b/polymer/build/devcpp/libEngine.dev @@ -0,0 +1,198 @@ +[Project] +FileName=libEngine.dev +Name=Build Engine library +UnitCount=15 +Type=2 +Ver=1 +ObjFiles= +Includes=..\include;..\src;C:\sdks\msc\dx7\include +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-DKSFORBUILD_@@_-funsigned-char_@@_ +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput=..\devcpp +ObjectOutput=..\devcpp +OverrideOutput=1 +OverrideOutputName=libengine.a +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000100010000d0 + +[Unit1] +FileName=..\src\cache1d.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\src\engine.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\src\crc32.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\src\osd.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\src\pragmas.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\src\a.nasm +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=nasm -s -DUNDERSCORES -f win32 ../src/a.nasm -o ../devcpp/a.o + +[Unit7] +FileName=engineinfo.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\src\defs.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\src\compat.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\src\baselayer.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\src\glbuild.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\src\kplib.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\src\mmulti.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\src\scriptfile.c +CompileCpp=0 +Folder=Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit15] +FileName=..\src\winlayer.c +CompileCpp=0 +Folder=Build Engine +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/polymer/build/game.cfg b/polymer/build/game.cfg new file mode 100644 index 000000000..5dc3bf6cd --- /dev/null +++ b/polymer/build/game.cfg @@ -0,0 +1,97 @@ +; KenBuild configuration + +; Video mode selection +; 0 - Windowed +; 1 - Fullscreen +fullscreen = 0 + +; Video resolution selection +; 0 - 320 x 200 +; 1 - 360 x 200 +; 2 - 320 x 240 +; 3 - 360 x 240 +; 4 - 320 x 400 +; 5 - 360 x 400 +; 6 - 640 x 350 +; 7 - 640 x 400 +; 8 - 640 x 480 +; 9 - 800 x 600 +; 10 - 1024 x 768 +; 11 - 1280 x 1024 +; 12 - 1600 x 1200 +resolution = 8 + +; 3D-mode colour depth +bpp = 8 + +; 3D mode brightness setting +; 0 - lowest +; 15 - highest +brightness = 0 + +; Maximum OpenGL mode refresh rate (Windows only, in Hertz) +maxrefreshfreq = 60 + +; Sound sample frequency +; 0 - 6 KHz +; 1 - 8 KHz +; 2 - 11.025 KHz +; 3 - 16 KHz +; 4 - 22.05 KHz +; 5 - 32 KHz +; 6 - 44.1 KHz +samplerate = 4 + +; Music playback +; 0 - Off +; 1 - On +music = 1 + +; Enable mouse +; 0 - No +; 1 - Yes +mouse = 1 + +; Key Settings +; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex! +; +---------------------------------------------------------------------------------------------+ +; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 | +; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL | +; | | +; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A | +; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- | +; | | +; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E | +; |TAB Q W E R T Y U I O P [ ] \ DEL END PGDN KP7 KP8 KP9 KP+ | +; | | +; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D | +; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C | +; | KPENTER| +; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 | +; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 | +; | | +; | 1D 38 39 B8 9D CB D0 CD 52 53 | +; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. | +; +---------------------------------------------------------------------------------------------+ + +keyforward = C8 +keybackward = D0 +keyturnleft = CB +keyturnright = CD +keyrun = 2A +keystrafe = 9D +keyfire = 1D +keyuse = 39 +keystandhigh = 1E +keystandlow = 2C +keylookup = D1 +keylookdown = C9 +keystrafeleft = 33 +keystraferight = 34 +key2dmode = 9C +keyviewcycle = 1C +key2dzoomin = D +key2dzoomout = C +keychat = F +keyconsole = 29 + diff --git a/polymer/build/include/a.h b/polymer/build/include/a.h new file mode 100644 index 000000000..eb174e79f --- /dev/null +++ b/polymer/build/include/a.h @@ -0,0 +1,245 @@ +// Assembly-language function wrappers for a.asm functions +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + + +#ifndef __a_h__ +#define __a_h__ + +#if defined(USE_A_C) + +#define ENGINE_USING_A_C + +void setvlinebpl(long dabpl); +void fixtransluscence(long datransoff); +void settransnormal(void); +void settransreverse(void); + +void sethlinesizes(long logx, long logy, long bufplc); +void setpalookupaddress(char *paladdr); +void setuphlineasm4(long bxinc, long byinc); +void hlineasm4(long cnt, long skiploadincs, long paloffs, unsigned long by, unsigned long bx, long p); + +void setupslopevlin(long logylogx, long bufplc, long pinc); +void slopevlin(long p, long i, long slopaloffs, long cnt, long bx, long by); + +void setupvlineasm(long neglogy); +void vlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p); + +void setupmvlineasm(long neglogy); +void mvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p); + +void setuptvlineasm(long neglogy); +void tvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p); + +void msethlineshift(long logx, long logy); +void mhline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p); + +void tsethlineshift(long logx, long logy); +void thline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p); + +void setupspritevline(long paloffs, long bxinc, long byinc, long ysiz); +void spritevline(long bx, long by, long cnt, long bufplc, long p); + +void msetupspritevline(long paloffs, long bxinc, long byinc, long ysiz); +void mspritevline(long bx, long by, long cnt, long bufplc, long p); + +void tsetupspritevline(long paloffs, long bxinc, long byinc, long ysiz); +void tspritevline(long bx, long by, long cnt, long bufplc, long p); + +void setupdrawslab (long dabpl, long pal); +void drawslab (long dx, long v, long dy, long vi, long vptr, long p); +void stretchhline (long p0, long u, long cnt, long uinc, long rptr, long p); + +void mmxoverlay(); + +#elif defined(__WATCOMC__) // USE_A_C + +extern long mmxoverlay(); +#pragma aux mmxoverlay modify [eax ebx ecx edx]; +extern long sethlinesizes(long,long,long); +#pragma aux sethlinesizes parm [eax][ebx][ecx]; +extern long setpalookupaddress(char *); +#pragma aux setpalookupaddress parm [eax]; +extern long setuphlineasm4(long,long); +#pragma aux setuphlineasm4 parm [eax][ebx]; +extern long hlineasm4(long,long,long,long,long,long); +#pragma aux hlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setuprhlineasm4(long,long,long,long,long,long); +#pragma aux setuprhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long rhlineasm4(long,long,long,long,long,long); +#pragma aux rhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setuprmhlineasm4(long,long,long,long,long,long); +#pragma aux setuprmhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long rmhlineasm4(long,long,long,long,long,long); +#pragma aux rmhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setupqrhlineasm4(long,long,long,long,long,long); +#pragma aux setupqrhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long qrhlineasm4(long,long,long,long,long,long); +#pragma aux qrhlineasm4 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setvlinebpl(long); +#pragma aux setvlinebpl parm [eax]; +extern long fixtransluscence(long); +#pragma aux fixtransluscence parm [eax]; +extern long prevlineasm1(long,long,long,long,long,long); +#pragma aux prevlineasm1 parm [eax][ebx][ecx][edx][esi][edi]; +extern long vlineasm1(long,long,long,long,long,long); +#pragma aux vlineasm1 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setuptvlineasm(long); +#pragma aux setuptvlineasm parm [eax]; +extern long tvlineasm1(long,long,long,long,long,long); +#pragma aux tvlineasm1 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setuptvlineasm2(long,long,long); +#pragma aux setuptvlineasm2 parm [eax][ebx][ecx]; +extern long tvlineasm2(long,long,long,long,long,long); +#pragma aux tvlineasm2 parm [eax][ebx][ecx][edx][esi][edi]; +extern long mvlineasm1(long,long,long,long,long,long); +#pragma aux mvlineasm1 parm [eax][ebx][ecx][edx][esi][edi]; +extern long setupvlineasm(long); +#pragma aux setupvlineasm parm [eax]; +extern long vlineasm4(long,long); +#pragma aux vlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi]; +extern long setupmvlineasm(long); +#pragma aux setupmvlineasm parm [eax]; +extern long mvlineasm4(long,long); +#pragma aux mvlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi]; +extern void setupspritevline(long,long,long,long,long,long); +#pragma aux setupspritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern void spritevline(long,long,long,long,long,long); +#pragma aux spritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern void msetupspritevline(long,long,long,long,long,long); +#pragma aux msetupspritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern void mspritevline(long,long,long,long,long,long); +#pragma aux mspritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern void tsetupspritevline(long,long,long,long,long,long); +#pragma aux tsetupspritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern void tspritevline(long,long,long,long,long,long); +#pragma aux tspritevline parm [eax][ebx][ecx][edx][esi][edi]; +extern long mhline(long,long,long,long,long,long); +#pragma aux mhline parm [eax][ebx][ecx][edx][esi][edi]; +extern long mhlineskipmodify(long,long,long,long,long,long); +#pragma aux mhlineskipmodify parm [eax][ebx][ecx][edx][esi][edi]; +extern long msethlineshift(long,long); +#pragma aux msethlineshift parm [eax][ebx]; +extern long thline(long,long,long,long,long,long); +#pragma aux thline parm [eax][ebx][ecx][edx][esi][edi]; +extern long thlineskipmodify(long,long,long,long,long,long); +#pragma aux thlineskipmodify parm [eax][ebx][ecx][edx][esi][edi]; +extern long tsethlineshift(long,long); +#pragma aux tsethlineshift parm [eax][ebx]; +extern long setupslopevlin(long,long,long); +#pragma aux setupslopevlin parm [eax][ebx][ecx] modify [edx]; +extern long slopevlin(long,long,long,long,long,long); +#pragma aux slopevlin parm [eax][ebx][ecx][edx][esi][edi]; +extern long settransnormal(); +#pragma aux settransnormal parm; +extern long settransreverse(); +#pragma aux settransreverse parm; +extern long setupdrawslab(long,long); +#pragma aux setupdrawslab parm [eax][ebx]; +extern long drawslab(long,long,long,long,long,long); +#pragma aux drawslab parm [eax][ebx][ecx][edx][esi][edi]; + +#elif defined(__GNUC__) && defined(__i386__) // __WATCOMC__ + +#if defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__SYLLABLE__) +#define __cdecl +#endif + +extern long __cdecl mmxoverlay(); +extern long __cdecl sethlinesizes(long,long,long); +extern long __cdecl setpalookupaddress(char *); +extern long __cdecl setuphlineasm4(long,long); +extern long __cdecl hlineasm4(long,long,long,long,long,long); +extern long __cdecl setuprhlineasm4(long,long,long,long,long,long); +extern long __cdecl rhlineasm4(long,long,long,long,long,long); +extern long __cdecl setuprmhlineasm4(long,long,long,long,long,long); +extern long __cdecl rmhlineasm4(long,long,long,long,long,long); +extern long __cdecl setupqrhlineasm4(long,long,long,long,long,long); +extern long __cdecl qrhlineasm4(long,long,long,long,long,long); +extern long __cdecl setvlinebpl(long); +extern long __cdecl fixtransluscence(long); +extern long __cdecl prevlineasm1(long,long,long,long,long,long); +extern long __cdecl vlineasm1(long,long,long,long,long,long); +extern long __cdecl setuptvlineasm(long); +extern long __cdecl tvlineasm1(long,long,long,long,long,long); +extern long __cdecl setuptvlineasm2(long,long,long); +extern long __cdecl tvlineasm2(long,long,long,long,long,long); +extern long __cdecl mvlineasm1(long,long,long,long,long,long); +extern long __cdecl setupvlineasm(long); +extern long __cdecl vlineasm4(long,long); +extern long __cdecl setupmvlineasm(long); +extern long __cdecl mvlineasm4(long,long); +extern long __cdecl setupspritevline(long,long,long,long,long,long); +extern long __cdecl spritevline(long,long,long,long,long,long); +extern long __cdecl msetupspritevline(long,long,long,long,long,long); +extern long __cdecl mspritevline(long,long,long,long,long,long); +extern long __cdecl tsetupspritevline(long,long,long,long,long,long); +extern long __cdecl tspritevline(long,long,long,long,long,long); +extern long __cdecl mhline(long,long,long,long,long,long); +extern long __cdecl mhlineskipmodify(long,long,long,long,long,long); +extern long __cdecl msethlineshift(long,long); +extern long __cdecl thline(long,long,long,long,long,long); +extern long __cdecl thlineskipmodify(long,long,long,long,long,long); +extern long __cdecl tsethlineshift(long,long); +extern long __cdecl setupslopevlin(long,long,long); +extern long __cdecl slopevlin(long,long,long,long,long,long); +extern long __cdecl settransnormal(); +extern long __cdecl settransreverse(); +extern long __cdecl setupdrawslab(long,long); +extern long __cdecl drawslab(long,long,long,long,long,long); +extern void __cdecl stretchhline(long,long,long,long,long,long); + +#elif defined(_MSC_VER) // __GNUC__ && __i386__ + +extern long _cdecl mmxoverlay(); +extern long _cdecl sethlinesizes(long,long,long); +extern long _cdecl setpalookupaddress(char *); +extern long _cdecl setuphlineasm4(long,long); +extern long _cdecl hlineasm4(long,long,long,long,long,long); +extern long _cdecl setuprhlineasm4(long,long,long,long,long,long); +extern long _cdecl rhlineasm4(long,long,long,long,long,long); +extern long _cdecl setuprmhlineasm4(long,long,long,long,long,long); +extern long _cdecl rmhlineasm4(long,long,long,long,long,long); +extern long _cdecl setupqrhlineasm4(long,long,long,long,long,long); +extern long _cdecl qrhlineasm4(long,long,long,long,long,long); +extern long _cdecl setvlinebpl(long); +extern long _cdecl fixtransluscence(long); +extern long _cdecl prevlineasm1(long,long,long,long,long,long); +extern long _cdecl vlineasm1(long,long,long,long,long,long); +extern long _cdecl setuptvlineasm(long); +extern long _cdecl tvlineasm1(long,long,long,long,long,long); +extern long _cdecl setuptvlineasm2(long,long,long); +extern long _cdecl tvlineasm2(long,long,long,long,long,long); +extern long _cdecl mvlineasm1(long,long,long,long,long,long); +extern long _cdecl setupvlineasm(long); +extern long _cdecl vlineasm4(long,long); +extern long _cdecl setupmvlineasm(long); +extern long _cdecl mvlineasm4(long,long); +extern long _cdecl setupspritevline(long,long,long,long,long,long); +extern long _cdecl spritevline(long,long,long,long,long,long); +extern long _cdecl msetupspritevline(long,long,long,long,long,long); +extern long _cdecl mspritevline(long,long,long,long,long,long); +extern long _cdecl tsetupspritevline(long,long,long,long,long,long); +extern long _cdecl tspritevline(long,long,long,long,long,long); +extern long _cdecl mhline(long,long,long,long,long,long); +extern long _cdecl mhlineskipmodify(long,long,long,long,long,long); +extern long _cdecl msethlineshift(long,long); +extern long _cdecl thline(long,long,long,long,long,long); +extern long _cdecl thlineskipmodify(long,long,long,long,long,long); +extern long _cdecl tsethlineshift(long,long); +extern long _cdecl setupslopevlin(long,long,long); +extern long _cdecl slopevlin(long,long,long,long,long,long); +extern long _cdecl settransnormal(); +extern long _cdecl settransreverse(); +extern long _cdecl setupdrawslab(long,long); +extern long _cdecl drawslab(long,long,long,long,long,long); +extern void _cdecl stretchhline(long,long,long,long,long,long); + +#else // _MSC_VER + +#error Unsupported compiler or architecture. + +#endif // else + +#endif // __a_h__ diff --git a/polymer/build/include/baselayer.h b/polymer/build/include/baselayer.h new file mode 100644 index 000000000..d4d47cf41 --- /dev/null +++ b/polymer/build/include/baselayer.h @@ -0,0 +1,126 @@ +// Base services interface declaration +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __baselayer_h__ +#define __baselayer_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _buildargc; +extern char **_buildargv; + +extern char quitevent, appactive; + +extern char *startwin_labeltext; + +// video +extern long xres, yres, bpp, fullscreen, bytesperline, imageSize, frameplace; +extern char offscreenrendering; + +extern void (*baselayer_onvideomodechange)(int); + +#ifdef USE_OPENGL +struct glinfo { + const char *vendor; + const char *renderer; + const char *version; + const char *extensions; + + float maxanisotropy; + char bgra; + char clamptoedge; + char texcompr; + char texnpot; + char multisample; + char nvmultisamplehint; +}; +extern struct glinfo glinfo; +#endif + +extern char inputdevices; + +// keys +#define KEYFIFOSIZ 64 +extern char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; +extern unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; + +// mouse +extern long mousex, mousey, mouseb; + +// joystick +extern long *joyaxis, *joyhat, joyb; +extern char joyisgamepad, joynumaxes, joynumbuttons, joynumhats; +extern long joyaxespresent; + + + +int initsystem(void); +void uninitsystem(void); + +void initprintf(const char *, ...); +void debugprintf(const char *,...); + +int handleevents(void); + +typedef void (*KeyPressCallback)(long,long); +typedef void (*MousePressCallback)(long,long); +typedef void (*JoyPressCallback)(long,long); +int initinput(void); +void uninitinput(void); +void releaseallbuttons(void); +void setkeypresscallback(void (*callback)(long,long)); +void setmousepresscallback(void (*callback)(long,long)); +void setjoypresscallback(void (*callback)(long,long)); +const unsigned char *getkeyname(int num); +const unsigned char *getjoyname(int what, int num); // what: 0=axis, 1=button, 2=hat + +unsigned char bgetchar(void); +int bkbhit(void); +void bflushchars(void); + +int initmouse(void); +void uninitmouse(void); +void grabmouse(char a); +void readmousexy(long *x, long *y); +void readmousebstatus(long *b); +void setjoydeadzone(int axis, unsigned short dead, unsigned short satur); +void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur); + +int inittimer(int); +void uninittimer(void); +void sampletimer(void); +unsigned long getticks(void); +int gettimerfreq(void); +void (*installusertimercallback(void (*callback)(void)))(void); + +int checkvideomode(int *x, int *y, int c, int fs); +int setvideomode(int x, int y, int c, int fs); +void getvalidmodes(void); +void resetvideomode(void); + +void begindrawing(void); +void enddrawing(void); +void showframe(int); + +int setpalette(int start, int num, char *dapal); +//int getpalette(int start, int num, char *dapal); +int setgamma(float ro, float go, float bo); + +int switchrendermethod(int,int); // 0 = software, 1 = opengl | bool = reinit + +int wm_msgbox(char *name, char *fmt, ...); +int wm_ynbox(char *name, char *fmt, ...); +void wm_setapptitle(char *name); + +// baselayer.c +int baselayer_init(); + +#ifdef __cplusplus +} +#endif + +#endif // __baselayer_h__ + diff --git a/polymer/build/include/baselayer.h.r276 b/polymer/build/include/baselayer.h.r276 new file mode 100644 index 000000000..2cb503c9c --- /dev/null +++ b/polymer/build/include/baselayer.h.r276 @@ -0,0 +1,121 @@ +// Base services interface declaration +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __baselayer_h__ +#define __baselayer_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _buildargc; +extern char **_buildargv; + +extern char quitevent, appactive; + +extern char *startwin_labeltext; + +// video +extern long xres, yres, bpp, fullscreen, bytesperline, imageSize, frameplace; +extern char offscreenrendering; + +extern void (*baselayer_onvideomodechange)(int); + +#ifdef USE_OPENGL +struct glinfo { + const char *vendor; + const char *renderer; + const char *version; + const char *extensions; + + float maxanisotropy; + char bgra, clamptoedge, texcompr, texnpot; +}; +extern struct glinfo glinfo; +#endif + +extern char inputdevices; + +// keys +#define KEYFIFOSIZ 64 +extern char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; +extern unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; + +// mouse +extern long mousex, mousey, mouseb; + +// joystick +extern long *joyaxis, *joyhat, joyb; +extern char joyisgamepad, joynumaxes, joynumbuttons, joynumhats; +extern long joyaxespresent; + + + +int initsystem(void); +void uninitsystem(void); + +void initprintf(const char *, ...); +void debugprintf(const char *,...); + +int handleevents(void); + +typedef void (*KeyPressCallback)(long,long); +typedef void (*MousePressCallback)(long,long); +typedef void (*JoyPressCallback)(long,long); +int initinput(void); +void uninitinput(void); +void releaseallbuttons(void); +void setkeypresscallback(void (*callback)(long,long)); +void setmousepresscallback(void (*callback)(long,long)); +void setjoypresscallback(void (*callback)(long,long)); +const unsigned char *getkeyname(int num); +const unsigned char *getjoyname(int what, int num); // what: 0=axis, 1=button, 2=hat + +unsigned char bgetchar(void); +int bkbhit(void); +void bflushchars(void); + +int initmouse(void); +void uninitmouse(void); +void grabmouse(char a); +void readmousexy(long *x, long *y); +void readmousebstatus(long *b); +void setjoydeadzone(int axis, unsigned short dead, unsigned short satur); +void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur); + +int inittimer(int); +void uninittimer(void); +void sampletimer(void); +unsigned long getticks(void); +int gettimerfreq(void); +void (*installusertimercallback(void (*callback)(void)))(void); + +int checkvideomode(int *x, int *y, int c, int fs); +int setvideomode(int x, int y, int c, int fs); +void getvalidmodes(void); +void resetvideomode(void); + +void begindrawing(void); +void enddrawing(void); +void showframe(int); + +int setpalette(int start, int num, char *dapal); +//int getpalette(int start, int num, char *dapal); +int setgamma(float ro, float go, float bo); + +int switchrendermethod(int,int); // 0 = software, 1 = opengl | bool = reinit + +int wm_msgbox(char *name, char *fmt, ...); +int wm_ynbox(char *name, char *fmt, ...); +void wm_setapptitle(char *name); + +// baselayer.c +int baselayer_init(); + +#ifdef __cplusplus +} +#endif + +#endif // __baselayer_h__ + diff --git a/polymer/build/include/baselayer.h.r277 b/polymer/build/include/baselayer.h.r277 new file mode 100644 index 000000000..45d0c78ba --- /dev/null +++ b/polymer/build/include/baselayer.h.r277 @@ -0,0 +1,126 @@ +// Base services interface declaration +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __baselayer_h__ +#define __baselayer_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _buildargc; +extern char **_buildargv; + +extern char quitevent, appactive; + +extern char *startwin_labeltext; + +// video +extern long xres, yres, bpp, fullscreen, bytesperline, imageSize, frameplace; +extern char offscreenrendering; + +extern void (*baselayer_onvideomodechange)(int); + +#ifdef USE_OPENGL +struct glinfo { + const char *vendor; + const char *renderer; + const char *version; + const char *extensions; + + float maxanisotropy; + char bgra; + char clamptoedge; + char texcompr; + char texnpot; + char multisample; + char nvmultisamplehint; +}; +extern struct glinfo glinfo; +#endif + +extern char inputdevices; + +// keys +#define KEYFIFOSIZ 64 +extern char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; +extern unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; + +// mouse +extern long mousex, mousey, mouseb; + +// joystick +extern long *joyaxis, *joyhat, joyb; +extern char joyisgamepad, joynumaxes, joynumbuttons, joynumhats; +extern long joyaxespresent; + + + +int initsystem(void); +void uninitsystem(void); + +void initprintf(const char *, ...); +void debugprintf(const char *,...); + +int handleevents(void); + +typedef void (*KeyPressCallback)(long,long); +typedef void (*MousePressCallback)(long,long); +typedef void (*JoyPressCallback)(long,long); +int initinput(void); +void uninitinput(void); +void releaseallbuttons(void); +void setkeypresscallback(void (*callback)(long,long)); +void setmousepresscallback(void (*callback)(long,long)); +void setjoypresscallback(void (*callback)(long,long)); +const unsigned char *getkeyname(int num); +const unsigned char *getjoyname(int what, int num); // what: 0=axis, 1=button, 2=hat + +unsigned char bgetchar(void); +int bkbhit(void); +void bflushchars(void); + +int initmouse(void); +void uninitmouse(void); +void grabmouse(char a); +void readmousexy(long *x, long *y); +void readmousebstatus(long *b); +void setjoydeadzone(int axis, unsigned short dead, unsigned short satur); +void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur); + +int inittimer(int); +void uninittimer(void); +void sampletimer(void); +unsigned long getticks(void); +int gettimerfreq(void); +void (*installusertimercallback(void (*callback)(void)))(void); + +int checkvideomode(int *x, int *y, int c, int fs); +int setvideomode(int x, int y, int c, int fs); +void getvalidmodes(void); +void resetvideomode(void); + +void begindrawing(void); +void enddrawing(void); +void showframe(int); + +int setpalette(int start, int num, char *dapal); +//int getpalette(int start, int num, char *dapal); +int setgamma(float ro, float go, float bo); + +int switchrendermethod(int,int); // 0 = software, 1 = opengl | bool = reinit + +int wm_msgbox(char *name, char *fmt, ...); +int wm_ynbox(char *name, char *fmt, ...); +void wm_setapptitle(char *name); + +// baselayer.c +int baselayer_init(); + +#ifdef __cplusplus +} +#endif + +#endif // __baselayer_h__ + diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h new file mode 100644 index 000000000..79d16fb25 --- /dev/null +++ b/polymer/build/include/build.h @@ -0,0 +1,516 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + + +#ifndef __build_h__ +#define __build_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXSECTORSV8 4096 +#define MAXWALLSV8 16384 +#define MAXSPRITESV8 16384 + +#define MAXSECTORSV7 1024 +#define MAXWALLSV7 8192 +#define MAXSPRITESV7 4096 + +#define MAXSECTORS MAXSECTORSV8 +#define MAXWALLS MAXWALLSV8 +#define MAXSPRITES MAXSPRITESV8 + +#define MAXTILES 15360 +#define MAXVOXELS 4096 +#define MAXSTATUS 1024 +#define MAXPLAYERS 16 +#define MAXXDIM 1600 +#define MAXYDIM 1200 +#define MAXPALOOKUPS 256 +#define MAXPSKYTILES 256 +#define MAXSPRITESONSCREEN 2048 +#define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites + +#define CLIPMASK0 (((1L)<<16)+1L) +#define CLIPMASK1 (((256L)<<16)+64L) + + //Make all variables in BUILD.H defined in the ENGINE, + //and externed in GAME +#ifdef ENGINE +# define EXTERN +#else +# define EXTERN extern +#endif + +#ifdef __GNUC__ +#define BPACK __attribute__ ((packed)) +#else +#define BPACK +#endif + +#ifdef _MSC_VER +#pragma pack(1) +#endif + +#ifdef __WATCOMC__ +#pragma pack(push,1); +#endif + + +//ceilingstat/floorstat: +// bit 0: 1 = parallaxing, 0 = not "P" +// bit 1: 1 = groudraw, 0 = not +// bit 2: 1 = swap x&y, 0 = not "F" +// bit 3: 1 = double smooshiness "E" +// bit 4: 1 = x-flip "F" +// bit 5: 1 = y-flip "F" +// bit 6: 1 = Align texture to first wall of sector "R" +// bits 7-8: "T" +// 00 = normal floors +// 01 = masked floors +// 10 = transluscent masked floors +// 11 = reverse transluscent masked floors +// bits 9-15: reserved + + //40 bytes +typedef struct BPACK +{ + short wallptr, wallnum; + long ceilingz, floorz; + short ceilingstat, floorstat; + short ceilingpicnum, ceilingheinum; + signed char ceilingshade; + char ceilingpal, ceilingxpanning, ceilingypanning; + short floorpicnum, floorheinum; + signed char floorshade; + char floorpal, floorxpanning, floorypanning; + char visibility, filler; + short lotag, hitag, extra; +} sectortype; + +//cstat: +// bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B" +// bit 1: 1 = bottoms of invisible walls swapped, 0 = not "2" +// bit 2: 1 = align picture on bottom (for doors), 0 = top "O" +// bit 3: 1 = x-flipped, 0 = normal "F" +// bit 4: 1 = masking wall, 0 = not "M" +// bit 5: 1 = 1-way wall, 0 = not "1" +// bit 6: 1 = Blocking wall (use with hitscan / cliptype 1) "H" +// bit 7: 1 = Transluscence, 0 = not "T" +// bit 8: 1 = y-flipped, 0 = normal "F" +// bit 9: 1 = Transluscence reversing, 0 = normal "T" +// bits 10-15: reserved + + //32 bytes +typedef struct BPACK +{ + long x, y; + short point2, nextwall, nextsector, cstat; + short picnum, overpicnum; + signed char shade; + char pal, xrepeat, yrepeat, xpanning, ypanning; + short lotag, hitag, extra; +} walltype; + +//cstat: +// bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B" +// bit 1: 1 = transluscence, 0 = normal "T" +// bit 2: 1 = x-flipped, 0 = normal "F" +// bit 3: 1 = y-flipped, 0 = normal "F" +// bits 5-4: 00 = FACE sprite (default) "R" +// 01 = WALL sprite (like masked walls) +// 10 = FLOOR sprite (parallel to ceilings&floors) +// bit 6: 1 = 1-sided sprite, 0 = normal "1" +// bit 7: 1 = Real centered centering, 0 = foot center "C" +// bit 8: 1 = Blocking sprite (use with hitscan / cliptype 1) "H" +// bit 9: 1 = Transluscence reversing, 0 = normal "T" +// bits 10-14: reserved +// bit 15: 1 = Invisible sprite, 0 = not invisible + + //44 bytes +typedef struct BPACK +{ + long x, y, z; + short cstat, picnum; + signed char shade; + char pal, clipdist, filler; + unsigned char xrepeat, yrepeat; + signed char xoffset, yoffset; + short sectnum, statnum; + short ang, owner, xvel, yvel, zvel; + short lotag, hitag, extra; +} spritetype; + +typedef struct BPACK { + unsigned long mdanimtims; + short mdanimcur; + short angoff; + short pitch, roll; + short xoff, yoff, zoff; + unsigned char flags; + char filler[3]; +} spriteexttype; +#define SPREXT_NOTMD 1 +#define SPREXT_NOMDANIM 2 +EXTERN spriteexttype spriteext[MAXSPRITES+MAXUNIQHUDID]; +EXTERN long guniqhudid; + +EXTERN sectortype sector[MAXSECTORS]; +EXTERN walltype wall[MAXWALLS]; +EXTERN spritetype sprite[MAXSPRITES]; + +EXTERN long spritesortcnt; +EXTERN spritetype tsprite[MAXSPRITESONSCREEN]; + +EXTERN long xdim, ydim, ylookup[MAXYDIM+1], numpages; +EXTERN long yxaspect, viewingrange; + +#define MAXVALIDMODES 256 +EXTERN long validmodecnt; +struct validmode_t { + long xdim,ydim; + char bpp; + char fs; // bit 0 = fullscreen flag + char filler[2]; + long extra; // internal use +}; +EXTERN struct validmode_t validmode[MAXVALIDMODES]; + +EXTERN short numsectors, numwalls; +EXTERN /*volatile*/ long totalclock; +EXTERN long numframes, randomseed; +EXTERN short sintable[2048]; +EXTERN char palette[768]; +EXTERN short numpalookups; +EXTERN char *palookup[MAXPALOOKUPS]; +EXTERN char parallaxtype, showinvisibility; +EXTERN long parallaxyoffs, parallaxyscale; +EXTERN long visibility, parallaxvisibility; + +EXTERN long windowx1, windowy1, windowx2, windowy2; +EXTERN short startumost[MAXXDIM], startdmost[MAXXDIM]; + +EXTERN short pskyoff[MAXPSKYTILES], pskybits; + +EXTERN short headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1]; +EXTERN short prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; +EXTERN short nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES]; + +EXTERN short tilesizx[MAXTILES], tilesizy[MAXTILES]; +EXTERN char walock[MAXTILES]; +EXTERN long numtiles, picanm[MAXTILES], waloff[MAXTILES]; + + //These variables are for auto-mapping with the draw2dscreen function. + //When you load a new board, these bits are all set to 0 - since + //you haven't mapped out anything yet. Note that these arrays are + //bit-mapped. + //If you want draw2dscreen() to show sprite #54 then you say: + // spritenum = 54; + // show2dsprite[spritenum>>3] |= (1<<(spritenum&7)); + //And if you want draw2dscreen() to not show sprite #54 then you say: + // spritenum = 54; + // show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7)); + //Automapping defaults to 0 (do nothing). If you set automapping to 1, + // then in 3D mode, the walls and sprites that you see will show up the + // next time you flip to 2D mode. + +EXTERN char show2dsector[(MAXSECTORS+7)>>3]; +EXTERN char show2dwall[(MAXWALLS+7)>>3]; +EXTERN char show2dsprite[(MAXSPRITES+7)>>3]; +EXTERN char automapping; + +EXTERN char gotpic[(MAXTILES+7)>>3]; +EXTERN char gotsector[(MAXSECTORS+7)>>3]; + +EXTERN char captureformat; +extern char vgapalette[5*256]; +extern unsigned long drawlinepat; + +extern void faketimerhandler(void); + +extern char apptitle[256]; +typedef struct { + unsigned char r,g,b,f; +} palette_t; +extern palette_t curpalette[256], curpalettefaded[256], palfadergb; +extern char palfadedelta; + +extern long dommxoverlay, novoxmips; + +#ifdef SUPERBUILD +extern long tiletovox[MAXTILES]; +extern long usevoxels, voxscale[MAXVOXELS]; +#endif +#ifdef POLYMOST +extern long usemodels, usehightile; +#endif + +extern char *engineerrstr; +extern char noclip; + +/************************************************************************* +POSITION VARIABLES: + + POSX is your x - position ranging from 0 to 65535 + POSY is your y - position ranging from 0 to 65535 + (the length of a side of the grid in EDITBORD would be 1024) + POSZ is your z - position (height) ranging from 0 to 65535, 0 highest. + ANG is your angle ranging from 0 to 2047. Instead of 360 degrees, or + 2 * PI radians, I use 2048 different angles, so 90 degrees would + be 512 in my system. + +SPRITE VARIABLES: + + EXTERN short headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1]; + EXTERN short prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; + EXTERN short nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES]; + + Example: if the linked lists look like the following: + �������������������������������Ŀ + Sector lists: Status lists: + �������������������������������Ĵ + Sector0: 4, 5, 8 Status0: 2, 0, 8 + Sector1: 16, 2, 0, 7 Status1: 4, 5, 16, 7, 3, 9 + Sector2: 3, 9 + �������������������������������� + Notice that each number listed above is shown exactly once on both the + left and right side. This is because any sprite that exists must + be in some sector, and must have some kind of status that you define. + + +Coding example #1: + To go through all the sprites in sector 1, the code can look like this: + + sectnum = 1; + i = headspritesect[sectnum]; + while (i != -1) + { + nexti = nextspritesect[i]; + + //your code goes here + //ex: printf("Sprite %d is in sector %d\n",i,sectnum); + + i = nexti; + } + +Coding example #2: + To go through all sprites with status = 1, the code can look like this: + + statnum = 1; //status 1 + i = headspritestat[statnum]; + while (i != -1) + { + nexti = nextspritestat[i]; + + //your code goes here + //ex: printf("Sprite %d has a status of 1 (active)\n",i,statnum); + + i = nexti; + } + + insertsprite(short sectnum, short statnum); + deletesprite(short spritenum); + changespritesect(short spritenum, short newsectnum); + changespritestat(short spritenum, short newstatnum); + +TILE VARIABLES: + NUMTILES - the number of tiles found TILES.DAT. + TILESIZX[MAXTILES] - simply the x-dimension of the tile number. + TILESIZY[MAXTILES] - simply the y-dimension of the tile number. + WALOFF[MAXTILES] - the actual 32-bit offset pointing to the top-left + corner of the tile. + PICANM[MAXTILES] - flags for animating the tile. + +TIMING VARIABLES: + TOTALCLOCK - When the engine is initialized, TOTALCLOCK is set to zero. + From then on, it is incremented 120 times a second by 1. That + means that the number of seconds elapsed is totalclock / 120. + NUMFRAMES - The number of times the draw3dscreen function was called + since the engine was initialized. This helps to determine frame + rate. (Frame rate = numframes * 120 / totalclock.) + +OTHER VARIABLES: + + STARTUMOST[320] is an array of the highest y-coordinates on each column + that my engine is allowed to write to. You need to set it only + once. + STARTDMOST[320] is an array of the lowest y-coordinates on each column + that my engine is allowed to write to. You need to set it only + once. + SINTABLE[2048] is a sin table with 2048 angles rather than the + normal 360 angles for higher precision. Also since SINTABLE is in + all integers, the range is multiplied by 16383, so instead of the + normal -1=0 for a particular palette +// how: pass -1 to invalidate all instances of the tile in texture memory, or a bitfield +// bit 0: opaque or masked (non-translucent) texture, using repeating +// bit 1: ignored +// bit 2: 33% translucence, using repeating +// bit 3: 67% translucence, using repeating +// bit 4: opaque or masked (non-translucent) texture, using clamping +// bit 5: ignored +// bit 6: 33% translucence, using clamping +// bit 7: 67% translucence, using clamping +// clamping is for sprites, repeating is for walls +void invalidatetile(short tilenume, long pal, long how); + +void setpolymost2dview(void); // sets up GL for 2D drawing + +long polymost_drawtilescreen(long tilex, long tiley, long wallnum, long dimen); +void polymost_glreset(void); +void polymost_precache(long dapicnum, long dapalnum, long datype); + +#if defined(POLYMOST) && defined(USE_OPENGL) +extern long glanisotropy; +extern long glusetexcompr; +extern long gltexfiltermode; +extern long glredbluemode; +extern long glusetexcache, glusetexcachecompression; +extern long glmultisample, glnvmultisamplehint; +void gltexapplyprops (void); +#endif + +void hicinit(void); +// effect bitset: 1 = greyscale, 2 = invert +void hicsetpalettetint(long palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect); +// flags bitset: 1 = don't compress +int hicsetsubsttex(long picnum, long palnum, char *filen, float alphacut, char flags); +int hicsetskybox(long picnum, long palnum, char *faces[6]); +int hicclearsubst(long picnum, long palnum); + +int md_loadmodel(const char *fn); +int md_setmisc(int modelid, float scale, int shadeoff, float zadd); +int md_tilehasmodel(int tilenume); +int md_defineframe(int modelid, const char *framename, int tilenume, int skinnum); +int md_defineanimation(int modelid, const char *framestart, const char *frameend, int fps, int flags); +int md_defineskin(int modelid, const char *skinfn, int palnum, int skinnum, int surfnum); +int md_definehud (int modelid, int tilex, double xadd, double yadd, double zadd, double angadd, int flags); +int md_undefinetile(int tile); +int md_undefinemodel(int modelid); + +int loaddefinitionsfile(char *fn); + +extern long mapversion; // if loadboard() fails with -2 return, try loadoldboard(). if it fails with -2, board is dodgy +long loadoldboard(char *filename, char fromwhere, long *daposx, long *daposy, long *daposz, short *daang, short *dacursectnum); + +#ifdef _MSC_VER +#pragma pack() +#endif + +#ifdef __WATCOMC__ +#pragma pack(pop) +#endif + +#undef BPACK + +#ifdef __cplusplus +} +#endif + +#endif // __build_h__ diff --git a/polymer/build/include/cache1d.h b/polymer/build/include/cache1d.h new file mode 100644 index 000000000..03c2e3f70 --- /dev/null +++ b/polymer/build/include/cache1d.h @@ -0,0 +1,63 @@ +// cache1d.h + +#ifndef __cache1d_h__ +#define __cache1d_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +void initcache(long dacachestart, long dacachesize); +void allocache(long *newhandle, long newbytes, char *newlockptr); +void suckcache(long *suckptr); +void agecache(void); + +extern int pathsearchmode; // 0 = gamefs mode (default), 1 = localfs mode (editor's mode) +int addsearchpath(const char *p); +int findfrompath(const char *fn, char **where); +int openfrompath(const char *fn, int flags, int mode); +BFILE *fopenfrompath(const char *fn, const char *mode); + +long initgroupfile(char *filename); +void uninitsinglegroupfile(long grphandle); +void uninitgroupfile(void); +long kopen4load(char *filename, char searchfirst); // searchfirst: 0 = anywhere, 1 = first group, 2 = any group +long kread(long handle, void *buffer, long leng); +long klseek(long handle, long offset, long whence); +long kfilelength(long handle); +long ktell(long handle); +void kclose(long handle); + +enum { + CACHE1D_FIND_FILE = 1, + CACHE1D_FIND_DIR = 2, + CACHE1D_FIND_DRIVE = 4, + + CACHE1D_OPT_NOSTACK = 0x100, + + // the lower the number, the higher the priority + CACHE1D_SOURCE_DRIVE = 0, + CACHE1D_SOURCE_CURDIR = 1, + CACHE1D_SOURCE_PATH = 2, // + path stack depth + CACHE1D_SOURCE_ZIP = 0x7ffffffe, + CACHE1D_SOURCE_GRP = 0x7fffffff, +}; +typedef struct _CACHE1D_FIND_REC { + char *name; + int type, source; + struct _CACHE1D_FIND_REC *next, *prev, *usera, *userb; +} CACHE1D_FIND_REC; +void klistfree(CACHE1D_FIND_REC *rec); +CACHE1D_FIND_REC *klistpath(const char *path, const char *mask, int type); + +int kdfread(void *buffer, bsize_t dasizeof, bsize_t count, long fil); +int dfread(void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil); +void kdfwrite(void *buffer, bsize_t dasizeof, bsize_t count, long fil); +void dfwrite(void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil); + +#ifdef __cplusplus +} +#endif + +#endif // __cache1d_h__ + diff --git a/polymer/build/include/compat.h b/polymer/build/include/compat.h new file mode 100644 index 000000000..9d9e82d87 --- /dev/null +++ b/polymer/build/include/compat.h @@ -0,0 +1,432 @@ +// Compatibility declarations for things which might not be present in +// certain build environments. It also levels the playing field caused +// by different platforms. + +#ifndef __compat_h__ +#define __compat_h__ + +// Define this to rewrite all 'B' versions to library functions. This +// is for platforms which give us a standard sort of C library so we +// link directly. Platforms like PalmOS which don't have a standard C +// library will need to wrap these functions with suitable emulations. +#define __compat_h_macrodef__ + +#ifdef __cplusplus +# include +#else +# include +#endif + +#ifdef __compat_h_macrodef__ +# ifdef __cplusplus +# include +# include +# include +# include +# else +# include +# include +# include +# include +# endif +# include +# include +# include +# include +# include +# if defined(_WIN32) +# include +# else +# include +# endif +#endif + +#ifdef EFENCE +# include +#endif + +#if defined(__WATCOMC__) +# define inline __inline +# define int64 __int64 +# define uint64 unsigned __int64 +# define longlong(x) x##i64 +#elif defined(_MSC_VER) +# define inline __inline +# define int64 __int64 +# define uint64 unsigned __int64 +# define longlong(x) x##i64 +#else +# define longlong(x) x##ll +typedef long long int64; +typedef unsigned long long uint64; +#endif + +#ifndef NULL +# define NULL ((void *)0) +#endif + +#if defined(__linux) +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif __BYTE_ORDER == __BIG_ENDIAN +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# define B_ENDIAN_C_INLINE 1 + +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif _BYTE_ORDER == _BIG_ENDIAN +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# define B_SWAP64(x) __bswap64(x) +# define B_SWAP32(x) __bswap32(x) +# define B_SWAP16(x) __bswap16(x) + +#elif defined(__APPLE__) +# if defined(__LITTLE_ENDIAN__) +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif defined(__BIG_ENDIAN__) +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# include +# define B_SWAP64(x) OSSwapConstInt64(x) +# define B_SWAP32(x) OSSwapConstInt32(x) +# define B_SWAP16(x) OSSwapConstInt16(x) + +#elif defined(__BEOS__) +# include +# if LITTLE_ENDIAN != 0 +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif BIG_ENDIAN != 0 +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# define B_ENDIAN_C_INLINE 1 + +#elif defined(__QNX__) +# if defined __LITTLEENDIAN__ +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif defined __BIGENDIAN__ +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# define B_ENDIAN_C_INLINE 1 + +#elif defined(__sun) +# if defined _LITTLE_ENDIAN +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# elif defined _BIG_ENDIAN +# define B_LITTLE_ENDIAN 0 +# define B_BIG_ENDIAN 1 +# endif +# define B_ENDIAN_C_INLINE 1 + +#elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__) +# define B_LITTLE_ENDIAN 1 +# define B_BIG_ENDIAN 0 +# define B_ENDIAN_C_INLINE 1 +#endif + +#if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN) +# error Unknown endianness +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined B_ENDIAN_X86_INLINE +# if defined(_MSC_VER) + // inline asm using bswap/xchg +# elif defined(__GNUC__) + // inline asm using bswap/xchg +# elif defined(__WATCOMC__) + // inline asm using bswap/xchg +# endif +#elif defined B_ENDIAN_C_INLINE +static inline unsigned short B_SWAP16(unsigned short s) { return (s>>8)|(s<<8); } +static inline unsigned long B_SWAP32(unsigned long l) { return ((l>>8)&0xff00)|((l&0xff00)<<8)|(l<<24)|(l>>24); } +static inline uint64 B_SWAP64(uint64 l) { return (l>>56)|((l>>40)&0xff00)|((l>>24)&0xff0000)|((l>>8)&0xff000000)|((l&255)<<56)|((l&0xff00)<<40)|((l&0xff0000)<<24)|((l&0xff000000)<<8); } +#endif + +#if B_LITTLE_ENDIAN == 1 +# define B_LITTLE64(x) (x) +# define B_BIG64(x) B_SWAP64(x) +# define B_LITTLE32(x) (x) +# define B_BIG32(x) B_SWAP32(x) +# define B_LITTLE16(x) (x) +# define B_BIG16(x) B_SWAP16(x) +#elif B_BIG_ENDIAN == 1 +# define B_LITTLE64(x) B_SWAP64(x) +# define B_BIG64(x) (x) +# define B_LITTLE32(x) B_SWAP32(x) +# define B_BIG32(x) (x) +# define B_LITTLE16(x) B_SWAP16(x) +# define B_BIG16(x) (x) +#endif + +#ifndef FP_OFF +# define FP_OFF(__p) ((unsigned)(__p)) +#endif + +#ifdef __compat_h_macrodef__ + +# ifndef O_BINARY +# define O_BINARY 0 +# endif +# ifndef O_TEXT +# define O_TEXT 0 +# endif + +# ifndef F_OK +# define F_OK 0 +# endif + +# define BO_BINARY O_BINARY +# define BO_TEXT O_TEXT +# define BO_RDONLY O_RDONLY +# define BO_WRONLY O_WRONLY +# define BO_RDWR O_RDWR +# define BO_APPEND O_APPEND +# define BO_CREAT O_CREAT +# define BO_TRUNC O_TRUNC +# define BS_IRGRP S_IRGRP +# define BS_IWGRP S_IWGRP +# define BS_IEXEC S_IEXEC +# define BS_IWRITE S_IWRITE +# define BS_IREAD S_IREAD +# define BS_IFIFO S_IFIFO +# define BS_IFCHR S_IFCHR +# define BS_IFBLK S_IFBLK +# define BS_IFDIR S_IFDIR +# define BS_IFREG S_IFREG +# define BSEEK_SET SEEK_SET +# define BSEEK_CUR SEEK_CUR +# define BSEEK_END SEEK_END +#else +# define BO_BINARY 0 +# define BO_TEXT 1 +# define BO_RDONLY 2 +# define BO_WRONLY 4 +# define BO_RDWR 6 +# define BO_APPEND 8 +# define BO_CREAT 16 +# define BO_TRUNC 32 +# define BS_IRGRP 0 +# define BS_IWGRP 0 +# define BS_IEXEC 1 +# define BS_IWRITE 2 +# define BS_IREAD 4 +# define BS_IFIFO 0x1000 +# define BS_IFCHR 0x2000 +# define BS_IFBLK 0x3000 +# define BS_IFDIR 0x4000 +# define BS_IFREG 0x8000 +# define BSEEK_SET 0 +# define BSEEK_CUR 1 +# define BSEEK_END 2 +#endif + +#ifdef UNDERSCORES +# define ASMSYM(x) "_" x +#else +# define ASMSYM(x) x +#endif + +#ifndef min +# define min(a,b) ( ((a) < (b)) ? (a) : (b) ) +#endif + +#ifndef max +# define max(a,b) ( ((a) > (b)) ? (a) : (b) ) +#endif + + +#define BMAX_PATH 260 + + +struct Bdirent { + unsigned short namlen; + char *name; + unsigned mode; + unsigned size; + unsigned mtime; +}; +typedef void BDIR; + +BDIR* Bopendir(const char *name); +struct Bdirent* Breaddir(BDIR *dir); +int Bclosedir(BDIR *dir); + + +#ifdef __compat_h_macrodef__ +# define BFILE FILE +# define bsize_t size_t +# define bssize_t ssize_t +#else +typedef void BFILE; +typedef unsigned long bsize_t; +typedef signed long bssize_t; +#endif + + +#ifdef __compat_h_macrodef__ +# define Brand rand +# define Balloca alloca +# define Bmalloc malloc +# define Bcalloc calloc +# define Brealloc realloc +# define Bfree free +# define Bopen open +# define Bclose close +# define Bwrite write +# define Bread read +# define Blseek lseek +# if defined(__GNUC__) +# define Btell(h) lseek(h,0,SEEK_CUR) +# else +# define Btell tell +# endif +# define Bstat stat +# define Bfopen fopen +# define Bfclose fclose +# define Bfeof feof +# define Bfgetc fgetc +# define Brewind rewind +# define Bfgets fgets +# define Bfputc fputc +# define Bfputs fputs +# define Bfread fread +# define Bfwrite fwrite +# define Bfprintf fprintf +# define Bstrdup strdup +# define Bstrcpy strcpy +# define Bstrncpy strncpy +# define Bstrcmp strcmp +# define Bstrncmp strncmp +# if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__QNX__) +# define Bstrcasecmp stricmp +# define Bstrncasecmp strnicmp +# else +# define Bstrcasecmp strcasecmp +# define Bstrncasecmp strncasecmp +# endif +# if defined(_WIN32) +# define Bstrlwr strlwr +# define Bstrupr strupr +# define Bmkdir(s,x) mkdir(s) +# else +# define Bmkdir mkdir +# endif +# define Bstrcat strcat +# define Bstrncat strncat +# define Bstrlen strlen +# define Bstrchr strchr +# define Bstrrchr strrchr +# define Batoi atoi +# define Batol atol +# define Bstrtol strtol +# define Bstrtoul strtoul +# define Bstrtod strtod +# define Btoupper toupper +# define Btolower tolower +# define Bmemcpy memcpy +# define Bmemmove memmove +# define Bmemchr memchr +# define Bmemset memset +# define Bmemcmp memcmp +# define Bprintf printf +# define Bsprintf sprintf +# ifdef _MSC_VER +# define Bsnprintf _snprintf +# define Bvsnprintf _vsnprintf +# else +# define Bsnprintf snprintf +# define Bvsnprintf vsnprintf +# endif +# define Bvfprintf vfprintf +# define Bgetcwd getcwd +# define Bgetenv getenv +# define Btime() time(NULL) + +#else + +int Brand(void); +void *Bmalloc(bsize_t size); +void Bfree(void *ptr); +int Bopen(const char *pathname, int flags, unsigned mode); +int Bclose(int fd); +bssize_t Bwrite(int fd, const void *buf, bsize_t count); +bssize_t Bread(int fd, void *buf, bsize_t count); +int Blseek(int fildes, int offset, int whence); +BFILE *Bfopen(const char *path, const char *mode); +int Bfclose(BFILE *stream); +int Bfeof(BFILE *stream); +int Bfgetc(BFILE *stream); +void Brewind(BFILE *stream); +char *Bfgets(char *s, int size, BFILE *stream); +int Bfputc(int c, BFILE *stream); +int Bfputs(const char *s, BFILE *stream); +bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream); +bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream); +char *Bstrdup(const char *s); +char *Bstrcpy(char *dest, const char *src); +char *Bstrncpy(char *dest, const char *src, bsize_t n); +int Bstrcmp(const char *s1, const char *s2); +int Bstrncmp(const char *s1, const char *s2, bsize_t n); +int Bstrcasecmp(const char *s1, const char *s2); +int Bstrncasecmp(const char *s1, const char *s2, bsize_t n); +char *Bstrcat(char *dest, const char *src); +char *Bstrncat(char *dest, const char *src, bsize_t n); +bsize_t Bstrlen(const char *s); +char *Bstrchr(const char *s, int c); +char *Bstrrchr(const char *s, int c); +int Batoi(const char *nptr); +long Batol(const char *nptr); +long int Bstrtol(const char *nptr, char **endptr, int base); +unsigned long int Bstrtoul(const char *nptr, char **endptr, int base); +void *Bmemcpy(void *dest, const void *src, bsize_t n); +void *Bmemmove(void *dest, const void *src, bsize_t n); +void *Bmemchr(const void *s, int c, bsize_t n); +void *Bmemset(void *s, int c, bsize_t n); +int Bmemcmp(const void *s1, const void *s2, bsize_t n); +int Bprintf(const char *format, ...); +int Bsprintf(char *str, const char *format, ...); +int Bsnprintf(char *str, bsize_t size, const char *format, ...); +int Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap); +char *Bgetcwd(char *buf, bsize_t size); +char *Bgetenv(const char *name); +#endif + +char *Bgethomedir(void); +unsigned int Bgetsysmemsize(void); +int Bcorrectfilename(char *filename, int removefn); +int Bcanonicalisefilename(char *filename, int removefn); +char *Bgetsystemdrives(void); +long Bfilelength(int fd); +char *Bstrtoken(char *s, char *delim, char **ptrptr, int chop); +long Bwildmatch (const char *i, const char *j); + +#if !defined(_WIN32) +char *Bstrlwr(char *); +char *Bstrupr(char *); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __compat_h__ + diff --git a/polymer/build/include/crc32.h b/polymer/build/include/crc32.h new file mode 100644 index 000000000..d05dc5c0f --- /dev/null +++ b/polymer/build/include/crc32.h @@ -0,0 +1,20 @@ +#ifndef __crc32_h__ +#define __crc32_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +void initcrc32table(void); + +unsigned long crc32once(unsigned char *blk, unsigned long len); + +void crc32init(unsigned long *crcvar); +void crc32block(unsigned long *crcvar, unsigned char *blk, unsigned long len); +unsigned long crc32finish(unsigned long *crcvar); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/polymer/build/include/dxdidf.h b/polymer/build/include/dxdidf.h new file mode 100644 index 000000000..b4de78a1d --- /dev/null +++ b/polymer/build/include/dxdidf.h @@ -0,0 +1,332 @@ +#ifndef __dxdidf_h__ +#define __dxdidf_h__ + +// Keyboard + +static DIOBJECTDATAFORMAT c_dfDIKeyboard_odf[] = { + { &GUID_Key, 0, 0x8000000C, 0x00000000 }, + { &GUID_Key, 1, 0x8000010C, 0x00000000 }, + { &GUID_Key, 2, 0x8000020C, 0x00000000 }, + { &GUID_Key, 3, 0x8000030C, 0x00000000 }, + { &GUID_Key, 4, 0x8000040C, 0x00000000 }, + { &GUID_Key, 5, 0x8000050C, 0x00000000 }, + { &GUID_Key, 6, 0x8000060C, 0x00000000 }, + { &GUID_Key, 7, 0x8000070C, 0x00000000 }, + { &GUID_Key, 8, 0x8000080C, 0x00000000 }, + { &GUID_Key, 9, 0x8000090C, 0x00000000 }, + { &GUID_Key, 10, 0x80000A0C, 0x00000000 }, + { &GUID_Key, 11, 0x80000B0C, 0x00000000 }, + { &GUID_Key, 12, 0x80000C0C, 0x00000000 }, + { &GUID_Key, 13, 0x80000D0C, 0x00000000 }, + { &GUID_Key, 14, 0x80000E0C, 0x00000000 }, + { &GUID_Key, 15, 0x80000F0C, 0x00000000 }, + { &GUID_Key, 16, 0x8000100C, 0x00000000 }, + { &GUID_Key, 17, 0x8000110C, 0x00000000 }, + { &GUID_Key, 18, 0x8000120C, 0x00000000 }, + { &GUID_Key, 19, 0x8000130C, 0x00000000 }, + { &GUID_Key, 20, 0x8000140C, 0x00000000 }, + { &GUID_Key, 21, 0x8000150C, 0x00000000 }, + { &GUID_Key, 22, 0x8000160C, 0x00000000 }, + { &GUID_Key, 23, 0x8000170C, 0x00000000 }, + { &GUID_Key, 24, 0x8000180C, 0x00000000 }, + { &GUID_Key, 25, 0x8000190C, 0x00000000 }, + { &GUID_Key, 26, 0x80001A0C, 0x00000000 }, + { &GUID_Key, 27, 0x80001B0C, 0x00000000 }, + { &GUID_Key, 28, 0x80001C0C, 0x00000000 }, + { &GUID_Key, 29, 0x80001D0C, 0x00000000 }, + { &GUID_Key, 30, 0x80001E0C, 0x00000000 }, + { &GUID_Key, 31, 0x80001F0C, 0x00000000 }, + { &GUID_Key, 32, 0x8000200C, 0x00000000 }, + { &GUID_Key, 33, 0x8000210C, 0x00000000 }, + { &GUID_Key, 34, 0x8000220C, 0x00000000 }, + { &GUID_Key, 35, 0x8000230C, 0x00000000 }, + { &GUID_Key, 36, 0x8000240C, 0x00000000 }, + { &GUID_Key, 37, 0x8000250C, 0x00000000 }, + { &GUID_Key, 38, 0x8000260C, 0x00000000 }, + { &GUID_Key, 39, 0x8000270C, 0x00000000 }, + { &GUID_Key, 40, 0x8000280C, 0x00000000 }, + { &GUID_Key, 41, 0x8000290C, 0x00000000 }, + { &GUID_Key, 42, 0x80002A0C, 0x00000000 }, + { &GUID_Key, 43, 0x80002B0C, 0x00000000 }, + { &GUID_Key, 44, 0x80002C0C, 0x00000000 }, + { &GUID_Key, 45, 0x80002D0C, 0x00000000 }, + { &GUID_Key, 46, 0x80002E0C, 0x00000000 }, + { &GUID_Key, 47, 0x80002F0C, 0x00000000 }, + { &GUID_Key, 48, 0x8000300C, 0x00000000 }, + { &GUID_Key, 49, 0x8000310C, 0x00000000 }, + { &GUID_Key, 50, 0x8000320C, 0x00000000 }, + { &GUID_Key, 51, 0x8000330C, 0x00000000 }, + { &GUID_Key, 52, 0x8000340C, 0x00000000 }, + { &GUID_Key, 53, 0x8000350C, 0x00000000 }, + { &GUID_Key, 54, 0x8000360C, 0x00000000 }, + { &GUID_Key, 55, 0x8000370C, 0x00000000 }, + { &GUID_Key, 56, 0x8000380C, 0x00000000 }, + { &GUID_Key, 57, 0x8000390C, 0x00000000 }, + { &GUID_Key, 58, 0x80003A0C, 0x00000000 }, + { &GUID_Key, 59, 0x80003B0C, 0x00000000 }, + { &GUID_Key, 60, 0x80003C0C, 0x00000000 }, + { &GUID_Key, 61, 0x80003D0C, 0x00000000 }, + { &GUID_Key, 62, 0x80003E0C, 0x00000000 }, + { &GUID_Key, 63, 0x80003F0C, 0x00000000 }, + { &GUID_Key, 64, 0x8000400C, 0x00000000 }, + { &GUID_Key, 65, 0x8000410C, 0x00000000 }, + { &GUID_Key, 66, 0x8000420C, 0x00000000 }, + { &GUID_Key, 67, 0x8000430C, 0x00000000 }, + { &GUID_Key, 68, 0x8000440C, 0x00000000 }, + { &GUID_Key, 69, 0x8000450C, 0x00000000 }, + { &GUID_Key, 70, 0x8000460C, 0x00000000 }, + { &GUID_Key, 71, 0x8000470C, 0x00000000 }, + { &GUID_Key, 72, 0x8000480C, 0x00000000 }, + { &GUID_Key, 73, 0x8000490C, 0x00000000 }, + { &GUID_Key, 74, 0x80004A0C, 0x00000000 }, + { &GUID_Key, 75, 0x80004B0C, 0x00000000 }, + { &GUID_Key, 76, 0x80004C0C, 0x00000000 }, + { &GUID_Key, 77, 0x80004D0C, 0x00000000 }, + { &GUID_Key, 78, 0x80004E0C, 0x00000000 }, + { &GUID_Key, 79, 0x80004F0C, 0x00000000 }, + { &GUID_Key, 80, 0x8000500C, 0x00000000 }, + { &GUID_Key, 81, 0x8000510C, 0x00000000 }, + { &GUID_Key, 82, 0x8000520C, 0x00000000 }, + { &GUID_Key, 83, 0x8000530C, 0x00000000 }, + { &GUID_Key, 84, 0x8000540C, 0x00000000 }, + { &GUID_Key, 85, 0x8000550C, 0x00000000 }, + { &GUID_Key, 86, 0x8000560C, 0x00000000 }, + { &GUID_Key, 87, 0x8000570C, 0x00000000 }, + { &GUID_Key, 88, 0x8000580C, 0x00000000 }, + { &GUID_Key, 89, 0x8000590C, 0x00000000 }, + { &GUID_Key, 90, 0x80005A0C, 0x00000000 }, + { &GUID_Key, 91, 0x80005B0C, 0x00000000 }, + { &GUID_Key, 92, 0x80005C0C, 0x00000000 }, + { &GUID_Key, 93, 0x80005D0C, 0x00000000 }, + { &GUID_Key, 94, 0x80005E0C, 0x00000000 }, + { &GUID_Key, 95, 0x80005F0C, 0x00000000 }, + { &GUID_Key, 96, 0x8000600C, 0x00000000 }, + { &GUID_Key, 97, 0x8000610C, 0x00000000 }, + { &GUID_Key, 98, 0x8000620C, 0x00000000 }, + { &GUID_Key, 99, 0x8000630C, 0x00000000 }, + { &GUID_Key, 100, 0x8000640C, 0x00000000 }, + { &GUID_Key, 101, 0x8000650C, 0x00000000 }, + { &GUID_Key, 102, 0x8000660C, 0x00000000 }, + { &GUID_Key, 103, 0x8000670C, 0x00000000 }, + { &GUID_Key, 104, 0x8000680C, 0x00000000 }, + { &GUID_Key, 105, 0x8000690C, 0x00000000 }, + { &GUID_Key, 106, 0x80006A0C, 0x00000000 }, + { &GUID_Key, 107, 0x80006B0C, 0x00000000 }, + { &GUID_Key, 108, 0x80006C0C, 0x00000000 }, + { &GUID_Key, 109, 0x80006D0C, 0x00000000 }, + { &GUID_Key, 110, 0x80006E0C, 0x00000000 }, + { &GUID_Key, 111, 0x80006F0C, 0x00000000 }, + { &GUID_Key, 112, 0x8000700C, 0x00000000 }, + { &GUID_Key, 113, 0x8000710C, 0x00000000 }, + { &GUID_Key, 114, 0x8000720C, 0x00000000 }, + { &GUID_Key, 115, 0x8000730C, 0x00000000 }, + { &GUID_Key, 116, 0x8000740C, 0x00000000 }, + { &GUID_Key, 117, 0x8000750C, 0x00000000 }, + { &GUID_Key, 118, 0x8000760C, 0x00000000 }, + { &GUID_Key, 119, 0x8000770C, 0x00000000 }, + { &GUID_Key, 120, 0x8000780C, 0x00000000 }, + { &GUID_Key, 121, 0x8000790C, 0x00000000 }, + { &GUID_Key, 122, 0x80007A0C, 0x00000000 }, + { &GUID_Key, 123, 0x80007B0C, 0x00000000 }, + { &GUID_Key, 124, 0x80007C0C, 0x00000000 }, + { &GUID_Key, 125, 0x80007D0C, 0x00000000 }, + { &GUID_Key, 126, 0x80007E0C, 0x00000000 }, + { &GUID_Key, 127, 0x80007F0C, 0x00000000 }, + { &GUID_Key, 128, 0x8000800C, 0x00000000 }, + { &GUID_Key, 129, 0x8000810C, 0x00000000 }, + { &GUID_Key, 130, 0x8000820C, 0x00000000 }, + { &GUID_Key, 131, 0x8000830C, 0x00000000 }, + { &GUID_Key, 132, 0x8000840C, 0x00000000 }, + { &GUID_Key, 133, 0x8000850C, 0x00000000 }, + { &GUID_Key, 134, 0x8000860C, 0x00000000 }, + { &GUID_Key, 135, 0x8000870C, 0x00000000 }, + { &GUID_Key, 136, 0x8000880C, 0x00000000 }, + { &GUID_Key, 137, 0x8000890C, 0x00000000 }, + { &GUID_Key, 138, 0x80008A0C, 0x00000000 }, + { &GUID_Key, 139, 0x80008B0C, 0x00000000 }, + { &GUID_Key, 140, 0x80008C0C, 0x00000000 }, + { &GUID_Key, 141, 0x80008D0C, 0x00000000 }, + { &GUID_Key, 142, 0x80008E0C, 0x00000000 }, + { &GUID_Key, 143, 0x80008F0C, 0x00000000 }, + { &GUID_Key, 144, 0x8000900C, 0x00000000 }, + { &GUID_Key, 145, 0x8000910C, 0x00000000 }, + { &GUID_Key, 146, 0x8000920C, 0x00000000 }, + { &GUID_Key, 147, 0x8000930C, 0x00000000 }, + { &GUID_Key, 148, 0x8000940C, 0x00000000 }, + { &GUID_Key, 149, 0x8000950C, 0x00000000 }, + { &GUID_Key, 150, 0x8000960C, 0x00000000 }, + { &GUID_Key, 151, 0x8000970C, 0x00000000 }, + { &GUID_Key, 152, 0x8000980C, 0x00000000 }, + { &GUID_Key, 153, 0x8000990C, 0x00000000 }, + { &GUID_Key, 154, 0x80009A0C, 0x00000000 }, + { &GUID_Key, 155, 0x80009B0C, 0x00000000 }, + { &GUID_Key, 156, 0x80009C0C, 0x00000000 }, + { &GUID_Key, 157, 0x80009D0C, 0x00000000 }, + { &GUID_Key, 158, 0x80009E0C, 0x00000000 }, + { &GUID_Key, 159, 0x80009F0C, 0x00000000 }, + { &GUID_Key, 160, 0x8000A00C, 0x00000000 }, + { &GUID_Key, 161, 0x8000A10C, 0x00000000 }, + { &GUID_Key, 162, 0x8000A20C, 0x00000000 }, + { &GUID_Key, 163, 0x8000A30C, 0x00000000 }, + { &GUID_Key, 164, 0x8000A40C, 0x00000000 }, + { &GUID_Key, 165, 0x8000A50C, 0x00000000 }, + { &GUID_Key, 166, 0x8000A60C, 0x00000000 }, + { &GUID_Key, 167, 0x8000A70C, 0x00000000 }, + { &GUID_Key, 168, 0x8000A80C, 0x00000000 }, + { &GUID_Key, 169, 0x8000A90C, 0x00000000 }, + { &GUID_Key, 170, 0x8000AA0C, 0x00000000 }, + { &GUID_Key, 171, 0x8000AB0C, 0x00000000 }, + { &GUID_Key, 172, 0x8000AC0C, 0x00000000 }, + { &GUID_Key, 173, 0x8000AD0C, 0x00000000 }, + { &GUID_Key, 174, 0x8000AE0C, 0x00000000 }, + { &GUID_Key, 175, 0x8000AF0C, 0x00000000 }, + { &GUID_Key, 176, 0x8000B00C, 0x00000000 }, + { &GUID_Key, 177, 0x8000B10C, 0x00000000 }, + { &GUID_Key, 178, 0x8000B20C, 0x00000000 }, + { &GUID_Key, 179, 0x8000B30C, 0x00000000 }, + { &GUID_Key, 180, 0x8000B40C, 0x00000000 }, + { &GUID_Key, 181, 0x8000B50C, 0x00000000 }, + { &GUID_Key, 182, 0x8000B60C, 0x00000000 }, + { &GUID_Key, 183, 0x8000B70C, 0x00000000 }, + { &GUID_Key, 184, 0x8000B80C, 0x00000000 }, + { &GUID_Key, 185, 0x8000B90C, 0x00000000 }, + { &GUID_Key, 186, 0x8000BA0C, 0x00000000 }, + { &GUID_Key, 187, 0x8000BB0C, 0x00000000 }, + { &GUID_Key, 188, 0x8000BC0C, 0x00000000 }, + { &GUID_Key, 189, 0x8000BD0C, 0x00000000 }, + { &GUID_Key, 190, 0x8000BE0C, 0x00000000 }, + { &GUID_Key, 191, 0x8000BF0C, 0x00000000 }, + { &GUID_Key, 192, 0x8000C00C, 0x00000000 }, + { &GUID_Key, 193, 0x8000C10C, 0x00000000 }, + { &GUID_Key, 194, 0x8000C20C, 0x00000000 }, + { &GUID_Key, 195, 0x8000C30C, 0x00000000 }, + { &GUID_Key, 196, 0x8000C40C, 0x00000000 }, + { &GUID_Key, 197, 0x8000C50C, 0x00000000 }, + { &GUID_Key, 198, 0x8000C60C, 0x00000000 }, + { &GUID_Key, 199, 0x8000C70C, 0x00000000 }, + { &GUID_Key, 200, 0x8000C80C, 0x00000000 }, + { &GUID_Key, 201, 0x8000C90C, 0x00000000 }, + { &GUID_Key, 202, 0x8000CA0C, 0x00000000 }, + { &GUID_Key, 203, 0x8000CB0C, 0x00000000 }, + { &GUID_Key, 204, 0x8000CC0C, 0x00000000 }, + { &GUID_Key, 205, 0x8000CD0C, 0x00000000 }, + { &GUID_Key, 206, 0x8000CE0C, 0x00000000 }, + { &GUID_Key, 207, 0x8000CF0C, 0x00000000 }, + { &GUID_Key, 208, 0x8000D00C, 0x00000000 }, + { &GUID_Key, 209, 0x8000D10C, 0x00000000 }, + { &GUID_Key, 210, 0x8000D20C, 0x00000000 }, + { &GUID_Key, 211, 0x8000D30C, 0x00000000 }, + { &GUID_Key, 212, 0x8000D40C, 0x00000000 }, + { &GUID_Key, 213, 0x8000D50C, 0x00000000 }, + { &GUID_Key, 214, 0x8000D60C, 0x00000000 }, + { &GUID_Key, 215, 0x8000D70C, 0x00000000 }, + { &GUID_Key, 216, 0x8000D80C, 0x00000000 }, + { &GUID_Key, 217, 0x8000D90C, 0x00000000 }, + { &GUID_Key, 218, 0x8000DA0C, 0x00000000 }, + { &GUID_Key, 219, 0x8000DB0C, 0x00000000 }, + { &GUID_Key, 220, 0x8000DC0C, 0x00000000 }, + { &GUID_Key, 221, 0x8000DD0C, 0x00000000 }, + { &GUID_Key, 222, 0x8000DE0C, 0x00000000 }, + { &GUID_Key, 223, 0x8000DF0C, 0x00000000 }, + { &GUID_Key, 224, 0x8000E00C, 0x00000000 }, + { &GUID_Key, 225, 0x8000E10C, 0x00000000 }, + { &GUID_Key, 226, 0x8000E20C, 0x00000000 }, + { &GUID_Key, 227, 0x8000E30C, 0x00000000 }, + { &GUID_Key, 228, 0x8000E40C, 0x00000000 }, + { &GUID_Key, 229, 0x8000E50C, 0x00000000 }, + { &GUID_Key, 230, 0x8000E60C, 0x00000000 }, + { &GUID_Key, 231, 0x8000E70C, 0x00000000 }, + { &GUID_Key, 232, 0x8000E80C, 0x00000000 }, + { &GUID_Key, 233, 0x8000E90C, 0x00000000 }, + { &GUID_Key, 234, 0x8000EA0C, 0x00000000 }, + { &GUID_Key, 235, 0x8000EB0C, 0x00000000 }, + { &GUID_Key, 236, 0x8000EC0C, 0x00000000 }, + { &GUID_Key, 237, 0x8000ED0C, 0x00000000 }, + { &GUID_Key, 238, 0x8000EE0C, 0x00000000 }, + { &GUID_Key, 239, 0x8000EF0C, 0x00000000 }, + { &GUID_Key, 240, 0x8000F00C, 0x00000000 }, + { &GUID_Key, 241, 0x8000F10C, 0x00000000 }, + { &GUID_Key, 242, 0x8000F20C, 0x00000000 }, + { &GUID_Key, 243, 0x8000F30C, 0x00000000 }, + { &GUID_Key, 244, 0x8000F40C, 0x00000000 }, + { &GUID_Key, 245, 0x8000F50C, 0x00000000 }, + { &GUID_Key, 246, 0x8000F60C, 0x00000000 }, + { &GUID_Key, 247, 0x8000F70C, 0x00000000 }, + { &GUID_Key, 248, 0x8000F80C, 0x00000000 }, + { &GUID_Key, 249, 0x8000F90C, 0x00000000 }, + { &GUID_Key, 250, 0x8000FA0C, 0x00000000 }, + { &GUID_Key, 251, 0x8000FB0C, 0x00000000 }, + { &GUID_Key, 252, 0x8000FC0C, 0x00000000 }, + { &GUID_Key, 253, 0x8000FD0C, 0x00000000 }, + { &GUID_Key, 254, 0x8000FE0C, 0x00000000 }, + { &GUID_Key, 255, 0x8000FF0C, 0x00000000 } +}; + +const DIDATAFORMAT c_dfDIKeyboard = { 24, 16, 0x00000002, 256, 256, c_dfDIKeyboard_odf }; + +// Mouse + +static DIOBJECTDATAFORMAT c_dfDIMouse_odf[] = { + { &GUID_XAxis, 0, 0x00FFFF03, 0x00000000 }, + { &GUID_YAxis, 4, 0x00FFFF03, 0x00000000 }, + { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000000 }, + { NULL, 12, 0x00FFFF0C, 0x00000000 }, + { NULL, 13, 0x00FFFF0C, 0x00000000 }, + { NULL, 14, 0x80FFFF0C, 0x00000000 }, + { NULL, 15, 0x80FFFF0C, 0x00000000 } +}; + +const DIDATAFORMAT c_dfDIMouse = { 24, 16, 0x00000002, 16, 7, c_dfDIMouse_odf }; + +// Joystick + +static DIOBJECTDATAFORMAT c_dfDIJoystick_odf[] = { + { &GUID_XAxis, 0, 0x80FFFF03, 0x00000100 }, + { &GUID_YAxis, 4, 0x80FFFF03, 0x00000100 }, + { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000100 }, + { &GUID_RxAxis, 12, 0x80FFFF03, 0x00000100 }, + { &GUID_RyAxis, 16, 0x80FFFF03, 0x00000100 }, + { &GUID_RzAxis, 20, 0x80FFFF03, 0x00000100 }, + { &GUID_Slider, 24, 0x80FFFF03, 0x00000100 }, + { &GUID_Slider, 28, 0x80FFFF03, 0x00000100 }, + { &GUID_POV, 32, 0x80FFFF10, 0x00000000 }, + { &GUID_POV, 36, 0x80FFFF10, 0x00000000 }, + { &GUID_POV, 40, 0x80FFFF10, 0x00000000 }, + { &GUID_POV, 44, 0x80FFFF10, 0x00000000 }, + { NULL, 48, 0x80FFFF0C, 0x00000000 }, + { NULL, 49, 0x80FFFF0C, 0x00000000 }, + { NULL, 50, 0x80FFFF0C, 0x00000000 }, + { NULL, 51, 0x80FFFF0C, 0x00000000 }, + { NULL, 52, 0x80FFFF0C, 0x00000000 }, + { NULL, 53, 0x80FFFF0C, 0x00000000 }, + { NULL, 54, 0x80FFFF0C, 0x00000000 }, + { NULL, 55, 0x80FFFF0C, 0x00000000 }, + { NULL, 56, 0x80FFFF0C, 0x00000000 }, + { NULL, 57, 0x80FFFF0C, 0x00000000 }, + { NULL, 58, 0x80FFFF0C, 0x00000000 }, + { NULL, 59, 0x80FFFF0C, 0x00000000 }, + { NULL, 60, 0x80FFFF0C, 0x00000000 }, + { NULL, 61, 0x80FFFF0C, 0x00000000 }, + { NULL, 62, 0x80FFFF0C, 0x00000000 }, + { NULL, 63, 0x80FFFF0C, 0x00000000 }, + { NULL, 64, 0x80FFFF0C, 0x00000000 }, + { NULL, 65, 0x80FFFF0C, 0x00000000 }, + { NULL, 66, 0x80FFFF0C, 0x00000000 }, + { NULL, 67, 0x80FFFF0C, 0x00000000 }, + { NULL, 68, 0x80FFFF0C, 0x00000000 }, + { NULL, 69, 0x80FFFF0C, 0x00000000 }, + { NULL, 70, 0x80FFFF0C, 0x00000000 }, + { NULL, 71, 0x80FFFF0C, 0x00000000 }, + { NULL, 72, 0x80FFFF0C, 0x00000000 }, + { NULL, 73, 0x80FFFF0C, 0x00000000 }, + { NULL, 74, 0x80FFFF0C, 0x00000000 }, + { NULL, 75, 0x80FFFF0C, 0x00000000 }, + { NULL, 76, 0x80FFFF0C, 0x00000000 }, + { NULL, 77, 0x80FFFF0C, 0x00000000 }, + { NULL, 78, 0x80FFFF0C, 0x00000000 }, + { NULL, 79, 0x80FFFF0C, 0x00000000 } +}; + +const DIDATAFORMAT c_dfDIJoystick = { 24, 16, 0x00000001, 80, 44, c_dfDIJoystick_odf }; + +#endif // __dxdidf_h__ diff --git a/polymer/build/include/editor.h b/polymer/build/include/editor.h new file mode 100644 index 000000000..130dfa3a2 --- /dev/null +++ b/polymer/build/include/editor.h @@ -0,0 +1,68 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. + +#ifndef __editor_h__ +#define __editor_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUMBUILDKEYS 20 + +extern long qsetmode; +extern short searchsector, searchwall, searchstat; +extern long zmode, kensplayerheight; +extern short defaultspritecstat; + +extern short temppicnum, tempcstat, templotag, temphitag, tempextra; +extern char tempshade, temppal, tempxrepeat, tempyrepeat; +extern char somethingintab; + +extern char buildkeys[NUMBUILDKEYS]; + +extern long ydim16, xdimgame, ydimgame, bppgame, xdim2d, ydim2d; + + +extern int ExtInit(void); +extern void ExtUnInit(void); +extern void ExtPreCheckKeys(void); +#ifdef SUPERBUILD +extern void ExtAnalyzeSprites(void); +#endif +extern void ExtCheckKeys(void); +extern void ExtPreLoadMap(void); +extern void ExtLoadMap(const char *mapname); +extern void ExtPreSaveMap(void); +extern void ExtSaveMap(const char *mapname); +extern const char *ExtGetSectorCaption(short sectnum); +extern const char *ExtGetWallCaption(short wallnum); +extern const char *ExtGetSpriteCaption(short spritenum); +extern void ExtShowSectorData(short sectnum); +extern void ExtShowWallData(short wallnum); +extern void ExtShowSpriteData(short spritenum); +extern void ExtEditSectorData(short sectnum); +extern void ExtEditWallData(short wallnum); +extern void ExtEditSpriteData(short spritenum); + + +int loadsetup(const char *fn); // from config.c +int writesetup(const char *fn); // from config.c + +void editinput(void); +void clearmidstatbar16(void); + +long getnumber256(char namestart[80], long num, long maxnumber, char sign); +long getnumber16(char namestart[80], long num, long maxnumber, char sign); +void printmessage256(char name[82]); +void printmessage16(char name[82]); + +void getpoint(long searchxe, long searchye, long *x, long *y); +long getpointhighlight(long xplc, long yplc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/polymer/build/include/engineinfo.h b/polymer/build/include/engineinfo.h new file mode 100644 index 000000000..75adc1b4f --- /dev/null +++ b/polymer/build/include/engineinfo.h @@ -0,0 +1,6 @@ +extern const char _engine_cflags[]; +extern const char _engine_libs[]; +extern const char _engine_uname[]; +extern const char _engine_compiler[]; +extern const char _engine_date[]; + diff --git a/polymer/build/include/game.h b/polymer/build/include/game.h new file mode 100644 index 000000000..e121c4ff0 --- /dev/null +++ b/polymer/build/include/game.h @@ -0,0 +1,56 @@ +// game.h + +void operatesector(short dasector); +void operatesprite(short dasprite); +long changehealth(short snum, short deltahealth); +void changenumbombs(short snum, short deltanumbombs); +void changenummissiles(short snum, short deltanummissiles); +void changenumgrabbers(short snum, short deltanumgrabbers); +void drawstatusflytime(short snum); +void drawstatusbar(short snum); +void prepareboard(char *daboardfilename); +void checktouchsprite(short snum, short sectnum); +void checkgrabbertouchsprite(short snum, short sectnum); +void shootgun(short snum, long x, long y, long z, short daang, long dahoriz, short dasectnum, char guntype); +void analyzesprites(long dax, long day); +void tagcode(void); +void statuslistcode(void); +void activatehitag(short dahitag); +void bombexplode(long i); +void processinput(short snum); +void view(short snum, long *vx, long *vy, long *vz, short *vsectnum, short ang, long horiz); +void updatesectorz(long x, long y, long z, short *sectnum); +void drawscreen(short snum, long dasmoothratio); +void movethings(void); +void fakedomovethings(void); +void fakedomovethingscorrect(void); +void domovethings(void); +void getinput(void); +void initplayersprite(short snum); +void playback(void); +void setup3dscreen(void); +void findrandomspot(long *x, long *y, short *sectnum); +void warp(long *x, long *y, long *z, short *daang, short *dasector); +void warpsprite(short spritenum); +void initlava(void); +void movelava(char *dapic); +void doanimations(void); +long getanimationgoal(long animptr); +long setanimation(long *animptr, long thegoal, long thevel, long theacc); +void checkmasterslaveswitch(void); +long testneighborsectors(short sect1, short sect2); +long loadgame(void); +long savegame(void); +void faketimerhandler(void); +void getpackets(void); +void drawoverheadmap(long cposx, long cposy, long czoom, short cang); +long movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, long clipmask); +void waitforeverybody(void); +void searchmap(short startsector); +void setinterpolation(long *posptr); +void stopinterpolation(long *posptr); +void updateinterpolations(void); +void dointerpolations(void); +void restoreinterpolations(void); +void printext(long x, long y, char *buffer, short tilenum, char invisiblecol); +void drawtilebackground (long thex, long they, short tilenum, signed char shade, long cx1, long cy1, long cx2, long cy2, char dapalnum); diff --git a/polymer/build/include/glbuild.h b/polymer/build/include/glbuild.h new file mode 100644 index 000000000..0b066a14a --- /dev/null +++ b/polymer/build/include/glbuild.h @@ -0,0 +1,211 @@ +#ifdef USE_OPENGL + +#ifdef RENDERTYPEWIN +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#if defined(__APPLE__) +# include +#else +# include +#endif + +// get this header from http://oss.sgi.com/projects/ogl-sample/registry/ +// if you are missing it +//#include +#if defined(__APPLE__) +# include +#else +# include "glext.h" +#endif + +#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT +#error You should get an updated copy of glext.h from http://oss.sgi.com/projects/ogl-sample/registry/ +#endif + +#ifdef DYNAMIC_OPENGL + +#ifndef APIENTRY +# define APIENTRY +#endif + +extern void (APIENTRY * bglClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +extern void (APIENTRY * bglClear)( GLbitfield mask ); +extern void (APIENTRY * bglColorMask)( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); +extern void (APIENTRY * bglAlphaFunc)( GLenum func, GLclampf ref ); +extern void (APIENTRY * bglBlendFunc)( GLenum sfactor, GLenum dfactor ); +extern void (APIENTRY * bglCullFace)( GLenum mode ); +extern void (APIENTRY * bglFrontFace)( GLenum mode ); +extern void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); +extern void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); +extern void (APIENTRY * bglEnable)( GLenum cap ); +extern void (APIENTRY * bglDisable)( GLenum cap ); +extern void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); +extern void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); +extern void (APIENTRY * bglPushAttrib)( GLbitfield mask ); +extern void (APIENTRY * bglPopAttrib)( void ); +extern GLenum (APIENTRY * bglGetError)( void ); +extern const GLubyte* (APIENTRY * bglGetString)( GLenum name ); +extern void (APIENTRY * bglHint)( GLenum target, GLenum mode ); + +// Depth +extern void (APIENTRY * bglDepthFunc)( GLenum func ); +extern void (APIENTRY * bglDepthMask)( GLboolean flag ); +extern void (APIENTRY * bglDepthRange)( GLclampd near_val, GLclampd far_val ); + +// Matrix +extern void (APIENTRY * bglMatrixMode)( GLenum mode ); +extern void (APIENTRY * bglOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +extern void (APIENTRY * bglFrustum)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +extern void (APIENTRY * bglViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); +extern void (APIENTRY * bglPushMatrix)( void ); +extern void (APIENTRY * bglPopMatrix)( void ); +extern void (APIENTRY * bglLoadIdentity)( void ); +extern void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); + +// Drawing +extern void (APIENTRY * bglBegin)( GLenum mode ); +extern void (APIENTRY * bglEnd)( void ); +extern void (APIENTRY * bglVertex2f)( GLfloat x, GLfloat y ); +extern void (APIENTRY * bglVertex2i)( GLint x, GLint y ); +extern void (APIENTRY * bglVertex3d)( GLdouble x, GLdouble y, GLdouble z ); +extern void (APIENTRY * bglVertex3fv)( const GLfloat *v ); +extern void (APIENTRY * bglColor4f)( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); +extern void (APIENTRY * bglColor4ub)( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); +extern void (APIENTRY * bglTexCoord2d)( GLdouble s, GLdouble t ); +extern void (APIENTRY * bglTexCoord2f)( GLfloat s, GLfloat t ); + +// Lighting +extern void (APIENTRY * bglShadeModel)( GLenum mode ); + +// Raster funcs +extern void (APIENTRY * bglReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); + +// Texture mapping +extern void (APIENTRY * bglTexEnvf)( GLenum target, GLenum pname, GLfloat param ); +extern void (APIENTRY * bglGenTextures)( GLsizei n, GLuint *textures ); // 1.1 +extern void (APIENTRY * bglDeleteTextures)( GLsizei n, const GLuint *textures); // 1.1 +extern void (APIENTRY * bglBindTexture)( GLenum target, GLuint texture ); // 1.1 +extern void (APIENTRY * bglTexImage2D)( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); +extern void (APIENTRY * bglTexSubImage2D)( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); // 1.1 +extern void (APIENTRY * bglTexParameterf)( GLenum target, GLenum pname, GLfloat param ); +extern void (APIENTRY * bglTexParameteri)( GLenum target, GLenum pname, GLint param ); +extern void (APIENTRY * bglGetTexLevelParameteriv)( GLenum target, GLint level, GLenum pname, GLint *params ); +extern void (APIENTRY * bglCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void (APIENTRY * bglGetCompressedTexImageARB)(GLenum, GLint, GLvoid *); + +// Fog +extern void (APIENTRY * bglFogf)( GLenum pname, GLfloat param ); +extern void (APIENTRY * bglFogi)( GLenum pname, GLint param ); +extern void (APIENTRY * bglFogfv)( GLenum pname, const GLfloat *params ); + +#ifdef RENDERTYPEWIN +// Windows +extern HGLRC (WINAPI * bwglCreateContext)(HDC); +extern BOOL (WINAPI * bwglDeleteContext)(HGLRC); +extern PROC (WINAPI * bwglGetProcAddress)(LPCSTR); +extern BOOL (WINAPI * bwglMakeCurrent)(HDC,HGLRC); + +extern BOOL (WINAPI * bwglSwapBuffers)(HDC); +extern int (WINAPI * bwglChoosePixelFormat)(HDC,CONST PIXELFORMATDESCRIPTOR*); +extern int (WINAPI * bwglDescribePixelFormat)(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); +extern int (WINAPI * bwglGetPixelFormat)(HDC); +extern BOOL (WINAPI * bwglSetPixelFormat)(HDC,int,const PIXELFORMATDESCRIPTOR*); +#endif + +#else // DYNAMIC_OPENGL + +#define bglClearColor glClearColor +#define bglClear glClear +#define bglColorMask glColorMask +#define bglAlphaFunc glAlphaFunc +#define bglBlendFunc glBlendFunc +#define bglCullFace glCullFace +#define bglFrontFace glFrontFace +#define bglPolygonOffset glPolygonOffset +#define bglPolygonMode glPolygonMode +#define bglEnable glEnable +#define bglDisable glDisable +#define bglGetFloatv glGetFloatv +#define bglGetIntegerv glGetIntegerv +#define bglPushAttrib glPushAttrib +#define bglPopAttrib glPopAttrib +#define bglGetError glGetError +#define bglGetString glGetString +#define bglHint glHint + +// Depth +#define bglDepthFunc glDepthFunc +#define bglDepthMask glDepthMask +#define bglDepthRange glDepthRange + +// Matrix +#define bglMatrixMode glMatrixMode +#define bglOrtho glOrtho +#define bglFrustum glFrustum +#define bglViewport glViewport +#define bglPushMatrix glPushMatrix +#define bglPopMatrix glPopMatrix +#define bglLoadIdentity glLoadIdentity +#define bglLoadMatrixf glLoadMatrixf + +// Drawing +#define bglBegin glBegin +#define bglEnd glEnd +#define bglVertex2f glVertex2f +#define bglVertex2i glVertex2i +#define bglVertex3d glVertex3d +#define bglVertex3fv glVertex3fv +#define bglColor4f glColor4f +#define bglColor4ub glColor4ub +#define bglTexCoord2d glTexCoord2d +#define bglTexCoord2f glTexCoord2f + +// Lighting +#define bglShadeModel glShadeModel + +// Raster funcs +#define bglReadPixels glReadPixels + +// Texture mapping +#define bglTexEnvf glTexEnvf +#define bglGenTextures glGenTextures +#define bglDeleteTextures glDeleteTextures +#define bglBindTexture glBindTexture +#define bglTexImage2D glTexImage2D +#define bglTexSubImage2D glTexSubImage2D +#define bglTexParameterf glTexParameterf +#define bglTexParameteri glTexParameteri +#define bglGetTexLevelParameteriv glGetTexLevelParameteriv +#define bglCompressedTexImage2DARB glCompressedTexImage2DARB +#define bglGetCompressedTexImageARB glGetCompressedTexImageARB + +// Fog +#define bglFogf glFogf +#define bglFogi glFogi +#define bglFogfv glFogfv + +#ifdef RENDERTYPEWIN +#define bwglCreateContext wglCreateContext +#define bwglDeleteContext wglDeleteContext +#define bwglGetProcAddress wglGetProcAddress +#define bwglMakeCurrent wglMakeCurrent + +#define bwglSwapBuffers SwapBuffers +#define bwglChoosePixelFormat ChoosePixelFormat +#define bwglDescribePixelFormat DescribePixelFormat +#define bwglGetPixelFormat GetPixelFormat +#define bwglSetPixelFormat SetPixelFormat +#endif + +#endif + +#endif //USE_OPENGL + +extern char *gldriver; + +int loadgldriver(const char *driver); +int loadglextensions(void); +int unloadgldriver(void); + diff --git a/polymer/build/include/glext.h b/polymer/build/include/glext.h new file mode 100644 index 000000000..f8b6cbc61 --- /dev/null +++ b/polymer/build/include/glext.h @@ -0,0 +1,5545 @@ +#ifndef __glext_h_ +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glext.h last updated 2003/5/9 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define GL_GLEXT_VERSION 18 + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_env_add +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_window_pos +#endif + +#ifndef GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_compression_vtc +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_NV_vertex_program1_1 +#endif + +#ifndef GL_EXT_shadow_funcs +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_NV_vertex_program2 +#endif + +#ifndef GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#endif + + +/*************************************************************/ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +GLAPI void APIENTRY glBlendEquation (GLenum); +GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogram (GLenum); +GLAPI void APIENTRY glResetMinmax (GLenum); +GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum); +GLAPI void APIENTRY glClientActiveTexture (GLenum); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glFogCoordf (GLfloat); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *); +GLAPI void APIENTRY glFogCoordd (GLdouble); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); +GLAPI void APIENTRY glPointParameteri (GLenum, GLint); +GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); +GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos2i (GLint, GLint); +GLAPI void APIENTRY glWindowPos2iv (const GLint *); +GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *); +GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3iv (const GLint *); +GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); +GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); +GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); +GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); +GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); +GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexBlendARB (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#endif + +#ifndef GL_ARB_texture_mirror_repeat +#define GL_ARB_texture_mirror_repeat 1 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (APIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +/* GL types for handling large vertex buffer objects */ +/* Only used by this extension for now; later needs to be moved earlier in glext.h */ +#include +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); +GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); +GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); +typedef void (APIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); +typedef void (APIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); +typedef GLvoid* (APIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogramEXT (GLenum); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint); +GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRY * PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRY * PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRY * PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRY * PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +GLAPI void APIENTRY glDeformSGIX (GLbitfield); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRY * PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum); +GLAPI void APIENTRY glTextureLightEXT (GLenum); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); +GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); +GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); +GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *); +GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); +GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); +GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); +GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRY * PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRY * PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRY * PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRY * PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRY * PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRY * PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRY * PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRY * PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRY * PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRY * PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (GLenum, const GLint *, const GLsizei *, GLsizei, GLint); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); +GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFinishFenceNV (GLuint); +GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); +GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (APIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (APIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); +GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); +typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); +typedef void (APIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); +GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); +typedef GLboolean (APIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); +typedef void (APIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); +GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); +GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); +GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); +GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); +GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); +GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); +GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); +typedef void (APIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); +typedef void (APIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); +GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); +GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#endif + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef GLboolean (APIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +/* GL type for representing NVIDIA "half" floating point type in host memory */ +/* Only used by this extension for now; later needs to be moved earlier in glext.h */ +typedef unsigned short GLhalfNV; +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (APIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#endif + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLvoid* (APIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/polymer/build/include/gtkbits.h b/polymer/build/include/gtkbits.h new file mode 100644 index 000000000..08581b9c3 --- /dev/null +++ b/polymer/build/include/gtkbits.h @@ -0,0 +1,15 @@ +#ifndef __gtkbits_h__ +#define __gtkbits_h__ + +extern void gtkbuild_init(int *argc, char ***argv); +extern void gtkbuild_exit(int r); +extern int gtkbuild_msgbox(char *name, char *msg); +extern int gtkbuild_ynbox(char *name, char *msg); +extern void gtkbuild_create_startwin(void); +extern void gtkbuild_settitle_startwin(const char *title); +extern void gtkbuild_puts_startwin(const char *str); +extern void gtkbuild_close_startwin(void); +extern void gtkbuild_update_startwin(void); +extern void *gtkbuild_get_app_icon(void); + +#endif diff --git a/polymer/build/include/kplib.h b/polymer/build/include/kplib.h new file mode 100644 index 000000000..20aaa6b6e --- /dev/null +++ b/polymer/build/include/kplib.h @@ -0,0 +1,21 @@ + //High-level (easy) picture loading function: +extern void kpzload (const char *, long *, long *, long *, long *); + //Low-level PNG/JPG functions: +extern void kpgetdim (const char *, long, long *, long *); +extern long kprender (const char *, long, long, long, long, long, long, long); + + //ZIP functions: +extern long kzaddstack (const char *); +extern void kzuninit (); +extern long kzopen (const char *); +extern long kzread (void *, long); +extern long kzfilelength (); +extern long kzseek (long, long); +extern long kztell (); +extern long kzgetc (); +extern long kzeof (); +extern void kzclose (); + +extern void kzfindfilestart (const char *); //pass wildcard string +extern long kzfindfile (char *); //you alloc buf, returns 1:found,0:~found + diff --git a/polymer/build/include/lzf.h b/polymer/build/include/lzf.h new file mode 100644 index 000000000..8538609ab --- /dev/null +++ b/polymer/build/include/lzf.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000-2005 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License version 2 (the "GPL"), in which case the + * provisions of the GPL are applicable instead of the above. If you wish to + * allow the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under the + * BSD license, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. If + * you do not delete the provisions above, a recipient may use your version + * of this file under either the BSD or the GPL. + */ + +#ifndef LZF_H +#define LZF_H + +/*********************************************************************** +** +** lzf -- an extremely fast/free compression/decompression-method +** http://liblzf.plan9.de/ +** +** This algorithm is believed to be patent-free. +** +***********************************************************************/ + +#define LZF_VERSION 0x0105 /* 1.5 */ + +/* + * Compress in_len bytes stored at the memory block starting at + * in_data and write the result to out_data, up to a maximum length + * of out_len bytes. + * + * If the output buffer is not large enough or any error occurs + * return 0, otherwise return the number of bytes used (which might + * be considerably larger than in_len, so it makes sense to always + * use out_len == in_len - 1), to ensure _some_ compression, and store + * the data uncompressed otherwise. + * + * lzf_compress might use different algorithms on different systems and + * even diferent runs, thus might result in different compressed strings + * depending on the phase of the moon or similar factors. However, all + * these strings are architecture-independent and will result in the + * original data when decompressed using lzf_decompress. + * + * The buffers must not be overlapping. + * + * If the option LZF_STATE_ARG is enabled, an extra argument must be + * supplied which is not reflected in this header file. Refer to lzfP.h + * and lzf_c.c. + * + */ +unsigned int +lzf_compress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len); + +/* + * Decompress data compressed with some version of the lzf_compress + * function and stored at location in_data and length in_len. The result + * will be stored at out_data up to a maximum of out_len characters. + * + * If the output buffer is not large enough to hold the decompressed + * data, a 0 is returned and errno is set to E2BIG. Otherwise the number + * of decompressed bytes (i.e. the original length of the data) is + * returned. + * + * If an error in the compressed data is detected, a zero is returned and + * errno is set to EINVAL. + * + * This function is very fast, about as fast as a copying loop. + */ +unsigned int +lzf_decompress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len); + +#endif + diff --git a/polymer/build/include/lzwnew.h b/polymer/build/include/lzwnew.h new file mode 100644 index 000000000..6606bb3a5 --- /dev/null +++ b/polymer/build/include/lzwnew.h @@ -0,0 +1,2 @@ +long lzwcompress (unsigned char *ucompbuf, long ucompleng, unsigned char *compbuf); +long lzwuncompress (unsigned char *compbuf, long compleng, unsigned char *ucompbuf, long ucompleng); diff --git a/polymer/build/include/md4.h b/polymer/build/include/md4.h new file mode 100644 index 000000000..27c2e3611 --- /dev/null +++ b/polymer/build/include/md4.h @@ -0,0 +1,38 @@ +/* MD4.H - header file for MD4C.C + Modified from original version published in RFC1320 by + Jonathon Fowler (jonof@edgenetwork.org) + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD4 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD4 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +/* MD4 context. */ +typedef struct { + unsigned long state[4]; /* state (ABCD) */ + unsigned long count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD4_CTX; + +void md4once(unsigned char *block, unsigned int len, unsigned char digest[16]); +void md4init(MD4_CTX *); +void md4block(MD4_CTX *, unsigned char *, unsigned int); +void md4finish(unsigned char [16], MD4_CTX *); diff --git a/polymer/build/include/mmulti.h b/polymer/build/include/mmulti.h new file mode 100644 index 000000000..1d3cb5bfe --- /dev/null +++ b/polymer/build/include/mmulti.h @@ -0,0 +1,29 @@ +// mmulti.h + +#ifndef __mmulti_h__ +#define __mmulti_h__ + +#define MAXMULTIPLAYERS 16 + +extern long myconnectindex, numplayers; +extern long connecthead, connectpoint2[MAXMULTIPLAYERS]; +extern char syncstate; + +long initmultiplayersparms(long argc, char **argv); +long initmultiplayerscycle(void); + +void initmultiplayers(long argc, char **argv, char damultioption, char dacomrateoption, char dapriority); +void setpackettimeout(long datimeoutcount, long daresendagaincount); +void uninitmultiplayers(void); +void sendlogon(void); +void sendlogoff(void); +long getoutputcirclesize(void); +void setsocket(short newsocket); +void sendpacket(long other, char *bufptr, long messleng); +long getpacket(long *other, char *bufptr); +void flushpackets(void); +void genericmultifunction(long other, char *bufptr, long messleng, long command); +long isvalidipaddress(char *st); + +#endif // __mmulti_h__ + diff --git a/polymer/build/include/mmultimsgs.h b/polymer/build/include/mmultimsgs.h new file mode 100644 index 000000000..350ac2ce1 --- /dev/null +++ b/polymer/build/include/mmultimsgs.h @@ -0,0 +1,65 @@ +#ifndef __MMULTIMSGS_H__ +#define __MMULTIMSGS_H__ + +/* + * Ok, so this header file defines the message bytes and outlines the basic + * message descriptions for out-of-band messages that are common to all games + * that utilize my net code. Once a game determines that it is indeed talking + * to another peer of the same genus, the rest is up to the game itself to + * decide, but for basic stuff, the interfaces will be identical. + * + * Why am I not choosing to implement all this engine-side? Because all the + * games are different and about the only thing they are guaranteed to use in + * common that I can be certain of is the services my net code will provide. + * So, since I can't code anything in particular with every Build game in mind, + * I'm putting handling all the game-visible messages into the game's domain. + * The engine will still handle its own internal messages because the game + * never sees them. Ever. + * + * CMDs are messages sent by a peer to another, and RSPs are the replies. + * + * The master of the network game, regardless if the eventual game is talking + * with a peer-to-peer design or not, shall enumerate each peer as it joins + * and the master will always assign itself peer number 0. This simplifies + * things all-round because each peer that joins automatically knows that + * id 0 is its master and it already knows the master's address. Technically + * every other peer who joins may get a sequential number for its id so maybe + * even transmitting the peer unique ids is unnecessary and we'd be easier + * just sending a number of players, but the less craftiness at this point + * in time, the better. + * + * -- Jonathon + */ + +#define MSGPROTOVER 0x00 + // 0x00 20031209 + + +#define MSG_CMD_GETGAMEINFO 0x10 + // char MSG_CMD_GETGAMEINFO + // char MSGPROTOVER +#define MSG_RSP_BADPROTO 0x11 + // char MSG_RSP_BADPROTO +#define MSG_RSP_NOGAME 0x12 + // char MSG_RSP_NOGAME + // char[8] gamename +#define MSG_RSP_GAMEINFO 0x13 + // char MSG_RSP_GAMEINFO + // char[8] gamename eg. DUKE3DSW/DUKE3D\x00\x00/DUKE3DAT + // ... other information particular to the game + + +#define MSG_CMD_JOINGAME 0x20 + // char MSG_CMD_JOINGAME +#define MSG_RSP_GAMEINPROG 0x21 + // char MSG_RSP_GAMEINPROG +#define MSG_RSP_JOINACCEPTED 0x22 + // char MSG_RSP_JOINACCEPTED + // short uniqueid + // char numtofollow + // short[numtofollow] peeruid + // ... other information particular to the game +#define MSG_RSP_GAMEFULL 0x23 + // char MSG_RSP_GAMEFULL + +#endif diff --git a/polymer/build/include/names.h b/polymer/build/include/names.h new file mode 100644 index 000000000..6373be4d8 --- /dev/null +++ b/polymer/build/include/names.h @@ -0,0 +1,49 @@ +//Be careful when changing this file - it is parsed by Editart and Build. +#define SWITCH1ON 15 +#define SLIME 34 +#define BACKGROUND 37 +#define KENPICTURE 48 +#define BUILDDISK 49 +#define SWITCH2ON 66 +#define SWITCH2OFF 69 +#define ALPHABET 73 +#define NO 74 +#define DEMOSIGN 75 +#define COIN 76 +#define COINSTACK 77 +#define GIFTBOX 78 +#define DIAMONDS 79 +#define EVILALGRAVE 83 +#define STATUSBAR 87 +#define DAYSKY 89 +#define WATERFOUNTAIN 90 +#define USEWATERFOUNTAIN 91 +#define NIGHTSKY 93 +#define BULLET 98 +#define BOMB 100 +#define CANNON 101 +#define GUNONBOTTOM 102 +#define BOMBEMITTER 103 +#define EXPLOSION 105 +#define SPLASH 106 +#define BROWNMONSTER 110 +#define SKELETON 113 +#define AL 114 +#define EVILAL 115 +#define PLAYER 120 +#define SWITCH3OFF 146 +#define SWITCH3ON 147 +#define AIRPLANE 148 +#define SPIRAL 149 +#define COMPASS 150 +#define FOOTPRINT 156 +#define STATUSBARFILL8 160 +#define STATUSBARFILL4 161 +#define BOUNCYMAT 162 +#define MIRROR 165 +#define FLOORMIRROR 166 +#define GRABBER 167 +#define GRABCANNON 168 +#define MISSILE 169 +#define LAUNCHER 171 +#define MIRRORLABEL 4000 diff --git a/polymer/build/include/osd.h b/polymer/build/include/osd.h new file mode 100644 index 000000000..58a2b15c8 --- /dev/null +++ b/polymer/build/include/osd.h @@ -0,0 +1,77 @@ +// On-screen display (ie. console) +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __osd_h__ +#define __osd_h__ + + +typedef struct { + int numparms; + const char *name; + const char **parms; + const char *raw; +} osdfuncparm_t; + +#define OSDCMD_OK 0 +#define OSDCMD_SHOWHELP 1 + +// initializes things +void OSD_Init(void); + +// sets the file to echo output to +void OSD_SetLogFile(char *fn); + +// sets the functions the OSD will call to interrogate the environment +void OSD_SetFunctions( + void (*drawchar)(int,int,char,int,int), + void (*drawstr)(int,int,char*,int,int,int), + void (*drawcursor)(int,int,int,int), + int (*colwidth)(int), + int (*rowheight)(int), + void (*clearbg)(int,int), + int (*gettime)(void), + void (*onshow)(int) + ); + +// sets the parameters for presenting the text +void OSD_SetParameters( + int promptshade, int promptpal, + int editshade, int editpal, + int textshade, int textpal + ); + +// sets the scancode for the key which activates the onscreen display +void OSD_CaptureKey(int sc); + +// handles keyboard input when capturing input. returns 0 if key was handled +// or the scancode if it should be handled by the game. +int OSD_HandleKey(int sc, int press); + +// handles the readjustment when screen resolution changes +void OSD_ResizeDisplay(int w,int h); + +// shows or hides the onscreen display +void OSD_ShowDisplay(int onf); + +// draw the osd to the screen +void OSD_Draw(void); + +// just like printf +void OSD_Printf(const char *fmt, ...); +#define printOSD OSD_Printf + +// executes buffered commands +void OSD_DispatchQueued(void); + +// executes a string +int OSD_Dispatch(const char *cmd); + +// registers a function +// name = name of the function +// help = a short help string +// func = the entry point to the function +int OSD_RegisterFunction(const char *name, const char *help, int (*func)(const osdfuncparm_t*)); + +#endif // __osd_h__ + diff --git a/polymer/build/include/osxbits.h b/polymer/build/include/osxbits.h new file mode 100644 index 000000000..e990e5404 --- /dev/null +++ b/polymer/build/include/osxbits.h @@ -0,0 +1,7 @@ +#ifndef __osxbits_h__ +#define __osxbits_h__ + +int osx_msgbox(char *name, char *msg); +int osx_ynbox(char *name, char *msg); + +#endif \ No newline at end of file diff --git a/polymer/build/include/pragmas.h b/polymer/build/include/pragmas.h new file mode 100644 index 000000000..df51e0f0c --- /dev/null +++ b/polymer/build/include/pragmas.h @@ -0,0 +1,3704 @@ +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + + +#ifndef __pragmas_h__ +#define __pragmas_h__ + +extern long dmval; + +#if defined(NOASM) + +// +// Generic C +// + +#define qw(x) ((int64)(x)) // quadword cast +#define dw(x) ((long)(x)) // doubleword cast +#define wo(x) ((short)(x)) // word cast +#define by(x) ((char)(x)) // byte cast + +#define _scaler(a) \ +static inline long mulscale##a(long eax, long edx) \ +{ \ + return dw((qw(eax) * qw(edx)) >> a); \ +} \ +\ +static inline long divscale##a(long eax, long ebx) \ +{ \ + return dw((qw(eax) << a) / qw(ebx)); \ +} \ +\ +static inline long dmulscale##a(long eax, long edx, long esi, long edi) \ +{ \ + return dw(((qw(eax) * qw(edx)) + (qw(esi) * qw(edi))) >> a); \ +} \ +\ +static inline long tmulscale##a(long eax, long edx, long ebx, long ecx, long esi, long edi) \ +{ \ + return dw(((qw(eax) * qw(edx)) + (qw(ebx) * qw(ecx)) + (qw(esi) * qw(edi))) >> a); \ +} \ + +_scaler(1) _scaler(2) _scaler(3) _scaler(4) +_scaler(5) _scaler(6) _scaler(7) _scaler(8) +_scaler(9) _scaler(10) _scaler(11) _scaler(12) +_scaler(13) _scaler(14) _scaler(15) _scaler(16) +_scaler(17) _scaler(18) _scaler(19) _scaler(20) +_scaler(21) _scaler(22) _scaler(23) _scaler(24) +_scaler(25) _scaler(26) _scaler(27) _scaler(28) +_scaler(29) _scaler(30) _scaler(31) _scaler(32) + +static inline void swapchar(void* a, void* b) { char t = *((char*)b); *((char*)b) = *((char*)a); *((char*)a) = t; } +static inline void swapchar2(void* a, void* b, long s) { swapchar(a,b); swapchar((char*)a+1,(char*)b+s); } +static inline void swapshort(void* a, void* b) { short t = *((short*)b); *((short*)b) = *((short*)a); *((short*)a) = t; } +static inline void swaplong(void* a, void* b) { long t = *((long*)b); *((long*)b) = *((long*)a); *((long*)a) = t; } +static inline void swap64bit(void* a, void* b) { int64 t = *((int64*)b); *((int64*)b) = *((int64*)a); *((int64*)a) = t; } + +static inline char readpixel(void* s) { return (*((char*)(s))); } +static inline void drawpixel(void* s, char a) { *((char*)(s)) = a; } +static inline void drawpixels(void* s, short a) { *((short*)(s)) = a; } +static inline void drawpixelses(void* s, long a) { *((long*)(s)) = a; } + +static inline long mul3(long a) { return (a<<1)+a; } +static inline long mul5(long a) { return (a<<2)+a; } +static inline long mul9(long a) { return (a<<3)+a; } + +static inline long divmod(long a, long b) { unsigned long _a=(unsigned long)a, _b=(unsigned long)b; dmval = _a%_b; return _a/_b; } +static inline long moddiv(long a, long b) { unsigned long _a=(unsigned long)a, _b=(unsigned long)b; dmval = _a/_b; return _a%_b; } + +static inline long klabs(long a) { if (a < 0) return -a; return a; } +static inline long ksgn(long a) { if (a > 0) return 1; if (a < 0) return -1; return 0; } + +static inline long umin(long a, long b) { if ((unsigned long)a < (unsigned long)b) return a; return b; } +static inline long umax(long a, long b) { if ((unsigned long)a < (unsigned long)b) return b; return a; } +static inline long kmin(long a, long b) { if ((signed long)a < (signed long)b) return a; return b; } +static inline long kmax(long a, long b) { if ((signed long)a < (signed long)b) return b; return a; } + +static inline long sqr(long eax) { return (eax) * (eax); } +static inline long scale(long eax, long edx, long ecx) { return dw((qw(eax) * qw(edx)) / qw(ecx)); } +static inline long mulscale(long eax, long edx, long ecx) { return dw((qw(eax) * qw(edx)) >> by(ecx)); } +static inline long divscale(long eax, long ebx, long ecx) { return dw((qw(eax) << by(ecx)) / qw(ebx)); } +static inline long dmulscale(long eax, long edx, long esi, long edi, long ecx) { return dw(((qw(eax) * qw(edx)) + (qw(esi) * qw(edi))) >> by(ecx)); } + +static inline long boundmulscale(long a, long d, long c) +{ // courtesy of Ken + int64 p; + p = (((int64)a)*((int64)d))>>c; + if (p >= longlong(2147483647)) p = longlong(2147483647); + if (p < longlong(-2147483648)) p = longlong(-2147483648); + return((long)p); +} + +#undef qw +#undef dw +#undef wo +#undef by +#undef _scaler + +void qinterpolatedown16 (long bufptr, long num, long val, long add); +void qinterpolatedown16short (long bufptr, long num, long val, long add); + +void clearbuf(void* d, long c, long a); +void copybuf(void* s, void* d, long c); +void swapbuf4(void* a, void* b, long c); + +void clearbufbyte(void *D, long c, long a); +void copybufbyte(void *S, void *D, long c); +void copybufreverse(void *S, void *D, long c); + + +#elif defined(__GNUC__) && defined(__i386__) // NOASM + +// +// GCC Inline Assembler version +// + +//{{{ + +#ifndef UNDERSCORES +#define _DMVAL "dmval" +#else +#define _DMVAL "_dmval" +#endif + + +// maybe one day I'll make these into macros +long boundmulscale(long a, long b, long c); +void clearbufbyte(void *D, long c, long a); +void copybufbyte(void *S, void *D, long c); +void copybufreverse(void *S, void *D, long c); + + +#ifdef NO_GCC_BUILTINS +#define sqr(a) \ + ({ long __a=(a); \ + __asm__ __volatile__ ("imull %0, %0" \ + : "=q" (__a) \ + : "0" (__a) \ + : "cc"); \ + __a; }) +#else +#define sqr(a) __builtin_sqr(a) +#endif + +#define scale(a,d,c) \ + ({ long __a=(a), __d=(d), __c=(c); \ + __asm__ __volatile__ ("imull %%edx; idivl %%ecx" \ + : "=a" (__a), "=d" (__d) \ + : "0" (__a), "1" (__d), "c" (__c) : "cc"); \ + __a; }) + +#define mulscale(a,d,c) \ + ({ long __a=(a), __d=(d), __c=(c); \ + __asm__ __volatile__ ("imull %%edx; shrdl %%cl, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d), "c" (__c) : "cc"); \ + __a; }) +#define mulscale1(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $1, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale2(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $2, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale3(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $3, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale4(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $4, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale5(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $5, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale6(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $6, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale7(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $7, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale8(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $8, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale9(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $9, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale10(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $10, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale11(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $11, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale12(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $12, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale13(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $13, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale14(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $14, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale15(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $15, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale16(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $16, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale17(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $17, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale18(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $18, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale19(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $19, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale20(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $20, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale21(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $21, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale22(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $22, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale23(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $23, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale24(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $24, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale25(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $25, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale26(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $26, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale27(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $27, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale28(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $28, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale29(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $29, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale30(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $30, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale31(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $31, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __a; }) +#define mulscale32(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx" \ + : "=a" (__a), "=d" (__d) \ + : "a" (__a), "d" (__d) : "cc"); \ + __d; }) + +#define dmulscale(a,d,S,D,c) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D), __c=(c); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl %%cl, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D), "c" (__c) : "ebx", "cc"); \ + __a; }) +#define dmulscale1(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $1, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale2(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $2, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale3(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $3, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale4(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $4, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale5(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $5, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale6(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $6, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale7(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $7, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale8(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $8, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale9(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $9, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale10(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $10, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale11(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $11, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale12(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $12, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale13(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $13, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale14(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $14, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale15(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $15, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale16(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $16, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale17(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $17, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale18(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $18, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale19(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $19, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale20(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $20, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale21(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $21, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale22(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $22, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale23(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $23, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale24(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $24, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale25(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $25, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale26(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $26, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale27(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $27, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale28(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $28, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale29(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $29, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale30(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $30, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale31(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx; shrdl $31, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __a; }) +#define dmulscale32(a,d,S,D) \ + ({ long __a=(a), __d=(d), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; movl %%eax, %%ebx; movl %%esi, %%eax; movl %%edx, %%esi; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%esi, %%edx" \ + : "=a" (__a), "=d" (__d), "=S" (__S) \ + : "a" (__a), "d" (__d), "S" (__S), "D" (__D) : "ebx", "cc"); \ + __d; }) + +#define tmulscale1(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $1, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale2(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $2, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale3(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $3, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale4(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $4, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale5(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $5, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale6(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $6, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale7(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $7, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale8(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $8, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale9(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $9, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale10(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $10, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale11(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $11, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale12(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $12, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale13(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $13, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale14(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $14, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale15(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $15, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale16(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $16, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale17(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $17, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale18(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $18, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale19(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $19, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale20(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $20, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale21(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $21, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale22(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $22, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale23(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $23, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale24(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $24, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale25(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $25, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale26(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $26, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale27(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $27, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale28(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $28, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale29(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $29, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale30(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $30, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale31(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx; shrdl $31, %%edx, %%eax" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __a; }) +#define tmulscale32(a,d,b,c,S,D) \ + ({ long __a=(a), __d=(d), __b=(b), __c=(c), __S=(S), __D=(D); \ + __asm__ __volatile__ ("imull %%edx; xchgl %%ebx, %%eax; xchgl %%ecx, %%edx; " \ + "imull %%edx; addl %%eax, %%ebx; adcl %%edx, %%ecx; movl %%esi, %%eax; " \ + "imull %%edi; addl %%ebx, %%eax; adcl %%ecx, %%edx" \ + : "=a" (__a), "=d" (__d), "=b" (__b), "=c" (__c) \ + : "a" (__a), "d" (__d), "b" (__b), "c" (__c), "S" (__S), "D" (__D) : "cc"); \ + __d; }) + +#define divscale(a,b,c) \ + ({ long __a=(a), __b=(b), __c=(c); \ + __asm__ __volatile__ ("movl %%eax, %%edx; shll %%cl, %%eax; negb %%cl; sarl %%cl, %%edx; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "c" (__c), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale1(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("addl %%eax, %%eax; sbbl %%edx, %%edx; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale2(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $30, %%edx; leal (,%%eax,4), %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale3(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $29, %%edx; leal (,%%eax,8), %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale4(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $28, %%edx; shll $4, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale5(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $27, %%edx; shll $5, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale6(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $26, %%edx; shll $6, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale7(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $25, %%edx; shll $7, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale8(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $24, %%edx; shll $8, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale9(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $23, %%edx; shll $9, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale10(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $22, %%edx; shll $10, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale11(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $21, %%edx; shll $11, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale12(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $20, %%edx; shll $12, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale13(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $19, %%edx; shll $13, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale14(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $18, %%edx; shll $14, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale15(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $17, %%edx; shll $15, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale16(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $16, %%edx; shll $16, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale17(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $15, %%edx; shll $17, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale18(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $14, %%edx; shll $18, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale19(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $13, %%edx; shll $19, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale20(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $12, %%edx; shll $20, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale21(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $11, %%edx; shll $21, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale22(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $10, %%edx; shll $22, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale23(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $9, %%edx; shll $23, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale24(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $8, %%edx; shll $24, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale25(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $7, %%edx; shll $25, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale26(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $6, %%edx; shll $26, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale27(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $5, %%edx; shll $27, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale28(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $4, %%edx; shll $28, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale29(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $3, %%edx; shll $29, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale30(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $2, %%edx; shll $30, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale31(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("movl %%eax, %%edx; sarl $1, %%edx; shll $31, %%eax; idivl %%ebx" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "edx", "cc"); \ + __a; }) +#define divscale32(d,b) \ + ({ long __d=(d), __b=(b), __r; \ + __asm__ __volatile__ ("xorl %%eax, %%eax; idivl %%ebx" \ + : "=a" (__r), "=d" (__d) : "d" (__d), "b" (__b) : "cc"); \ + __r; }) + +#define readpixel(D) \ + ({ void *__D=(D); long __a; \ + __asm__ __volatile__ ("movb (%%edi), %%al" \ + : "=a" (__a): "D" (__D) : "cc"); \ + __a; }) +#define drawpixel(D,a) \ + ({ void *__D=(D); long __a=(a); \ + __asm__ __volatile__ ("movb %%al, (%%edi)" \ + : : "D" (__D), "a" (__a) : "memory", "cc"); \ + 0; }) +#define drawpixels(D,a) \ + ({ void *__D=(D); long __a=(a); \ + __asm__ __volatile__ ("movw %%ax, (%%edi)" \ + : : "D" (__D), "a" (__a) : "memory", "cc"); \ + 0; }) +#define drawpixelses(D,a) \ + ({ void *__D=(D); long __a=(a); \ + __asm__ __volatile__ ("movl %%eax, (%%edi)" \ + : : "D" (__D), "a" (__a) : "memory", "cc"); \ + 0; }) +#define clearbuf(D,c,a) \ + ({ void *__D=(D); long __c=(c), __a=(a); \ + __asm__ __volatile__ ("rep; stosl" \ + : "=&D" (__D), "=&c" (__c) : "0" (__D), "1" (__c), "a" (__a) : "memory", "cc"); \ + 0; }) +#define copybuf(S,D,c) \ + ({ void *__S=(S), *__D=(D); long __c=(c); \ + __asm__ __volatile__ ("rep; movsl" \ + : "=&S" (__S), "=&D" (__D), "=&c" (__c) : "0" (__S), "1" (__D), "2" (__c) : "memory", "cc"); \ + 0; }) + +#define mul3(a) \ + ({ long __a=(a), __r; \ + __asm__ __volatile__ ("lea (%1,%1,2), %0" \ + : "=r" (__r) : "0" (__a) : "cc"); \ + __r; }) +#define mul5(a) \ + ({ long __a=(a), __r; \ + __asm__ __volatile__ ("lea (%1,%1,4), %0" \ + : "=r" (__r) : "0" (__a) : "cc"); \ + __r; }) +#define mul9(a) \ + ({ long __a=(a), __r; \ + __asm__ __volatile__ ("lea (%1,%1,8), %0" \ + : "=r" (__r) : "0" (__a) : "cc"); \ + __r; }) + +//returns eax/ebx, dmval = eax%edx; +#define divmod(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("xorl %%edx, %%edx; divl %%ebx; movl %%edx, "_DMVAL \ + : "+a" (__a) : "b" (__b) : "edx", "memory", "cc"); \ + __a; }) +//returns eax%ebx, dmval = eax/edx; +#define moddiv(a,b) \ + ({ long __a=(a), __b=(b), __d; \ + __asm__ __volatile__ ("xorl %%edx, %%edx; divl %%ebx; movl %%eax, "_DMVAL \ + : "=d" (__d) : "a" (__a), "b" (__b) : "eax", "memory", "cc"); \ + __d; }) + +#define klabs(a) \ + ({ long __a=(a); \ + __asm__ __volatile__ ("testl %%eax, %%eax; jns 0f; negl %%eax; 0:" \ + : "=a" (__a) : "a" (__a) : "cc"); \ + __a; }) +#define ksgn(b) \ + ({ long __b=(b), __r; \ + __asm__ __volatile__ ("addl %%ebx, %%ebx; sbbl %%eax, %%eax; cmpl %%ebx, %%eax; adcb $0, %%al" \ + : "=a" (__r) : "b" (__b) : "cc"); \ + __r; }) + +#define umin(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("subl %%ebx, %%eax; sbbl %%ecx, %%ecx; andl %%ecx, %%eax; addl %%ebx, %%eax" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "ecx", "cc"); \ + __a; }) +#define umax(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("subl %%ebx, %%eax; sbbl %%ecx, %%ecx; xorl $0xffffffff, %%ecx; andl %%ecx, %%eax; addl %%ebx, %%eax" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "ecx", "cc"); \ + __a; }) + +#define kmin(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("cmpl %%ebx, %%eax; jl 0f; movl %%ebx, %%eax; 0:" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "cc"); \ + __a; }) +#define kmax(a,b) \ + ({ long __a=(a), __b=(b); \ + __asm__ __volatile__ ("cmpl %%ebx, %%eax; jg 0f; movl %%ebx, %%eax; 0:" \ + : "=a" (__a) : "a" (__a), "b" (__b) : "cc"); \ + __a; }) + +#define swapchar(a,b) \ + ({ void *__a=(a), *__b=(b); \ + __asm__ __volatile__ ("movb (%%eax), %%cl; movb (%%ebx), %%ch; movb %%cl, (%%ebx); movb %%ch, (%%eax)" \ + : : "a" (__a), "b" (__b) : "ecx", "memory", "cc"); \ + 0; }) +#define swapshort(a,b) \ + ({ void *__a=(a), *__b=(b); \ + __asm__ __volatile__ ("movw (%%eax), %%cx; movw (%%ebx), %%dx; movw %%cx, (%%ebx); movw %%dx, (%%eax)" \ + : : "a" (__a), "b" (__b) : "ecx", "edx", "memory", "cc"); \ + 0; }) +#define swaplong(a,b) \ + ({ void *__a=(a), *__b=(b); \ + __asm__ __volatile__ ("movl (%%eax), %%ecx; movl (%%ebx), %%edx; movl %%ecx, (%%ebx); movl %%edx, (%%eax)" \ + : : "a" (__a), "b" (__b) : "ecx", "edx", "memory", "cc"); \ + 0; }) +#define swapbuf4(a,b,c) \ + ({ void *__a=(a), *__b=(b); long __c=(c); \ + __asm__ __volatile__ ("0: movl (%%eax), %%esi; movl (%%ebx), %%edi; movl %%esi, (%%ebx); " \ + "movl %%edi, (%%eax); addl $4, %%eax; addl $4, %%ebx; decl %%ecx; jnz 0b" \ + : : "a" (__a), "b" (__b), "c" (__c) : "esi", "edi", "memory", "cc"); \ + 0; }) +#define swap64bit(a,b) \ + ({ void *__a=(a), *__b=(b); \ + __asm__ __volatile__ ("movl (%%eax), %%ecx; movl (%%ebx), %%edx; movl %%ecx, (%%ebx); " \ + "movl 4(%%eax), %%ecx; movl %%edx, (%%eax); movl 4(%%ebx), %%edx; " \ + "movl %%ecx, 4(%%ebx); movl %%edx, 4(%%eax)" \ + : : "a" (__a), "b" (__b) : "ecx", "edx", "memory", "cc"); \ + 0; }) + +//swapchar2(ptr1,ptr2,xsiz); is the same as: +//swapchar(ptr1,ptr2); swapchar(ptr1+1,ptr2+xsiz); +#define swapchar2(a,b,S) \ + ({ void *__a=(a), *__b=(b); long __S=(S); \ + __asm__ __volatile__ ("addl %%ebx, %%esi; movw (%%eax), %%cx; movb (%%ebx), %%dl; " \ + "movb %%cl, (%%ebx); movb (%%esi), %%dh; movb %%ch, (%%esi); " \ + "movw %%dx, (%%eax)" \ + : : "a" (__a), "b" (__b), "S" (__S) : "ecx", "edx", "memory", "cc"); \ + 0; }) + + +#define qinterpolatedown16(a,c,d,S) \ + ({ void *__a=(void*)(a); long __c=(c), __d=(d), __S=(S); \ + __asm__ __volatile__ ("movl %%ecx, %%ebx; shrl $1, %%ecx; jz 1f; " \ + "0: leal (%%edx,%%esi,), %%edi; sarl $16, %%edx; movl %%edx, (%%eax); " \ + "leal (%%edi,%%esi,), %%edx; sarl $16, %%edi; movl %%edi, 4(%%eax); " \ + "addl $8, %%eax; decl %%ecx; jnz 0b; testl $1, %%ebx; jz 2f; " \ + "1: sarl $16, %%edx; movl %%edx, (%%eax); 2:" \ + : "=a" (__a), "=c" (__c), "=d" (__d) : "a" (__a), "c" (__c), "d" (__d), "S" (__S) \ + : "ebx", "edi", "memory", "cc"); \ + 0; }) + +#define qinterpolatedown16short(a,c,d,S) \ + ({ void *__a=(void*)(a); long __c=(c), __d=(d), __S=(S); \ + __asm__ __volatile__ ("testl %%ecx, %%ecx; jz 3f; testb $2, %%al; jz 0f; movl %%edx, %%ebx; " \ + "sarl $16, %%ebx; movw %%bx, (%%eax); addl %%esi, %%edx; addl $2, %%eax; " \ + "decl %%ecx; jz 3f; " \ + "0: subl $2, %%ecx; jc 2f; " \ + "1: movl %%edx, %%ebx; addl %%esi, %%edx; sarl $16, %%ebx; movl %%edx, %%edi; " \ + "andl $0xffff0000, %%edi; addl %%esi, %%edx; addl %%edi, %%ebx; " \ + "movl %%ebx, (%%eax); addl $4, %%eax; subl $2, %%ecx; jnc 1b; testb $1, %%cl; " \ + "jz 3f; " \ + "2: movl %%edx, %%ebx; sarl $16, %%ebx; movw %%bx, (%%eax); 3:" \ + : "=a" (__a), "=c" (__c), "=d" (__d) : "a" (__a), "c" (__c), "d" (__d), "S" (__S) \ + : "ebx", "edi", "memory", "cc"); \ + 0; }) + + +//}}} + +#elif defined(__WATCOMC__) // __GNUC__ && __i386__ + +// +// Watcom C inline assembler +// + +//{{{ +#pragma aux sqr =\ + "imul eax, eax",\ + parm nomemory [eax]\ + modify exact [eax]\ + value [eax] +long sqr(long); + +#pragma aux scale =\ + "imul edx",\ + "idiv ecx",\ + parm nomemory [eax][edx][ecx]\ + modify exact [eax edx] +long scale(long,long,long); + +#pragma aux mulscale =\ + "imul edx",\ + "shrd eax, edx, cl",\ + parm nomemory [eax][edx][ecx]\ + modify exact [eax edx] +long mulscale(long,long,long); + +#pragma aux mulscale1 =\ + "imul edx",\ + "shrd eax, edx, 1",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale1(long,long); + +#pragma aux mulscale2 =\ + "imul edx",\ + "shrd eax, edx, 2",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale2(long,long); + +#pragma aux mulscale3 =\ + "imul edx",\ + "shrd eax, edx, 3",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale3(long,long); + +#pragma aux mulscale4 =\ + "imul edx",\ + "shrd eax, edx, 4",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale4(long,long); + +#pragma aux mulscale5 =\ + "imul edx",\ + "shrd eax, edx, 5",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale5(long,long); + +#pragma aux mulscale6 =\ + "imul edx",\ + "shrd eax, edx, 6",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale6(long,long); + +#pragma aux mulscale7 =\ + "imul edx",\ + "shrd eax, edx, 7",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale7(long,long); + +#pragma aux mulscale8 =\ + "imul edx",\ + "shrd eax, edx, 8",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale8(long,long); + +#pragma aux mulscale9 =\ + "imul edx",\ + "shrd eax, edx, 9",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale9(long,long); + +#pragma aux mulscale10 =\ + "imul edx",\ + "shrd eax, edx, 10",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale10(long,long); + +#pragma aux mulscale11 =\ + "imul edx",\ + "shrd eax, edx, 11",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale11(long,long); + +#pragma aux mulscale12 =\ + "imul edx",\ + "shrd eax, edx, 12",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale12(long,long); + +#pragma aux mulscale13 =\ + "imul edx",\ + "shrd eax, edx, 13",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale13(long,long); + +#pragma aux mulscale14 =\ + "imul edx",\ + "shrd eax, edx, 14",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale14(long,long); + +#pragma aux mulscale15 =\ + "imul edx",\ + "shrd eax, edx, 15",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale15(long,long); + +#pragma aux mulscale16 =\ + "imul edx",\ + "shrd eax, edx, 16",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale16(long,long); + +#pragma aux mulscale17 =\ + "imul edx",\ + "shrd eax, edx, 17",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale17(long,long); + +#pragma aux mulscale18 =\ + "imul edx",\ + "shrd eax, edx, 18",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale18(long,long); + +#pragma aux mulscale19 =\ + "imul edx",\ + "shrd eax, edx, 19",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale19(long,long); + +#pragma aux mulscale20 =\ + "imul edx",\ + "shrd eax, edx, 20",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale20(long,long); + +#pragma aux mulscale21 =\ + "imul edx",\ + "shrd eax, edx, 21",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale21(long,long); + +#pragma aux mulscale22 =\ + "imul edx",\ + "shrd eax, edx, 22",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale22(long,long); + +#pragma aux mulscale23 =\ + "imul edx",\ + "shrd eax, edx, 23",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale23(long,long); + +#pragma aux mulscale24 =\ + "imul edx",\ + "shrd eax, edx, 24",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale24(long,long); + +#pragma aux mulscale25 =\ + "imul edx",\ + "shrd eax, edx, 25",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale25(long,long); + +#pragma aux mulscale26 =\ + "imul edx",\ + "shrd eax, edx, 26",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale26(long,long); + +#pragma aux mulscale27 =\ + "imul edx",\ + "shrd eax, edx, 27",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale27(long,long); + +#pragma aux mulscale28 =\ + "imul edx",\ + "shrd eax, edx, 28",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale28(long,long); + +#pragma aux mulscale29 =\ + "imul edx",\ + "shrd eax, edx, 29",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale29(long,long); + +#pragma aux mulscale30 =\ + "imul edx",\ + "shrd eax, edx, 30",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale30(long,long); + +#pragma aux mulscale31 =\ + "imul edx",\ + "shrd eax, edx, 31",\ + parm nomemory [eax][edx]\ + modify exact [eax edx] +long mulscale31(long,long); + +#pragma aux mulscale32 =\ + "imul edx",\ + parm nomemory [eax][edx]\ + modify exact [eax edx]\ + value [edx] +long mulscale32(long,long); + +#pragma aux dmulscale =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, cl",\ + parm nomemory [eax][edx][esi][edi][ecx]\ + modify exact [eax ebx edx esi] +long dmulscale(long,long,long,long,long); + +#pragma aux dmulscale1 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 1",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale1(long,long,long,long); + +#pragma aux dmulscale2 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 2",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale2(long,long,long,long); + +#pragma aux dmulscale3 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 3",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale3(long,long,long,long); + +#pragma aux dmulscale4 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 4",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale4(long,long,long,long); + +#pragma aux dmulscale5 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 5",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale5(long,long,long,long); + +#pragma aux dmulscale6 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 6",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale6(long,long,long,long); + +#pragma aux dmulscale7 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 7",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale7(long,long,long,long); + +#pragma aux dmulscale8 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 8",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale8(long,long,long,long); + +#pragma aux dmulscale9 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 9",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale9(long,long,long,long); + +#pragma aux dmulscale10 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 10",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale10(long,long,long,long); + +#pragma aux dmulscale11 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 11",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale11(long,long,long,long); + +#pragma aux dmulscale12 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 12",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale12(long,long,long,long); + +#pragma aux dmulscale13 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 13",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale13(long,long,long,long); + +#pragma aux dmulscale14 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 14",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale14(long,long,long,long); + +#pragma aux dmulscale15 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 15",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale15(long,long,long,long); + +#pragma aux dmulscale16 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 16",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale16(long,long,long,long); + +#pragma aux dmulscale17 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 17",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale17(long,long,long,long); + +#pragma aux dmulscale18 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 18",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale18(long,long,long,long); + +#pragma aux dmulscale19 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 19",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale19(long,long,long,long); + +#pragma aux dmulscale20 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 20",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale20(long,long,long,long); + +#pragma aux dmulscale21 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 21",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale21(long,long,long,long); + +#pragma aux dmulscale22 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 22",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale22(long,long,long,long); + +#pragma aux dmulscale23 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 23",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale23(long,long,long,long); + +#pragma aux dmulscale24 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 24",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale24(long,long,long,long); + +#pragma aux dmulscale25 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 25",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale25(long,long,long,long); + +#pragma aux dmulscale26 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 26",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale26(long,long,long,long); + +#pragma aux dmulscale27 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 27",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale27(long,long,long,long); + +#pragma aux dmulscale28 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 28",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale28(long,long,long,long); + +#pragma aux dmulscale29 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 29",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale29(long,long,long,long); + +#pragma aux dmulscale30 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 30",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale30(long,long,long,long); + +#pragma aux dmulscale31 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + "shrd eax, edx, 31",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi] +long dmulscale31(long,long,long,long); + +#pragma aux dmulscale32 =\ + "imul edx",\ + "mov ebx, eax",\ + "mov eax, esi",\ + "mov esi, edx",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, esi",\ + parm nomemory [eax][edx][esi][edi]\ + modify exact [eax ebx edx esi]\ + value [edx] +long dmulscale32(long,long,long,long); + +#pragma aux tmulscale1 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 1",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale1(long,long,long,long,long,long); + +#pragma aux tmulscale2 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 2",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale2(long,long,long,long,long,long); + +#pragma aux tmulscale3 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 3",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale3(long,long,long,long,long,long); + +#pragma aux tmulscale4 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 4",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale4(long,long,long,long,long,long); + +#pragma aux tmulscale5 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 5",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale5(long,long,long,long,long,long); + +#pragma aux tmulscale6 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 6",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale6(long,long,long,long,long,long); + +#pragma aux tmulscale7 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 7",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale7(long,long,long,long,long,long); + +#pragma aux tmulscale8 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 8",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale8(long,long,long,long,long,long); + +#pragma aux tmulscale9 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 9",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale9(long,long,long,long,long,long); + +#pragma aux tmulscale10 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 10",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale10(long,long,long,long,long,long); + +#pragma aux tmulscale11 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 11",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale11(long,long,long,long,long,long); + +#pragma aux tmulscale12 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 12",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale12(long,long,long,long,long,long); + +#pragma aux tmulscale13 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 13",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale13(long,long,long,long,long,long); + +#pragma aux tmulscale14 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 14",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale14(long,long,long,long,long,long); + +#pragma aux tmulscale15 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 15",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale15(long,long,long,long,long,long); + +#pragma aux tmulscale16 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 16",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale16(long,long,long,long,long,long); + +#pragma aux tmulscale17 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 17",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale17(long,long,long,long,long,long); + +#pragma aux tmulscale18 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 18",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale18(long,long,long,long,long,long); + +#pragma aux tmulscale19 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 19",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale19(long,long,long,long,long,long); + +#pragma aux tmulscale20 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 20",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale20(long,long,long,long,long,long); + +#pragma aux tmulscale21 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 21",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale21(long,long,long,long,long,long); + +#pragma aux tmulscale22 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 22",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale22(long,long,long,long,long,long); + +#pragma aux tmulscale23 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 23",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale23(long,long,long,long,long,long); + +#pragma aux tmulscale24 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 24",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale24(long,long,long,long,long,long); + +#pragma aux tmulscale25 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 25",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale25(long,long,long,long,long,long); + +#pragma aux tmulscale26 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 26",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale26(long,long,long,long,long,long); + +#pragma aux tmulscale27 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 27",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale27(long,long,long,long,long,long); + +#pragma aux tmulscale28 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 28",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale28(long,long,long,long,long,long); + +#pragma aux tmulscale29 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 29",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale29(long,long,long,long,long,long); + +#pragma aux tmulscale30 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 30",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale30(long,long,long,long,long,long); + +#pragma aux tmulscale31 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + "shrd eax, edx, 31",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx] +long tmulscale31(long,long,long,long,long,long); + +#pragma aux tmulscale32 =\ + "imul edx",\ + "xchg eax, ebx",\ + "xchg edx, ecx",\ + "imul edx",\ + "add ebx, eax",\ + "adc ecx, edx",\ + "mov eax, esi",\ + "imul edi",\ + "add eax, ebx",\ + "adc edx, ecx",\ + parm nomemory [eax][edx][ebx][ecx][esi][edi]\ + modify exact [eax ebx ecx edx]\ + value [edx] +long tmulscale32(long,long,long,long,long,long); + +#pragma aux boundmulscale =\ + "imul ebx",\ + "mov ebx, edx",\ + "shrd eax, edx, cl",\ + "sar edx, cl",\ + "xor edx, eax",\ + "js checkit",\ + "xor edx, eax",\ + "jz skipboundit",\ + "cmp edx, 0xffffffff",\ + "je skipboundit",\ + "checkit:",\ + "mov eax, ebx",\ + "sar eax, 31",\ + "xor eax, 0x7fffffff",\ + "skipboundit:",\ + parm nomemory [eax][ebx][ecx]\ + modify exact [eax ebx edx] +long boundmulscale(long,long,long); + +#pragma aux divscale =\ + "mov edx, eax",\ + "shl eax, cl",\ + "neg cl",\ + "sar edx, cl",\ + "idiv ebx",\ + parm nomemory [eax][ebx][ecx]\ + modify exact [eax ecx edx] +long divscale(long,long,long); + +#pragma aux divscale1 =\ + "add eax, eax",\ + "sbb edx, edx",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale1(long,long); + +#pragma aux divscale2 =\ + "mov edx, eax",\ + "sar edx, 30",\ + "lea eax, [eax*4]",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale2(long,long); + +#pragma aux divscale3 =\ + "mov edx, eax",\ + "sar edx, 29",\ + "lea eax, [eax*8]",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale3(long,long); + +#pragma aux divscale4 =\ + "mov edx, eax",\ + "sar edx, 28",\ + "shl eax, 4",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale4(long,long); + +#pragma aux divscale5 =\ + "mov edx, eax",\ + "sar edx, 27",\ + "shl eax, 5",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale5(long,long); + +#pragma aux divscale6 =\ + "mov edx, eax",\ + "sar edx, 26",\ + "shl eax, 6",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale6(long,long); + +#pragma aux divscale7 =\ + "mov edx, eax",\ + "sar edx, 25",\ + "shl eax, 7",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale7(long,long); + +#pragma aux divscale8 =\ + "mov edx, eax",\ + "sar edx, 24",\ + "shl eax, 8",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale8(long,long); + +#pragma aux divscale9 =\ + "mov edx, eax",\ + "sar edx, 23",\ + "shl eax, 9",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale9(long,long); + +#pragma aux divscale10 =\ + "mov edx, eax",\ + "sar edx, 22",\ + "shl eax, 10",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale10(long,long); + +#pragma aux divscale11 =\ + "mov edx, eax",\ + "sar edx, 21",\ + "shl eax, 11",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale11(long,long); + +#pragma aux divscale12 =\ + "mov edx, eax",\ + "sar edx, 20",\ + "shl eax, 12",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale12(long,long); + +#pragma aux divscale13 =\ + "mov edx, eax",\ + "sar edx, 19",\ + "shl eax, 13",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale13(long,long); + +#pragma aux divscale14 =\ + "mov edx, eax",\ + "sar edx, 18",\ + "shl eax, 14",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale14(long,long); + +#pragma aux divscale15 =\ + "mov edx, eax",\ + "sar edx, 17",\ + "shl eax, 15",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale15(long,long); + +#pragma aux divscale16 =\ + "mov edx, eax",\ + "sar edx, 16",\ + "shl eax, 16",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale16(long,long); + +#pragma aux divscale17 =\ + "mov edx, eax",\ + "sar edx, 15",\ + "shl eax, 17",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale17(long,long); + +#pragma aux divscale18 =\ + "mov edx, eax",\ + "sar edx, 14",\ + "shl eax, 18",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale18(long,long); + +#pragma aux divscale19 =\ + "mov edx, eax",\ + "sar edx, 13",\ + "shl eax, 19",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale19(long,long); + +#pragma aux divscale20 =\ + "mov edx, eax",\ + "sar edx, 12",\ + "shl eax, 20",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale20(long,long); + +#pragma aux divscale21 =\ + "mov edx, eax",\ + "sar edx, 11",\ + "shl eax, 21",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale21(long,long); + +#pragma aux divscale22 =\ + "mov edx, eax",\ + "sar edx, 10",\ + "shl eax, 22",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale22(long,long); + +#pragma aux divscale23 =\ + "mov edx, eax",\ + "sar edx, 9",\ + "shl eax, 23",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale23(long,long); + +#pragma aux divscale24 =\ + "mov edx, eax",\ + "sar edx, 8",\ + "shl eax, 24",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale24(long,long); + +#pragma aux divscale25 =\ + "mov edx, eax",\ + "sar edx, 7",\ + "shl eax, 25",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale25(long,long); + +#pragma aux divscale26 =\ + "mov edx, eax",\ + "sar edx, 6",\ + "shl eax, 26",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale26(long,long); + +#pragma aux divscale27 =\ + "mov edx, eax",\ + "sar edx, 5",\ + "shl eax, 27",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale27(long,long); + +#pragma aux divscale28 =\ + "mov edx, eax",\ + "sar edx, 4",\ + "shl eax, 28",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale28(long,long); + +#pragma aux divscale29 =\ + "mov edx, eax",\ + "sar edx, 3",\ + "shl eax, 29",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale29(long,long); + +#pragma aux divscale30 =\ + "mov edx, eax",\ + "sar edx, 2",\ + "shl eax, 30",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale30(long,long); + +#pragma aux divscale31 =\ + "mov edx, eax",\ + "sar edx, 1",\ + "shl eax, 31",\ + "idiv ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax edx] +long divscale31(long,long); + +#pragma aux divscale32 =\ + "xor eax, eax",\ + "idiv ebx",\ + parm nomemory [edx][ebx]\ + modify exact [eax edx] +long divscale32(long,long); + +#pragma aux readpixel =\ + "mov al, byte ptr [edi]",\ + parm nomemory [edi]\ + modify exact [eax] +long readpixel(void*); + +#pragma aux drawpixel =\ + "mov byte ptr [edi], al",\ + parm [edi][eax]\ + modify exact +long drawpixel(void*,long); + +#pragma aux drawpixels =\ + "mov word ptr [edi], ax",\ + parm [edi][eax]\ + modify exact +long drawpixels(void*,long); + +#pragma aux drawpixelses =\ + "mov dword ptr [edi], eax",\ + parm [edi][eax]\ + modify exact +long drawpixelses(void*,long); + +#pragma aux clearbuf =\ + "rep stosd",\ + parm [edi][ecx][eax]\ + modify exact [edi ecx] +long clearbuf(void*,long,long); + +#pragma aux clearbufbyte =\ + "cmp ecx, 4",\ + "jae longcopy",\ + "test cl, 1",\ + "jz preskip",\ + "stosb",\ + "preskip: shr ecx, 1",\ + "rep stosw",\ + "jmp endit",\ + "longcopy: test edi, 1",\ + "jz skip1",\ + "stosb",\ + "dec ecx",\ + "skip1: test edi, 2",\ + "jz skip2",\ + "stosw",\ + "sub ecx, 2",\ + "skip2: mov ebx, ecx",\ + "shr ecx, 2",\ + "rep stosd",\ + "test bl, 2",\ + "jz skip3",\ + "stosw",\ + "skip3: test bl, 1",\ + "jz endit",\ + "stosb",\ + "endit:",\ + parm [edi][ecx][eax]\ + modify [ebx] +long clearbufbyte(void*,long,long); + +#pragma aux copybuf =\ + "rep movsd",\ + parm [esi][edi][ecx]\ + modify exact [ecx esi edi] +long copybuf(void*,void*,long); + +#pragma aux copybufbyte =\ + "cmp ecx, 4",\ + "jae longcopy",\ + "test cl, 1",\ + "jz preskip",\ + "movsb",\ + "preskip: shr ecx, 1",\ + "rep movsw",\ + "jmp endit",\ + "longcopy: test edi, 1",\ + "jz skip1",\ + "movsb",\ + "dec ecx",\ + "skip1: test edi, 2",\ + "jz skip2",\ + "movsw",\ + "sub ecx, 2",\ + "skip2: mov ebx, ecx",\ + "shr ecx, 2",\ + "rep movsd",\ + "test bl, 2",\ + "jz skip3",\ + "movsw",\ + "skip3: test bl, 1",\ + "jz endit",\ + "movsb",\ + "endit:",\ + parm [esi][edi][ecx]\ + modify [ebx] +long copybufbyte(void*,void*,long); + +#pragma aux copybufreverse =\ + "shr ecx, 1",\ + "jnc skipit1",\ + "mov al, byte ptr [esi]",\ + "dec esi",\ + "mov byte ptr [edi], al",\ + "inc edi",\ + "skipit1: shr ecx, 1",\ + "jnc skipit2",\ + "mov ax, word ptr [esi-1]",\ + "sub esi, 2",\ + "ror ax, 8",\ + "mov word ptr [edi], ax",\ + "add edi, 2",\ + "skipit2: test ecx, ecx",\ + "jz endloop",\ + "begloop: mov eax, dword ptr [esi-3]",\ + "sub esi, 4",\ + "bswap eax",\ + "mov dword ptr [edi], eax",\ + "add edi, 4",\ + "dec ecx",\ + "jnz begloop",\ + "endloop:",\ + parm [esi][edi][ecx] +long copybufreverse(void*,void*,long); + +#pragma aux qinterpolatedown16 =\ + "mov ebx, ecx",\ + "shr ecx, 1",\ + "jz skipbegcalc",\ + "begqcalc: lea edi, [edx+esi]",\ + "sar edx, 16",\ + "mov dword ptr [eax], edx",\ + "lea edx, [edi+esi]",\ + "sar edi, 16",\ + "mov dword ptr [eax+4], edi",\ + "add eax, 8",\ + "dec ecx",\ + "jnz begqcalc",\ + "test ebx, 1",\ + "jz skipbegqcalc2",\ + "skipbegcalc: sar edx, 16",\ + "mov dword ptr [eax], edx",\ + "skipbegqcalc2:",\ + parm [eax][ecx][edx][esi]\ + modify exact [eax ebx ecx edx edi] +long qinterpolatedown16(long,long,long,long); + +#pragma aux qinterpolatedown16short =\ + "test ecx, ecx",\ + "jz endit",\ + "test al, 2",\ + "jz skipalignit",\ + "mov ebx, edx",\ + "sar ebx, 16",\ + "mov word ptr [eax], bx",\ + "add edx, esi",\ + "add eax, 2",\ + "dec ecx",\ + "jz endit",\ + "skipalignit: sub ecx, 2",\ + "jc finishit",\ + "begqcalc: mov ebx, edx",\ + "add edx, esi",\ + "sar ebx, 16",\ + "mov edi, edx",\ + "and edi, 0ffff0000h",\ + "add edx, esi",\ + "add ebx, edi",\ + "mov dword ptr [eax], ebx",\ + "add eax, 4",\ + "sub ecx, 2",\ + "jnc begqcalc",\ + "test cl, 1",\ + "jz endit",\ + "finishit: mov ebx, edx",\ + "sar ebx, 16",\ + "mov word ptr [eax], bx",\ + "endit:",\ + parm [eax][ecx][edx][esi]\ + modify exact [eax ebx ecx edx edi] +long qinterpolatedown16short(long,long,long,long); + +#pragma aux mul3 =\ + "lea eax, [eax+eax*2]",\ + parm nomemory [eax] +long mul3(long); + +#pragma aux mul5 =\ + "lea eax, [eax+eax*4]",\ + parm nomemory [eax] +long mul5(long); + +#pragma aux mul9 =\ + "lea eax, [eax+eax*8]",\ + parm nomemory [eax] +long mul9(long); + + //returns eax/ebx, dmval = eax%edx; +#pragma aux divmod =\ + "xor edx, edx",\ + "div ebx",\ + "mov dmval, edx",\ + parm [eax][ebx]\ + modify exact [eax edx]\ + value [eax] +long divmod(long,long); + + //returns eax%ebx, dmval = eax/edx; +#pragma aux moddiv =\ + "xor edx, edx",\ + "div ebx",\ + "mov dmval, eax",\ + parm [eax][ebx]\ + modify exact [eax edx]\ + value [edx] +long moddiv(long,long); + +#pragma aux klabs =\ + "test eax, eax",\ + "jns skipnegate",\ + "neg eax",\ + "skipnegate:",\ + parm nomemory [eax] +long klabs(long); + +#pragma aux ksgn =\ + "add ebx, ebx",\ + "sbb eax, eax",\ + "cmp eax, ebx",\ + "adc al, 0",\ + parm nomemory [ebx]\ + modify exact [eax ebx] +long ksgn(long); + + //eax = (unsigned min)umin(eax,ebx) +#pragma aux umin =\ + "sub eax, ebx",\ + "sbb ecx, ecx",\ + "and eax, ecx",\ + "add eax, ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax ecx] +long umin(long,long); + + //eax = (unsigned max)umax(eax,ebx) +#pragma aux umax =\ + "sub eax, ebx",\ + "sbb ecx, ecx",\ + "xor ecx, 0xffffffff",\ + "and eax, ecx",\ + "add eax, ebx",\ + parm nomemory [eax][ebx]\ + modify exact [eax ecx] +long umax(long,long); + +#pragma aux kmin =\ + "cmp eax, ebx",\ + "jl skipit",\ + "mov eax, ebx",\ + "skipit:",\ + parm nomemory [eax][ebx]\ + modify exact [eax] +long kmin(long,long); + +#pragma aux kmax =\ + "cmp eax, ebx",\ + "jg skipit",\ + "mov eax, ebx",\ + "skipit:",\ + parm nomemory [eax][ebx]\ + modify exact [eax] +long kmax(long,long); + +#pragma aux swapchar =\ + "mov cl, [eax]",\ + "mov ch, [ebx]",\ + "mov [ebx], cl",\ + "mov [eax], ch",\ + parm [eax][ebx]\ + modify exact [ecx] +long swapchar(void*,void*); + +#pragma aux swapshort =\ + "mov cx, [eax]",\ + "mov dx, [ebx]",\ + "mov [ebx], cx",\ + "mov [eax], dx",\ + parm [eax][ebx]\ + modify exact [ecx edx] +long swapshort(void*,void*); + +#pragma aux swaplong =\ + "mov ecx, [eax]",\ + "mov edx, [ebx]",\ + "mov [ebx], ecx",\ + "mov [eax], edx",\ + parm [eax][ebx]\ + modify exact [ecx edx] +long swaplong(void*,void*); + +#pragma aux swapbuf4 =\ + "begswap:",\ + "mov esi, [eax]",\ + "mov edi, [ebx]",\ + "mov [ebx], esi",\ + "mov [eax], edi",\ + "add eax, 4",\ + "add ebx, 4",\ + "dec ecx",\ + "jnz short begswap",\ + parm [eax][ebx][ecx]\ + modify exact [eax ebx ecx esi edi] +long swapbuf4(void*,void*,long); + +#pragma aux swap64bit =\ + "mov ecx, [eax]",\ + "mov edx, [ebx]",\ + "mov [ebx], ecx",\ + "mov ecx, [eax+4]",\ + "mov [eax], edx",\ + "mov edx, [ebx+4]",\ + "mov [ebx+4], ecx",\ + "mov [eax+4], edx",\ + parm [eax][ebx]\ + modify exact [ecx edx] +long swap64bit(void*,void*); + + //swapchar2(ptr1,ptr2,xsiz); is the same as: + //swapchar(ptr1,ptr2); swapchar(ptr1+1,ptr2+xsiz); +#pragma aux swapchar2 =\ + "add esi, ebx",\ + "mov cx, [eax]",\ + "mov dl, [ebx]",\ + "mov [ebx], cl",\ + "mov dh, [esi]",\ + "mov [esi], ch",\ + "mov [eax], dx",\ + parm [eax][ebx][esi]\ + modify exact [ecx edx esi] +long swapchar2(void*,void*,long); +//}}} + +#elif defined(_MSC_VER) // __WATCOMC__ + +// +// Microsoft C inline assembler +// + +//{{{ +static __inline long sqr(long a) +{ + _asm mov eax, a + _asm imul eax, eax +} + +static __inline long scale(long a, long d, long c) +{ + _asm mov eax, a + _asm imul d + _asm idiv c +} + +static __inline long mulscale(long a, long d, long c) +{ + _asm mov ecx, c + _asm mov eax, a + _asm imul d + _asm shrd eax, edx, cl +} + +#define MULSCALE(x) \ +static __inline long mulscale##x (long a, long d) \ +{ \ + _asm mov eax, a \ + _asm imul d \ + _asm shrd eax, edx, x \ +} + +MULSCALE(1) MULSCALE(2) MULSCALE(3) MULSCALE(4) +MULSCALE(5) MULSCALE(6) MULSCALE(7) MULSCALE(8) +MULSCALE(9) MULSCALE(10) MULSCALE(11) MULSCALE(12) +MULSCALE(13) MULSCALE(14) MULSCALE(15) MULSCALE(16) +MULSCALE(17) MULSCALE(18) MULSCALE(19) MULSCALE(20) +MULSCALE(21) MULSCALE(22) MULSCALE(23) MULSCALE(24) +MULSCALE(25) MULSCALE(26) MULSCALE(27) MULSCALE(28) +MULSCALE(29) MULSCALE(30) MULSCALE(31) +#undef MULSCALE +static __inline long mulscale32(long a, long d) +{ + _asm mov eax, a + _asm imul d + _asm mov eax, edx +} + +static __inline long dmulscale(long a, long d, long S, long D, long c) +{ + _asm mov ecx, c + _asm mov eax, a + _asm imul d + _asm mov ebx, eax + _asm mov eax, S + _asm mov esi, edx + _asm imul D + _asm add eax, ebx + _asm adc edx, esi + _asm shrd eax, edx, cl +} + +#define DMULSCALE(x) \ +static __inline long dmulscale##x (long a, long d, long S, long D) \ +{ \ + _asm mov eax, a \ + _asm imul d \ + _asm mov ebx, eax \ + _asm mov eax, S \ + _asm mov esi, edx \ + _asm imul D \ + _asm add eax, ebx \ + _asm adc edx, esi \ + _asm shrd eax, edx, x \ +} + +DMULSCALE(1) DMULSCALE(2) DMULSCALE(3) DMULSCALE(4) +DMULSCALE(5) DMULSCALE(6) DMULSCALE(7) DMULSCALE(8) +DMULSCALE(9) DMULSCALE(10) DMULSCALE(11) DMULSCALE(12) +DMULSCALE(13) DMULSCALE(14) DMULSCALE(15) DMULSCALE(16) +DMULSCALE(17) DMULSCALE(18) DMULSCALE(19) DMULSCALE(20) +DMULSCALE(21) DMULSCALE(22) DMULSCALE(23) DMULSCALE(24) +DMULSCALE(25) DMULSCALE(26) DMULSCALE(27) DMULSCALE(28) +DMULSCALE(29) DMULSCALE(30) DMULSCALE(31) +#undef DMULSCALE +static __inline long dmulscale32(long a, long d, long S, long D) +{ + _asm mov eax, a + _asm imul d + _asm mov ebx, eax + _asm mov eax, S + _asm mov esi, edx + _asm imul D + _asm add eax, ebx + _asm adc edx, esi + _asm mov eax, edx +} + +#define TMULSCALE(x) \ +static __inline long tmulscale##x (long a, long d, long b, long c, long S, long D) \ +{ \ + _asm mov eax, a \ + _asm mov ebx, b \ + _asm imul d \ + _asm xchg eax, ebx \ + _asm mov ecx, c \ + _asm xchg edx, ecx \ + _asm imul edx \ + _asm add ebx, eax \ + _asm adc ecx, edx \ + _asm mov eax, S \ + _asm imul D \ + _asm add eax, ebx \ + _asm adc edx, ecx \ +} + +TMULSCALE(1) TMULSCALE(2) TMULSCALE(3) TMULSCALE(4) +TMULSCALE(5) TMULSCALE(6) TMULSCALE(7) TMULSCALE(8) +TMULSCALE(9) TMULSCALE(10) TMULSCALE(11) TMULSCALE(12) +TMULSCALE(13) TMULSCALE(14) TMULSCALE(15) TMULSCALE(16) +TMULSCALE(17) TMULSCALE(18) TMULSCALE(19) TMULSCALE(20) +TMULSCALE(21) TMULSCALE(22) TMULSCALE(23) TMULSCALE(24) +TMULSCALE(25) TMULSCALE(26) TMULSCALE(27) TMULSCALE(28) +TMULSCALE(29) TMULSCALE(30) TMULSCALE(31) +#undef TMULSCALE +static __inline long tmulscale32(long a, long d, long b, long c, long S, long D) +{ + _asm mov eax, a + _asm mov ebx, b + _asm imul d + _asm xchg eax, ebx + _asm mov ecx, c + _asm xchg edx, ecx + _asm imul edx + _asm add ebx, eax + _asm adc ecx, edx + _asm mov eax, S + _asm imul D + _asm add eax, ebx + _asm adc edx, ecx + _asm mov eax, edx +} + +static __inline long boundmulscale(long a, long b, long c) +{ + _asm mov eax, a + _asm mov ecx, c + _asm imul b + _asm mov ebx, edx + _asm shrd eax, edx, cl + _asm sar edx, cl + _asm xor edx, eax + _asm js checkit + _asm xor edx, eax + _asm jz skipboundit + _asm cmp edx, 0xffffffff + _asm je skipboundit + checkit: + _asm mov eax, ebx + _asm sar eax, 31 + _asm xor eax, 0x7fffffff + skipboundit: + ; +} + +static __inline long divscale(long a, long b, long c) +{ + _asm mov eax, a + _asm mov ecx, c + _asm mov edx, eax + _asm shl eax, cl + _asm neg cl + _asm sar edx, cl + _asm idiv b +} + +static __inline long divscale1(long a, long b) +{ + _asm mov eax, a + _asm add eax, eax + _asm sbb edx, edx + _asm idiv b +} + +static __inline long divscale2(long a, long b) +{ + _asm mov eax, a + _asm mov edx, eax + _asm sar edx, 30 + _asm lea eax, [eax*4] + _asm idiv b +} + +static __inline long divscale3(long a, long b) +{ + _asm mov eax, a + _asm mov edx, eax + _asm sar edx, 29 + _asm lea eax, [eax*8] + _asm idiv b +} + +#define DIVSCALE(x,y) \ +static __inline long divscale##y(long a, long b) \ +{ \ + _asm mov eax, a \ + _asm mov edx, eax \ + _asm sar edx, x \ + _asm shl eax, y \ + _asm idiv b \ +} + +DIVSCALE(28,4) DIVSCALE(27,5) DIVSCALE(26,6) DIVSCALE(25,7) +DIVSCALE(24,8) DIVSCALE(23,9) DIVSCALE(22,10) DIVSCALE(21,11) +DIVSCALE(20,12) DIVSCALE(19,13) DIVSCALE(18,14) DIVSCALE(17,15) +DIVSCALE(16,16) DIVSCALE(15,17) DIVSCALE(14,18) DIVSCALE(13,19) +DIVSCALE(12,20) DIVSCALE(11,21) DIVSCALE(10,22) DIVSCALE(9,23) +DIVSCALE(8,24) DIVSCALE(7,25) DIVSCALE(6,26) DIVSCALE(5,27) +DIVSCALE(4,28) DIVSCALE(3,29) DIVSCALE(2,30) DIVSCALE(1,31) + +static __inline long divscale32(long d, long b) +{ + _asm mov edx, d + _asm xor eax, eax + _asm idiv b +} + +static __inline char readpixel(void *d) +{ + _asm mov edx, d + _asm mov al, byte ptr [edx] +} + +static __inline void drawpixel(void *d, char a) +{ + _asm mov edx, d + _asm mov al, a + _asm mov byte ptr [edx], al +} + +static __inline void drawpixels(void *d, short a) +{ + _asm mov edx, d + _asm mov ax, a + _asm mov word ptr [edx], ax +} + +static __inline void drawpixelses(void *d, long a) +{ + _asm mov edx, d + _asm mov eax, a + _asm mov dword ptr [edx], eax +} + +static __inline void clearbuf(void *d, long c, long a) +{ + _asm mov edi, d + _asm mov ecx, c + _asm mov eax, a + _asm rep stosd +} + +static __inline void clearbufbyte(void *d, long c, long a) +{ + _asm mov edi, d + _asm mov ecx, c + _asm mov eax, a + _asm { + cmp ecx, 4 + jae longcopy + test cl, 1 + jz preskip + stosb + } + preskip: + _asm { + shr ecx, 1 + rep stosw + jmp endit + } + longcopy: + _asm { + test edi, 1 + jz skip1 + stosb + dec ecx + } + skip1: + _asm { + test edi, 2 + jz skip2 + stosw + sub ecx, 2 + } + skip2: + _asm { + mov ebx, ecx + shr ecx, 2 + rep stosd + test bl, 2 + jz skip3 + stosw + } + skip3: + _asm { + test bl, 1 + jz endit + stosb + } + endit: + ; +} + +static __inline void copybuf(void *s, void *d, long c) +{ + _asm mov esi, s + _asm mov edi, d + _asm mov ecx, c + _asm rep movsd +} + +static __inline void copybufbyte(void *s, void *d, long c) +{ + _asm mov esi, s + _asm mov edi, d + _asm mov ecx, c + _asm { + cmp ecx, 4 + jae longcopy + test cl, 1 + jz preskip + movsb + } + preskip: + _asm { + shr ecx, 1 + rep movsw + jmp endit + } + longcopy: + _asm { + test edi, 1 + jz skip1 + movsb + dec ecx + } + skip1: + _asm { + test edi, 2 + jz skip2 + movsw + sub ecx, 2 + } + skip2: + _asm { + mov ebx, ecx + shr ecx, 2 + rep movsd + test bl, 2 + jz skip3 + movsw + } + skip3: + _asm { + test bl, 1 + jz endit + movsb + } + endit: + ; +} + +static __inline void copybufreverse(void *s, void *d, long c) +{ + _asm mov esi, s + _asm mov edi, d + _asm mov ecx, c + _asm { + shr ecx, 1 + jnc skipit1 + mov al, byte ptr [esi] + dec esi + mov byte ptr [edi], al + inc edi + } + skipit1: + _asm { + shr ecx, 1 + jnc skipit2 + mov ax, word ptr [esi-1] + sub esi, 2 + ror ax, 8 + mov word ptr [edi], ax + add edi, 2 + } + skipit2: + _asm { + test ecx, ecx + jz endloop + } + begloop: + _asm { + mov eax, dword ptr [esi-3] + sub esi, 4 + bswap eax + mov dword ptr [edi], eax + add edi, 4 + dec ecx + jnz begloop + } + endloop: + ; +} + +static __inline void qinterpolatedown16(long a, long c, long d, long s) +{ + _asm mov eax, a + _asm mov ecx, c + _asm mov edx, d + _asm mov esi, s + _asm { + mov ebx, ecx + shr ecx, 1 + jz skipbegcalc + } + begqcalc: + _asm { + lea edi, [edx+esi] + sar edx, 16 + mov dword ptr [eax], edx + lea edx, [edi+esi] + sar edi, 16 + mov dword ptr [eax+4], edi + add eax, 8 + dec ecx + jnz begqcalc + test ebx, 1 + jz skipbegqcalc2 + } + skipbegcalc: + _asm { + sar edx, 16 + mov dword ptr [eax], edx + } + skipbegqcalc2: + ; +} + +static __inline void qinterpolatedown16short(long a, long c, long d, long s) +{ + _asm mov eax, a + _asm mov ecx, c + _asm mov edx, d + _asm mov esi, s + _asm { + test ecx, ecx + jz endit + test al, 2 + jz skipalignit + mov ebx, edx + sar ebx, 16 + mov word ptr [eax], bx + add edx, esi + add eax, 2 + dec ecx + jz endit + } + skipalignit: + _asm { + sub ecx, 2 + jc finishit + } + begqcalc: + _asm { + mov ebx, edx + add edx, esi + sar ebx, 16 + mov edi, edx + and edi, 0ffff0000h + add edx, esi + add ebx, edi + mov dword ptr [eax], ebx + add eax, 4 + sub ecx, 2 + jnc begqcalc + test cl, 1 + jz endit + } + finishit: + _asm { + mov ebx, edx + sar ebx, 16 + mov word ptr [eax], bx + } + endit: + ; +} + +static __inline long mul3(long a) +{ + _asm mov eax, a + _asm lea eax, [eax+eax*2] +} + +static __inline long mul5(long a) +{ + _asm mov eax, a + _asm lea eax, [eax+eax*4] +} + +static __inline long mul9(long a) +{ + _asm mov eax, a + _asm lea eax, [eax+eax*8] +} + + //returns eax/ebx, dmval = eax%edx; +static __inline long divmod(long a, long b) +{ + _asm mov eax, a + _asm xor edx, edx + _asm div b + _asm mov dmval, edx +} + + //returns eax%ebx, dmval = eax/edx; +static __inline long moddiv(long a, long b) +{ + _asm mov eax, a + _asm xor edx, edx + _asm div b + _asm mov dmval, eax + _asm mov eax, edx +} + +static __inline long klabs(long a) +{ + _asm mov eax, a + _asm test eax, eax + _asm jns skipnegate + _asm neg eax + skipnegate: + ; +} + +static __inline long ksgn(long b) +{ + _asm mov ebx, b + _asm add ebx, ebx + _asm sbb eax, eax + _asm cmp eax, ebx + _asm adc al, 0 +} + + //eax = (unsigned min)umin(eax,ebx) +static __inline long umin(long a, long b) +{ + _asm mov eax, a + _asm sub eax, b + _asm sbb ecx, ecx + _asm and eax, ecx + _asm add eax, b +} + + //eax = (unsigned max)umax(eax,ebx) +static __inline long umax(long a, long b) +{ + _asm mov eax, a + _asm sub eax, b + _asm sbb ecx, ecx + _asm xor ecx, 0xffffffff + _asm and eax, ecx + _asm add eax, b +} + +static __inline long kmin(long a, long b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm cmp eax, ebx + _asm jl skipit + _asm mov eax, ebx + skipit: + ; +} + +static __inline long kmax(long a, long b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm cmp eax, ebx + _asm jg skipit + _asm mov eax, ebx + skipit: + ; +} + +static __inline void swapchar(void *a, void *b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov cl, [eax] + _asm mov ch, [ebx] + _asm mov [ebx], cl + _asm mov [eax], ch +} + +static __inline void swapshort(void *a, void *b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov cx, [eax] + _asm mov dx, [ebx] + _asm mov [ebx], cx + _asm mov [eax], dx +} + +static __inline void swaplong(void *a, void *b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov ecx, [eax] + _asm mov edx, [ebx] + _asm mov [ebx], ecx + _asm mov [eax], edx +} + +static __inline void swapbuf4(void *a, void *b, long c) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov ecx, c + begswap: + _asm { + mov esi, [eax] + mov edi, [ebx] + mov [ebx], esi + mov [eax], edi + add eax, 4 + add ebx, 4 + dec ecx + jnz short begswap + } +} + +static __inline void swap64bit(void *a, void *b) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov ecx, [eax] + _asm mov edx, [ebx] + _asm mov [ebx], ecx + _asm mov ecx, [eax+4] + _asm mov [eax], edx + _asm mov edx, [ebx+4] + _asm mov [ebx+4], ecx + _asm mov [eax+4], edx +} + + //swapchar2(ptr1,ptr2,xsiz); is the same as: + //swapchar(ptr1,ptr2); swapchar(ptr1+1,ptr2+xsiz); +static __inline void swapchar2(void *a, void *b, long s) +{ + _asm mov eax, a + _asm mov ebx, b + _asm mov esi, s + _asm add esi, ebx + _asm mov cx, [eax] + _asm mov dl, [ebx] + _asm mov [ebx], cl + _asm mov dh, [esi] + _asm mov [esi], ch + _asm mov [eax], dx +} +//}}} + +#else // _MSC_VER + +#error Unsupported compiler or architecture. + +#endif + +#endif // __pragmas_h__ + diff --git a/polymer/build/include/scriptfile.h b/polymer/build/include/scriptfile.h new file mode 100644 index 000000000..01557f2f6 --- /dev/null +++ b/polymer/build/include/scriptfile.h @@ -0,0 +1,26 @@ +typedef struct { + char *textbuf; + unsigned int textlength; + char *ltextptr; // pointer to start of the last token fetched (use this for line numbers) + char *textptr; + char *eof; + char *filename; + int linenum; + long *lineoffs; +} scriptfile; + +char *scriptfile_gettoken(scriptfile *sf); +int scriptfile_getnumber(scriptfile *sf, int *num); +int scriptfile_getdouble(scriptfile *sf, double *num); +int scriptfile_getstring(scriptfile *sf, char **st); +int scriptfile_getsymbol(scriptfile *sf, int *num); +int scriptfile_getlinum(scriptfile *sf, char *ptr); +int scriptfile_getbraces(scriptfile *sf, char **braceend); + +scriptfile *scriptfile_fromfile(char *fn); +scriptfile *scriptfile_fromstring(char *string); +void scriptfile_close(scriptfile *sf); + +int scriptfile_getsymbolvalue(char *name, int *val); +int scriptfile_addsymbolvalue(char *name, int val); +void scriptfile_clearsymbols(void); diff --git a/polymer/build/include/sdlayer.h b/polymer/build/include/sdlayer.h new file mode 100644 index 000000000..85d637b8d --- /dev/null +++ b/polymer/build/include/sdlayer.h @@ -0,0 +1,21 @@ +// SDL interface layer +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __build_interface_layer__ +#define __build_interface_layer__ SDL + +#include "baselayer.h" + +struct sdlappicon { + int width,height; + unsigned int *pixels; + unsigned char *mask; +}; + +#else +#if (__build_interface_layer__ != SDL) +#error "Already using the " __build_interface_layer__ ". Can't now use SDL." +#endif +#endif // __build_interface_layer__ + diff --git a/polymer/build/include/tmp/buildsound.h b/polymer/build/include/tmp/buildsound.h new file mode 100644 index 000000000..c85922bc4 --- /dev/null +++ b/polymer/build/include/tmp/buildsound.h @@ -0,0 +1,15 @@ + +typedef struct { + unsigned long samplerate; // sample rate of the sound + unsigned short channels; // number of channels + unsigned short bitspersample; // bits per sample + unsigned short format; // 0 = pcm + unsigned long soundlength; // bytes required for sound storage +} SoundInfo; + + +int ReadVOCInfo(int fh, SoundInfo *snd); +int ReadVOCData(int fh, char *data, int bufferlen); + +int ReadWAVInfo(int fh, SoundInfo *snd); +int ReadWAVData(int fh, char *data, int bufferlen); diff --git a/polymer/build/include/tmp/pragmas-functions.h b/polymer/build/include/tmp/pragmas-functions.h new file mode 100644 index 000000000..185c60dfe --- /dev/null +++ b/polymer/build/include/tmp/pragmas-functions.h @@ -0,0 +1,159 @@ +#ifdef USE_C_FUNCTION_PRAGMAS +long sqr(long a); +long scale(long a, long d, long c); +long mulscale(long a, long d, long c); +long mulscale1(long a, long d); +long mulscale2(long a, long d); +long mulscale3(long a, long d); +long mulscale4(long a, long d); +long mulscale5(long a, long d); +long mulscale6(long a, long d); +long mulscale7(long a, long d); +long mulscale8(long a, long d); +long mulscale9(long a, long d); +long mulscale10(long a, long d); +long mulscale11(long a, long d); +long mulscale12(long a, long d); +long mulscale13(long a, long d); +long mulscale14(long a, long d); +long mulscale15(long a, long d); +long mulscale16(long a, long d); +long mulscale17(long a, long d); +long mulscale18(long a, long d); +long mulscale19(long a, long d); +long mulscale20(long a, long d); +long mulscale21(long a, long d); +long mulscale22(long a, long d); +long mulscale23(long a, long d); +long mulscale24(long a, long d); +long mulscale25(long a, long d); +long mulscale26(long a, long d); +long mulscale27(long a, long d); +long mulscale28(long a, long d); +long mulscale29(long a, long d); +long mulscale30(long a, long d); +long mulscale31(long a, long d); +long mulscale32(long a, long d); +long dmulscale(long a, long d, long S, long D, long c); +long dmulscale1(long a, long d, long S, long D); +long dmulscale2(long a, long d, long S, long D); +long dmulscale3(long a, long d, long S, long D); +long dmulscale4(long a, long d, long S, long D); +long dmulscale5(long a, long d, long S, long D); +long dmulscale6(long a, long d, long S, long D); +long dmulscale7(long a, long d, long S, long D); +long dmulscale8(long a, long d, long S, long D); +long dmulscale9(long a, long d, long S, long D); +long dmulscale10(long a, long d, long S, long D); +long dmulscale11(long a, long d, long S, long D); +long dmulscale12(long a, long d, long S, long D); +long dmulscale13(long a, long d, long S, long D); +long dmulscale14(long a, long d, long S, long D); +long dmulscale15(long a, long d, long S, long D); +long dmulscale16(long a, long d, long S, long D); +long dmulscale17(long a, long d, long S, long D); +long dmulscale18(long a, long d, long S, long D); +long dmulscale19(long a, long d, long S, long D); +long dmulscale20(long a, long d, long S, long D); +long dmulscale21(long a, long d, long S, long D); +long dmulscale22(long a, long d, long S, long D); +long dmulscale23(long a, long d, long S, long D); +long dmulscale24(long a, long d, long S, long D); +long dmulscale25(long a, long d, long S, long D); +long dmulscale26(long a, long d, long S, long D); +long dmulscale27(long a, long d, long S, long D); +long dmulscale28(long a, long d, long S, long D); +long dmulscale29(long a, long d, long S, long D); +long dmulscale30(long a, long d, long S, long D); +long dmulscale31(long a, long d, long S, long D); +long dmulscale32(long a, long d, long S, long D); +long tmulscale1(long a, long d, long b, long c, long S, long D); +long tmulscale2(long a, long d, long b, long c, long S, long D); +long tmulscale3(long a, long d, long b, long c, long S, long D); +long tmulscale4(long a, long d, long b, long c, long S, long D); +long tmulscale5(long a, long d, long b, long c, long S, long D); +long tmulscale6(long a, long d, long b, long c, long S, long D); +long tmulscale7(long a, long d, long b, long c, long S, long D); +long tmulscale8(long a, long d, long b, long c, long S, long D); +long tmulscale9(long a, long d, long b, long c, long S, long D); +long tmulscale10(long a, long d, long b, long c, long S, long D); +long tmulscale11(long a, long d, long b, long c, long S, long D); +long tmulscale12(long a, long d, long b, long c, long S, long D); +long tmulscale13(long a, long d, long b, long c, long S, long D); +long tmulscale14(long a, long d, long b, long c, long S, long D); +long tmulscale15(long a, long d, long b, long c, long S, long D); +long tmulscale16(long a, long d, long b, long c, long S, long D); +long tmulscale17(long a, long d, long b, long c, long S, long D); +long tmulscale18(long a, long d, long b, long c, long S, long D); +long tmulscale19(long a, long d, long b, long c, long S, long D); +long tmulscale20(long a, long d, long b, long c, long S, long D); +long tmulscale21(long a, long d, long b, long c, long S, long D); +long tmulscale22(long a, long d, long b, long c, long S, long D); +long tmulscale23(long a, long d, long b, long c, long S, long D); +long tmulscale24(long a, long d, long b, long c, long S, long D); +long tmulscale25(long a, long d, long b, long c, long S, long D); +long tmulscale26(long a, long d, long b, long c, long S, long D); +long tmulscale27(long a, long d, long b, long c, long S, long D); +long tmulscale28(long a, long d, long b, long c, long S, long D); +long tmulscale29(long a, long d, long b, long c, long S, long D); +long tmulscale30(long a, long d, long b, long c, long S, long D); +long tmulscale31(long a, long d, long b, long c, long S, long D); +long tmulscale32(long a, long d, long b, long c, long S, long D); +long divscale(long a, long b, long c); +long divscale1(long a, long b); +long divscale2(long a, long b); +long divscale3(long a, long b); +long divscale4(long a, long b); +long divscale5(long a, long b); +long divscale6(long a, long b); +long divscale7(long a, long b); +long divscale8(long a, long b); +long divscale9(long a, long b); +long divscale10(long a, long b); +long divscale11(long a, long b); +long divscale12(long a, long b); +long divscale13(long a, long b); +long divscale14(long a, long b); +long divscale15(long a, long b); +long divscale16(long a, long b); +long divscale17(long a, long b); +long divscale18(long a, long b); +long divscale19(long a, long b); +long divscale20(long a, long b); +long divscale21(long a, long b); +long divscale22(long a, long b); +long divscale23(long a, long b); +long divscale24(long a, long b); +long divscale25(long a, long b); +long divscale26(long a, long b); +long divscale27(long a, long b); +long divscale28(long a, long b); +long divscale29(long a, long b); +long divscale30(long a, long b); +long divscale31(long a, long b); +long divscale32(long d, long b); +long readpixel(void *D); +void drawpixel(void *D, long a); +void drawpixels(void *D, long a); +void drawpixelses(void *D, long a); +void clearbuf(void* D, long c, long a); +void copybuf(void *S, void *D, long c); +long mul3(long a); +long mul5(long a); +long mul9(long a); +long divmod(long a, long b); +long moddiv(long a, long b); +long klabs(long a); +long ksgn(long b); +long umin(long a, long b); +long umax(long a, long b); +long kmin(long a, long b); +long kmax(long a, long b); +void swapchar(void *a, void *b); +void swapshort(void *a, void *b); +void swaplong(void *a, void *b); +void swapbuf4(void *a, void *b, long c); +void swap64bit(void *a, void *b); +void swapchar2(void *a, void *b, long S); +#endif + diff --git a/polymer/build/include/winlayer.h b/polymer/build/include/winlayer.h new file mode 100644 index 000000000..415b4f74c --- /dev/null +++ b/polymer/build/include/winlayer.h @@ -0,0 +1,54 @@ +// Windows DIB/DirectDraw interface layer +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) + +#ifndef __build_interface_layer__ +#define __build_interface_layer__ WIN + +extern int backgroundidle; // set to 1 to tell winlayer to go to idle priority when inactive +extern unsigned maxrefreshfreq; + +extern int glusecds; + +long win_gethwnd(void); +long win_gethinstance(void); + +// resource ids +#define WIN_STARTWIN 1000 +#define WIN_STARTWIN_ITEMBITMAP 100 // banner bitmap +#define WIN_STARTWIN_ITEMTEXT 101 // text header +#define WIN_STARTWIN_ITEMLIST 102 // output list box +#define WIN_STARTWINBMP 200 + + // *hwnd - receives the window handle to the startup dialog box + // saferect[] - receives the safe area to draw controls over (l,t,w,h) + // onclose - called before the startup window closes + // returns 0 if successful, 1 if the window isn't open +int win_getstartupwin(long *hwnd, long saferect[4], void (*onclose)(void)); +int win_getstartupcommand(void); + +void win_allowtaskswitching(int onf); +int win_checkinstance(void); + +/* +#ifdef KENBUILD +#define DISCLAIMER "IMPORTANT:\n" \ + "\tThis is a source port by Jonathon Fowler (jonof@edgenetwk.com) of the Build Engine, " \ + "editor and test game by Ken Silverman to the Windows and Linux operating systems. It is " \ + "distributed under the terms listed in BUILDLIC.TXT included with this package." +#endif +#ifdef DUKE3D +#define DISCLAIMER "IMPORTANT:\n" \ + "\tThis port of Duke Nukem 3D was done by Jonathon Fowler (jonof@edgenetwk.com) and is not " \ + "endorsed or supported by 3D Realms or Apogee. They will not provide support for it. Visit " \ + "http://jonof.edgenetwk.com/buildport/duke3d/ for details." +#endif +*/ +#include "baselayer.h" + +#else +#if (__build_interface_layer__ != WIN) +#error "Already using the " __build_interface_layer__ ". Can't now use Windows." +#endif +#endif // __build_interface_layer__ + diff --git a/polymer/build/makegnu.bat b/polymer/build/makegnu.bat new file mode 100644 index 000000000..027d85aa6 --- /dev/null +++ b/polymer/build/makegnu.bat @@ -0,0 +1 @@ +make -f Makefile %1 %2 %3 %4 %5 diff --git a/polymer/build/makemsc.bat b/polymer/build/makemsc.bat new file mode 100644 index 000000000..19243ed20 --- /dev/null +++ b/polymer/build/makemsc.bat @@ -0,0 +1 @@ +nmake /f Makefile.msvc %1 %2 %3 %4 %5 diff --git a/polymer/build/makew.bat b/polymer/build/makew.bat new file mode 100644 index 000000000..7184b0f08 --- /dev/null +++ b/polymer/build/makew.bat @@ -0,0 +1 @@ +wmake -f Makefile.watcom %1 %2 %3 %4 %5 diff --git a/polymer/build/obj.gnu/keep.me b/polymer/build/obj.gnu/keep.me new file mode 100644 index 000000000..e69de29bb diff --git a/polymer/build/obj.msc/keep.me b/polymer/build/obj.msc/keep.me new file mode 100644 index 000000000..e69de29bb diff --git a/polymer/build/obj.watcom/keep.me b/polymer/build/obj.watcom/keep.me new file mode 100644 index 000000000..e69de29bb diff --git a/polymer/build/osx/engine/engine.xcode/project.pbxproj b/polymer/build/osx/engine/engine.xcode/project.pbxproj new file mode 100644 index 000000000..444e8d545 --- /dev/null +++ b/polymer/build/osx/engine/engine.xcode/project.pbxproj @@ -0,0 +1,1539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + AB2B5C7308E6979600899067 = { + buildPhases = ( + AB2B5C7408E6979600899067, + AB2B5C7508E6979600899067, + AB2B5C8408E6979600899067, + AB2B5C9608E6979600899067, + ); + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = "SETSPRITEZ SUPERBUILD POLYMOST USE_OPENGL USE_A_C NOASM RENDERTYPESDL=1 KSFORBUILD WITHKPLIB"; + HEADER_SEARCH_PATHS = "../../include ../../src"; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = enginez; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wno-four-char-constants -Wno-unknown-pragmas -Wno-char-subscripts"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = enginez; + productName = engine; + productReference = AB2B5C9708E6979600899067; + productType = "com.apple.product-type.library.static"; + }; + AB2B5C7408E6979600899067 = { + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + isa = PBXShellScriptBuildPhase; + outputPaths = ( + engineinfo.c, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "source writeengineinfo.sh"; + }; + AB2B5C7508E6979600899067 = { + buildActionMask = 2147483647; + files = ( + AB2B5C7608E6979600899067, + AB2B5C7708E6979600899067, + AB2B5C7808E6979600899067, + AB2B5C7908E6979600899067, + AB2B5C7A08E6979600899067, + AB2B5C7B08E6979600899067, + AB2B5C7C08E6979600899067, + AB2B5C7D08E6979600899067, + AB2B5C7E08E6979600899067, + AB2B5C7F08E6979600899067, + AB2B5C8008E6979600899067, + AB2B5C8108E6979600899067, + AB2B5C8208E6979600899067, + AB2B5C8308E6979600899067, + AB8F394909545F3800B9F541, + ABD656410967A52B0066981D, + AB6F05A20983A54D00B8EBA0, + AB6F05AF0983A5DD00B8EBA0, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB2B5C7608E6979600899067 = { + fileRef = AB3AFE9308DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C7708E6979600899067 = { + fileRef = AB3AFE9408DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7808E6979600899067 = { + fileRef = AB3AFE9508DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7908E6979600899067 = { + fileRef = AB3AFE9608DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7A08E6979600899067 = { + fileRef = AB3AFE9708DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7B08E6979600899067 = { + fileRef = AB3AFE9808DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7C08E6979600899067 = { + fileRef = AB3AFE9908DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7D08E6979600899067 = { + fileRef = AB3AFE9A08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7E08E6979600899067 = { + fileRef = AB3AFE9B08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C7F08E6979600899067 = { + fileRef = AB3AFE9C08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C8008E6979600899067 = { + fileRef = AB3AFE9D08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C8108E6979600899067 = { + fileRef = AB3AFE9E08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C8208E6979600899067 = { + fileRef = AB3AFE9F08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C8308E6979600899067 = { + fileRef = AB3AFEA008DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB2B5C8408E6979600899067 = { + buildActionMask = 2147483647; + files = ( + AB2B5C8508E6979600899067, + AB2B5C8608E6979600899067, + AB2B5C8708E6979600899067, + AB2B5C8808E6979600899067, + AB2B5C8908E6979600899067, + AB2B5C8A08E6979600899067, + AB2B5C8B08E6979600899067, + AB2B5C8C08E6979600899067, + AB2B5C8D08E6979600899067, + AB2B5C8E08E6979600899067, + AB2B5C8F08E6979600899067, + AB2B5C9008E6979600899067, + AB2B5C9108E6979600899067, + AB2B5C9208E6979600899067, + AB2B5C9308E6979600899067, + AB2B5D4708E69D9000899067, + AB8F394609545F2600B9F541, + ABD6563A0967A4FA0066981D, + AB6F059E0983A53200B8EBA0, + AB6F059F0983A53200B8EBA0, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB2B5C8508E6979600899067 = { + fileRef = AB3AF5F908DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8608E6979600899067 = { + fileRef = AB3AF5FA08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8708E6979600899067 = { + fileRef = AB3AF5FB08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8808E6979600899067 = { + fileRef = AB3AF5FC08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8908E6979600899067 = { + fileRef = AB3AF5FD08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8A08E6979600899067 = { + fileRef = AB3AF5FE08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8B08E6979600899067 = { + fileRef = AB3AF5FF08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8C08E6979600899067 = { + fileRef = AB3AF60008DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8D08E6979600899067 = { + fileRef = AB3AF60308DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8E08E6979600899067 = { + fileRef = AB3AF60608DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C8F08E6979600899067 = { + fileRef = AB3AF60808DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C9008E6979600899067 = { + fileRef = AB3AF60908DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C9108E6979600899067 = { + fileRef = AB3AF60A08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C9208E6979600899067 = { + fileRef = AB3AF60508DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C9308E6979600899067 = { + fileRef = AB3AF9CE08DEE17600C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5C9608E6979600899067 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB2B5C9708E6979600899067 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libenginez.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB2B5D4508E69D9000899067 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = osxbits.m; + path = ../../src/osxbits.m; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB2B5D4608E69D9000899067 = { + fileRef = AB2B5D4508E69D9000899067; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5D4708E69D9000899067 = { + fileRef = AB2B5D4508E69D9000899067; + isa = PBXBuildFile; + settings = { + }; + }; + AB2B5D4808E69DB100899067 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = osxbits.h; + path = ../../include/osxbits.h; + refType = 4; + sourceTree = ""; + }; + AB3AF5E708DEDAA700C0AA42 = { + children = ( + AB3AF9D208DEE28200C0AA42, + AB3AF5F708DEDADD00C0AA42, + AB3AF62308DEDBBA00C0AA42, + AB3AF5F608DEDABE00C0AA42, + AB3AF9D008DEE1C400C0AA42, + ); + isa = PBXGroup; + refType = 4; + sourceTree = ""; + }; + AB3AF5E908DEDAA700C0AA42 = { + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_OPTIMIZATION_LEVEL = 0; + }; + isa = PBXBuildStyle; + name = Development; + }; + AB3AF5EA08DEDAA700C0AA42 = { + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = s; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + AB3AF5EB08DEDAA700C0AA42 = { + buildSettings = { + }; + buildStyles = ( + AB3AF5E908DEDAA700C0AA42, + AB3AF5EA08DEDAA700C0AA42, + ); + hasScannedForEncodings = 0; + isa = PBXProject; + mainGroup = AB3AF5E708DEDAA700C0AA42; + productRefGroup = AB3AF5F608DEDABE00C0AA42; + projectDirPath = ""; + targets = ( + AB3AFBF408DF03EE00C0AA42, + AB3AF5F408DEDABE00C0AA42, + AB3AF9DD08DEE2CF00C0AA42, + AB2B5C7308E6979600899067, + ); + }; + AB3AF5F108DEDABE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFEA108DF044D00C0AA42, + AB3AFEA208DF044D00C0AA42, + AB3AFEA308DF044D00C0AA42, + AB3AFEA408DF044D00C0AA42, + AB3AFEA508DF044D00C0AA42, + AB3AFEA608DF044D00C0AA42, + AB3AFEA708DF044D00C0AA42, + AB3AFEA808DF044D00C0AA42, + AB3AFEA908DF044D00C0AA42, + AB3AFEAA08DF044D00C0AA42, + AB3AFEAB08DF044D00C0AA42, + AB3AFEAC08DF044D00C0AA42, + AB3AFEAD08DF044D00C0AA42, + AB3AFEAE08DF044D00C0AA42, + AB8F394809545F3800B9F541, + ABD656400967A52B0066981D, + AB6F05A10983A54D00B8EBA0, + AB6F05AE0983A5DD00B8EBA0, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF5F208DEDABE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AF60D08DEDB3100C0AA42, + AB3AF60E08DEDB3100C0AA42, + AB3AF60F08DEDB3100C0AA42, + AB3AF61008DEDB3100C0AA42, + AB3AF61108DEDB3100C0AA42, + AB3AF61208DEDB3100C0AA42, + AB3AF61308DEDB3100C0AA42, + AB3AF61408DEDB3100C0AA42, + AB3AF61708DEDB3100C0AA42, + AB3AF61A08DEDB3100C0AA42, + AB3AF61C08DEDB3100C0AA42, + AB3AF61D08DEDB3100C0AA42, + AB3AF61E08DEDB3100C0AA42, + AB3AF62108DEDB4F00C0AA42, + AB3AF9CF08DEE17600C0AA42, + AB2B5D4608E69D9000899067, + AB8F394509545F2600B9F541, + ABD656390967A4FA0066981D, + AB6F059C0983A53200B8EBA0, + AB6F059D0983A53200B8EBA0, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF5F308DEDABE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF5F408DEDABE00C0AA42 = { + buildPhases = ( + AB3AF9CC08DEE11200C0AA42, + AB3AF5F108DEDABE00C0AA42, + AB3AF5F208DEDABE00C0AA42, + AB3AF5F308DEDABE00C0AA42, + ); + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = "SUPERBUILD POLYMOST USE_OPENGL USE_A_C NOASM RENDERTYPESDL=1 KSFORBUILD WITHKPLIB"; + HEADER_SEARCH_PATHS = "../../include ../../src"; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = engine; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wno-four-char-constants -Wno-unknown-pragmas -Wno-char-subscripts"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = engine; + productName = engine; + productReference = AB3AF5F508DEDABE00C0AA42; + productType = "com.apple.product-type.library.static"; + }; + AB3AF5F508DEDABE00C0AA42 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libengine.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AF5F608DEDABE00C0AA42 = { + children = ( + AB3AF5F508DEDABE00C0AA42, + AB3AF9DE08DEE2CF00C0AA42, + AB2B5C9708E6979600899067, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + AB3AF5F708DEDADD00C0AA42 = { + children = ( + AB3AFEAF08DF046600C0AA42, + AB3AF5F808DEDAEB00C0AA42, + ); + isa = PBXGroup; + name = Engine; + refType = 4; + sourceTree = ""; + }; + AB3AF5F808DEDAEB00C0AA42 = { + children = ( + AB8F394409545F2600B9F541, + AB3AF62208DEDB5700C0AA42, + AB3AF5F908DEDB3100C0AA42, + AB3AF5FA08DEDB3100C0AA42, + AB3AF5FB08DEDB3100C0AA42, + AB3AF5FC08DEDB3100C0AA42, + AB3AF5FD08DEDB3100C0AA42, + AB3AF5FE08DEDB3100C0AA42, + AB3AF5FF08DEDB3100C0AA42, + AB3AF9CE08DEE17600C0AA42, + AB3AF60008DEDB3100C0AA42, + AB3AF60308DEDB3100C0AA42, + AB6F059A0983A53200B8EBA0, + AB6F059B0983A53200B8EBA0, + ABD656380967A4FA0066981D, + AB3AF60508DEDB3100C0AA42, + AB3AF60608DEDB3100C0AA42, + AB2B5D4508E69D9000899067, + AB3AF60808DEDB3100C0AA42, + AB3AF60908DEDB3100C0AA42, + AB3AF60A08DEDB3100C0AA42, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = ""; + }; + AB3AF5F908DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = "a-c.c"; + path = "../../src/a-c.c"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FA08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = baselayer.c; + path = ../../src/baselayer.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FB08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = cache1d.c; + path = ../../src/cache1d.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FC08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = compat.c; + path = ../../src/compat.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FD08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = crc32.c; + path = ../../src/crc32.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FE08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = defs.c; + path = ../../src/defs.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF5FF08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = engine.c; + path = ../../src/engine.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60008DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = glbuild.c; + path = ../../src/glbuild.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60208DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = hightile.c; + path = ../../src/hightile.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60308DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = kplib.c; + path = ../../src/kplib.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60408DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = mdsprite.c; + path = ../../src/mdsprite.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60508DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = mmulti.c; + path = ../../src/mmulti.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60608DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = osd.c; + path = ../../src/osd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60708DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = polymost.c; + path = ../../src/polymost.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60808DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = pragmas.c; + path = ../../src/pragmas.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60908DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = scriptfile.c; + path = ../../src/scriptfile.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60A08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sdlayer.c; + path = ../../src/sdlayer.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60B08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = smalltextfont.c; + path = ../../src/smalltextfont.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60C08DEDB3100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = textfont.c; + path = ../../src/textfont.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF60D08DEDB3100C0AA42 = { + fileRef = AB3AF5F908DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF60E08DEDB3100C0AA42 = { + fileRef = AB3AF5FA08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF60F08DEDB3100C0AA42 = { + fileRef = AB3AF5FB08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61008DEDB3100C0AA42 = { + fileRef = AB3AF5FC08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61108DEDB3100C0AA42 = { + fileRef = AB3AF5FD08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61208DEDB3100C0AA42 = { + fileRef = AB3AF5FE08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61308DEDB3100C0AA42 = { + fileRef = AB3AF5FF08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61408DEDB3100C0AA42 = { + fileRef = AB3AF60008DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61708DEDB3100C0AA42 = { + fileRef = AB3AF60308DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61A08DEDB3100C0AA42 = { + fileRef = AB3AF60608DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61C08DEDB3100C0AA42 = { + fileRef = AB3AF60808DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61D08DEDB3100C0AA42 = { + fileRef = AB3AF60908DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF61E08DEDB3100C0AA42 = { + fileRef = AB3AF60A08DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF62108DEDB4F00C0AA42 = { + fileRef = AB3AF60508DEDB3100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF62208DEDB5700C0AA42 = { + children = ( + AB3AF60208DEDB3100C0AA42, + AB3AF60408DEDB3100C0AA42, + AB3AF60708DEDB3100C0AA42, + AB3AF60B08DEDB3100C0AA42, + AB3AF60C08DEDB3100C0AA42, + ); + isa = PBXGroup; + name = Included; + refType = 4; + sourceTree = ""; + }; + AB3AF62308DEDBBA00C0AA42 = { + children = ( + AB3AF64A08DEDC8600C0AA42, + AB3AF62408DEDBCD00C0AA42, + ); + isa = PBXGroup; + name = Frameworks; + refType = 4; + sourceTree = ""; + }; + AB3AF62408DEDBCD00C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = SDL.framework; + path = /Library/Frameworks/SDL.framework; + refType = 0; + sourceTree = ""; + }; + AB3AF64A08DEDC8600C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = OpenGL.framework; + path = /System/Library/Frameworks/OpenGL.framework; + refType = 0; + sourceTree = ""; + }; + AB3AF9CC08DEE11200C0AA42 = { + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + isa = PBXShellScriptBuildPhase; + outputPaths = ( + engineinfo.c, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "source writeengineinfo.sh"; + }; + AB3AF9CE08DEE17600C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = engineinfo.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9CF08DEE17600C0AA42 = { + fileRef = AB3AF9CE08DEE17600C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF9D008DEE1C400C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = text.script.sh; + path = writeengineinfo.sh; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9D208DEE28200C0AA42 = { + children = ( + AB3AFEB208DF049300C0AA42, + AB3AF9D308DEE28800C0AA42, + ); + isa = PBXGroup; + name = Editor; + refType = 4; + sourceTree = ""; + }; + AB3AF9D308DEE28800C0AA42 = { + children = ( + AB3AF9D408DEE2B000C0AA42, + AB3AF9D608DEE2B000C0AA42, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = ""; + }; + AB3AF9D408DEE2B000C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = build.c; + path = ../../src/build.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9D608DEE2B000C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = config.c; + path = ../../src/config.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9DA08DEE2CF00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFEB408DF04B100C0AA42, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9DB08DEE2CF00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AF9DF08DEE33C00C0AA42, + AB3AF9E108DEE33D00C0AA42, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9DC08DEE2CF00C0AA42 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9DD08DEE2CF00C0AA42 = { + buildPhases = ( + AB3AF9DA08DEE2CF00C0AA42, + AB3AF9DB08DEE2CF00C0AA42, + AB3AF9DC08DEE2CF00C0AA42, + ); + buildRules = ( + ); + buildSettings = { + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = "SUPERBUILD POLYMOST USE_OPENGL USE_A_C NOASM RENDERTYPESDL=1"; + HEADER_SEARCH_PATHS = ../../include; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = editor; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = editor; + productName = editor; + productReference = AB3AF9DE08DEE2CF00C0AA42; + productType = "com.apple.product-type.library.static"; + }; + AB3AF9DE08DEE2CF00C0AA42 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libeditor.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AF9DF08DEE33C00C0AA42 = { + fileRef = AB3AF9D408DEE2B000C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF9E108DEE33D00C0AA42 = { + fileRef = AB3AF9D608DEE2B000C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFBF408DF03EE00C0AA42 = { + buildPhases = ( + ); + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = All; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + AB3AFE8A08DF03F400C0AA42, + AB3AFE8C08DF03F400C0AA42, + ); + isa = PBXAggregateTarget; + name = All; + productName = All; + }; + AB3AFE8908DF03F400C0AA42 = { + containerPortal = AB3AF5EB08DEDAA700C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF5F408DEDABE00C0AA42; + remoteInfo = engine; + }; + AB3AFE8A08DF03F400C0AA42 = { + isa = PBXTargetDependency; + target = AB3AF5F408DEDABE00C0AA42; + targetProxy = AB3AFE8908DF03F400C0AA42; + }; + AB3AFE8B08DF03F400C0AA42 = { + containerPortal = AB3AF5EB08DEDAA700C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF9DD08DEE2CF00C0AA42; + remoteInfo = editor; + }; + AB3AFE8C08DF03F400C0AA42 = { + isa = PBXTargetDependency; + target = AB3AF9DD08DEE2CF00C0AA42; + targetProxy = AB3AFE8B08DF03F400C0AA42; + }; + AB3AFE9308DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = a.h; + path = ../../include/a.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9408DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = baselayer.h; + path = ../../include/baselayer.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9508DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = build.h; + path = ../../include/build.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9608DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = cache1d.h; + path = ../../include/cache1d.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9708DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = compat.h; + path = ../../include/compat.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9808DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = crc32.h; + path = ../../include/crc32.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9908DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = engineinfo.h; + path = ../../include/engineinfo.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9A08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = glbuild.h; + path = ../../include/glbuild.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9B08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = kplib.h; + path = ../../include/kplib.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9C08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mmulti.h; + path = ../../include/mmulti.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9D08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = osd.h; + path = ../../include/osd.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9E08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = pragmas.h; + path = ../../include/pragmas.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFE9F08DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = scriptfile.h; + path = ../../include/scriptfile.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFEA008DF044D00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = sdlayer.h; + path = ../../include/sdlayer.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFEA108DF044D00C0AA42 = { + fileRef = AB3AFE9308DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Private, + ); + }; + }; + AB3AFEA208DF044D00C0AA42 = { + fileRef = AB3AFE9408DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA308DF044D00C0AA42 = { + fileRef = AB3AFE9508DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA408DF044D00C0AA42 = { + fileRef = AB3AFE9608DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA508DF044D00C0AA42 = { + fileRef = AB3AFE9708DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA608DF044D00C0AA42 = { + fileRef = AB3AFE9808DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA708DF044D00C0AA42 = { + fileRef = AB3AFE9908DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA808DF044D00C0AA42 = { + fileRef = AB3AFE9A08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEA908DF044D00C0AA42 = { + fileRef = AB3AFE9B08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAA08DF044D00C0AA42 = { + fileRef = AB3AFE9C08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAB08DF044D00C0AA42 = { + fileRef = AB3AFE9D08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAC08DF044D00C0AA42 = { + fileRef = AB3AFE9E08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAD08DF044D00C0AA42 = { + fileRef = AB3AFE9F08DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAE08DF044D00C0AA42 = { + fileRef = AB3AFEA008DF044D00C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB3AFEAF08DF046600C0AA42 = { + children = ( + AB3AFE9308DF044D00C0AA42, + AB3AFE9408DF044D00C0AA42, + AB3AFE9508DF044D00C0AA42, + AB3AFE9608DF044D00C0AA42, + AB3AFE9708DF044D00C0AA42, + AB3AFE9808DF044D00C0AA42, + AB3AFE9908DF044D00C0AA42, + AB3AFE9A08DF044D00C0AA42, + AB3AFE9B08DF044D00C0AA42, + AB6F05AD0983A5DD00B8EBA0, + AB6F05A00983A54D00B8EBA0, + ABD6563F0967A52B0066981D, + AB8F394709545F3800B9F541, + AB3AFE9C08DF044D00C0AA42, + AB3AFE9D08DF044D00C0AA42, + AB2B5D4808E69DB100899067, + AB3AFE9E08DF044D00C0AA42, + AB3AFE9F08DF044D00C0AA42, + AB3AFEA008DF044D00C0AA42, + ); + isa = PBXGroup; + name = Headers; + path = ""; + refType = 4; + sourceTree = ""; + }; + AB3AFEB208DF049300C0AA42 = { + children = ( + AB3AFEB308DF04B100C0AA42, + ); + isa = PBXGroup; + name = Headers; + refType = 4; + sourceTree = ""; + }; + AB3AFEB308DF04B100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = editor.h; + path = ../../include/editor.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFEB408DF04B100C0AA42 = { + fileRef = AB3AFEB308DF04B100C0AA42; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB6F059A0983A53200B8EBA0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = lzf_c.c; + path = ../../src/lzf_c.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB6F059B0983A53200B8EBA0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = lzf_d.c; + path = ../../src/lzf_d.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB6F059C0983A53200B8EBA0 = { + fileRef = AB6F059A0983A53200B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB6F059D0983A53200B8EBA0 = { + fileRef = AB6F059B0983A53200B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB6F059E0983A53200B8EBA0 = { + fileRef = AB6F059A0983A53200B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB6F059F0983A53200B8EBA0 = { + fileRef = AB6F059B0983A53200B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB6F05A00983A54D00B8EBA0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = lzfP.h; + path = ../../src/lzfP.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB6F05A10983A54D00B8EBA0 = { + fileRef = AB6F05A00983A54D00B8EBA0; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Private, + ); + }; + }; + AB6F05A20983A54D00B8EBA0 = { + fileRef = AB6F05A00983A54D00B8EBA0; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Private, + ); + }; + }; + AB6F05AD0983A5DD00B8EBA0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = lzf.h; + path = ../../include/lzf.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB6F05AE0983A5DD00B8EBA0 = { + fileRef = AB6F05AD0983A5DD00B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB6F05AF0983A5DD00B8EBA0 = { + fileRef = AB6F05AD0983A5DD00B8EBA0; + isa = PBXBuildFile; + settings = { + }; + }; + AB8F394409545F2600B9F541 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = md4.c; + path = ../../src/md4.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB8F394509545F2600B9F541 = { + fileRef = AB8F394409545F2600B9F541; + isa = PBXBuildFile; + settings = { + }; + }; + AB8F394609545F2600B9F541 = { + fileRef = AB8F394409545F2600B9F541; + isa = PBXBuildFile; + settings = { + }; + }; + AB8F394709545F3800B9F541 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = md4.h; + path = ../../include/md4.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB8F394809545F3800B9F541 = { + fileRef = AB8F394709545F3800B9F541; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + AB8F394909545F3800B9F541 = { + fileRef = AB8F394709545F3800B9F541; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + ABD656380967A4FA0066981D = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = lzwnew.c; + path = ../../src/lzwnew.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + ABD656390967A4FA0066981D = { + fileRef = ABD656380967A4FA0066981D; + isa = PBXBuildFile; + settings = { + }; + }; + ABD6563A0967A4FA0066981D = { + fileRef = ABD656380967A4FA0066981D; + isa = PBXBuildFile; + settings = { + }; + }; + ABD6563F0967A52B0066981D = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = lzwnew.h; + path = ../../include/lzwnew.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + ABD656400967A52B0066981D = { + fileRef = ABD6563F0967A52B0066981D; + isa = PBXBuildFile; + settings = { + }; + }; + ABD656410967A52B0066981D = { + fileRef = ABD6563F0967A52B0066981D; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = AB3AF5EB08DEDAA700C0AA42; +} diff --git a/polymer/build/osx/engine/engineinfo.c b/polymer/build/osx/engine/engineinfo.c new file mode 100644 index 000000000..c3d9bc194 --- /dev/null +++ b/polymer/build/osx/engine/engineinfo.c @@ -0,0 +1,5 @@ +const char _engine_cflags[] = ""; +const char _engine_libs[] = ""; +const char _engine_uname[] = "Darwin megumi.fnord 7.9.0 Darwin Kernel Version 7.9.0: Wed Mar 30 20:11:17 PST 2005; root:xnu/xnu-517.12.7.obj~1/RELEASE_PPC Power Macintosh powerpc"; +const char _engine_compiler[] = "gcc 3.3 ppc-darwin"; +const char _engine_date[] = __DATE__ " " __TIME__; diff --git a/polymer/build/osx/engine/writeengineinfo.sh b/polymer/build/osx/engine/writeengineinfo.sh new file mode 100644 index 000000000..068c43b26 --- /dev/null +++ b/polymer/build/osx/engine/writeengineinfo.sh @@ -0,0 +1,10 @@ +#!/bin/sh +UNAME=`uname -a` +CC="gcc" +CCVERSION=`$CC -dumpversion` +CCMACHINE=`$CC -dumpmachine` +echo "const char _engine_cflags[] = \"$OTHER_CFLAGS\";" > engineinfo.c +echo "const char _engine_libs[] = \"$LIBS\";" >> engineinfo.c +echo "const char _engine_uname[] = \"$UNAME\";" >> engineinfo.c +echo "const char _engine_compiler[] = \"$CC $CCVERSION $CCMACHINE\";" >> engineinfo.c +echo "const char _engine_date[] = __DATE__ \" \" __TIME__;" >> engineinfo.c diff --git a/polymer/build/osx/game/build.osxmain.h b/polymer/build/osx/game/build.osxmain.h new file mode 100644 index 000000000..4683df57a --- /dev/null +++ b/polymer/build/osx/game/build.osxmain.h @@ -0,0 +1,11 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import + +@interface SDLMain : NSObject +@end diff --git a/polymer/build/osx/game/build.osxmain.m b/polymer/build/osx/game/build.osxmain.m new file mode 100644 index 000000000..881c83f3c --- /dev/null +++ b/polymer/build/osx/game/build.osxmain.m @@ -0,0 +1,179 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import +#import "build.osxmain.h" +#import /* for MAXPATHLEN */ +#import + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; + +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end + +@interface SDLApplication : NSApplication +@end + +@implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + char parentdir[MAXPATHLEN]; + char *c; + + strncpy ( parentdir, gArgv[0], sizeof(parentdir) ); + c = (char*) parentdir; + + while (*c != '\0') /* go to end */ + c++; + + while (*c != '/') /* back up to parent */ + c--; + + *c++ = '\0'; /* cut off last part (binary name) */ + + if (shouldChdir) + { + assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ + assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */ + } +} + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + + /* Set the main menu to contain the real app name instead of "SDL App" */ + //[self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]]; + [self fixMenu:[NSApp mainMenu] withAppName:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]]; + + /* Hand off to main application code */ + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + + /* Copy the arguments into a global variable */ + int i; + + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgc = 1; + gFinderLaunch = YES; + } else { + gArgc = argc; + gFinderLaunch = NO; + } + gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1)); + assert (gArgv != NULL); + for (i = 0; i < gArgc; i++) + gArgv[i] = argv[i]; + gArgv[i] = NULL; + + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); + + return 0; +} diff --git a/polymer/build/osx/game/editor-Info.plist b/polymer/build/osx/game/editor-Info.plist new file mode 100644 index 000000000..f9528ec10 --- /dev/null +++ b/polymer/build/osx/game/editor-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + build + CFBundleIdentifier + au.id.jonof.build + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + osxmain + NSPrincipalClass + NSApplication + + diff --git a/polymer/build/osx/game/game-Info.plist b/polymer/build/osx/game/game-Info.plist new file mode 100644 index 000000000..708c3b2f3 --- /dev/null +++ b/polymer/build/osx/game/game-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + game + CFBundleIdentifier + au.id.jonof.kenbuild + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + osxmain + NSPrincipalClass + NSApplication + + diff --git a/polymer/build/osx/game/game.osxmain.h b/polymer/build/osx/game/game.osxmain.h new file mode 100644 index 000000000..4683df57a --- /dev/null +++ b/polymer/build/osx/game/game.osxmain.h @@ -0,0 +1,11 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import + +@interface SDLMain : NSObject +@end diff --git a/polymer/build/osx/game/game.osxmain.m b/polymer/build/osx/game/game.osxmain.m new file mode 100644 index 000000000..fec706b93 --- /dev/null +++ b/polymer/build/osx/game/game.osxmain.m @@ -0,0 +1,179 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import +#import "game.osxmain.h" +#import /* for MAXPATHLEN */ +#import + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; + +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end + +@interface SDLApplication : NSApplication +@end + +@implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + char parentdir[MAXPATHLEN]; + char *c; + + strncpy ( parentdir, gArgv[0], sizeof(parentdir) ); + c = (char*) parentdir; + + while (*c != '\0') /* go to end */ + c++; + + while (*c != '/') /* back up to parent */ + c--; + + *c++ = '\0'; /* cut off last part (binary name) */ + + if (shouldChdir) + { + assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ + assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */ + } +} + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + + /* Set the main menu to contain the real app name instead of "SDL App" */ + //[self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]]; + [self fixMenu:[NSApp mainMenu] withAppName:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]]; + + /* Hand off to main application code */ + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + + /* Copy the arguments into a global variable */ + int i; + + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgc = 1; + gFinderLaunch = YES; + } else { + gArgc = argc; + gFinderLaunch = NO; + } + gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1)); + assert (gArgv != NULL); + for (i = 0; i < gArgc; i++) + gArgv[i] = argv[i]; + gArgv[i] = NULL; + + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); + + return 0; +} diff --git a/polymer/build/osx/game/game.xcode/project.pbxproj b/polymer/build/osx/game/game.xcode/project.pbxproj new file mode 100644 index 000000000..b08e004bb --- /dev/null +++ b/polymer/build/osx/game/game.xcode/project.pbxproj @@ -0,0 +1,825 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + AB2B5CB408E698F600899067 = { + fileType = archive.ar; + isa = PBXReferenceProxy; + path = libenginez.a; + refType = 3; + remoteRef = AB2B5CB808E6992B00899067; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB2B5CB808E6992B00899067 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = AB2B5C9708E6979600899067; + remoteInfo = enginez; + }; + AB2B5D3708E69B7D00899067 = { + containerPortal = AB3AF9E808DEE39200C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AFEC008DF04E300C0AA42; + remoteInfo = editor; + }; + AB2B5D3808E69B7D00899067 = { + isa = PBXTargetDependency; + target = AB3AFEC008DF04E300C0AA42; + targetProxy = AB2B5D3708E69B7D00899067; + }; + AB3A002208DF064900C0AA42 = { + fileRef = AB3AFABF08DF035400C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3A002408DF064900C0AA42 = { + fileRef = AB3AFA6F08DEE50200C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3A002508DF064900C0AA42 = { + fileRef = AB3AFA7308DEE53C00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3A002608DF066200C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = archive.ar; + name = libeditor.a; + path = /Users/jonof/ports/build/osx/engine/build/libeditor.a; + refType = 0; + sourceTree = ""; + }; + AB3A002708DF066200C0AA42 = { + fileRef = AB3A002608DF066200C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AF9E408DEE39200C0AA42 = { + children = ( + AB3AFA5F08DEE45000C0AA42, + ABBC7AA3099344E40064C16C, + AB3AF9EE08DEE3A100C0AA42, + AB3AF9EC08DEE39A00C0AA42, + AB3AFA7908DEFECF00C0AA42, + AB3AF9F908DEE3EE00C0AA42, + ); + isa = PBXGroup; + refType = 4; + sourceTree = ""; + }; + AB3AF9E608DEE39200C0AA42 = { + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_OPTIMIZATION_LEVEL = 0; + }; + isa = PBXBuildStyle; + name = Development; + }; + AB3AF9E708DEE39200C0AA42 = { + buildSettings = { + COPY_PHASE_STRIP = YES; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_OPTIMIZATION_LEVEL = 2; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + AB3AF9E808DEE39200C0AA42 = { + buildSettings = { + }; + buildStyles = ( + AB3AF9E608DEE39200C0AA42, + AB3AF9E708DEE39200C0AA42, + ); + hasScannedForEncodings = 0; + isa = PBXProject; + mainGroup = AB3AF9E408DEE39200C0AA42; + productRefGroup = AB3AF9F908DEE3EE00C0AA42; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = ABBC7AA5099344E60064C16C; + ProjectRef = ABBC7AA3099344E40064C16C; + }, + { + ProductGroup = AB3AFA6208DEE45200C0AA42; + ProjectRef = AB3AFA5F08DEE45000C0AA42; + }, + ); + targets = ( + AB3AFBF108DF03C900C0AA42, + AB3AF9F708DEE3EE00C0AA42, + AB3AFEC008DF04E300C0AA42, + ); + }; + AB3AF9EC08DEE39A00C0AA42 = { + children = ( + AB3AF9ED08DEE39E00C0AA42, + AB3AFA7708DEFEC100C0AA42, + AB3AF9FB08DEE3EE00C0AA42, + ); + isa = PBXGroup; + name = Game; + refType = 4; + sourceTree = ""; + }; + AB3AF9ED08DEE39E00C0AA42 = { + children = ( + AB3AFA6D08DEE4D700C0AA42, + AB3AF9F108DEE3DA00C0AA42, + AB3AF9F208DEE3DA00C0AA42, + AB3AF9F308DEE3DA00C0AA42, + ABBC7A9A099344CF0064C16C, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = ""; + }; + AB3AF9EE08DEE3A100C0AA42 = { + children = ( + AB3AF9EF08DEE3AB00C0AA42, + AB3AFEC308DF04E300C0AA42, + ); + isa = PBXGroup; + name = Editor; + refType = 4; + sourceTree = ""; + }; + AB3AF9EF08DEE3AB00C0AA42 = { + children = ( + AB3AFECC08DF059E00C0AA42, + AB3AF9F008DEE3C100C0AA42, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = ""; + }; + AB3AF9F008DEE3C100C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = bstub.c; + path = ../../src/bstub.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9F108DEE3DA00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = config.c; + path = ../../src/config.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9F208DEE3DA00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = game.c; + path = ../../src/game.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9F308DEE3DA00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sound.c; + path = ../../src/sound.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AF9F408DEE3EE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFA7808DEFEC200C0AA42, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9F508DEE3EE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFA5C08DEE43500C0AA42, + AB3AFA5D08DEE43500C0AA42, + AB3AFA6E08DEE4D700C0AA42, + ABBC7A9B099344CF0064C16C, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9F608DEE3EE00C0AA42 = { + buildActionMask = 2147483647; + files = ( + ABBC7B6409934A410064C16C, + AB3AFAC008DF035400C0AA42, + AB3AFB5708DF037500C0AA42, + AB3AFABE08DF030B00C0AA42, + AB3AFA7008DEE50200C0AA42, + AB3AFA7408DEE53C00C0AA42, + ABBC7B6609934A5A0064C16C, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AF9F708DEE3EE00C0AA42 = { + buildPhases = ( + AB3AF9F408DEE3EE00C0AA42, + AB3AF9F508DEE3EE00C0AA42, + AB3AF9F608DEE3EE00C0AA42, + ABBC7B40099347230064C16C, + ); + buildRules = ( + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = /Users/jonof/ports/jfaud/osx/build; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = "SUPERBUILD POLYMOST USE_OPENGL NOASM RENDERTYPESDL=1"; + HEADER_SEARCH_PATHS = "/Developer/SDKs/fmodapi3741mac/api/inc ../../include"; + INFOPLIST_FILE = "game-Info.plist"; + INSTALL_PATH = "$(USER_APPS_DIR)"; + LIBRARY_SEARCH_PATHS = "/Developer/SDKs/fmodapi3741mac/api/lib ../engine/build"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = game; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + AB3AFAB608DF00A400C0AA42, + ); + isa = PBXNativeTarget; + name = game; + productName = game; + productReference = AB3AF9F808DEE3EE00C0AA42; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + game + CFBundleIdentifier + com.yourcompany.game + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + +"; + productType = "com.apple.product-type.application"; + }; + AB3AF9F808DEE3EE00C0AA42 = { + explicitFileType = wrapper.application; + includeInIndex = 0; + isa = PBXFileReference; + path = game.app; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AF9F908DEE3EE00C0AA42 = { + children = ( + AB3AF9F808DEE3EE00C0AA42, + AB3AFEC108DF04E300C0AA42, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + AB3AF9FB08DEE3EE00C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = text.xml; + path = "game-Info.plist"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFA5C08DEE43500C0AA42 = { + fileRef = AB3AF9F108DEE3DA00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA5D08DEE43500C0AA42 = { + fileRef = AB3AF9F208DEE3DA00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA5F08DEE45000C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = "wrapper.pb-project"; + name = engine.xcode; + path = ../engine/engine.xcode; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFA6208DEE45200C0AA42 = { + children = ( + AB3AFA6308DEE45200C0AA42, + AB3AFA6408DEE45200C0AA42, + AB2B5CB408E698F600899067, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + AB3AFA6308DEE45200C0AA42 = { + fileType = archive.ar; + isa = PBXReferenceProxy; + path = libengine.a; + refType = 3; + remoteRef = AB3AFA6708DEE46200C0AA42; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AFA6408DEE45200C0AA42 = { + fileType = archive.ar; + isa = PBXReferenceProxy; + path = libeditor.a; + refType = 3; + remoteRef = AB3AFA6808DEE46200C0AA42; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AFA6708DEE46200C0AA42 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = AB3AF5F508DEDABE00C0AA42; + remoteInfo = engine; + }; + AB3AFA6808DEE46200C0AA42 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = AB3AF9DE08DEE2CF00C0AA42; + remoteInfo = editor; + }; + AB3AFA6D08DEE4D700C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = game.osxmain.m; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFA6E08DEE4D700C0AA42 = { + fileRef = AB3AFA6D08DEE4D700C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA6F08DEE50200C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = OpenGL.framework; + path = /System/Library/Frameworks/OpenGL.framework; + refType = 0; + sourceTree = ""; + }; + AB3AFA7008DEE50200C0AA42 = { + fileRef = AB3AFA6F08DEE50200C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA7308DEE53C00C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = SDL.framework; + path = /Library/Frameworks/SDL.framework; + refType = 0; + sourceTree = ""; + }; + AB3AFA7408DEE53C00C0AA42 = { + fileRef = AB3AFA7308DEE53C00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA7708DEFEC100C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.nib; + path = osxmain.nib; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFA7808DEFEC200C0AA42 = { + fileRef = AB3AFA7708DEFEC100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFA7908DEFECF00C0AA42 = { + children = ( + AB3A002608DF066200C0AA42, + AB3AFABD08DF030B00C0AA42, + ABBC7AD6099345F70064C16C, + AB3AFABF08DF035400C0AA42, + AB3AFB5608DF037500C0AA42, + ABBC7B6509934A5A0064C16C, + AB3AFA6F08DEE50200C0AA42, + AB3AFA7308DEE53C00C0AA42, + ); + isa = PBXGroup; + name = Frameworks; + refType = 4; + sourceTree = ""; + }; + AB3AFAB508DF00A400C0AA42 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF5F408DEDABE00C0AA42; + remoteInfo = engine; + }; + AB3AFAB608DF00A400C0AA42 = { + isa = PBXTargetDependency; + name = "engine (from engine.xcode)"; + targetProxy = AB3AFAB508DF00A400C0AA42; + }; + AB3AFABD08DF030B00C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = archive.ar; + name = libengine.a; + path = /Users/jonof/ports/build/osx/engine/build/libengine.a; + refType = 0; + sourceTree = ""; + }; + AB3AFABE08DF030B00C0AA42 = { + fileRef = AB3AFABD08DF030B00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFABF08DF035400C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = AppKit.framework; + path = /System/Library/Frameworks/AppKit.framework; + refType = 0; + sourceTree = ""; + }; + AB3AFAC008DF035400C0AA42 = { + fileRef = AB3AFABF08DF035400C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFB5608DF037500C0AA42 = { + comments = "Needed for fmod to link."; + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Carbon.framework; + path = /System/Library/Frameworks/Carbon.framework; + refType = 0; + sourceTree = ""; + }; + AB3AFB5708DF037500C0AA42 = { + fileRef = AB3AFB5608DF037500C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFBF108DF03C900C0AA42 = { + buildPhases = ( + ); + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = All; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + AB3AFBF308DF03D200C0AA42, + AB2B5D3808E69B7D00899067, + ); + isa = PBXAggregateTarget; + name = All; + productName = All; + }; + AB3AFBF208DF03D200C0AA42 = { + containerPortal = AB3AF9E808DEE39200C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF9F708DEE3EE00C0AA42; + remoteInfo = game; + }; + AB3AFBF308DF03D200C0AA42 = { + isa = PBXTargetDependency; + target = AB3AF9F708DEE3EE00C0AA42; + targetProxy = AB3AFBF208DF03D200C0AA42; + }; + AB3AFEBD08DF04E300C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFECE08DF05AE00C0AA42, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AFEBE08DF04E300C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3AFECA08DF058D00C0AA42, + AB3AFECD08DF059E00C0AA42, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AFEBF08DF04E300C0AA42 = { + buildActionMask = 2147483647; + files = ( + AB3A002208DF064900C0AA42, + AB3A002708DF066200C0AA42, + AB3AFECF08DF063D00C0AA42, + AB3A002408DF064900C0AA42, + AB3A002508DF064900C0AA42, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + AB3AFEC008DF04E300C0AA42 = { + buildPhases = ( + AB3AFEBD08DF04E300C0AA42, + AB3AFEBE08DF04E300C0AA42, + AB3AFEBF08DF04E300C0AA42, + ); + buildRules = ( + ); + buildSettings = { + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = "SUPERBUILD POLYMOST USE_OPENGL NOASM USE_A_C RENDERTYPESDL=1"; + HEADER_SEARCH_PATHS = ../../include; + INFOPLIST_FILE = "editor-Info.plist"; + INSTALL_PATH = "$(USER_APPS_DIR)"; + LIBRARY_SEARCH_PATHS = ../engine/build; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = build; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + AB3AFEC508DF04EB00C0AA42, + AB3AFEC708DF04EB00C0AA42, + ); + isa = PBXNativeTarget; + name = editor; + productName = editor; + productReference = AB3AFEC108DF04E300C0AA42; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + editor + CFBundleIdentifier + com.yourcompany.editor + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + +"; + productType = "com.apple.product-type.application"; + }; + AB3AFEC108DF04E300C0AA42 = { + explicitFileType = wrapper.application; + includeInIndex = 0; + isa = PBXFileReference; + path = build.app; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AB3AFEC308DF04E300C0AA42 = { + isa = PBXFileReference; + lastKnownFileType = text.xml; + path = "editor-Info.plist"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFEC408DF04EB00C0AA42 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF5F408DEDABE00C0AA42; + remoteInfo = engine; + }; + AB3AFEC508DF04EB00C0AA42 = { + isa = PBXTargetDependency; + name = "engine (from engine.xcode)"; + targetProxy = AB3AFEC408DF04EB00C0AA42; + }; + AB3AFEC608DF04EB00C0AA42 = { + containerPortal = AB3AFA5F08DEE45000C0AA42; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = AB3AF9DD08DEE2CF00C0AA42; + remoteInfo = editor; + }; + AB3AFEC708DF04EB00C0AA42 = { + isa = PBXTargetDependency; + name = "editor (from engine.xcode)"; + targetProxy = AB3AFEC608DF04EB00C0AA42; + }; + AB3AFECA08DF058D00C0AA42 = { + fileRef = AB3AF9F008DEE3C100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFECC08DF059E00C0AA42 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = build.osxmain.m; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + AB3AFECD08DF059E00C0AA42 = { + fileRef = AB3AFECC08DF059E00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFECE08DF05AE00C0AA42 = { + fileRef = AB3AFA7708DEFEC100C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + AB3AFECF08DF063D00C0AA42 = { + fileRef = AB3AFABD08DF030B00C0AA42; + isa = PBXBuildFile; + settings = { + }; + }; + ABBC7A9A099344CF0064C16C = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = jfaud_sound.cpp; + path = ../../src/jfaud_sound.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + ABBC7A9B099344CF0064C16C = { + fileRef = ABBC7A9A099344CF0064C16C; + isa = PBXBuildFile; + settings = { + }; + }; + ABBC7AA3099344E40064C16C = { + isa = PBXFileReference; + lastKnownFileType = "wrapper.pb-project"; + name = jfaud.xcode; + path = ../../../jfaud/osx/jfaud.xcode; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + ABBC7AA5099344E60064C16C = { + children = ( + ABBC7AA6099344E60064C16C, + ABBC7AA7099344E60064C16C, + ABBC7AA8099344E60064C16C, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + ABBC7AA6099344E60064C16C = { + fileType = wrapper.framework; + isa = PBXReferenceProxy; + path = jfaud.framework; + refType = 3; + remoteRef = ABBC7AAA099344F50064C16C; + sourceTree = BUILT_PRODUCTS_DIR; + }; + ABBC7AA7099344E60064C16C = { + fileType = archive.ar; + isa = PBXReferenceProxy; + path = libmpadec.a; + refType = 3; + remoteRef = ABBC7AAB099344F50064C16C; + sourceTree = BUILT_PRODUCTS_DIR; + }; + ABBC7AA8099344E60064C16C = { + fileType = wrapper.application; + isa = PBXReferenceProxy; + path = jfaudtest.app; + refType = 3; + remoteRef = ABBC7AAC099344F50064C16C; + sourceTree = BUILT_PRODUCTS_DIR; + }; + ABBC7AAA099344F50064C16C = { + containerPortal = ABBC7AA3099344E40064C16C; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = jfaud; + }; + ABBC7AAB099344F50064C16C = { + containerPortal = ABBC7AA3099344E40064C16C; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = ABE7399C095277C50040A74A; + remoteInfo = mpadec; + }; + ABBC7AAC099344F50064C16C = { + containerPortal = ABBC7AA3099344E40064C16C; + isa = PBXContainerItemProxy; + proxyType = 2; + remoteGlobalIDString = ABE7394E09526A5B0040A74A; + remoteInfo = jfaudtest; + }; + ABBC7AD6099345F70064C16C = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = jfaud.framework; + path = /Users/jonof/ports/jfaud/osx/build/jfaud.framework; + refType = 0; + sourceTree = ""; + }; + ABBC7B40099347230064C16C = { + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ABBC7B410993474A0064C16C, + ); + isa = PBXCopyFilesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + ABBC7B410993474A0064C16C = { + fileRef = ABBC7AD6099345F70064C16C; + isa = PBXBuildFile; + settings = { + }; + }; + ABBC7B6409934A410064C16C = { + fileRef = ABBC7AD6099345F70064C16C; + isa = PBXBuildFile; + settings = { + }; + }; + ABBC7B6509934A5A0064C16C = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = OpenAL.framework; + path = ../../../../../../Library/Frameworks/OpenAL.framework; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + ABBC7B6609934A5A0064C16C = { + fileRef = ABBC7B6509934A5A0064C16C; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = AB3AF9E808DEE39200C0AA42; +} diff --git a/polymer/build/osx/game/osxmain.nib/classes.nib b/polymer/build/osx/game/osxmain.nib/classes.nib new file mode 100644 index 000000000..b014bc964 --- /dev/null +++ b/polymer/build/osx/game/osxmain.nib/classes.nib @@ -0,0 +1,7 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {ACTIONS = {}; CLASS = SDLMain; LANGUAGE = ObjC; SUPERCLASS = NSObject; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/polymer/build/osx/game/osxmain.nib/info.nib b/polymer/build/osx/game/osxmain.nib/info.nib new file mode 100644 index 000000000..eb4b6a84b --- /dev/null +++ b/polymer/build/osx/game/osxmain.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 52 97 356 240 0 0 1024 746 + IBEditorPositions + + 29 + 196 422 195 44 0 0 1024 746 + + IBFramework Version + 364.0 + IBOpenObjects + + 29 + + IBSystem Version + 7W98 + + diff --git a/polymer/build/osx/game/osxmain.nib/objects.nib b/polymer/build/osx/game/osxmain.nib/objects.nib new file mode 100644 index 0000000000000000000000000000000000000000..7cdeb7ba7e1bb28d3d23492cad58e265c66f0176 GIT binary patch literal 1683 zcma)6&2Jk;6rXL<#tw#DK7dfgshrweST|KvOV|PSz!9zOA>MXB-2G5!FKD9i zh$}05UY3l0@#yfJ5r>kXH(LWk1cZUn|2t{DWEQuB)>Xm zK#XoTS2k?JGVWpq8^vNPXa=E`Pmhj{Pzxw#Dq4E253uJ1ZVg{*a{xl5lBF*tPEsXE zpKsvWElYQAG1j8r^B({O&hn&ee1hwmulpE|AY1TfGTQV<6)nAvCt+Z_7t$}jl&U7Q z>+hCz!)EmBXezaJPUIgpxfKS{Gpb{?Ke7A{U7iiK+@k1~D(o6R$_zCBJq{i>Tn z;2EGS?}fwU8S>c!6cTr-;GHKbfO?TCCP9U)id00xGU|uNGnj^t7+>%6&6p1d{C>;_ zecp@sZpMLm!u<#BIez2 z_+|Jpz6Hxu-NtwXhODOAg@52`{K9JkXOm=@B!e!F~`!F5O!z6+QjG+<&K++SGzEsgFMs*&d zx{e7S8)ls25_FhMz4R!xU2M}aRaN&}5aJmR%27Vt90RJ~R(Cp}{pAMqK~mADW}KHH zwk6`cL}Z5D#3it$3F`Wc3#Bh6(iQ{X#Qtezzpr)fkx?X5v_hZMk zux<62Jh)MHUY@OgXk3)+{OVx|B8qxvtr*7 zI|O|$dPI3ubQJNBph)Zz#Krm*(VrE664Vv<3F?T=IWfE`wg~!JtP$lk@efg67uy6e zu}9En;*g-9#9&GMO_YLoa98|A&_Kjj#UBKP5b2Ewg>ZqH(zSV~=I9HqZsBD|PSgJY DX=mSP literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/build.bmp b/polymer/build/rsrc/build.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6800c5365ec87dc16c14e76d41208066142bdc01 GIT binary patch literal 26774 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 literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/build.xcf b/polymer/build/rsrc/build.xcf new file mode 100644 index 0000000000000000000000000000000000000000..a1ddd6d4e38f66802ca9434816dde2b9c7f994d4 GIT binary patch literal 129379 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 z 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 literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/build_icon.bmp b/polymer/build/rsrc/build_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0244f3f79a8be15ddc0b79af964876b3ead92197 GIT binary patch literal 3126 zcmeH}dr(tX8o-H&BGy0%At8iBLUKbw-pNhK^CtI^2T33=1PK_x0_y_=DQyMhQ3wwO z!b>LIx(JA%Qmfcjs}`}V>+I}yX2)4=x6_$*_MiP{XSV&L)1CFNJq4Fx6nDG-`N!Tl z_sn;`?>oQq-S0c+%tbw#H{#YF4d`>hyZ8A^iemr?JkRaxga7xhLk8&Nl=K~BY63Z9 z2RUOWnL>(BiQD$?MoNi``=1)%V}Ut|F|#sSS4*$DeFC+KiG>Far_gBph_h0>8*V(|DC{r zCneQS_tpNjtoFOmk-vwUzwuVzz>ChBY!R)YNvl1C8R{@&EoN?PI`QbsZ+?9A?GIJ8 zD|^#*lx+!M6(%{Sr2L81a#<~Jb2{&vuyd}$2YFB}Fj2QBDU>G=yYicV6xaP$D)`0P zSCG8^s|4{`p>G95uF*#QW%pIe-qZv#eHYE`e~4k%y@6lr^=B=_WryRgqhJ+9uOY+& z$R04+-Ae><%Vt~QFp2bCi~}|I9(?s9iqCIOqh8bGblq_K=e_>rJm{dye-9^?G5o4T z)aWU_Yc|hWoeLJrqRq2_2xs*aS@PB_L$YWWFmfvqF3~mNx(N^ zXF&`S@!MH+jXSuifk!CuN$Y!zurFmM3pewDZ1*jKt%w#baOj8`ozQ3|4MYrv$5H!) zRy$=tqB{KtI{hGu&q`#i0&cm0S6Sd)Hk&Wx8_u`__b}`uy)l-uZ3jS!xS=eH^aZ|B zen5}Jbe1#hbR%MXN2waXoMUqNdpaztP=O?Ln~9i2dXjL>h{df2bXqJvfjU1_DhD%Y zO1Ezgd}%h@kwV%Iu#DXtKC9pbK7BXSTfVF@4e;2ALVkd74xw1L(byppRvbA#FP6M5 zm38p>HFZrF#FBSqiY{=0pw9OdiUDxatp#V*>QR}rleU}n6P6TD+nM$P9}Ia}YCgxv zO36w~e8W>72_Bwuh5I%3aOhZ{w{gm{uSe%;@YS>z9~-xnM0AD6v5G!h<)p3h48&4p zXX?3G2HGy_%h)Y7cy+hG<3iDi=|Ja#ul;=4z{kX)Q-RLK!goFhc3mv)zO=9B!~Ols zrTy1}or_x%URH7$s4VxWEcXbPVaYeVD->fQF=q45@*x#kFmCgnHxd1ONNsVBTAWdh zu|cLT1ty1Yo=JuzP%W4!6&$9lmH1^i(8xv2;KcDV9qd%44vuE*;lc7wpZ77Bj@WIt zMA`eD_7y101C+4rqy(yiSZ-lsw>9Hu=Vj`A~|K(l@)Y{{1ikC}}#D(OjJ)hPP` z0Wr?lZJ+Zp3q(0#cACaynC7G^MBEAi$1mbl$%PHL^(u~C&&j~SMm6eUOfr8<^14zg ztmm^_%sqSxX*;a!4F?GI{Vs3~-Rps%jayda!PDL>Il+VOL{0F`udw;%m!fZM(1(_5!h_Xw-?X87Jz${qVXEM$p#&e7$rc&MoD-5weFYK`qG10A1Jeivl)9HX8T;ta{9P9i~2M5>rofQ=ub1!vv z3ewWJ$;o$yhw;3;4gCv3jl*%Jw|9A9;7&9;QD0AukB>Ds0|B^ohr^eGkZG_*208mX=Z>Dr8a9scoN=NSG4$r~<+ literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/build_icon.c b/polymer/build/rsrc/build_icon.c new file mode 100644 index 000000000..f08f95938 --- /dev/null +++ b/polymer/build/rsrc/build_icon.c @@ -0,0 +1,192 @@ +#include "sdlayer.h" + +static unsigned int sdlappicon_pixels[] = { + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff654848, 0xffad8484, + 0xffb18888, 0xffbb8f8f, 0xff936d6d, 0xff130303, 0xff987373, 0xff936d6d, + 0xff100000, 0xff815f5f, 0xffaa8181, 0xff362020, 0xffa98080, 0xff5c3f3f, + 0xff715252, 0xffb78b8b, 0xff130202, 0xff100000, 0xff2f1a1a, 0xffa07a7a, + 0xffb78c8c, 0xffbd9090, 0xff856262, 0xff140303, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff432a2a, 0xff825f5f, 0xff190808, 0xff4c3131, 0xffd5a2a2, 0xff2c1717, + 0xff7e5b5b, 0xff543939, 0xff100000, 0xff674848, 0xff6e4f4f, 0xff100000, + 0xffb58989, 0xff1c0a0a, 0xff513535, 0xff7f5d5d, 0xff100000, 0xff100000, + 0xff100000, 0xffa97f7f, 0xff271414, 0xff220f0f, 0xffbb8d8d, 0xff442b2b, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff432a2a, 0xffba8e8e, 0xffb88d8d, 0xffc19494, + 0xff987171, 0xff110101, 0xff7e5b5b, 0xff533939, 0xff100000, 0xff694949, + 0xff6e4f4f, 0xff100000, 0xffb08585, 0xff1c0a0a, 0xff513535, 0xff7b5a5a, + 0xff100000, 0xff100000, 0xff100000, 0xffa67c7c, 0xff261212, 0xff100000, + 0xff956e6e, 0xff704f4f, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff4c3232, 0xff896565, + 0xff261212, 0xff503535, 0xffd4a2a2, 0xff351e1e, 0xff755454, 0xff835f5f, + 0xff261111, 0xff936c6c, 0xff715050, 0xff160505, 0xffb28686, 0xff241111, + 0xff573a3a, 0xff836060, 0xff251111, 0xff674949, 0xff140303, 0xffa77e7e, + 0xff392222, 0xff3a2222, 0xffbf9191, 0xff3b2424, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff725252, 0xffb78a8a, 0xffc19292, 0xffba8c8c, 0xff866161, 0xff110101, + 0xff2c1818, 0xffb28585, 0xffc49393, 0xffab8080, 0xff261313, 0xff3f2727, + 0xffb18686, 0xff644545, 0xff7c5a5a, 0xffb98c8c, 0xffc09191, 0xffba8c8c, + 0xff341e1e, 0xffa77e7e, 0xffbf9090, 0xffba8d8d, 0xff745353, 0xff110101, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff272159, 0xff383793, 0xff3e3da3, 0xff2e286b, + 0xff2e296e, 0xff2a2157, 0xff100001, 0xff37358e, 0xff140611, 0xff353286, + 0xff3d3ca0, 0xff3f3c9f, 0xff180a1a, 0xff323080, 0xff353285, 0xff261e51, + 0xff322c75, 0xff100000, 0xff322e7b, 0xff1f153a, 0xff333284, 0xff3b3a9d, + 0xff403fa8, 0xff13040b, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff2e296d, 0xff251c4b, + 0xff1a0d25, 0xff110104, 0xff353284, 0xff5453db, 0xff1a0d22, 0xff3e3da6, + 0xff231a47, 0xff332f7d, 0xff150714, 0xff2c225b, 0xff1f1333, 0xff2b2461, + 0xff281f54, 0xff2a235d, 0xff5454df, 0xff251a44, 0xff38358f, 0xff211841, + 0xff332f7e, 0xff1c0f29, 0xff140611, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff2f296f, 0xff3e3ca0, 0xff332e7d, 0xff100000, 0xff363287, 0xff2d2667, + 0xff3f3ca0, 0xff4746bc, 0xff241b4a, 0xff2a235f, 0xff1e1436, 0xff3d3b9e, + 0xff1f1231, 0xff2a225d, 0xff271f52, 0xff2a2461, 0xff30296e, 0xff4441af, + 0xff4443b2, 0xff231944, 0xff3e3ea5, 0xff3c3998, 0xff1a0e25, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff302a73, 0xff2e2768, 0xff241b48, 0xff1e1232, + 0xff39358f, 0xff190d24, 0xff35307f, 0xff5150d4, 0xff22173f, 0xff4746b9, + 0xff2a2159, 0xff4947bd, 0xff261d4d, 0xff35307f, 0xff352f7d, 0xff2d2667, + 0xff261c4c, 0xff292158, 0xff5555df, 0xff231a47, 0xff38358f, 0xff251b49, + 0xff261c4c, 0xff110205, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff221842, 0xff2f286c, + 0xff2f286b, 0xff221840, 0xff383b78, 0xff292c43, 0xff2a2c43, 0xff4650a1, + 0xff252633, 0xff424a92, 0xff4650a3, 0xff3d4587, 0xff252634, 0xff404990, + 0xff40498f, 0xff363c6e, 0xff2f3458, 0xff252633, 0xff4851a4, 0xff1a0e26, + 0xff2d2666, 0xff2f286b, 0xff2e276a, 0xff110206, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff446281, 0xff527ea5, + 0xff4f799e, 0xff537fa6, 0xff517ca3, 0xff5a88b3, 0xff45698a, 0xff537fa7, + 0xff4e779b, 0xff5480a8, 0xff5581a9, 0xff5683ac, 0xff5987b1, 0xff5887b0, + 0xff547fa7, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff241d34, 0xff251f3c, 0xff1c101d, 0xff14080c, + 0xff4d5c85, 0xff546a96, 0xff4b5f87, 0xff36475f, 0xff5b6f86, 0xff507096, + 0xff405683, 0xff394d6e, 0xff51657c, 0xff556f92, 0xff405785, 0xff394e72, + 0xff435d86, 0xff466094, 0xff466095, 0xff261c33, 0xff211b3a, 0xff221d3b, + 0xff150913, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff170b1a, 0xff505cb1, 0xff363d88, + 0xff241e3f, 0xff31305e, 0xff45498c, 0xff424381, 0xff3c3c7e, 0xff2a295d, + 0xff6b72a4, 0xff2c2d76, 0xff2e2f7e, 0xff252565, 0xff6771a5, 0xff2c2d78, + 0xff2f3180, 0xff292970, 0xff424999, 0xff313188, 0xff2d2d7b, 0xff414a9c, + 0xff343490, 0xff2f2e7f, 0xff150b1c, 0xff100000, 0xff100103, 0xff150714, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff32305e, + 0xff3a3f98, 0xff394095, 0xff1e163c, 0xff3f3c77, 0xff323388, 0xff434991, + 0xff303082, 0xff39438f, 0xff313385, 0xff323481, 0xff3e4598, 0xff2d2e7d, + 0xff454ba0, 0xff2c2c7a, 0xff3b429e, 0xff2c2c79, 0xff4249ac, 0xff323289, + 0xff191532, 0xff4c51a2, 0xff393998, 0xff211e48, 0xff100104, 0xff100000, + 0xff180b1f, 0xff251c4a, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff4751a7, 0xff3b3b9e, 0xff424ea6, 0xff1f173f, 0xff3e4293, + 0xff363694, 0xff3b4598, 0xff353592, 0xff424793, 0xff373796, 0xff3b3f8f, + 0xff393a9b, 0xff393a89, 0xff4244a1, 0xff2d2f7a, 0xff27225c, 0xff272460, + 0xff4a50b1, 0xff3e3ea5, 0xff383b95, 0xff4b53c0, 0xff4343ae, 0xff3a3c98, + 0xff100206, 0xff100000, 0xff2a225b, 0xff1d112e, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff1a0e22, 0xff545bc6, 0xff3e42a0, 0xff464db5, + 0xff231b47, 0xff4f58b7, 0xff3e3ea3, 0xff4e53ab, 0xff393998, 0xff4045a8, + 0xff4040a7, 0xff3d4798, 0xff4141ab, 0xff3d459a, 0xff4242ad, 0xff3a4094, + 0xff4444b0, 0xff3c439c, 0xff4445b1, 0xff2d2c76, 0xff1d1736, 0xff4c54bf, + 0xff36358e, 0xff11030a, 0xff0f0000, 0xff100000, 0xff4547ab, 0xff1b0f29, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff3a3671, 0xff494bb6, + 0xff4c52a4, 0xff5052b1, 0xff2b2663, 0xff4b52c0, 0xff4445b1, 0xff4344af, + 0xff2d2a70, 0xff4d58be, 0xff3e3ea2, 0xff4149a6, 0xff4040a7, 0xff464da6, + 0xff4444b1, 0xff454ca2, 0xff4444b0, 0xff414ca1, 0xff4444b3, 0xff343585, + 0xff323473, 0xff4a4cc3, 0xff3f45a1, 0xff1e182d, 0xff100000, 0xff190e26, + 0xff758bf0, 0xff21173f, 0xff100000, 0xff100000, 0xff100000, 0xff100001, + 0xff5052af, 0xff4545b8, 0xff4e51bd, 0xff4444b4, 0xff36378f, 0xff525ac3, + 0xff333284, 0xff12050e, 0xff170915, 0xff4c52c6, 0xff4343b2, 0xff5053c2, + 0xff3a3a9c, 0xff4045aa, 0xff4848be, 0xff484abf, 0xff4242b0, 0xff3f45a6, + 0xff4545b7, 0xff4343b2, 0xff474cab, 0xff4545b9, 0xff4646bd, 0xff1f1a45, + 0xff160918, 0xff5e65c0, 0xffc4d6f6, 0xff4244a4, 0xff100103, 0xff100000, + 0xff100000, 0xff1a0e23, 0xff575cd5, 0xff4140aa, 0xff34307b, 0xff4949c3, + 0xff3d439f, 0xff4b4ec4, 0xff2b2666, 0xff100000, 0xff13040a, 0xff313279, + 0xff3f3fa9, 0xff3e41a5, 0xff333681, 0xff333183, 0xff4041ad, 0xff4248ae, + 0xff4751b6, 0xff5467ca, 0xff556bcc, 0xff5870d1, 0xff7385d6, 0xff7b87d3, + 0xff9096d5, 0xff969fd7, 0xffb6bef0, 0xffebeff9, 0xfffafafa, 0xffadc5f7, + 0xff5567c8, 0xff2e2768, 0xff100000, 0xff373872, 0xff5154d4, 0xff332e7a, + 0xff33326d, 0xff4d4dcf, 0xff474fa7, 0xff4444b4, 0xff2d2761, 0xff2a2751, + 0xff3a4186, 0xff4b52bb, 0xff535ed5, 0xff5762df, 0xff5666e6, 0xff5a66ef, + 0xff5b6bee, 0xff5b73d9, 0xff5062b6, 0xff444f9c, 0xff3d4685, 0xff373b71, + 0xff373769, 0xff433b67, 0xff433c66, 0xff433e70, 0xff7179d1, 0xffccd9f6, + 0xffd1dbf4, 0xff6166bd, 0xff201639, 0xff110205, 0xff100001, 0xff525abb, + 0xff5050d7, 0xff231a45, 0xff3c3a63, 0xff3d3da4, 0xff3e46a1, 0xff404ba1, + 0xff3f47a2, 0xff3f42a7, 0xff4545b7, 0xff4c4ccb, 0xff5050d7, 0xff4e4fd1, + 0xff393792, 0xff251c4d, 0xff160a1b, 0xff100103, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff1a0f29, 0xff6d87f4, 0xff5b67d8, 0xff150712, 0xff100000, 0xff100000, + 0xff1c1227, 0xff5b66de, 0xff4646bf, 0xff261f4e, 0xff3c4389, 0xff3c4599, + 0xff2f317c, 0xff2d2d7a, 0xff303081, 0xff34348f, 0xff383898, 0xff3b3b9e, + 0xff2a2a64, 0xff150817, 0xff0f0000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100103, 0xff5863e1, 0xff2e286a, 0xff100000, + 0xff100000, 0xff100000, 0xff38386d, 0xff4143aa, 0xff3f499e, 0xff374089, + 0xff2b2b73, 0xff2b2b75, 0xff2a2a73, 0xff2b2b74, 0xff2d2d7b, 0xff303081, + 0xff2c2e75, 0xff150f1c, 0xff0f0000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff4c4bc6, + 0xff150815, 0xff100000, 0xff100000, 0xff100000, 0xff3a438e, 0xff353f84, + 0xff262766, 0xff262665, 0xff262666, 0xff272769, 0xff272769, 0xff28286d, + 0xff292970, 0xff272769, 0xff120a0f, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100001, 0xff3a358f, 0xff0f0000, 0xff100000, 0xff100000, 0xff100000, + 0xff170e10, 0xff16060e, 0xff13050e, 0xff19060e, 0xff19070e, 0xff110103, + 0xff100002, 0xff100002, 0xff100002, 0xff100001, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff13050e, 0xff28215b, 0xff100000, 0xff100000, + 0xff100000, 0xff100000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000,}; + +static unsigned char sdlappicon_mask[] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255,}; + +struct sdlappicon sdlappicon = { + 32,32, // width,height + sdlappicon_pixels, + sdlappicon_mask +}; diff --git a/polymer/build/rsrc/build_icon.ico b/polymer/build/rsrc/build_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d585cc1569ed4bc75982a81982d15cdeba8565a4 GIT binary patch literal 2998 zcmds(J&4>!7>2*Kr!ZJZnmhXnqr!0!;x5Nj1{c9Aso6ESx!T=yw+i@zA*8sSY zFsWSR7m~%8sL467%Q-1>Q`=2kUE#3ghz%(WDJIWIyEb-yAmAn$X;wS$_s#b{Gpk*# z$Uu(C*|RxUB|je%c~gY3Fg_t)oDfNmi@X&z`aATP_s?xtgj05R`wOqUmDy}2v!7=2 zPdPc0!MyPL zqNi=1-um_{k?)I(`CvUtdwcJHJ{RwcJn`#(-}`y;AqJkKC>RxQ%N-0Z7RCDd{(OH< z^%>*h_(Y5%Bsfr_TW5^x!9W-DzMhr>&%r7zWHK5stgx*_vjwo zqkD9Z9vBD4!7CF)g>D^|wKzJO1QlQ~Fc=sN419U$K^Yhf3FvJ zJ~FTe9tMw}hmGG2I=OK8$iW_XIDF*b^YE;}!{TA_uy|NJEFKmQi^tQ$!tV_o9Tp#1 z_)I)3KJG`yV%QT)M}r~25MT%}1Q-Gg0fqpBhatcaVDK;m7y=9dh5$o=A;1t|2rvW~ z0t^9$07Jmv;~(%3_*-gN#ukpy)s8th8>({TV8#ivKTeohhgM$Ng_wHTw z@Zm%C=+Pr}czCE5i-mgn^r?FG?3wzz=Tdw!g?PkA)$4vvQTyMvG`7E-l$KGhs&d)> zlvTxeSuHcF^3{Yo3RzPRV+LujW;C5a)95Z()pb)>!xu%ejV2DtrY!5Kroy;sn#04U zSsFHH&NN9hsJghMeVHz8XXob4?|us(M~g{4uB)a>({atzx~5n>b=sWiS5S|dl9X~B z83}PvF_-K;%6A5}9#^9njg5Gjk1N=!EXIXM-iP8VyG0>R(EB)C`I4sfp`(!=WmrAWDa&DAWo47pWj!P?EE`=7d$^bcl7K`kXC<_%rcA%ME1k%$d@;?Y z3u&`c(`-$qTDPmeH8SkxZ=aI2HEC13&BSRY)3sHB;WRznX0OE4_W1(Wj-vmR^GF}r OMJp2hr>p7z>+2tGa-44f literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/editor_banner.c b/polymer/build/rsrc/editor_banner.c new file mode 100644 index 000000000..eecb4c98c --- /dev/null +++ b/polymer/build/rsrc/editor_banner.c @@ -0,0 +1,2267 @@ +#include + + + + + + + +/* GdkPixbuf RGB C-Source image dump */ + +const GdkPixdata startbanner_pixdata = { + 0x47646b50, /* Pixbuf magic: 'GdkP' */ + 24 + 76160, /* header length + pixel_data length */ + 0x1010001, /* pixdata_type */ + 272, /* rowstride */ + 90, /* width */ + 280, /* height */ + /* pixel_data: */ + "\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2" + "\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\0\"M" + "\4\37M\4\37M\0\"M\0\"M\4\37M\0\"M\0#O\0#O\0$P\0#O\0$P\0$P\14#Q\0%Q\0" + "$P\0$P\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T" + "\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X" + "\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\0\0\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\15@s\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\24" + "Cw\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\32" + "G{\32G{\34H|\32G{\32G{\35I}\35I}\35I}\35I}\34H|\20L\177\20L\177\20L\177" + "\35I}\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P" + "\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\0\0\2\36E\2\36E\2\36E\2\36E" + "\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5" + "\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\0" + "#O\0\"M\14#Q\0$P\0$P\0$P\0#O\14#Q\0%Q\0$P\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14" + "#Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2" + "'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12" + "+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17At\15@s\17" + "At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30" + "Ey\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\34H|\34H|\34H|\32G{\35I}\35I}\35" + "I}\20L\177\35I}\35I}\20L\177\20L\177\20L\177\22M\200\22M\200\22M\200" + "\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\27P" + "\203\27P\203\27P\203\27P\203\35I}\27P\203\27P\203\27P\203\27P\203\33" + "Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205" + "\33Q\205\33Q\205\0\0\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H" + "\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\0\"M\4\37" + "M\4\37M\4\37M\0\"M\4\37M\4\37M\0\"M\0#O\0\"M\0#O\0#O\0#O\0$P\0$P\0$P" + "\0%Q\14#Q\0$P\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14" + "#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X" + "\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,ZK\312\363K\312\363\13,Z\13,Z\13,Z\0\0" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23" + "Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\24Cw\30Ey\30" + "Ey\30Ey\32G{\32G{\32G{\34H|\34H|\34H|\35I}\35I}\35I}\35I}\34H|\20L\177" + "\20L\177\35I}\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P" + "\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33" + "Q\205\0\0\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40" + "H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\4\37M\4\37M\4\37M\0" + "\"M\0\"M\4\37M\0\"M\14#Q\0\"M\0$P\0$P\0$P\0$P\0$P\14#Q\0$P\14#Q\0$P\0" + "%Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2" + "'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X" + "\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,ZK\312\363K\312\363\13,Z\13,Z\13,Z\0\0\11>q\11>" + "q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15" + "@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23" + "Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\34" + "H|\32G{\20L\177\34H|\32G{\35I}\35I}\35I}\34H|\20L\177\20L\177\20L\177" + "\35I}\22M\200\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P" + "\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33" + "Q\205\0\0\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40" + "H\5\40H\5\40H\4\37M\4\37M\0\"M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\4\37" + "M\0\"M\0\"M\0#O\0\"M\0$P\0$P\0#O\0$P\0%Q\0$P\14#Q\0$P\14#Q\0%Q\0%Q\14" + "#Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2" + "'T\2'T\10*X\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12" + "+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,ZK\312\363K\312\363\13,Z\13,Z\13,Z\0\0\11>q\11>q\11>" + "q\11>q\11>q\11>q\11>q\11>q\15@s\11>q\11>q\15@s\15@s\15@s\15@s\15@s\17" + "At\15@s\15@s\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\34H|\32" + "G{\34H|\20L\177\35I}\35I}\34H|\35I}\20L\177\20L\177\35I}\20L\177\22M" + "\200\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P" + "\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33" + "Q\205\0\0\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37" + "M\0\"M\4\37M\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\4\37M\0\"M\0\"M" + "\0\"M\14#Q\0#O\0$P\0$P\0#O\0$P\0$P\0%Q\14#Q\0$P\0%Q\0%Q\14#Q\0%Q\14#" + "Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12" + "+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,ZK\312\363K\312\363\13,Z\13,Z\13,Z\0\0\11>q\11>q\11>q\11>" + "q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\17" + "At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24" + "Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\34H|\32G{\34H|\35" + "I}\35I}\34H|\35I}\35I}\20L\177\35I}\20L\177\20L\177\22M\200\22M\200\24" + "N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0" + "\0\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\4\37M\4\37M\4" + "\37M\0\"M\4\37M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\0\"M\0\"M\0#O\0$P\0" + "$P\0$P\0$P\0$P\0$P\0%Q\0$P\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\14#Q" + "\14#Q\0%Q\14#Q\0%Q\14#Q\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12" + "+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15" + "-[\15-[K\312\363K\312\363\15-[\15-[\15-[\0\0\11>q\11>q\11>q\11>q\15@" + "s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\17At\23" + "Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\24" + "Cw\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\34H|\34H|\34H|\32G{\34H|\35I}\35I}\35" + "I}\35I}\35I}\20L\177\35I}\35I}\22M\200\22M\200\22M\200\24N\201\24N\201" + "\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P" + "\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0\0\5" + "\40H\5\40H\5\40H\5\40H\4\37M\4\37M\4\37M\4\37M\0\"M\4\37M\4\37M\4\37" + "M\5\40H\4\37M\0\"M\0\"M\4\37M\0\"M\0#O\0\"M\0#O\0#O\0$P\0#O\0$P\0$P\14" + "#Q\0%Q\0%Q\14#Q\0$P\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\14#Q\0%Q\14#" + "Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\2'T\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[K" + "\312\363K\312\363\15-[\15-[\15-[\0\0\15@s\15@s\15@s\15@s\15@s\15@s\15" + "@s\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23" + "Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30" + "Ey\30Ey\32G{\30Ey\34H|\34H|\34H|\34H|\35I}\35I}\35I}\35I}\35I}\35I}\20" + "L\177\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\35I}\26O\202\26" + "O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0\0\0\"M\4" + "\37M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\4\37M\4\37M\4\37M\0\"M\4\37M\0" + "\"M\4\37M\0\"M\0\"M\0\"M\0#O\0\"M\14#Q\0#O\0$P\0$P\14#Q\0$P\0%Q\14#Q" + "\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\2'" + "T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[K\312\363" + "K\312\363\15-[\15-[\15-[\0\0\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s" + "\15@s\15@s\15@s\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23" + "Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32" + "G{\30Ey\34H|\32G{\34H|\34H|\35I}\35I}\34H|\35I}\20L\177\20L\177\35I}" + "\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O" + "\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0" + "\0\0\"M\4\37M\5\40H\4\37M\4\37M\0\"M\4\37M\0\"M\4\37M\0\"M\0\"M\0\"M" + "\4\37M\0\"M\0#O\0\"M\0\"M\0#O\0$P\0#O\0$P\0#O\14#Q\14#Q\0$P\0%Q\0$P\0" + "%Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2" + "'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12" + "+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[K\312\363" + "K\312\363\15-[\15-[\15-[\0\0\15@s\15@s\15@s\15@s\15@s\15@s\15@s\15@s" + "\23Bv\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24" + "Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\34" + "H|\34H|\34H|\34H|\20L\177\35I}\35I}\35I}\34H|\20L\177\20L\177\20L\177" + "\20L\177\22M\200\22M\200\22M\200\24N\201\26O\202\26O\202\26O\202\26O" + "\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33" + "Q\205\0\0\4\37M\4\37M\0\"M\4\37M\0\"M\4\37M\0\"M\0\"M\0\"M\4\37M\0\"" + "M\0#O\0#O\0\"M\0\"M\0\"M\0$P\0#O\0$P\0$P\0$P\14#Q\0%Q\14#Q\0%Q\0%Q\14" + "#Q\0%Q\0%Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2" + "'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12" + "+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[K" + "\312\363K\312\363\15-[\15-[\15-[\0\0\15@s\15@s\15@s\15@s\15@s\17At\17" + "At\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34" + "H|\34H|\34H|\34H|\35I}\34H|\35I}\35I}\35I}\20L\177\20L\177\35I}\22M\200" + "\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O" + "\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33" + "Q\205\0\0\4\37M\4\37M\0\"M\4\37M\4\37M\4\37M\0\"M\0\"M\0#O\14#Q\0\"M" + "\0\"M\0\"M\0\"M\0\"M\0$P\0$P\0$P\0#O\0$P\0$P\0%Q\14#Q\0%Q\0%Q\0%Q\0%" + "Q\0%Q\0%Q\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\2'T\14#Q\2'T\14#Q\2'T\2" + "'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+" + "Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[K\312\363K\312\363\15-[\15-[\15-[\0\0\15@s\17At\17At\17At\17At\17A" + "t\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\34" + "H|\34H|\20L\177\34H|\34H|\35I}\35I}\35I}\20L\177\20L\177\20L\177\35I" + "}\22M\200\35I}\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R" + "\206\34R\206\34R\206\34R\206\34R\206\34R\206K\312\363K\312\363\33Q\205" + "\33Q\205\33Q\205\0\0\0\"M\0\"M\4\37M\0\"M\4\37M\0\"M\0\"M\0\"M\14#Q\0" + "\"M\0$P\0#O\0$P\0#O\0$P\0$P\0$P\14#Q\0$P\0%Q\0$P\0%Q\14#Q\0%Q\14#Q\0" + "%Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T" + "\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y" + "\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\15-[\15-[\15-[" + "\15-[\15-[K\312\363K\312\363\15-[\15-[\15-[\0\0\17At\17At\17At\23Bv\23" + "Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\20L\177" + "\34H|\34H|\34H|\34H|\20L\177\35I}\35I}\35I}\35I}\20L\177\20L\177\35I" + "}\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\35I}\26O\202" + "\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R" + "\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206K\312\363K\312\363" + "\33Q\205\33Q\205\33Q\205\0\0\4\37M\0\"M\14#Q\0\"M\14#Q\0\"M\0\"M\0\"" + "M\0#O\0$P\0#O\0$P\0#O\0#O\0$P\14#Q\14#Q\14#Q\0$P\14#Q\0$P\0%Q\0%Q\0%" + "Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'" + "T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12" + "+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17" + ".\\\15-[\15-[\15-[K\312\363K\312\363\15-[\15-[\15-[\0\0\23Bv\23Bv\23" + "Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\23Bv\23Bv\24Cw\23Bv\24Cw\24Cw\24" + "Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\34" + "H|\34H|\34H|\34H|\34H|\35I}\20L\177\35I}\35I}\20L\177\35I}\20L\177\20" + "L\177\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R\206\34R\206\34R\206\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206" + "K\312\363K\312\363\34R\206\33Q\205\33Q\205\0\0\0\"M\0\"M\0#O\0\"M\0\"" + "M\0$P\0#O\0$P\0#O\0$P\0#O\0#O\0#O\14#Q\0$P\14#Q\0$P\14#Q\0$P\0%Q\14#" + "Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\2'T\2'T\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12" + "+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[K\312\363K\312\363\15-[\15-[\15" + "-[\0\0\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24" + "Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32" + "G{\30Ey\34H|\34H|\34H|\32G{\34H|\35I}\20L\177\35I}\20L\177\35I}\20L\177" + "\35I}\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202" + "\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R\206\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\34R\206\34R\206\34R\206K\312\363K\312\363\34R\206\33Q\205\33Q\205\0" + "\0\0\"M\0\"M\0\"M\0\"M\0$P\0$P\0$P\0$P\0$P\0#O\0$P\0%Q\14#Q\0$P\14#Q" + "\0$P\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%" + "Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[K" + "\312\363K\312\363\15-[\15-[\15-[\0\0\23Bv\23Bv\24Cw\23Bv\23Bv\23Bv\23" + "Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30" + "Ey\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\34H|\34H|\34H|\35I}\34H|\35I}\34" + "H|\35I}\20L\177\20L\177\20L\177\20L\177\22M\200\35I}\24N\201\24N\201" + "\24N\201\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P" + "\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206K\312\363K\312" + "\363\34R\206\33Q\205\33Q\205\0\0\0$P\0#O\0#O\0$P\0$P\0#O\0$P\0$P\0$P" + "\0$P\14#Q\0%Q\14#Q\0%Q\14#Q\0$P\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0" + "%Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\K\312\363K\312\363\15-[\15-[\15-[\0\0\23" + "Bv\23Bv\24Cw\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24" + "Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\34H|\32G{\34" + "H|\32G{\35I}\35I}\35I}\35I}\20L\177\20L\177\35I}\20L\177\35I}\22M\200" + "\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P" + "\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R" + "\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207K\312\363K\312\363\34R\206\33Q\205\33Q\205\0\0\0" + "$P\0#O\0$P\0#O\5\40H\0$P\0%Q\14#Q\0$P\0%Q\14#Q\0%Q\0$P\14#Q\0%Q\0%Q\0" + "%Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\2'T" + "\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15" + "-[K\312\363K\312\363\15-[\15-[\15-[\0\0\23Bv\23Bv\23Bv\23Bv\23Bv\24C" + "w\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\24Cw\30Ey\30Ey\30Ey\30" + "Ey\30Ey\30Ey\32G{\30Ey\34H|\20L\177\34H|\34H|\34H|\35I}\35I}\35I}\34" + "H|\20L\177\20L\177\35I}\20L\177\22M\200\22M\200\24N\201\24N\201\24N\201" + "\26O\202\26O\202\26O\202\35I}\27P\203\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206" + "K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0\0\0$P\0$P\0$P\0#O\14#Q\0" + "%Q\14#Q\0%Q\14#Q\0$P\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\14" + "#Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T" + "\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13," + "Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[K\312\363K\312\363" + "\15-[\15-[\15-[\0\0\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24C" + "w\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\32" + "G{\34H|\32G{\34H|\35I}\35I}\35I}\20L\177\35I}\20L\177\20L\177\20L\177" + "\22M\200\35I}\22M\200\22M\200\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206K\312\363K\312" + "\363\33Q\205\33Q\205\33Q\205\0\0\14#Q\14#Q\0$P\14#Q\14#Q\0$P\14#Q\0$" + "P\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q" + "\14#Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*" + "X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17." + "\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[K\312\363K\312\363\15-" + "[\15-[\15-[\0\0\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24" + "Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\34H|\32G{\34H|\32" + "G{\20L\177\35I}\20L\177\35I}\35I}\35I}\20L\177\20L\177\20L\177\20L\177" + "\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O" + "\202\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R" + "\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206\33Q\205K\312\363" + "K\312\363\33Q\205\33Q\205\33Q\205\0\0\0$P\14#Q\0%Q\0$P\14#Q\0$P\14#Q" + "\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0" + "%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[K\312\363K\312\363\15-" + "[\15-[\13,Z\0\0\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\24" + "Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\34H|\32G{\34H|\32" + "G{\35I}\35I}\20L\177\35I}\20L\177\20L\177\20L\177\20L\177\35I}\22M\200" + "\35I}\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R\206\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\34R\206\33Q\205\33Q\205\33Q\205K\312\363K\312" + "\363\33Q\205\33Q\205\33Q\205\0\0\14#Q\14#Q\0$P\0%Q\0$P\0$P\14#Q\0%Q\0" + "%Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\2'" + "T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*" + "X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[K\312\363K\312\363\15-[\13," + "Z\13,Z\0\0\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\24Cw\30Ey\30" + "Ey\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\20L\177\34H|\32G{\20L\177\32G{" + "\20L\177\35I}\34H|\35I}\20L\177\20L\177\20L\177\20L\177\22M\200\22M\200" + "\22M\200\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P" + "\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\34R\206\34R\206\34R\206\33Q\205\33Q\205" + "K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0\0\14#Q\14#Q\0$P\14#Q\0%" + "Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#" + "Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13" + ",Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-[K\312\363" + "K\312\363\13,Z\13,Z\13,Z\0\0\24Cw\24Cw\24Cw\30Ey\24Cw\24Cw\30Ey\24Cw" + "\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\32G{\34H|\34H|\34H|\20" + "L\177\35I}\35I}\35I}\20L\177\35I}\20L\177\20L\177\20L\177\35I}\22M\200" + "\35I}\22M\200\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206\33Q\205\33Q\205\33Q" + "\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0\0\14#Q\0%Q\0" + "%Q\14#Q\0%Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\14#Q\0" + "%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[K\312\363K\312\363\13,Z\13,Z\13,Z\0\0\30Ey\24Cw\24Cw\30Ey\30Ey\30E" + "y\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\34H|\32G{\34" + "H|\20L\177\35I}\35I}\35I}\35I}\35I}\35I}\20L\177\20L\177\35I}\35I}\22" + "M\200\22M\200\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\34R\206\34R\206\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\27P\203\0\0\0" + "%Q\14#Q\0%Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\14#Q\14#Q\0%Q\14#Q\0" + "%Q\0%Q\14#Q\0%Q\14#Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\13,ZK\312\363K\312\363\13,Z\12+Y\12+Y\0\0\30Ey\30Ey\24Cw\30E" + "y\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\32G{\32G{\34H|\34H|\34" + "H|\34H|\34H|\35I}\34H|\35I}\35I}\35I}\35I}\20L\177\20L\177\22M\200\35" + "I}\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\27P\203\27" + "P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\34R\206\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\27P\203\27" + "P\203\0\0\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\14#Q\14#Q\0%Q\14#Q\14" + "#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X" + "\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\13,Z\13,Z\13,ZK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\30E" + "y\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\32G{\34H|\20" + "L\177\32G{\32G{\34H|\34H|\35I}\20L\177\35I}\35I}\35I}\20L\177\20L\177" + "\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O" + "\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206\34R\206" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205K\312" + "\363K\312\363\27P\203\27P\203\26O\202\0\0\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\14" + "#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2" + "'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y" + "\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,ZK\312\363K\312" + "\363\12+Y\12+Y\10*X\0\0\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{" + "\30Ey\32G{\32G{\34H|\32G{\34H|\32G{\34H|\35I}\35I}\35I}\35I}\35I}\20" + "L\177\20L\177\20L\177\20L\177\22M\200\22M\200\22M\200\35I}\24N\201\26" + "O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\34R\206\34R\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205K\312\363K\312\363\27P\203\26O\202\26O\202\0\0\14" + "#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q" + "\0%Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13" + ",Z\13,Z\12+YK\312\363K\312\363\10*X\10*X\10*X\0\0\30Ey\30Ey\30Ey\30E" + "y\30Ey\30Ey\30Ey\32G{\30Ey\32G{\34H|\34H|\32G{\20L\177\34H|\34H|\20L" + "\177\35I}\34H|\35I}\35I}\20L\177\20L\177\20L\177\20L\177\22M\200\22M" + "\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\27P\203\33Q\205\27P\203\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R\206" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\34R\206\34R\206\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203K\312\363" + "K\312\363\26O\202\26O\202\26O\202\0\0\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#" + "Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'" + "T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+" + "Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-" + "[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+YK\312\363K\312" + "\363\10*X\10*X\10*X\0\0\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\30Ey" + "\34H|\34H|\34H|\32G{\32G{\34H|\34H|\35I}\34H|\35I}\20L\177\20L\177\20" + "L\177\35I}\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26" + "O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R\206\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\27P\203\27P\203\27P\203K\312\363K\312\363\26O\202\24N\201\24N\201" + "\0\0\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0" + "%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X" + "\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13" + ",Z\12+Y\12+Y\12+Y\10*XK\312\363K\312\363\10*X\10*X\10*X\0\0\30Ey\30E" + "y\30Ey\30Ey\30Ey\32G{\30Ey\30Ey\32G{\34H|\32G{\20L\177\34H|\34H|\34H" + "|\35I}\35I}\20L\177\35I}\20L\177\35I}\20L\177\20L\177\22M\200\35I}\22" + "M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\34R\206\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\34R\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P\203\26O\202\26O\202" + "K\312\363K\312\363\24N\201\22M\200\22M\200\0\0\14#Q\0%Q\14#Q\14#Q\0%" + "Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2" + "'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12" + "+Y\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15" + "-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10*X\10*XK\312\363K\312" + "\363\2'T\10*X\2'T\0\0\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\32G{\34H|\34" + "H|\32G{\34H|\34H|\20L\177\35I}\20L\177\35I}\35I}\20L\177\20L\177\20L" + "\177\35I}\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26" + "O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205" + "\33Q\205\33Q\205\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R" + "\206\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\34R\206\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P" + "\203\27P\203\26O\202\26O\202\26O\202K\312\363K\312\363\22M\200\20L\177" + "\35I}\0\0\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*" + "X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15" + "-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12" + "+Y\10*X\10*X\10*X\10*XK\312\363K\312\363\2'T\2'T\2'T\0\0\30Ey\30Ey\32" + "G{\30Ey\32G{\32G{\34H|\32G{\34H|\34H|\34H|\32G{\35I}\35I}\34H|\35I}\35" + "I}\35I}\35I}\20L\177\20L\177\22M\200\35I}\22M\200\24N\201\24N\201\26" + "O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\34R\206\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P" + "\203\27P\203\27P\203\26O\202\26O\202\26O\202\24N\201\24N\201K\312\363" + "K\312\363\35I}\20L\177\35I}\0\0\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0" + "%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\" + "\17.\\\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12" + "+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*XK\312\363K\312\363\2'T\2'T" + "\2'T\0\0\30Ey\32G{\32G{\32G{\32G{\32G{\34H|\20L\177\32G{\34H|\34H|\35" + "I}\20L\177\35I}\35I}\35I}\20L\177\20L\177\20L\177\20L\177\35I}\22M\200" + "\22M\200\24N\201\35I}\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202\26O\202" + "\24N\201\22M\200\22M\200K\312\363K\312\363\35I}\35I}\35I}\0\0\0%Q\0%" + "Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\14#Q\2'T\2'T\2'" + "T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+" + "Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13" + ",Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2" + "'TK\312\363K\312\363\14#Q\2'T\0%Q\0\0\30Ey\30Ey\32G{\32G{\34H|\34H|\34" + "H|\32G{\34H|\34H|\20L\177\35I}\35I}\35I}\35I}\20L\177\35I}\20L\177\20" + "L\177\35I}\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26" + "O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R" + "\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P\203\26O\202\26O\202\26O" + "\202\26O\202\24N\201\22M\200\35I}\20L\177\20L\177K\312\363K\312\363\35" + "I}\34H|\20L\177\0\0\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\17" + ".\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15-" + "[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12+Y\10*X\10*X\10*X\14" + "#Q\10*X\10*X\2'T\2'T\2'TK\312\363K\312\363\0%Q\14#Q\0%Q\0\0\30Ey\32G" + "{\32G{\32G{\34H|\34H|\32G{\20L\177\34H|\34H|\35I}\35I}\35I}\35I}\35I" + "}\35I}\20L\177\35I}\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26" + "O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206\34R\206\36S\207\36S\207" + "\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\36S" + "\207\34R\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P\203\26O" + "\202\26O\202\26O\202\24N\201\22M\200\22M\200\35I}\20L\177\20L\177\35" + "I}K\312\363K\312\363\32G{\34H|\32G{\0\0\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%" + "Q\0%Q\0%Q\2'T\2'T\14#Q\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\17.\\\17.\\" + "\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[" + "\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10" + "*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'TK\312\363K\312\363\14#Q\0%" + "Q\0%Q\0\0\30Ey\32G{\20L\177\34H|\34H|\20L\177\34H|\34H|\32G{\34H|\35" + "I}\35I}\34H|\35I}\20L\177\20L\177\20L\177\35I}\22M\200\35I}\22M\200\24" + "N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203" + "\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\34R\206" + "\34R\206\34R\206\36S\207\36S\207\36S\207\36S\207\36S\207\36S\207\34R" + "\206\34R\206\34R\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P" + "\203\26O\202\26O\202\26O\202\26O\202\24N\201\22M\200\22M\200\35I}\20" + "L\177\20L\177\35I}\35I}K\312\363K\312\363\32G{\30Ey\30Ey\0\0\0%Q\14#" + "Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\17.\\\17.\\\17.\\\17.\\\17.\\\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10" + "*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\2'T\0%QK\312\363K\312\363" + "\14#Q\0%Q\0%Q\0\0\32G{\30Ey\34H|\32G{\34H|\20L\177\34H|\34H|\34H|\35" + "I}\35I}\35I}\35I}\20L\177\35I}\20L\177\20L\177\20L\177\35I}\22M\200\24" + "N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203" + "\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R" + "\206\34R\206\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\35I}\26O\202" + "\26O\202\26O\202\26O\202\24N\201\22M\200\22M\200\20L\177\20L\177\35I" + "}\35I}\35I}\32G{\34H|K\312\363K\312\363\30Ey\30Ey\30Ey\0\0\14#Q\0%Q\0" + "%Q\0%Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\10*X\10*" + "X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\14#Q\0%Q\14#QK\312\363K\312\363\0%Q" + "\0%Q\14#Q\0\0\32G{\34H|\32G{\34H|\32G{\34H|\20L\177\35I}\20L\177\35I" + "}\35I}\35I}\35I}\20L\177\35I}\20L\177\20L\177\22M\200\22M\200\22M\200" + "\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P" + "\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206\34R\206" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\27P\203\33Q\205\33Q\205\27P\203\27P\203\27P\203\26O\202\26O\202" + "\26O\202\26O\202\24N\201\22M\200\35I}\20L\177\20L\177\20L\177\35I}\20" + "L\177\34H|\34H|\32G{\32G{K\312\363K\312\363\30Ey\24Cw\24Cw\0\0\14#Q\0" + "%Q\14#Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'" + "T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10" + "*X\10*X\2'T\2'T\2'T\2'T\2'T\0%Q\0%Q\0%Q\0%Q\0%QK\312\363K\312\363\14" + "#Q\14#Q\0#O\0\0\32G{\34H|\34H|\34H|\34H|\34H|\34H|\35I}\34H|\35I}\35" + "I}\35I}\20L\177\35I}\20L\177\20L\177\22M\200\22M\200\22M\200\24N\201" + "\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P" + "\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202" + "\24N\201\24N\201\22M\200\22M\200\35I}\20L\177\35I}\35I}\35I}\32G{\34" + "H|\30Ey\30Ey\30EyK\312\363K\312\363\24Cw\24Cw\24Cw\0\0\0%Q\0%Q\0%Q\14" + "#Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\2'T\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2" + "'T\2'T\2'T\2'T\14#Q\0%Q\14#Q\14#Q\14#Q\0%QK\312\363K\312\363\0%Q\0$P" + "\0$P\0\0\34H|\34H|\20L\177\34H|\34H|\34H|\34H|\35I}\20L\177\35I}\35I" + "}\34H|\20L\177\20L\177\35I}\20L\177\22M\200\22M\200\24N\201\24N\201\26" + "O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203" + "\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202\24N\201\24N\201\22M" + "\200\22M\200\35I}\35I}\35I}\35I}\35I}\32G{\34H|\32G{\32G{\30Ey\24Cw\24" + "CwK\312\363K\312\363\23Bv\23Bv\23Bv\0\0\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\2'" + "T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\14#Q\10*X\10*X\10*X" + "\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12" + "+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\14#Q\0%Q\0" + "%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0$PK\312\363K\312\363\0$P\0\"M\4\37M\0\0\34H" + "|\20L\177\34H|\32G{\34H|\20L\177\35I}\35I}\34H|\35I}\35I}\20L\177\20" + "L\177\20L\177\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\35I}\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P\203" + "\27P\203\26O\202\26O\202\35I}\24N\201\22M\200\22M\200\20L\177\20L\177" + "\35I}\35I}\34H|\34H|\32G{\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24CwK\312\363" + "K\312\363\23Bv\23Bv\17At\0\0\0%Q\0%Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T" + "\14#Q\2'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12" + "+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12+Y\10*X\10*X\10" + "*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\2'T\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0" + "%Q\0%Q\14#QK\312\363K\312\363\0#O\0\"M\4\37M\0\0\32G{\34H|\34H|\20L\177" + "\34H|\20L\177\35I}\35I}\34H|\35I}\35I}\35I}\20L\177\20L\177\22M\200\22" + "M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202" + "\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\27P\203\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202\24N" + "\201\22M\200\22M\200\20L\177\20L\177\20L\177\35I}\35I}\32G{\34H|\34H" + "|\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23BvK\312\363K\312\363\17At\15@" + "s\15@s\0\0\0%Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2" + "'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12" + "+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\12+Y\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2'T\2'" + "T\2'T\2'T\2'T\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0$P\14#Q\0#O\0\"MK\312\363" + "K\312\363\0\"M\4\37M\5\40H\0\0\34H|\32G{\34H|\32G{\32G{\35I}\34H|\35" + "I}\35I}\35I}\20L\177\20L\177\20L\177\20L\177\22M\200\22M\200\24N\201" + "\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P" + "\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P" + "\203\27P\203\26O\202\26O\202\26O\202\24N\201\24N\201\22M\200\22M\200" + "\35I}\20L\177\35I}\35I}\35I}\32G{\34H|\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw" + "\24Cw\23Bv\23Bv\23BvK\312\363K\312\363\15@s\11>q\11>q\0\0\0%Q\14#Q\0" + "%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\14#Q\10*X\10" + "*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\15" + "-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12+Y\10" + "*X\10*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\14#Q\2'T\14#Q\0%Q\0%Q\14" + "#Q\14#Q\0%Q\0%Q\14#Q\0$P\0#O\0#O\0\"M\0\"MK\312\363K\312\363\4\37M\5" + "\40H\0\"M\0\0\34H|\34H|\32G{\32G{\35I}\20L\177\35I}\20L\177\35I}\20L" + "\177\20L\177\20L\177\35I}\20L\177\22M\200\22M\200\24N\201\24N\201\26" + "O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\35I}\27P\203\27" + "P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\27P\203\27P\203\27P\203\27P\203\26O\202\26O\202\26O" + "\202\35I}\24N\201\35I}\22M\200\20L\177\20L\177\35I}\35I}\35I}\34H|\34" + "H|\34H|\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@sK\312\363" + "K\312\363\11>q\11>q\11>q\0\0\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'" + "T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12" + "+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\15-[\15" + "-[\15-[\15-[\15-[\15-[\15-[\15-[\15-[\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\12+Y\12+Y\12+Y\12+Y\10*X\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2" + "'T\14#Q\2'T\2'T\0%Q\0%Q\14#Q\14#Q\14#Q\14#Q\0%Q\0$P\0%Q\14#Q\0#O\0\"" + "M\0\"M\0\"M\4\37MK\312\363K\312\363\5\40H\2\36E\5\40H\0\0\32G{\34H|\34" + "H|\20L\177\35I}\35I}\35I}\34H|\35I}\20L\177\20L\177\20L\177\20L\177\22" + "M\200\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P\203\27P\203" + "\27P\203\26O\202\26O\202\26O\202\26O\202\24N\201\22M\200\22M\200\20L" + "\177\20L\177\20L\177\35I}\35I}\34H|\32G{\34H|\32G{\30Ey\30Ey\24Cw\24" + "Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\17At\15@sK\312\363K\312\363\11>q\11" + ">q\6=p\0\0\0%Q\0%Q\0%Q\0%Q\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10" + "*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+Y\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\12+Y\12+Y\12+Y\12+Y\10" + "*X\10*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\2'T\0%Q\0%Q\0%Q\0%Q\0" + "%Q\14#Q\0%Q\0$P\0%Q\0$P\0#O\0$P\0\"M\4\37M\4\37M\4\37M\5\40HK\312\363" + "K\312\363\5\40H\2\36E\2\36E\0\0\32G{\34H|\32G{\34H|\35I}\35I}\35I}\34" + "H|\34H|\20L\177\35I}\20L\177\20L\177\22M\200\22M\200\24N\201\24N\201" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P" + "\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\27P\203\27P\203\27P\203\27P\203\26O\202\26O\202\35I}\26O\202\24N\201" + "\24N\201\22M\200\22M\200\20L\177\20L\177\35I}\35I}\35I}\20L\177\34H|" + "\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\11" + ">q\11>qK\312\363K\312\363\6=p\4q\11>q\11>qK\312\363K\312\363\4q\11>q\11>q\11>q\6=pK\312" + "\363K\312\363\2" + "\0\0\34H|\32G{\35I}\35I}\35I}\35I}\20L\177\20L\177\35I}\20L\177\20L\177" + "\22M\200\22M\200\22M\200\35I}\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203\27P" + "\203\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202\26O\202\26O\202" + "\24N\201\35I}\22M\200\20L\177\35I}\20L\177\34H|\35I}\35I}\32G{\34H|\30" + "Ey\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\17At\15@s\15@s\11>q\11" + ">q\11>q\11>q\11>q\6=p\6=pK\312\363K\312\363\0:l\2\10\32=\11\33>\0\0\32G{\34H|\35I}\35I}\35I}\35I}\20L" + "\177\20L\177\35I}\20L\177\20L\177\22M\200\22M\200\35I}\24N\201\24N\201" + "\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P" + "\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\27P\203\27P\203\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202" + "\35I}\26O\202\24N\201\24N\201\22M\200\22M\200\20L\177\20L\177\35I}\20" + "L\177\35I}\32G{\32G{\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23" + "Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\6=p\6=p\4K\312\363K\312\363\11\33>\10\32=\0" + "\34C\0\0\34H|\34H|\34H|\34H|\35I}\35I}\35I}\35I}\20L\177\20L\177\22M" + "\200\35I}\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26" + "O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201\24N\201\22M\200\22M" + "\200\20L\177\20L\177\35I}\35I}\35I}\34H|\32G{\32G{\30Ey\30Ey\30Ey\24" + "Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\6" + "=p\6=p\2q\11>q\11>q\11>q\6=p\4\0\34C\10\32=\11\33>K\312\363K\312\363\10\32=\0\32:\0\32:\0\0" + "\34H|\34H|\20L\177\35I}\35I}\35I}\20L\177\20L\177\35I}\20L\177\22M\200" + "\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P" + "\203\27P\203\27P\203\27P\203\27P\203\26O\202\26O\202\26O\202\26O\202" + "\26O\202\24N\201\24N\201\22M\200\22M\200\22M\200\35I}\20L\177\35I}\34" + "H|\35I}\32G{\34H|\32G{\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23" + "Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\6=p\4\11\33>\10\32=K\312" + "\363K\312\363\0\32:\10\32=\5\30:\0\0\34H|\34H|\35I}\35I}\35I}\20L\177" + "\20L\177\20L\177\35I}\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P" + "\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\26O\202\26O" + "\202\26O\202\26O\202\26O\202\24N\201\24N\201\22M\200\22M\200\22M\200" + "\20L\177\20L\177\20L\177\20L\177\35I}\34H|\32G{\34H|\32G{\30Ey\30Ey\30" + "Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\6" + "=p\4\10\32=\11\33>\0\34C\10\32=\10\32=K\312\363K\312\363\0\32:\5" + "\30:\5\30:\0\0\34H|\35I}\35I}\35I}\35I}\20L\177\35I}\20L\177\35I}\22" + "M\200\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\27P\203\35I}\27P\203\27P\203\27P\203\27P\203" + "\27P\203\27P\203\35I}\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201\24N" + "\201\22M\200\22M\200\20L\177\20L\177\35I}\35I}\35I}\35I}\34H|\32G{\34" + "H|\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\11" + ">q\11>q\11>q\11>q\6=p\4\0\34C\11\33>\10\32=\0\32:\10\32=\10\32=\10\32=\0\32" + ":K\312\363K\312\363\5\30:\5\30:\0\32:\0\0\35I}\34H|\35I}\35I}\20L\177" + "\35I}\20L\177\35I}\22M\200\22M\200\35I}\24N\201\24N\201\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P" + "\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\27P\203\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\35I}\24N\201\22M\200\35I}\22M\200\20L\177\35I}\35I}\20L\177\35I" + "}\34H|\34H|\34H|\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17" + "At\15@s\15@s\11>q\376\377\374\376\377\374\376\377\374^\203\243\6=p\6" + "=p\2\0\34C\0\32:\10\32=\11\33>\10\32=\10\32=\10\32=\0\32:\0\32:K" + "\312\363K\312\363\5\31""6\0\32:\0\32:\0\0\35I}\20L\177\35I}\35I}\20L" + "\177\35I}\20L\177\20L\177\22M\200\35I}\22M\200\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N" + "\201\24N\201\22M\200\22M\200\22M\200\20L\177\35I}\20L\177\20L\177\35" + "I}\34H|\34H|\32G{\32G{\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\23Bv\23Bv\23Bv\23" + "Bv\17At\15@s\15@s\11>q\11>q\326\336\347\376\377\374\376\377\3745_\211" + "\2\0\34C\0\34C\0\32:\0\32:\10\32=\10\32=\10\32=\0\32:" + "\0\32:\5\30:\5\30:K\312\363K\312\363\0\32:\0\32:\5\31""6\0\0\34H|\35" + "I}\34H|\35I}\35I}\20L\177\35I}\20L\177\22M\200\22M\200\22M\200\24N\201" + "\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\35I}\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26" + "O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201" + "\24N\201\22M\200\22M\200\35I}\20L\177\20L\177\35I}\35I}\35I}\34H|\34" + "H|\20L\177\34H|\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17" + "At\15@s\15@s\11>q\11>q\11>q\11>q\36Ky\331\342\352\376\377\374\363\370" + "\373`|\235\0:l\0:l\0:l\21""9f\17""8e\17""8e\17""8e\17""8e\13""6c\10""4" + "a\10""4a\10""4aK\312\363K\312\363\10""4a\6""3`\4""3_\0\0\2'T\2'T\2'T" + "\2'T\2'T\2'T\2'T\10*X\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*" + "X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\14" + "#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0#O\0$P\0\"M\0\"M\0\"M" + "\4\37M\0\"M\5\40H\5\40H\2\36E\2\36E\213\232\255\235\251\266\367\375\377" + "\376\377\374\376\377\374\325\332\334\235\251\266\216\232\247\215\230" + "\245\215\230\245\210\227\252\215\230\245\215\230\245\215\230\245\5\30" + ":\5\30:\5\30:K\312\363K\312\363\0\32:\5\31""6\5\31""6\0\0\35I}\20L\177" + "\35I}\20L\177\20L\177\20L\177\35I}\22M\200\22M\200\22M\200\24N\201\24" + "N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201\24N\201" + "\22M\200\22M\200\22M\200\35I}\20L\177\20L\177\35I}\34H|\35I}\34H|\32" + "G{\34H|\30Ey\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15" + "@s\15@s\11>q\11>q\11>q\11>q\6=p\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\10""4a\10" + "4a\10""4aK\312\363K\312\363\11""6]\6""3`\6""3`\0\0\2'T\2'T\2'T\2'T\2" + "'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X" + "\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\2'T\10*X\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\14#Q\0%" + "Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\0$P\14#Q\0$P\0#O\0\"M\4\37M\4\37M\4\37M" + "\5\40H\0\"M\2\36E\5\40H\2\36E\2\36E\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\5\30" + ":\0\32:\0\32:K\312\363K\312\363\5\31""6\0\32:\5\31""6\0\0\34H|\35I}\35" + "I}\20L\177\20L\177\35I}\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201" + "\26O\202\26O\202\26O\202\26O\202\35I}\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\24N\201\24N\201\24N\201\22M\200\22M\200" + "\20L\177\35I}\35I}\35I}\35I}\35I}\34H|\32G{\34H|\34H|\32G{\30Ey\30Ey" + "\30Ey\30Ey\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11" + ">q\11>q\6=p\4q\11>q\11>q\11>q\6=" + "p\6=p\4\10\32=\0\32:\10\32=\10\32=\0\32:\0\32:\10" + "\32=\5\30:\5\30:\5\30:\0\32:\0\32:\0\32:\5\31""6K\312\363K\312\363\5" + "\31""6\5\31""6\4\30""5\0\0\34H|\20L\177\20L\177\20L\177\20L\177\20L\177" + "\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201\24N\201\24N" + "\201\22M\200\22M\200\22M\200\35I}\20L\177\35I}\35I}\20L\177\35I}\35I" + "}\34H|\20L\177\34H|\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23B" + "v\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\6=p\6=p\2\0\34" + "C\0\32:\11\33>6Kk\235\251\266\333\340\343\362\367\371\362\367\371\326" + "\336\347\235\251\2669Id\0\32:\0\32:\0\32:\5\31""6\5\31""6\5\31""6K\312" + "\363K\312\363\5\31""6\4\30""5\4\30""5\0\0\35I}\20L\177\35I}\20L\177\20" + "L\177\22M\200\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201\24N\201\24N\201" + "\24N\201\22M\200\22M\200\20L\177\20L\177\20L\177\20L\177\34H|\35I}\35" + "I}\34H|\32G{\34H|\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23" + "Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\4\10\32=\205\224" + "\247\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\210\224\241" + "\0\32:\5\31""6\5\31""6\5\31""6K\312\363K\312\363\4\30""5\4\30""5\4\30" + "5\0\0\35I}\20L\177\20L\177\20L\177\22M\200\22M\200\22M\200\35I}\24N\201" + "\24N\201\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N\201" + "\24N\201\24N\201\24N\201\22M\200\22M\200\20L\177\35I}\20L\177\20L\177" + "\34H|\35I}\35I}\34H|\34H|\32G{\32G{\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24" + "Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\6=p\4q\11>q\11>q\11>q\6=p\4\0\34C\0\34C\0\32:\10\32=\10\32=\353\360" + "\363\376\377\374\376\377\374M_u\0\32:\5\30:\5\30:\5\30:\0\32:\0\32:M" + "_u\376\377\374\376\377\374\354\362\364\5\31""6\5\31""6\5\31""6K\312\363" + "K\312\363\4\30""5\4\30""5\4\30""5\0\0\20L\177\35I}\20L\177\22M\200\22" + "M\200\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\24N" + "\201\35I}\24N\201\24N\201\22M\200\35I}\22M\200\22M\200\20L\177\35I}\20" + "L\177\35I}\20L\177\35I}\35I}\20L\177\34H|\34H|\32G{\30Ey\30Ey\30Ey\24" + "Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11" + ">q\6=p\6=p\2q\11>q\11>q\11>q\6=p\4\0\34C\0\32:\10\32=\10\32=\10\32=\10\32=\215\230" + "\245\376\377\374\376\377\374\376\377\374\370\372\367\267\277\307\222" + "\236\253\222\236\253\267\277\307\370\372\367\376\377\374\376\377\374" + "\376\377\374\215\230\245\5\31""6\0\32:\5\31""6K\312\363K\312\363\5\31" + "6\5\31""6\0\32:\0\0\20L\177\20L\177\35I}\22M\200\22M\200\24N\201\24N" + "\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201" + "\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200\35I" + "}\22M\200\20L\177\20L\177\20L\177\20L\177\35I}\35I}\35I}\35I}\32G{\34" + "H|\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\17" + "At\15@s\15@s\15@s\11>q\11>q\11>q\6=p\6=p\4\0\34C\10\32=\10\32" + "=\0\34C\10\32=\10\32=\0\32:\0\32:\201\220\242\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\206\222\237\5\31""6\5\31""6\5\31""6\5\31" + "6K\312\363K\312\363\5\31""6\5\31""6\5\31""6\0\0\20L\177\20L\177\22M\200" + "\22M\200\22M\200\24N\201\24N\201\24N\201\35I}\24N\201\24N\201\24N\201" + "\24N\201\24N\201\24N\201\24N\201\35I}\24N\201\24N\201\24N\201\22M\200" + "\22M\200\22M\200\22M\200\35I}\20L\177\20L\177\20L\177\35I}\20L\177\34" + "H|\35I}\34H|\32G{\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\24" + "Cw\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\6=p\6=p\4\11\33>\10\32=\10\32=\10\32=\0\32:\0\32:\10\32=\5\30:\0\32:9" + "Id\235\251\266\333\340\343\363\370\373\370\372\367\333\340\343\235\251" + "\2668K`\5\31""6\5\31""6\5\31""6\5\31""6\5\31""6\5\31""6K\312\363K\312" + "\363\5\31""6\5\31""6\5\31""6\0\0\22M\200\22M\200\22M\200\22M\200\35I" + "}\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24" + "N\201\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\35I}\22M\200\35" + "I}\20L\177\20L\177\20L\177\20L\177\20L\177\35I}\35I}\32G{\34H|\32G{\30" + "Ey\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\6=p\4\10\32=\11\33>\0\34C\10\32=\0\32:\0\32:\0\32:\10\32=\5" + "\30:\5\30:\5\30:\5\30:\0\32:\5\31""6\0\32:\0\32:\5\31""6\5\31""6\5\31" + "6\5\31""6\5\31""6\5\31""6\5\31""6\5\31""6\5\31""6K\312\363K\312\363\5" + "\31""6\5\31""6\5\31""6\0\0\22M\200\22M\200\22M\200\22M\200\24N\201\24" + "N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201" + "\24N\201\24N\201\22M\200\22M\200\22M\200\22M\200\35I}\20L\177\20L\177" + "\20L\177\20L\177\34H|\35I}\34H|\35I}\20L\177\34H|\34H|\32G{\30Ey\30E" + "y\24Cw\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\15" + "@s\11>q\11>q\11>q\4\10\32=\11\33>\0\32:\10\32=\0\34C\10\32=\10\32" + "=\0\32:\0\32:\5\30:\376\377\374\376\377\374\376\377\374%6P\0\32:\0\32" + ":\5\31""6\0\32:\5\31""6\5\31""6%6P\376\377\374\376\377\374\376\377\374" + "\5\31""6\5\31""6\5\31""6K\312\363K\312\363\5\31""6\0\32:\5\31""6\0\0" + "\22M\200\22M\200\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N" + "\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200" + "\35I}\22M\200\35I}\20L\177\20L\177\20L\177\20L\177\20L\177\35I}\20L\177" + "\34H|\32G{\34H|\32G{\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23" + "Bv\23Bv\17At\17At\15@s\15@s\11>q\11>q\11>q\11>q\6=p\6=p\4\10" + "\32=\11\33>\0\34C\10\32=\0\34C\0\32:\0\32:\0\32:\5\30:\5\30:\376\377" + "\374\376\377\374\376\377\374%6P\5\31""6\0\32:\0\32:\0\32:\0\32:\5\31" + "6;Nc\376\377\374\376\377\374\376\377\374\5\31""6\0\32:\0\32:K\312\363" + "K\312\363\0\32:\5\31""6\0\32:\0\0\22M\200\22M\200\24N\201\24N\201\24" + "N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201" + "\24N\201\22M\200\22M\200\35I}\22M\200\20L\177\20L\177\20L\177\20L\177" + "\20L\177\35I}\34H|\35I}\20L\177\34H|\32G{\34H|\32G{\30Ey\30Ey\30Ey\24" + "Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11" + ">q\6=p\6=p\4\0\34C\11\33>\0\32:\11\33>\0\34C\10\32=\10\32=\0\32:\0\32" + ":\215\230\245\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\343\350\353\0\32:\5\31""6\0\32:K\312\363K\312\363\5\30:\5\30:\5\30:" + "\0\0\22M\200\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201" + "\35I}\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\22M\200\22M\200" + "\20L\177\20L\177\20L\177\20L\177\35I}\35I}\35I}\20L\177\34H|\32G{\34" + "H|\20L\177\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17" + "At\15@s\15@s\17At\11>q\11>q\11>q\11>q\6=p\4\0\34C\11\33>\10" + "\32=\0\32:\11\33>\10\32=\0\34C\10\32=\0\32:\10\32=\0\32:\215\230\245" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\370\372\3675Mg\0\32:\5\31" + "6\0\32:K\312\363K\312\363\5\30:\5\30:\5\30:\0\0\24N\201\24N\201\24N\201" + "\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\22M" + "\200\22M\200\35I}\22M\200\22M\200\20L\177\20L\177\35I}\20L\177\34H|\35" + "I}\35I}\35I}\34H|\20L\177\34H|\32G{\32G{\30Ey\30Ey\30Ey\30Ey\24Cw\24" + "Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\6=p\6" + "=p\4" + "\11\33>\0\32:\11\33>\10\32=\10\32=\10\32=\0\32:\10\32=\0\32:\0\32:\5" + "\30:\5\30:\5\30:\5\30:\376\377\374\376\377\374\376\377\374%6P\0\32:\4" + "\30""5\0\32:\5\31""6\0\32:\0\32:\0\32:\5\31""6\0\32:\5\31""6\0\32:\5" + "\30:\0\32:K\312\363K\312\363\5\30:\0\32:\10\32=\0\0\24N\201\24N\201\24" + "N\201\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200" + "\35I}\22M\200\22M\200\22M\200\20L\177\20L\177\20L\177\20L\177\20L\177" + "\35I}\34H|\35I}\34H|\32G{\34H|\30Ey\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24" + "Cw\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\6" + "=p\4\10\32=\11\33>\10\32=\10\32=\10\32=\0\34C\0\32:\0\32:\0\32:\5" + "\30:\5\30:\5\30:\5\30:\5\30:\5\30:\5\30:\5\30:\0\32:\0\32:\0\32:\5\31" + "6\0\32:\5\31""6\0\32:\0\32:\0\32:\5\30:\5\30:\5\30:\5\30:\5\30:K\312" + "\363K\312\363\0\32:\10\32=\0\34C\0\0\24N\201\24N\201\24N\201\24N\201" + "\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\22M" + "\200\35I}\20L\177\20L\177\20L\177\20L\177\20L\177\35I}\35I}\35I}\20L" + "\177\34H|\34H|\30Ey\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23B" + "v\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\4\0\34C\10\32=\10\32=\0\32:\0\32:\10\32=\10\32=\214\227\244\214\227" + "\244\214\227\244\30'F\5\30:\214\227\244\214\227\244\214\227\244\214\227" + "\244\214\227\244\214\227\244\214\227\244\214\227\244\214\227\244\214" + "\227\244\214\227\244\214\227\244\214\227\244\214\227\244\5\30:\0\32:" + "\10\32=K\312\363K\312\363\10\32=\10\32=\0\34C\0\0\35I}\24N\201\24N\201" + "\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\22M" + "\200\35I}\20L\177\20L\177\20L\177\20L\177\35I}\35I}\35I}\35I}\34H|\20" + "L\177\34H|\30Ey\32G{\30Ey\30Ey\24Cw\30Ey\24Cw\24Cw\23Bv\23Bv\24Cw\23" + "Bv\17At\15@s\15@s\11>q\15@s\11>q\11>q\11>q\6=p\6=p\4\10" + "\32=\11\33>\10\32=\0\34C\10\32=\10\32=\10\32=\0\32:\0\32:\0\32:\10\32" + "=\376\377\374\376\377\374\376\377\374\37""6U\5\30:\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\0\32:\10\32=\10\32=K\312\363K\312\363\10\32=\0\32:\11\33" + ">\0\0\24N\201\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200" + "\22M\200\22M\200\35I}\20L\177\20L\177\20L\177\20L\177\35I}\35I}\35I}" + "\35I}\34H|\34H|\32G{\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\24" + "Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\4\11\33>\10\32=\10\32=\0\34C\10\32=\0\34C\10\32=\10\32=" + "\10\32=\0\32:\10\32=\0\32:\376\377\374\376\377\374\376\377\374\37""6" + "U\5\30:\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\0\32:\10\32=\0\34CK\312\363K\312" + "\363\0\32:\0\32:\0\34C\0\0\24N\201\24N\201\24N\201\24N\201\24N\201\24" + "N\201\22M\200\22M\200\35I}\22M\200\20L\177\20L\177\20L\177\35I}\20L\177" + "\35I}\20L\177\35I}\35I}\32G{\34H|\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\30Ey" + "\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11" + ">q\6=p\4\0\34C\0\34C\0\0\24N\201" + "\24N\201\24N\201\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\22M" + "\200\35I}\20L\177\35I}\20L\177\35I}\34H|\35I}\35I}\34H|\34H|\34H|\30" + "Ey\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\6=p\6=p\4\10\32=\10\32" + "=\10\32=\0\34C\10\32=\10\32=\10\32=\10\32=\0\32:\0\32:\10\32=\0\32:\0" + "\32:\5\30:\5\30:\5\30:\5\30:\5\30:\5\30:\0\32:\0\32:\10\32=\0\32:\10" + "\32=\10\32=\0\32:\10\32=\10\32=\10\32=\10\32=\0\32:\11\33>\0\32:K\312" + "\363K\312\363\0\34C\0\35D\0\35D\0\0\24N\201\24N\201\24N\201\24N\201\24" + "N\201\22M\200\22M\200\22M\200\22M\200\35I}\20L\177\20L\177\20L\177\35" + "I}\35I}\35I}\35I}\34H|\32G{\34H|\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24" + "Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6" + "=p\6=p\4\0\32:\10\32=\0\34C\10\32" + "=\0\34C\10\32=\10\32=\10\32=\0\32:\0\32:\10\32=\10\32=\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\10\32=\11\33>\0\34CK\312\363K\312\363\0\35D\2\36E\2\36E\0\0" + "\24N\201\24N\201\24N\201\22M\200\22M\200\22M\200\22M\200\22M\200\20L" + "\177\20L\177\35I}\20L\177\35I}\35I}\35I}\34H|\34H|\32G{\34H|\30Ey\30" + "Ey\30Ey\30Ey\24Cw\30Ey\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15" + "@s\11>q\15@s\11>q\11>q\11>q\6=p\6=p\4\0\32:\11" + "\33>\11\33>\10\32=\0\34C\10\32=\10\32=\10\32=\0\32:\10\32=\10\32=\0\32" + ":\10\32=\0\32:\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\0\34C\11\33>\0\35DK\312\363K\312" + "\363\2\36E\2\36E\5\40H\0\0\24N\201\24N\201\24N\201\22M\200\22M\200\22" + "M\200\22M\200\20L\177\20L\177\20L\177\20L\177\35I}\20L\177\35I}\35I}" + "\20L\177\34H|\20L\177\30Ey\30Ey\30Ey\30Ey\24Cw\30Ey\24Cw\24Cw\23Bv\23" + "Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\4q\11>q\0\0\10*X\10*X\10*X\10" + "*X\2'T\10*X\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\14" + "#Q\0%Q\0%Q\14#Q\0$P\0%Q\0$P\0#O\0\"M\0\"M\4\37M\4\37M\0\"M\4\37M\5\40" + "H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\11\33>\0\34C" + "\0\34C\11\33>\11\33>\11\33>\10\32=\10\32=\10\32=\0\34C\10\32=\10\32=" + "\10\32=\0\32:\10\32=\10\32=\0\32:\10\32=\0\32:\10\32=\0\32:\0\32:\0\32" + ":\0\32:\10\32=Pcy\370\372\367\367\375\377\200\217\241*\77_\5\40H\5!C" + "-Cb\201\220\242\370\372\367\367\375\377w\206\231\0\34C\0\35D\0\35D\0" + "\35DK\312\363K\312\363\5\40H\2\36E\2\36E\0\0\24N\201\24N\201\24N\201" + "\22M\200\22M\200\22M\200\20L\177\20L\177\20L\177\20L\177\34H|\35I}\35" + "I}\35I}\32G{\34H|\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23" + "Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=" + "p\2q\11>q\11>q\0\0\10*X\10*" + "X\10*X\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\2'T\2'T\0%Q\0%Q\14#Q\0%Q\0" + "%Q\14#Q\14#Q\14#Q\0%Q\0$P\0%Q\0$P\0$P\0\"M\0\"M\0\"M\4\37M\4\37M\0\"" + "M\4\37M\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0" + "\35D\0\34C\0\34C\0\34C\10\32=\0\32:\0\32:\11\33>\0\32:\10\32=\10\32=" + "\10\32=\10\32=\10\32=\0\34C\0\32:\10\32=\10\32=\0\32:\10\32=\10\32=\0" + "\32:\10\32=\10\32=\0\34C\247\262\300\376\377\374\376\377\374*\77_\10" + "\32=\11\33>\11\33>\10\32=\0\32:\0\34C*\77_\376\377\374\376\377\374\275" + "\305\315\0\35D\2\36E\2\36EK\312\363K\312\363\2\36E\5\40H\5\40H\0\0\24" + "N\201\24N\201\22M\200\22M\200\22M\200\20L\177\20L\177\35I}\20L\177\34" + "H|\35I}\35I}\35I}\20L\177\32G{\34H|\32G{\30Ey\30Ey\30Ey\30Ey\24Cw\24" + "Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11" + ">q\6=p\6=p\4q\11>q\15@s\0\0" + "\10*X\10*X\10*X\2'T\10*X\2'T\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\0%Q\0%Q\14" + "#Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\0$P\0%Q\0$P\0#O\0\"M\14#Q\0\"M\0\"M\4\37" + "M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0" + "\35D\0\34C\0\34C\0\34C\11\33>\10\32=\0\32:\10\32=\0\32:\10\32=\0\34C" + "\10\32=\10\32=\10\32=\10\32=\10\32=\10\32=\0\34C\10\32=\0\34C\10\32=" + "\10\32=\0\34C\10\32=\10\32=\10\32=\365\372\375\376\377\374\376\377\374" + "\307\317\330\30""0N\0\32:\11\33>\11\33>\0\34C\30""0N\307\317\330\376" + "\377\374\376\377\374\370\372\367\2\36E\2\36E\2\36EK\312\363K\312\363" + "\5\40H\0\"M\4\37M\0\0\24N\201\22M\200\22M\200\22M\200\22M\200\35I}\20" + "L\177\35I}\35I}\35I}\35I}\35I}\20L\177\34H|\32G{\32G{\32G{\30Ey\30Ey" + "\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\17At\17At\15@s\15@s\11>q\11" + ">q\11>q\11>q\11>q\11>q\6=p\4q\11>qK\312\363K\312\363\15@s\15" + "@s\15@s\0\0\10*X\10*X\10*X\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\14#Q\0" + "%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0$P\14#Q\0#O\0#O\0\"M\0#O\4\37M\4\37" + "M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\0" + "\35D\0\35D\0\35D\0\34C\11\33>\0\34C\11\33>\0\32:\11\33>\0\32:\10\32=" + "\0\32:\10\32=\10\32=\10\32=\10\32=\10\32=\10\32=\0\34C\10\32=\10\32=" + "\0\34C\10\32=\0\34C\0\34C\10\32=\10\32=\10\32=\205\224\247\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\210" + "\227\252\2\36E\2\36E\2\36EK\312\363K\312\363\4\37M\4\37M\4\37M\0\0\22" + "M\200\22M\200\22M\200\22M\200\20L\177\20L\177\20L\177\35I}\35I}\35I}" + "\35I}\34H|\34H|\32G{\32G{\30Ey\30Ey\30Ey\24Cw\30Ey\24Cw\24Cw\23Bv\23" + "Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6" + "=p\4q\11" + ">q\11>qK\312\363K\312\363\15@s\17At\23Bv\0\0\10*X\2'T\10*X\10*X\2'T\2" + "'T\2'T\2'T\14#Q\2'T\2'T\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\0$P\14" + "#Q\0$P\0$P\14#Q\0\"M\0\"M\0\"M\4\37M\4\37M\5\40H\5\40H\5\40H\5\40H\2" + "\36E\5\40H\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\11\33>\0\34C\0\34C\0\34" + "C\0\32:\11\33>\0\32:\10\32=\0\32:\11\33>\10\32=\0\34C\10\32=\10\32=\0" + "\34C\10\32=\0\34C\10\32=\10\32=\0\34C\10\32=\10\32=\10\32=\11\33>\0\32" + ":\10\32=\11\33>\34""4R\307\317\330\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\307\317" + "\330\33""9]\2\36E\2\36E\5\40H\5\40HK\312\363K\312\363\4\37M\0\"M\0\"" + "M\0\0\22M\200\22M\200\22M\200\20L\177\20L\177\35I}\20L\177\34H|\35I}" + "\35I}\32G{\34H|\34H|\32G{\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23" + "Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\6=p\6" + "=p\6=p\4q\11>q\11>q\11>q\15@sK\312\363K\312\363\23Bv\23Bv\23Bv\0\0\2" + "'T\10*X\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\14" + "#Q\0%Q\0%Q\14#Q\0$P\0$P\0$P\0$P\0\"M\4\37M\0\"M\0\"M\4\37M\5\40H\5\40" + "H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\11\33>" + "\0\34C\0\34C\0\34C\0\34C\0\32:\11\33>\11\33>\10\32=\0\32:\10\32=\11\33" + ">\0\32:\10\32=\10\32=\0\34C\0\34C\10\32=\10\32=\10\32=\0\32:\10\32=\10" + "\32=\10\32=\11\33>\0\32:\0\32:\10\32=\0\34C\0\34C\0\34C\0\34C\0\35D\0" + "\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\4\37MK\312" + "\363K\312\363\14#Q\0$P\0$P\0\0\22M\200\22M\200\22M\200\35I}\20L\177\20" + "L\177\35I}\20L\177\35I}\32G{\34H|\34H|\34H|\32G{\30Ey\30Ey\30Ey\30Ey" + "\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11" + ">q\11>q\11>q\11>q\6=p\6=p\4q\11>q\11>q\11>q\15@s\15@s\15@s" + "K\312\363K\312\363\23Bv\23Bv\24Cw\0\0\10*X\2'T\2'T\2'T\2'T\2'T\2'T\2" + "'T\2'T\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\0#O\0#O\0$P" + "\0\"M\0#O\4\37M\4\37M\0\"M\5\40H\5\40H\5\40H\2\36E\5\40H\2\36E\5\40H" + "\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\11\33>\0\34C\0\34C\11\33>\0\34C" + "\11\33>\10\32=\11\33>\10\32=\0\32:\11\33>\0\32:\10\32=\10\32=\11\33>" + "\11\33>\0\32:\10\32=\11\33>\10\32=\0\32:\10\32=\0\32:\10\32=\11\33>\0" + "\34C\11\33>\0\34C\11\33>\0\34C\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\2" + "\36E\2\36E\5\40H\5\40H\4\37M\4\37M\4\37M\0\"MK\312\363K\312\363\0$P\14" + "#Q\14#Q\0\0\22M\200\20L\177\35I}\20L\177\20L\177\35I}\35I}\20L\177\35" + "I}\32G{\34H|\32G{\32G{\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23" + "Bv\23Bv\17At\15@s\15@s\15@s\11>q\15@s\11>q\11>q\11>q\11>q\6=p\4q\6=p\11>q\11>q%P\177\313\327\345\320\331\341\313\327\345\15@s" + "\17At\23BvK\312\363K\312\363\23Bv\24Cw\24Cw\0\0\10*X\2'T\2'T\2'T\2'T" + "\14#Q\2'T\2'T\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0$P\14#Q\0" + "$P\0$P\0\"M\14#Q\0\"M\0\"M\4\37M\4\37M\5\40H\5\40H\2\36E\2\36E\5\40H" + "\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\11\33>\0\34C\0\34C\0\34C\0" + "\34C\11\33>\11\33>\10\32=\11\33>\10\32=\0\32:\11\33>\10\32=\11\33>\11" + "\33>\10\32=\0\32:\11\33>\10\32=\0\32:\11\33>\10\32=\0\32:\0\32:\376\377" + "\374\376\377\374\376\377\374\"9X\11\33>\0\35D\0\35D\376\377\374\376\377" + "\374\376\377\374\37<`\2\36E\2\36E\5\40H\37<`\376\377\374\376\377\374" + "\376\377\374\0\"M\14#Q\0#OK\312\363K\312\363\0$P\0%Q\14#Q\0\0\20L\177" + "\20L\177\20L\177\20L\177\34H|\35I}\35I}\35I}\32G{\34H|\34H|\30Ey\30E" + "y\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\4q\11>q\11>q\40W\204\376\377\374\376\377\374\376\377" + "\374\23Bv\23Bv\23BvK\312\363K\312\363\24Cw\24Cw\30Ey\0\0\2'T\2'T\2'T" + "\2'T\2'T\2'T\2'T\14#Q\0%Q\0%Q\14#Q\14#Q\14#Q\14#Q\14#Q\0%Q\0%Q\0$P\0" + "$P\0$P\0$P\0#O\0\"M\4\37M\0\"M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\34C\0\34C\0\34" + "C\0\34C\0\34C\0\34C\0\32:\10\32=\0\32:\10\32=\10\32=\0\32:\11\33>\10" + "\32=\0\32:\11\33>\10\32=\0\32:\11\33>\10\32=\11\33>\0\34C\0\34C\11\33" + ">\376\377\374\376\377\374\376\377\374\37""6U\0\35D\0\35D\2\36E\376\377" + "\374\376\377\374\376\377\374\37<`\2\36E\5\40H\5\40H(q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\4q\11>q\11>q\40W\204\376\377\374\376\377\374\376" + "\377\374\23Bv\23Bv\23BvK\312\363K\312\363\24Cw\30Ey\30Ey\0\0\2'T\2'T" + "\2'T\14#Q\2'T\2'T\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\0" + "$P\0$P\0$P\0\"M\0#O\0\"M\0\"M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\34C\0\34C\0" + "\34C\0\34C\0\34C\0\34C\11\33>\10\32=\11\33>\11\33>\0\32:\11\33>\0\32" + ":\0\32:\0\32:\11\33>\0\32:\10\32=\0\34C\0\34C\0\34C\0\34C\0\34C\11\33" + ">\376\377\374\376\377\374\376\377\374(q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\4q\376\377\374\376\377" + "\374\376\377\374\40W\204\11>q\15@s\15@s\40W\204\376\377\374\376\377\374" + "\376\377\374\23Bv\24Cw\24CwK\312\363K\312\363\24Cw\30Ey\32G{\0\0\2'T" + "\2'T\2'T\2'T\2'T\2'T\0%Q\0%Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\0%Q\0$P\14#Q" + "\0$P\0#O\14#Q\0\"M\0\"M\0\"M\4\37M\4\37M\4\37M\5\40H\5\40H\2\36E\5\40" + "H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\34C\0" + "\34C\0\34C\0\34C\11\33>\0\34C\0\34C\11\33>\10\32=\10\32=\0\32:\0\32:" + "\0\32:\10\32=\0\32:\0\34C\0\34C\0\34C\0\34C\0\34C\0\34C\0\34C\0\35D\0" + "\35D\376\377\374\376\377\374\376\377\374\"9X\2\36E\2\36E\2\36E\376\377" + "\374\376\377\374\376\377\374(q\11>q\11" + ">q\11>q\11>q\11>q\6=p\6=p\4\0\34C\0\34C\0\34" + "C\0\34C\0\34C\11\33>\0\34C\11\33>\0\34C\11\33>\0\34C\0\34C\11\33>\0\34" + "C\0\35D\0\35D\0\35D\0\35D\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\0$P\0%Q\14#QK\312\363K\312\363\0" + "%Q\0%Q\0%Q\0\0\20L\177\34H|\35I}\35I}\34H|\32G{\34H|\30Ey\32G{\30Ey\30" + "Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\4\0\34C\0\34C\0\34C\0\34C\0\34C\0\34C\11\33>\0\34C\0\34C\0\34C\11\33" + ">\0\34C\11\33>\0\35D\0\35D\0\35D\0\35D\2\36E\2\36E\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\0%Q\14#" + "Q\0%QK\312\363K\312\363\0%Q\0%Q\2'T\0\0\20L\177\35I}\35I}\32G{\34H|\32" + "G{\32G{\30Ey\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17" + "At\15@s\15@s\15@s\11>q\15@s\11>q\11>q\11>q\11>q\11>q\6=p\6=p\4\0\34C\0\34C\0\34C\0\34C\11\33>\0\34" + "C\11\33>\0\34C\0\34C\0\34C\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\2\36E" + "\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\4\37M\4\37M\4\37M\0" + "\"M\0\"M\0\"M\0#O\0#O\0$P\0$P\0$P\0%Q\0%Q\0%Q\0%QK\312\363K\312\363\14" + "#Q\2'T\2'T\0\0\34H|\35I}\34H|\34H|\34H|\34H|\32G{\30Ey\30Ey\30Ey\24C" + "w\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\17At\17At\15@s\15@s\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\15" + "@s\15@s\15@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\30" + "Ey\34H|K\312\363K\312\363\35I}\35I}\35I}\0\0\2'T\2'T\14#Q\0%Q\14#Q\14" + "#Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\0#O\0$P\0\"M\0#O\0\"M\4\37M\4\37" + "M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2" + "\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\35D\0\34C\0\34C\11\33>\0\34" + "C\0\34C\0\34C\11\33>\0\34C\0\34C\0\34C\0\34C\0\34C\0\34C\0\35D\0\35D" + "\0\35D\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2" + "\36E\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\0\"M\14#Q\0\"M\0$P\0$P\0%Q\0" + "$P\14#Q\0%Q\14#Q\14#Q\14#Q\0%QK\312\363K\312\363\2'T\2'T\2'T\0\0\20L" + "\177\35I}\34H|\32G{\34H|\32G{\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23B" + "v\23Bv\23Bv\23Bv\17At\17At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\17At\23Bv" + "\23Bv\24Cw\23Bv\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\32G{\34H|\32G{K\312\363" + "K\312\363\35I}\20L\177\20L\177\0\0\2'T\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\14#" + "Q\0%Q\0%Q\0%Q\14#Q\0$P\0$P\5\40H\0\"M\0\"M\0\"M\4\37M\4\37M\4\37M\5\40" + "H\5\40H\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\34C\0\34C\11\33>\11\33>\0" + "\34C\0\34C\0\34C\0\34C\0\34C\11\33>\0\35D\0\35D\0\35D\0\35D\0\35D\0\35" + "D\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\5\40H\0" + "\"M\4\37M\4\37M\4\37M\0\"M\0#O\0\"M\0$P\14#Q\0%Q\0$P\0%Q\0%Q\14#Q\0%" + "Q\0%Q\0%Q\14#QK\312\363K\312\363\2'T\2'T\2'T\0\0\35I}\34H|\20L\177\34" + "H|\32G{\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17" + "At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\4q\11>q\11>q\11>q" + "\11>q\11>q\11>q\15@s\15@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\30Ey\30Ey\30Ey\32G{\20L\177\34H|\35I}K\312\363K\312\363\20L\177\20" + "L\177\22M\200\0\0\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0$P" + "\0$P\0#O\0#O\0\"M\4\37M\4\37M\4\37M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36" + "E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0" + "\35D\0\35D\0\35D\0\35D\0\34C\11\33>\0\34C\11\33>\0\34C\0\34C\11\33>\0" + "\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36" + "E\5\40H\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\0\"M\0\"" + "M\0\"M\0$P\0#O\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\14#Q\2'TK\312\363" + "K\312\363\2'T\2'T\10*X\0\0\34H|\32G{\34H|\30Ey\30Ey\30Ey\30Ey\30Ey\24" + "Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\17At\23" + "Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\32G{\34H|\32G{\34H|\35" + "I}\35I}K\312\363K\312\363\20L\177\22M\200\22M\200\0\0\14#Q\0%Q\0%Q\0" + "%Q\14#Q\14#Q\14#Q\0%Q\0$P\0%Q\0$P\0#O\5\40H\0\"M\0\"M\0\"M\0\"M\4\37" + "M\4\37M\4\37M\5\40H\5\40H\0\"M\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35" + "D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0" + "\35D\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\5\40H\5\40H\5\40" + "H\0\"M\4\37M\0\"M\0\"M\0\"M\14#Q\0$P\0#O\0$P\0$P\14#Q\0%Q\0%Q\0%Q\14" + "#Q\14#Q\0%Q\0%Q\2'T\2'T\2'TK\312\363K\312\363\2'T\10*X\10*X\0\0\34H|" + "\34H|\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23" + "Bv\17At\15@s\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6" + "=p\4q\11>q\11>q\11>q" + "\11>q\11>q\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\24Cw\30Ey\30Ey\30Ey\32G{\20L\177\34H|\35I}\34H|\20L\177K\312\363K" + "\312\363\22M\200\22M\200\24N\201\0\0\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\14" + "#Q\0%Q\14#Q\0$P\0$P\14#Q\0\"M\0\"M\4\37M\4\37M\0\"M\4\37M\5\40H\5\40" + "H\5\40H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0" + "\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35" + "D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\0\"M" + "\14#Q\0\"M\0$P\0#O\14#Q\0%Q\0$P\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T" + "\2'T\2'TK\312\363K\312\363\2'T\10*X\10*X\0\0\32G{\32G{\30Ey\30Ey\30E" + "y\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15" + "@s\17At\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\32G{\32" + "G{\34H|\32G{\35I}\34H|\35I}\35I}K\312\363K\312\363\22M\200\24N\201\35" + "I}\0\0\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\0$P\0$P\0$P\0#O\0#O\0\"M\0" + "\"M\4\37M\4\37M\0\"M\5\40H\5\40H\5\40H\2\36E\2\36E\5\40H\2\36E\5\40H" + "\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0" + "\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5" + "\40H\5\40H\0\"M\4\37M\0\"M\0\"M\14#Q\0\"M\0$P\0$P\0$P\14#Q\0$P\0%Q\14" + "#Q\14#Q\0%Q\14#Q\0%Q\14#Q\2'T\14#Q\2'T\2'T\2'TK\312\363K\312\363\10*" + "X\10*X\10*X\0\0\32G{\30Ey\30Ey\30Ey\30Ey\24Cw\24Cw\24Cw\23Bv\23Bv\23" + "Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\6=p\6=p\6=p\4q\11>q\11>q\11" + ">q\11>q\11>q\11>q\15@s\15@s\220\253\302\220\253\302\220\253\302\220\253" + "\302\220\253\302\230\253\304\221\254\303\230\253\304\221\254\303\221" + "\254\303\222\255\304\222\255\304\222\255\304\222\255\304\230\253\304" + "\222\255\304\230\253\304\223\256\305\223\256\305\34H|\20L\177\35I}K\312" + "\363K\312\363\24N\201\26O\202\26O\202\0\0\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0" + "$P\0$P\0#O\0$P\0#O\0\"M\4\37M\4\37M\0\"M\4\37M\4\37M\5\40H\0\"M\5\40" + "H\5\40H\5\40H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0" + "\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35" + "D\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\2'T\2'T\10*XK\312\363K\312\363\10*X\10*X\10*X\0\0\30Ey\30Ey\30E" + "y\24Cw\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s" + "\15@s\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\20L\177\35I}\22M\200K\312\363K\312\363\26" + "O\202\26O\202\26O\202\0\0\14#Q\14#Q\0%Q\0%Q\0%Q\0$P\0%Q\0$P\0#O\0$P\14" + "#Q\0\"M\4\37M\4\37M\0\"M\4\37M\5\40H\5\40H\5\40H\5\40H\2\36E\2\36E\2" + "\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35" + "D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\0\35D\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\5\40" + "H\5\40H\5\40H\0\"M\4\37M\4\37M\0\"M\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\2'T\2'T\10*" + "XK\312\363K\312\363\10*X\10*X\10*X\0\0\30Ey\30Ey\24Cw\24Cw\24Cw\24Cw" + "\23Bv\23Bv\24Cw\23Bv\23Bv\17At\15@s\15@s\15@s\15@s\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\4q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\17At\17At\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\35I}\22M\200\22M\200K\312\363K\312\363\26O\202\26O\202\26O\202" + "\0\0\0%Q\0%Q\0%Q\0%Q\0$P\0$P\0#O\0$P\0#O\0\"M\4\37M\0\"M\0\"M\4\37M\0" + "\"M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0\35D\0" + "\35D\0\35D\0\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\4" + "\37M\0\"M\0\"M\0\"M\14#Q\0$P\0$P\0$P\0$POk\214\363\370\373\367\375\377" + "\204\230\257,Gl\10*X\12+Y,Gl\205\224\247\367\375\377\367\375\377x\213" + "\243\2'T\2'T\10*X\10*XK\312\363K\312\363\10*X\10*X\10*X\0\0\30Ey\24C" + "w\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15@s\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\17At\23" + "Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw3e\224\365\372\375\376\377\374y\231\265" + "\30Ey\30Ey\34H|\32G{\34H|\35I}r\227\267\376\377\374\376\377\374c\207" + "\250\22M\200\22M\200\24N\201K\312\363K\312\363\26O\202\26O\202\27P\203" + "\0\0\0%Q\14#Q\0$P\0%Q\0$P\0#O\0$P\0\"M\0\"M\0\"M\4\37M\4\37M\4\37M\4" + "\37M\5\40H\5\40H\0\"M\5\40H\5\40H\2\36E\2\36E\5\40H\5\40H\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\0\35D\0\35D\0\35D\0\35D\0" + "\35D\0\35D\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40" + "H\2\36E\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\4" + "\37M\0\"M\0#O\0\"M\0$P\0#O\14#Q\14#Q\14#Q\252\265\303\376\377\374\376" + "\377\374,Gl\14#Q\0%Q\0%Q\14#Q\2'T\2'T.In\376\377\374\376\377\374\274" + "\310\326\2'T\10*X\10*XK\312\363K\312\363\10*X\10*X\12+Y\0\0\24Cw\24C" + "w\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15@s\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\4q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17At\23Bv\23" + "Bv\24Cw\23Bv\23Bv\24Cw\24Cw\24Cw\354\362\364\376\377\374\376\377\374" + "Ks\237\32G{\34H|\32G{\34H|\20L\177\34H|Tv\234\376\377\374\376\377\374" + "\354\362\364\22M\200\24N\201\24N\201K\312\363K\312\363\26O\202\26O\202" + "\27P\203\0\0\0$P\14#Q\0$P\0%Q\0$P\0$P\0\"M\0\"M\4\37M\4\37M\4\37M\0\"" + "M\4\37M\5\40H\5\40H\5\40H\5\40H\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\5\40H\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37" + "M\4\37M\0\"M\0\"M\0$P\0#O\0#O\14#Q\0%Q\14#Q\14#Q\365\372\375\376\377" + "\374\376\377\374\312\322\333\34""8a\14#Q\0%Q\2'T\2'T\37:d\312\322\333" + "\376\377\374\376\377\374\365\372\375\10*X\10*X\10*XK\312\363K\312\363" + "\10*X\12+Y\12+Y\0\0\24Cw\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\15@" + "s\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=" + "p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15" + "@s\15@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\30Ey\333\344" + "\354\376\377\374\376\377\374\376\377\374\363\370\373\274\310\326\225" + "\260\307\225\260\307\274\310\326\364\371\374\376\377\374\376\377\374" + "\376\377\374\336\347\357\22M\200\35I}\26O\202K\312\363K\312\363\26O\202" + "\27P\203\27P\203\0\0\0%Q\14#Q\0#O\0#O\0$P\14#Q\0\"M\0\"M\4\37M\4\37M" + "\4\37M\0\"M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\4\37M\4\37M\4\37M\4" + "\37M\0\"M\0\"M\0\"M\0$P\0#O\0$P\0$P\14#Q\14#Q\0%Q\0%Q\210\227\252\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\213\232\255\10*X\10*X\10*XK\312\363K\312\363\10*X\12+Y\12+Y\0\0" + "\24Cw\24Cw\23Bv\23Bv\23Bv\23Bv\23Bv\17At\17At\15@s\15@s\15@s\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\4q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\23Bv\23Bv\23" + "Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\27P\203\333\344\354\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\336\347\357\"V\212\24N\201" + "\26O\202\26O\202K\312\363K\312\363\26O\202\27P\203\27P\203\0\0\0%Q\0" + "$P\0$P\0$P\0\"M\0#O\4\37M\4\37M\4\37M\4\37M\4\37M\5\40H\5\40H\5\40H\5" + "\40H\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40" + "H\5\40H\5\40H\5\40H\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\0#O\0\"M\0$P\0" + "#O\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\14#Q\37:d\303\314\324\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\307\317\330&@k\10*X\10*X\10*X\10*XK\312\363K\312\363\10*X\12" + "+Y\12+Y\0\0\23Bv\23Bv\24Cw\23Bv\23Bv\23Bv\17At\15@s\15@s\15@s\15@s\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6" + "=p\4q\11" + ">q\11>q\11>q\11>q\11>q\15@s\11>q\11>q\11>q\15@s\15@s\15@s\17At\17At\23" + "Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\35I}X" + "\203\250\263\303\326\341\352\362\365\372\375\365\372\375\343\350\353" + "\264\304\327o\206\243\24N\201\22M\200\24N\201\24N\201\26O\202\26O\202" + "K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\0$P\0$P\0\"M\0\"M\0\"" + "M\4\37M\0\"M\0\"M\4\37M\4\37M\5\40H\5\40H\5\40H\5\40H\5\40H\2\36E\2\36" + "E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\4" + "\37M\4\37M\0\"M\4\37M\4\37M\0\"M\0#O\0$P\0#O\0#O\14#Q\0%Q\0$P\0%Q\0%" + "Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10" + "*X\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\23Bv\23Bv\23B" + "v\23Bv\17At\17At\15@s\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\15@s\15@s\15@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\32G{\34H|\32G{\34H|\35I}\35I}\34H|\35" + "I}\20L\177\20L\177\22M\200\22M\200\22M\200\24N\201\26O\202\26O\202\26" + "O\202K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\0$P\0\"M\14#Q\0\"" + "M\0\"M\4\37M\0\"M\4\37M\4\37M\4\37M\5\40H\5\40H\5\40H\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\0" + "\"M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\0$P\0#O\0$P\0$P\14#Q\0$P\0%Q\14" + "#Q\0%Q\14#Q\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\10*X" + "\10*X\10*X\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\23Bv\23" + "Bv\23Bv\17At\15@s\15@s\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\230\253\304\222\255\304\222\255\304\222\255\304\230\253" + "\304\230\253\304\230\253\304\230\253\304\230\253\304\230\253\304\223" + "\256\305\223\256\305\224\257\306\224\257\306\224\257\306\224\257\306" + "\224\257\306\225\260\307\225\260\307\26O\202\26O\202\26O\202K\312\363" + "K\312\363\27P\203\27P\203\27P\203\0\0\0$P\14#Q\0\"M\0\"M\0\"M\4\37M\4" + "\37M\4\37M\5\40H\5\40H\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\5\40H\2\36" + "E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\0" + "\"M\0\"M\0#O\0\"M\0\"M\0$P\0$P\0$P\0$P\14#Q\0%Q\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\23Bv\23Bv\17At\17" + "At\15@s\15@s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@" + "s\15@s\17At\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24" + "Cw\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\26O\202\26O\202\26O\202K\312\363K\312\363\27" + "P\203\27P\203\27P\203\0\0\0\"M\4\37M\0\"M\4\37M\0\"M\4\37M\4\37M\5\40" + "H\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2" + "\36E\5\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\4\37M\0\"M\4\37M\14#Q\0" + "\"M\0$P\0#O\0$P\0$P\14#Q\0$P\0%Q\0%Q\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\10*X\10" + "*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\23Bv\17At\23Bv\15@s\15@" + "s\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=" + "p\6=p\6=p\6=p\6=p\6=p\4q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15" + "@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\26O\202\26O\202\26O\202K\312\363K\312\363\27P\203" + "\27P\203\27P\203\0\0\0\"M\4\37M\4\37M\4\37M\4\37M\0\"M\5\40H\5\40H\5" + "\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40" + "H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\4\37M\4\37M\0\"M\0\"M\0#O\0\"M\0" + "$P\0$P\0$P\14#Q\14#Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\2'T" + "\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*XK\312" + "\363K\312\363\12+Y\12+Y\12+Y\0\0\17At\15@s\15@s\15@s\15@s\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6" + "=p\6=p\4q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\17At\17At\23Bv\23" + "Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\34" + "H|\34H|\32G{\35I}\35I}\35I}\20L\177\20L\177\20L\177\20L\177\22M\200\35" + "I}\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202K\312\363K" + "\312\363\27P\203\27P\203\27P\203\0\0\0\"M\4\37M\4\37M\4\37M\4\37M\5\40" + "H\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5" + "\40H\5\40H\5\40H\5\40H\0\"M\4\37M\0\"M\0\"M\4\37M\4\37M\4\37M\0\"M\0" + "#O\0#O\0#O\0#O\14#Q\0%Q\0%Q\14#Q\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\15@s\15@s\15@s\15@s\11>" + "q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17" + "At\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30" + "Ey\32G{\20L\177\34H|\34H|\35I}\35I}\35I}\35I}\20L\177\20L\177\20L\177" + "\22M\200\22M\200\22M\200\24N\201\26O\202\26O\202\26O\202\26O\202\26O" + "\202\26O\202K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\0\"M\4\37" + "M\4\37M\5\40H\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2" + "\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\0\"M\4\37" + "M\0\"M\14#Q\0\"M\0#O\0$P\0$P\0$P\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\14#Q" + "\217\236\261\217\236\261\217\236\261\27""5]\0%Q\217\236\261\217\236\261" + "\217\236\261\217\236\261\217\236\261\217\236\261\217\236\261\217\236" + "\261\217\236\261\217\236\261\217\236\261\220\240\262\220\240\262\220" + "\240\262\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\15@s\15" + "@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6" + "=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15" + "@s\15@s\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30" + "Ey\30Ey\30Ey\376\377\374\376\377\374\376\377\374-`\217\35I}\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\26O\202\26O\202\26O\202K\312\363K\312\363\27P\203" + "\27P\203\27P\203\0\0\4\37M\4\37M\5\40H\5\40H\5\40H\0\"M\2\36E\2\36E\2" + "\36E\2\36E\5\40H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40" + "H\4\37M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\0\"M\14#Q\0#O\0#O\14#Q\0%Q" + "\0$P\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\376\377\374\376\377\374\376\377\374&@k" + "\2'T\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\10*X\10*X\10*XK\312\363K\312\363" + "\12+Y\12+Y\12+Y\0\0\15@s\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>" + "q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p" + "\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\376\377\374\376\377\374\376" + "\377\374-`\217\34H|\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\26O\202\26O\202\26O" + "\202K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\0\"M\5\40H\5\40H\5" + "\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40" + "H\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\4\37M\0\"M\0\"M\0#O\0\"M\0" + "#O\5\40H\0$P\14#Q\0$P\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\14#Q\0%Q\376\377\374" + "\376\377\374\376\377\374(q\11>q\11>q\11>q\11>" + "q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p" + "\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\17At\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23" + "Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\32G{\34H|\32" + "G{\34H|\20L\177\35I}\35I}\34H|\35I}\20L\177\20L\177\20L\177\22M\200\22" + "M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202" + "\26O\202\26O\202K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\5\40H" + "\5\40H\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2" + "\36E\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\4\37M\0\"M\0\"M\0\"M\0" + "\"M\0\"M\0#O\0#O\0$P\0$P\14#Q\0$P\0%Q\14#Q\14#Q\0%Q\14#Q\14#Q\0%Q\14" + "#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\12+YK\312\363K\312\363\12+Y\12+Y\12+Y\0\0" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>" + "q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17" + "At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30" + "Ey\30Ey\30Ey\32G{\34H|\32G{\34H|\35I}\20L\177\35I}\35I}\35I}\20L\177" + "\20L\177\20L\177\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O" + "\202\26O\202\26O\202\26O\202\26O\202\27P\203K\312\363K\312\363\27P\203" + "\27P\203\27P\203\0\0\5\40H\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H" + "\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\4" + "\37M\0\"M\0\"M\4\37M\0#O\0\"M\0\"M\0$P\0#O\14#Q\0%Q\14#Q\0%Q\0%Q\14#" + "Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\10" + "*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*XK\312\363" + "K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6" + "=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\34H|\32G{\34H|\35I}\35I}\34" + "H|\35I}\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\26O\202\26O\202\26O\202K\312\363" + "K\312\363\27P\203\27P\203\27P\203\0\0\5\40H\5\40H\2\36E\5\40H\2\36E\2" + "\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5" + "\40H\2\36E\2\36E\2\36E\2\36E\2\36E\0\"M\5\40H\5\40H\5\40H\5\40H\4\37" + "M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\14#Q\0#O\0#O\0$P\0$P\14#Q\0%Q\0%" + "Q\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\2'T\14#Q\2'T\2'T\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12" + "+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17At\17" + "At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30" + "Ey\32G{\30Ey\32G{\34H|\34H|\35I}\35I}\35I}\35I}\20L\177\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\26O\202\26O\202\26O\202K\312\363K\312\363\27P\203\27" + "P\203\27P\203\0\0\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\5\40H\2\36" + "E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\5\40H\2\36" + "E\2\36E\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\4\37M\4\37M\4\37M\0" + "\"M\0\"M\0\"M\5\40H\0$P\0$P\0%Q\0$P\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0" + "%Q\14#Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T\2'T\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\10*X\10*X\10*XK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23" + "Bv\23Bv\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\32G{\30Ey\34H|\32G{\34" + "H|\32G{\35I}\35I}\35I}\35I}\20L\177\224\257\306\224\257\306\224\257\306" + "\224\257\306\230\253\304\224\257\306\230\253\304\233\267\316\310\324" + "\342\367\375\377\376\377\374\376\377\374\246\276\317\225\260\307\26O" + "\202\26O\202\26O\202K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2" + "\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5" + "\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40" + "H\5\40H\4\37M\0\"M\4\37M\4\37M\4\37M\4\37M\0\"M\14#Q\0\"M\0\"M\0$P\0" + "$P\0$P\14#Q\0%Q\0$P\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X1Lq\337\344" + "\347\376\377\374\325\332\334\13""6c\10*X\10*X\10*XK\312\363K\312\363" + "\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\23" + "Bv\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30" + "Ey\30Ey\30Ey\32G{\34H|\32G{\34H|\20L\177\35I}\35I}\35I}\34H|\20L\177" + "\20L\177\20L\177\35I}\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201" + "\26O\202\26O\202_\200\247\376\377\374\376\377\374\215\250\277\26O\202" + "\26O\202\27P\203K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2\36E" + "\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40" + "H\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\4" + "\37M\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\14#Q\0\"M\0#O\0$P\0#O\0%Q\14" + "#Q\0$P\0$P\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\2'T\14#Q\2" + "'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X/Jo\376" + "\377\374\376\377\374\320\331\341\10*X\12+Y\12+YK\312\363K\312\363\12" + "+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6" + "=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\17At\17" + "At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30" + "Ey\30Ey\30Ey\34H|\32G{\34H|\32G{\35I}\35I}\35I}\35I}\35I}\20L\177\20" + "L\177\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201\26O\202" + "\26O\202\26O\202\202\231\266\376\377\374\376\377\374\363\370\373\26O" + "\202\27P\203\27P\203K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2" + "\36E\5\40H\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5" + "\40H\2\36E\2\36E\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\0\"" + "M\4\37M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\0#O\0$P\0#O\0$P\0$P\14#Q\0" + "%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\14#Q" + "\2'T\2'T\2'T\2'T\217\236\261\221\244\274\217\236\261\221\244\274\217" + "\236\261\217\236\261\217\236\261\222\242\264\232\251\274\303\314\324" + "\376\377\374\376\377\374\376\377\374\364\371\374\10*X\12+Y\12+YK\312" + "\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\6=p\6=p\6=" + "p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15" + "@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30" + "Ey\30Ey\30Ey\30Ey\32G{\34H|\32G{\34H|\34H|\34H|\34H|\35I}\35I}\35I}\35" + "I}\20L\177\20L\177\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\330\341\351\26O\202\27P\203\27P" + "\203K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2\36E\2\36E\2\36E" + "\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2" + "\36E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40" + "H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\0\"M\4\37" + "M\0\"M\4\37M\0\"M\0\"M\14#Q\0#O\0$P\14#Q\0%Q\0%Q\0$P\14#Q\0%Q\0%Q\14" + "#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374|\217\247\10*X\12+Y\12+YK\312\363K\312\363\12+Y\12+Y\12+" + "Y\0\0\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=" + "p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\24Cw\23" + "Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\20" + "L\177\34H|\34H|\34H|\35I}\35I}\35I}\35I}\35I}\20L\177\35I}\20L\177\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\303\317\335\36S\207\26O\202\27P\203\27P\203K\312\363K\312\363\27" + "P\203\27P\203\27P\203\0\0\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5" + "\40H\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\0\"M\0\"M\14#Q\0\"M\0#O\0$P\0" + "$P\0$P\14#Q\0$P\0$P\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q" + "\2'T\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\367" + "\375\377\353\360\363\275\305\315e|\231\13,Z\10*X\12+Y\12+Y\12+YK\312" + "\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p" + "\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\17At\15@s\15@s\15@s\17At\17" + "At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30" + "Ey\30Ey\32G{\30Ey\32G{\34H|\34H|\34H|\34H|\35I}\35I}\35I}\20L\177\35" + "I}\20L\177\20L\177\35I}\22M\200\22M\200\24N\201\24N\201\24N\201\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\27P" + "\203\27P\203\27P\203K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2" + "\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\4\37M\0\"M" + "\0\"M\0\"M\0\"M\14#Q\0#O\0$P\0#O\0$P\0%Q\0$P\14#Q\0$P\14#Q\0%Q\14#Q\14" + "#Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\10*X\2'" + "T\10*X\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\12+Y\12+Y\12+YK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>" + "q\11>q\11>q\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\6=p\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15" + "@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24" + "Cw\30Ey\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\20L\177\34H|\32G{\34H|\34H|\35" + "I}\20L\177\35I}\34H|\20L\177\20L\177\20L\177\20L\177\20L\177\22M\200" + "\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\35I}\26O\202\26O\202" + "\26O\202\26O\202\26O\202\26O\202\26O\202\27P\203\27P\203\27P\203K\312" + "\363K\312\363\27P\203\27P\203\27P\203\0\0\2\36E\2\36E\2\36E\2\36E\2\36" + "E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5" + "\40H\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40" + "H\5\40H\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\0#O\0$P\0#O\0$" + "P\0$P\14#Q\0$P\0$P\0$P\0%Q\14#Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%" + "Q\2'T\14#Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12+Y\12+YK\312\363" + "K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\6=p\6=p\6=p\6=p\6=p" + "\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23" + "Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30" + "Ey\32G{\32G{\32G{\34H|\34H|\32G{\35I}\35I}\35I}\34H|\20L\177\35I}\20" + "L\177\20L\177\22M\200\22M\200\22M\200\22M\200\24N\201\24N\201\26O\202" + "\26O\202\33Q\205\177\237\272\331\342\352\366\373\376\357\364\367\303" + "\317\335_\200\247\26O\202\27P\203\27P\203\27P\203\27P\203K\312\363K\312" + "\363\27P\203\27P\203\27P\203\0\0\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E" + "\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\2" + "\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\0\"M\4\37" + "M\4\37M\0\"M\4\37M\4\37M\0\"M\14#Q\0\"M\0\"M\0\"M\0$P\0#O\0#O\0$P\0$" + "P\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\2'T\14#Q\2" + "'T\2'T\2'T\2'T\2'T\2'T\2'T\27""5]\204\230\257\333\340\343\370\372\367" + "\353\360\363\242\261\305#=g\15-[\270\303\321\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374o\206\243\12+Y\12+Y\12" + "+Y\12+YK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>" + "q\6=p\6=p\6=p\6=p\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\17At\17" + "At\23Bv\23Bv\23Bv\24Cw\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30" + "Ey\30Ey\30Ey\32G{\32G{\34H|\34H|\34H|\32G{\35I}\35I}\35I}\34H|\20L\177" + "\20L\177\20L\177\20L\177\24N\201\276\312\330\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\333\344\354\202\242\276\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\366\373\3763e\224\27P\203\27P\203\27P\203K\312\363K\312\363" + "\27P\203\27P\203\27P\203\0\0\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36" + "E\5\40H\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2" + "\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\0\"M\0\"M\4\37M\4\37M" + "\4\37M\0\"M\4\37M\0\"M\14#Q\0\"M\0#O\0$P\0$P\0$P\0$P\14#Q\0%Q\14#Q\0" + "%Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'" + "T\2'T\2'T\2'TRj\205\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\367\375\377\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\204\230\257\12+Y\12+Y\12+YK\312\363K\312\363\12+Y\12+Y\12+Y\0\0" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15" + "@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24" + "Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\20L\177\34H|\34H|\20L\177" + "\34H|\34H|\35I}\35I}\35I}\35I}\20L\177\20L\177\35I}\35I}\246\276\317" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\300\314\332\231" + "\264\313\313\327\345\376\377\374\376\377\374\376\377\374\310\324\342" + "\27P\203\27P\203\27P\203K\312\363K\312\363\27P\203\27P\203\27P\203\0" + "\0\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H" + "\2\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5" + "\40H\0\"M\5\40H\0\"M\4\37M\4\37M\0\"M\4\37M\0\"M\4\37M\0\"M\0\"M\14#" + "Q\0#O\0$P\0#O\0$P\0$P\0$P\14#Q\0%Q\14#Q\0%Q\0%Q\14#Q\14#Q\0%Q\0%Q\0%" + "Q\0%Q\0%Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\320\331\341\376" + "\377\374\376\377\374\365\372\375\247\262\300\242\261\305\370\372\367" + "\376\377\374\376\377\374\376\377\374\204\230\257\10*X\10*X\12+Y\242\261" + "\305\376\377\374\376\377\374\350\355\360\12+Y\12+Y\12+YK\312\363K\312" + "\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23" + "Bv\23Bv\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34" + "H|\32G{\34H|\34H|\34H|\35I}\20L\177\35I}\35I}\35I}\20L\177\35I}\22M\200" + "\22M\200\357\364\367\376\377\374\376\377\374y\231\265\24N\201\26O\202" + "r\227\267\376\377\374\376\377\374\376\377\374-`\217\26O\202\27P\203\27" + "P\203Tv\234\376\377\374\376\377\374\366\373\376\27P\203\27P\203\27P\203" + "K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2\36E\2\36E\5\40H\2\36" + "E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2" + "\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\4\37" + "M\4\37M\4\37M\0\"M\0\"M\14#Q\0\"M\0\"M\0\"M\0$P\0#O\0%Q\14#Q\0$P\14#" + "Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\0%Q\14#Q\2'T\2'T\2'T" + "\2'T\2'T\2'T\2'T\2'T\2'T\10*X\372\374\371\376\377\374\376\377\374#Gp" + "\10*X\10*X/Jo\376\377\374\376\377\374\376\377\374\13,Z\10*X\12+Y\12+" + "Y,Ep\376\377\374\376\377\374\376\377\374\12+Y\12+Y\12+YK\312\363K\312" + "\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23" + "Bv\24Cw\24Cw\24Cw\24Cw\30Ey\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\32G{\34H|\32" + "G{\20L\177\34H|\35I}\35I}\34H|\35I}\20L\177\20L\177\20L\177\35I}\22M" + "\200\22M\200\22M\200\376\377\374\376\377\374\376\377\3743e\224\26O\202" + "\26O\2023e\224\376\377\374\376\377\374\376\377\374\26O\202\27P\203\27" + "P\203\27P\2033e\224\376\377\374\376\377\374\376\377\374\27P\203\27P\203" + "\27P\203K\312\363K\312\363\27P\203\27P\203\27P\203\0\0\2\36E\5\40H\2" + "\36E\2\36E\2\36E\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36" + "E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\0\"M\4\37M\4\37M\4" + "\37M\4\37M\4\37M\0\"M\4\37M\0\"M\0\"M\0$P\0#O\0$P\0#O\14#Q\0%Q\14#Q\14" + "#Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\14#Q\0%Q\0%Q\0%Q\0%Q\0%Q\2'T\14#Q\2'T\2" + "'T\2'T\2'T\2'T\2'T\2'T\10*X\2'T\10*X\376\377\374\376\377\374\376\377" + "\374,Ep\10*X\10*X\"Fo\376\377\374\376\377\374\376\377\374\12+Y\12+Y\12" + "+Y\12+Y,Ep\376\377\374\376\377\374\376\377\374\12+Y\12+Y\12+YK\312\363" + "K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q" + "\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15" + "@s\15@s\15@s\15@s\15@s\15@s\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24" + "Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\32G{\32G{\34H|\34" + "H|\32G{\34H|\35I}\35I}\35I}\34H|\20L\177\20L\177\35I}\20L\177\20L\177" + "\22M\200\22M\200\22M\200\376\377\374\376\377\374\376\377\374\242\271" + "\313\225\260\307\225\260\307\242\271\313\376\377\374\376\377\374\376" + "\377\374\225\260\307\225\260\307\225\260\307\235\261\311\242\271\313" + "\376\377\374\376\377\374\376\377\374\27P\203\27P\203\27P\203K\312\363" + "K\312\363\35I}\27P\203\27P\203\0\0\5\40H\2\36E\2\36E\2\36E\2\36E\5\40" + "H\2\36E\5\40H\2\36E\2\36E\2\36E\5\40H\2\36E\2\36E\5\40H\5\40H\5\40H\5" + "\40H\5\40H\5\40H\5\40H\4\37M\0\"M\4\37M\4\37M\4\37M\0\"M\4\37M\0\"M\14" + "#Q\0\"M\0#O\0$P\0$P\0#O\14#Q\0$P\0%Q\14#Q\0%Q\14#Q\14#Q\0%Q\14#Q\14#" + "Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T" + "\10*X\2'T\10*X\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\12+Y\12+Y\12+YK\312\363K\312\363\12+Y\12+Y\12" + "+Y\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\17At\17" + "At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30" + "Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\32G{\34H|\32G{\34H|\35I}\35I}\35I}\35" + "I}\20L\177\35I}\20L\177\35I}\22M\200\22M\200\22M\200\24N\201\24N\201" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\27P\203\27P\203\27P\203K\312\363K\312\363\27P\203\27P\203" + "\27P\203\0\0\5\40H\2\36E\5\40H\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\2" + "\36E\2\36E\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\0\"" + "M\4\37M\0\"M\4\37M\4\37M\0\"M\0\"M\0#O\0\"M\0\"M\5\40H\0$P\0#O\0$P\0" + "%Q\0$P\14#Q\0$P\0%Q\0%Q\0%Q\14#Q\14#Q\14#Q\14#Q\14#Q\0%Q\0%Q\14#Q\0%" + "Q\2'T\2'T\2'T\2'T\14#Q\2'T\2'T\2'T\10*X\2'T\10*X\10*X\10*X\10*X\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\12+Y\12+Y\12+YK\312\363K\312\363\12+Y\12+Y\12+Y\0\0\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\17At\17At\17At\23Bv\23Bv\23Bv\24" + "Cw\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32" + "G{\34H|\32G{\34H|\34H|\32G{\35I}\35I}\35I}\35I}\20L\177\20L\177\20L\177" + "\20L\177\22M\200\22M\200\22M\200\24N\201\24N\201\24N\201\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\33Q\205\33Q\205\33Q\205K\312\363K\312\363\33Q\205\33Q\205\33Q\205\0" + "\0\2\36E\2\36E\5\40H\2\36E\5\40H\2\36E\5\40H\2\36E\2\36E\5\40H\5\40H" + "\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\4\37M\4\37M\4\37M\4\37M\0\"M\4\37" + "M\0\"M\0\"M\0\"M\14#Q\0\"M\0#O\0$P\0#O\0$P\0$P\0$P\0%Q\14#Q\14#Q\14#" + "Q\0%Q\0%Q\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\0%Q\14#Q\0%Q\2'T\14#Q\2'T\2'T\2'" + "T\2'T\2'T\2'T\10*X\10*X\2'T\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10" + "*X\10*X\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\0\0\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\17At\15" + "@s\15@s\15@s\17At\17At\17At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24" + "Cw\24Cw\24Cw\30Ey\30Ey\30Ey\30Ey\30Ey\30Ey\32G{\30Ey\34H|\20L\177\34" + "H|\34H|\35I}\35I}\35I}\34H|\35I}\20L\177\20L\177\20L\177\20L\177\35I" + "}\22M\200\22M\200\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26" + "O\202\26O\202\26O\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\27P\203\27P\203\27P\203\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\0\0\2\36E\2\36E" + "\5\40H\2\36E\2\36E\5\40H\2\36E\5\40H\5\40H\5\40H\5\40H\5\40H\5\40H\5" + "\40H\5\40H\0\"M\4\37M\0\"M\4\37M\4\37M\4\37M\4\37M\4\37M\0\"M\0#O\0\"" + "M\0\"M\0$P\0$P\0#O\0#O\14#Q\0%Q\14#Q\0$P\14#Q\0%Q\0%Q\0%Q\14#Q\0%Q\14" + "#Q\14#Q\0%Q\0%Q\14#Q\0%Q\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\2'T\10*X\10" + "*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\10*X\12+Y\12+Y\12" + "+Y\12+Y\12+Y\12+Y\12+Y\12+Y\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13,Z\13" + ",Z\13,Z\13,Z\13,Z\13,Z\0\0\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11>q\11" + ">q\11>q\11>q\11>q\11>q\11>q\15@s\15@s\15@s\15@s\15@s\15@s\15@s\17At\17" + "At\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\23Bv\24Cw\24Cw\24Cw\24Cw\24Cw\24Cw\30" + "Ey\24Cw\30Ey\30Ey\30Ey\30Ey\32G{\34H|\32G{\34H|\20L\177\35I}\35I}\20" + "L\177\35I}\34H|\20L\177\20L\177\20L\177\35I}\22M\200\22M\200\22M\200" + "\24N\201\24N\201\26O\202\26O\202\26O\202\26O\202\26O\202\26O\202\26O" + "\202\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203\27P\203" + "\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q" + "\205\33Q\205\33Q\205\33Q\205\33Q\205\33Q\205\0\0", +}; + + diff --git a/polymer/build/rsrc/game.bmp b/polymer/build/rsrc/game.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1b00a3ad0bfac200b6ed1d0f988ed73f4ef546fe GIT binary patch literal 26774 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 af#kJZNj67)*n0hhxG6VUka{SEH~U`=C>Tiq literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/game.xcf b/polymer/build/rsrc/game.xcf new file mode 100644 index 0000000000000000000000000000000000000000..fadc54b2d9b82786e3cc3e30a3b53b4d32dd4cee GIT binary patch literal 86377 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 + + + + + + + +/* GdkPixbuf RGB C-Source image dump */ + +const GdkPixdata startbanner_pixdata = { + 0x47646b50, /* Pixbuf magic: 'GdkP' */ + 24 + 76160, /* header length + pixel_data length */ + 0x1010001, /* pixdata_type */ + 272, /* rowstride */ + 90, /* width */ + 280, /* height */ + /* pixel_data: */ + "\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25" + "0\10\30""1\1\25""0\10\30""1\1\30""1\1\23""3\3\27""1\12\23""3\3\23""3" + "\3\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3" + "\30""1\1\23""3\3\27""1\12\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\32" + "8\2\32""8\2\27""8\11\34:\5\34:\5\27""8\11\34:\5\27=\7\27=\7\27=\7\27" + "=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\36B\5\32\77\12\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\36B\5\33A\14\33A\14\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23""2" + "Z\15.W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0" + "Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""2Z\15-\\\16-\\\16""0Y\24-\\\16-\\\16""3[\16/^\20""3[\16/^\20/^" + "\20/^\20""3[\16""0_\21""3[\16""0_\21""0_\21""0_\21""2a\23""2a\23""2a" + "\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7" + "e\17""7e\17""7e\17""7e\17""9g\21""7f\30""4j\23""4j\23""9g\21""4j\23""5" + "k\24""4j\23""9g\21""5k\24""9g\21""5k\24""4j\23""5k\24""9g\21""4j\23""5" + "k\24""5k\24""5k\24""6l\25""9g\21""5k\24""5k\24""5k\24""5k\24""6l\25""9" + "g\21\0\0\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25" + "0\10\30""1\1\25""0\10\25""0\10\23""3\3\23""3\3\27""1\12\23""3\3\27""1" + "\12\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\30" + "1\1\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25" + "5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\32" + "8\2\32""8\2\27""8\11\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\27=\7" + "\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36" + "B\5\33A\14\36B\5\33A\14\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23." + "W\23""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""2" + "Z\15""2Z\15""3[\16-\\\16""3[\16""0Y\24/^\20/^\20""3[\16/^\20/^\20/^\20" + "3[\16""0_\21""0_\21""3[\16""0_\21""3[\16""2a\23""2a\23""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5d\26""5d\26""5d\26" + "7e\17""5d\26""9g\21""9g\21""9g\21""4j\23""4j\23""4j\23""9g\21""4j\23" + "9g\21""4j\23""9g\21""5k\24""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24" + "9g\21""6l\25""9g\21""5k\24""5k\24\202\320q\202\320q9g\21""6l\25""9g\21" + "\0\0\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0" + "\10\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3" + "\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\27" + "1\12\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\31""9\13\32" + "8\2\27""8\11\34:\5\31""9\13\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\35;\6" + "\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5" + "\202\320q\202\320q\33A\14\36B\5\33A\14\0\0.W\23.W\23.W\23""2Z\15.W\23" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24" + "2Z\15""2Z\15""2Z\15""0Y\24-\\\16-\\\16""0Y\24/^\20/^\20/^\20/^\20""3" + "[\16/^\20/^\20""3[\16""3[\16""0_\21""3[\16""0_\21""2a\23""2a\23""2a\23" + "2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17" + "5d\26""5d\26""7e\17""5d\26""9g\21""7f\30""4j\23""4j\23""4j\23""9g\21" + "4j\23""9g\21""9g\21""4j\23""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25" + "9g\21""5k\24""9g\21""5k\24""6l\25""9g\21""6l\25""5k\24\202\320q\202\320" + "q5k\24""6l\25""5k\24\0\0\30""1\1\25""0\10\30""1\1\23""3\3\27""1\12\23" + "3\3\23""3\3\27""1\12\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3" + "\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\30""1\1\23" + "3\3\30""1\1\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\32""8\2\32""8\2\31""9" + "\13\34:\5\27""8\11\31""9\13\34:\5\31""9\13\27=\7\27=\7\27=\7\30>\10\30" + ">\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36" + "B\5\33A\14\202\320q\202\320q\36B\5\33A\14\36B\5\0\0.W\23""0Y\24""2Z\15" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15" + "0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24-\\\16-\\\16""3[\16-\\\16""3[\16/^\20/^\20""3[\16" + "/^\20/^\20""3[\16""3[\16""0_\21""0_\21""3[\16""0_\21""0_\21""2a\23""2" + "a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5" + "d\26""7e\17""7e\17""7e\17""9g\21""7f\30""9g\21""4j\23""4j\23""4j\23""9" + "g\21""4j\23""9g\21""4j\23""4j\23""4j\23""9g\21""5k\24""9g\21""9g\21""5" + "k\24""9g\21""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25""5k\24""5" + "k\24\202\320q\202\320q9g\21""6l\25""6l\25\0\0\27""1\12\30""1\1\23""3" + "\3\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\27""1\12\23" + "3\3\23""3\3\30""1\1\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12" + "\23""3\3\27""1\12\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25" + "5\6\25""5\6\27""7\10\27""7\10\25""5\6\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32" + "8\2\32""8\2\32""8\2\34:\5\27""8\11\34:\5\34:\5\27=\7\27=\7\27=\7\27=" + "\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33" + "A\14\36B\5\33A\14\36B\5\202\320q\202\320q\33A\14\33A\14\36B\5\0\0""0" + "Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0" + "Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24-\\\16-\\\16-\\\16-\\\16""3[\16""3[\16" + "/^\20/^\20/^\20/^\20""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21" + "2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""7e\17""5d\26" + "5d\26""7e\17""5d\26""5d\26""7e\17""9g\21""9g\21""7f\30""5k\24""9g\21" + "9g\21""9g\21""4j\23""9g\21""4j\23""9g\21""4j\23""9g\21""5k\24""9g\21" + "4j\23""9g\21""6l\25""5k\24""6l\25""5k\24""6l\25""5k\24""9g\21""5k\24" + "9g\21""6l\25""5k\24\202\320q\202\320q5k\24""9g\21""5k\24\0\0\23""3\3" + "\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23" + "3\3\27""1\12\30""1\1\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\30""1\1" + "\23""3\3\27""1\12\23""3\3\24""4\5\24""4\5\30""1\1\25""5\6\25""5\6\25" + "5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32" + "8\2\31""9\13\32""8\2\31""9\13\34:\5\34:\5\34:\5\34:\5\27=\7\27=\7\27" + "=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\36" + "B\5\33A\14\33A\14\36B\5\33A\14\36B\5\202\320q\202\320q\36B\5\33A\14\36" + "B\5\0\0""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24""0Y\24""2Z\15""0Y\24-\\\16-\\\16-\\\16-\\\16""0Y\24/^\20""3[\16" + "/^\20/^\20""3[\16""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0" + "_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5" + "d\26""7e\17""5d\26""5d\26""5d\26""7e\17""7f\30""9g\21""7f\30""9g\21""5" + "k\24""9g\21""4j\23""9g\21""4j\23""4j\23""9g\21""4j\23""4j\23""5k\24""6" + "l\25""9g\21""5k\24""5k\24""9g\21""6l\25""5k\24""9g\21""9g\21""5k\24""9" + "g\21""6l\25""9g\21""5k\24""5k\24\202\320q\202\320q5k\24""9g\21""5k\24" + "\0\0\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3" + "\27""1\12\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\27" + "1\12\23""3\3\30""1\1\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6" + "\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9" + "\13\32""8\2\31""9\13\32""8\2\27""8\11\34:\5\27""8\11\34:\5\34:\5\27=" + "\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36" + "B\5\32\77\12\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33" + "A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\202\320q\202\320" + "q\36B\5\33A\14\36B\5\0\0""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2" + "Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0" + "Y\24""0Y\24""2Z\15""2Z\15""0Y\24""3[\16-\\\16-\\\16-\\\16""3[\16-\\\16" + "3[\16/^\20""3[\16/^\20/^\20/^\20""0_\21""0_\21""3[\16""0_\21""3[\16""0" + "_\21""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7" + "e\17""5d\26""7e\17""7e\17""7e\17""7e\17""7e\17""7f\30""9g\21""4j\23""9" + "g\21""5k\24""9g\21""5k\24""4j\23""9g\21""5k\24""4j\23""9g\21""4j\23""9" + "g\21""6l\25""9g\21""5k\24""9g\21""6l\25""5k\24""9g\21""5k\24""5k\24""5" + "k\24""9g\21""5k\24""6l\25""9g\21""5k\24""9g\21\202\320q\202\320q5k\24" + "5k\24""9g\21\0\0\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\23" + "3\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3" + "\23""3\3\27""1\12\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25" + "5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31" + "9\13\32""8\2\31""9\13\32""8\2\31""9\13\34:\5\27""8\11\34:\5\27=\7\27" + "=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5" + "\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14" + "\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\202\320q" + "\202\320q\33A\14\33A\14\36B\5\0\0""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24" + "2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15-\\\16-\\\16-\\\16""0Y\24/^\20" + "3[\16/^\20""3[\16/^\20""3[\16""3[\16""0_\21""0_\21""0_\21""0_\21""0_" + "\21""3[\16""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3" + "b\24""7e\17""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9g\21""9g\21""5" + "k\24""9g\21""9g\21""4j\23""5k\24""4j\23""5k\24""9g\21""9g\21""4j\23""9" + "g\21""6l\25""5k\24""6l\25""6l\25""9g\21""6l\25""9g\21""6l\25""9g\21""6" + "l\25""9g\21""5k\24""9g\21""5k\24""6l\25""5k\24""9g\21""5k\24\202\320" + "q\202\320q9g\21""5k\24""5k\24\0\0\27""1\12\30""1\1\23""3\3\23""3\3\23" + "3\3\27""1\12\23""3\3\27""1\12\30""1\1\23""3\3\23""3\3\27""1\12\23""3" + "\3\23""3\3\30""1\1\24""4\5\24""4\5\24""4\5\24""4\5\24""4\5\30""1\1\25" + "5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\31""9\13\32""8\2\31""9\13\32""8\2\27""8\11\34:\5\34:\5\27""8\11" + "\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A" + "\14\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33" + "A\14\33A\14\202\320q\202\320q\33A\14\36B\5\33A\14\0\0""0Y\24""0Y\24""0" + "Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0" + "Y\24""2Z\15""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15-\\\16-\\\16""3[\16-\\" + "\16/^\20""3[\16/^\20""3[\16/^\20""3[\16/^\20""0_\21""3[\16""0_\21""0" + "_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3" + "b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""9g\21""9" + "g\21""4j\23""5k\24""9g\21""5k\24""9g\21""4j\23""9g\21""9g\21""5k\24""9" + "g\21""5k\24""9g\21""5k\24""9g\21""6l\25""9g\21""6l\25""5k\24""6l\25""9" + "g\21""9g\21""9g\21""6l\25""9g\21""9g\21""9g\21""9g\21""5k\24""9g\21""5" + "k\24""9g\21\202\320q\202\320q9g\21""5k\24""9g\21\0\0\27""1\12\23""3\3" + "\27""1\12\23""3\3\30""1\1\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\23" + "3\3\23""3\3\27""1\12\24""4\5\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6" + "\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\31""9\13\32""8\2\31""9\13\32""8\2\31""9\13\34:\5\34:\5\34" + ":\5\31""9\13\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77" + "\12\36B\5\32\77\12\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33" + "A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33" + "A\14\33A\14\36B\5\33A\14\202\320q\202\320q\33A\14\36B\5\33A\14\0\0""0" + "Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2" + "Z\15""0Y\24""2Z\15""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15-\\\16""3[\16-\\" + "\16/^\20/^\20/^\20""3[\16/^\20""3[\16/^\20""3[\16""0_\21""0_\21""0_\21" + "0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24" + "3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""7e\17""9g\21" + "4j\23""4j\23""4j\23""9g\21""5k\24""9g\21""5k\24""4j\23""4j\23""5k\24" + "4j\23""5k\24""9g\21""5k\24""9g\21""5k\24""6l\25""9g\21""6l\25""9g\21" + "5k\24""9g\21""6l\25""9g\21""5k\24""5k\24""9g\21""5k\24""5k\24""9g\21" + "9g\21""5k\24""6l\25\202\320q\202\320q5k\24""6l\25""9g\21\0\0\23""3\3" + "\23""3\3\27""1\12\23""3\3\30""1\1\30""1\1\27""1\12\23""3\3\23""3\3\30" + "1\1\23""3\3\24""4\5\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32" + "8\2\31""9\13\31""9\13\31""9\13\32""8\2\34:\5\34:\5\31""9\13\34:\5\34" + ":\5\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5\32" + "\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\36" + "B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\33A\14\33A" + "\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14" + "\36B\5\33A\14\202\320q\202\320q\33A\14\36B\5\33A\14\0\0""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24" + "2Z\15""0Y\24""0Y\24-\\\16""3[\16-\\\16""0Y\24/^\20""3[\16/^\20/^\20/" + "^\20/^\20""3[\16/^\20/^\20""0_\21""0_\21""3[\16""0_\21""0_\21""0_\21" + "2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26" + "5d\26""7e\17""7e\17""7e\17""5d\26""9g\21""9g\21""9g\21""4j\23""5k\24" + "9g\21""5k\24""5k\24""9g\21""5k\24""9g\21""4j\23""6l\25""5k\24""9g\21" + "5k\24""9g\21""6l\25""5k\24""5k\24""9g\21""5k\24""9g\21""5k\24""6l\25" + "9g\21""6l\25""9g\21""6l\25""6l\25""9g\21""5k\24""6l\25""9g\21""6l\25" + "6l\25\202\320q\202\320q9g\21""6l\25""5k\24\0\0\23""3\3\30""1\1\27""1" + "\12\23""3\3\30""1\1\27""1\12\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5" + "\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31" + "9\13\31""9\13\34:\5\27""8\11\34:\5\27""8\11\34:\5\27=\7\27=\7\27=\7\27" + "=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5" + "\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36" + "B\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14" + "\36B\5\36B\5\202\320q\202\320q\33A\14\33A\14\36B\5\0\0""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""2Z\15""0Y\24" + "-\\\16""3[\16-\\\16-\\\16-\\\16-\\\16""3[\16""3[\16/^\20""3[\16/^\20" + "/^\20""3[\16/^\20""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""2" + "a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5" + "d\26""7e\17""7e\17""5d\26""7e\17""9g\21""7f\30""4j\23""9g\21""4j\23""4" + "j\23""5k\24""9g\21""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24""9g\21""5" + "k\24""6l\25""9g\21""6l\25""5k\24""9g\21""5k\24""5k\24""9g\21""6l\25""6" + "l\25""5k\24""5k\24""6l\25@m\30""6l\25""6l\25""6l\25""6l\25@m\30""6l\25" + "6l\25\202\320q\202\320q9g\21""9g\21""5k\24\0\0\23""3\3\23""3\3\27""1" + "\12\23""3\3\30""1\1\24""4\5\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25" + "5\6\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\31""9\13\31""9\13\32" + "8\2\34:\5\34:\5\31""9\13\34:\5\34:\5\27=\7\27=\7\27=\7\30>\10\30>\10" + "\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14\33A\14\33A\14" + "\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33" + "A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\33A\14\33A\14\36B\5\36B\5" + "\33A\14\202\320q\202\320q\33A\14\33A\14\36B\5\0\0""0Y\24""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15-\\\16-\\\16""3[\16""3[\16""3" + "[\16-\\\16-\\\16/^\20/^\20""3[\16/^\20""3[\16/^\20""3[\16/^\20/^\20/" + "^\20""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5d\26""7e\17""7e\17""7" + "e\17""9g\21""7f\30""4j\23""9g\21""4j\23""9g\21""9g\21""4j\23""4j\23""9" + "g\21""4j\23""9g\21""9g\21""6l\25""5k\24""5k\24""5k\24""9g\21""6l\25""9" + "g\21""5k\24""5k\24""5k\24""5k\24""5k\24""9g\21""6l\25""9g\21""6l\25""9" + "g\21""6l\25""6l\25@m\30""6l\25""6l\25""6l\25""6l\25@m\30""6l\25\202\320" + "q\202\320q9g\21""5k\24""5k\24\0\0\23""3\3\24""4\5\24""4\5\24""4\5\24" + "4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\32""8\2\31""9\13\31""9\13\32""8\2\31""9\13\34:\5\34:\5" + "\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\33" + "A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\36B\5" + "\33A\14\36B\5\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\202\320q" + "\202\320q\36B\5\33A\14\36B\5\0\0""0Y\24""2Z\15""2Z\15""0Y\24""2Z\15""2" + "Z\15""0Y\24""0Y\24-\\\16""3[\16-\\\16""3[\16""0Y\24-\\\16""3[\16/^\20" + "/^\20/^\20""3[\16/^\20/^\20/^\20""3[\16""0_\21""3[\16""0_\21""0_\21""0" + "_\21""3[\16""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3" + "b\24""3b\24""5d\26""7e\17""5d\26""5d\26""5d\26""7e\17""9g\21""9g\21""5" + "k\24""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24""9g\21""4j\23""9g\21""6" + "l\25""9g\21""5k\24""9g\21""5k\24""6l\25""6l\25""9g\21""9g\21""6l\25""9" + "g\21""5k\24""9g\21""5k\24""6l\25""6l\25""6l\25@m\30@m\30""6l\25@m\30" + "6l\25""6l\25""6l\25""6l\25""6l\25""6l\25""6l\25\202\320q\202\320q@m\30" + "6l\25""5k\24\0\0\24""4\5\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5" + "\6\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\31" + "9\13\32""8\2\31""9\13\32""8\2\34:\5\34:\5\34:\5\31""9\13\27=\7\27=\7" + "\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\33A\14\33A" + "\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14" + "\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14" + "\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\202\320q\202\320q\36B\5\36B" + "\5\33A\14\0\0""2Z\15""0Y\24""2Z\15""0Y\24-\\\16""3[\16-\\\16-\\\16""3" + "[\16-\\\16""0Y\24-\\\16/^\20/^\20/^\20""3[\16/^\20""3[\16/^\20""3[\16" + "/^\20""0_\21""0_\21""3[\16""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23" + "2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17" + "5d\26""5d\26""7e\17""7e\17""7f\30""9g\21""4j\23""9g\21""5k\24""9g\21" + "5k\24""4j\23""4j\23""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21""5k\24" + "9g\21""5k\24""6l\25""9g\21""6l\25""6l\25""9g\21""9g\21""6l\25@m\30""6" + "l\25""6l\25""6l\25@m\30""6l\25@m\30@m\30""6l\25""6l\25""6l\25""6l\25" + "6l\25@m\30""6l\25""6l\25\202\320q\202\320q6l\25""6l\25""9g\21\0\0\24" + "4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\32""8\2\31""9\13\31""9\13\31""9\13\32""8\2\34:\5\34:\5" + "\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32" + "\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33" + "A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\36B" + "\5\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\36" + "B\5\33A\14\202\320q\202\320q\33A\14\36B\5\33A\14\0\0""3[\16""0Y\24""3" + "[\16-\\\16-\\\16-\\\16-\\\16-\\\16""0Y\24-\\\16/^\20/^\20/^\20""3[\16" + "/^\20/^\20""3[\16/^\20/^\20""0_\21""0_\21""0_\21""0_\21""0_\21""3[\16" + "0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24" + "3b\24""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9g\21""7f\30" + "4j\23""5k\24""9g\21""4j\23""9g\21""5k\24""4j\23""9g\21""4j\23""9g\21" + "5k\24""6l\25""5k\24""9g\21""6l\25""9g\21""5k\24""6l\25""9g\21""5k\24" + "6l\25""9g\21@m\30@m\30""6l\25""6l\25""6l\25@m\30""6l\25""6l\25""6l\25" + "@m\30""6l\25""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25\202\320q\202" + "\320q6l\25""5k\24""9g\21\0\0\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6" + "\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31" + "9\13\32""8\2\31""9\13\34:\5\34:\5\27""8\11\34:\5\27=\7\27=\7\27=\7\27" + "=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\33A\14\33A" + "\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5" + "\36B\5\36B\5\36B\5\36B\5\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\36B" + "\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\202\320q\202\320" + "q\33A\14\33A\14\33A\14\0\0""0Y\24-\\\16""3[\16-\\\16-\\\16-\\\16-\\\16" + "/^\20""3[\16/^\20""3[\16/^\20""3[\16/^\20/^\20""0Y\24/^\20/^\20""0_\21" + "0_\21""0_\21""0_\21""3[\16""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26" + "7e\17""5d\26""9g\21""9g\21""9g\21""9g\21""5k\24""5k\24""9g\21""5k\24" + "9g\21""4j\23""9g\21""5k\24""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21" + "6l\25""9g\21""9g\21""6l\25""6l\25""9g\21""6l\25""6l\25@m\30""6l\25""6" + "l\25@m\30""6l\25@m\30""6l\25""6l\25""6l\25""6l\25""6l\25""6l\25@m\30" + "6l\25""6l\25""6l\25@m\30""6l\25\202\320q\202\320q6l\25""9g\21""5k\24" + "\0\0\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\31""9\13\32""8\2\32""8\2\31""9\13\32""8\2\27""8\11\34:" + "\5\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14" + "\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\33" + "A\14\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5" + "\36B\5\36B\5\33A\14\36B\5\33A\14\202\320q\202\320q\36B\5\33A\14\33A\14" + "\0\0-\\\16-\\\16""3[\16-\\\16""3[\16/^\20/^\20""3[\16/^\20""3[\16/^\20" + "/^\20""3[\16/^\20/^\20""3[\16""0_\21""0_\21""0_\21""0_\21""3[\16""0_" + "\21""0_\21""3[\16""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3" + "b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26""7e\17""7f\30""7f\30""9" + "g\21""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""4j\23""9g\21""9g\21""6" + "l\25""9g\21""9g\21""6l\25""5k\24""9g\21""9g\21""9g\21""5k\24""9g\21""5" + "k\24""6l\25@m\30""6l\25@m\30""6l\25""6l\25""6l\25""6l\25@m\30""6l\25" + "@m\30""6l\25@m\30""6l\25@m\30""6l\25""6l\25@m\30""6l\25@m\30""6l\25""6" + "l\25""6l\25\202\320q\202\320q5k\24""9g\21""5k\24\0\0\25""5\6\25""5\6" + "\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\32" + "8\2\31""9\13\27""8\11\31""9\13\34:\5\34:\5\31""9\13\34:\5\27=\7\27=\7" + "\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\36B\5\33" + "A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A" + "\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36" + "B\5\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36" + "B\5\202\320q\202\320q\36B\5\33A\14\33A\14\0\0""3[\16-\\\16-\\\16""3[" + "\16/^\20/^\20/^\20/^\20/^\20/^\20""3[\16/^\20""3[\16/^\20""0_\21""0_" + "\21""0_\21""0_\21""0_\21""3[\16""0_\21""0_\21""0_\21""2a\23""2a\23""2" + "a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7" + "e\17""5d\26""7e\17""7e\17""9g\21""4j\23""9g\21""4j\23""4j\23""5k\24""4" + "j\23""9g\21""5k\24""9g\21""4j\23""9g\21""6l\25""5k\24""5k\24""5k\24""6" + "l\25""9g\21""6l\25""9g\21""5k\24""9g\21""6l\25""6l\25""6l\25""6l\25@" + "m\30""6l\25@m\30""6l\25@m\30""6l\25""6l\25@m\30""6l\25""6l\25""6l\25" + "6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25""6l\25@m\30\202\320q\202" + "\320q5k\24""5k\24""5k\24\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\32""8\2\31""9\13\32""8\2\32""8\2\32""8\2\31""9\13\34:\5" + "\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32" + "\77\12\32\77\12\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14" + "\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\36" + "B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\202\320q\202\320q\36B\5" + "\33A\14\36B\5\0\0/^\20/^\20""3[\16/^\20/^\20""3[\16/^\20/^\20/^\20/^" + "\20/^\20/^\20""3[\16""0_\21""0_\21""3[\16""0_\21""3[\16""0_\21""3[\16" + "0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24" + "3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17""7f\30""9g\21""9g\21" + "9g\21""5k\24""9g\21""4j\23""4j\23""9g\21""9g\21""5k\24""9g\21""6l\25" + "9g\21""9g\21""5k\24""6l\25""9g\21""6l\25""9g\21""6l\25""9g\21@m\30""6" + "l\25@m\30""6l\25""6l\25""6l\25@m\30@m\30""6l\25""6l\25""6l\25@m\30""6" + "l\25@m\30""6l\25""6l\25@m\30""6l\25""6l\25""6l\25@m\30@m\30""6l\25@m" + "\30""6l\25""5k\24\202\320q\202\320q5k\24""9g\21""5k\24\0\0\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\31""9\13\32""8\2\34:" + "\5\31""9\13\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36" + "B\5\32\77\12\32\77\12\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5" + "\33A\14\33A\14\33A\14\36B\5\36B\5\36B\5\33A\14\36B\5\36B\5\33A\14\36" + "B\5\36B\5\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\36" + "B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\33A\14\36B\5\202\320" + "q\202\320q\36B\5\33A\14\33A\14\0\0/^\20/^\20""3[\16""3[\16/^\20""3[\16" + "/^\20/^\20/^\20/^\20""0Y\24/^\20""0_\21""0_\21""0_\21""0_\21""0_\21""3" + "[\16""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3" + "b\24""3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9" + "g\21""9g\21""9g\21""4j\23""4j\23""9g\21""4j\23""4j\23""9g\21""5k\24""5" + "k\24""9g\21""6l\25""9g\21""6l\25""9g\21""5k\24""9g\21""9g\21""5k\24""6" + "l\25""6l\25""6l\25@m\30""6l\25@m\30""6l\25@m\30@m\30""6l\25""6l\25@m" + "\30@m\30""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25""6l\25" + "@m\30""6l\25""5k\24""9g\21""5k\24\202\320q\202\320q5k\24""9g\21""5k\24" + "\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\32""8\2\32""8\2\32""8\2\32""8\2\32""8" + "\2\34:\5\31""9\13\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\30>\10\30>\10\30" + ">\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5" + "\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14" + "\36B\5\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14" + "\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\36B" + "\5\33A\14\202\320q\202\320q\33A\14\33A\14\33A\14\0\0/^\20/^\20""3[\16" + "/^\20""3[\16/^\20/^\20""3[\16/^\20""3[\16""0_\21""0_\21""0_\21""3[\16" + "0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17" + "5d\26""9g\21""9g\21""5k\24""4j\23""9g\21""5k\24""9g\21""5k\24""9g\21" + "4j\23""9g\21""6l\25""5k\24""5k\24""5k\24""6l\25""5k\24""5k\24""9g\21" + "9g\21""9g\21""9g\21""6l\25""6l\25@m\30@m\30""6l\25""6l\25@m\30""6l\25" + "6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25""6" + "l\25@m\30""6l\25@m\30@m\30""6l\25""6l\25""5k\24""9g\21\202\320q\202\320" + "q9g\21""5k\24""9g\21\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\31" + "9\13\32""8\2\32""8\2\34:\5\34:\5\34:\5\34:\5\27""8\11\27=\7\27=\7\27" + "=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\33A\14\36B\5\33A\14" + "\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36" + "B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\36" + "B\5\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36" + "B\5\33A\14\33A\14\36B\5\33A\14\202\320q\202\320q\33A\14\36B\5\33A\14" + "\0\0/^\20/^\20/^\20/^\20/^\20""3[\16/^\20""3[\16""0_\21""0_\21""0_\21" + "0_\21""3[\16""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7e\17" + "5d\26""5d\26""7e\17""9g\21""5k\24""4j\23""4j\23""5k\24""9g\21""4j\23" + "5k\24""9g\21""9g\21""6l\25""9g\21""6l\25""6l\25""9g\21""5k\24""9g\21" + "6l\25""5k\24""9g\21""5k\24@m\30""6l\25@m\30""6l\25""6l\25""6l\25""6l" + "\25@m\30""6l\25""6l\25""6l\25@m\30@m\30""6l\25""6l\25@m\30@m\30""6l\25" + "6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25@m\30""5k\24""9g\21""6l\25" + "5k\24\202\320q\202\320q6l\25""6l\25""9g\21\0\0\27""7\10\27""7\10\27""7" + "\10\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31" + "9\13\32""8\2\31""9\13\34:\5\27""8\11\34:\5\31""9\13\34:\5\27=\7\27=\7" + "\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14" + "\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\33" + "A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5" + "\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\36B" + "\5\36B\5\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\202\320q\202\320q\33" + "A\14\33A\14\36B\5\0\0/^\20/^\20""3[\16/^\20/^\20/^\20""0_\21""0_\21""0" + "_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2" + "a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5" + "d\26""7e\17""5d\26""7e\17""5d\26""9g\21""9g\21""5k\24""9g\21""5k\24""4" + "j\23""9g\21""4j\23""4j\23""5k\24""9g\21""5k\24""9g\21""5k\24""6l\25""6" + "l\25""5k\24""6l\25""5k\24""9g\21""5k\24@m\30""6l\25""6l\25""6l\25""6" + "l\25@m\30""6l\25""6l\25@m\30""6l\25""6l\25@m\30""6l\25@m\30""6l\25@m" + "\30""6l\25@m\30@m\30""6l\25""6l\25""6l\25""6l\25@m\30""6l\25""9g\21""6" + "l\25""9g\21""5k\24""9g\21""5k\24\202\320q\202\320q5k\24""9g\21""4j\23" + "\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32" + "8\2\31""9\13\31""9\13\32""8\2\31""9\13\34:\5\34:\5\31""9\13\31""9\13" + "\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36" + "B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5" + "\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B" + "\5\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A" + "\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14" + "\202\320q\202\320q\36B\5\32\77\12\32\77\12\0\0/^\20/^\20/^\20/^\20""0" + "_\21""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""2" + "a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3" + "b\24""7e\17""5d\26""5d\26""7e\17""5d\26""7e\17""7f\30""9g\21""4j\23""9" + "g\21""4j\23""4j\23""4j\23""9g\21""4j\23""5k\24""5k\24""5k\24""9g\21""9" + "g\21""5k\24""6l\25""9g\21""6l\25""9g\21""5k\24""9g\21@m\30""6l\25""6" + "l\25@m\30""6l\25""6l\25@m\30@m\30""6l\25""6l\25@m\30@m\30@m\30""6l\25" + "6l\25""6l\25@m\30@m\30""6l\25""6l\25@m\30""6l\25@m\30""6l\25""6l\25""6" + "l\25""9g\21""6l\25""9g\21""5k\24""9g\21""9g\21""9g\21\202\320q\202\320" + "q5k\24""9g\21""5k\24\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\32""8\2\32""8\2\32""8\2\32""8\2\31""9\13\31""9\13\31""9\13\34:\5" + "\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77" + "\12\36B\5\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14" + "\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\36B\5\36B\5\36B" + "\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14\33A\14\36B\5\36B\5\33A\14\36" + "B\5\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\33A\14\202\320q\202\320q\36B\5\32\77\12\32\77\12\0\0/" + "^\20/^\20""0_\21""3[\16""0_\21""0_\21""0_\21""3[\16""0_\21""3[\16""0" + "_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3" + "b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7e\17""7e\17""5d\26""9" + "g\21""7f\30""5k\24""9g\21""4j\23""9g\21""5k\24""4j\23""5k\24""5k\24""4" + "j\23""6l\25""9g\21""9g\21""6l\25""9g\21""6l\25""9g\21""5k\24""9g\21""5" + "k\24""9g\21""6l\25""6l\25@m\30@m\30""6l\25""6l\25""6l\25@m\30@m\30""6" + "l\25""6l\25""6l\25@m\30@m\30""6l\25""6l\25""6l\25@m\30""6l\25@m\30""6" + "l\25@m\30""6l\25@m\30""6l\25""6l\25""9g\21""5k\24""6l\25""5k\24""9g\21" + "5k\24""9g\21\202\320q\202\320q4j\23""4j\23""5k\24\0\0\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\32""8\2\32""8\2\31""9" + "\13\34:\5\31""9\13\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\30>\10\30>" + "\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\32\77\12\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33" + "A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\36B\5\36B\5" + "\33A\14\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14" + "\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14\33A\14\33A" + "\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\202\320q\202\320q\32\77\12" + "\36B\5\32\77\12\0\0""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21" + "3[\16""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""7e\17" + "5d\26""7e\17""7f\30""9g\21""9g\21""4j\23""4j\23""5k\24""9g\21""5k\24" + "9g\21""4j\23""4j\23""6l\25""5k\24""9g\21""5k\24""5k\24""6l\25""9g\21" + "9g\21""5k\24""9g\21""5k\24""6l\25@m\30""6l\25@m\30@m\30""6l\25""6l\25" + "@m\30""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25@m\30""6l\25""6l\25" + "6l\25""6l\25""6l\25@m\30@m\30""6l\25@m\30""5k\24""6l\25""9g\21""9g\21" + "6l\25""9g\21""6l\25""5k\24""5k\24\202\320q\202\320q5k\24""4j\23""4j\23" + "\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\32""8\2\31""9\13\32" + "8\2\32""8\2\31""9\13\34:\5\27""8\11\34:\5\27""8\11\27=\7\27=\7\27=\7" + "\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77" + "\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\33A\14\36B\5\33A\14\33A\14" + "\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\36B\5\36" + "B\5\36B\5\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\36" + "B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\36B\5\33A\14" + "\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\202" + "\320q\202\320q\32\77\12\32\77\12\36B\5\0\0""0_\21""0_\21""0_\21""0_\21" + "0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23" + "2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26" + "5d\26""7e\17""5d\26""9g\21""7f\30""4j\23""5k\24""9g\21""5k\24""4j\23" + "9g\21""4j\23""9g\21""4j\23""5k\24""5k\24""9g\21""5k\24""9g\21""5k\24" + "9g\21""5k\24""6l\25""9g\21""5k\24@m\30""6l\25@m\30""6l\25@m\30""6l\25" + "@m\30""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6" + "l\25""6l\25""6l\25""6l\25""6l\25@m\30""6l\25@m\30""5k\24""9g\21""9g\21" + "5k\24""6l\25""9g\21""5k\24""9g\21""5k\24""9g\21""4j\23\202\320q\202\320" + "q9g\21""9g\21""4j\23\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\31""9\13\32""8" + "\2\32""8\2\32""8\2\31""9\13\34:\5\34:\5\34:\5\34:\5\34:\5\27=\7\27=\7" + "\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36B\5\33A\14\33A\14" + "\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33" + "A\14\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\36" + "B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14" + "\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\32" + "\77\12\36B\5\202\320q\202\320q\32\77\12\32\77\12\32\77\12\0\0""3[\16" + "0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23" + "2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26" + "5d\26""7e\17""5d\26""7e\17""5d\26""7e\17""9g\21""9g\21""4j\23""9g\21" + "5k\24""9g\21""4j\23""9g\21""4j\23""5k\24""9g\21""6l\25""6l\25""9g\21" + "5k\24""9g\21""6l\25""9g\21""5k\24""5k\24""9g\21""5k\24@m\30""6l\25""6" + "l\25""6l\25""6l\25""6l\25@m\30""6l\25""6l\25@m\30""6l\25@m\30""6l\25" + "@m\30""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25""6l\25@m\30""6l\25" + "5k\24""9g\21""9g\21""6l\25""5k\24""5k\24""6l\25""5k\24""9g\21""4j\23" + "4j\23""5k\24\202\320q\202\320q9g\21""9g\21""7f\30\0\0\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31" + "9\13\32""8\2\32""8\2\32""8\2\31""9\13\32""8\2\34:\5\31""9\13\34:\5\31" + "9\13\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36" + "B\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14" + "\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33" + "A\14\36B\5\33A\14\32\77\12\32\77\12\32\77\12\32\77\12\202\320q\202\320" + "q\32\77\12\32\77\12\30>\10\0\0""0_\21""0_\21""3[\16""0_\21""0_\21""0" + "_\21""0_\21""3[\16""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3" + "b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""7" + "e\17""9g\21""9g\21""9g\21""4j\23""9g\21""4j\23""9g\21""9g\21""4j\23""9" + "g\21""4j\23""6l\25""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25""9" + "g\21""5k\24""6l\25@m\30""6l\25""6l\25""6l\25""6l\25""6l\25""6l\25""6" + "l\25""6l\25@m\30""6l\25@m\30""6l\25@m\30""6l\25""6l\25""6l\25""6l\25" + "@m\30""6l\25@m\30""6l\25""9g\21""5k\24""9g\21""9g\21""6l\25""5k\24""6" + "l\25""9g\21""6l\25""5k\24""9g\21""4j\23""9g\21""5k\24""4j\23\202\320" + "q\202\320q9g\21""5d\26""7e\17\0\0\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\32""8\2" + "\31""9\13\32""8\2\34:\5\34:\5\31""9\13\34:\5\34:\5\27=\7\27=\7\27=\7" + "\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77" + "\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\36B\5\33A\14\33" + "A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B" + "\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\36B\5\36B\5\33A\14" + "\36B\5\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14" + "\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\32\77\12" + "\36B\5\32\77\12\32\77\12\36B\5\202\320q\202\320q\35;\6\30>\10\27=\7\0" + "\0""3[\16""0_\21""0_\21""0_\21""3[\16""0_\21""0_\21""2a\23""2a\23""2" + "a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5" + "d\26""5d\26""7e\17""7e\17""7e\17""5d\26""9g\21""9g\21""9g\21""9g\21""4" + "j\23""4j\23""4j\23""5k\24""9g\21""9g\21""5k\24""9g\21""9g\21""5k\24""9" + "g\21""9g\21""5k\24""9g\21""9g\21""5k\24""5k\24@m\30""6l\25@m\30@m\30" + "6l\25""6l\25""6l\25""6l\25""6l\25""6l\25@m\30""6l\25""6l\25""6l\25@m" + "\30""6l\25@m\30""6l\25@m\30@m\30""6l\25""6l\25""9g\21""9g\21""5k\24""5" + "k\24""9g\21""5k\24""6l\25""9g\21""5k\24""9g\21""5k\24""4j\23""9g\21""5" + "k\24""9g\21""5k\24""4j\23\202\320q\202\320q7e\17""5d\26""7e\17\0\0\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31" + "9\13\32""8\2\31""9\13\32""8\2\31""9\13\34:\5\34:\5\34:\5\34:\5\27""8" + "\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\36B\5\33A\14\33" + "A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\36" + "B\5\36B\5\36B\5\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33" + "A\14\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\36B\5\33A\14\33" + "A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\202\320q\202\320" + "q\27=\7\27=\7\27=\7\0\0""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2" + "a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3" + "b\24""3b\24""7e\17""5d\26""5d\26""7e\17""5d\26""7e\17""7f\30""9g\21""5" + "k\24""4j\23""9g\21""5k\24""4j\23""9g\21""5k\24""5k\24""4j\23""9g\21""5" + "k\24""9g\21""6l\25""5k\24""9g\21""9g\21""5k\24""9g\21""6l\25""5k\24@" + "m\30@m\30""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25""6l\25""6l\25" + "6l\25""6l\25@m\30""6l\25""6l\25@m\30@m\30@m\30""6l\25""5k\24""9g\21""9" + "g\21""5k\24""5k\24""6l\25""9g\21""5k\24""5k\24""6l\25""4j\23""9g\21""4" + "j\23""9g\21""4j\23""9g\21""9g\21""9g\21""9g\21\202\320q\202\320q7e\17" + "5d\26""3b\24\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2" + "\31""9\13\32""8\2\32""8\2\31""9\13\31""9\13\32""8\2\34:\5\34:\5\31""9" + "\13\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32" + "\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5" + "\32\77\12\32\77\12\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33" + "A\14\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14\33A\14\36B\5" + "\36B\5\36B\5\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\36B\5\36B\5\36B" + "\5\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\36B\5" + "\33A\14\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\30>\10\202\320q\202\320q\27=\7\34:\5\31""9\13\0\0""3[\16" + "0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""5d\26" + "5d\26""7e\17""7f\30""7f\30""4j\23""4j\23""4j\23""9g\21""4j\23""5k\24" + "9g\21""5k\24""4j\23""6l\25""9g\21""6l\25""9g\21""6l\25""9g\21""5k\24" + "9g\21""5k\24""9g\21""5k\24""9g\21@m\30""6l\25@m\30""6l\25""6l\25""6l" + "\25@m\30@m\30""6l\25""6l\25""6l\25""6l\25@m\30@m\30""6l\25@m\30""6l\25" + "9g\21""6l\25""9g\21""9g\21""5k\24""9g\21""5k\24""6l\25""9g\21""5k\24" + "5k\24""9g\21""4j\23""9g\21""5k\24""5k\24""9g\21""9g\21""9g\21""9g\21" + "5d\26""7e\17\202\320q\202\320q3b\24""3b\24""3b\24\0\0\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\32""8\2\32""8" + "\2\31""9\13\34:\5\31""9\13\31""9\13\27""8\11\34:\5\27=\7\27=\7\27=\7" + "\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14\36B" + "\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5" + "\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\33A\14\36B" + "\5\36B\5\36B\5\33A\14\36B\5\36B\5\36B\5\33A\14\33A\14\33A\14\33A\14\33" + "A\14\36B\5\33A\14\33A\14\36B\5\33A\14\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27=\7\202\320q" + "\202\320q\27""8\11\34:\5\31""9\13\0\0""3[\16""0_\21""0_\21""0_\21""2" + "a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3" + "b\24""5d\26""7e\17""5d\26""5d\26""5d\26""7e\17""5d\26""7f\30""9g\21""9" + "g\21""9g\21""4j\23""9g\21""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""5" + "k\24""5k\24""6l\25""5k\24""9g\21""9g\21""6l\25""6l\25""9g\21""5k\24""6" + "l\25""5k\24@m\30""6l\25@m\30""6l\25""6l\25""6l\25@m\30""6l\25@m\30""6" + "l\25""6l\25@m\30""6l\25@m\30""6l\25""6l\25""9g\21""6l\25""9g\21""5k\24" + "9g\21""9g\21""5k\24""6l\25""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24" + "4j\23""4j\23""9g\21""5k\24""9g\21""7e\17""5d\26""5d\26""5d\26\202\320" + "q\202\320q3b\24""2a\23""2a\23\0\0\27""7\10\27""7\10\27""7\10\32""8\2" + "\31""9\13\31""9\13\32""8\2\32""8\2\31""9\13\31""9\13\34:\5\34:\5\27""8" + "\11\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\32\77\12\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\33" + "A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\36B\5\33A\14\36B\5\33" + "A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14" + "\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\30>\10" + "\30>\10\27=\7\27=\7\27=\7\202\320q\202\320q\32""8\2\31""9\13\31""9\13" + "\0\0""3[\16""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""7e\17""5d\26""5" + "d\26""5d\26""7e\17""7f\30""9g\21""4j\23""9g\21""5k\24""9g\21""5k\24""9" + "g\21""5k\24""9g\21""9g\21""5k\24""6l\25""5k\24""9g\21""5k\24""6l\25""9" + "g\21""5k\24""6l\25""5k\24""5k\24""9g\21""5k\24@m\30@m\30""6l\25""6l\25" + "@m\30""6l\25""6l\25""6l\25@m\30""6l\25@m\30""6l\25""6l\25@m\30""5k\24" + "6l\25""9g\21""9g\21""6l\25""9g\21""5k\24""9g\21""5k\24""5k\24""5k\24" + "9g\21""5k\24""4j\23""9g\21""4j\23""4j\23""9g\21""9g\21""7e\17""5d\26" + "7e\17""5d\26""5d\26""3b\24\202\320q\202\320q2a\23""2a\23""0_\21\0\0\27" + "7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\32""8\2\32""8\2\31""9" + "\13\34:\5\34:\5\27""8\11\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7" + "\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\36B\5\33A" + "\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14" + "\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B" + "\5\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14" + "\36B\5\33A\14\33A\14\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5" + "\32\77\12\32\77\12\32\77\12\30>\10\27=\7\27=\7\27=\7\34:\5\27""8\11\202" + "\320q\202\320q\31""9\13\27""7\10\27""7\10\0\0""0_\21""0_\21""2a\23""2" + "a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3" + "b\24""5d\26""5d\26""5d\26""7e\17""7e\17""5d\26""7e\17""7f\30""9g\21""9" + "g\21""5k\24""4j\23""5k\24""9g\21""4j\23""9g\21""5k\24""9g\21""6l\25""9" + "g\21""5k\24""5k\24""9g\21""5k\24""5k\24""9g\21""6l\25""9g\21""6l\25""5" + "k\24""6l\25""9g\21""6l\25""6l\25""6l\25""6l\25""6l\25""6l\25@m\30""6" + "l\25""6l\25@m\30""6l\25@m\30""5k\24""9g\21""5k\24""6l\25""9g\21""6l\25" + "9g\21""6l\25""6l\25""5k\24""9g\21""9g\21""4j\23""9g\21""5k\24""9g\21" + "4j\23""4j\23""9g\21""9g\21""7e\17""7e\17""7e\17""5d\26""3b\24""3b\24" + "3b\24\202\320q\202\320q0_\21""0_\21""0_\21\0\0\27""7\10\27""7\10\32""8" + "\2\32""8\2\31""9\13\32""8\2\31""9\13\31""9\13\34:\5\34:\5\27""8\11\34" + ":\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36" + "B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14" + "\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\36" + "B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\32\77\12\32" + "\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\30>\10\30>\10" + "\27=\7\27=\7\34:\5\34:\5\31""9\13\32""8\2\202\320q\202\320q\27""7\10" + "\27""7\10\27""7\10\0\0""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2a" + "\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5" + "d\26""5d\26""5d\26""5d\26""9g\21""7f\30""4j\23""9g\21""4j\23""4j\23""9" + "g\21""9g\21""4j\23""4j\23""5k\24""6l\25""9g\21""6l\25""6l\25""9g\21""5" + "k\24""6l\25""9g\21""6l\25""5k\24""6l\25""6l\25""5k\24""5k\24""5k\24""6" + "l\25""6l\25@m\30""6l\25""6l\25""6l\25""6l\25@m\30""6l\25@m\30""5k\24" + "6l\25""9g\21""5k\24""5k\24""6l\25""5k\24""6l\25""9g\21""5k\24""6l\25" + "5k\24""9g\21""4j\23""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21""5d\26" + "7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23\202\320q\202\320" + "q0_\21""0_\21/^\20\0\0\27""7\10\32""8\2\32""8\2\31""9\13\32""8\2\32""8" + "\2\32""8\2\31""9\13\34:\5\34:\5\31""9\13\34:\5\27""8\11\27=\7\27=\7\27" + "=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\36B\5" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\36B\5\33A\14\36B\5\33" + "A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\36B" + "\5\33A\14\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\36B\5\33" + "A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14" + "\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\30>\10\30>\10\27=\7\27=\7\27""8\11\34:\5\34:\5\31""9\13\32""8\2\31" + "9\13\202\320q\202\320q\27""7\10\27""7\10\27""7\10\0\0""0_\21""2a\23""2" + "a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""3" + "b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""7e\17""7f\30""9g\21""4" + "j\23""5k\24""4j\23""9g\21""4j\23""4j\23""5k\24""9g\21""4j\23""5k\24""6" + "l\25""9g\21""9g\21""6l\25""5k\24""6l\25""9g\21""5k\24""9g\21""5k\24""6" + "l\25""5k\24""9g\21""5k\24""6l\25@m\30@m\30""6l\25""6l\25@m\30@m\30""6" + "l\25""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25""9g\21""6l\25""5k\24""9" + "g\21""5k\24""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21""4j\23""4j\23""7" + "f\30""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""2a\23""2a\23""2" + "a\23""0_\21\202\320q\202\320q/^\20""3[\16/^\20\0\0\27""7\10\32""8\2\31" + "9\13\32""8\2\31""9\13\31""9\13\32""8\2\34:\5\34:\5\31""9\13\27""8\11" + "\34:\5\27=\7\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12" + "\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33" + "A\14\33A\14\36B\5\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A" + "\14\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36" + "B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\36B\5\32\77\12\32\77\12\30>\10\27=\7\27=\7\27=\7\34:\5\31" + "9\13\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\202\320q\202\320q\27" + "7\10\27""7\10\25""5\6\0\0""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""7" + "e\17""7e\17""7e\17""7f\30""9g\21""9g\21""5k\24""4j\23""4j\23""9g\21""5" + "k\24""5k\24""9g\21""4j\23""5k\24""9g\21""6l\25""5k\24""9g\21""9g\21""5" + "k\24""5k\24""6l\25""9g\21""5k\24""5k\24""9g\21""6l\25""9g\21""5k\24""9" + "g\21""5k\24""9g\21""6l\25""9g\21""6l\25""9g\21""6l\25""9g\21""6l\25""9" + "g\21""5k\24""5k\24""5k\24""5k\24""9g\21""5k\24""5k\24""5k\24""9g\21""5" + "k\24""4j\23""9g\21""5k\24""4j\23""9g\21""9g\21""5d\26""5d\26""7e\17""5" + "d\26""3b\24""3b\24""3b\24""2a\23""2a\23""0_\21""0_\21""3[\16\202\320" + "q\202\320q/^\20/^\20""0Y\24\0\0\32""8\2\31""9\13\32""8\2\31""9\13\32" + "8\2\31""9\13\32""8\2\31""9\13\34:\5\34:\5\27""8\11\34:\5\27=\7\27=\7" + "\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12" + "\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\33A" + "\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14" + "\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\36" + "B\5\33A\14\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\30>\10\30>\10\27=\7\27=\7\31""9\13\27""8\11\34:\5\31""9\13\32" + "8\2\27""7\10\27""7\10\27""7\10\27""7\10\202\320q\202\320q\27""7\10\25" + "5\6\25""5\6\0\0""2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b" + "\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26""7" + "e\17""9g\21""7f\30""9g\21""4j\23""9g\21""4j\23""4j\23""4j\23""4j\23""9" + "g\21""5k\24""9g\21""9g\21""9g\21""6l\25""9g\21""9g\21""6l\25""9g\21""6" + "l\25""9g\21""6l\25""5k\24""6l\25""9g\21""6l\25""9g\21""6l\25""6l\25""9" + "g\21""5k\24""9g\21""5k\24""9g\21""6l\25""5k\24""9g\21""9g\21""6l\25""9" + "g\21""6l\25""6l\25""9g\21""5k\24""5k\24""9g\21""5k\24""4j\23""4j\23""4" + "j\23""9g\21""9g\21""7f\30""7e\17""5d\26""7e\17""7e\17""3b\24""3b\24""3" + "b\24""2a\23""2a\23""2a\23""0_\21""0_\21/^\20""3[\16\202\320q\202\320" + "q3[\16-\\\16""2Z\15\0\0\31""9\13\31""9\13\32""8\2\31""9\13\32""8\2\31" + "9\13\34:\5\34:\5\34:\5\34:\5\31""9\13\27=\7\27=\7\27=\7\27=\7\30>\10" + "\30>\10\30>\10\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\33A\14\33A\14\33A\14" + "\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\33A\14\33A\14\36" + "B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A" + "\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\32\77\12\36" + "B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27=\7\27" + "=\7\34:\5\34:\5\27""8\11\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\202\320q\202\320q\25""5\6\24""4\5\27""1\12\0\0" + "2a\23""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24" + "3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9g\21" + "4j\23""5k\24""4j\23""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""5k\24" + "9g\21""9g\21""9g\21""9g\21""6l\25""6l\25""9g\21""5k\24""5k\24""5k\24" + "5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25""9g\21""6l\25""9g\21" + "6l\25""9g\21""5k\24""9g\21""9g\21""5k\24""6l\25""9g\21""6l\25""5k\24" + "9g\21""9g\21""5k\24""9g\21""5k\24""4j\23""4j\23""9g\21""9g\21""5d\26" + "7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""3[\16" + "0_\21""3[\16/^\20""3[\16/^\20\202\320q\202\320q2Z\15""0Y\24""0Y\24\0" + "\0\32""8\2\32""8\2\31""9\13\32""8\2\32""8\2\34:\5\34:\5\31""9\13\34:" + "\5\34:\5\27""8\11\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14" + "\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33" + "A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\36" + "B\5\33A\14\33A\14\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\27""8\11" + "\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\202\320q\202\320q\24""4\5\23""3\3\23""3\3\0\0""2a" + "\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""3" + "b\24""7e\17""5d\26""5d\26""7e\17""7e\17""5d\26""9g\21""9g\21""4j\23""9" + "g\21""4j\23""9g\21""4j\23""5k\24""9g\21""5k\24""4j\23""9g\21""5k\24""5" + "k\24""9g\21""5k\24""6l\25""9g\21""6l\25""9g\21""6l\25""9g\21""5k\24""9" + "g\21""5k\24""5k\24""9g\21""5k\24""6l\25""9g\21""6l\25""6l\25""9g\21""9" + "g\21""9g\21""6l\25""5k\24""9g\21""5k\24""6l\25""9g\21""5k\24""5k\24""4" + "j\23""9g\21""9g\21""5k\24""9g\21""4j\23""9g\21""5d\26""5d\26""5d\26""5" + "d\26""5d\26""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21/" + "^\20/^\20""3[\16/^\20-\\\16\202\320q\202\320q0Y\24""2Z\15""0Y\24\0\0" + "\32""8\2\32""8\2\31""9\13\32""8\2\32""8\2\34:\5\34:\5\31""9\13\34:\5" + "\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\36B\5\32\77\12\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14" + "\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33" + "A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A" + "\14\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\30>\10\27=\7\27=\7\27=\7\31""9\13\34:\5\27""8\11\32""8\2\31" + "9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\24""4\5\202\320q\202\320q\27""1\12\23""3\3\27""1\12\0\0""2a\23""2" + "a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5" + "d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9g\21""9g\21""4j\23""9g\21""4" + "j\23""5k\24""5k\24""9g\21""4j\23""4j\23""5k\24""9g\21""6l\25""9g\21""9" + "g\21""5k\24""9g\21""6l\25""5k\24""6l\25""9g\21""6l\25""6l\25""5k\24""9" + "g\21""6l\25""9g\21""5k\24""6l\25""9g\21""5k\24""5k\24""6l\25""9g\21""5" + "k\24""5k\24""9g\21""6l\25""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24""9" + "g\21""9g\21""4j\23""9g\21""9g\21""7e\17""7e\17""7e\17""5d\26""3b\24""3" + "b\24""3b\24""2a\23""2a\23""0_\21""0_\21""0_\21""3[\16/^\20/^\20/^\20" + "-\\\16""0Y\24""0Y\24\202\320q\202\320q0Y\24""0Y\24""0Y\24\0\0\32""8\2" + "\31""9\13\32""8\2\32""8\2\34:\5\34:\5\31""9\13\34:\5\34:\5\27=\7\27=" + "\7\27=\7\27=\7\27=\7\30>\10\30>\10\36B\5\32\77\12\36B\5\32\77\12\32\77" + "\12\36B\5\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\33A\14\36" + "B\5\33A\14\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\36B" + "\5\33A\14\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\30>\10\30>\10\27=\7\27" + "=\7\31""9\13\27""8\11\34:\5\27""8\11\32""8\2\32""8\2\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3" + "\202\320q\202\320q\30""1\1\23""3\3\27""1\12\0\0""2a\23""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7e\17" + "5d\26""7e\17""5d\26""9g\21""9g\21""5k\24""4j\23""4j\23""5k\24""4j\23" + "4j\23""4j\23""9g\21""5k\24""9g\21""5k\24""5k\24""9g\21""6l\25""9g\21" + "5k\24""9g\21""5k\24""9g\21""6l\25""6l\25""5k\24""5k\24""9g\21""6l\25" + "5k\24""9g\21""5k\24""9g\21""6l\25""5k\24""6l\25""9g\21""6l\25""9g\21" + "6l\25""9g\21""4j\23""4j\23""5k\24""9g\21""9g\21""9g\21""4j\23""9g\21" + "9g\21""5d\26""7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23" + "2a\23""0_\21""0_\21""3[\16""3[\16/^\20/^\20""3[\16""0Y\24""2Z\15""2Z" + "\15""0Y\24\202\320q\202\320q0Y\24""0Y\24.W\23\0\0\32""8\2\31""9\13\32" + "8\2\32""8\2\31""9\13\34:\5\34:\5\34:\5\31""9\13\27=\7\27=\7\27=\7\27" + "=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14\33" + "A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5" + "\33A\14\36B\5\36B\5\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\33A\14\33" + "A\14\33A\14\33A\14\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27=\7\27=\7\27""8\11\34:\5" + "\27""8\11\32""8\2\31""9\13\31""9\13\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3\23""3" + "\3\202\320q\202\320q\30""1\1\30""1\1\25""0\10\0\0""2a\23""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26" + "7e\17""5d\26""7e\17""9g\21""7f\30""4j\23""4j\23""9g\21""5k\24""9g\21" + "5k\24""4j\23""5k\24""9g\21""6l\25""6l\25""5k\24""9g\21""5k\24""9g\21" + "5k\24""5k\24""5k\24""5k\24""5k\24""6l\25""5k\24""9g\21""5k\24""5k\24" + "5k\24""9g\21""6l\25""9g\21""5k\24""6l\25""9g\21""5k\24""9g\21""6l\25" + "9g\21""9g\21""4j\23""9g\21""4j\23""9g\21""9g\21""4j\23""9g\21""7e\17" + "5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21" + "0_\21""0_\21""3[\16/^\20""3[\16""3[\16-\\\16-\\\16""0Y\24""0Y\24""2Z" + "\15""0Y\24\202\320q\202\320q.W\23.W\23-V\22\0\0\32""8\2\31""9\13\32""8" + "\2\32""8\2\34:\5\27""8\11\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30" + ">\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\33A\14\36B\5\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36" + "B\5\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\31""9\13\32""8\2\31" + "9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\25""5\6\24""4\5\30""1\1\23""3\3\23""3\3\23""3\3\202\320" + "q\202\320q\25""0\10\25""0\10\25""0\10\0\0""2a\23""2a\23""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""5d\26" + "7e\17""9g\21""7f\30""4j\23""5k\24""9g\21""4j\23""9g\21""4j\23""5k\24" + "9g\21""4j\23""9g\21""6l\25""5k\24""6l\25""6l\25""9g\21""5k\24""9g\21" + "5k\24""6l\25""9g\21""6l\25""9g\21""5k\24""5k\24""5k\24""5k\24""9g\21" + "5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25""9g\21""9g\21""4j\23" + "9g\21""9g\21""4j\23""9g\21""4j\23""7f\30""9g\21""5d\26""7e\17""5d\26" + "5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""3[\16""0_\21""0_\21""0_\21" + "/^\20""3[\16/^\20""0Y\24""3[\16""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""2" + "Z\15\202\320q\202\320q-V\22-V\22-V\22\0\0\32""8\2\31""9\13\32""8\2\27" + "8\11\34:\5\34:\5\27""8\11\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10" + "\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36" + "B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\33A\14\36B\5\36B\5\33A" + "\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14" + "\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\30>\10\30>\10\27=\7\27=\7\27""8\11\34:\5\27""8\11\32""8\2\32""8" + "\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\30""1\1\30""1\1\23""3\3\23""3\3\27""1\12\30""1\1" + "\202\320q\202\320q\25""0\10\25""0\10\25/\7\0\0""2a\23""2a\23""2a\23""3" + "b\24""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""5d\26""7" + "e\17""7e\17""7f\30""9g\21""5k\24""4j\23""9g\21""4j\23""9g\21""4j\23""5" + "k\24""9g\21""4j\23""9g\21""5k\24""9g\21""5k\24""6l\25""9g\21""6l\25""5" + "k\24""9g\21""5k\24""9g\21""6l\25""9g\21""9g\21""5k\24""6l\25""9g\21""5" + "k\24""9g\21""5k\24""9g\21""5k\24""9g\21""9g\21""5k\24""9g\21""9g\21""4" + "j\23""9g\21""4j\23""9g\21""9g\21""9g\21""5d\26""7e\17""7e\17""5d\26""3" + "b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16/^\20/^\20" + "3[\16-\\\16""3[\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15.W\23.W\23" + "\202\320q\202\320q-V\22""0R\16*T\16\0\0\31""9\13\31""9\13\32""8\2\34" + ":\5\34:\5\27""8\11\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>" + "\10\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\36B\5\32\77\12\32\77\12\36B\5\32\77\12\33A\14\36B\5\33A\14\33A\14\36" + "B\5\33A\14\33A\14\36B\5\33A\14\33A\14\33A\14\33A\14\33A\14\36B\5\33A" + "\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>" + "\10\27=\7\27=\7\34:\5\34:\5\31""9\13\32""8\2\31""9\13\32""8\2\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5" + "\24""4\5\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\30""1\1\30""1\1\202" + "\320q\202\320q\25/\7\25/\7\25/\7\0\0""2a\23""2a\23""2a\23""3b\24""3b" + "\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""9" + "g\21""9g\21""9g\21""9g\21""4j\23""4j\23""4j\23""4j\23""5k\24""4j\23""9" + "g\21""5k\24""9g\21""5k\24""6l\25""9g\21""5k\24""6l\25""9g\21""6l\25""9" + "g\21""5k\24""9g\21""5k\24""9g\21""6l\25""6l\25""9g\21""9g\21""5k\24""9" + "g\21""5k\24""9g\21""4j\23""9g\21""9g\21""5k\24""4j\23""9g\21""5k\24""4" + "j\23""9g\21""9g\21""7e\17""5d\26""5d\26""7e\17""3b\24""3b\24""3b\24""2" + "a\23""2a\23""2a\23""3[\16""0_\21""0_\21""3[\16/^\20/^\20/^\20""3[\16" + "-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23-V\22\202\320" + "q\202\320q*T\16""0R\16*T\16\0\0\31""9\13\32""8\2\27""8\11\34:\5\34:\5" + "\34:\5\31""9\13\27=\7\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\36B\5\36B\5\33A\14\33A\14\36B\5\33A\14\36B\5" + "\33A\14\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\33" + "A\14\33A\14\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77" + "\12\32\77\12\32\77\12\36B\5\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7" + "\27""8\11\34:\5\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\27""1\12\23""3" + "\3\27""1\12\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\202\320" + "q\202\320q\25/\7\25/\7\25/\7\0\0""2a\23""2a\23""3b\24""3b\24""3b\24""3" + "b\24""3b\24""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""7e\17""7f\30""9" + "g\21""4j\23""4j\23""5k\24""9g\21""4j\23""4j\23""5k\24""9g\21""4j\23""4" + "j\23""5k\24""5k\24""6l\25""9g\21""6l\25""9g\21""6l\25""5k\24""9g\21""5" + "k\24""5k\24""6l\25""9g\21""9g\21""5k\24""5k\24""9g\21""5k\24""9g\21""5" + "k\24""5k\24""9g\21""9g\21""5k\24""4j\23""5k\24""9g\21""9g\21""9g\21""5" + "d\26""5d\26""5d\26""7e\17""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""3" + "[\16""0_\21""0_\21/^\20/^\20/^\20/^\20""3[\16-\\\16""2Z\15""0Y\24""0" + "Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23.W\23-V\22-V\22\202\320q\202\320q" + "*T\16*T\16*T\16\0\0\32""8\2\31""9\13\34:\5\34:\5\27""8\11\34:\5\34:\5" + "\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32" + "\77\12\36B\5\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\33" + "A\14\33A\14\36B\5\33A\14\33A\14\33A\14\36B\5\33A\14\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\34:\5\34:\5\32""8\2\32" + "8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\25""0\10" + "\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\202\320q\202\320q\25/\7\24" + ".\5\24.\5\0\0""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""5d\26" + "7e\17""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""7f\30""4j\23""9g\21" + "5k\24""9g\21""5k\24""4j\23""4j\23""4j\23""9g\21""5k\24""4j\23""5k\24" + "5k\24""6l\25""9g\21""6l\25""9g\21""5k\24""9g\21""5k\24""9g\21""6l\25" + "6l\25""9g\21""5k\24""6l\25""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21" + "5k\24""9g\21""9g\21""5k\24""9g\21""9g\21""7e\17""7e\17""5d\26""5d\26" + "3b\24""3b\24""3b\24""2a\23""2a\23""0_\21""3[\16""0_\21/^\20""3[\16/^" + "\20""3[\16-\\\16-\\\16""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24.W\23" + ".W\23.W\23-V\22-V\22*T\16*T\16\202\320q\202\320q*T\16*T\16*T\16\0\0\32" + "8\2\31""9\13\34:\5\34:\5\27""8\11\34:\5\27=\7\27=\7\27=\7\27=\7\27=\7" + "\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5" + "\33A\14\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\33A\14\36B\5\33" + "A\14\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27" + "=\7\27=\7\27""8\11\34:\5\31""9\13\32""8\2\32""8\2\32""8\2\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24" + "4\5\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3\30""1\1\25""0\10\25""0\10" + "\25""0\10\25/\7\25/\7\25/\7\202\320q\202\320q\24.\5\24.\5\24.\5\0\0""2" + "a\23""2a\23""3b\24""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5d\26""7" + "e\17""5d\26""7e\17""7f\30""9g\21""9g\21""9g\21""9g\21""4j\23""5k\24""9" + "g\21""4j\23""4j\23""9g\21""5k\24""9g\21""4j\23""5k\24""6l\25""9g\21""6" + "l\25""5k\24""5k\24""9g\21""6l\25""6l\25""9g\21""5k\24""4j\23""9g\21""4" + "j\23""9g\21""4j\23""5k\24""4j\23""9g\21""4j\23""9g\21""5k\24""9g\21""9" + "g\21""9g\21""7e\17""7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2" + "a\23""2a\23""0_\21""3[\16""0_\21""3[\16/^\20/^\20""3[\16-\\\16""2Z\15" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24.W\23.W\23-V\22-V\22*T\16*T\16" + "*T\16*T\16\202\320q\202\320q*T\16*T\16*T\16\0\0\32""8\2\31""9\13\34:" + "\5\34:\5\34:\5\31""9\13\34:\5\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10" + "\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\33A\14\33" + "A\14\36B\5\33A\14\36B\5\33A\14\33A\14\33A\14\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36" + "B\5\32\77\12\32\77\12\30>\10\30>\10\27=\7\27=\7\31""9\13\34:\5\34:\5" + "\31""9\13\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3\30""1\1\23""3\3" + "\27""1\12\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/" + "\7\25/\7\25/\7\202\320q\202\320q\24.\5\24.\5\23,\3\0\0""2a\23""2a\23" + "3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26""7e\17" + "5d\26""9g\21""7f\30""4j\23""9g\21""4j\23""9g\21""5k\24""4j\23""9g\21" + "4j\23""4j\23""9g\21""4j\23""4j\23""5k\24""4j\23""9g\21""5k\24""6l\25" + "9g\21""6l\25""9g\21""5k\24""9g\21""9g\21""5k\24""9g\21""4j\23""5k\24" + "9g\21""4j\23""5k\24""4j\23""4j\23""4j\23""9g\21""9g\21""7e\17""5d\26" + "5d\26""5d\26""7e\17""3b\24""3b\24""3b\24""2a\23""2a\23""0_\21""3[\16" + "0_\21""0_\21/^\20""3[\16/^\20-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24""0Y\24""0Y\24.W\23.W\23-V\22-V\22*T\16*T\16*T\16""0R\16*T\16\202" + "\320q\202\320q*T\16*T\16*N\22\0\0\31""9\13\32""8\2\31""9\13\34:\5\34" + ":\5\31""9\13\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\34:\5\31""9\13\32""8" + "\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\25""5\6\25""5\6\24""4\5\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3" + "\27""1\12\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7" + "\24.\5\24.\5\202\320q\202\320q\24.\5\23,\3\23,\3\0\0""2a\23""2a\23""3" + "b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5d\26""7e\17""9" + "g\21""7f\30""9g\21""4j\23""9g\21""5k\24""9g\21""9g\21""5k\24""9g\21""5" + "k\24""9g\21""5k\24""4j\23""5k\24""9g\21""5k\24""4j\23""9g\21""4j\23""4" + "j\23""5k\24""9g\21""5k\24""4j\23""4j\23""9g\21""4j\23""4j\23""5k\24""9" + "g\21""4j\23""9g\21""4j\23""9g\21""9g\21""5d\26""7e\17""7e\17""7e\17""5" + "d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16/" + "^\20/^\20/^\20""3[\16-\\\16-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24.W\23.W\23-V\22-V\22*T\16""0R\16*T\16*T\16""0R\16*T\16*T\16\202" + "\320q\202\320q(R\14*N\22.P\14\0\0\31""9\13\34:\5\34:\5\31""9\13\34:\5" + "\27""8\11\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\36" + "B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\30>\10" + "\30>\10\30>\10\27=\7\27=\7\34:\5\31""9\13\34:\5\31""9\13\32""8\2\31""9" + "\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\27""1\12\27""1\12\23""3\3\23""3\3\27""1\12\30""1" + "\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\24.\5\24" + ".\5\24.\5\202\320q\202\320q\23,\3\17+\10\23,\3\0\0""2a\23""3b\24""3b" + "\24""3b\24""3b\24""5d\26""5d\26""5d\26""7e\17""7e\17""7e\17""5d\26""9" + "g\21""7f\30""9g\21""9g\21""4j\23""5k\24""4j\23""9g\21""4j\23""9g\21""9" + "g\21""4j\23""5k\24""9g\21""4j\23""9g\21""9g\21""4j\23""9g\21""4j\23""5" + "k\24""9g\21""9g\21""4j\23""9g\21""4j\23""4j\23""5k\24""9g\21""4j\23""5" + "k\24""9g\21""9g\21""7f\30""7e\17""5d\26""7e\17""5d\26""5d\26""5d\26""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21""3[\16""3" + "[\16/^\20-\\\16""3[\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15.W\23" + ".W\23-V\22-V\22-V\22""0R\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16\202" + "\320q\202\320q*N\22.P\14.P\14\0\0\32""8\2\31""9\13\27""8\11\34:\5\34" + ":\5\35;\6\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36" + "B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\30>\10\30>\10" + "\30>\10\27=\7\27=\7\27=\7\31""9\13\34:\5\34:\5\31""9\13\32""8\2\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25" + "5\6\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\25""0\10" + "\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5" + "\24.\5\24.\5\202\320q\202\320q\23,\3\23,\3\17+\10\0\0""2a\23""3b\24""3" + "b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""9g\21""9" + "g\21""9g\21""9g\21""9g\21""5k\24""4j\23""5k\24""9g\21""4j\23""5k\24""9" + "g\21""4j\23""4j\23""5k\24""9g\21""5k\24""9g\21""9g\21""4j\23""4j\23""9" + "g\21""5k\24""9g\21""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24""9g\21""4" + "j\23""9g\21""7f\30""7e\17""5d\26""5d\26""5d\26""7e\17""3b\24""3b\24""3" + "b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""3[\16/^\20/^\20""0Y\24" + "3[\16""2Z\15""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24.W\23.W\23-V\22" + "-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*N\22\202\320q\202" + "\320q.P\14*N\22.P\14\0\0\27""8\11\34:\5\27""8\11\34:\5\31""9\13\27=\7" + "\27=\7\27=\7\30>\10\30>\10\30>\10\30>\10\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5" + "\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\34" + ":\5\27""8\11\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3\30""1" + "\1\23""3\3\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\17+\10\23,\3\202\320" + "q\202\320q\23,\3\23,\3\23,\3\0\0""3b\24""3b\24""3b\24""3b\24""5d\26""7" + "e\17""5d\26""7e\17""7e\17""7e\17""5d\26""9g\21""7f\30""4j\23""4j\23""9" + "g\21""9g\21""5k\24""9g\21""4j\23""4j\23""5k\24""9g\21""4j\23""4j\23""4" + "j\23""9g\21""4j\23""9g\21""5k\24""4j\23""9g\21""4j\23""5k\24""9g\21""5" + "k\24""9g\21""5k\24""9g\21""4j\23""5k\24""7f\30""9g\21""5d\26""5d\26""7" + "e\17""5d\26""7e\17""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0" + "_\21""0_\21""3[\16/^\20/^\20""3[\16-\\\16-\\\16""0Y\24""0Y\24""2Z\15" + "0Y\24""0Y\24""2Z\15.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16(R\14.P\14*N\22\202\320q\202\320q.P\14*N\22.P\14\0\0\34" + ":\5\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\30>\10\30" + ">\10\30>\10\27=\7\27=\7\27=\7\34:\5\34:\5\32""8\2\31""9\13\32""8\2\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\27""7\10\25""5\6\25" + "5\6\24""4\5\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\30""1\1\25""0\10" + "\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5" + "\24.\5\24.\5\23,\3\23,\3\23,\3\202\320q\202\320q\17+\10\23,\3\23,\3\0" + "\0""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5" + "d\26""7e\17""9g\21""7f\30""4j\23""9g\21""4j\23""5k\24""9g\21""4j\23""9" + "g\21""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""5k\24""4j\23""4j\23""9" + "g\21""9g\21""9g\21""5k\24""9g\21""4j\23""9g\21""5k\24""9g\21""4j\23""9" + "g\21""9g\21""5d\26""7e\17""7e\17""5d\26""7e\17""5d\26""3b\24""3b\24""3" + "b\24""2a\23""2a\23""0_\21""0_\21""3[\16/^\20/^\20""3[\16/^\20-\\\16""0" + "Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23-V\22" + "-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14.P\14.P\14*N\22" + "\202\320q\202\320q.P\14.P\14.P\14\0\0\34:\5\31""9\13\34:\5\31""9\13\27" + "=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12" + "\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32" + "\77\12\32\77\12\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\31""9\13\34:\5" + "\34:\5\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3\23""3\3\27""1" + "\12\30""1\1\23""3\3\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25/\7" + "\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\17+\10\23" + ",\3\202\320q\202\320q\23,\3\23,\3\23,\3\0\0""3b\24""3b\24""3b\24""3b" + "\24""7e\17""5d\26""7e\17""5d\26""7e\17""7e\17""5d\26""9g\21""7f\30""4" + "j\23""4j\23""5k\24""9g\21""5k\24""9g\21""4j\23""5k\24""9g\21""4j\23""9" + "g\21""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""5k\24""9g\21""9g\21""5" + "k\24""4j\23""9g\21""4j\23""9g\21""9g\21""5d\26""7e\17""5d\26""5d\26""5" + "d\26""7e\17""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0" + "_\21""0_\21/^\20/^\20""3[\16-\\\16""3[\16""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24.W\23.W\23.W\23-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*N\22.P\14.P\14.P\14.P\14\202\320q\202\320q*N\22*N\22*" + "N\22\0\0\34:\5\34:\5\34:\5\31""9\13\27=\7\27=\7\27=\7\30>\10\30>\10\30" + ">\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\36B\5\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\27=\7\27=\7\27" + "=\7\34:\5\34:\5\27""8\11\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4" + "\5\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\30""1\1\30""1\1\25""0\10" + "\25""0\10\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3" + "\17+\10\23,\3\23,\3\17+\10\23,\3\202\320q\202\320q\23,\3\17+\10\23,\3" + "\0\0""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""7e\17""7e\17""7e\17""7" + "e\17""9g\21""7f\30""9g\21""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21""5" + "k\24""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""4j\23""4j\23""5k\24""9" + "g\21""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""9g\21""7e\17""5d\26""5" + "d\26""7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""3" + "[\16""0_\21""3[\16""0_\21""3[\16/^\20/^\20/^\20""3[\16-\\\16""2Z\15""0" + "Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23-V\22-V\22""0R\16*T\16*T\16" + "*T\16""0R\16*T\16*T\16*T\16*T\16(R\14.P\14.P\14*N\22.P\14.P\14*N\22\202" + "\320q\202\320q*N\22*N\22*N\22\0\0\34:\5\34:\5\31""9\13\27=\7\27=\7\27" + "=\7\27=\7\30>\10\30>\10\35;\6\32\77\12\32\77\12\32\77\12\32\77\12\36" + "B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12" + "\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\27=\7\27" + "=\7\27=\7\27""8\11\34:\5\34:\5\34:\5\27""8\11\32""8\2\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25" + "5\6\24""4\5\27""1\12\23""3\3\23""3\3\23""3\3\27""1\12\30""1\1\25""0\10" + "\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5" + "\24.\5\23,\3\17+\10\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\202\320q\202" + "\320q\17+\10\23,\3\17+\10\0\0""3b\24""3b\24""7e\17""5d\26""5d\26""7e" + "\17""5d\26""7e\17""5d\26""7e\17""9g\21""9g\21""5k\24""4j\23""5k\24""9" + "g\21""9g\21""5k\24""4j\23""5k\24""9g\21""9g\21""5k\24""4j\23""4j\23""9" + "g\21""4j\23""5k\24""4j\23""9g\21""4j\23""5k\24""4j\23""7f\30""9g\21""9" + "g\21""7e\17""7e\17""5d\26""7e\17""7e\17""3b\24""3b\24""3b\24""3b\24""2" + "a\23""2a\23""2a\23""0_\21""0_\21""0_\21""3[\16/^\20/^\20/^\20-\\\16-" + "\\\16""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24.W\23.W\23-V\22" + "-V\22*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*N\22.P\14*N\22." + "P\14.P\14*N\22.P\14*N\22\202\320q\202\320q*N\22*N\22*N\22\0\0\34:\5\27" + "8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30" + ">\10\30>\10\27=\7\27=\7\27=\7\34:\5\34:\5\27""8\11\32""8\2\32""8\2\31" + "9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\24""4\5\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\30" + "1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24" + ".\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\17+\10\23,\3\23" + ",\3\202\320q\202\320q\17+\10\23,\3\17+\10\0\0""3b\24""3b\24""5d\26""5" + "d\26""7e\17""5d\26""5d\26""7e\17""5d\26""9g\21""7f\30""9g\21""9g\21""4" + "j\23""9g\21""5k\24""4j\23""9g\21""5k\24""9g\21""9g\21""4j\23""4j\23""5" + "k\24""4j\23""9g\21""9g\21""4j\23""5k\24""9g\21""4j\23""9g\21""9g\21""7" + "f\30""7e\17""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24""2" + "a\23""2a\23""2a\23""0_\21""0_\21""0_\21/^\20""3[\16/^\20/^\20/^\20""3" + "[\16""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15.W\23.W\23-V\22" + "-V\22-V\22*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16(R\14*N\22.P\14*" + "N\22.P\14.P\14*N\22.P\14*N\22.P\14\202\320q\202\320q*N\22*N\22*N\22\0" + "\0\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12" + "\36B\5\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10" + "\30>\10\27=\7\27=\7\27=\7\34:\5\31""9\13\34:\5\31""9\13\32""8\2\32""8" + "\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\24""4\5\24""4\5\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3" + "\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7" + "\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23" + ",\3\23,\3\23,\3\23,\3\202\320q\202\320q\17+\10\17+\10\17+\10\0\0""3b" + "\24""5d\26""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""7" + "f\30""9g\21""9g\21""5k\24""4j\23""5k\24""9g\21""9g\21""4j\23""4j\23""4" + "j\23""4j\23""9g\21""4j\23""5k\24""9g\21""4j\23""9g\21""4j\23""9g\21""7" + "f\30""9g\21""7e\17""5d\26""7e\17""7e\17""5d\26""7e\17""3b\24""3b\24""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21/^\20/^\20""3[\16" + "3[\16-\\\16""3[\16""2Z\15""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24." + "W\23.W\23-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*N\22" + "(R\14.P\14.P\14*N\22*N\22.P\14*N\22.P\14*N\22*N\22\202\320q\202\320q" + "*N\22*N\22*N\22\0\0\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10" + "\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77" + "\12\32\77\12\32\77\12\36B\5\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>" + "\10\27=\7\27=\7\27=\7\34:\5\31""9\13\34:\5\27""8\11\32""8\2\31""9\13" + "\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\25""5\6\24""4\5\30""1\1\24""4\5\27""1\12\23""3\3\30""1\1\23""3\3" + "\27""1\12\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/" + "\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\17+\10\23,\3\23,\3" + "\23,\3\23,\3\23,\3\17+\10\17+\10\17+\10\202\320q\202\320q\17+\10\17+" + "\10\17+\10\0\0""3b\24""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""7e\17" + "5d\26""9g\21""9g\21""9g\21""9g\21""4j\23""9g\21""4j\23""4j\23""9g\21" + "5k\24""4j\23""5k\24""9g\21""4j\23""4j\23""9g\21""4j\23""5k\24""9g\21" + "9g\21""9g\21""9g\21""7e\17""5d\26""5d\26""5d\26""5d\26""5d\26""3b\24" + "3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21/^\20/^\20""3[" + "\16/^\20""3[\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24" + ".W\23.W\23.W\23-V\22-V\22*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*N\22.P\14*N\22.P\14.P\14*N\22.P\14*N\22*N\22*N\22*N\22*N\22\202" + "\320q\202\320q*N\22*N\22*N\22\0\0\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10" + "\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\30>\10\30>" + "\10\30>\10\30>\10\27=\7\27=\7\27=\7\27""8\11\34:\5\34:\5\31""9\13\32" + "8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\25""5\6\25""5\6\24""4\5\23""3\3\23""3\3\23""3\3\23""3\3" + "\23""3\3\27""1\12\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25" + "/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\23,\3\17+\10\23,\3\23,\3\17+\10\17+\10\17+\10\202\320q\202\320" + "q\17+\10\17+\10\17+\10\0\0""7e\17""5d\26""5d\26""5d\26""7e\17""7e\17" + "5d\26""5d\26""9g\21""7f\30""9g\21""9g\21""5k\24""9g\21""4j\23""5k\24" + "9g\21""4j\23""4j\23""5k\24""9g\21""5k\24""5k\24""9g\21""5k\24""9g\21" + "9g\21""9g\21""9g\21""7e\17""5d\26""5d\26""7e\17""5d\26""5d\26""3b\24" + "3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16""0_\21" + "0Y\24""3[\16/^\20-\\\16-\\\16""2Z\15""2Z\15""2Z\15""0Y\24""0Y\24""2Z" + "\15""0Y\24.W\23.W\23-V\22-V\22-V\22*T\16""0R\16*T\16*T\16*T\16*T\16*" + "T\16*T\16(R\14.P\14*N\22.P\14.P\14*N\22.P\14.P\14*N\22.P\14*N\22*N\22" + "*N\22*N\22\202\320q\202\320q*N\22*N\22*N\22\0\0\27=\7\27=\7\27=\7\27" + "=\7\30>\10\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\36" + "B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12" + "\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30" + ">\10\30>\10\27=\7\27=\7\27=\7\34:\5\31""9\13\34:\5\34:\5\32""8\2\27""8" + "\11\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\25""5\6\25""5\6\24""4\5\23""3\3\23""3\3\27""1\12\23""3" + "\3\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25" + "/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\23,\3\17+\10\23,\3\17+\10\17+\10\17+\10\23,\3\17+\10\202\320q" + "\202\320q\23,\3\17+\10\17+\10\0\0""5d\26""7e\17""5d\26""7e\17""7e\17" + "5d\26""7e\17""5d\26""9g\21""9g\21""9g\21""7f\30""4j\23""4j\23""4j\23" + "4j\23""9g\21""9g\21""5k\24""5k\24""9g\21""4j\23""9g\21""9g\21""7f\30" + "9g\21""9g\21""7e\17""5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""3b\24" + "3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""3[\16""3[\16" + "/^\20/^\20""3[\16-\\\16""3[\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2" + "Z\15""0Y\24.W\23.W\23-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T" + "\16*T\16*T\16*N\22.P\14*N\22.P\14.P\14.P\14*N\22.P\14.P\14*N\22*N\22" + "*N\22*N\22*N\22\202\320q\202\320q*N\22*N\22*N\22\0\0\27=\7\27=\7\27=" + "\7\30>\10\30>\10\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30" + ">\10\27=\7\27=\7\27=\7\27=\7\34:\5\31""9\13\34:\5\34:\5\32""8\2\31""9" + "\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\25""5\6\24""4\5\24""4\5\27""1\12\23""3\3\23""3\3\23""3\3" + "\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/" + "\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\23,\3\23,\3\23,\3\17+\10\17+\10\17+\10\17+\10\23,\3\17+\10\202" + "\320q\202\320q\17+\10\23,\3\17+\10\0\0""5d\26""7e\17""5d\26""7e\17""5" + "d\26""7e\17""7e\17""7e\17""9g\21""9g\21""9g\21""7f\30""4j\23""9g\21""4" + "j\23""5k\24""9g\21""4j\23""4j\23""5k\24""9g\21""9g\21""7f\30""9g\21""9" + "g\21""7e\17""5d\26""7e\17""7e\17""5d\26""7e\17""5d\26""3b\24""3b\24""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21""3[\16/" + "^\20""3[\16/^\20-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y" + "\24.W\23.W\23.W\23-V\22-V\22*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16(R\14.P\14.P\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22*N\22" + "*N\22*N\22*N\22\202\320q\202\320q*N\22*N\22*N\22\0\0\27=\7\27=\7\30>" + "\10\30>\10\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\27=" + "\7\27=\7\27=\7\34:\5\31""9\13\34:\5\34:\5\31""9\13\32""8\2\31""9\13\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\24""4\5\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\30""1\1" + "\25""0\10\30""1\1\25""0\10\30""1\1\25/\7\25/\7\25/\7\25/\7\25/\7\24." + "\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\23,\3\23,\3\17+\10\17+\10\17+\10\17+\10\17+\10\23,\3\202\320q" + "\202\320q\17+\10\17+\10\17+\10\0\0""5d\26""5d\26""7e\17""5d\26""7e\17" + "5d\26""7e\17""9g\21""9g\21""9g\21""7f\30""9g\21""4j\23""9g\21""9g\21" + "5k\24""4j\23""9g\21""9g\21""7f\30""9g\21""9g\21""9g\21""5d\26""7e\17" + "7e\17""7e\17""5d\26""7e\17""5d\26""3b\24""3b\24""3b\24""3b\24""2a\23" + "2a\23""2a\23""2a\23""0_\21""0_\21""3[\16/^\20""3[\16/^\20""0Y\24""3[" + "\16""2Z\15""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15.W\23.W\23" + "-V\22-V\22-V\22*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16.P\14*" + "N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22*N\22*N\22*N\22" + "*N\22*N\22\202\320q\202\320q*N\22*N\22*N\22\0\0\27=\7\27=\7\30>\10\30" + ">\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=" + "\7\27""8\11\34:\5\31""9\13\34:\5\31""9\13\32""8\2\32""8\2\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24" + "4\5\24""4\5\23""3\3\27""1\12\30""1\1\23""3\3\30""1\1\30""1\1\25""0\10" + "\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5" + "\24.\5\24.\5\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23" + ",\3\23,\3\17+\10\17+\10\17+\10\17+\10\17+\10\23,\3\17+\10\202\320q\202" + "\320q\23,\3\17+\10\23,\3\0\0""5d\26""5d\26""5d\26""7e\17""7e\17""7f\30" + "9g\21""9g\21""9g\21""7f\30""9g\21""9g\21""7f\30""9g\21""9g\21""9g\21" + "7f\30""9g\21""7f\30""9g\21""9g\21""7e\17""7e\17""5d\26""7e\17""5d\26" + "5d\26""5d\26""5d\26""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23" + "3[\16""0_\21""0_\21""0_\21""3[\16/^\20""3[\16/^\20""3[\16""0Y\24""2Z" + "\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23-V\22-V\22-V\22" + "*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14(R\14.P\14*N\22." + "P\14*N\22*N\22.P\14*N\22.P\14*N\22*N\22*N\22*N\22*N\22*N\22*N\22*N\22" + "\202\320q\202\320q*N\22*N\22*N\22\0\0\27=\7\27=\7\30>\10\30>\10\30>\10" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30" + ">\10\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\34:\5\34:\5" + "\34:\5\27""8\11\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5" + "\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10\25" + "0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\23" + ",\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\17+\10\17" + "+\10\23,\3\17+\10\17+\10\17+\10\23,\3\17+\10\23,\3\202\320q\202\320q" + "\17+\10\17+\10\23,\3\0\0""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""7" + "f\30""9g\21""7f\30""9g\21""9g\21""9g\21""7f\30""9g\21""9g\21""9g\21""7" + "f\30""9g\21""9g\21""9g\21""7e\17""5d\26""5d\26""7e\17""7e\17""5d\26""5" + "d\26""5d\26""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0" + "_\21""0_\21""0_\21/^\20/^\20""3[\16/^\20-\\\16""3[\16""2Z\15""2Z\15""0" + "Y\24""0Y\24""2Z\15""2Z\15""0Y\24.W\23.W\23-V\22-V\22*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14*N\22.P\14*N\22.P\14*N\22.P\14" + "*N\22.P\14.P\14.P\14*N\22*N\22*N\22*N\22*N\22*N\22*N\22*N\22\202\320" + "q\202\320q*N\22*N\22*N\22\0\0\27=\7\30>\10\30>\10\30>\10\30>\10\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30" + ">\10\30>\10\35;\6\27=\7\27=\7\27=\7\34:\5\31""9\13\34:\5\34:\5\31""9" + "\13\32""8\2\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\23""3\3\23""3\3" + "\23""3\3\23""3\3\23""3\3\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23" + ",\3\23,\3\23,\3\17+\10\23,\3\23,\3\17+\10\23,\3\23,\3\17+\10\17+\10\17" + "+\10\23,\3\17+\10\17+\10\23,\3\17+\10\17+\10\202\320q\202\320q\17+\10" + "\17+\10\23,\3\0\0""5d\26""7e\17""5d\26""7e\17""5d\26""9g\21""7f\30""9" + "g\21""9g\21""9g\21""7f\30""9g\21""9g\21""7f\30""7f\30""9g\21""9g\21""7" + "e\17""5d\26""7e\17""5d\26""7e\17""7e\17""5d\26""5d\26""5d\26""5d\26""3" + "b\24""3b\24""3b\24""2a\23""2a\23""2a\23""3[\16""0_\21""0_\21""0_\21""3" + "[\16/^\20/^\20""3[\16-\\\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15" + "0Y\24""2Z\15""0Y\24.W\23.W\23-V\22-V\22*T\16""0R\16*T\16""0R\16*T\16" + "*T\16*T\16*T\16*T\16*T\16(R\14*N\22.P\14.P\14.P\14.P\14*N\22.P\14.P\14" + "*N\22.P\14.P\14*N\22*N\22*N\22*N\22*N\22*N\22*N\22*N\22\202\320q\202" + "\320q*N\22*N\22*N\22\0\0\30>\10\30>\10\30>\10\30>\10\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\27=\7\27=" + "\7\27=\7\27=\7\27=\7\31""9\13\34:\5\34:\5\34:\5\32""8\2\31""9\13\32""8" + "\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\25""5\6\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\23""3" + "\3\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25" + "/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\17+\10\23," + "\3\17+\10\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\17+\10\17+\10\17" + "+\10\23,\3\17+\10\17+\10\23,\3\17+\10\202\320q\202\320q\17+\10\17+\10" + "\23,\3\0\0""5d\26""7e\17""7e\17""5d\26""7f\30""9g\21""7f\30""9g\21""9" + "g\21""9g\21""7f\30""9g\21""9g\21""9g\21""7f\30""9g\21""7e\17""7e\17""7" + "e\17""7e\17""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24""3" + "b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""3[\16/^\20""3[\16/^\20" + "/^\20-\\\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15.W" + "\23.W\23.W\23-V\22-V\22*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16(R\14(R\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14.P\14*N\22*N\22" + "*N\22*N\22*N\22*N\22*N\22*N\22*N\22*N\22\202\320q\202\320q*N\22*N\22" + "*N\22\0\0\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\30" + ">\10\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\31""9\13\34" + ":\5\34:\5\34:\5\32""8\2\31""9\13\32""8\2\32""8\2\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24" + "4\5\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\30""1\1\30""1\1" + "\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24" + ".\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\17+\10\23,\3\23,\3\17+\10\17+\10\17+\10\17+\10\23,\3\17+\10\17" + "+\10\17+\10\202\320q\202\320q\17+\10\23,\3\23,\3\0\0""7e\17""7e\17""9" + "g\21""7f\30""9g\21""7f\30""9g\21""9g\21""9g\21""9g\21""7f\30""9g\21""9" + "g\21""7f\30""9g\21""5d\26""7e\17""5d\26""7e\17""7e\17""5d\26""5d\26""5" + "d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""2a\23""0_\21""0" + "_\21""0_\21""0_\21/^\20/^\20""0Y\24/^\20-\\\16-\\\16""2Z\15""0Y\24""0" + "Y\24""0Y\24""0Y\24""0Y\24""2Z\15.W\23.W\23-V\22-V\22-V\22*T\16*T\16""0" + "R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16.P\14*N\22.P\14*N\22.P\14.P\14" + ".P\14.P\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22*N\22*N\22*N\22*N\22*N\22" + "*N\22*N\22\202\320q\202\320q*N\22.P\14.P\14\0\0\30>\10\30>\10\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\27" + "=\7\35;\6\27=\7\27=\7\34:\5\34:\5\34:\5\34:\5\31""9\13\32""8\2\31""9" + "\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\25""5\6\24""4\5\24""4\5\27""1\12\23""3\3\23""3\3\27""1\12" + "\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7" + "\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23" + ",\3\23,\3\17+\10\23,\3\17+\10\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\17" + "+\10\17+\10\17+\10\17+\10\23,\3\17+\10\23,\3\23,\3\202\320q\202\320q" + "\23,\3\23,\3\23,\3\0\0""7e\17""7e\17""9g\21""7f\30""9g\21""9g\21""9g" + "\21""9g\21""9g\21""7f\30""9g\21""9g\21""9g\21""7f\30""7e\17""5d\26""5" + "d\26""7e\17""5d\26""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24""2" + "a\23""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21""3[\16/^\20""3" + "[\16/^\20""3[\16-\\\16""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y" + "\24.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16" + "*T\16*T\16(R\14*N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14.P\14.P\14*N\22" + "*N\22*N\22.P\14*N\22*N\22*N\22*N\22.P\14*N\22.P\14*N\22\202\320q\202" + "\320q*N\22.P\14*N\22\0\0\30>\10\30>\10\36B\5\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>" + "\10\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\27""8\11\31""9" + "\13\34:\5\34:\5\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\24""4" + "\5\23""3\3\23""3\3\23""3\3\30""1\1\27""1\12\30""1\1\30""1\1\25""0\10" + "\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23" + ",\3\17+\10\23,\3\202\320q\202\320q\23,\3\17+\10\23,\3\0\0""7e\17""7f" + "\30""9g\21""9g\21""9g\21""9g\21""9g\21""9g\21""7f\30""9g\21""7f\30""9" + "g\21""7e\17""7e\17""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""5d\26""3" + "b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""2a\23""0_\21""0_\21""0" + "_\21/^\20/^\20""3[\16/^\20-\\\16-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""2Z\15""0Y\24""0Y\24.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16(R\14(R\14.P\14*N\22.P\14*N\22.P\14.P\14" + "*N\22.P\14*N\22.P\14*N\22.P\14*N\22.P\14.P\14*N\22.P\14.P\14*N\22*N\22" + ".P\14.P\14\202\320q\202\320q.P\14.P\14*N\22\0\0\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\30>\10\30>\10\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7" + "\27=\7\31""9\13\34:\5\31""9\13\34:\5\32""8\2\31""9\13\32""8\2\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5" + "\6\25""5\6\24""4\5\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12" + "\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7" + "\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23" + ",\3\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\17+" + "\10\23,\3\17+\10\23,\3\17+\10\23,\3\23,\3\17+\10\23,\3\202\320q\202\320" + "q\23,\3\23,\3\23,\3\0\0""7f\30""9g\21""9g\21""9g\21""9g\21""9g\21""9" + "g\21""7f\30""9g\21""9g\21""9g\21""5d\26""7e\17""5d\26""5d\26""7e\17""5" + "d\26""5d\26""7e\17""5d\26""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2" + "a\23""0_\21""0_\21""0_\21""3[\16""0_\21/^\20""3[\16/^\20-\\\16-\\\16" + "-\\\16""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23-V\22" + "-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14.P\14" + ".P\14*N\22.P\14*N\22.P\14.P\14.P\14*N\22.P\14*N\22.P\14.P\14*N\22.P\14" + "*N\22.P\14.P\14*N\22.P\14.P\14*N\22.P\14.P\14\202\320q\202\320q*N\22" + ".P\14.P\14\0\0\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\30>" + "\10\27=\7\27=\7\27=\7\27=\7\27=\7\34:\5\34:\5\27""8\11\34:\5\31""9\13" + "\32""8\2\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\27""1\12\23""3\3\27""1\12" + "\23""3\3\27""1\12\23""3\3\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23" + ",\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\23," + "\3\23,\3\17+\10\23,\3\17+\10\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23" + ",\3\23,\3\17+\10\202\320q\202\320q\23,\3\23,\3\23,\3\0\0""7f\30""9g\21" + "9g\21""9g\21""9g\21""9g\21""7f\30""9g\21""9g\21""5d\26""7e\17""5d\26" + "5d\26""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24" + "3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21""0_\21""3[\16" + "/^\20/^\20/^\20""0Y\24-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24.W\23.W\23-V\22-V\22-V\22""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*N\22.P\14*N\22.P\14.P\14*N\22.P\14.P\14*N\22.P\14" + ".P\14*N\22.P\14.P\14.P\14.P\14.P\14*N\22.P\14.P\14.P\14.P\14*N\22.P\14" + ".P\14\202\320q\202\320q*N\22*N\22.P\14\0\0\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10" + "\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\34:\5\34:\5\34:\5\34:\5" + "\31""9\13\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5\23""3\3" + "\27""1\12\23""3\3\23""3\3\23""3\3\30""1\1\30""1\1\25""0\10\30""1\1\25" + "0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\17+\10\23" + ",\3\17+\10\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\17" + "+\10\23,\3\17+\10\23,\3\23,\3\17+\10\202\320q\202\320q\23,\3\23,\3\24" + ".\5\0\0""9g\21""9g\21""9g\21""9g\21""9g\21""9g\21""7f\30""9g\21""9g\21" + "7e\17""7e\17""5d\26""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24" + "3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21" + "/^\20/^\20""3[\16/^\20-\\\16-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "2Z\15""0Y\24""0Y\24.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16""0R\16*T" + "\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14.P\14.P\14.P\14\242\261\230\236" + "\262\222\242\261\230\235\261\220\235\261\220\235\261\220\235\261\220" + "\235\261\220\242\261\230\236\262\222\242\261\230\236\262\222\242\261" + "\230\236\262\222\235\261\220\242\261\230\235\261\220\236\262\222\235" + "\261\220.P\14*N\22.P\14\202\320q\202\320q*N\22*T\16*T\16\0\0\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10" + "\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\34:\5\34:\5\27""8" + "\11\34:\5\31""9\13\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5" + "\23""3\3\23""3\3\30""1\1\30""1\1\23""3\3\23""3\3\25""0\10\30""1\1\25" + "0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24." + "\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\17+\10\23,\3\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\17+\10\23,\3\17+\10\202\320q\202\320q\24.\5\24.\5\24.\5\0\0""7f" + "\30""9g\21""9g\21""7f\30""9g\21""9g\21""9g\21""7f\30""7e\17""5d\26""7" + "e\17""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24""3" + "b\24""2a\23""2a\23""2a\23""3[\16""0_\21""0_\21""0_\21""3[\16/^\20/^\20" + "/^\20-\\\16-\\\16""3[\16""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0" + "Y\24.W\23.W\23-V\22-V\22-V\22*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16(R\14*N\22.P\14.P\14\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + ".P\14.P\14.P\14\202\320q\202\320q*T\16*T\16*T\16\0\0\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30" + ">\10\27=\7\27=\7\27=\7\27=\7\27=\7\34:\5\27""8\11\34:\5\34:\5\31""9\13" + "\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\23""3\3\23""3\3\30" + "1\1\23""3\3\23""3\3\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\23,\3\23,\3\23,\3\23,\3\17+\10\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\23,\3\23,\3" + "\17+\10\202\320q\202\320q\24.\5\24.\5\24.\5\0\0""9g\21""7f\30""9g\21" + "7f\30""9g\21""9g\21""7e\17""7e\17""5d\26""7e\17""5d\26""5d\26""5d\26" + "5d\26""5d\26""7e\17""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23" + "3[\16""0_\21""0_\21""0_\21""3[\16/^\20/^\20/^\20""3[\16-\\\16""0Y\24" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23-V\22-V\22-" + "V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*N\22" + "(R\14*N\22.P\14.P\14\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374*N\22(R\14*T\16\202\320q" + "\202\320q*T\16*T\16*T\16\0\0\32\77\12\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\30>\10\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27" + "=\7\34:\5\34:\5\34:\5\31""9\13\32""8\2\32""8\2\31""9\13\32""8\2\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\24""4\5\24""4\5\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12" + "\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3" + "\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3[mP\367\371\366\372" + "\374\371\214\227\2067M+\27""1\12\27""1\12""7M+\214\227\206\372\374\371" + "\373\375\372\177\216v\23,\3\23,\3\24.\5\24.\5\202\320q\202\320q\24.\5" + "\24.\5\25/\7\0\0""9g\21""7f\30""7f\30""9g\21""9g\21""9g\21""7e\17""7" + "e\17""5d\26""7e\17""5d\26""5d\26""5d\26""7e\17""5d\26""3b\24""3b\24""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16""0_\21/^\20/^\20" + "/^\20/^\20-\\\16""3[\16""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24.W\23.W\23-V\22-V\22-V\22*T\16*T\16""0R\16*T\16""0R\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*N\22(R\14*N\22.P\14.P\14*N\22.P\14" + ".P\14*N\22*N\22Po7\370\372\367\376\377\374\215\236y*N\22.P\14.P\14.P" + "\14*N\22.P\14\215\236y\376\377\374\376\377\374t\211^*T\16*T\16*T\16\202" + "\320q\202\320q*T\16*T\16""0R\16\0\0\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27" + "=\7\31""9\13\34:\5\31""9\13\34:\5\31""9\13\32""8\2\31""9\13\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\25""5\6\25""5\6\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3\23""3\3" + "\23""3\3\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25" + "/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\23,\3\253\271" + "\255\376\377\374\376\377\3747M+\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3" + "8N,\376\377\374\376\377\374\302\311\276\24.\5\24.\5\24.\5\202\320q\202" + "\320q\25/\7\25/\7\25/\7\0\0""7f\30""9g\21""7f\30""9g\21""9g\21""9g\21" + "7e\17""7e\17""5d\26""7e\17""7e\17""5d\26""7e\17""5d\26""3b\24""3b\24" + "3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21/^\20/^" + "\20""3[\16/^\20""3[\16-\\\16""3[\16""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15" + "0Y\24""2Z\15.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16""0R\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*N\22(R\14*N\22*N\22.P\14.P\14" + "*N\22.P\14.P\14*N\22\360\362\357\376\377\374\376\377\374b|K*N\22.P\14" + ".P\14.P\14.P\14(R\14b|K\376\377\374\376\377\374\361\363\360*T\16*T\16" + "*T\16\202\320q\202\320q*T\16*T\16*T\16\0\0\32\77\12\32\77\12\32\77\12" + "\32\77\12\36B\5\32\77\12\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7" + "\27""8\11\34:\5\34:\5\31""9\13\31""9\13\32""8\2\31""9\13\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3" + "\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/" + "\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\17+\10\23,\3\370\372" + "\367\376\377\374\376\377\374\315\324\311(>\35\23,\3\23,\3\17+\10\23," + "\3(>\35\321\327\314\376\377\374\376\377\374\370\372\367\24.\5\24.\5\24" + ".\5\202\320q\202\320q\25/\7\25/\7\25/\7\0\0""9g\21""9g\21""7f\30""9g" + "\21""9g\21""7e\17""7e\17""5d\26""7e\17""7e\17""5d\26""5d\26""5d\26""3" + "b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""3[\16""0_\21""0_\21""3" + "[\16/^\20""3[\16/^\20/^\20-\\\16-\\\16""2Z\15""2Z\15""2Z\15""0Y\24""0" + "Y\24""2Z\15""0Y\24""2Z\15.W\23.W\23.W\23-V\22-V\22-V\22*T\16""0R\16*" + "T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16.P\14*N\22(R" + "\14*N\22.P\14.P\14*N\22.P\14*N\22.P\14.P\14\341\347\334\376\377\374\376" + "\377\374\376\377\374\366\370\364\277\313\270\245\264\233\245\264\233" + "\277\313\270\367\371\366\376\377\374\376\377\374\376\377\374\341\347" + "\334*T\16*T\16*T\16\202\320q\202\320q*T\16""0R\16-V\22\0\0\32\77\12\32" + "\77\12\32\77\12\32\77\12\30>\10\30>\10\30>\10\30>\10\30>\10\27=\7\27" + "=\7\27=\7\34:\5\27""8\11\34:\5\34:\5\31""9\13\32""8\2\31""9\13\32""8" + "\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\24""4\5\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3" + "\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\23" + ",\3\221\234\213\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\221\234\213\24.\5\25/\7\25/\7\202\320q\202\320q" + "\25/\7\25""0\10\25""0\10\0\0""9g\21""9g\21""9g\21""5d\26""7e\17""7e\17" + "5d\26""7e\17""5d\26""5d\26""7e\17""5d\26""3b\24""3b\24""3b\24""3b\24" + "2a\23""2a\23""2a\23""3[\16""0_\21""0_\21""0_\21""3[\16/^\20""3[\16/^" + "\20-\\\16-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z" + "\15.W\23.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16""0R\16*T\16""0R\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14*N\22(R\14*N\22.P\14.P\14" + ".P\14.P\14*N\22.P\14*N\22""6Y\35\341\347\334\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\341\347\3349\\\37*T\16*T\16*T\16\202\320" + "q\202\320q*T\16-V\22-V\22\0\0\32\77\12\32\77\12\32\77\12\30>\10\30>\10" + "\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\27=\7\34:\5\27""8\11\34:\5\32" + "8\2\32""8\2\32""8\2\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\23""3\3\30""1" + "\1\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\30""1\1\25""0\10\25""0\10" + "\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\23,\3\23,\3\23,\3\23,\3\23,\3" + "\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\17+\10+A\40\307\316\303\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\313\321\3061E\36\25/\7\25/\7\25/\7\25/\7\202\320" + "q\202\320q\25""0\10\25""0\10\25""0\10\0\0""9g\21""9g\21""7f\30""7e\17" + "7e\17""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3b\24" + "3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21""3[\16/^\20/^" + "\20""3[\16-\\\16""0Y\24-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y" + "\24""2Z\15.W\23.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16(R\14.P\14*N\22.P\14*N\22" + ".P\14.P\14.P\14*N\22*N\22.P\14(R\14(R\14*N\22m\212^\270\303\261\344\353" + "\340\370\372\367\370\372\367\345\354\341\267\307\255m\212^0R\16""0R\16" + "*T\16*T\16*T\16*T\16\202\320q\202\320q-V\22.W\23.W\23\0\0\32\77\12\32" + "\77\12\32\77\12\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\27=\7\31" + "9\13\34:\5\34:\5\31""9\13\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5" + "\6\24""4\5\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3" + "\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\17+\10\23,\3\23,\3\23,\3\23,\3\23" + ",\3\23,\3\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\202\320q\202\320q\25""0\10\30""1\1\30" + "1\1\0\0""9g\21""9g\21""7f\30""5d\26""7e\17""5d\26""5d\26""5d\26""5d\26" + "5d\26""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""3[\16""0_\21" + "0_\21""3[\16/^\20/^\20/^\20""3[\16-\\\16-\\\16""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22*T\16*" + "T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0" + "R\16*T\16*T\16(R\14(R\14.P\14(R\14*N\22(R\14(R\14.P\14(R\14(R\14.P\14" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*" + "T\16*T\16-V\22\202\320q\202\320q.W\23.W\23""0Y\24\0\0\32\77\12\32\77" + "\12\32\77\12\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\34:\5\34:\5" + "\27""8\11\32""8\2\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\24""4\5\24""4\5" + "\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\30""1\1\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\23,\3\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25""0\10\25""0\10\202\320q\202\320q\30""1\1\23""3\3\23" + "3\3\0\0""9g\21""9g\21""5d\26""7e\17""5d\26""5d\26""5d\26""7e\17""5d\26" + "3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21" + "3[\16""0_\21""3[\16""3[\16""3[\16""0Y\24-\\\16""3[\16""2Z\15""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15.W\23.W\23-V\22-V\22-V\22*T\16" + "*T\16*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16(R\14(R\14(R\14\236\262\222\236\262\222" + "\236\262\222\242\261\230\236\262\222\242\261\230\236\262\222\242\261" + "\230\236\262\222\242\261\230\236\262\222\236\262\222\236\262\222\237" + "\263\223\237\263\223\237\263\223\237\263\223\237\263\223\237\263\223" + "-V\22-V\22-V\22\202\320q\202\320q2Z\15""0Y\24""2Z\15\0\0\32\77\12\30" + ">\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\27=\7\34:\5\27""8\11\34:" + "\5\34:\5\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\30""1\1" + "\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\25""0\10\25""0\10\30" + "1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\24.\5\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\25""0\10\25""0\10" + "\30""1\1\202\320q\202\320q\23""3\3\27""1\12\23""3\3\0\0""9g\21""7e\17" + "7e\17""7e\17""5d\26""7e\17""5d\26""7e\17""3b\24""3b\24""3b\24""3b\24" + "2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21""0_\21/^\20""3[\16/^" + "\20""3[\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2" + "Z\15""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22*T\16*T\16""0R\16*T\16*T\16" + "0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374-V\22.W\23.W\23\202\320q" + "\202\320q0Y\24""0Y\24""0Y\24\0\0\32\77\12\30>\10\30>\10\35;\6\27=\7\27" + "=\7\27=\7\27=\7\27""8\11\34:\5\27""8\11\34:\5\31""9\13\32""8\2\31""9" + "\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\24""4\5\24""4\5\24""4\5\23""3\3\23""3\3\23""3\3\23""3\3" + "\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10" + "\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\24.\5\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\30""1\1\25""0\10\25""0\10\202\320q\202" + "\320q\23""3\3\23""3\3\30""1\1\0\0""7e\17""7e\17""5d\26""7e\17""5d\26" + "5d\26""5d\26""3b\24""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21" + "0_\21""0_\21""0_\21""3[\16/^\20""3[\16/^\20-\\\16-\\\16""2Z\15""2Z\15" + "0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24.W\23.W\23.W\23-V\22-" + "V\22-V\22""0R\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374.W\23.W\23""0Y\24\202\320q\202\320q0Y\24""2Z\15""2" + "Z\15\0\0\30>\10\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\34:\5\27""8\11" + "\31""9\13\34:\5\32""8\2\27""8\11\32""8\2\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4" + "\5\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\25""0\10\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10" + "\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\23""3\3\23""3\3\202\320q" + "\202\320q\30""1\1\24""4\5\24""4\5\0\0""7e\17""7e\17""7e\17""5d\26""5" + "d\26""7e\17""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""3" + "[\16""0_\21""0_\21""0_\21/^\20/^\20/^\20""0Y\24-\\\16-\\\16""2Z\15""0" + "Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15.W\23.W\23.W\23-V\22-V" + "\22-V\22-V\22*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T\16" + "*T\16-V\22-V\22.W\23.W\23.W\23""0Y\24""0Y\24""2Z\15\202\320q\202\320" + "q2Z\15""0Y\24-\\\16\0\0\30>\10\30>\10\30>\10\27=\7\27=\7\27=\7\31""9" + "\13\34:\5\34:\5\34:\5\31""9\13\31""9\13\31""9\13\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25" + "5\6\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3\23""3\3\30""1\1\23""3\3" + "\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\24.\5\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\23""3\3\23""3" + "\3\23""3\3\202\320q\202\320q\24""4\5\25""5\6\25""5\6\0\0""7e\17""5d\26" + "7e\17""7e\17""5d\26""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23" + "2a\23""0_\21""3[\16""0_\21""0_\21/^\20/^\20/^\20""3[\16""3[\16-\\\16" + "2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23" + ".W\23-V\22-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T\16""0R" + "\16*T\16-V\22-V\22-V\22""2Z\15.W\23""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15" + "\202\320q\202\320q-\\\16-\\\16/^\20\0\0\30>\10\30>\10\27=\7\27=\7\27" + "=\7\27""8\11\34:\5\34:\5\31""9\13\32""8\2\32""8\2\31""9\13\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25" + "5\6\25""5\6\24""4\5\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3" + "\23""3\3\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\226\240\217\226\240\217\226\240\217#>\27\25/\7\226\240\217" + "\226\240\217\226\240\217\226\240\217\226\240\217\226\240\217\227\241" + "\220\227\241\220\227\241\220\227\241\220\227\241\220\230\242\221\225" + "\245\214\230\242\221\23""3\3\30""1\1\23""3\3\202\320q\202\320q\25""5" + "\6\27""7\10\27""7\10\0\0""5d\26""5d\26""7e\17""5d\26""5d\26""3b\24""3" + "b\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""3[\16/" + "^\20/^\20""3[\16/^\20-\\\16""3[\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "2Z\15""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22*T\16*T\16*T" + "\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16\376\377\374\376\377" + "\374\376\377\374Po7*T\16\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\3740Y\24""0Y\24" + "2Z\15\202\320q\202\320q-\\\16/^\20/^\20\0\0\30>\10\27=\7\27=\7\27=\7" + "\27=\7\27""8\11\34:\5\34:\5\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5" + "\6\25""5\6\24""4\5\24""4\5\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\30" + "1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25/" + "\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5" + "\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\376\377\374\376\377\374\376\377\3744H\"\25/\7\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\23""3\3\24""4\5\24""4\5\202\320q\202\320q\27" + "7\10\27""7\10\25""5\6\0\0""5d\26""5d\26""5d\26""5d\26""3b\24""3b\24""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16""0_\21/^\20""3" + "[\16/^\20""3[\16-\\\16-\\\16""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22-V\22*T\16*T\16*T\16" + "0R\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16\376\377\374\376\377" + "\374\376\377\374Fj,*T\16\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\3742Z\15""0Y\24" + "-\\\16\202\320q\202\320q3[\16""3[\16""0_\21\0\0\27=\7\27=\7\27=\7\27" + "=\7\34:\5\31""9\13\34:\5\31""9\13\32""8\2\31""9\13\31""9\13\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5" + "\6\25""5\6\24""4\5\24""4\5\30""1\1\27""1\12\23""3\3\23""3\3\27""1\12" + "\23""3\3\27""1\12\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5" + "\24.\5\24.\5\25/\7\25/\7\376\377\374\376\377\374\376\377\3744H\"\25/" + "\7\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\24""4\5\25""5\6\25""5\6\202\320q\202" + "\320q\27""7\10\27""7\10\27""7\10\0\0""7e\17""5d\26""5d\26""3b\24""3b" + "\24""3b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21/^\20/^\20" + "0Y\24/^\20""3[\16/^\20""0Y\24-\\\16""2Z\15""2Z\15""0Y\24""0Y\24""2Z\15" + "0Y\24""0Y\24""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22-V\22*T\16""0R\16*T" + "\16*T\16""0R\16*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16""0R\16-V\22-V\22-V\22.W\23.W\23.W\23""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15-\\\16-\\\16\202\320q\202\320" + "q3[\16""0_\21""0_\21\0\0\27=\7\27=\7\27=\7\27""8\11\34:\5\27""8\11\31" + "9\13\32""8\2\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\23""3" + "\3\27""1\12\23""3\3\23""3\3\30""1\1\27""1\12\23""3\3\25""0\10\30""1\1" + "\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24" + ".\5\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\30""1\1\30" + "1\1\25""0\10\30""1\1\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\24""4" + "\5\24""4\5\24""4\5\25""5\6\27""7\10\202\320q\202\320q\27""7\10\27""7" + "\10\27""7\10\0\0""5d\26""5d\26""7e\17""3b\24""3b\24""3b\24""2a\23""2" + "a\23""2a\23""0_\21""0_\21""3[\16/^\20/^\20""3[\16/^\20/^\20""3[\16-\\" + "\16-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24.W\23.W\23.W\23-V\22-V\22-V\22-V\22*T\16*T\16*T\16""0R\16*T\16*T" + "\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16-V\22" + "-V\22-V\22.W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0" + "Y\24""0Y\24""2Z\15""3[\16/^\20/^\20\202\320q\202\320q3[\16""3[\16""0" + "_\21\0\0\27=\7\27=\7\34:\5\34:\5\34:\5\31""9\13\32""8\2\32""8\2\32""8" + "\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\25""5\6\25""5\6\24""4\5\24""4\5\23""3\3\27""1\12\23""3\3\23""3\3" + "\23""3\3\27""1\12\23""3\3\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\24.\5\24.\5\24.\5\24.\5\24.\5\24.\5\24" + ".\5\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\30""1\1\23""3\3" + "\30""1\1\23""3\3\27""1\12\23""3\3\23""3\3\24""4\5\25""5\6\25""5\6\27" + "7\10\27""7\10\27""7\10\202\320q\202\320q\27""7\10\27""7\10\32""8\2\0" + "\0""7e\17""5d\26""3b\24""3b\24""3b\24""2a\23""2a\23""2a\23""2a\23""0" + "_\21""3[\16""0_\21/^\20""3[\16""3[\16""3[\16/^\20-\\\16""0Y\24""2Z\15" + "2Z\15""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15.W\23.W\23.W\23" + "-V\22-V\22-V\22-V\22*T\16""0R\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T" + "\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16""0" + "R\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16""0R\16-V\22-V\22-V\22\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374/^\20/^\20/^\20\202\320q\202\320q0_\21""2a\23" + "2a\23\0\0\27=\7\34:\5\27""8\11\34:\5\34:\5\32""8\2\31""9\13\32""8\2\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25" + "5\6\25""5\6\24""4\5\24""4\5\23""3\3\30""1\1\23""3\3\30""1\1\23""3\3\23" + "3\3\27""1\12\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\30""1\1\25""0" + "\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25" + "0\10\25""0\10\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\27""7\10\27""7\10\27""7" + "\10\202\320q\202\320q\27""7\10\31""9\13\32""8\2\0\0""5d\26""3b\24""3" + "b\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21""3[\16/" + "^\20/^\20""3[\16/^\20-\\\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15" + "0Y\24""2Z\15""0Y\24""0Y\24.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22""0" + "R\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16""0R\16*T\16*T\16*T\16""0R\16" + "*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16" + "*T\16""0R\16-V\22-V\22-V\22-V\22.W\23\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "3[\16/^\20""0_\21\202\320q\202\320q2a\23""2a\23""3b\24\0\0\27=\7\34:" + "\5\27""8\11\34:\5\31""9\13\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6" + "\24""4\5\24""4\5\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\27""1" + "\12\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\25""0\10\30""1" + "\1\30""1\1\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\27""7\10\27""7\10\27""7\10\202" + "\320q\202\320q\32""8\2\32""8\2\31""9\13\0\0""3b\24""3b\24""3b\24""2a" + "\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21""0_\21/^\20""3[\16/^\20" + "/^\20-\\\16""3[\16""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""2Z\15""2" + "Z\15""0Y\24.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22*T\16*T\16*T\16*T" + "\16*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T" + "\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16-V\22-V\22" + "-V\22-V\22.W\23.W\23.W\23\240\264\224\240\264\224\240\264\224\240\264" + "\224\240\264\224\240\264\224\240\264\224\247\273\233\313\326\304\373" + "\375\372\376\377\374\376\377\374\263\303\251\242\266\226/^\20""0_\21" + "0_\21\202\320q\202\320q2a\23""3b\24""3b\24\0\0\34:\5\34:\5\31""9\13\32" + "8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\24""4\5\23""3" + "\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\25""0\10\30""1\1\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\23""3" + "\3\30""1\1\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\24""4\5\24""4\5:U" + ",\341\344\340\376\377\374\327\336\323&\77\23\27""7\10\27""7\10\27""7" + "\10\202\320q\202\320q\31""9\13\34:\5\34:\5\0\0""3b\24""3b\24""2a\23""2" + "a\23""2a\23""2a\23""0_\21""0_\21""0_\21""0_\21""3[\16/^\20/^\20/^\20" + "-\\\16""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24" + "2Z\15""0Y\24.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22*T\16*T\16*T\16*" + "T\16*T\16""0R\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16" + "*T\16*T\16""0R\16*T\16*T\16*T\16*T\16""0R\16*T\16-V\22-V\22-V\22-V\22" + ".W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24" + "0Y\24""2Z\15-\\\16-\\\16m\217[\376\377\374\376\377\374\236\257\2123[" + "\16""0_\21""2a\23\202\320q\202\320q3b\24""3b\24""7e\17\0\0\34:\5\34:" + "\5\31""9\13\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\24""4" + "\5\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\30""1\1\30" + "1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1" + "\1\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\24""4\5\24" + "4\5\25""5\6\25""5\6\27""7\10:U,\376\377\374\376\377\374\324\332\317\27" + "7\10\27""7\10\32""8\2\202\320q\202\320q\34:\5\31""9\13\27=\7\0\0""3b" + "\24""3b\24""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16""0_\21/^\20""3[" + "\16/^\20/^\20""3[\16-\\\16""0Y\24""2Z\15""2Z\15""0Y\24""2Z\15""2Z\15" + "0Y\24""2Z\15""0Y\24.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22" + "*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16" + "0R\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16-V\22-V\22-V\22-" + "V\22-V\22.W\23.W\23.W\23""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2" + "Z\15""2Z\15""2Z\15""3[\16-\\\16/^\20""3[\16\222\253\204\376\377\374\376" + "\377\374\366\370\3640_\21""2a\23""2a\23\202\320q\202\320q3b\24""5d\26" + "5d\26\0\0\34:\5\31""9\13\32""8\2\31""9\13\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5" + "\6\24""4\5\24""4\5\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\30" + "1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10" + "\30""1\1\30""1\1\30""1\1\30""1\1\23""3\3\27""1\12\230\242\221\230\242" + "\221\225\245\214\230\242\221\230\242\221\230\242\221\225\245\214\230" + "\242\221\243\256\234\310\317\304\376\377\374\376\377\374\376\377\374" + "\367\371\366\31""9\13\32""8\2\31""9\13\202\320q\202\320q\27""8\11\27" + "=\7\27=\7\0\0""3b\24""2a\23""2a\23""2a\23""0_\21""3[\16""0_\21""0_\21" + "3[\16""3[\16/^\20/^\20""3[\16-\\\16-\\\16""0Y\24""2Z\15""2Z\15""0Y\24" + "2Z\15""0Y\24""2Z\15""0Y\24""2Z\15.W\23.W\23.W\23.W\23-V\22-V\22-V\22" + "-V\22-V\22*T\16*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16-V\22-V\22-V" + "\22-V\22-V\22.W\23.W\23.W\23.W\23""2Z\15""0Y\24""0Y\24""0Y\24\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\336\344\3312a\23""2a\23""3b\24\202\320q\202\320q5d\26""5" + "d\26""7e\17\0\0\32""8\2\31""9\13\32""8\2\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6\24""4" + "\5\24""4\5\27""1\12\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\23" + "3\3\30""1\1\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0" + "\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1" + "\1\25""0\10\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\207\226~\32""8\2\31""9\13\34:\5\202\320q\202\320q\27=\7\30>\10\30" + ">\10\0\0""2a\23""2a\23""2a\23""0_\21""0_\21""3[\16""0_\21/^\20""3[\16" + "/^\20/^\20-\\\16""3[\16-\\\16""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y" + "\24""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22" + "-V\22*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16-V\22-V\22-V\22-V\22.W" + "\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\311\324\3025d\26""2a\23""3b\24""3b\24\202\320q\202\320q5d\26""7e\17" + "7e\17\0\0\27""8\11\32""8\2\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6\24""4\5\24""4" + "\5\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\30" + "1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\30""1\1\23""3" + "\3\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\373\375\372\355\357\353\302\311\276q\204f\35;\6\32""8\2" + "\27""8\11\34:\5\31""9\13\202\320q\202\320q\30>\10\30>\10\32\77\12\0\0" + "2a\23""2a\23""0_\21""0_\21""3[\16""0_\21""3[\16/^\20""3[\16/^\20-\\\16" + "3[\16-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0" + "Y\24""0Y\24.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22*T\16""0" + "R\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16" + "*T\16*T\16*T\16*T\16-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""3[\16" + "-\\\16/^\20""3[\16/^\20""3[\16/^\20""0_\21""0_\21""0_\21""2a\23""2a\23" + "3b\24""3b\24""5d\26\202\320q\202\320q7e\17""5d\26""9g\21\0\0\31""9\13" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\23""3\3\27""1\12\30""1\1" + "\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\25""0\10\25""0\10\30""1\1\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\23""3\3\23""3\3\30""1" + "\1\23""3\3\23""3\3\30""1\1\23""3\3\24""4\5\24""4\5\25""5\6\25""5\6\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31" + "9\13\32""8\2\31""9\13\34:\5\34:\5\27=\7\202\320q\202\320q\30>\10\32\77" + "\12\32\77\12\0\0""2a\23""0_\21""0_\21""0_\21""0_\21/^\20/^\20/^\20""3" + "[\16-\\\16-\\\16-\\\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y" + "\24""2Z\15""0Y\24""2Z\15.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22" + "-V\22*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16" + "*T\16*T\16""0R\16*T\16""0R\16-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23" + ".W\23.W\23""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2" + "Z\15""0Y\24-\\\16-\\\16/^\20/^\20""3[\16""3[\16""3[\16""0_\21""0_\21" + "0_\21""2a\23""2a\23""3b\24""3b\24""3b\24""7e\17\202\320q\202\320q7e\17" + "9g\21""9g\21\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6\24""4\5\23""3\3\23" + "3\3\23""3\3\23""3\3\27""1\12\30""1\1\23""3\3\23""3\3\25""0\10\30""1\1" + "\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\30""1\1\27""1\12" + "\23""3\3\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\24""4\5\24""4\5\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\32""8\2\31""9\13\34:\5\27""8\11\34:\5\27=\7\27=\7\202\320" + "q\202\320q\32\77\12\32\77\12\32\77\12\0\0""0_\21""0_\21""3[\16""0_\21" + "/^\20/^\20""3[\16/^\20""0Y\24-\\\16-\\\16""0Y\24""2Z\15""0Y\24""2Z\15" + "0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23.W\23.W\23-V\22" + "-V\22-V\22-V\22-V\22*T\16*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16""0R\16*T\16*T\16-V\22-V\22-V\22-V\22-V\22-V\22-V" + "\22.W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""2Z\15""0Y\24""2Z\15""3[\16/^\20""3[\16/^\20""3[\16""4c\25\221\252" + "\202\336\344\331\371\373\370\361\363\360\316\327\277p\217V3b\24""3b\24" + "3b\24""5d\26""7e\17\202\320q\202\320q9g\21""5k\24""4j\23\0\0\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5" + "\6\25""5\6\24""4\5\24""4\5\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3" + "\23""3\3\27""1\12\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10\30""1\1\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25/\7\25/\7\25/\7\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1" + "\1\30""1\1\30""1\1\25""0\10\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3" + "\27""1\12\23""3\3\30""1\1\33;\15\216\235\205\331\343\336\371\373\370" + "\356\360\355\252\265\2434H\"\31""9\13\270\306\271\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374|\217p\34:\5\27=" + "\7\27=\7\30>\10\202\320q\202\320q\32\77\12\32\77\12\36B\5\0\0""0_\21" + "3[\16""0_\21""3[\16/^\20""3[\16/^\20-\\\16""3[\16""3[\16""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24.W\23.W\23.W\23" + ".W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22""0R\16*T\16*T\16*T\16*T\16*" + "T\16*T\16*T\16*T\16*T\16""0R\16*T\16""0R\16*T\16-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""2Z\15" + "0Y\24""0Y\24""0Y\24""3[\16\305\320\276\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\341\347\334\221\252\202\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\371\373\370Nw15d\26""7e\17""7e\17\202\320q\202\320q4j\23""9g\21""4j" + "\23\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10" + "\25""5\6\25""5\6\25""5\6\24""4\5\23""3\3\30""1\1\23""3\3\27""1\12\23" + "3\3\27""1\12\23""3\3\23""3\3\27""1\12\30""1\1\25""0\10\30""1\1\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7" + "\25/\7\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10" + "\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\27""1\12\23""3\3\23""3\3\27" + "1\12\23""3\3\23""3\3\23""3\3\24""4\5]pS\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\373\375\372\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\212\240\206\27=\7\27=\7\30>\10\202\320q\202" + "\320q\32\77\12\32\77\12\32\77\12\0\0""3[\16/^\20/^\20""3[\16/^\20""3" + "[\16-\\\16-\\\16""0Y\24""2Z\15""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22*T\16*T\16*T\16*T\16*T\16*T\16""0R\16*T\16*T\16*" + "T\16-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""2Z\15\263\303" + "\251\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\311\321\271" + "\247\273\233\321\334\312\376\377\374\376\377\374\376\377\374\316\331" + "\3077e\17""7e\17""7e\17\202\320q\202\320q5k\24""9g\21""5k\24\0\0\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6\25""5" + "\6\24""4\5\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3" + "\27""1\12\27""1\12\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25/\7" + "\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\30" + "1\1\25""0\10\30""1\1\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12" + "\23""3\3\23""3\3\24""4\5\24""4\5\341\344\340\376\377\374\376\377\374" + "\371\373\370\252\265\243\252\265\243\370\372\367\376\377\374\376\377" + "\374\376\377\374\216\235\205\31""9\13\32""8\2\31""9\13\252\265\243\376" + "\377\374\376\377\374\352\354\351\30>\10\30>\10\30>\10\202\320q\202\320" + "q\36B\5\32\77\12\36B\5\0\0""0_\21""3[\16/^\20""3[\16""3[\16-\\\16""3" + "[\16""3[\16""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22*T\16""0R\16*T\16*T\16*T\16*T\16*T\16*T\16-V\22-V\22-" + "V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23""2Z\15""0Y\24" + "2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15\361\363" + "\360\376\377\374\376\377\374\213\241u3[\16/^\20\203\240s\376\377\374" + "\376\377\374\376\377\374Jt.2a\23""2a\23""3b\24b\207G\376\377\374\376" + "\377\374\371\373\3707e\17""5d\26""7f\30\202\320q\202\320q5k\24""9g\21" + "5k\24\0\0\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\25""5\6\25""5" + "\6\24""4\5\24""4\5\24""4\5\27""1\12\23""3\3\23""3\3\23""3\3\30""1\1\23" + "3\3\27""1\12\23""3\3\25""0\10\25""0\10\30""1\1\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25/\7\25/\7\25/\7\25/\7\25/\7\25/\7\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25" + "0\10\30""1\1\25""0\10\23""3\3\30""1\1\23""3\3\30""1\1\23""3\3\30""1\1" + "\23""3\3\23""3\3\23""3\3\24""4\5\24""4\5\25""5\6\373\375\372\376\377" + "\374\376\377\374:U,\27""7\10\27""7\10:U,\376\377\374\376\377\374\376" + "\377\374\35;\6\31""9\13\34:\5\34:\5""8S*\376\377\374\376\377\374\376" + "\377\374\30>\10\30>\10\32\77\12\202\320q\202\320q\32\77\12\32\77\12\36" + "B\5\0\0/^\20/^\20/^\20""3[\16-\\\16""0Y\24-\\\16""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23.W\23" + ".W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22""0R\16*T\16*" + "T\16*T\16*T\16-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23" + ".W\23.W\23.W\23.W\23""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24" + "2Z\15""0Y\24""2Z\15""0Y\24-\\\16\376\377\374\376\377\374\376\377\374" + "Mq23[\16""0_\21Jt.\376\377\374\376\377\374\376\377\3742a\23""2a\23""3" + "b\24""3b\24Nw1\376\377\374\376\377\374\376\377\3747e\17""7f\30""9g\21" + "\202\320q\202\320q5k\24""9g\21""5k\24\0\0\27""7\10\27""7\10\27""7\10" + "\27""7\10\25""5\6\25""5\6\24""4\5\24""4\5\30""1\1\27""1\12\23""3\3\27" + "1\12\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\30""1\1\25""0\10\25""0" + "\10\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\30""1\1\25""0\10\25""0\10\30""1\1\30""1\1\23""3" + "\3\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3\24" + "4\5\25""5\6\25""5\6\25""5\6\376\377\374\376\377\374\376\377\3744O'\27" + "7\10\27""7\10""5P(\376\377\374\376\377\374\376\377\374\32""8\2\34:\5" + "\34:\5\34:\5""5U%\376\377\374\376\377\374\376\377\374\30>\10\32\77\12" + "\32\77\12\202\320q\202\320q\36B\5\32\77\12\36B\5\0\0""3[\16/^\20/^\20" + "0Y\24-\\\16-\\\16""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23""2Z\15""0Y\24" + "2Z\15""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""3[\16-\\\16""3" + "[\16\376\377\374\376\377\374\376\377\374\261\276\237\242\266\226\242" + "\266\226\261\276\237\376\377\374\376\377\374\376\377\374\244\270\230" + "\247\271\223\244\270\230\247\271\223\255\302\241\376\377\374\376\377" + "\374\376\377\3745d\26""7f\30""5k\24\202\320q\202\320q4j\23""4j\23""5" + "k\24\0\0\27""7\10\27""7\10\25""5\6\25""5\6\25""5\6\24""4\5\24""4\5\23" + "3\3\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12" + "\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\30" + "1\1\25""0\10\30""1\1\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3" + "\23""3\3\23""3\3\23""3\3\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\32\77\12\32\77\12\32\77\12\202\320q\202\320q\36B\5\32\77\12" + "\36B\5\0\0""0Y\24/^\20""3[\16-\\\16""3[\16""2Z\15""2Z\15""2Z\15""2Z\15" + "0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23.W\23.W\23." + "W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + ".W\23""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15" + "2Z\15""0Y\24-\\\16""3[\16-\\\16/^\20\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\3747f\30""5k\24""9g\21\202" + "\320q\202\320q5k\24""4j\23""9g\21\0\0\27""7\10\25""5\6\25""5\6\25""5" + "\6\24""4\5\24""4\5\30""1\1\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\30" + "1\1\23""3\3\27""1\12\23""3\3\30""1\1\25""0\10\25""0\10\30""1\1\30""1" + "\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30" + "1\1\25""0\10\30""1\1\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3" + "\23""3\3\23""3\3\23""3\3\30""1\1\24""4\5\24""4\5\24""4\5\25""5\6\25""5" + "\6\27""7\10\27""7\10\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\32\77\12\36B\5\32\77\12\202\320q\202" + "\320q\36B\5\32\77\12\32\77\12\0\0-\\\16-\\\16""3[\16""2Z\15""0Y\24""2" + "Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24." + "W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23" + ".W\23.W\23.W\23.W\23.W\23""2Z\15""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2" + "Z\15""0Y\24""2Z\15""2Z\15""2Z\15""0Y\24-\\\16""3[\16/^\20""3[\16\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\3747f\30""4j\23""9g\21\202\320q\202\320q9g\21""9g\21""9g\21\0\0" + "\25""5\6\25""5\6\24""4\5\24""4\5\24""4\5\27""1\12\23""3\3\27""1\12\30" + "1\1\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\25""0\10\30""1\1\25""0\10" + "\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\23""3\3" + "\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\24""4\5\24" + "4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\32""8\2\31""9\13\34:" + "\5\34:\5\27""8\11\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\32\77\12\202\320q\202\320q\32\77\12\32\77\12\32\77\12\0\0-\\\16" + "2Z\15""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24.W\23.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-" + "V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22.W\23""2Z\15.W\23.W\23.W\23""2Z\15""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15-\\\16""0Y\24-\\\16""3" + "[\16/^\20/^\20""3[\16/^\20""3[\16""0_\21""3[\16""0_\21""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""7e\17""5d\26" + "9g\21""4j\23""5k\24""9g\21\202\320q\202\320q4j\23""9g\21""5k\24\0\0\25" + "5\6\24""4\5\24""4\5\24""4\5\23""3\3\23""3\3\27""1\12\30""1\1\23""3\3" + "\23""3\3\27""1\12\23""3\3\23""3\3\25""0\10\30""1\1\30""1\1\30""1\1\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30" + "1\1\30""1\1\30""1\1\30""1\1\30""1\1\30""1\1\23""3\3\23""3\3\23""3\3\27" + "1\12\30""1\1\23""3\3\23""3\3\27""1\12\24""4\5\24""4\5\25""5\6\25""5\6" + "\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\31""9\13\31""9\13\32""8\2\27""8\11\34:\5\31""9" + "\13\27=\7\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5" + "\32\77\12\202\320q\202\320q\32\77\12\32\77\12\36B\5\0\0-\\\16""0Y\24" + "2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24" + "2Z\15.W\23""2Z\15.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-" + "V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + ".W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0" + "Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24-\\\16""3[\16/^\20""3[" + "\16/^\20""3[\16""3[\16""0_\21""3[\16""0_\21""0_\21""2a\23""2a\23""2a" + "\23""2a\23""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""7e\17""7e\17""7" + "f\30""9g\21""9g\21""5k\24""9g\21\202\320q\202\320q4j\23""9g\21""5k\24" + "\0\0\25""5\6\24""4\5\24""4\5\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3" + "\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\25""0\10\30""1\1\30""1\1\25" + "0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\25" + "0\10\25""0\10\30""1\1\25""0\10\25""0\10\23""3\3\30""1\1\23""3\3\23""3" + "\3\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\27""8\11q\204f\304\313\300\356\360\355" + "\373\375\372\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\32\77\12\32\77\12\36B\5\202" + "\320q\202\320q\36B\5\32\77\12\32\77\12\0\0""0Y\24""2Z\15""0Y\24""0Y\24" + "0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15.W\23.W\23.W\23" + ".W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23" + ".W\23""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24" + "0Y\24""2Z\15""2Z\15""3[\16-\\\16/^\20""3[\16/^\20""0Y\24""3[\16""0_\21" + "3[\16""0_\21""0_\21""2a\23""5d\26\311\321\271\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\3749g\21""5k\24""4j" + "\23\202\320q\202\320q4j\23""9g\21""4j\23\0\0\24""4\5\27""1\12\23""3\3" + "\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\23""3\3\30" + "1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\27""1" + "\12\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3" + "\27""1\12\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\210" + "\227\177\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\32\77\12\32\77\12\36B\5\202\320q\202\320" + "q\32\77\12\32\77\12\36B\5\0\0""2Z\15""0Y\24""2Z\15""2Z\15""0Y\24""0Y" + "\24""0Y\24""2Z\15""0Y\24""0Y\24.W\23.W\23.W\23.W\23.W\23.W\23.W\23-V" + "\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0" + "Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""3" + "[\16-\\\16-\\\16/^\20/^\20/^\20/^\20""3[\16""0_\21""3[\16""0_\21""3[" + "\16""2a\23""2a\23\336\344\331\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\3744j\23""9g\21""4j\23\202" + "\320q\202\320q9g\21""4j\23""4j\23\0\0\23""3\3\30""1\1\23""3\3\23""3\3" + "\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\25""0\10\30""1\1\25" + "0\10\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30" + "1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\27""1\12\23""3\3\30""1" + "\1\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\24""4\5" + "\24""4\5\24""4\5\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\367\371" + "\366\376\377\374\376\377\374\376\377\374\306\315\302\236\261\235\236" + "\261\235\230\247\216\231\250\217\231\250\217\231\250\217\231\250\217" + "\232\251\220\231\250\217\32\77\12\32\77\12\32\77\12\202\320q\202\320" + "q\32\77\12\32\77\12\32\77\12\0\0""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24.W\23.W\23""2Z\15.W\23.W\23.W\23-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""2Z\15""0Y" + "\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2" + "Z\15""0Y\24-\\\16/^\20""3[\16/^\20/^\20/^\20""3[\16""0_\21""0_\21""0" + "_\21""0_\21""2a\23""2a\23\366\370\364\376\377\374\376\377\374\222\253" + "\2045d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""7f\30""4j\23""9" + "g\21""5k\24""9g\21""4j\23\202\320q\202\320q9g\21""4j\23""9g\21\0\0\27" + "1\12\23""3\3\30""1\1\23""3\3\23""3\3\27""1\12\27""1\12\23""3\3\23""3" + "\3\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\30""1\1\25""0\10\25""0\10\30""1\1\30""1\1\30""1\1\25""0" + "\10\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\27""1\12\27""1\12\23""3" + "\3\30""1\1\30""1\1\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32" + "8\2\32""8\2\31""9\13\321\327\314\376\377\374\376\377\374\10\30>\10\32\77\12\32\77\12\32\77\12\36B\5\32\77" + "\12\32\77\12\32\77\12\202\320q\202\320q\32\77\12\32\77\12\32\77\12\0" + "\0""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y" + "\24""0Y\24""2Z\15""0Y\24-\\\16-\\\16""0Y\24/^\20""3[\16/^\20""3[\16/" + "^\20""0_\21""3[\16""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23\227\260" + "\210\376\377\374\376\377\374r\224`5d\26""5d\26""5d\26""5d\26""7e\17""5" + "d\26""9g\21""9g\21""4j\23""4j\23""9g\21""5k\24""9g\21\202\320q\202\320" + "q5k\24""9g\21""5k\24\0\0\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\27" + "1\12\23""3\3\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\25""0" + "\10\30""1\1\25""0\10\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3\23""3\3" + "\27""1\12\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25" + "5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\32""8\2\32""8\2\31""9\13\31""9\13\"B\24\327\336\323\376" + "\377\374\345\347\344@[2\27=\7\27=\7\30>\10\30>\10\32\77\12\32\77\12\32" + "\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\202\320q\202\320" + "q\32\77\12\36B\5\32\77\12\0\0""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y" + "\24""0Y\24.W\23.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + ".W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24-\\\16/^" + "\20""3[\16/^\20/^\20""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23" + "2a\23""2a\23""3b\24\244\270\230\266\304\244\376\377\374\376\377\374\373" + "\375\372\316\331\307\254\300\237\244\270\230\242\273\223\247\271\223" + "\247\271\223\243\274\224\247\271\223\243\274\2244j\23""9g\21""9g\21\202" + "\320q\202\320q9g\21""4j\23""4j\23\0\0\23""3\3\30""1\1\27""1\12\23""3" + "\3\23""3\3\27""1\12\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\30""1\1" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\30""1\1\30""1" + "\1\30""1\1\30""1\1\27""1\12\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3" + "\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\24""4\5\24""4\5\24""4\5\25" + "5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\34:\5\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\36B\5\32\77\12\32\77\12\202\320q\202\320q\32" + "\77\12\32\77\12\36B\5\0\0""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24." + "W\23.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23" + ".W\23.W\23.W\23""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z" + "\15""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""3[\16/^\20/^\20" + "/^\20""3[\16/^\20""0_\21""3[\16""0_\21""0_\21""3[\16""2a\23""2a\23""2" + "a\23""2a\23""3b\24\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\3744j\23""5k\24""9g\21\202" + "\320q\202\320q5k\24""9g\21""4j\23\0\0\27""1\12\23""3\3\30""1\1\23""3" + "\3\27""1\12\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10" + "\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1" + "\1\30""1\1\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3" + "\23""3\3\30""1\1\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5" + "\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\31""9\13\34:\5\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\32\77\12\36B\5\32\77\12\202\320q\202\320q\32" + "\77\12\32\77\12\32\77\12\0\0""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z" + "\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""3[\16-\\\16/^\20/^\20""3[\16" + "/^\20/^\20""3[\16""0_\21""0_\21""3[\16""0_\21""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\3744j\23""5k\24""9g\21\202" + "\320q\202\320q4j\23""9g\21""5k\24\0\0\23""3\3\23""3\3\23""3\3\27""1\12" + "\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\25""0" + "\10\23""3\3\23""3\3\30""1\1\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\27" + "1\12\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\31""9\13\32""8\2\32""8\2\34:\5\34:\5\31""9\13\34:\5\27=" + "\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\202\320q\202\320" + "q\36B\5\32\77\12\32\77\12\0\0""0Y\24""2Z\15""0Y\24.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24" + "2Z\15""2Z\15""0Y\24""0Y\24""3[\16-\\\16/^\20/^\20/^\20""3[\16/^\20/^" + "\20""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""3b\24""3" + "b\24""3b\24""3b\24""7e\17""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21""9" + "g\21""4j\23""9g\21""9g\21""5k\24""5k\24""9g\21""4j\23""9g\21\202\320" + "q\202\320q4j\23""5k\24""4j\23\0\0\23""3\3\30""1\1\30""1\1\25""0\10\30" + "1\1\25""0\10\30""1\1\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25" + "0\10\30""1\1\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\23""3\3\27""1\12" + "\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\30""1\1\27""1\12\23""3\3\23" + "3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31""9" + "\13\32""8\2\32""8\2\31""9\13\31""9\13\34:\5\34:\5\27""8\11\27=\7\27=" + "\7\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\32\77\12\36B\5\32\77\12\36B\5\32\77\12\202\320q\202\320q\32\77\12" + "\32\77\12\36B\5\0\0""2Z\15""0Y\24.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + ".W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24" + "0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15" + "2Z\15""0Y\24-\\\16""0Y\24/^\20/^\20""3[\16/^\20""3[\16/^\20/^\20""0_" + "\21""0_\21""0_\21""3[\16""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3" + "b\24""5d\26""5d\26""7e\17""5d\26W\201:\210\245w\231\262\213\247\271\223" + "Cr$5k\24""4j\23""4j\23""9g\21""5k\24""5k\24""4j\23""4j\23\202\320q\202" + "\320q9g\21""4j\23""5k\24\0\0\23""3\3\23""3\3\30""1\1\25""0\10\30""1\1" + "\30""1\1\30""1\1\25""0\10\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25" + "0\10\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\27""1\12\23""3\3\23""3" + "\3\30""1\1\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\30""1\1\24""4\5\24" + "4\5\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\31" + "9\13\32""8\2\31""9\13\34:\5\27""8\11\34:\5\34:\5\27=\7\27=\7C^5\313\321" + "\306\376\377\374\376\377\374\376\377\374\376\377\3747W(r\212e\376\377" + "\374\376\377\374\341\347\334\33A\14\32\77\12\36B\5\32\77\12\202\320q" + "\202\320q\32\77\12\32\77\12\36B\5\0\0""0Y\24.W\23.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23""2" + "Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24-\\\16""3[\16-\\\16""3[\16/^\20""3[\16/^\20""3[\16" + "/^\20""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""3b\24" + "3b\24""3b\24""3b\24""3b\24""5d\26c\210H\366\370\364\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374Nw1Cr$\364\367\363\376\377\374" + "\376\377\374h\214L4j\23""5k\24""9g\21\202\320q\202\320q9g\21""4j\23""9" + "g\21\0\0\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25" + "0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1" + "\1\25""0\10\23""3\3\23""3\3\27""1\12\30""1\1\27""1\12\23""3\3\23""3\3" + "\23""3\3\23""3\3\27""1\12\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25" + "5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\32""8\2\27""8\11\34" + ":\5\27""8\11\34:\5\34:\5'E\20\350\352\347\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\3747W(\32\77\12\262\275\253" + "\376\377\374\376\377\374\217\245\213\36B\5\32\77\12\32\77\12\202\320" + "q\202\320q\32\77\12\36B\5\32\77\12\0\0.W\23.W\23.W\23.W\23.W\23.W\23" + ".W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""2" + "Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""2" + "Z\15""0Y\24""0Y\24-\\\16-\\\16-\\\16""3[\16/^\20""3[\16/^\20/^\20/^\20" + "0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24" + "3b\24""3b\24""5d\26\221\247{\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374N}/9g\21\210\243p\376\377" + "\374\376\377\374\316\327\2779g\21""4j\23""9g\21\202\320q\202\320q5k\24" + "5k\24""4j\23\0\0\30""1\1\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\30" + "1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\30""1\1\25""0" + "\10\25""0\10\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3\27""1\12\30""1" + "\1\23""3\3\23""3\3\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25" + "5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\32""8\2\32""8\2\34:" + "\5\27""8\11\34:\5\34:\5\27=\7\310\317\304\376\377\374\376\377\374\324" + "\332\3173S$\376\377\374\376\377\374\376\377\3747W(\36B\5Ok@\376\377\374" + "\376\377\374\347\351\346\36B\5\32\77\12\32\77\12\202\320q\202\320q\32" + "\77\12\36B\5\32\77\12\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23""2Z\15.W\23""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15" + "3[\16-\\\16-\\\16""3[\16/^\20""3[\16/^\20/^\20/^\20""0_\21""0_\21""0" + "_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5" + "d\26""5d\26\360\362\357\376\377\374\376\377\374s\222Y7e\17\376\377\374" + "\376\377\374\376\377\374V\17794j\23V\1779\376\377\374\376\377\374\370" + "\372\3675k\24""9g\21""5k\24\202\320q\202\320q9g\21""5k\24""9g\21\0\0" + "\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\25" + "0\10\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\23""3\3\23""3\3\23""3\3" + "\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\24""4" + "\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\31""9\13\32""8\2\32""8\2\31""9\13\34:\5\27""8\11\34:\5\34:\5\27=" + "\7\27=\7\372\374\371\376\377\374\376\377\3749Y)\32\77\12\376\377\374" + "\376\377\374\376\377\3747W(\32\77\12\77_/\376\377\374\376\377\374\371" + "\373\370\32\77\12\32\77\12\36B\5\202\320q\202\320q\32\77\12\32\77\12" + "\32\77\12\0\0.W\23.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15" + "0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""2Z\15""0Y\24-\\\16-\\\16""3" + "[\16/^\20/^\20/^\20""3[\16""3[\16""0_\21""0_\21""0_\21""0_\21""3[\16" + "2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26" + "5d\26\361\363\360\376\377\374\376\377\374d\211I9g\21\376\377\374\376" + "\377\374\376\377\374N}/4j\23|\234b\376\377\374\376\377\374\355\357\353" + "5k\24""9g\21""4j\23\202\320q\202\320q5k\24""9g\21""5k\24\0\0\30""1\1" + "\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1" + "\1\30""1\1\25""0\10\30""1\1\25""0\10\27""1\12\23""3\3\27""1\12\23""3" + "\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\30""1\1\24" + "4\5\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\31" + "9\13\32""8\2\27""8\11\32""8\2\34:\5\31""9\13\27""8\11\34:\5\27=\7\27" + "=\7\27=\7\321\327\314\376\377\374\376\377\374\236\261\235\32\77\12\376" + "\377\374\376\377\374\376\377\3747V\40\40E\20\324\332\317\376\377\374" + "\376\377\374\313\321\306\36B\5\32\77\12\32\77\12\202\320q\202\320q\32" + "\77\12\32\77\12\32\77\12\0\0.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""3[\16" + "0Y\24-\\\16/^\20/^\20""3[\16/^\20""3[\16/^\20""0_\21""0_\21""0_\21""0" + "_\21""2a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7" + "e\17""5d\26""5d\26\240\271\221\376\377\374\376\377\374\376\377\374\261" + "\306\245\376\377\374\376\377\374\376\377\374\240\271\221\341\347\334" + "\376\377\374\376\377\374\376\377\374\233\264\2155k\24""4j\23""9g\21\202" + "\320q\202\320q4j\23""9g\21""4j\23\0\0\30""1\1\30""1\1\30""1\1\25""0\10" + "\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\25" + "0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\25""0" + "\10\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3" + "\27""1\12\23""3\3\23""3\3\27""1\12\24""4\5\24""4\5\24""4\5\25""5\6\25" + "5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\31""9\13\31" + "9\13\34:\5\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7""9Y)\373\375\372\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\372\374\3717V\40\32" + "\77\12\32\77\12\32\77\12\202\320q\202\320q\32\77\12\32\77\12\32\77\12" + "\0\0.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + "0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24" + "0Y\24""2Z\15""2Z\15""0Y\24""3[\16-\\\16-\\\16""3[\16/^\20""0Y\24""3[" + "\16/^\20/^\20""0_\21""0_\21""0_\21""3[\16""0_\21""0_\21""2a\23""2a\23" + "2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""7e\17""5d\26" + "5d\26\231\262\213\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\232\261\2049g\21""9g\21""4j\23""9g\21\202\320q\202\320q5k\24""9g\21" + "9g\21\0\0\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1\1\30""1\1\25""0" + "\10\30""1\1\30""1\1\25""0\10\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3" + "\30""1\1\23""3\3\30""1\1\23""3\3\30""1\1\23""3\3\23""3\3\24""4\5\30""1" + "\1\24""4\5\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8" + "\2\32""8\2\31""9\13\32""8\2\27""8\11\34:\5\27""8\11\34:\5\27=\7\27=\7" + "\27=\7\27=\7\27=\7\30>\10\32\77\12\234\253\222\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\234\253\222\36B\5\32\77\12\32\77\12\36B\5\32\77\12\202\320q\202" + "\320q\36B\5\32\77\12\32\77\12\0\0.W\23.W\23.W\23.W\23-V\22-V\22-V\22" + "-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""2" + "Z\15""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""2Z\15-\\\16""0Y\24-\\" + "\16""3[\16""3[\16/^\20/^\20""3[\16/^\20""0_\21""0_\21""0_\21""0_\21""0" + "_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5" + "d\26""7e\17""5d\26""5d\26""5d\26""5d\26""7e\17""9g\21c\210H\264\310\247" + "\345\354\341\372\374\371\372\374\371\345\354\341\266\304\244`\214J5k" + "\24""4j\23""4j\23""5k\24""9g\21""4j\23\202\320q\202\320q4j\23""5k\24" + "9g\21\0\0\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10" + "\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1" + "\1\30""1\1\25""0\10\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3" + "\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\24""4\5\24""4\5\25" + "5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\32" + "8\2\31""9\13\32""8\2\31""9\13\34:\5\31""9\13\34:\5\27""8\11\27=\7\27" + "=\7\35;\6\27=\7\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12Nj\77" + "\32\77\12\36B\5\32\77\12\202\320q\202\320q\32\77\12\36B\5\32\77\12\0" + "\0.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-V\22-" + "V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23""2Z\15.W\23""0Y\24""0Y\24" + "2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24" + "2Z\15""2Z\15""2Z\15-\\\16""3[\16-\\\16/^\20""3[\16/^\20""3[\16/^\20/" + "^\20/^\20""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26p\217V5d\26""5d\26""7e" + "\17""5d\26""7e\17""9g\21""9g\21""9g\21""5k\24""9g\21""5k\24""9g\21""4" + "j\23""9g\21""4j\23c\210H\363\365\3629g\21""4j\23""4j\23\202\320q\202" + "\320q9g\21""5k\24""9g\21\0\0\30""1\1\25""0\10\30""1\1\25""0\10\25""0" + "\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\25" + "0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\30""1" + "\1\30""1\1\25""0\10\30""1\1\27""1\12\23""3\3\27""1\12\23""3\3\30""1\1" + "\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\23""3\3\30""1\1\24""4\5\24""4" + "\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8" + "\2\31""9\13\31""9\13\32""8\2\31""9\13\27""8\11\34:\5\34:\5\34:\5\27=" + "\7\27=\7\367\371\366QpJ\30>\10\30>\10\30>\10\32\77\12\32\77\12\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12Ef" + "5\360\362\357\376\377\374\32\77\12\32\77\12\36B\5\202\320q\202\320q\32" + "\77\12\32\77\12\32\77\12\0\0.W\23.W\23.W\23""2Z\15-V\22-V\22-V\22-V\22" + "-V\22-V\22-V\22.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + ".W\23""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15" + "0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15-\\\16""3[\16""0Y\24/^\20""3" + "[\16/^\20""0Y\24""3[\16/^\20""0_\21""0_\21""0_\21""0_\21""0_\21""0_\21" + "2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""7e\17" + "5d\26\376\377\374\367\371\366d\211I7e\17""5d\26""7f\30""9g\21""9g\21" + "5k\24""9g\21""5k\24""9g\21""5k\24""9g\21[\205>\363\362\351\376\377\374" + "\376\377\3749g\21""5k\24""4j\23\202\320q\202\320q4j\23""5k\24""4j\23" + "\0\0\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10\25""0\10\25""0" + "\10\25""0\10\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\30""1" + "\1\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1" + "\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3\27""1\12\23""3\3\27" + "1\12\23""3\3\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\32""8\2\34:" + "\5\27""8\11\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\376\377\374\376\377\374" + "\363\365\362Lh=\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12" + "\32\77\12\32\77\12\32\77\12\77_/\355\357\353\376\377\374\376\377\374" + "\376\377\374\32\77\12\36B\5\32\77\12\202\320q\202\320q\36B\5\32\77\12" + "\36B\5\0\0.W\23.W\23.W\23.W\23.W\23-V\22-V\22-V\22-V\22.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""2Z\15""0Y" + "\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2" + "Z\15""2Z\15""0Y\24""3[\16""3[\16-\\\16""3[\16/^\20""3[\16/^\20""3[\16" + "3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23" + "2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26\376\377" + "\374\376\377\374\376\377\374\364\367\363b\207G9g\21""7f\30""5k\24""9" + "g\21""9g\21""4j\23""9g\21V\1779\355\357\353\376\377\374\376\377\374\376" + "\377\374\376\377\3745k\24""4j\23""4j\23\202\320q\202\320q9g\21""5k\24" + "5k\24\0\0\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1" + "\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\25""0\10" + "\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\23""3\3\27""1\12\23""3\3\23" + "3\3\23""3\3\23""3\3\27""1\12\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3" + "\27""1\12\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\31""9\13\32""8\2\31""9\13\34:\5\34:\5" + "\27""8\11\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\363\365\362\376\377\374" + "\376\377\374\376\377\374\360\362\357C^5\32\77\12\32\77\12\32\77\12\32" + "\77\12\36B\5;[+\337\351\344\376\377\374\376\377\374\376\377\374\376\377" + "\374\270\303\261\36B\5\32\77\12\36B\5\202\320q\202\320q\32\77\12\32\77" + "\12\36B\5\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""2Z\15.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23""2Z\15.W\23.W\23.W\23""0Y\24""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24-\\\16""3[\16-\\\16/^\20/^\20""3[\16/^\20/^\20""3" + "[\16/^\20""3[\16""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""2" + "a\23""3b\24""3b\24""3b\24""3b\24""7e\17""5d\26""5d\26""7e\17""7e\17h" + "\214L\370\372\367\376\377\374\376\377\374\376\377\374\360\362\357Y\203" + "<9g\21""4j\23""9g\21T{/\347\356\343\376\377\374\376\377\374\376\377\374" + "\376\377\374\303\323\271@m\30""9g\21""5k\24""4j\23\202\320q\202\320q" + "4j\23""9g\21""4j\23\0\0\25""0\10\30""1\1\25""0\10\30""1\1\30""1\1\25" + "0\10\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\25""0\10\30""1\1\30""1" + "\1\30""1\1\25""0\10\30""1\1\25""0\10\30""1\1\27""1\12\23""3\3\23""3\3" + "\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\23""3\3\27""1\12\23""3\3\23" + "3\3\30""1\1\23""3\3\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\32""8\2\31""9\13\32""8\2\34:\5\34:\5\34" + ":\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10YpL\367\371\366" + "\376\377\374\376\377\374\376\377\374\355\357\353\77_/\32\77\12""7V\40" + "\337\351\344\376\377\374\376\377\374\376\377\374\376\377\374\277\313" + "\270\40E\20\32\77\12\36B\5\32\77\12\32\77\12\202\320q\202\320q\32\77" + "\12\32\77\12\36B\5\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23." + "W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""2Z\15""0" + "Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15-\\\16-\\\16""3[\16/^\20/^\20""3[\16/^\20/^" + "\20/^\20""0_\21""0_\21""0_\21""0_\21""0_\21""3[\16""2a\23""2a\23""2a" + "\23""2a\23""3b\24""3b\24""3b\24""3b\24""7e\17""7e\17""5d\26""7e\17""7" + "e\17""5d\26""7e\17""7e\17s\222Y\371\373\370\376\377\374\376\377\374\376" + "\377\374\352\361\346j\217N\344\353\340\376\377\374\376\377\374\376\377" + "\374\376\377\374\313\326\304@m\30""9g\21""5k\24""9g\21""4j\23""4j\23" + "\202\320q\202\320q4j\23""9g\21""4j\23\0\0\30""1\1\30""1\1\25""0\10\30" + "1\1\30""1\1\25""0\10\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\30""1\1" + "\25""0\10\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\23""3\3\23" + "3\3\23""3\3\23""3\3\30""1\1\30""1\1\23""3\3\30""1\1\23""3\3\23""3\3\23" + "3\3\23""3\3\24""4\5\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\32""8\2\31""9\13\31""9" + "\13\34:\5\31""9\13\34:\5\31""9\13\27=\7\27=\7\27=\7\27=\7\30>\10\30>" + "\10\35;\6\32\77\12\32\77\12d{V\372\374\371\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\304\322\305\"H\22\32\77\12\36B\5\32\77\12\32\77\12\36B\5\32\77\12\202" + "\320q\202\320q\32\77\12\32\77\12\36B\5\0\0.W\23.W\23.W\23.W\23.W\23." + "W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24" + "0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15" + "0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""3[\16-\\\16""3[\16-\\\16""3[\16/^" + "\20/^\20/^\20/^\20""3[\16""0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2" + "a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5" + "d\26""7e\17""7e\17""7e\17""5d\26""7e\17""9g\21""7f\30""4j\23|\234b\373" + "\375\372\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\321\334\312Cr$4j\23""9g\21""4j\23""5k\24""9g\21""4j\23""9" + "g\21\202\320q\202\320q4j\23""4j\23""9g\21\0\0\30""1\1\25""0\10\30""1" + "\1\30""1\1\30""1\1\30""1\1\30""1\1\30""1\1\25""0\10\30""1\1\30""1\1\30" + "1\1\25""0\10\30""1\1\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\23""3" + "\3\23""3\3\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\23""3\3\23""3\3\23" + "3\3\27""1\12\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\31""9\13\32""8\2\32""8\2\32""8\2\34:\5" + "\27""8\11\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30" + ">\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12m\204_\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\321\327\314'E\20\32\77\12" + "\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\202\320" + "q\202\320q\32\77\12\32\77\12\36B\5\0\0.W\23.W\23.W\23.W\23.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23""0Y\24""0Y\24""2Z\15""0" + "Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0" + "Y\24""2Z\15""0Y\24""0Y\24-\\\16-\\\16-\\\16/^\20/^\20""0Y\24/^\20/^\20" + "/^\20/^\20/^\20""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a" + "\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""7e\17""5d\26""5" + "d\26""7e\17""7e\17""5d\26\247\271\223\247\271\223\247\271\223\243\274" + "\224\243\274\224\243\274\224\341\347\334\376\377\374\376\377\374\376" + "\377\374\376\377\374\261\306\245\243\274\224\247\271\223\243\274\224" + "\247\271\223\243\274\224\243\274\2244j\23""9g\21""4j\23\202\320q\202" + "\320q9g\21""4j\23""4j\23\0\0\25""0\10\25""0\10\30""1\1\30""1\1\30""1" + "\1\25""0\10\30""1\1\25""0\10\25""0\10\30""1\1\30""1\1\25""0\10\25""0" + "\10\30""1\1\30""1\1\23""3\3\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12" + "\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\24""4\5\24" + "4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27""7\10\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\32""8\2\32""8\2\31""9\13\32""8\2\27""8\11\34:\5\34:\5\31" + "9\13\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77\12\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\32\77\12\32\77\12\32\77\12\202\320q\202\320q\32\77\12\36B\5" + "\32\77\12\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + ".W\23.W\23""2Z\15""0Y\24""2Z\15""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""2Z\15-\\\16""3" + "[\16-\\\16-\\\16""3[\16/^\20""3[\16/^\20/^\20/^\20/^\20""0_\21""0_\21" + "0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24" + "3b\24""3b\24""5d\26""7e\17""5d\26""7e\17""7e\17""5d\26""5d\26""9g\21" + "7f\30\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\3749g\21""4j\23""9g\21\202\320q\202\320q9g\21""4j\23""9" + "g\21\0\0\25""0\10\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\30""1\1" + "\25""0\10\30""1\1\30""1\1\30""1\1\30""1\1\27""1\12\23""3\3\23""3\3\23" + "3\3\23""3\3\23""3\3\27""1\12\23""3\3\30""1\1\23""3\3\27""1\12\30""1\1" + "\23""3\3\23""3\3\23""3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5" + "\6\25""5\6\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\32""8\2\32""8\2\31""9" + "\13\32""8\2\31""9\13\34:\5\27""8\11\34:\5\27""8\11\27=\7\27=\7\27=\7" + "\30>\10\35;\6\30>\10\30>\10\32\77\12\32\77\12\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\32\77\12\36" + "B\5\32\77\12\202\320q\202\320q\32\77\12\36B\5\32\77\12\0\0.W\23.W\23" + ".W\23.W\23.W\23.W\23.W\23.W\23""2Z\15.W\23""2Z\15""0Y\24""0Y\24""0Y\24" + "2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24" + "2Z\15""0Y\24""0Y\24""2Z\15""0Y\24-\\\16""3[\16-\\\16""3[\16/^\20""3[" + "\16/^\20/^\20/^\20/^\20""3[\16""0_\21""0_\21""0_\21""3[\16""0_\21""2" + "a\23""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24""3b\24""5d\26""5" + "d\26""5d\26""5d\26""7e\17""7e\17""5d\26""9g\21""9g\21""9g\21\376\377" + "\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376" + "\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374" + "\376\377\374\376\377\374\376\377\374\376\377\374\376\377\374\376\377" + "\3749g\21""5k\24""6l\25\202\320q\202\320q5k\24""6l\25""9g\21\0\0\30""1" + "\1\30""1\1\25""0\10\30""1\1\25""0\10\25""0\10\25""0\10\30""1\1\30""1" + "\1\30""1\1\23""3\3\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\27""1\12" + "\23""3\3\23""3\3\30""1\1\23""3\3\27""1\12\23""3\3\27""1\12\23""3\3\23" + "3\3\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10" + "\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7" + "\10\27""7\10\27""7\10\31""9\13\32""8\2\31""9\13\31""9\13\32""8\2\34:" + "\5\27""8\11\34:\5\27""8\11\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>" + "\10\30>\10\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B" + "\5\32\77\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77" + "\12\36B\5\32\77\12\36B\5\33A\14\36B\5\33A\14\33A\14\36B\5\33A\14\36B" + "\5\33A\14\33A\14\36B\5\33A\14\0\0.W\23.W\23.W\23.W\23.W\23.W\23.W\23" + "2Z\15""0Y\24""0Y\24""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24" + "0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""2Z\15" + "2Z\15-\\\16-\\\16""0Y\24-\\\16/^\20""3[\16/^\20/^\20/^\20/^\20""0_\21" + "0_\21""0_\21""0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24" + "3b\24""3b\24""3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17" + "5d\26""9g\21""9g\21""4j\23""9g\21""4j\23""9g\21""5k\24""4j\23""4j\23" + "9g\21""4j\23""9g\21""4j\23""5k\24""9g\21""5k\24""9g\21""5k\24""6l\25" + "9g\21""5k\24""6l\25""9g\21""6l\25""6l\25""5k\24""5k\24""9g\21""6l\25" + "5k\24\0\0\30""1\1\25""0\10\25""0\10\25""0\10\25""0\10\25""0\10\30""1" + "\1\23""3\3\30""1\1\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\23""3\3\30" + "1\1\23""3\3\27""1\12\23""3\3\23""3\3\23""3\3\23""3\3\27""1\12\23""3\3" + "\24""4\5\24""4\5\24""4\5\25""5\6\25""5\6\25""5\6\25""5\6\27""7\10\27" + "7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27""7\10\27" + "7\10\27""7\10\27""7\10\32""8\2\32""8\2\31""9\13\32""8\2\34:\5\27""8\11" + "\34:\5\34:\5\34:\5\27=\7\27=\7\27=\7\27=\7\30>\10\30>\10\30>\10\32\77" + "\12\32\77\12\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\32\77\12\36B\5" + "\32\77\12\36B\5\32\77\12\32\77\12\32\77\12\36B\5\32\77\12\36B\5\32\77" + "\12\36B\5\33A\14\36B\5\33A\14\36B\5\33A\14\36B\5\36B\5\33A\14\36B\5\33" + "A\14\33A\14\36B\5\0\0.W\23.W\23.W\23.W\23.W\23.W\23""2Z\15""0Y\24""0" + "Y\24""0Y\24""0Y\24""2Z\15""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0Y\24""0" + "Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""0Y\24""2Z\15""3[\16-\\\16-\\" + "\16""3[\16/^\20""3[\16/^\20/^\20/^\20""3[\16/^\20""3[\16""0_\21""0_\21" + "0_\21""0_\21""0_\21""2a\23""2a\23""2a\23""2a\23""3b\24""3b\24""3b\24" + "3b\24""3b\24""5d\26""5d\26""5d\26""5d\26""5d\26""7e\17""5d\26""9g\21" + "7f\30""4j\23""9g\21""4j\23""5k\24""9g\21""5k\24""4j\23""9g\21""4j\23" + "4j\23""9g\21""5k\24""5k\24""4j\23""4j\23""6l\25""9g\21""5k\24""5k\24" + "5k\24""5k\24""9g\21""6l\25""5k\24""9g\21""5k\24""9g\21""9g\21""5k\24" + "\0\0", +}; + + diff --git a/polymer/build/rsrc/game_icon.bmp b/polymer/build/rsrc/game_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b921dcd0379fe7db56b6e50dfc41dad3d9de6463 GIT binary patch literal 3126 zcmeH}TZ`I26o9wy{Q-Rx$(GRi5NMHh5wS(2gsfPxB1LvXkPw0tu|Xt=h=|A{OX*V| zee`Gct7kh5$r9Gf?nCKe9L^l)eCLwM<>O`X`Poj2%qG9w-S64i3pC{Je_6=vM86mp zov3Jc)nNJM`|a0nv#a5P(Hq|cliU96rysAq(Mk>M;q-?X>t1AE4P;b1p`boo$H3oQ z`Z>eQ>0+2p+l``VFc@@p((QIxP9_s9Ze&~eoH_!@@s^1UNf0N-x6)9IAC-|yq1 z_`~5)=L?g0wOWxmE`(bw7HR(ZYwJ~|_3m>(2!Oa$Di!#f%|`gtI2w&~eyi2OBKbpR zo3v=XUb9T(pU>ydt&5EOtJP{4hLof7hfkg`5yeNRKg3G#RsRWLnr6EH@VO!hKKYBN zZ%nE(aaMvM;|>D$#t-5621LX0u7V;FBsem{I~3bav`| z{e04&MCP)z45M5wbJ8dT!NqYLIpDT!qbp&_*?6l-p->QrT;F^7Cow)HpN9Ls|L5Wz zCqO`@`-5HGo<}O6(tNT$606)nW$-!k+*yYS$CW7Ae8?)3y%c$L|MUD_uXkAUas1!^ zj1%?1^YfJb=V{OF#-pCx5LxOoFE3RQ8}_}vzQ61bNWBNopoA&!ugB&~ YEvL<2^@mSrslttxd}*I#fD$I~-{LrYJOBUy literal 0 HcmV?d00001 diff --git a/polymer/build/rsrc/game_icon.c b/polymer/build/rsrc/game_icon.c new file mode 100644 index 000000000..82d833ac8 --- /dev/null +++ b/polymer/build/rsrc/game_icon.c @@ -0,0 +1,192 @@ +#include "sdlayer.h" + +static unsigned int sdlappicon_pixels[] = { + 0xff415f7a, 0xff364a5c, 0xff364a5c, 0xff607486, 0xff667a8c, 0xff667a8c, + 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, + 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, + 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, + 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff667a8c, 0xff607486, 0xff364a5c, + 0xff364a5c, 0xff415f7a, 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff334d66, + 0xff334d66, 0xff747474, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff747474, 0xff334d66, 0xff334d66, 0xff364a5c, + 0xff364a5c, 0xff334d66, 0xff334d66, 0xff747474, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff747474, 0xff334d66, + 0xff334d66, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff5c5c5c, + 0xff404040, 0xff808080, 0xff646464, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff646464, 0xff7c7c7c, 0xff404040, + 0xff5c5c5c, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff6c6c6c, 0xff686868, 0xff808080, 0xff686868, 0xff808080, + 0xff808080, 0xff808080, 0xff6c6c6c, 0xff6a6a6a, 0xff727272, 0xff6c6c6c, + 0xff6c6c6c, 0xff767676, 0xff626262, 0xff6c6c6c, 0xff808080, 0xff6c6c6c, + 0xff686868, 0xff747474, 0xff808080, 0xff808080, 0xff808080, 0xff707070, + 0xff787878, 0xff686868, 0xff6c6c6c, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, 0xff808080, 0xff808080, + 0xff686868, 0xff808080, 0xff808080, 0xff808080, 0xff6c6c6c, 0xff6a6a6a, + 0xff727272, 0xff6a6a6a, 0xff6a6a6a, 0xff808080, 0xff6c6c6c, 0xff6c6c6c, + 0xff808080, 0xff6c6c6c, 0xff7c7c7c, 0xff6c6c6c, 0xff808080, 0xff808080, + 0xff808080, 0xff707070, 0xff787878, 0xff808080, 0xff747474, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, + 0xff808080, 0xff808080, 0xff686868, 0xff808080, 0xff808080, 0xff808080, + 0xff767676, 0xff6c6c6c, 0xff7c7c7c, 0xff707070, 0xff707070, 0xff767676, + 0xff6c6c6c, 0xff767676, 0xff6c6c6c, 0xff767676, 0xff6c6c6c, 0xff7e7e7e, + 0xff808080, 0xff808080, 0xff808080, 0xff707070, 0xff787878, 0xff808080, + 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff747474, 0xff808080, 0xff808080, 0xff646464, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff646464, + 0xff787878, 0xff808080, 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, 0xff808080, 0xff808080, + 0xff686868, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff707070, 0xff787878, 0xff808080, 0xff747474, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, + 0xff808080, 0xff808080, 0xff686868, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff707070, 0xff787878, 0xff808080, + 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff747474, 0xff808080, 0xff808080, 0xff686868, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff707070, + 0xff787878, 0xff808080, 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, 0xff808080, 0xff808080, + 0xff646464, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff646464, 0xff787878, 0xff808080, 0xff747474, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, + 0xff808080, 0xff808080, 0xff686868, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff707070, 0xff787878, 0xff808080, + 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff747474, 0xff808080, 0xff808080, 0xff686868, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff707070, + 0xff787878, 0xff808080, 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, 0xff808080, 0xff808080, + 0xff686868, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff707070, 0xff787878, 0xff808080, 0xff747474, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff747474, + 0xff808080, 0xff808080, 0xff6c6c6c, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff686868, + 0xff686868, 0xff686868, 0xff686868, 0xff686868, 0xff787878, 0xff808080, + 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff747474, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff747474, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff666666, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff808080, + 0xff808080, 0xff808080, 0xff808080, 0xff808080, 0xff666666, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff3c3c3c, + 0xff666666, 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, + 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, + 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, + 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff747474, 0xff666666, + 0xff3c3c3c, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff302424, 0xff3e3e3e, + 0xff484848, 0xff444444, 0xff444444, 0xff464646, 0xff4c4c4c, 0xff484848, + 0xff484848, 0xff4a4a4a, 0xff4c4c4c, 0xff4c4c4c, 0xff4c4c4c, 0xff4c4c4c, + 0xff4a4a4a, 0xff404040, 0xff343434, 0xff343434, 0xff343434, 0xff343434, + 0xff2c2c2c, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff202020, + 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff3c3c3c, 0xff727272, 0xff707070, 0xff565656, 0xff505050, 0xff525252, + 0xff6a6a6a, 0xff787878, 0xff767676, 0xff747474, 0xff7a7a7a, 0xff7c7c7c, + 0xff787878, 0xff787878, 0xff7a7a7a, 0xff727272, 0xff505050, 0xff484848, + 0xff484848, 0xff484848, 0xff464646, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff202020, 0xff202020, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202020, 0xff444444, 0xff6c6c6c, 0xff6c6c6c, 0xff303030, + 0xff202020, 0xff202020, 0xff545454, 0xff787878, 0xff747474, 0xff747474, + 0xff787878, 0xff7c7c7c, 0xff808080, 0xff808080, 0xff7a7a7a, 0xff747474, + 0xff505050, 0xff484848, 0xff484848, 0xff484848, 0xff484848, 0xff202020, + 0xff202020, 0xff364a5c, 0xff364a5c, 0xff282828, 0xff606060, 0xff686868, + 0xff747474, 0xff4e4e4e, 0xff565656, 0xff202020, 0xff444444, 0xff686868, + 0xff6c6c6c, 0xff303030, 0xff202020, 0xff202020, 0xff545454, 0xff767676, + 0xff767676, 0xff767676, 0xff7c7c7c, 0xff787878, 0xff7c7c7c, 0xff7c7c7c, + 0xff7e7e7e, 0xff767676, 0xff505050, 0xff484848, 0xff484848, 0xff484848, + 0xff484848, 0xff202020, 0xff202020, 0xff364a5c, 0xff364a5c, 0xff606060, + 0xffa8a8a8, 0xff7e7e7e, 0xffa8a8a8, 0xff6c6c6c, 0xff7c7c7c, 0xff202020, + 0xff444444, 0xff6a6a6a, 0xff6c6c6c, 0xff303030, 0xff202020, 0xff202020, + 0xff545454, 0xff747474, 0xff787878, 0xff787878, 0xff7e7e7e, 0xff7c7c7c, + 0xff787878, 0xff787878, 0xff828282, 0xff7c7c7c, 0xff505050, 0xff484848, + 0xff484848, 0xff484848, 0xff484848, 0xff202020, 0xff202020, 0xff364a5c, + 0xff364a5c, 0xff7c7c7c, 0xff808080, 0xff404040, 0xffa8a8a8, 0xffa0a0a0, + 0xff7c7c7c, 0xff202020, 0xff464646, 0xff767676, 0xff727272, 0xff303030, + 0xff202020, 0xff202020, 0xff545454, 0xff767676, 0xff7a7a7a, 0xff787878, + 0xff7e7e7e, 0xff7c7c7c, 0xff787878, 0xff7c7c7c, 0xff8c8c8c, 0xff7e7e7e, + 0xff505050, 0xff484848, 0xff484848, 0xff484848, 0xff484848, 0xff222222, + 0xff25303a, 0xff364a5c, 0xff364a5c, 0xff606060, 0xffa8a8a8, 0xff7e7e7e, + 0xffa8a8a8, 0xff6c6c6c, 0xff7c7c7c, 0xff202020, 0xff484848, 0xff787878, + 0xff727272, 0xff303030, 0xff202020, 0xff202020, 0xff585858, 0xff808080, + 0xff808080, 0xff808080, 0xff888888, 0xff868686, 0xff7e7e7e, 0xff7a7a7a, + 0xff848484, 0xff747474, 0xff505050, 0xff484848, 0xff484848, 0xff484848, + 0xff484848, 0xff252b30, 0xff2a4054, 0xff385168, 0xff3a5874, 0xff282c30, + 0xff606060, 0xff686868, 0xff747474, 0xff4e4e4e, 0xff565656, 0xff202020, + 0xff484848, 0xff787878, 0xff707070, 0xff303030, 0xff202020, 0xff202020, + 0xff585858, 0xff7c7c7c, 0xff7a7a7a, 0xff787878, 0xff828282, 0xff808080, + 0xff808080, 0xff7c7c7c, 0xff828282, 0xff747474, 0xff505050, 0xff484848, + 0xff484848, 0xff484848, 0xff484848, 0xff242424, 0xff26394c, 0xff364a5c, + 0xff4c7498, 0xff334d66, 0xff202428, 0xff202020, 0xff202020, 0xff202020, + 0xff202020, 0xff202428, 0xff4c5660, 0xff747474, 0xff707070, 0xff585858, + 0xff585858, 0xff5c5c5c, 0xff747474, 0xff7c7c7c, 0xff707070, 0xff787878, + 0xff7c7c7c, 0xff787878, 0xff7c7c7c, 0xff868686, 0xff828282, 0xff787878, + 0xff505050, 0xff484848, 0xff484848, 0xff484848, 0xff464646, 0xff202020, + 0xff202020, 0xff364a5c, 0xff4c7498, 0xff4c7498, 0xff3a5874, 0xff364a5c, + 0xff364a5c, 0xff364a5c, 0xff364a5c, 0xff3a5874, 0xff55738e, 0xff5a6e80, + 0xff5e7284, 0xff5e7284, 0xff64788a, 0xff687c8e, 0xff6c8092, 0xff667a8c, + 0xff627688, 0xff627688, 0xff627688, 0xff627688, 0xff64788a, 0xff6a7e90, + 0xff667a8c, 0xff627688, 0xff4e6274, 0xff4a5e70, 0xff4a5e70, 0xff4a5e70, + 0xff44586a, 0xff364a5c, 0xff364a5c, 0xff415f7a,}; + +static unsigned char sdlappicon_mask[] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255,}; + +struct sdlappicon sdlappicon = { + 32,32, // width,height + sdlappicon_pixels, + sdlappicon_mask +}; diff --git a/polymer/build/rsrc/game_icon.ico b/polymer/build/rsrc/game_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b6868267fa73d296c4094cfc51f47d527b7e1dc5 GIT binary patch literal 2998 zcmds&FKi=66o;qh2M$!#+Fl0*Tm!0xoir#?K$R?V6zNEC*kfB#5K>?iT&Yr|VF%i( z1tp<9uu`OgW^h6-DBvourCd-~DtP^79Xl7>xfWD9wa=d2o!{Gizi(#tk8>ZnC+^v^ zjJ>$upE&oKbMzhkr|!q6&VABx?(?M4zM!S^-XA09_`A_)x?{_stE$RXuPgWVw;$Zw zKh1sj@+EpY(b~T=bJ2Sr=W(`uMt0tfRp)t(Rjg)G)!%;g>S4e7<=uW~A-{Ni=Xt7s zU$5JbVXP6fF95TdO#280X?Ee^oSnOBYH$P`bOWPcynUyIFzvj8k#dP7MU0snx1 zz&|iI0fqoWFoOe~d5HK$7-C{z4tR&s&|r&jMEoKgF>x>l5ssKRSdYjUA}kS>2up+| z!os_YhK^^1g-4o(4ogfdtVx6=ruk@DJaeKnG#Cs9gTY`h7z_r3!C;6m7z_qOgu!4i z7z_r3!C){L3+5S7kH>O*dn--T$Yb9nzEFIn_@z%3o4vhZK@7i4(R|hJ z(q>38GQ+*1n-Se!U8B@ZP4Q+jX?p#BKhLsaxLcNWznAr!dN<3)ZF15~>Xh$igQ6&J znwzqj=0;cnt--) + { + *((char *)p) = palptr[gbuf[((bx>>(32-glogx))<>(32-glogy))]]; + bx -= gbxinc; + by -= gbyinc; + p--; + } +} + + + //Sloped ceiling/floor vertical line functions +void setupslopevlin(long logylogx, long bufplc, long pinc) +{ + glogx = (logylogx&255); glogy = (logylogx>>8); + gbuf = (char *)bufplc; gpinc = pinc; +} +void slopevlin(long p, long i, long slopaloffs, long cnt, long bx, long by) +{ + long *slopalptr, bz, bzinc; + unsigned long u, v; + + bz = asm3; bzinc = (asm1>>3); + slopalptr = (long *)slopaloffs; + for(;cnt>0;cnt--) + { + i = krecip(bz>>6); bz += bzinc; + u = bx+globalx3*i; + v = by+globaly3*i; + (*(char *)p) = *(char *)(slopalptr[0]+gbuf[((u>>(32-glogx))<>(32-glogy))]); + slopalptr--; + p += gpinc; + } +} + + + //Wall,face sprite/wall sprite vertical line functions +void setupvlineasm(long neglogy) { glogy = neglogy; } +void vlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + for(;cnt>=0;cnt--) + { + *((char *)p) = gpal[gbuf[vplc>>glogy]]; + p += bpl; + vplc += vinc; + } +} + +void setupmvlineasm(long neglogy) { glogy = neglogy; } +void mvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; if (ch != 255) *((char *)p) = gpal[ch]; + p += bpl; + vplc += vinc; + } +} + +void setuptvlineasm(long neglogy) { glogy = neglogy; } +void tvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + if (transmode) + { + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + p += bpl; + vplc += vinc; + } + } + else + { + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + p += bpl; + vplc += vinc; + } + } +} + + //Floor sprite horizontal line functions +void msethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } +void mhline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)asm3; + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gpal[ch]; + bx += asm1; + by += asm2; + p++; + } +} + +void tsethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } +void thline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)asm3; + if (transmode) + { + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + bx += asm1; + by += asm2; + p++; + } + } + else + { + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + bx += asm1; + by += asm2; + p++; + } + } +} + + + //Rotatesprite vertical line functions +void setupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void spritevline(long bx, long by, long cnt, long bufplc, long p) +{ + gbuf = (char *)bufplc; + for(;cnt>1;cnt--) + { + (*(char *)p) = gpal[gbuf[(bx>>16)*glogy+(by>>16)]]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } +} + + //Rotatesprite vertical line functions +void msetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void mspritevline(long bx, long by, long cnt, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) (*(char *)p) = gpal[ch]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } +} + +void tsetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void tspritevline(long bx, long by, long cnt, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + if (transmode) + { + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } + } + else + { + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } + } +} + +void setupdrawslab (long dabpl, long pal) + { bpl = dabpl; gpal = (char *)pal; } + +void drawslab (long dx, long v, long dy, long vi, long vptr, long p) +{ + long x; + + while (dy > 0) + { + for(x=0;x>16)+vptr))]; + p += bpl; v += vi; dy--; + } +} + +void stretchhline (long p0, long u, long cnt, long uinc, long rptr, long p) +{ + p0 = p-(cnt<<2); + do + { + p--; + *(char *)p = *(char *)((u>>16)+rptr); u -= uinc; + } while (p > p0); +} + + +void mmxoverlay() { } + +/* + * vim:ts=4: + */ + diff --git a/polymer/build/src/a.masm b/polymer/build/src/a.masm new file mode 100644 index 000000000..bd9ece295 --- /dev/null +++ b/polymer/build/src/a.masm @@ -0,0 +1,2664 @@ +; "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +; Ken Silverman's official web site: "http://www.advsys.net/ken" +; See the included license file "BUILDLIC.TXT" for license info. + +.586P +.8087 +;include mmx.inc ;Include this if using < WATCOM 11.0 WASM + +;Warning: IN THIS FILE, ALL SEGMENTS ARE REMOVED. THIS MEANS THAT DS:[] +;MUST BE ADDED FOR ALL SELF-MODIFIES FOR MASM TO WORK. +; +;WASM PROBLEMS: +; 1. Requires all scaled registers (*1,*2,*4,*8) to be last thing on line +; 2. Using 'DATA' is nice for self-mod. code, but WDIS only works with 'CODE' +; +;MASM PROBLEMS: +; 1. Requires DS: to be written out for self-modifying code to work +; 2. Doesn't encode short jumps automatically like WASM +; 3. Stupidly adds wait prefix to ffree's + +EXTRN _asm1 : dword +EXTRN _asm2 : dword +EXTRN _asm3 : dword +EXTRN _asm4 : dword +EXTRN _reciptable : near +EXTRN _fpuasm : dword +EXTRN _globalx3 : dword +EXTRN _globaly3 : dword +EXTRN _ylookup : near + +EXTRN _vplce : near +EXTRN _vince : near +EXTRN _palookupoffse : near +EXTRN _bufplce : near + +EXTRN _ebpbak : dword +EXTRN _espbak : dword + +EXTRN _pow2char : near +EXTRN _pow2long : near + + +; Some macros to help make cdecl calling easier to manage +CDECLBEGIN MACRO noi:=<0> + IF noi GE 2 + push ebx + ENDIF + IF noi GE 3 + push ecx + ENDIF + IF noi GE 4 + push edx + ENDIF + IF noi GE 5 + push esi + ENDIF + IF noi GE 6 + push edi + ENDIF +ENDM + +CDECLEND MACRO noi:=<0> + IF noi GE 6 + pop edi + ENDIF + IF noi GE 5 + pop esi + ENDIF + IF noi GE 4 + pop edx + ENDIF + IF noi GE 3 + pop ecx + ENDIF + IF noi GE 2 + pop ebx + ENDIF +ENDM + +CDECLPARAM MACRO registername:REQ,paramnumber:REQ,offsetted:REQ +; mov registername, dword ptr [esp + (paramnumber*4+16)] + mov registername, dword ptr [esp + ((paramnumber+offsetted)*4+4)] +ENDM + +CDECLBEGINSET MACRO numparams:REQ + CDECLBEGIN numparams + +% _offsetted = numparams - 1 + + IF numparams GE 1 + CDECLPARAM eax,0,%_offsetted + ENDIF + IF numparams GE 2 + CDECLPARAM ebx,1,%_offsetted + ENDIF + IF numparams GE 3 + CDECLPARAM ecx,2,%_offsetted + ENDIF + IF numparams GE 4 + CDECLPARAM edx,3,%_offsetted + ENDIF + IF numparams GE 5 + CDECLPARAM esi,4,%_offsetted + ENDIF + IF numparams GE 6 + CDECLPARAM edi,5,%_offsetted + ENDIF +ENDM + +CDECLENDSET MACRO numparams:REQ + CDECLEND numparams +ENDM + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +ALIGN 16 +PUBLIC _sethlinesizes +_sethlinesizes: +CDECLBEGINSET 3 + + mov byte ptr [machxbits1+2], al + mov byte ptr [machxbits2+2], al + mov byte ptr [machxbits3+2], al + neg al + mov byte ptr [hxsiz1+2], al + mov byte ptr [hxsiz2+2], al + mov byte ptr [hxsiz3+2], al + mov byte ptr [hxsiz4+2], al + mov byte ptr [machnegxbits1+2], al + + mov byte ptr [hysiz1+3], bl + mov byte ptr [hysiz2+3], bl + mov byte ptr [hysiz3+3], bl + mov byte ptr [hysiz4+3], bl + mov byte ptr [hmach3a+2], bl + mov byte ptr [hmach3b+2], bl + mov byte ptr [hmach3c+2], bl + mov byte ptr [hmach3d+2], bl + + mov dword ptr [hoffs1+2], ecx + mov dword ptr [hoffs2+2], ecx + mov dword ptr [hoffs3+2], ecx + mov dword ptr [hoffs4+2], ecx + mov dword ptr [hoffs5+2], ecx + mov dword ptr [hoffs6+2], ecx + mov dword ptr [hoffs7+2], ecx + mov dword ptr [hoffs8+2], ecx + + push edx ;JBF + mov edx, -1 + mov cl, al + sub cl, bl + shr edx, cl + mov dword ptr [hmach2a+1], edx + mov dword ptr [hmach2b+1], edx + mov dword ptr [hmach2c+1], edx + mov dword ptr [hmach2d+1], edx + pop edx ;JBF + +CDECLENDSET 3 + ret + +ALIGN 16 +PUBLIC _prosethlinesizes +_prosethlinesizes: +CDECLBEGINSET 3 + + mov dword ptr [prohbuf-4], ecx + neg eax + mov ecx, eax + sub eax, ebx + mov byte ptr [prohshru-1], al ;bl = 32-al-bl + mov eax, -1 + shr eax, cl + mov ecx, ebx + shl eax, cl + mov dword ptr [prohand-4], eax ;((-1>>(-oal))<>(32-xbits) adc al, 88h 1 1/2 + ;bufplc mov cl, byte ptr [edx+88888888h] 1 1/2 + ;paloffs&255 mov bl, byte ptr [ecx+88888888h] 1 1/2 +ALIGN 16 +PUBLIC _hlineasm4 +_hlineasm4: +CDECLBEGINSET 6 + + push ebp + + lea ebp, [eax+1] + + cmp ebp, 8 + jle shorthline + + test edi, 1 + jnz short skipthe1byte + + mov eax, esi +hxsiz1: shr eax, 26 +hysiz1: shld eax, edx, 6 +hoffs1: mov cl, byte ptr [eax+88888888h] +pal1: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov byte ptr [edi], bl + dec edi + dec ebp + +skipthe1byte: + test edi, 2 + jnz short skipthe2byte + + mov eax, esi +hxsiz2: shr eax, 26 +hysiz2: shld eax, edx, 6 +hoffs2: mov cl, byte ptr [eax+88888888h] +pal2: mov bh, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + + mov eax, esi +hxsiz3: shr eax, 26 +hysiz3: shld eax, edx, 6 +hoffs3: mov cl, byte ptr [eax+88888888h] +pal3: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov word ptr [edi-1], bx + sub edi, 2 + sub ebp, 2 + +skipthe2byte: + + mov eax, esi +machxbits1: shl esi, 6 ;xbits +machnegxbits1: shr eax, 32-6 ;32-xbits + mov dl, al + + inc edi + + add ebx, ebx + mov eax, edx + jc beginhline64 + + mov eax, _asm1 +machxbits2: rol eax, 6 ;xbits + mov dword ptr [hmach4a+2], eax + mov dword ptr [hmach4b+2], eax + mov dword ptr [hmach4c+2], eax + mov dword ptr [hmach4d+2], eax + mov ebx, eax + mov eax, _asm2 + mov al, bl + mov dword ptr [hmach1a+2], eax + mov dword ptr [hmach1b+2], eax + mov dword ptr [hmach1c+2], eax + mov dword ptr [hmach1d+2], eax + + mov eax, edx + jmp beginhline64 +ALIGN 16 +prebeginhline64: + mov dword ptr [edi], ebx +beginhline64: + +hmach3a: rol eax, 6 +hmach2a: and eax, 00008888h +hmach4a: sub esi, 88888888h +hmach1a: sbb edx, 88888888h + sub edi, 4 +hoffs4: mov cl, byte ptr [eax+88888888h] + mov eax, edx + +hmach3b: rol eax, 6 +hmach2b: and eax, 00008888h +hmach4b: sub esi, 88888888h +hmach1b: sbb edx, 88888888h +pal4: mov bh, byte ptr [ecx+88888888h] +hoffs5: mov cl, byte ptr [eax+88888888h] + mov eax, edx + +hmach3c: rol eax, 6 +pal5: mov bl, byte ptr [ecx+88888888h] +hmach2c: and eax, 00008888h + shl ebx, 16 +hmach4c: sub esi, 88888888h +hmach1c: sbb edx, 88888888h +hoffs6: mov cl, byte ptr [eax+88888888h] + + mov eax, edx + ;( + +hmach3d: rol eax, 6 +hmach2d: and eax, 00008888h +hmach4d: sub esi, 88888888h +hmach1d: sbb edx, 88888888h +pal6: mov bh, byte ptr [ecx+88888888h] +hoffs7: mov cl, byte ptr [eax+88888888h] + mov eax, edx + sub ebp, 4 + nop +pal7: mov bl, byte ptr [ecx+88888888h] + jnc prebeginhline64 +skipthe4byte: + + test ebp, 2 + jz skipdrawthe2 + rol ebx, 16 + mov word ptr [edi+2], bx + sub edi, 2 +skipdrawthe2: + test ebp, 1 + jz skipdrawthe1 + shr ebx, 24 + mov byte ptr [edi+3], bl +skipdrawthe1: + + pop ebp +CDECLENDSET 6 + ret + +shorthline: + test ebp, ebp + jz endshorthline +begshorthline: + mov eax, esi +hxsiz4: shr eax, 26 +hysiz4: shld eax, edx, 6 +hoffs8: mov cl, byte ptr [eax+88888888h] +pal8: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov byte ptr [edi], bl + dec edi + dec ebp + jnz begshorthline +endshorthline: + pop ebp +CDECLENDSET 6 + ret + + + ;eax: 00000000 00000000 00000000 temp---- + ;ebx: 00000000 00000000 00000000 temp---- + ;ecx: UUUUUUuu uuuuuuuu uuuuuuuu uuuuuuuu + ;edx: VVVVVVvv vvvvvvvv vvvvvvvv vvvvvvvv + ;esi: cnt----- -------- -------- -------- + ;edi: vid----- -------- -------- -------- + ;ebp: paloffs- -------- -------- -------- + ;esp: ???????? ???????? ???????? ???????? +ALIGN 16 +PUBLIC _prohlineasm4 +_prohlineasm4: +CDECLBEGINSET 6 + + push ebp + + lea ebp, [ecx+88888888h] +prohpala: + mov ecx, esi + lea esi, [eax+1] + sub edi, esi + +prohbeg: + mov eax, ecx + shr eax, 20 +prohshru: + mov ebx, edx + shr ebx, 26 +prohshrv: + and eax, 88888888h +prohand: + movzx eax, byte ptr [eax+ebx+88888888h] +prohbuf: + mov al, [eax+ebp] + sub ecx, _asm1 + sub edx, _asm2 + mov [edi+esi], al + dec esi + jnz prohbeg + + pop ebp +CDECLENDSET 6 + ret + + + +ALIGN 16 +PUBLIC _setupvlineasm +_setupvlineasm: +CDECLBEGINSET 1 + ;First 2 lines for VLINEASM1, rest for VLINEASM4 + mov byte ptr [premach3a+2], al + mov byte ptr [mach3a+2], al + + push ecx + mov byte ptr [machvsh1+2], al ;32-shy + mov byte ptr [machvsh3+2], al ;32-shy + mov byte ptr [machvsh5+2], al ;32-shy + mov byte ptr [machvsh6+2], al ;32-shy + mov ah, al + sub ah, 16 + mov byte ptr [machvsh8+2], ah ;16-shy + neg al + mov byte ptr [machvsh7+2], al ;shy + mov byte ptr [machvsh9+2], al ;shy + mov byte ptr [machvsh10+2], al ;shy + mov byte ptr [machvsh11+2], al ;shy + mov byte ptr [machvsh12+2], al ;shy + mov cl, al + mov eax, 1 + shl eax, cl + dec eax + mov dword ptr [machvsh2+2], eax ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +machvsh5: shl esi, 88h ;32-sh + mov eax, edx +machvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +machvsh7: shr eax, 88h ;sh + add esi, eax +machvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword ptr _vplce[12], esi + mov dword ptr _vplce[4], ebp + + pop ebp + +CDECLEND 6 + ret + + ;eax: -------temp1------- + ;ebx: -------temp2------- + ;ecx: ylo4 --------- + ;edx: ylo2 --------- + ;esi: yhi1 yhi2 + ;edi: ---videoplc/cnt---- + ;ebp: yhi3 yhi4 + ;esp: +ALIGN 16 +PUBLIC _provlineasm4 +_provlineasm4: +CDECLBEGIN 6 +CDECLPARAM ecx,0,5 +CDECLPARAM edi,1,5 + + push ebp + + mov eax, dword ptr _ylookup[ecx*4] + add eax, edi + mov dword ptr [promachvline4end1+2], eax + inc eax + mov dword ptr [promachvline4end2+2], eax + inc eax + mov dword ptr [promachvline4end3+2], eax + inc eax + mov dword ptr [promachvline4end4+2], eax + sub eax, 3 + sub edi, eax + + mov eax, dword ptr _bufplce[0] + mov ebx, dword ptr _bufplce[4] + mov ecx, dword ptr _bufplce[8] + mov edx, dword ptr _bufplce[12] + mov dword ptr [promachvbuf1+3], ecx + mov dword ptr [promachvbuf2+3], edx + mov dword ptr [promachvbuf3+3], eax + mov dword ptr [promachvbuf4+3], ebx + + mov eax, dword ptr _palookupoffse[0] + mov ebx, dword ptr _palookupoffse[4] + mov ecx, dword ptr _palookupoffse[8] + mov edx, dword ptr _palookupoffse[12] + mov dword ptr [promachvpal1+2], ecx + mov dword ptr [promachvpal2+2], edx + mov dword ptr [promachvpal3+2], eax + mov dword ptr [promachvpal4+2], ebx + + ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ;edx: ³v3lo ³v1lo ³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ´ + ;esi: ³v2hi v2lo ³ v3hi³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´ + ;ebp: ³v0hi v0lo ³ v1hi³ + ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ + + mov ebp, dword ptr _vince[0] + mov ebx, dword ptr _vince[4] + mov esi, dword ptr _vince[8] + mov eax, dword ptr _vince[12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh9: rol eax, 88h ;sh +promachvsh10: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + ; + mov eax, edx + and eax, 0ffff0000h + mov dword ptr [promachvinc1+2], eax + mov dword ptr [promachvinc2+2], esi + shl edx, 16 + mov dword ptr [promachvinc3+2], edx + mov dword ptr [promachvinc5+2], ebp + + mov ebp, dword ptr _vplce[0] + mov ebx, dword ptr _vplce[4] + mov esi, dword ptr _vplce[8] + mov eax, dword ptr _vplce[12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh11: rol eax, 88h ;sh +promachvsh12: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + + mov eax, esi + mov ecx, edx + shl ecx, 16 + jmp short probeginvlineasm4 +ALIGN 16 + nop + nop + nop +probeginvlineasm4: +promachvsh1: shr eax, 88h ;32-sh + mov ebx, esi +promachvsh2: and ebx, 00000088h ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +promachvsh5: shl esi, 88h ;32-sh + mov eax, edx +promachvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +promachvsh7: shr eax, 88h ;sh + add esi, eax +promachvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword ptr _vplce[12], esi + mov dword ptr _vplce[4], ebp + + pop ebp + +CDECLEND 6 + ret + + +ALIGN 16 +PUBLIC _mvlineasm4 +_mvlineasm4: +CDECLBEGIN 6 +CDECLPARAM ecx,0,5 +CDECLPARAM edi,1,5 + + push ebp + + mov eax, dword ptr _bufplce[0] + mov ebx, dword ptr _bufplce[4] + mov dword ptr [machmv1+2], eax + mov dword ptr [machmv4+2], ebx + mov eax, dword ptr _bufplce[8] + mov ebx, dword ptr _bufplce[12] + mov dword ptr [machmv7+2], eax + mov dword ptr [machmv10+2], ebx + + mov eax, dword ptr _palookupoffse[0] + mov ebx, dword ptr _palookupoffse[4] + mov dword ptr [machmv2+2], eax + mov dword ptr [machmv5+2], ebx + mov eax, dword ptr _palookupoffse[8] + mov ebx, dword ptr _palookupoffse[12] + mov dword ptr [machmv8+2], eax + mov dword ptr [machmv11+2], ebx + + mov eax, dword ptr _vince[0] ;vince + mov ebx, dword ptr _vince[4] + xor al, al + xor bl, bl + mov dword ptr [machmv3+2], eax + mov dword ptr [machmv6+2], ebx + mov eax, dword ptr _vince[8] + mov ebx, dword ptr _vince[12] + mov dword ptr [machmv9+2], eax + mov dword ptr [machmv12+2], ebx + + mov ebx, ecx + mov ecx, dword ptr _vplce[0] + mov edx, dword ptr _vplce[4] + mov esi, dword ptr _vplce[8] + mov ebp, dword ptr _vplce[12] + mov cl, bl + inc cl + inc bh + mov byte ptr _asm3[0], bh +fixchain2ma: sub edi, 320 + + jmp short beginmvlineasm4 +ALIGN 16 +beginmvlineasm4: + dec cl + jz endmvlineasm4 +beginmvlineasm42: + mov eax, ebp + mov ebx, esi +machmv16: shr eax, 32 +machmv15: shr ebx, 32 +machmv12: add ebp, 88888888h ;vince[3] +machmv9: add esi, 88888888h ;vince[2] +machmv10: mov al, byte ptr [eax+88888888h] ;bufplce[3] +machmv7: mov bl, byte ptr [ebx+88888888h] ;bufplce[2] + cmp al, 255 + adc dl, dl + cmp bl, 255 + adc dl, dl +machmv8: mov bl, byte ptr [ebx+88888888h] ;palookupoffs[2] +machmv11: mov bh, byte ptr [eax+88888888h] ;palookupoffs[3] + + mov eax, edx +machmv14: shr eax, 32 + shl ebx, 16 +machmv4: mov al, byte ptr [eax+88888888h] ;bufplce[1] + cmp al, 255 + adc dl, dl +machmv6: add edx, 88888888h ;vince[1] +machmv5: mov bh, byte ptr [eax+88888888h] ;palookupoffs[1] + + mov eax, ecx +machmv13: shr eax, 32 +machmv3: add ecx, 88888888h ;vince[0] +machmv1: mov al, byte ptr [eax+88888888h] ;bufplce[0] + cmp al, 255 + adc dl, dl +machmv2: mov bl, byte ptr [eax+88888888h] ;palookupoffs[0] + + shl dl, 4 + xor eax, eax +fixchain2mb: add edi, 320 + mov al, dl + add eax, offset mvcase0 + jmp eax ;16 byte cases + +ALIGN 16 +endmvlineasm4: + dec byte ptr _asm3[0] + jnz beginmvlineasm42 + + mov dword ptr _vplce[0], ecx + mov dword ptr _vplce[4], edx + mov dword ptr _vplce[8], esi + mov dword ptr _vplce[12], ebp + pop ebp +CDECLEND 6 + ret + + ;5,7,8,8,11,13,12,14,11,13,14,14,12,14,15,7 +ALIGN 16 +mvcase0: + jmp beginmvlineasm4 +ALIGN 16 +mvcase1: + mov byte ptr [edi], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase2: + mov byte ptr [edi+1], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase3: + mov word ptr [edi], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase4: + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase5: + mov byte ptr [edi], bl + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 + mvcase6: + shr ebx, 8 + mov word ptr [edi+1], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase7: + mov word ptr [edi], bx + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase8: + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase9: + mov byte ptr [edi], bl + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase10: + mov byte ptr [edi+1], bh + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase11: + mov word ptr [edi], bx + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase12: + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase13: + mov byte ptr [edi], bl + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase14: + mov byte ptr [edi+1], bh + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase15: + mov dword ptr [edi], ebx + jmp beginmvlineasm4 + +ALIGN 16 +PUBLIC _setupspritevline +_setupspritevline: +CDECLBEGINSET 6 + + mov dword ptr [spal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [smach1+2], eax + mov dword ptr [smach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [smach2+2], eax + add eax, edx + mov dword ptr [smach5+2], eax + + mov dword ptr [smach3+2], ecx ;yinc's + +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _spritevline +_spritevline: +CDECLBEGINSET 6 + jmp short _spritevline_start + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +prestartsvline: +smach1: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +smach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +startsvline: +spal: mov al, [eax+88888888h] ;palookup + mov byte ptr [edi], al +fixchain1s: add edi, 320 + +_spritevline_start: +smach3: add edx, 88888888h ;dayinc + dec ecx + ja short prestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short endsvline +smach4: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +smach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short startsvline +endsvline: +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _msetupspritevline +_msetupspritevline: +CDECLBEGINSET 6 + + mov dword ptr [mspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [msmach1+2], eax + mov dword ptr [msmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [msmach2+2], eax + add eax, edx + mov dword ptr [msmach5+2], eax + + mov dword ptr [msmach3+2], ecx ;yinc's + +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _mspritevline +_mspritevline: +CDECLBEGINSET 6 + jmp short _mspritevline_start + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +mprestartsvline: +msmach1: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +msmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +mstartsvline: + cmp al, 255 + je short mskipsvline +mspal: mov al, [eax+88888888h] ;palookup + mov byte ptr [edi], al +mskipsvline: +mfixchain1s: add edi, 320 + +_mspritevline_start: +msmach3: add edx, 88888888h ;dayinc + dec ecx + ja short mprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short mendsvline +msmach4: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +msmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short mstartsvline +mendsvline: +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _tsetupspritevline +_tsetupspritevline: +CDECLBEGINSET 6 + mov dword ptr [tspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [tsmach1+2], eax + mov dword ptr [tsmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [tsmach2+2], eax + add eax, edx + mov dword ptr [tsmach5+2], eax + + mov dword ptr [tsmach3+2], ecx ;yinc's +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _tspritevline +_tspritevline: +CDECLBEGINSET 6 + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p + push ebp + mov ebp, ebx + xor ebx, ebx + jmp tenterspritevline +ALIGN 16 +tprestartsvline: +tsmach1: add ebp, 88888888h ;xincshl16 + mov al, byte ptr [esi] +tsmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +tstartsvline: + cmp al, 255 + je short tskipsvline +transrev2: + mov bh, byte ptr [edi] +transrev3: +tspal: mov bl, [eax+88888888h] ;palookup +tmach4: mov al, byte ptr [ebx+88888888h] ;_transluc + mov byte ptr [edi], al +tskipsvline: +tfixchain1s: add edi, 320 + +tenterspritevline: +tsmach3: add edx, 88888888h ;dayinc + dec ecx + ja short tprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short tendsvline +tsmach4: add ebp, 88888888h ;xincshl16 + mov al, byte ptr [esi] +tsmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short tstartsvline +tendsvline: + pop ebp +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _msethlineshift +_msethlineshift: +CDECLBEGINSET 2 + neg al + mov byte ptr [msh1d+2], al + mov byte ptr [msh2d+3], bl + mov byte ptr [msh3d+2], al + mov byte ptr [msh4d+3], bl + mov byte ptr [msh5d+2], al + mov byte ptr [msh6d+3], bl +CDECLENDSET 2 + ret + +ALIGN 16 +PUBLIC _mhline +_mhline: +CDECLBEGINSET 6 + ;_asm1 = bxinc + ;_asm2 = byinc + ;_asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword ptr [mmach1d+2], eax + mov dword ptr [mmach5d+2], eax + mov dword ptr [mmach9d+2], eax + mov eax, _asm3 + mov dword ptr [mmach2d+2], eax + mov dword ptr [mmach2da+2], eax + mov dword ptr [mmach2db+2], eax + mov dword ptr [mmach6d+2], eax + mov dword ptr [mmach10d+2], eax + mov eax, _asm1 + mov dword ptr [mmach3d+2], eax + mov dword ptr [mmach7d+2], eax + mov eax, _asm2 + mov dword ptr [mmach4d+2], eax + mov dword ptr [mmach8d+2], eax + jmp short _mhlineskipmodify_nosetup + +ALIGN 16 +PUBLIC _mhlineskipmodify +_mhlineskipmodify: +CDECLBEGINSET 6 +_mhlineskipmodify_nosetup: + + push ebp + + xor eax, eax + mov ebp, ebx + + test ecx, 00010000h + jnz short mbeghline + +msh1d: shr ebx, 26 +msh2d: shld ebx, esi, 6 + add ebp, _asm1 +mmach9d: mov al, byte ptr [ebx+88888888h] ;picoffs + add esi, _asm2 + cmp al, 255 + je mskip5 + + mmach10d: mov cl, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi], cl +mskip5: + inc edi + sub ecx, 65536 + jc mendhline + jmp short mbeghline + +ALIGN 16 +mpreprebeghline: ;1st only + mov al, cl +mmach2d: mov al, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi], al + +mprebeghline: + add edi, 2 + sub ecx, 131072 + jc short mendhline +mbeghline: +mmach3d: lea ebx, [ebp+88888888h] ;bxinc +msh3d: shr ebp, 26 +msh4d: shld ebp, esi, 6 +mmach4d: add esi, 88888888h ;byinc +mmach1d: mov cl, byte ptr [ebp+88888888h] ;picoffs +mmach7d: lea ebp, [ebx+88888888h] ;bxinc + +msh5d: shr ebx, 26 +msh6d: shld ebx, esi, 6 +mmach8d: add esi, 88888888h ;byinc +mmach5d: mov ch, byte ptr [ebx+88888888h] ;picoffs + + cmp cl, 255 + je short mskip1 + cmp ch, 255 + je short mpreprebeghline + + mov al, cl ;BOTH +mmach2da: mov bl, byte ptr [eax+88888888h] ;shadeoffs + mov al, ch +mmach2db: mov bh, byte ptr [eax+88888888h] ;shadeoffs + mov word ptr [edi], bx + add edi, 2 + sub ecx, 131072 + jnc short mbeghline + jmp mendhline +mskip1: ;2nd only + cmp ch, 255 + je short mprebeghline + + mov al, ch +mmach6d: mov al, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi+1], al + add edi, 2 + sub ecx, 131072 + jnc short mbeghline +mendhline: + + pop ebp +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _tsethlineshift +_tsethlineshift: +CDECLBEGINSET 2 + neg al + mov byte ptr [tsh1d+2], al + mov byte ptr [tsh2d+3], bl + mov byte ptr [tsh3d+2], al + mov byte ptr [tsh4d+3], bl + mov byte ptr [tsh5d+2], al + mov byte ptr [tsh6d+3], bl +CDECLENDSET 2 + ret + +ALIGN 16 +PUBLIC _thline +_thline: +CDECLBEGINSET 6 + ;_asm1 = bxinc + ;_asm2 = byinc + ;_asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword ptr [tmach1d+2], eax + mov dword ptr [tmach5d+2], eax + mov dword ptr [tmach9d+2], eax + mov eax, _asm3 + mov dword ptr [tmach2d+2], eax + mov dword ptr [tmach6d+2], eax + mov dword ptr [tmach10d+2], eax + mov eax, _asm1 + mov dword ptr [tmach3d+2], eax + mov dword ptr [tmach7d+2], eax + mov eax, _asm2 + mov dword ptr [tmach4d+2], eax + mov dword ptr [tmach8d+2], eax + jmp short _thlineskipmodify_nosetup + +ALIGN 16 +PUBLIC _thlineskipmodify +_thlineskipmodify: +CDECLBEGINSET 6 +_thlineskipmodify_nosetup: + + push ebp + + xor eax, eax + xor edx, edx + mov ebp, ebx + + test ecx, 00010000h + jnz short tbeghline + +tsh1d: shr ebx, 26 +tsh2d: shld ebx, esi, 6 + add ebp, _asm1 +tmach9d: mov al, byte ptr [ebx+88888888h] ;picoffs + add esi, _asm2 + cmp al, 255 + je tskip5 + +transrev4: +tmach10d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev5: + mov dh, byte ptr [edi] +tmach1: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi], al +tskip5: + inc edi + sub ecx, 65536 + jc tendhline + jmp short tbeghline + +ALIGN 16 +tprebeghline: + add edi, 2 + sub ecx, 131072 + jc short tendhline +tbeghline: +tmach3d: lea ebx, [ebp+88888888h] ;bxinc +tsh3d: shr ebp, 26 +tsh4d: shld ebp, esi, 6 +tmach4d: add esi, 88888888h ;byinc +tmach1d: mov cl, byte ptr [ebp+88888888h] ;picoffs +tmach7d: lea ebp, [ebx+88888888h] ;bxinc + +tsh5d: shr ebx, 26 +tsh6d: shld ebx, esi, 6 +tmach8d: add esi, 88888888h ;byinc +tmach5d: mov ch, byte ptr [ebx+88888888h] ;picoffs + + cmp cx, 0ffffh + je short tprebeghline + + mov bx, word ptr [edi] + + cmp cl, 255 + je short tskip1 + mov al, cl +transrev6: +tmach2d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev7: + mov dh, bl +tmach2: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi], al + + cmp ch, 255 + je short tskip2 +tskip1: + mov al, ch +transrev8: +tmach6d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev9: + mov dh, bh +tmach3: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi+1], al +tskip2: + + add edi, 2 + sub ecx, 131072 + jnc tbeghline +tendhline: + + pop ebp +CDECLENDSET 6 + ret + + + ;eax=shiftval, ebx=palookup1, ecx=palookup2 +ALIGN 16 +PUBLIC _setuptvlineasm2 +_setuptvlineasm2: +CDECLBEGINSET 3 + mov byte ptr [tran2shra+2], al + mov byte ptr [tran2shrb+2], al + mov dword ptr [tran2pala+2], ebx + mov dword ptr [tran2palb+2], ecx + mov dword ptr [tran2palc+2], ebx + mov dword ptr [tran2pald+2], ecx +CDECLENDSET 3 + ret + + ;Pass: eax=vplc2, ebx=vinc1, ecx=bufplc1, edx=bufplc2, esi=vplc1, edi=p + ; _asm1=vinc2, _asm2=pend + ;Return: _asm1=vplc1, _asm2=vplc2 +ALIGN 16 +PUBLIC _tvlineasm2 +_tvlineasm2: +CDECLBEGINSET 6 + + push ebp + + mov ebp, eax + + mov dword ptr [tran2inca+2], ebx + mov eax, _asm1 + mov dword ptr [tran2incb+2], eax + + mov dword ptr [tran2bufa+2], ecx ;bufplc1 + mov dword ptr [tran2bufb+2], edx ;bufplc2 + + mov eax, _asm2 + sub edi, eax + mov dword ptr [tran2edia+3], eax + mov dword ptr [tran2edic+2], eax + inc eax + mov dword ptr [tran2edie+2], eax +fixchaint2a: sub eax, 320 + mov dword ptr [tran2edif+2], eax + dec eax + mov dword ptr [tran2edib+3], eax + mov dword ptr [tran2edid+2], eax + + xor ecx, ecx + xor edx, edx + jmp short begintvline2 + + ;eax 0000000000 temp temp + ;ebx 0000000000 odat2 odat1 + ;ecx 0000000000000000 ndat1 + ;edx 0000000000000000 ndat2 + ;esi vplc1 + ;edi videoplc-------------- + ;ebp vplc2 + +ALIGN 16 + ;LEFT ONLY +skipdraw2: +transrev10: +tran2edic: mov ah, byte ptr [edi+88888888h] ;getpixel +transrev11: +tran2palc: mov al, byte ptr [ecx+88888888h] ;palookup1 +fixchaint2d: add edi, 320 +tran2trac: mov bl, byte ptr [eax+88888888h] ;_transluc +tran2edid: mov byte ptr [edi+88888888h-320], bl ;drawpixel + jnc short begintvline2 + jmp endtvline2 + +skipdraw1: + cmp dl, 255 + jne short skipdraw3 +fixchaint2b: add edi, 320 + jc short endtvline2 + +begintvline2: + mov eax, esi +tran2shra: shr eax, 88h ;globalshift + mov ebx, ebp +tran2shrb: shr ebx, 88h ;globalshift +tran2inca: add esi, 88888888h ;vinc1 +tran2incb: add ebp, 88888888h ;vinc2 +tran2bufa: mov cl, byte ptr [eax+88888888h] ;bufplc1 + cmp cl, 255 +tran2bufb: mov dl, byte ptr [ebx+88888888h] ;bufplc2 + je short skipdraw1 + cmp dl, 255 + je short skipdraw2 + + ;mov ax The transluscent reverse of both! + ;mov bl, ah + ;mov ah + ;mov bh + + ;BOTH +transrev12: +tran2edia: mov bx, word ptr [edi+88888888h] ;getpixels +transrev13: + mov ah, bl +transrev14: +tran2pala: mov al, byte ptr [ecx+88888888h] ;palookup1 +transrev15: +tran2palb: mov bl, byte ptr [edx+88888888h] ;palookup2 +fixchaint2c: add edi, 320 +tran2traa: mov al, byte ptr [eax+88888888h] ;_transluc +tran2trab: mov ah, byte ptr [ebx+88888888h] ;_transluc +tran2edib: mov word ptr [edi+88888888h-320], ax ;drawpixels + jnc short begintvline2 + jmp short endtvline2 + + ;RIGHT ONLY +skipdraw3: +transrev16: +tran2edie: mov ah, byte ptr [edi+88888889h] ;getpixel +transrev17: +tran2pald: mov al, byte ptr [edx+88888888h] ;palookup2 +fixchaint2e: add edi, 320 +tran2trad: mov bl, byte ptr [eax+88888888h] ;_transluc +tran2edif: mov byte ptr [edi+88888889h-320], bl ;drawpixel + jnc short begintvline2 + +endtvline2: + mov _asm1, esi + mov _asm2, ebp + + pop ebp + +CDECLENDSET 6 + ret + + +BITSOFPRECISION equ 3 +BITSOFPRECISIONPOW equ 8 + +;Double-texture mapping with palette lookup +;eax: ylo1------------|----dat|----dat +;ebx: ylo2--------------------|----cnt +;ecx: 000000000000000000000000|---temp +;edx: xhi1-xlo1---------------|---yhi1 +;esi: xhi2-xlo2---------------|---yhi2 +;edi: ------------------------videopos +;ebp: ----------------------------temp + +ALIGN 16 +PUBLIC _setupslopevlin2 +_setupslopevlin2: +CDECLBEGINSET 6 + + mov dword ptr [slop3+2], edx ;ptr + mov dword ptr [slop7+2], edx ;ptr + mov dword ptr [slop4+2], esi ;tptr + mov dword ptr [slop8+2], esi ;tptr + mov byte ptr [slop2+2], ah ;ybits + mov byte ptr [slop6+2], ah ;ybits + mov dword ptr [slop9+2], edi ;pinc + + mov edx, 1 + mov cl, al + add cl, ah + shl edx, cl + dec edx + mov cl, ah + ror edx, cl + + mov dword ptr [slop1+2], edx ;ybits...xbits + mov dword ptr [slop5+2], edx ;ybits...xbits + +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _slopevlin2 +_slopevlin2: +CDECLBEGINSET 6 + + push ebp + xor ecx, ecx + +slopevlin2begin: + mov ebp, edx +slop1: and ebp, 88000088h ;ybits...xbits +slop2: rol ebp, 6 ;ybits + add eax, _asm1 ;xinc1<>(32-xbits)) +slop3: mov cl, byte ptr [ebp+88888888h] ;bufplc + + mov ebp, esi +slop4: mov al, byte ptr [ecx+88888888h] ;paloffs +slop5: and ebp, 88000088h ;ybits...xbits +slop6: rol ebp, 6 ;ybits + add ebx, _asm3 ;xinc2<>(32-xbits)) +slop8: mov ah, byte ptr [ecx+88888888h] ;paloffs + + dec bl + mov word ptr [edi], ax +slop9: lea edi, [edi+88888888h] ;pinc + jnz short slopevlin2begin + + pop ebp + mov eax, edi + +CDECLENDSET 6 + ret + + +ALIGN 16 +PUBLIC _setupslopevlin +_setupslopevlin: +CDECLBEGINSET 3 + + mov dword ptr [slopmach3+3], ebx ;ptr + mov dword ptr [slopmach5+2], ecx ;pinc + neg ecx + mov dword ptr [slopmach6+2], ecx ;-pinc + + mov edx, 1 + mov cl, al + shl edx, cl + dec edx + mov cl, ah + shl edx, cl + mov dword ptr [slopmach7+2], edx + + neg ah + mov byte ptr [slopmach2+2], ah + + sub ah, al + mov byte ptr [slopmach1+2], ah + + fild dword ptr _asm1 + fstp dword ptr _asm2 + +CDECLENDSET 3 + ret + +ALIGN 16 +PUBLIC _slopevlin +_slopevlin: +CDECLBEGINSET 6 + + mov _ebpbak, ebp + mov _espbak, esp + + sub ecx, esp + mov dword ptr [slopmach4+3], ecx + + fild dword ptr _asm3 +slopmach6: lea ebp, [eax+88888888h] + fadd dword ptr _asm2 + + mov _asm1, ebx + shl ebx, 3 + + mov eax, _globalx3 + mov ecx, _globaly3 + imul eax, ebx + imul ecx, ebx + add esi, eax + add edi, ecx + + mov ebx, edx + jmp short bigslopeloop +ALIGN 16 +bigslopeloop: + fst dword ptr _fpuasm + + mov eax, _fpuasm + add eax, eax + sbb edx, edx + mov ecx, eax + shr ecx, 24 + and eax, 00ffe000h + shr eax, 11 + sub cl, 2 + mov eax, dword ptr _reciptable[eax] + shr eax, cl + xor eax, edx + mov edx, _asm1 + mov ecx, _globalx3 + mov _asm1, eax + sub eax, edx + mov edx, _globaly3 + imul ecx, eax + imul eax, edx + + fadd dword ptr _asm2 + + cmp ebx, BITSOFPRECISIONPOW + mov _asm4, ebx + mov cl, bl + jl short slopeskipmin + mov cl, BITSOFPRECISIONPOW +slopeskipmin: + +;eax: yinc............. +;ebx: 0 0 0 ? +;ecx: xinc......... cnt +;edx: ? +;esi: xplc............. +;edi: yplc............. +;ebp: videopos + + mov ebx, esi + mov edx, edi + +beginnerslopeloop: +slopmach1: shr ebx, 20 + add esi, ecx +slopmach2: shr edx, 26 +slopmach7: and ebx, 88888888h + add edi, eax +slopmach5: add ebp, 88888888h ;pinc +slopmach3: mov dl, byte ptr [ebx+edx+88888888h] ;ptr +slopmach4: mov ebx, dword ptr [esp+88888888h] + sub esp, 4 + dec cl + mov al, byte ptr [ebx+edx] ;tptr + mov ebx, esi + mov [ebp], al + mov edx, edi + jnz short beginnerslopeloop + + mov ebx, _asm4 + sub ebx, BITSOFPRECISIONPOW + jg bigslopeloop + + ffree st(0) + + mov esp, _espbak + mov ebp, _ebpbak + +CDECLENDSET 6 + ret + + +ALIGN 16 +PUBLIC _setuprhlineasm4 +_setuprhlineasm4: +CDECLBEGINSET 6 + + mov dword ptr [rmach1a+2], eax + mov dword ptr [rmach1b+2], eax + mov dword ptr [rmach1c+2], eax + mov dword ptr [rmach1d+2], eax + mov dword ptr [rmach1e+2], eax + + mov dword ptr [rmach2a+2], ebx + mov dword ptr [rmach2b+2], ebx + mov dword ptr [rmach2c+2], ebx + mov dword ptr [rmach2d+2], ebx + mov dword ptr [rmach2e+2], ebx + + mov dword ptr [rmach3a+2], ecx + mov dword ptr [rmach3b+2], ecx + mov dword ptr [rmach3c+2], ecx + mov dword ptr [rmach3d+2], ecx + mov dword ptr [rmach3e+2], ecx + + mov dword ptr [rmach4a+2], edx + mov dword ptr [rmach4b+2], edx + mov dword ptr [rmach4c+2], edx + mov dword ptr [rmach4d+2], edx + mov dword ptr [rmach4e+2], edx + + mov dword ptr [rmach5a+2], esi + mov dword ptr [rmach5b+2], esi + mov dword ptr [rmach5c+2], esi + mov dword ptr [rmach5d+2], esi + mov dword ptr [rmach5e+2], esi + +CDECLENDSET 6 + ret + + ;Non power of 2, non masking, with palookup method #1 (6 clock cycles) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: xlo + ;esi: ylo + ;edi: videopos/cnt + ;ebp: tempvar + ;esp: +ALIGN 16 +PUBLIC _rhlineasm4 +_rhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle endrhline + + lea ebp, [edi-4] + sub ebp, eax + mov dword ptr [rmach6a+2], ebp + add ebp, 3 + mov dword ptr [rmach6b+2], ebp + mov edi, eax + test edi, 3 + jz short begrhline + jmp short startrhline1 + +ALIGN 16 +startrhline1: + mov cl, byte ptr [ebx] ;bufplc +rmach1e: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2e: sub esi, 88888888h ;ylo +rmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach4e: mov al, byte ptr [ecx+88888888h] ;palookup +rmach5e: and ebp, 88888888h ;tilesizy +rmach6b: mov byte ptr [edi+88888888h], al ;vidcntoffs + sub ebx, ebp + dec edi + test edi, 3 + jnz short startrhline1 + test edi, edi + jz endrhline + +begrhline: + mov cl, byte ptr [ebx] ;bufplc +rmach1a: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2a: sub esi, 88888888h ;ylo +rmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5a: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1b: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4a: mov ah, byte ptr [ecx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc +rmach2b: sub esi, 88888888h ;ylo +rmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5b: and ebp, 88888888h ;tilesizy +rmach4b: mov al, byte ptr [ecx+88888888h] ;palookup + sub ebx, ebp + + shl eax, 16 + + mov cl, byte ptr [ebx] ;bufplc +rmach1c: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2c: sub esi, 88888888h ;ylo +rmach3c: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5c: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1d: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4c: mov ah, byte ptr [ecx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc +rmach2d: sub esi, 88888888h ;ylo +rmach3d: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5d: and ebp, 88888888h ;tilesizy +rmach4d: mov al, byte ptr [ecx+88888888h] ;palookup + sub ebx, ebp + +rmach6a: mov dword ptr [edi+88888888h], eax ;vidcntoffs + sub edi, 4 + jnz begrhline +endrhline: + pop ebp + +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _setuprmhlineasm4 +_setuprmhlineasm4: +CDECLBEGINSET 6 + mov dword ptr [rmmach1+2], eax + mov dword ptr [rmmach2+2], ebx + mov dword ptr [rmmach3+2], ecx + mov dword ptr [rmmach4+2], edx + mov dword ptr [rmmach5+2], esi +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _rmhlineasm4 +_rmhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle short endrmhline + + lea ebp, [edi-1] + sub ebp, eax + mov dword ptr [rmmach6+2], ebp + mov edi, eax + jmp short begrmhline + +ALIGN 16 +begrmhline: + mov cl, byte ptr [ebx] ;bufplc +rmmach1: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmmach2: sub esi, 88888888h ;ylo +rmmach3: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmmach5: and ebp, 88888888h ;tilesizy + cmp cl, 255 + je short rmskip +rmmach4: mov al, byte ptr [ecx+88888888h] ;palookup +rmmach6: mov byte ptr [edi+88888888h], al ;vidcntoffs +rmskip: + sub ebx, ebp + dec edi + jnz short begrmhline +endrmhline: + pop ebp + +CDECLENDSET 6 + ret + +ALIGN 16 +PUBLIC _setupqrhlineasm4 +_setupqrhlineasm4: +CDECLBEGINSET 6 + + mov dword ptr [qrmach2e+2], ebx + mov dword ptr [qrmach3e+2], ecx + xor edi, edi + sub edi, ecx + mov dword ptr [qrmach7a+2], edi + mov dword ptr [qrmach7b+2], edi + + add ebx, ebx + adc ecx, ecx + mov dword ptr [qrmach2a+2], ebx + mov dword ptr [qrmach2b+2], ebx + mov dword ptr [qrmach3a+2], ecx + mov dword ptr [qrmach3b+2], ecx + + mov dword ptr [qrmach4a+2], edx + mov dword ptr [qrmach4b+2], edx + mov dword ptr [qrmach4c+2], edx + mov dword ptr [qrmach4d+2], edx + mov dword ptr [qrmach4e+2], edx + +CDECLENDSET 6 + ret + + ;Non power of 2, non masking, with palookup method (FASTER BUT NO SBB'S) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: 0 dat + ;esi: ylo + ;edi: videopos/cnt + ;ebp: ? + ;esp: +ALIGN 16 +PUBLIC _qrhlineasm4 ;4 pixels in 9 cycles! 2.25 cycles/pixel +_qrhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle endqrhline + + mov ebp, eax + test ebp, 3 + jz short skipqrhline1 + jmp short startqrhline1 + +ALIGN 16 +startqrhline1: + mov cl, byte ptr [ebx] ;bufplc + dec edi +qrmach2e: sub esi, 88888888h ;ylo + dec ebp +qrmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4e: mov al, byte ptr [ecx+88888888h] ;palookup + mov byte ptr [edi], al ;vidcntoffs + test ebp, 3 + jnz short startqrhline1 + test ebp, ebp + jz short endqrhline + +skipqrhline1: + mov cl, byte ptr [ebx] ;bufplc + jmp short begqrhline +ALIGN 16 +begqrhline: +qrmach7a: mov dl, byte ptr [ebx+88888888h] ;bufplc +qrmach2a: sub esi, 88888888h ;ylo +qrmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4a: mov ah, byte ptr [ecx+88888888h] ;palookup +qrmach4b: mov al, byte ptr [edx+88888888h] ;palookup + sub edi, 4 + shl eax, 16 + mov cl, byte ptr [ebx] ;bufplc +qrmach7b: mov dl, byte ptr [ebx+88888888h] ;bufplc +qrmach2b: sub esi, 88888888h ;ylo +qrmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4c: mov ah, byte ptr [ecx+88888888h] ;palookup +qrmach4d: mov al, byte ptr [edx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc + mov dword ptr [edi], eax + sub ebp, 4 + jnz short begqrhline + +endqrhline: + pop ebp + +CDECLENDSET 6 + ret + + +PUBLIC _setupdrawslab +_setupdrawslab: +CDECLBEGINSET 2 + + mov dword ptr [voxbpl1+2], eax + mov dword ptr [voxbpl2+2], eax + mov dword ptr [voxbpl3+2], eax + mov dword ptr [voxbpl4+2], eax + mov dword ptr [voxbpl5+2], eax + mov dword ptr [voxbpl6+2], eax + mov dword ptr [voxbpl7+2], eax + mov dword ptr [voxbpl8+2], eax + + mov dword ptr [voxpal1+2], ebx + mov dword ptr [voxpal2+2], ebx + mov dword ptr [voxpal3+2], ebx + mov dword ptr [voxpal4+2], ebx + mov dword ptr [voxpal5+2], ebx + mov dword ptr [voxpal6+2], ebx + mov dword ptr [voxpal7+2], ebx + mov dword ptr [voxpal8+2], ebx + +CDECLENDSET 2 + ret + +ALIGN 16 +PUBLIC _drawslab +_drawslab: +CDECLBEGINSET 6 + + push ebp + cmp eax, 2 + je voxbegdraw2 + ja voxskip2 + xor eax, eax +voxbegdraw1: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + dec ecx + mov al, byte ptr [esi+ebp] +voxpal1: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl1: lea edi, [edi+88888888h] + jnz voxbegdraw1 + pop ebp + +CDECLENDSET 6 + ret + +voxbegdraw2: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + xor eax, eax + dec ecx + mov al, byte ptr [esi+ebp] +voxpal2: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl2: lea edi, [edi+88888888h] + jnz voxbegdraw2 + pop ebp + +CDECLENDSET 6 + ret + +voxskip2: + cmp eax, 4 + jne voxskip4 + xor eax, eax +voxbegdraw4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal3: mov al, byte ptr [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword ptr [edi], eax +voxbpl3: add edi, 88888888h + dec ecx + jnz voxbegdraw4 + pop ebp + +CDECLENDSET 6 + ret + +voxskip4: + add eax, edi + + test edi, 1 + jz voxskipslab1 + cmp edi, eax + je voxskipslab1 + + push eax + push ebx + push ecx + push edi +voxbegslab1: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal4: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl4: add edi, 88888888h + dec ecx + jnz voxbegslab1 + pop edi + pop ecx + pop ebx + pop eax + inc edi + +voxskipslab1: + push eax + test edi, 2 + jz voxskipslab2 + dec eax + cmp edi, eax + jge voxskipslab2 + + push ebx + push ecx + push edi +voxbegslab2: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal5: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl5: add edi, 88888888h + dec ecx + jnz voxbegslab2 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab2: + mov eax, [esp] + + sub eax, 3 + cmp edi, eax + jge voxskipslab3 + +voxprebegslab3: + push ebx + push ecx + push edi +voxbegslab3: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal6: mov al, byte ptr [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword ptr [edi], eax +voxbpl6: add edi, 88888888h + dec ecx + jnz voxbegslab3 + pop edi + pop ecx + pop ebx + add edi, 4 + + mov eax, [esp] + + sub eax, 3 + cmp edi, eax + jl voxprebegslab3 + +voxskipslab3: + mov eax, [esp] + + dec eax + cmp edi, eax + jge voxskipslab4 + + push ebx + push ecx + push edi +voxbegslab4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal7: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl7: add edi, 88888888h + dec ecx + jnz voxbegslab4 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab4: + pop eax + + cmp edi, eax + je voxskipslab5 + +voxbegslab5: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal8: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl8: add edi, 88888888h + dec ecx + jnz voxbegslab5 + +voxskipslab5: + pop ebp + +CDECLENDSET 6 + ret + +;modify: loinc +;eax: | dat | dat | dat | dat | +;ebx: | loplc1 | +;ecx: | loplc2 | cnthi | cntlo | +;edx: |--------|--------|--------| hiplc1 | +;esi: |--------|--------|--------| hiplc2 | +;edi: |--------|--------|--------| vidplc | +;ebp: |--------|--------|--------| hiinc | + +PUBLIC _stretchhline +_stretchhline: +CDECLBEGINSET 6 + + push ebp + + mov eax, ebx + shl ebx, 16 + sar eax, 16 + and ecx, 0000ffffh + or ecx, ebx + + add esi, eax + mov eax, edx + mov edx, esi + + mov ebp, eax + shl eax, 16 + sar ebp, 16 + + add ecx, eax + adc esi, ebp + + add eax, eax + adc ebp, ebp + mov dword ptr [loinc1+2], eax + mov dword ptr [loinc2+2], eax + mov dword ptr [loinc3+2], eax + mov dword ptr [loinc4+2], eax + + inc ch + + jmp begloop + +begloop: + mov al, [edx] +loinc1: sub ebx, 88888888h + sbb edx, ebp + mov ah, [esi] +loinc2: sub ecx, 88888888h + sbb esi, ebp + sub edi, 4 + shl eax, 16 +loinc3: sub ebx, 88888888h + mov al, [edx] + sbb edx, ebp + mov ah, [esi] +loinc4: sub ecx, 88888888h + sbb esi, ebp + mov [edi], eax + dec cl + jnz begloop + dec ch + jnz begloop + + pop ebp + +CDECLENDSET 6 + ret + + +PUBLIC _mmxoverlay +_mmxoverlay: + push ebx ;JBF + push ecx ;JBF + push edx ;JBF + + pushfd ;Check if CPUID is available + pop eax + mov ebx, eax + xor eax, 00200000h + push eax + popfd + pushfd + pop eax + cmp eax, ebx + je pentium + xor eax, eax + dw 0a20fh + test eax, eax + jz pentium + mov eax, 1 + dw 0a20fh + and eax, 00000f00h + test edx, 00800000h ;Check if MMX is available + jz nommx + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumii + jmp pentiummmx +nommx: + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumpro +pentium: + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM II Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumii: + ;Hline overlay (MMX doens't help) + mov byte ptr [_sethlinesizes], 0e9h + mov dword ptr [_sethlinesizes+1], (offset _prosethlinesizes)-(offset _sethlinesizes)-5 + mov byte ptr [_setpalookupaddress], 0e9h + mov dword ptr [_setpalookupaddress+1], (offset _prosetpalookupaddress)-(offset _setpalookupaddress)-5 + mov byte ptr [_setuphlineasm4], 0c3h ;ret (no code required) + mov byte ptr [_hlineasm4], 0e9h + mov dword ptr [_hlineasm4+1], (offset _prohlineasm4)-(offset _hlineasm4)-5 + + ;Vline overlay + mov byte ptr [_setupvlineasm], 0e9h + mov dword ptr [_setupvlineasm+1], (offset _prosetupvlineasm)-(offset _setupvlineasm)-5 + mov byte ptr [_vlineasm4], 0e9h + mov dword ptr [_vlineasm4+1], (offset _provlineasm4)-(offset _vlineasm4)-5 + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM MMX Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiummmx: + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM PRO Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumpro: + ;Hline overlay (MMX doens't help) + mov byte ptr [_sethlinesizes], 0e9h + mov dword ptr [_sethlinesizes+1], (offset _prosethlinesizes)-(offset _sethlinesizes)-5 + mov byte ptr [_setpalookupaddress], 0e9h + mov dword ptr [_setpalookupaddress+1], (offset _prosetpalookupaddress)-(offset _setpalookupaddress)-5 + mov byte ptr [_setuphlineasm4], 0c3h ;ret (no code required) + mov byte ptr [_hlineasm4], 0e9h + mov dword ptr [_hlineasm4+1], (offset _prohlineasm4)-(offset _hlineasm4)-5 + + ;Vline overlay + mov byte ptr [_setupvlineasm], 0e9h + mov dword ptr [_setupvlineasm+1], (offset _prosetupvlineasm)-(offset _setupvlineasm)-5 + mov byte ptr [_vlineasm4], 0e9h + mov dword ptr [_vlineasm4+1], (offset _provlineasm4)-(offset _vlineasm4)-5 + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +CODE ENDS +END diff --git a/polymer/build/src/a.nasm b/polymer/build/src/a.nasm new file mode 100644 index 000000000..9ac5dbb21 --- /dev/null +++ b/polymer/build/src/a.nasm @@ -0,0 +1,2751 @@ +; "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +; Ken Silverman's official web site: "http://www.advsys.net/ken" +; See the included license file "BUILDLIC.TXT" for license info. +; +; This file has been modified from Ken Silverman's original release +; by Jonathon Fowler (jonof@edgenetwk.com) + +;CPU 586 + +SECTION .data + +%ifdef UNDERSCORES +%define asm1 _asm1 +%define asm2 _asm2 +%define asm3 _asm3 +%define asm4 _asm4 +%define reciptable _reciptable +%define fpuasm _fpuasm +%define globalx3 _globalx3 +%define globaly3 _globaly3 +%define ylookup _ylookup +%define vplce _vplce +%define vince _vince +%define palookupoffse _palookupoffse +%define bufplce _bufplce +%define ebpbak _ebpbak +%define espbak _espbak +%define pow2char _pow2char +%define pow2long _pow2long + +%define sethlinesizes _sethlinesizes +%define prosethlinesizes _prosethlinesizes +%define setvlinebpl _setvlinebpl +%define setpalookupaddress _setpalookupaddress +%define prosetpalookupaddress _prosetpalookupaddress +%define setuphlineasm4 _setuphlineasm4 +%define hlineasm4 _hlineasm4 +%define prohlineasm4 _prohlineasm4 +%define prosetuphlineasm4 _prosetupvlineasm +%define setupmvlineasm _setupmvlineasm +%define setuptvlineasm _setuptvlineasm +%define prevlineasm1 _prevlineasm1 +%define vlineasm1 _vlineasm1 +%define mvlineasm1 _mvlineasm1 +%define fixtransluscence _fixtransluscence +%define settransnormal _settransnormal +%define settransreverse _settransreverse +%define tvlineasm1 _tvlineasm1 +%define vlineasm4 _vlineasm4 +%define provlineasm4 _provlineasm4 +%define setupvlineasm _setupvlineasm +%define mvlineasm4 _mvlineasm4 +%define setupspritevline _setupspritevline +%define spritevline _spritevline +%define msetupspritevline _msetupspritevline +%define mspritevline _mspritevline +%define tsetupspritevline _tsetupspritevline +%define tspritevline _tspritevline +%define msethlineshift _msethlineshift +%define mhline _mhline +%define mhlineskipmodify _mhlineskipmodify +%define tsethlineshift _tsethlineshift +%define thline _thline +%define thlineskipmodify _thlineskipmodify +%define setuptvlineasm2 _setuptvlineasm2 +%define tvlineasm2 _tvlineasm2 +%define setupslopevlin2 _setupslopevlin2 +%define slopevlin2 _slopevlin2 +%define setupslopevlin _setupslopevlin +%define slopevlin _slopevlin +%define setuprhlineasm4 _setuprhlineasm4 +%define rhlineasm4 _rhlineasm4 +%define setuprmhlineasm4 _setuprmhlineasm4 +%define rmhlineasm4 _rmhlineasm4 +%define setupqrhlineasm4 _setupqrhlineasm4 +%define qrhlineasm4 _qrhlineasm4 +%define setupdrawslab _setupdrawslab +%define drawslab _drawslab +%define stretchhline _stretchhline +%define mmxoverlay _mmxoverlay + +%endif + +; Some macros to help make cdecl calling easier to manage +%macro CDECLBEGIN 1 +%if %1 >= 2 + push ebx +%endif +%if %1 >= 3 + push ecx +%endif +%if %1 >= 4 + push edx +%endif +%if %1 >= 5 + push esi +%endif +%if %1 >= 6 + push edi +%endif +%endmacro + +%macro CDECLEND 1 +%if %1 >= 6 + pop edi +%endif +%if %1 >= 5 + pop esi +%endif +%if %1 >= 4 + pop edx +%endif +%if %1 >= 3 + pop ecx +%endif +%if %1 >= 2 + pop ebx +%endif +%endmacro + +%macro CDECLPARAM 3 +; mov %1, dword [esp + (%2*4+16)] + mov %1, dword [esp + ((%2+%3)*4+4)] +%endmacro + +%macro CDECLBEGINSET 1 + CDECLBEGIN %1 + +%assign _offsetted %1-1 + +%if %1 >= 1 + CDECLPARAM eax,0,_offsetted +%endif +%if %1 >= 2 + CDECLPARAM ebx,1,_offsetted +%endif +%if %1 >= 3 + CDECLPARAM ecx,2,_offsetted +%endif +%if %1 >= 4 + CDECLPARAM edx,3,_offsetted +%endif +%if %1 >= 5 + CDECLPARAM esi,4,_offsetted +%endif +%if %1 >= 6 + CDECLPARAM edi,5,_offsetted +%endif +%endmacro + +%macro CDECLENDSET 1 + CDECLEND %1 +%endmacro + + + EXTERN asm1 + EXTERN asm2 + EXTERN asm3 + EXTERN asm4 + EXTERN reciptable + EXTERN fpuasm + EXTERN globalx3 + EXTERN globaly3 + EXTERN ylookup + + EXTERN vplce + EXTERN vince + EXTERN palookupoffse + EXTERN bufplce + + EXTERN ebpbak + EXTERN espbak + + EXTERN pow2char + EXTERN pow2long + + GLOBAL sethlinesizes + GLOBAL prosethlinesizes + GLOBAL setvlinebpl + GLOBAL setpalookupaddress + GLOBAL prosetpalookupaddress + GLOBAL setuphlineasm4 + GLOBAL hlineasm4 + GLOBAL prohlineasm4 + GLOBAL prosetupvlineasm + GLOBAL setupmvlineasm + GLOBAL setuptvlineasm + GLOBAL prevlineasm1 + GLOBAL vlineasm1 + GLOBAL mvlineasm1 ;Masked vline + GLOBAL fixtransluscence + GLOBAL settransnormal + GLOBAL settransreverse + GLOBAL tvlineasm1 ;Masked & transluscent vline + GLOBAL vlineasm4 + GLOBAL provlineasm4 + GLOBAL setupvlineasm + GLOBAL mvlineasm4 + GLOBAL setupspritevline + GLOBAL spritevline + GLOBAL msetupspritevline + GLOBAL mspritevline + GLOBAL tsetupspritevline + GLOBAL tspritevline + GLOBAL msethlineshift + GLOBAL mhline + GLOBAL mhlineskipmodify + GLOBAL tsethlineshift + GLOBAL thline + GLOBAL thlineskipmodify + GLOBAL setuptvlineasm2 + GLOBAL tvlineasm2 + GLOBAL setupslopevlin2 + GLOBAL slopevlin2 + GLOBAL setupslopevlin + GLOBAL slopevlin + GLOBAL setuprhlineasm4 + GLOBAL rhlineasm4 + GLOBAL setuprmhlineasm4 + GLOBAL rmhlineasm4 + GLOBAL setupqrhlineasm4 + GLOBAL qrhlineasm4 ;4 pixels in 9 cycles! 2.25 cycles/pixel + GLOBAL setupdrawslab + GLOBAL drawslab + GLOBAL stretchhline + GLOBAL mmxoverlay + + + ALIGN 16 +sethlinesizes: +CDECLBEGINSET 3 + + mov byte [machxbits1+2], al + mov byte [machxbits2+2], al + mov byte [machxbits3+2], al + neg al + mov byte [hxsiz1+2], al + mov byte [hxsiz2+2], al + mov byte [hxsiz3+2], al + mov byte [hxsiz4+2], al + mov byte [machnegxbits1+2], al + + mov byte [hysiz1+3], bl + mov byte [hysiz2+3], bl + mov byte [hysiz3+3], bl + mov byte [hysiz4+3], bl + mov byte [hmach3a+2], bl + mov byte [hmach3b+2], bl + mov byte [hmach3c+2], bl + mov byte [hmach3d+2], bl + + mov dword [hoffs1+2], ecx + mov dword [hoffs2+2], ecx + mov dword [hoffs3+2], ecx + mov dword [hoffs4+2], ecx + mov dword [hoffs5+2], ecx + mov dword [hoffs6+2], ecx + mov dword [hoffs7+2], ecx + mov dword [hoffs8+2], ecx + + push edx ;JBF + mov edx, -1 + mov cl, al + sub cl, bl + shr edx, cl + mov dword [hmach2a+1], edx + mov dword [hmach2b+1], edx + mov dword [hmach2c+1], edx + mov dword [hmach2d+1], edx + pop edx ;JBF + +CDECLENDSET 3 + ret + + + ALIGN 16 +prosethlinesizes: +CDECLBEGINSET 3 + + mov dword [prohbuf-4], ecx + neg eax + mov ecx, eax + sub eax, ebx + mov byte [prohshru-1], al ;bl = 32-al-bl + mov eax, -1 + shr eax, cl + mov ecx, ebx + shl eax, cl + mov dword [prohand-4], eax ;((-1>>(-oal))<>(32-xbits) adc al, 88h 1 1/2 + ;bufplc mov cl, byte [edx+88888888h] 1 1/2 + ;paloffs&255 mov bl, byte [ecx+88888888h] 1 1/2 + ALIGN 16 +hlineasm4: +CDECLBEGINSET 6 + + push ebp + + lea ebp, [eax+1] + + cmp ebp, 8 + jle near shorthline + + test edi, 1 + jnz short skipthe1byte + + mov eax, esi +hxsiz1: shr eax, 26 +hysiz1: shld eax, edx, 6 +hoffs1: mov cl, byte [eax+88888888h] +pal1: mov bl, byte [ecx+88888888h] + sub esi, dword [asm1] + sub edx, dword [asm2] + mov byte [edi], bl + dec edi + dec ebp + +skipthe1byte: + test edi, 2 + jnz short skipthe2byte + + mov eax, esi +hxsiz2: shr eax, 26 +hysiz2: shld eax, edx, 6 +hoffs2: mov cl, byte [eax+88888888h] +pal2: mov bh, byte [ecx+88888888h] + sub esi, dword [asm1] + sub edx, dword [asm2] + + mov eax, esi +hxsiz3: shr eax, 26 +hysiz3: shld eax, edx, 6 +hoffs3: mov cl, byte [eax+88888888h] +pal3: mov bl, byte [ecx+88888888h] + sub esi, dword [asm1] + sub edx, dword [asm2] + mov word [edi-1], bx + sub edi, 2 + sub ebp, 2 + +skipthe2byte: + + mov eax, esi +machxbits1: shl esi, 6 ;xbits +machnegxbits1: shr eax, 32-6 ;32-xbits + mov dl, al + + inc edi + + add ebx, ebx + mov eax, edx + jc beginhline64 + + mov eax, dword [asm1] +machxbits2: rol eax, 6 ;xbits + mov dword [hmach4a+2], eax + mov dword [hmach4b+2], eax + mov dword [hmach4c+2], eax + mov dword [hmach4d+2], eax + mov ebx, eax + mov eax, dword [asm2] + mov al, bl + mov dword [hmach1a+2], eax + mov dword [hmach1b+2], eax + mov dword [hmach1c+2], eax + mov dword [hmach1d+2], eax + + mov eax, edx + jmp beginhline64 +ALIGN 16 +prebeginhline64: + mov dword [edi], ebx +beginhline64: + +hmach3a: rol eax, 6 +hmach2a: and eax, 00008888h +hmach4a: sub esi, 88888888h +hmach1a: sbb edx, 88888888h + sub edi, 4 +hoffs4: mov cl, byte [eax+88888888h] + mov eax, edx + +hmach3b: rol eax, 6 +hmach2b: and eax, 00008888h +hmach4b: sub esi, 88888888h +hmach1b: sbb edx, 88888888h +pal4: mov bh, byte [ecx+88888888h] +hoffs5: mov cl, byte [eax+88888888h] + mov eax, edx + +hmach3c: rol eax, 6 +pal5: mov bl, byte [ecx+88888888h] +hmach2c: and eax, 00008888h + shl ebx, 16 +hmach4c: sub esi, 88888888h +hmach1c: sbb edx, 88888888h +hoffs6: mov cl, byte [eax+88888888h] + + mov eax, edx + ;( + +hmach3d: rol eax, 6 +hmach2d: and eax, 00008888h +hmach4d: sub esi, 88888888h +hmach1d: sbb edx, 88888888h +pal6: mov bh, byte [ecx+88888888h] +hoffs7: mov cl, byte [eax+88888888h] + mov eax, edx + sub ebp, 4 + nop +pal7: mov bl, byte [ecx+88888888h] + jnc near prebeginhline64 +skipthe4byte: + + test ebp, 2 + jz skipdrawthe2 + rol ebx, 16 + mov word [edi+2], bx + sub edi, 2 +skipdrawthe2: + test ebp, 1 + jz skipdrawthe1 + shr ebx, 24 + mov byte [edi+3], bl +skipdrawthe1: + + pop ebp +CDECLENDSET 6 + ret + +shorthline: + test ebp, ebp + jz endshorthline +begshorthline: + mov eax, esi +hxsiz4: shr eax, 26 +hysiz4: shld eax, edx, 6 +hoffs8: mov cl, byte [eax+88888888h] +pal8: mov bl, byte [ecx+88888888h] + sub esi, dword [asm1] + sub edx, dword [asm2] + mov byte [edi], bl + dec edi + dec ebp + jnz near begshorthline +endshorthline: + pop ebp +CDECLENDSET 6 + ret + + + ;eax: 00000000 00000000 00000000 temp---- + ;ebx: 00000000 00000000 00000000 temp---- + ;ecx: UUUUUUuu uuuuuuuu uuuuuuuu uuuuuuuu + ;edx: VVVVVVvv vvvvvvvv vvvvvvvv vvvvvvvv + ;esi: cnt----- -------- -------- -------- + ;edi: vid----- -------- -------- -------- + ;ebp: paloffs- -------- -------- -------- + ;esp: ???????? ???????? ???????? ???????? + ALIGN 16 +prohlineasm4: +CDECLBEGINSET 6 + + push ebp + + lea ebp, [ecx+88888888h] +prohpala: + mov ecx, esi + lea esi, [eax+1] + sub edi, esi + +prohbeg: + mov eax, ecx + shr eax, 20 +prohshru: + mov ebx, edx + shr ebx, 26 +prohshrv: + and eax, 88888888h +prohand: + movzx eax, byte [eax+ebx+88888888h] +prohbuf: + mov al, [eax+ebp] + sub ecx, dword [asm1] + sub edx, dword [asm2] + mov [edi+esi], al + dec esi + jnz prohbeg + + pop ebp +CDECLENDSET 6 + ret + + + + ALIGN 16 +setupvlineasm: +CDECLBEGINSET 1 + ;First 2 lines for VLINEASM1, rest for VLINEASM4 + mov byte [premach3a+2], al + mov byte [mach3a+2], al + + push ecx + mov byte [machvsh1+2], al ;32-shy + mov byte [machvsh3+2], al ;32-shy + mov byte [machvsh5+2], al ;32-shy + mov byte [machvsh6+2], al ;32-shy + mov ah, al + sub ah, 16 + mov byte [machvsh8+2], ah ;16-shy + neg al + mov byte [machvsh7+2], al ;shy + mov byte [machvsh9+2], al ;shy + mov byte [machvsh10+2], al ;shy + mov byte [machvsh11+2], al ;shy + mov byte [machvsh12+2], al ;shy + mov cl, al + mov eax, 1 + shl eax, cl + dec eax + mov dword [machvsh2+2], eax ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +machvsh5: shl esi, 88h ;32-sh + mov eax, edx +machvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +machvsh7: shr eax, 88h ;sh + add esi, eax +machvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword [vplce+12], esi + mov dword [vplce+4], ebp + + pop ebp +CDECLEND 6 + ret + + ;eax: -------temp1------- + ;ebx: -------temp2------- + ;ecx: ylo4 --------- + ;edx: ylo2 --------- + ;esi: yhi1 yhi2 + ;edi: ---videoplc/cnt---- + ;ebp: yhi3 yhi4 + ;esp: + ALIGN 16 +provlineasm4: +CDECLBEGIN 6 +CDECLPARAM ecx,0,5 +CDECLPARAM edi,1,5 + push ebp + + mov eax, dword [ylookup+ecx*4] + add eax, edi + mov dword [promachvline4end1+2], eax + inc eax + mov dword [promachvline4end2+2], eax + inc eax + mov dword [promachvline4end3+2], eax + inc eax + mov dword [promachvline4end4+2], eax + sub eax, 3 + sub edi, eax + + mov eax, dword [bufplce] + mov ebx, dword [bufplce+4] + mov ecx, dword [bufplce+8] + mov edx, dword [bufplce+12] + mov dword [promachvbuf1+3], ecx + mov dword [promachvbuf2+3], edx + mov dword [promachvbuf3+3], eax + mov dword [promachvbuf4+3], ebx + + mov eax, dword [palookupoffse] + mov ebx, dword [palookupoffse+4] + mov ecx, dword [palookupoffse+8] + mov edx, dword [palookupoffse+12] + mov dword [promachvpal1+2], ecx + mov dword [promachvpal2+2], edx + mov dword [promachvpal3+2], eax + mov dword [promachvpal4+2], ebx + + ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ;edx: ³v3lo ³v1lo ³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ´ + ;esi: ³v2hi v2lo ³ v3hi³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´ + ;ebp: ³v0hi v0lo ³ v1hi³ + ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ + + mov ebp, dword [vince] + mov ebx, dword [vince+4] + mov esi, dword [vince+8] + mov eax, dword [vince+12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh9: rol eax, 88h ;sh +promachvsh10: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + ; + mov eax, edx + and eax, 0ffff0000h + mov dword [promachvinc1+2], eax + mov dword [promachvinc2+2], esi + shl edx, 16 + mov dword [promachvinc3+2], edx + mov dword [promachvinc5+2], ebp + + mov ebp, dword [vplce] + mov ebx, dword [vplce+4] + mov esi, dword [vplce+8] + mov eax, dword [vplce+12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh11: rol eax, 88h ;sh +promachvsh12: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + + mov eax, esi + mov ecx, edx + shl ecx, 16 + jmp short probeginvlineasm4 +ALIGN 16 + nop + nop + nop +probeginvlineasm4: +promachvsh1: shr eax, 88h ;32-sh + mov ebx, esi +promachvsh2: and ebx, 00000088h ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +promachvsh5: shl esi, 88h ;32-sh + mov eax, edx +promachvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +promachvsh7: shr eax, 88h ;sh + add esi, eax +promachvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword [vplce+12], esi + mov dword [vplce+4], ebp + + pop ebp +CDECLEND 6 + ret + + + ALIGN 16 +mvlineasm4: +CDECLBEGIN 6 +CDECLPARAM ecx,0,5 +CDECLPARAM edi,1,5 + + push ebp + + mov eax, dword [bufplce] + mov ebx, dword [bufplce+4] + mov dword [machmv1+2], eax + mov dword [machmv4+2], ebx + mov eax, dword [bufplce+8] + mov ebx, dword [bufplce+12] + mov dword [machmv7+2], eax + mov dword [machmv10+2], ebx + + mov eax, dword [palookupoffse] + mov ebx, dword [palookupoffse+4] + mov dword [machmv2+2], eax + mov dword [machmv5+2], ebx + mov eax, dword [palookupoffse+8] + mov ebx, dword [palookupoffse+12] + mov dword [machmv8+2], eax + mov dword [machmv11+2], ebx + + mov eax, dword [vince] + mov ebx, dword [vince+4] + xor al, al + xor bl, bl + mov dword [machmv3+2], eax + mov dword [machmv6+2], ebx + mov eax, dword [vince+8] + mov ebx, dword [vince+12] + mov dword [machmv9+2], eax + mov dword [machmv12+2], ebx + + mov ebx, ecx + mov ecx, dword [vplce] + mov edx, dword [vplce+4] + mov esi, dword [vplce+8] + mov ebp, dword [vplce+12] + mov cl, bl + inc cl + inc bh + mov byte [asm3], bh +fixchain2ma: sub edi, 320 + + jmp short beginmvlineasm4 +ALIGN 16 +beginmvlineasm4: + dec cl + jz near endmvlineasm4 +beginmvlineasm42: + mov eax, ebp + mov ebx, esi +machmv16: shr eax, 32 +machmv15: shr ebx, 32 +machmv12: add ebp, 88888888h ;vince[3] +machmv9: add esi, 88888888h ;vince[2] +machmv10: mov al, byte [eax+88888888h] ;bufplce[3] +machmv7: mov bl, byte [ebx+88888888h] ;bufplce[2] + cmp al, 255 + adc dl, dl + cmp bl, 255 + adc dl, dl +machmv8: mov bl, byte [ebx+88888888h] ;palookupoffs[2] +machmv11: mov bh, byte [eax+88888888h] ;palookupoffs[3] + + mov eax, edx +machmv14: shr eax, 32 + shl ebx, 16 +machmv4: mov al, byte [eax+88888888h] ;bufplce[1] + cmp al, 255 + adc dl, dl +machmv6: add edx, 88888888h ;vince[1] +machmv5: mov bh, byte [eax+88888888h] ;palookupoffs[1] + + mov eax, ecx +machmv13: shr eax, 32 +machmv3: add ecx, 88888888h ;vince[0] +machmv1: mov al, byte [eax+88888888h] ;bufplce[0] + cmp al, 255 + adc dl, dl +machmv2: mov bl, byte [eax+88888888h] ;palookupoffs[0] + + shl dl, 4 + xor eax, eax +fixchain2mb: add edi, 320 + mov al, dl + add eax, mvcase0 + jmp eax ;16 byte cases + +ALIGN 16 +endmvlineasm4: + dec byte [asm3] + jnz near beginmvlineasm42 ;near + + mov dword [vplce], ecx + mov dword [vplce+4], edx + mov dword [vplce+8], esi + mov dword [vplce+12], ebp + pop ebp +CDECLEND 6 + ret + + ;5,7,8,8,11,13,12,14,11,13,14,14,12,14,15,7 +ALIGN 16 +mvcase0: + jmp beginmvlineasm4 +ALIGN 16 +mvcase1: + mov byte [edi], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase2: + mov byte [edi+1], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase3: + mov word [edi], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase4: + shr ebx, 16 + mov byte [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase5: + mov byte [edi], bl + shr ebx, 16 + mov byte [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 + mvcase6: + shr ebx, 8 + mov word [edi+1], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase7: + mov word [edi], bx + shr ebx, 16 + mov byte [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase8: + shr ebx, 16 + mov byte [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase9: + mov byte [edi], bl + shr ebx, 16 + mov byte [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase10: + mov byte [edi+1], bh + shr ebx, 16 + mov byte [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase11: + mov word [edi], bx + shr ebx, 16 + mov byte [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase12: + shr ebx, 16 + mov word [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase13: + mov byte [edi], bl + shr ebx, 16 + mov word [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase14: + mov byte [edi+1], bh + shr ebx, 16 + mov word [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase15: + mov dword [edi], ebx + jmp beginmvlineasm4 + + + ALIGN 16 +setupspritevline: +CDECLBEGINSET 6 + + mov dword [spal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword [smach1+2], eax + mov dword [smach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword [smach2+2], eax + add eax, edx + mov dword [smach5+2], eax + + mov dword [smach3+2], ecx ;yinc's + +CDECLENDSET 6 + ret + + + ALIGN 16 +spritevline: +CDECLBEGINSET 6 + jmp short spritevline_start + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +prestartsvline: +smach1: add ebx, 88888888h ;xincshl16 + mov al, byte [esi] +smach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +startsvline: +spal: mov al, [eax+88888888h] ;palookup + mov byte [edi], al +fixchain1s: add edi, 320 + +spritevline_start: +smach3: add edx, 88888888h ;dayinc + dec ecx + ja short prestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short endsvline +smach4: add ebx, 88888888h ;xincshl16 + mov al, byte [esi] +smach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short startsvline +endsvline: +CDECLENDSET 6 + ret + + + ALIGN 16 +msetupspritevline: +CDECLBEGINSET 6 + + mov dword [mspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword [msmach1+2], eax + mov dword [msmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword [msmach2+2], eax + add eax, edx + mov dword [msmach5+2], eax + + mov dword [msmach3+2], ecx ;yinc's + +CDECLENDSET 6 + ret + + + ALIGN 16 +mspritevline: +CDECLBEGINSET 6 + jmp short mspritevline_start + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +mprestartsvline: +msmach1: add ebx, 88888888h ;xincshl16 + mov al, byte [esi] +msmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +mstartsvline: + cmp al, 255 + je short mskipsvline +mspal: mov al, [eax+88888888h] ;palookup + mov byte [edi], al +mskipsvline: +mfixchain1s: add edi, 320 + +mspritevline_start: +msmach3: add edx, 88888888h ;dayinc + dec ecx + ja short mprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short mendsvline +msmach4: add ebx, 88888888h ;xincshl16 + mov al, byte [esi] +msmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short mstartsvline +mendsvline: +CDECLENDSET 6 + ret + + + ALIGN 16 +tsetupspritevline: +CDECLBEGINSET 6 + mov dword [tspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword [tsmach1+2], eax + mov dword [tsmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword [tsmach2+2], eax + add eax, edx + mov dword [tsmach5+2], eax + + mov dword [tsmach3+2], ecx ;yinc's +CDECLENDSET 6 + ret + + + ALIGN 16 +tspritevline: +CDECLBEGINSET 6 + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p + push ebp + mov ebp, ebx + xor ebx, ebx + jmp tenterspritevline +ALIGN 16 +tprestartsvline: +tsmach1: add ebp, 88888888h ;xincshl16 + mov al, byte [esi] +tsmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +tstartsvline: + cmp al, 255 + je short tskipsvline +transrev2: + mov bh, byte [edi] +transrev3: +tspal: mov bl, [eax+88888888h] ;palookup +tmach4: mov al, byte [ebx+88888888h] ;_transluc + mov byte [edi], al +tskipsvline: +tfixchain1s: add edi, 320 + +tenterspritevline: +tsmach3: add edx, 88888888h ;dayinc + dec ecx + ja short tprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short tendsvline +tsmach4: add ebp, 88888888h ;xincshl16 + mov al, byte [esi] +tsmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short tstartsvline +tendsvline: + pop ebp +CDECLENDSET 6 + ret + + + ALIGN 16 +msethlineshift: +CDECLBEGINSET 2 + neg al + mov byte [msh1d+2], al + mov byte [msh2d+3], bl + mov byte [msh3d+2], al + mov byte [msh4d+3], bl + mov byte [msh5d+2], al + mov byte [msh6d+3], bl +CDECLENDSET 2 + ret + + + ALIGN 16 +mhline: +CDECLBEGINSET 6 + ;asm1 = bxinc + ;asm2 = byinc + ;asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword [mmach1d+2], eax + mov dword [mmach5d+2], eax + mov dword [mmach9d+2], eax + mov eax, dword [asm3] + mov dword [mmach2d+2], eax + mov dword [mmach2da+2], eax + mov dword [mmach2db+2], eax + mov dword [mmach6d+2], eax + mov dword [mmach10d+2], eax + mov eax, dword [asm1] + mov dword [mmach3d+2], eax + mov dword [mmach7d+2], eax + mov eax, dword [asm2] + mov dword [mmach4d+2], eax + mov dword [mmach8d+2], eax + jmp short mhlineskipmodify_nosetup + + + ALIGN 16 +mhlineskipmodify: +CDECLBEGINSET 6 +mhlineskipmodify_nosetup: + + push ebp + + xor eax, eax + mov ebp, ebx + + test ecx, 00010000h + jnz short mbeghline + +msh1d: shr ebx, 26 +msh2d: shld ebx, esi, 6 + add ebp, dword [asm1] +mmach9d: mov al, byte [ebx+88888888h] ;picoffs + add esi, dword [asm2] + cmp al, 255 + je mskip5 + +mmach10d: mov cl, byte [eax+88888888h] ;shadeoffs + mov byte [edi], cl +mskip5: + inc edi + sub ecx, 65536 + jc near mendhline + jmp short mbeghline + +ALIGN 16 +mpreprebeghline: ;1st only + mov al, cl +mmach2d: mov al, byte [eax+88888888h] ;shadeoffs + mov byte [edi], al + +mprebeghline: + add edi, 2 + sub ecx, 131072 + jc near mendhline +mbeghline: +mmach3d: lea ebx, [ebp+88888888h] ;bxinc +msh3d: shr ebp, 26 +msh4d: shld ebp, esi, 6 +mmach4d: add esi, 88888888h ;byinc +mmach1d: mov cl, byte [ebp+88888888h] ;picoffs +mmach7d: lea ebp, [ebx+88888888h] ;bxinc + +msh5d: shr ebx, 26 +msh6d: shld ebx, esi, 6 +mmach8d: add esi, 88888888h ;byinc +mmach5d: mov ch, byte [ebx+88888888h] ;picoffs + + cmp cl, 255 + je short mskip1 + cmp ch, 255 + je short mpreprebeghline + + mov al, cl ;BOTH +mmach2da: mov bl, byte [eax+88888888h] ;shadeoffs + mov al, ch +mmach2db: mov bh, byte [eax+88888888h] ;shadeoffs + mov word [edi], bx + add edi, 2 + sub ecx, 131072 + jnc short mbeghline + jmp mendhline +mskip1: ;2nd only + cmp ch, 255 + je short mprebeghline + + mov al, ch +mmach6d: mov al, byte [eax+88888888h] ;shadeoffs + mov byte [edi+1], al + add edi, 2 + sub ecx, 131072 + jnc short mbeghline +mendhline: + + pop ebp +CDECLENDSET 6 + ret + + + ALIGN 16 +tsethlineshift: +CDECLBEGINSET 2 + neg al + mov byte [tsh1d+2], al + mov byte [tsh2d+3], bl + mov byte [tsh3d+2], al + mov byte [tsh4d+3], bl + mov byte [tsh5d+2], al + mov byte [tsh6d+3], bl +CDECLENDSET 2 + ret + + + ALIGN 16 +thline: +CDECLBEGINSET 6 + ;asm1 = bxinc + ;asm2 = byinc + ;asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword [tmach1d+2], eax + mov dword [tmach5d+2], eax + mov dword [tmach9d+2], eax + mov eax, dword [asm3] + mov dword [tmach2d+2], eax + mov dword [tmach6d+2], eax + mov dword [tmach10d+2], eax + mov eax, dword [asm1] + mov dword [tmach3d+2], eax + mov dword [tmach7d+2], eax + mov eax, dword [asm2] + mov dword [tmach4d+2], eax + mov dword [tmach8d+2], eax + jmp thlineskipmodify_nosetup + + + ALIGN 16 +thlineskipmodify: +CDECLBEGINSET 6 +thlineskipmodify_nosetup: + + push ebp + + xor eax, eax + xor edx, edx + mov ebp, ebx + + test ecx, 00010000h + jnz short tbeghline + +tsh1d: shr ebx, 26 +tsh2d: shld ebx, esi, 6 + add ebp, dword [asm1] +tmach9d: mov al, byte [ebx+88888888h] ;picoffs + add esi, dword [asm2] + cmp al, 255 + je tskip5 + +transrev4: +tmach10d: mov dl, byte [eax+88888888h] ;shadeoffs +transrev5: + mov dh, byte [edi] +tmach1: mov al, byte [edx+88888888h] ;_transluc + mov byte [edi], al +tskip5: + inc edi + sub ecx, 65536 + jc near tendhline + jmp short tbeghline + +ALIGN 16 +tprebeghline: + add edi, 2 + sub ecx, 131072 + jc short tendhline +tbeghline: +tmach3d: lea ebx, [ebp+88888888h] ;bxinc +tsh3d: shr ebp, 26 +tsh4d: shld ebp, esi, 6 +tmach4d: add esi, 88888888h ;byinc +tmach1d: mov cl, byte [ebp+88888888h] ;picoffs +tmach7d: lea ebp, [ebx+88888888h] ;bxinc + +tsh5d: shr ebx, 26 +tsh6d: shld ebx, esi, 6 +tmach8d: add esi, 88888888h ;byinc +tmach5d: mov ch, byte [ebx+88888888h] ;picoffs + + cmp cx, 0ffffh + je short tprebeghline + + mov bx, word [edi] + + cmp cl, 255 + je short tskip1 + mov al, cl +transrev6: +tmach2d: mov dl, byte [eax+88888888h] ;shadeoffs +transrev7: + mov dh, bl +tmach2: mov al, byte [edx+88888888h] ;_transluc + mov byte [edi], al + + cmp ch, 255 + je short tskip2 +tskip1: + mov al, ch +transrev8: +tmach6d: mov dl, byte [eax+88888888h] ;shadeoffs +transrev9: + mov dh, bh +tmach3: mov al, byte [edx+88888888h] ;_transluc + mov byte [edi+1], al +tskip2: + + add edi, 2 + sub ecx, 131072 + jnc tbeghline +tendhline: + + pop ebp +CDECLENDSET 6 + ret + + + ;eax=shiftval, ebx=palookup1, ecx=palookup2 + ALIGN 16 +setuptvlineasm2: +CDECLBEGINSET 3 + mov byte [tran2shra+2], al + mov byte [tran2shrb+2], al + mov dword [tran2pala+2], ebx + mov dword [tran2palb+2], ecx + mov dword [tran2palc+2], ebx + mov dword [tran2pald+2], ecx +CDECLENDSET 3 + ret + + ;Pass: eax=vplc2, ebx=vinc1, ecx=bufplc1, edx=bufplc2, esi=vplc1, edi=p + ; asm1=vinc2, asm2=pend + ;Return: asm1=vplc1, asm2=vplc2 + ALIGN 16 +tvlineasm2: +CDECLBEGINSET 6 + + push ebp + + mov ebp, eax + + mov dword [tran2inca+2], ebx + mov eax, dword [asm1] + mov dword [tran2incb+2], eax + + mov dword [tran2bufa+2], ecx ;bufplc1 + mov dword [tran2bufb+2], edx ;bufplc2 + + mov eax, dword [asm2] + sub edi, eax + mov dword [tran2edia+3], eax + mov dword [tran2edic+2], eax + inc eax + mov dword [tran2edie+2], eax +fixchaint2a: sub eax, 320 + mov dword [tran2edif+2], eax + dec eax + mov dword [tran2edib+3], eax + mov dword [tran2edid+2], eax + + xor ecx, ecx + xor edx, edx + jmp short begintvline2 + + ;eax 0000000000 temp temp + ;ebx 0000000000 odat2 odat1 + ;ecx 0000000000000000 ndat1 + ;edx 0000000000000000 ndat2 + ;esi vplc1 + ;edi videoplc-------------- + ;ebp vplc2 + +ALIGN 16 + ;LEFT ONLY +skipdraw2: +transrev10: +tran2edic: mov ah, byte [edi+88888888h] ;getpixel +transrev11: +tran2palc: mov al, byte [ecx+88888888h] ;palookup1 +fixchaint2d: add edi, 320 +tran2trac: mov bl, byte [eax+88888888h] ;_transluc +tran2edid: mov byte [edi+88888888h-320], bl ;drawpixel + jnc short begintvline2 + jmp endtvline2 + +skipdraw1: + cmp dl, 255 + jne short skipdraw3 +fixchaint2b: add edi, 320 + jc short endtvline2 + +begintvline2: + mov eax, esi +tran2shra: shr eax, 88h ;globalshift + mov ebx, ebp +tran2shrb: shr ebx, 88h ;globalshift +tran2inca: add esi, 88888888h ;vinc1 +tran2incb: add ebp, 88888888h ;vinc2 +tran2bufa: mov cl, byte [eax+88888888h] ;bufplc1 + cmp cl, 255 +tran2bufb: mov dl, byte [ebx+88888888h] ;bufplc2 + je short skipdraw1 + cmp dl, 255 + je short skipdraw2 + + ;mov ax The transluscent reverse of both! + ;mov bl, ah + ;mov ah + ;mov bh + + ;BOTH +transrev12: +tran2edia: mov bx, word [edi+88888888h] ;getpixels +transrev13: + mov ah, bl +transrev14: +tran2pala: mov al, byte [ecx+88888888h] ;palookup1 +transrev15: +tran2palb: mov bl, byte [edx+88888888h] ;palookup2 +fixchaint2c: add edi, 320 +tran2traa: mov al, byte [eax+88888888h] ;_transluc +tran2trab: mov ah, byte [ebx+88888888h] ;_transluc +tran2edib: mov word [edi+88888888h-320], ax ;drawpixels + jnc short begintvline2 + jmp short endtvline2 + + ;RIGHT ONLY +skipdraw3: +transrev16: +tran2edie: mov ah, byte [edi+88888889h] ;getpixel +transrev17: +tran2pald: mov al, byte [edx+88888888h] ;palookup2 +fixchaint2e: add edi, 320 +tran2trad: mov bl, byte [eax+88888888h] ;_transluc +tran2edif: mov byte [edi+88888889h-320], bl ;drawpixel + jnc short begintvline2 + +endtvline2: + mov dword [asm1], esi + mov dword [asm2], ebp + + pop ebp +CDECLENDSET 6 + ret + + +BITSOFPRECISION equ 3 +BITSOFPRECISIONPOW equ 8 + +;Double-texture mapping with palette lookup +;eax: ylo1------------|----dat|----dat +;ebx: ylo2--------------------|----cnt +;ecx: 000000000000000000000000|---temp +;edx: xhi1-xlo1---------------|---yhi1 +;esi: xhi2-xlo2---------------|---yhi2 +;edi: ------------------------videopos +;ebp: ----------------------------temp + + ALIGN 16 +setupslopevlin2: +CDECLBEGINSET 6 + + mov dword [slop3+2], edx ;ptr + mov dword [slop7+2], edx ;ptr + mov dword [slop4+2], esi ;tptr + mov dword [slop8+2], esi ;tptr + mov byte [slop2+2], ah ;ybits + mov byte [slop6+2], ah ;ybits + mov dword [slop9+2], edi ;pinc + + mov edx, 1 + mov cl, al + add cl, ah + shl edx, cl + dec edx + mov cl, ah + ror edx, cl + + mov dword [slop1+2], edx ;ybits...xbits + mov dword [slop5+2], edx ;ybits...xbits + +CDECLENDSET 6 + ret + + ALIGN 16 +slopevlin2: +CDECLBEGINSET 6 + + push ebp + xor ecx, ecx + +slopevlin2begin: + mov ebp, edx +slop1: and ebp, 88000088h ;ybits...xbits +slop2: rol ebp, 6 ;ybits + add eax, dword [asm1] ;xinc1<>(32-xbits)) +slop3: mov cl, byte [ebp+88888888h] ;bufplc + + mov ebp, esi +slop4: mov al, byte [ecx+88888888h] ;paloffs +slop5: and ebp, 88000088h ;ybits...xbits +slop6: rol ebp, 6 ;ybits + add ebx, dword [asm3] ;xinc2<>(32-xbits)) +slop8: mov ah, byte [ecx+88888888h] ;paloffs + + dec bl + mov word [edi], ax +slop9: lea edi, [edi+88888888h] ;pinc + jnz short slopevlin2begin + + pop ebp + mov eax, edi + +CDECLENDSET 6 + ret + + + ALIGN 16 +setupslopevlin: +CDECLBEGINSET 3 + + mov dword [slopmach3+3], ebx ;ptr + mov dword [slopmach5+2], ecx ;pinc + neg ecx + mov dword [slopmach6+2], ecx ;-pinc + + mov edx, 1 + mov cl, al + shl edx, cl + dec edx + mov cl, ah + shl edx, cl + mov dword [slopmach7+2], edx + + neg ah + mov byte [slopmach2+2], ah + + sub ah, al + mov byte [slopmach1+2], ah + + fild dword [asm1] + fstp dword [asm2] + +CDECLENDSET 3 + ret + + + ALIGN 16 +slopevlin: +CDECLBEGINSET 6 + + mov dword [ebpbak], ebp + mov dword [espbak], esp + + sub ecx, esp + mov dword [slopmach4+3], ecx + + fild dword [asm3] +slopmach6: lea ebp, [eax+88888888h] + fadd dword [asm2] + + mov dword [asm1], ebx + shl ebx, 3 + + mov eax, dword [globalx3] + mov ecx, dword [globaly3] + imul eax, ebx + imul ecx, ebx + add esi, eax + add edi, ecx + + mov ebx, edx + jmp short bigslopeloop +ALIGN 16 +bigslopeloop: + fst dword [fpuasm] + + mov eax, dword [fpuasm] + add eax, eax + sbb edx, edx + mov ecx, eax + shr ecx, 24 + and eax, 00ffe000h + shr eax, 11 + sub cl, 2 + mov eax, dword [reciptable+eax] + shr eax, cl + xor eax, edx + mov edx, dword [asm1] + mov ecx, dword [globalx3] + mov dword [asm1], eax + sub eax, edx + mov edx, dword [globaly3] + imul ecx, eax + imul eax, edx + + fadd dword [asm2] + + cmp ebx, BITSOFPRECISIONPOW + mov dword [asm4], ebx + mov cl, bl + jl short slopeskipmin + mov cl, BITSOFPRECISIONPOW +slopeskipmin: + +;eax: yinc............. +;ebx: 0 0 0 ? +;ecx: xinc......... cnt +;edx: ? +;esi: xplc............. +;edi: yplc............. +;ebp: videopos + + mov ebx, esi + mov edx, edi + +beginnerslopeloop: +slopmach1: shr ebx, 20 + add esi, ecx +slopmach2: shr edx, 26 +slopmach7: and ebx, 88888888h + add edi, eax +slopmach5: add ebp, 88888888h ;pinc +slopmach3: mov dl, byte [ebx+edx+88888888h] ;ptr +slopmach4: mov ebx, dword [esp+88888888h] + sub esp, 4 + dec cl + mov al, byte [ebx+edx] ;tptr + mov ebx, esi + mov [ebp], al + mov edx, edi + jnz short beginnerslopeloop + + mov ebx, dword [asm4] + sub ebx, BITSOFPRECISIONPOW + jg near bigslopeloop + + ffree st0 + + mov esp, dword [espbak] + mov ebp, dword [ebpbak] + +CDECLENDSET 6 + ret + + + ALIGN 16 +setuprhlineasm4: +CDECLBEGINSET 6 + + mov dword [rmach1a+2], eax + mov dword [rmach1b+2], eax + mov dword [rmach1c+2], eax + mov dword [rmach1d+2], eax + mov dword [rmach1e+2], eax + + mov dword [rmach2a+2], ebx + mov dword [rmach2b+2], ebx + mov dword [rmach2c+2], ebx + mov dword [rmach2d+2], ebx + mov dword [rmach2e+2], ebx + + mov dword [rmach3a+2], ecx + mov dword [rmach3b+2], ecx + mov dword [rmach3c+2], ecx + mov dword [rmach3d+2], ecx + mov dword [rmach3e+2], ecx + + mov dword [rmach4a+2], edx + mov dword [rmach4b+2], edx + mov dword [rmach4c+2], edx + mov dword [rmach4d+2], edx + mov dword [rmach4e+2], edx + + mov dword [rmach5a+2], esi + mov dword [rmach5b+2], esi + mov dword [rmach5c+2], esi + mov dword [rmach5d+2], esi + mov dword [rmach5e+2], esi + +CDECLENDSET 6 + ret + + ;Non power of 2, non masking, with palookup method #1 (6 clock cycles) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: xlo + ;esi: ylo + ;edi: videopos/cnt + ;ebp: tempvar + ;esp: + ALIGN 16 +rhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle near endrhline + + lea ebp, [edi-4] + sub ebp, eax + mov dword [rmach6a+2], ebp + add ebp, 3 + mov dword [rmach6b+2], ebp + mov edi, eax + test edi, 3 + jz short begrhline + jmp short startrhline1 + +ALIGN 16 +startrhline1: + mov cl, byte [ebx] ;bufplc +rmach1e: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2e: sub esi, 88888888h ;ylo +rmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach4e: mov al, byte [ecx+88888888h] ;palookup +rmach5e: and ebp, 88888888h ;tilesizy +rmach6b: mov byte [edi+88888888h], al ;vidcntoffs + sub ebx, ebp + dec edi + test edi, 3 + jnz short startrhline1 + test edi, edi + jz near endrhline + +begrhline: + mov cl, byte [ebx] ;bufplc +rmach1a: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2a: sub esi, 88888888h ;ylo +rmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5a: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1b: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4a: mov ah, byte [ecx+88888888h] ;palookup + mov cl, byte [ebx] ;bufplc +rmach2b: sub esi, 88888888h ;ylo +rmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5b: and ebp, 88888888h ;tilesizy +rmach4b: mov al, byte [ecx+88888888h] ;palookup + sub ebx, ebp + + shl eax, 16 + + mov cl, byte [ebx] ;bufplc +rmach1c: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2c: sub esi, 88888888h ;ylo +rmach3c: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5c: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1d: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4c: mov ah, byte [ecx+88888888h] ;palookup + mov cl, byte [ebx] ;bufplc +rmach2d: sub esi, 88888888h ;ylo +rmach3d: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5d: and ebp, 88888888h ;tilesizy +rmach4d: mov al, byte [ecx+88888888h] ;palookup + sub ebx, ebp + +rmach6a: mov dword [edi+88888888h], eax ;vidcntoffs + sub edi, 4 + jnz near begrhline +endrhline: + pop ebp + +CDECLENDSET 6 + ret + + + ALIGN 16 +setuprmhlineasm4: +CDECLBEGINSET 6 + mov dword [rmmach1+2], eax + mov dword [rmmach2+2], ebx + mov dword [rmmach3+2], ecx + mov dword [rmmach4+2], edx + mov dword [rmmach5+2], esi +CDECLENDSET 6 + ret + + + ALIGN 16 +rmhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle short endrmhline + + lea ebp, [edi-1] + sub ebp, eax + mov dword [rmmach6+2], ebp + mov edi, eax + jmp short begrmhline + +ALIGN 16 +begrmhline: + mov cl, byte [ebx] ;bufplc +rmmach1: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmmach2: sub esi, 88888888h ;ylo +rmmach3: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmmach5: and ebp, 88888888h ;tilesizy + cmp cl, 255 + je short rmskip +rmmach4: mov al, byte [ecx+88888888h] ;palookup +rmmach6: mov byte [edi+88888888h], al ;vidcntoffs +rmskip: + sub ebx, ebp + dec edi + jnz short begrmhline +endrmhline: + pop ebp + +CDECLENDSET 6 + ret + + + ALIGN 16 +setupqrhlineasm4: +CDECLBEGINSET 6 + + mov dword [qrmach2e+2], ebx + mov dword [qrmach3e+2], ecx + xor edi, edi + sub edi, ecx + mov dword [qrmach7a+2], edi + mov dword [qrmach7b+2], edi + + add ebx, ebx + adc ecx, ecx + mov dword [qrmach2a+2], ebx + mov dword [qrmach2b+2], ebx + mov dword [qrmach3a+2], ecx + mov dword [qrmach3b+2], ecx + + mov dword [qrmach4a+2], edx + mov dword [qrmach4b+2], edx + mov dword [qrmach4c+2], edx + mov dword [qrmach4d+2], edx + mov dword [qrmach4e+2], edx + +CDECLENDSET 6 + ret + + ;Non power of 2, non masking, with palookup method (FASTER BUT NO SBB'S) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: 0 dat + ;esi: ylo + ;edi: videopos/cnt + ;ebp: ? + ;esp: + ALIGN 16 +qrhlineasm4: +CDECLBEGINSET 6 + + push ebp + + cmp eax, 0 + jle near endqrhline + + mov ebp, eax + test ebp, 3 + jz short skipqrhline1 + jmp short startqrhline1 + +ALIGN 16 +startqrhline1: + mov cl, byte [ebx] ;bufplc + dec edi +qrmach2e: sub esi, 88888888h ;ylo + dec ebp +qrmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4e: mov al, byte [ecx+88888888h] ;palookup + mov byte [edi], al ;vidcntoffs + test ebp, 3 + jnz short startqrhline1 + test ebp, ebp + jz short endqrhline + +skipqrhline1: + mov cl, byte [ebx] ;bufplc + jmp short begqrhline +ALIGN 16 +begqrhline: +qrmach7a: mov dl, byte [ebx+88888888h] ;bufplc +qrmach2a: sub esi, 88888888h ;ylo +qrmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4a: mov ah, byte [ecx+88888888h] ;palookup +qrmach4b: mov al, byte [edx+88888888h] ;palookup + sub edi, 4 + shl eax, 16 + mov cl, byte [ebx] ;bufplc +qrmach7b: mov dl, byte [ebx+88888888h] ;bufplc +qrmach2b: sub esi, 88888888h ;ylo +qrmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4c: mov ah, byte [ecx+88888888h] ;palookup +qrmach4d: mov al, byte [edx+88888888h] ;palookup + mov cl, byte [ebx] ;bufplc + mov dword [edi], eax + sub ebp, 4 + jnz short begqrhline + +endqrhline: + pop ebp + +CDECLENDSET 6 + ret + + +setupdrawslab: +CDECLBEGINSET 2 + + mov dword [voxbpl1+2], eax + mov dword [voxbpl2+2], eax + mov dword [voxbpl3+2], eax + mov dword [voxbpl4+2], eax + mov dword [voxbpl5+2], eax + mov dword [voxbpl6+2], eax + mov dword [voxbpl7+2], eax + mov dword [voxbpl8+2], eax + + mov dword [voxpal1+2], ebx + mov dword [voxpal2+2], ebx + mov dword [voxpal3+2], ebx + mov dword [voxpal4+2], ebx + mov dword [voxpal5+2], ebx + mov dword [voxpal6+2], ebx + mov dword [voxpal7+2], ebx + mov dword [voxpal8+2], ebx + +CDECLENDSET 2 + ret + + + ALIGN 16 +drawslab: +CDECLBEGINSET 6 + + push ebp + cmp eax, 2 + je near voxbegdraw2 + ja near voxskip2 + xor eax, eax +voxbegdraw1: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + dec ecx + mov al, byte [esi+ebp] +voxpal1: mov al, byte [eax+88888888h] + mov byte [edi], al +voxbpl1: lea edi, [edi+88888888h] + jnz near voxbegdraw1 + pop ebp + +CDECLENDSET 6 + ret + +voxbegdraw2: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + xor eax, eax + dec ecx + mov al, byte [esi+ebp] +voxpal2: mov al, byte [eax+88888888h] + mov ah, al + mov word [edi], ax +voxbpl2: lea edi, [edi+88888888h] + jnz near voxbegdraw2 + pop ebp + +CDECLENDSET 6 + ret + +voxskip2: + cmp eax, 4 + jne near voxskip4 + xor eax, eax +voxbegdraw4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal3: mov al, byte [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword [edi], eax +voxbpl3: add edi, 88888888h + dec ecx + jnz near voxbegdraw4 + pop ebp + +CDECLENDSET 6 + ret + +voxskip4: + add eax, edi + + test edi, 1 + jz near voxskipslab1 + cmp edi, eax + je near voxskipslab1 + + push eax + push ebx + push ecx + push edi +voxbegslab1: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal4: mov al, byte [eax+88888888h] + mov byte [edi], al +voxbpl4: add edi, 88888888h + dec ecx + jnz near voxbegslab1 + pop edi + pop ecx + pop ebx + pop eax + inc edi + +voxskipslab1: + push eax + test edi, 2 + jz near voxskipslab2 + dec eax + cmp edi, eax + jge near voxskipslab2 + + push ebx + push ecx + push edi +voxbegslab2: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal5: mov al, byte [eax+88888888h] + mov ah, al + mov word [edi], ax +voxbpl5: add edi, 88888888h + dec ecx + jnz near voxbegslab2 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab2: + mov eax, dword [esp] + + sub eax, 3 + cmp edi, eax + jge near voxskipslab3 + +voxprebegslab3: + push ebx + push ecx + push edi +voxbegslab3: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal6: mov al, byte [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword [edi], eax +voxbpl6: add edi, 88888888h + dec ecx + jnz near voxbegslab3 + pop edi + pop ecx + pop ebx + add edi, 4 + + mov eax, dword [esp] + + sub eax, 3 + cmp edi, eax + jl near voxprebegslab3 + +voxskipslab3: + mov eax, dword [esp] + + dec eax + cmp edi, eax + jge near voxskipslab4 + + push ebx + push ecx + push edi +voxbegslab4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal7: mov al, byte [eax+88888888h] + mov ah, al + mov word [edi], ax +voxbpl7: add edi, 88888888h + dec ecx + jnz near voxbegslab4 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab4: + pop eax + + cmp edi, eax + je near voxskipslab5 + +voxbegslab5: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte [esi+ebp] +voxpal8: mov al, byte [eax+88888888h] + mov byte [edi], al +voxbpl8: add edi, 88888888h + dec ecx + jnz near voxbegslab5 + +voxskipslab5: + pop ebp + +CDECLENDSET 6 + ret + +;modify: loinc +;eax: | dat | dat | dat | dat | +;ebx: | loplc1 | +;ecx: | loplc2 | cnthi | cntlo | +;edx: |--------|--------|--------| hiplc1 | +;esi: |--------|--------|--------| hiplc2 | +;edi: |--------|--------|--------| vidplc | +;ebp: |--------|--------|--------| hiinc | + +stretchhline: +CDECLBEGINSET 6 + + push ebp + + mov eax, ebx + shl ebx, 16 + sar eax, 16 + and ecx, 0000ffffh + or ecx, ebx + + add esi, eax + mov eax, edx + mov edx, esi + + mov ebp, eax + shl eax, 16 + sar ebp, 16 + + add ecx, eax + adc esi, ebp + + add eax, eax + adc ebp, ebp + mov dword [loinc1+2], eax + mov dword [loinc2+2], eax + mov dword [loinc3+2], eax + mov dword [loinc4+2], eax + + inc ch + + jmp begloop + +begloop: + mov al, [edx] +loinc1: sub ebx, 88888888h + sbb edx, ebp + mov ah, [esi] +loinc2: sub ecx, 88888888h + sbb esi, ebp + sub edi, 4 + shl eax, 16 +loinc3: sub ebx, 88888888h + mov al, [edx] + sbb edx, ebp + mov ah, [esi] +loinc4: sub ecx, 88888888h + sbb esi, ebp + mov [edi], eax + dec cl + jnz begloop + dec ch + jnz begloop + + pop ebp + +CDECLENDSET 6 + ret + + +mmxoverlay: + push ebx ;JBF + push ecx ;JBF + push edx ;JBF + + pushfd ;Check if CPUID is available + pop eax + mov ebx, eax + xor eax, 00200000h + push eax + popfd + pushfd + pop eax + cmp eax, ebx + je pentium + xor eax, eax + dw 0a20fh + test eax, eax + jz pentium + mov eax, 1 + dw 0a20fh + and eax, 00000f00h + test edx, 00800000h ;Check if MMX is available + jz nommx + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumii + jmp pentiummmx +nommx: + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumpro +pentium: + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM II Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumii: + ;Hline overlay (MMX doens't help) + mov byte [sethlinesizes], 0xe9 + mov dword [sethlinesizes+1], (prosethlinesizes-sethlinesizes-5) + mov byte [setpalookupaddress], 0xe9 + mov dword [setpalookupaddress+1], (prosetpalookupaddress-setpalookupaddress-5) + mov byte [setuphlineasm4], 0xc3 ;ret (no code required) + mov byte [hlineasm4], 0xe9 + mov dword [hlineasm4+1], (prohlineasm4-hlineasm4-5) + + ;Vline overlay + mov byte [setupvlineasm], 0xe9 + mov dword [setupvlineasm+1], (prosetupvlineasm-setupvlineasm-5) + mov byte [vlineasm4], 0xe9 + mov dword [vlineasm4+1], (provlineasm4-vlineasm4-5) + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM MMX Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiummmx: + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM PRO Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumpro: + ;Hline overlay (MMX doens't help) + mov byte [sethlinesizes], 0xe9 + mov dword [sethlinesizes+1], (prosethlinesizes-sethlinesizes-5) + mov byte [setpalookupaddress], 0xe9 + mov dword [setpalookupaddress+1], (prosetpalookupaddress-setpalookupaddress-5) + mov byte [setuphlineasm4], 0xc3 ;ret (no code required) + mov byte [hlineasm4], 0xe9 + mov dword [hlineasm4+1], (prohlineasm4-hlineasm4-5) + + ;Vline overlay + mov byte [setupvlineasm], 0xe9 + mov dword [setupvlineasm+1], (prosetupvlineasm-setupvlineasm-5) + mov byte [vlineasm4], 0xe9 + mov dword [vlineasm4+1], (provlineasm4-vlineasm4-5) + + pop edx ;JBF + pop ecx ;JBF + pop ebx ;JBF + ret + diff --git a/polymer/build/src/a.wasm b/polymer/build/src/a.wasm new file mode 100644 index 000000000..6b68da6d2 --- /dev/null +++ b/polymer/build/src/a.wasm @@ -0,0 +1,2420 @@ +; "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +; Ken Silverman's official web site: "http://www.advsys.net/ken" +; See the included license file "BUILDLIC.TXT" for license info. + +.586P +.8087 +;include mmx.inc ;Include this if using < WATCOM 11.0 WASM + +;Warning: IN THIS FILE, ALL SEGMENTS ARE REMOVED. THIS MEANS THAT DS:[] +;MUST BE ADDED FOR ALL SELF-MODIFIES FOR MASM TO WORK. +; +;WASM PROBLEMS: +; 1. Requires all scaled registers (*1,*2,*4,*8) to be last thing on line +; 2. Using 'DATA' is nice for self-mod. code, but WDIS only works with 'CODE' +; +;MASM PROBLEMS: +; 1. Requires DS: to be written out for self-modifying code to work +; 2. Doesn't encode short jumps automatically like WASM +; 3. Stupidly adds wait prefix to ffree's + +EXTRN _asm1 : dword +EXTRN _asm2 : dword +EXTRN _asm3 : dword +EXTRN _asm4 : dword +EXTRN _reciptable : near +EXTRN _fpuasm : dword +EXTRN _globalx3 : dword +EXTRN _globaly3 : dword +EXTRN _ylookup : near + +EXTRN _vplce : near +EXTRN _vince : near +EXTRN _palookupoffse : near +EXTRN _bufplce : near + +EXTRN _ebpbak : dword +EXTRN _espbak : dword + +EXTRN _pow2char : near +EXTRN _pow2long : near + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +ALIGN 16 +PUBLIC sethlinesizes_ +sethlinesizes_: + mov byte ptr [machxbits1+2], al + mov byte ptr [machxbits2+2], al + mov byte ptr [machxbits3+2], al + neg al + mov byte ptr [hxsiz1+2], al + mov byte ptr [hxsiz2+2], al + mov byte ptr [hxsiz3+2], al + mov byte ptr [hxsiz4+2], al + mov byte ptr [machnegxbits1+2], al + + mov byte ptr [hysiz1+3], bl + mov byte ptr [hysiz2+3], bl + mov byte ptr [hysiz3+3], bl + mov byte ptr [hysiz4+3], bl + mov byte ptr [hmach3a+2], bl + mov byte ptr [hmach3b+2], bl + mov byte ptr [hmach3c+2], bl + mov byte ptr [hmach3d+2], bl + + mov dword ptr [hoffs1+2], ecx + mov dword ptr [hoffs2+2], ecx + mov dword ptr [hoffs3+2], ecx + mov dword ptr [hoffs4+2], ecx + mov dword ptr [hoffs5+2], ecx + mov dword ptr [hoffs6+2], ecx + mov dword ptr [hoffs7+2], ecx + mov dword ptr [hoffs8+2], ecx + + mov edx, -1 + mov cl, al + sub cl, bl + shr edx, cl + mov dword ptr [hmach2a+1], edx + mov dword ptr [hmach2b+1], edx + mov dword ptr [hmach2c+1], edx + mov dword ptr [hmach2d+1], edx + + ret + +ALIGN 16 +PUBLIC prosethlinesizes_ +prosethlinesizes_: + mov dword ptr [prohbuf-4], ecx + neg eax + mov ecx, eax + sub eax, ebx + mov byte ptr [prohshru-1], al ;bl = 32-al-bl + mov eax, -1 + shr eax, cl + mov ecx, ebx + shl eax, cl + mov dword ptr [prohand-4], eax ;((-1>>(-oal))<>(32-xbits) adc al, 88h 1 1/2 + ;bufplc mov cl, byte ptr [edx+88888888h] 1 1/2 + ;paloffs&255 mov bl, byte ptr [ecx+88888888h] 1 1/2 +ALIGN 16 +PUBLIC hlineasm4_ +hlineasm4_: + push ebp + + lea ebp, [eax+1] + + cmp ebp, 8 + jle shorthline + + test edi, 1 + jnz short skipthe1byte + + mov eax, esi +hxsiz1: shr eax, 26 +hysiz1: shld eax, edx, 6 +hoffs1: mov cl, byte ptr [eax+88888888h] +pal1: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov byte ptr [edi], bl + dec edi + dec ebp + +skipthe1byte: + test edi, 2 + jnz short skipthe2byte + + mov eax, esi +hxsiz2: shr eax, 26 +hysiz2: shld eax, edx, 6 +hoffs2: mov cl, byte ptr [eax+88888888h] +pal2: mov bh, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + + mov eax, esi +hxsiz3: shr eax, 26 +hysiz3: shld eax, edx, 6 +hoffs3: mov cl, byte ptr [eax+88888888h] +pal3: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov word ptr [edi-1], bx + sub edi, 2 + sub ebp, 2 + +skipthe2byte: + + mov eax, esi +machxbits1: shl esi, 6 ;xbits +machnegxbits1: shr eax, 32-6 ;32-xbits + mov dl, al + + inc edi + + add ebx, ebx + mov eax, edx + jc beginhline64 + + mov eax, _asm1 +machxbits2: rol eax, 6 ;xbits + mov dword ptr [hmach4a+2], eax + mov dword ptr [hmach4b+2], eax + mov dword ptr [hmach4c+2], eax + mov dword ptr [hmach4d+2], eax + mov ebx, eax + mov eax, _asm2 + mov al, bl + mov dword ptr [hmach1a+2], eax + mov dword ptr [hmach1b+2], eax + mov dword ptr [hmach1c+2], eax + mov dword ptr [hmach1d+2], eax + + mov eax, edx + jmp beginhline64 +ALIGN 16 +prebeginhline64: + mov dword ptr [edi], ebx +beginhline64: + +hmach3a: rol eax, 6 +hmach2a: and eax, 00008888h +hmach4a: sub esi, 88888888h +hmach1a: sbb edx, 88888888h + sub edi, 4 +hoffs4: mov cl, byte ptr [eax+88888888h] + mov eax, edx + +hmach3b: rol eax, 6 +hmach2b: and eax, 00008888h +hmach4b: sub esi, 88888888h +hmach1b: sbb edx, 88888888h +pal4: mov bh, byte ptr [ecx+88888888h] +hoffs5: mov cl, byte ptr [eax+88888888h] + mov eax, edx + +hmach3c: rol eax, 6 +pal5: mov bl, byte ptr [ecx+88888888h] +hmach2c: and eax, 00008888h + shl ebx, 16 +hmach4c: sub esi, 88888888h +hmach1c: sbb edx, 88888888h +hoffs6: mov cl, byte ptr [eax+88888888h] + + mov eax, edx + ;( + +hmach3d: rol eax, 6 +hmach2d: and eax, 00008888h +hmach4d: sub esi, 88888888h +hmach1d: sbb edx, 88888888h +pal6: mov bh, byte ptr [ecx+88888888h] +hoffs7: mov cl, byte ptr [eax+88888888h] + mov eax, edx + sub ebp, 4 + nop +pal7: mov bl, byte ptr [ecx+88888888h] + jnc prebeginhline64 +skipthe4byte: + + test ebp, 2 + jz skipdrawthe2 + rol ebx, 16 + mov word ptr [edi+2], bx + sub edi, 2 +skipdrawthe2: + test ebp, 1 + jz skipdrawthe1 + shr ebx, 24 + mov byte ptr [edi+3], bl +skipdrawthe1: + + pop ebp + ret + +shorthline: + test ebp, ebp + jz endshorthline +begshorthline: + mov eax, esi +hxsiz4: shr eax, 26 +hysiz4: shld eax, edx, 6 +hoffs8: mov cl, byte ptr [eax+88888888h] +pal8: mov bl, byte ptr [ecx+88888888h] + sub esi, _asm1 + sub edx, _asm2 + mov byte ptr [edi], bl + dec edi + dec ebp + jnz begshorthline +endshorthline: + pop ebp + ret + + + ;eax: 00000000 00000000 00000000 temp---- + ;ebx: 00000000 00000000 00000000 temp---- + ;ecx: UUUUUUuu uuuuuuuu uuuuuuuu uuuuuuuu + ;edx: VVVVVVvv vvvvvvvv vvvvvvvv vvvvvvvv + ;esi: cnt----- -------- -------- -------- + ;edi: vid----- -------- -------- -------- + ;ebp: paloffs- -------- -------- -------- + ;esp: ???????? ???????? ???????? ???????? +ALIGN 16 +PUBLIC prohlineasm4_ +prohlineasm4_: + push ebp + + lea ebp, [ecx+88888888h] +prohpala: + mov ecx, esi + lea esi, [eax+1] + sub edi, esi + +prohbeg: + mov eax, ecx + shr eax, 20 +prohshru: + mov ebx, edx + shr ebx, 26 +prohshrv: + and eax, 88888888h +prohand: + movzx eax, byte ptr [eax+ebx+88888888h] +prohbuf: + mov al, [eax+ebp] + sub ecx, _asm1 + sub edx, _asm2 + mov [edi+esi], al + dec esi + jnz prohbeg + + pop ebp + ret + + + +ALIGN 16 +PUBLIC setupvlineasm_ +setupvlineasm_: + ;First 2 lines for VLINEASM1, rest for VLINEASM4 + mov byte ptr [premach3a+2], al + mov byte ptr [mach3a+2], al + + push ecx + mov byte ptr [machvsh1+2], al ;32-shy + mov byte ptr [machvsh3+2], al ;32-shy + mov byte ptr [machvsh5+2], al ;32-shy + mov byte ptr [machvsh6+2], al ;32-shy + mov ah, al + sub ah, 16 + mov byte ptr [machvsh8+2], ah ;16-shy + neg al + mov byte ptr [machvsh7+2], al ;shy + mov byte ptr [machvsh9+2], al ;shy + mov byte ptr [machvsh10+2], al ;shy + mov byte ptr [machvsh11+2], al ;shy + mov byte ptr [machvsh12+2], al ;shy + mov cl, al + mov eax, 1 + shl eax, cl + dec eax + mov dword ptr [machvsh2+2], eax ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +machvsh5: shl esi, 88h ;32-sh + mov eax, edx +machvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +machvsh7: shr eax, 88h ;sh + add esi, eax +machvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword ptr _vplce[12], esi + mov dword ptr _vplce[4], ebp + + pop ebp + ret + + ;eax: -------temp1------- + ;ebx: -------temp2------- + ;ecx: ylo4 --------- + ;edx: ylo2 --------- + ;esi: yhi1 yhi2 + ;edi: ---videoplc/cnt---- + ;ebp: yhi3 yhi4 + ;esp: +ALIGN 16 +PUBLIC provlineasm4_ +provlineasm4_: + push ebp + + mov eax, dword ptr _ylookup[ecx*4] + add eax, edi + mov dword ptr [promachvline4end1+2], eax + inc eax + mov dword ptr [promachvline4end2+2], eax + inc eax + mov dword ptr [promachvline4end3+2], eax + inc eax + mov dword ptr [promachvline4end4+2], eax + sub eax, 3 + sub edi, eax + + mov eax, dword ptr _bufplce[0] + mov ebx, dword ptr _bufplce[4] + mov ecx, dword ptr _bufplce[8] + mov edx, dword ptr _bufplce[12] + mov dword ptr [promachvbuf1+3], ecx + mov dword ptr [promachvbuf2+3], edx + mov dword ptr [promachvbuf3+3], eax + mov dword ptr [promachvbuf4+3], ebx + + mov eax, dword ptr _palookupoffse[0] + mov ebx, dword ptr _palookupoffse[4] + mov ecx, dword ptr _palookupoffse[8] + mov edx, dword ptr _palookupoffse[12] + mov dword ptr [promachvpal1+2], ecx + mov dword ptr [promachvpal2+2], edx + mov dword ptr [promachvpal3+2], eax + mov dword ptr [promachvpal4+2], ebx + + ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ;edx: ³v3lo ³v1lo ³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ´ + ;esi: ³v2hi v2lo ³ v3hi³ + ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄ´ + ;ebp: ³v0hi v0lo ³ v1hi³ + ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÙ + + mov ebp, dword ptr _vince[0] + mov ebx, dword ptr _vince[4] + mov esi, dword ptr _vince[8] + mov eax, dword ptr _vince[12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh9: rol eax, 88h ;sh +promachvsh10: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + ; + mov eax, edx + and eax, 0ffff0000h + mov dword ptr [promachvinc1+2], eax + mov dword ptr [promachvinc2+2], esi + shl edx, 16 + mov dword ptr [promachvinc3+2], edx + mov dword ptr [promachvinc5+2], ebp + + mov ebp, dword ptr _vplce[0] + mov ebx, dword ptr _vplce[4] + mov esi, dword ptr _vplce[8] + mov eax, dword ptr _vplce[12] + and esi, 0fffffe00h + and ebp, 0fffffe00h +promachvsh11: rol eax, 88h ;sh +promachvsh12: rol ebx, 88h ;sh + mov edx, eax + mov ecx, ebx + shr ecx, 16 + and edx, 0ffff0000h + add edx, ecx + and eax, 000001ffh + and ebx, 000001ffh + add esi, eax + add ebp, ebx + + mov eax, esi + mov ecx, edx + shl ecx, 16 + jmp short probeginvlineasm4 +ALIGN 16 + nop + nop + nop +probeginvlineasm4: +promachvsh1: shr eax, 88h ;32-sh + mov ebx, esi +promachvsh2: and ebx, 00000088h ;(1<>sh) + ;vplc3 = (ebp<<(32-sh))+((edx&65535)<<(16-sh)) +promachvsh5: shl esi, 88h ;32-sh + mov eax, edx +promachvsh6: shl ebp, 88h ;32-sh + and edx, 0000ffffh +promachvsh7: shr eax, 88h ;sh + add esi, eax +promachvsh8: shl edx, 88h ;16-sh + add ebp, edx + mov dword ptr _vplce[12], esi + mov dword ptr _vplce[4], ebp + + pop ebp + ret + + +ALIGN 16 +PUBLIC mvlineasm4_ +mvlineasm4_: + push ebp + + mov eax, dword ptr _bufplce[0] + mov ebx, dword ptr _bufplce[4] + mov dword ptr [machmv1+2], eax + mov dword ptr [machmv4+2], ebx + mov eax, dword ptr _bufplce[8] + mov ebx, dword ptr _bufplce[12] + mov dword ptr [machmv7+2], eax + mov dword ptr [machmv10+2], ebx + + mov eax, dword ptr _palookupoffse[0] + mov ebx, dword ptr _palookupoffse[4] + mov dword ptr [machmv2+2], eax + mov dword ptr [machmv5+2], ebx + mov eax, dword ptr _palookupoffse[8] + mov ebx, dword ptr _palookupoffse[12] + mov dword ptr [machmv8+2], eax + mov dword ptr [machmv11+2], ebx + + mov eax, dword ptr _vince[0] ;vince + mov ebx, dword ptr _vince[4] + xor al, al + xor bl, bl + mov dword ptr [machmv3+2], eax + mov dword ptr [machmv6+2], ebx + mov eax, dword ptr _vince[8] + mov ebx, dword ptr _vince[12] + mov dword ptr [machmv9+2], eax + mov dword ptr [machmv12+2], ebx + + mov ebx, ecx + mov ecx, dword ptr _vplce[0] + mov edx, dword ptr _vplce[4] + mov esi, dword ptr _vplce[8] + mov ebp, dword ptr _vplce[12] + mov cl, bl + inc cl + inc bh + mov byte ptr _asm3[0], bh +fixchain2ma: sub edi, 320 + + jmp short beginmvlineasm4 +ALIGN 16 +beginmvlineasm4: + dec cl + jz endmvlineasm4 +beginmvlineasm42: + mov eax, ebp + mov ebx, esi +machmv16: shr eax, 32 +machmv15: shr ebx, 32 +machmv12: add ebp, 88888888h ;vince[3] +machmv9: add esi, 88888888h ;vince[2] +machmv10: mov al, byte ptr [eax+88888888h] ;bufplce[3] +machmv7: mov bl, byte ptr [ebx+88888888h] ;bufplce[2] + cmp al, 255 + adc dl, dl + cmp bl, 255 + adc dl, dl +machmv8: mov bl, byte ptr [ebx+88888888h] ;palookupoffs[2] +machmv11: mov bh, byte ptr [eax+88888888h] ;palookupoffs[3] + + mov eax, edx +machmv14: shr eax, 32 + shl ebx, 16 +machmv4: mov al, byte ptr [eax+88888888h] ;bufplce[1] + cmp al, 255 + adc dl, dl +machmv6: add edx, 88888888h ;vince[1] +machmv5: mov bh, byte ptr [eax+88888888h] ;palookupoffs[1] + + mov eax, ecx +machmv13: shr eax, 32 +machmv3: add ecx, 88888888h ;vince[0] +machmv1: mov al, byte ptr [eax+88888888h] ;bufplce[0] + cmp al, 255 + adc dl, dl +machmv2: mov bl, byte ptr [eax+88888888h] ;palookupoffs[0] + + shl dl, 4 + xor eax, eax +fixchain2mb: add edi, 320 + mov al, dl + add eax, offset mvcase0 + jmp eax ;16 byte cases + +ALIGN 16 +endmvlineasm4: + dec byte ptr _asm3[0] + jnz beginmvlineasm42 + + mov dword ptr _vplce[0], ecx + mov dword ptr _vplce[4], edx + mov dword ptr _vplce[8], esi + mov dword ptr _vplce[12], ebp + pop ebp + ret + + ;5,7,8,8,11,13,12,14,11,13,14,14,12,14,15,7 +ALIGN 16 +mvcase0: + jmp beginmvlineasm4 +ALIGN 16 +mvcase1: + mov byte ptr [edi], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase2: + mov byte ptr [edi+1], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase3: + mov word ptr [edi], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase4: + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase5: + mov byte ptr [edi], bl + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 + mvcase6: + shr ebx, 8 + mov word ptr [edi+1], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase7: + mov word ptr [edi], bx + shr ebx, 16 + mov byte ptr [edi+2], bl + jmp beginmvlineasm4 +ALIGN 16 +mvcase8: + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase9: + mov byte ptr [edi], bl + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase10: + mov byte ptr [edi+1], bh + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase11: + mov word ptr [edi], bx + shr ebx, 16 + mov byte ptr [edi+3], bh + jmp beginmvlineasm4 +ALIGN 16 +mvcase12: + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase13: + mov byte ptr [edi], bl + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase14: + mov byte ptr [edi+1], bh + shr ebx, 16 + mov word ptr [edi+2], bx + jmp beginmvlineasm4 +ALIGN 16 +mvcase15: + mov dword ptr [edi], ebx + jmp beginmvlineasm4 + +ALIGN 16 +PUBLIC setupspritevline_ +setupspritevline_: + mov dword ptr [spal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [smach1+2], eax + mov dword ptr [smach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [smach2+2], eax + add eax, edx + mov dword ptr [smach5+2], eax + + mov dword ptr [smach3+2], ecx ;yinc's + ret + +ALIGN 16 +PUBLIC spritevline_ + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +prestartsvline: +smach1: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +smach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +startsvline: +spal: mov al, [eax+88888888h] ;palookup + mov byte ptr [edi], al +fixchain1s: add edi, 320 + +spritevline_: +smach3: add edx, 88888888h ;dayinc + dec ecx + ja short prestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short endsvline +smach4: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +smach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short startsvline +endsvline: + ret + +ALIGN 16 +PUBLIC msetupspritevline_ +msetupspritevline_: + mov dword ptr [mspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [msmach1+2], eax + mov dword ptr [msmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [msmach2+2], eax + add eax, edx + mov dword ptr [msmach5+2], eax + + mov dword ptr [msmach3+2], ecx ;yinc's + ret + +ALIGN 16 +PUBLIC mspritevline_ + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p +mprestartsvline: +msmach1: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +msmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +mstartsvline: + cmp al, 255 + je short mskipsvline +mspal: mov al, [eax+88888888h] ;palookup + mov byte ptr [edi], al +mskipsvline: +mfixchain1s: add edi, 320 + +mspritevline_: +msmach3: add edx, 88888888h ;dayinc + dec ecx + ja short mprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short mendsvline +msmach4: add ebx, 88888888h ;xincshl16 + mov al, byte ptr [esi] +msmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short mstartsvline +mendsvline: + ret + +ALIGN 16 +PUBLIC tsetupspritevline_ +tsetupspritevline_: + mov dword ptr [tspal+2], eax + + mov eax, esi ;xinc's + shl eax, 16 + mov dword ptr [tsmach1+2], eax + mov dword ptr [tsmach4+2], eax + mov eax, esi + sar eax, 16 + add eax, ebx ;watch out with ebx - it's passed + mov dword ptr [tsmach2+2], eax + add eax, edx + mov dword ptr [tsmach5+2], eax + + mov dword ptr [tsmach3+2], ecx ;yinc's + ret + +ALIGN 16 +PUBLIC tspritevline_ +tspritevline_: + ;eax = 0, ebx = x, ecx = cnt, edx = y, esi = yplc, edi = p + push ebp + mov ebp, ebx + xor ebx, ebx + jmp tenterspritevline +ALIGN 16 +tprestartsvline: +tsmach1: add ebp, 88888888h ;xincshl16 + mov al, byte ptr [esi] +tsmach2: adc esi, 88888888h ;xincshr16+yalwaysinc + +tstartsvline: + cmp al, 255 + je short tskipsvline +transrev2: + mov bh, byte ptr [edi] +transrev3: +tspal: mov bl, [eax+88888888h] ;palookup +tmach4: mov al, byte ptr [ebx+88888888h] ;_transluc + mov byte ptr [edi], al +tskipsvline: +tfixchain1s: add edi, 320 + +tenterspritevline: +tsmach3: add edx, 88888888h ;dayinc + dec ecx + ja short tprestartsvline ;jump if (no carry (add)) and (not zero (dec))! + jz short tendsvline +tsmach4: add ebp, 88888888h ;xincshl16 + mov al, byte ptr [esi] +tsmach5: adc esi, 88888888h ;xincshr16+yalwaysinc+daydime + jmp short tstartsvline +tendsvline: + pop ebp + ret + +ALIGN 16 +PUBLIC msethlineshift_ +msethlineshift_: + neg al + mov byte ptr [msh1d+2], al + mov byte ptr [msh2d+3], bl + mov byte ptr [msh3d+2], al + mov byte ptr [msh4d+3], bl + mov byte ptr [msh5d+2], al + mov byte ptr [msh6d+3], bl + ret + +ALIGN 16 +PUBLIC mhline_ +mhline_: + ;_asm1 = bxinc + ;_asm2 = byinc + ;_asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword ptr [mmach1d+2], eax + mov dword ptr [mmach5d+2], eax + mov dword ptr [mmach9d+2], eax + mov eax, _asm3 + mov dword ptr [mmach2d+2], eax + mov dword ptr [mmach2da+2], eax + mov dword ptr [mmach2db+2], eax + mov dword ptr [mmach6d+2], eax + mov dword ptr [mmach10d+2], eax + mov eax, _asm1 + mov dword ptr [mmach3d+2], eax + mov dword ptr [mmach7d+2], eax + mov eax, _asm2 + mov dword ptr [mmach4d+2], eax + mov dword ptr [mmach8d+2], eax + jmp short mhlineskipmodify_ + +ALIGN 16 +PUBLIC mhlineskipmodify_ +mhlineskipmodify_: + + push ebp + + xor eax, eax + mov ebp, ebx + + test ecx, 00010000h + jnz short mbeghline + +msh1d: shr ebx, 26 +msh2d: shld ebx, esi, 6 + add ebp, _asm1 +mmach9d: mov al, byte ptr [ebx+88888888h] ;picoffs + add esi, _asm2 + cmp al, 255 + je mskip5 + + mmach10d: mov cl, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi], cl +mskip5: + inc edi + sub ecx, 65536 + jc mendhline + jmp short mbeghline + +ALIGN 16 +mpreprebeghline: ;1st only + mov al, cl +mmach2d: mov al, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi], al + +mprebeghline: + add edi, 2 + sub ecx, 131072 + jc short mendhline +mbeghline: +mmach3d: lea ebx, [ebp+88888888h] ;bxinc +msh3d: shr ebp, 26 +msh4d: shld ebp, esi, 6 +mmach4d: add esi, 88888888h ;byinc +mmach1d: mov cl, byte ptr [ebp+88888888h] ;picoffs +mmach7d: lea ebp, [ebx+88888888h] ;bxinc + +msh5d: shr ebx, 26 +msh6d: shld ebx, esi, 6 +mmach8d: add esi, 88888888h ;byinc +mmach5d: mov ch, byte ptr [ebx+88888888h] ;picoffs + + cmp cl, 255 + je short mskip1 + cmp ch, 255 + je short mpreprebeghline + + mov al, cl ;BOTH +mmach2da: mov bl, byte ptr [eax+88888888h] ;shadeoffs + mov al, ch +mmach2db: mov bh, byte ptr [eax+88888888h] ;shadeoffs + mov word ptr [edi], bx + add edi, 2 + sub ecx, 131072 + jnc short mbeghline + jmp mendhline +mskip1: ;2nd only + cmp ch, 255 + je short mprebeghline + + mov al, ch +mmach6d: mov al, byte ptr [eax+88888888h] ;shadeoffs + mov byte ptr [edi+1], al + add edi, 2 + sub ecx, 131072 + jnc short mbeghline +mendhline: + + pop ebp + ret + +ALIGN 16 +PUBLIC tsethlineshift_ +tsethlineshift_: + neg al + mov byte ptr [tsh1d+2], al + mov byte ptr [tsh2d+3], bl + mov byte ptr [tsh3d+2], al + mov byte ptr [tsh4d+3], bl + mov byte ptr [tsh5d+2], al + mov byte ptr [tsh6d+3], bl + ret + +ALIGN 16 +PUBLIC thline_ +thline_: + ;_asm1 = bxinc + ;_asm2 = byinc + ;_asm3 = shadeoffs + ;eax = picoffs + ;ebx = bx + ;ecx = cnt + ;edx = ? + ;esi = by + ;edi = p + + mov dword ptr [tmach1d+2], eax + mov dword ptr [tmach5d+2], eax + mov dword ptr [tmach9d+2], eax + mov eax, _asm3 + mov dword ptr [tmach2d+2], eax + mov dword ptr [tmach6d+2], eax + mov dword ptr [tmach10d+2], eax + mov eax, _asm1 + mov dword ptr [tmach3d+2], eax + mov dword ptr [tmach7d+2], eax + mov eax, _asm2 + mov dword ptr [tmach4d+2], eax + mov dword ptr [tmach8d+2], eax + jmp thlineskipmodify_ + +ALIGN 16 +PUBLIC thlineskipmodify_ +thlineskipmodify_: + + push ebp + + xor eax, eax + xor edx, edx + mov ebp, ebx + + test ecx, 00010000h + jnz short tbeghline + +tsh1d: shr ebx, 26 +tsh2d: shld ebx, esi, 6 + add ebp, _asm1 +tmach9d: mov al, byte ptr [ebx+88888888h] ;picoffs + add esi, _asm2 + cmp al, 255 + je tskip5 + +transrev4: +tmach10d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev5: + mov dh, byte ptr [edi] +tmach1: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi], al +tskip5: + inc edi + sub ecx, 65536 + jc tendhline + jmp short tbeghline + +ALIGN 16 +tprebeghline: + add edi, 2 + sub ecx, 131072 + jc short tendhline +tbeghline: +tmach3d: lea ebx, [ebp+88888888h] ;bxinc +tsh3d: shr ebp, 26 +tsh4d: shld ebp, esi, 6 +tmach4d: add esi, 88888888h ;byinc +tmach1d: mov cl, byte ptr [ebp+88888888h] ;picoffs +tmach7d: lea ebp, [ebx+88888888h] ;bxinc + +tsh5d: shr ebx, 26 +tsh6d: shld ebx, esi, 6 +tmach8d: add esi, 88888888h ;byinc +tmach5d: mov ch, byte ptr [ebx+88888888h] ;picoffs + + cmp cx, 0ffffh + je short tprebeghline + + mov bx, word ptr [edi] + + cmp cl, 255 + je short tskip1 + mov al, cl +transrev6: +tmach2d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev7: + mov dh, bl +tmach2: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi], al + + cmp ch, 255 + je short tskip2 +tskip1: + mov al, ch +transrev8: +tmach6d: mov dl, byte ptr [eax+88888888h] ;shadeoffs +transrev9: + mov dh, bh +tmach3: mov al, byte ptr [edx+88888888h] ;_transluc + mov byte ptr [edi+1], al +tskip2: + + add edi, 2 + sub ecx, 131072 + jnc tbeghline +tendhline: + + pop ebp + ret + + + ;eax=shiftval, ebx=palookup1, ecx=palookup2 +ALIGN 16 +PUBLIC setuptvlineasm2_ +setuptvlineasm2_: + mov byte ptr [tran2shra+2], al + mov byte ptr [tran2shrb+2], al + mov dword ptr [tran2pala+2], ebx + mov dword ptr [tran2palb+2], ecx + mov dword ptr [tran2palc+2], ebx + mov dword ptr [tran2pald+2], ecx + ret + + ;Pass: eax=vplc2, ebx=vinc1, ecx=bufplc1, edx=bufplc2, esi=vplc1, edi=p + ; _asm1=vinc2, _asm2=pend + ;Return: _asm1=vplc1, _asm2=vplc2 +ALIGN 16 +PUBLIC tvlineasm2_ +tvlineasm2_: + push ebp + + mov ebp, eax + + mov dword ptr [tran2inca+2], ebx + mov eax, _asm1 + mov dword ptr [tran2incb+2], eax + + mov dword ptr [tran2bufa+2], ecx ;bufplc1 + mov dword ptr [tran2bufb+2], edx ;bufplc2 + + mov eax, _asm2 + sub edi, eax + mov dword ptr [tran2edia+3], eax + mov dword ptr [tran2edic+2], eax + inc eax + mov dword ptr [tran2edie+2], eax +fixchaint2a: sub eax, 320 + mov dword ptr [tran2edif+2], eax + dec eax + mov dword ptr [tran2edib+3], eax + mov dword ptr [tran2edid+2], eax + + xor ecx, ecx + xor edx, edx + jmp short begintvline2 + + ;eax 0000000000 temp temp + ;ebx 0000000000 odat2 odat1 + ;ecx 0000000000000000 ndat1 + ;edx 0000000000000000 ndat2 + ;esi vplc1 + ;edi videoplc-------------- + ;ebp vplc2 + +ALIGN 16 + ;LEFT ONLY +skipdraw2: +transrev10: +tran2edic: mov ah, byte ptr [edi+88888888h] ;getpixel +transrev11: +tran2palc: mov al, byte ptr [ecx+88888888h] ;palookup1 +fixchaint2d: add edi, 320 +tran2trac: mov bl, byte ptr [eax+88888888h] ;_transluc +tran2edid: mov byte ptr [edi+88888888h-320], bl ;drawpixel + jnc short begintvline2 + jmp endtvline2 + +skipdraw1: + cmp dl, 255 + jne short skipdraw3 +fixchaint2b: add edi, 320 + jc short endtvline2 + +begintvline2: + mov eax, esi +tran2shra: shr eax, 88h ;globalshift + mov ebx, ebp +tran2shrb: shr ebx, 88h ;globalshift +tran2inca: add esi, 88888888h ;vinc1 +tran2incb: add ebp, 88888888h ;vinc2 +tran2bufa: mov cl, byte ptr [eax+88888888h] ;bufplc1 + cmp cl, 255 +tran2bufb: mov dl, byte ptr [ebx+88888888h] ;bufplc2 + je short skipdraw1 + cmp dl, 255 + je short skipdraw2 + + ;mov ax The transluscent reverse of both! + ;mov bl, ah + ;mov ah + ;mov bh + + ;BOTH +transrev12: +tran2edia: mov bx, word ptr [edi+88888888h] ;getpixels +transrev13: + mov ah, bl +transrev14: +tran2pala: mov al, byte ptr [ecx+88888888h] ;palookup1 +transrev15: +tran2palb: mov bl, byte ptr [edx+88888888h] ;palookup2 +fixchaint2c: add edi, 320 +tran2traa: mov al, byte ptr [eax+88888888h] ;_transluc +tran2trab: mov ah, byte ptr [ebx+88888888h] ;_transluc +tran2edib: mov word ptr [edi+88888888h-320], ax ;drawpixels + jnc short begintvline2 + jmp short endtvline2 + + ;RIGHT ONLY +skipdraw3: +transrev16: +tran2edie: mov ah, byte ptr [edi+88888889h] ;getpixel +transrev17: +tran2pald: mov al, byte ptr [edx+88888888h] ;palookup2 +fixchaint2e: add edi, 320 +tran2trad: mov bl, byte ptr [eax+88888888h] ;_transluc +tran2edif: mov byte ptr [edi+88888889h-320], bl ;drawpixel + jnc short begintvline2 + +endtvline2: + mov _asm1, esi + mov _asm2, ebp + + pop ebp + ret + + +BITSOFPRECISION equ 3 +BITSOFPRECISIONPOW equ 8 + +;Double-texture mapping with palette lookup +;eax: ylo1------------|----dat|----dat +;ebx: ylo2--------------------|----cnt +;ecx: 000000000000000000000000|---temp +;edx: xhi1-xlo1---------------|---yhi1 +;esi: xhi2-xlo2---------------|---yhi2 +;edi: ------------------------videopos +;ebp: ----------------------------temp + +ALIGN 16 +PUBLIC setupslopevlin2_ +setupslopevlin2_: + mov dword ptr [slop3+2], edx ;ptr + mov dword ptr [slop7+2], edx ;ptr + mov dword ptr [slop4+2], esi ;tptr + mov dword ptr [slop8+2], esi ;tptr + mov byte ptr [slop2+2], ah ;ybits + mov byte ptr [slop6+2], ah ;ybits + mov dword ptr [slop9+2], edi ;pinc + + mov edx, 1 + mov cl, al + add cl, ah + shl edx, cl + dec edx + mov cl, ah + ror edx, cl + + mov dword ptr [slop1+2], edx ;ybits...xbits + mov dword ptr [slop5+2], edx ;ybits...xbits + + ret + +ALIGN 16 +PUBLIC slopevlin2_ +slopevlin2_: + push ebp + xor ecx, ecx + +slopevlin2begin: + mov ebp, edx +slop1: and ebp, 88000088h ;ybits...xbits +slop2: rol ebp, 6 ;ybits + add eax, _asm1 ;xinc1<>(32-xbits)) +slop3: mov cl, byte ptr [ebp+88888888h] ;bufplc + + mov ebp, esi +slop4: mov al, byte ptr [ecx+88888888h] ;paloffs +slop5: and ebp, 88000088h ;ybits...xbits +slop6: rol ebp, 6 ;ybits + add ebx, _asm3 ;xinc2<>(32-xbits)) +slop8: mov ah, byte ptr [ecx+88888888h] ;paloffs + + dec bl + mov word ptr [edi], ax +slop9: lea edi, [edi+88888888h] ;pinc + jnz short slopevlin2begin + + pop ebp + mov eax, edi + ret + + +ALIGN 16 +PUBLIC setupslopevlin_ +setupslopevlin_: + mov dword ptr [slopmach3+3], ebx ;ptr + mov dword ptr [slopmach5+2], ecx ;pinc + neg ecx + mov dword ptr [slopmach6+2], ecx ;-pinc + + mov edx, 1 + mov cl, al + shl edx, cl + dec edx + mov cl, ah + shl edx, cl + mov dword ptr [slopmach7+2], edx + + neg ah + mov byte ptr [slopmach2+2], ah + + sub ah, al + mov byte ptr [slopmach1+2], ah + + fild dword ptr _asm1 + fstp dword ptr _asm2 + ret + +ALIGN 16 +PUBLIC slopevlin_ +slopevlin_: + mov _ebpbak, ebp + mov _espbak, esp + + sub ecx, esp + mov dword ptr [slopmach4+3], ecx + + fild dword ptr _asm3 +slopmach6: lea ebp, [eax+88888888h] + fadd dword ptr _asm2 + + mov _asm1, ebx + shl ebx, 3 + + mov eax, _globalx3 + mov ecx, _globaly3 + imul eax, ebx + imul ecx, ebx + add esi, eax + add edi, ecx + + mov ebx, edx + jmp short bigslopeloop +ALIGN 16 +bigslopeloop: + fst dword ptr _fpuasm + + mov eax, _fpuasm + add eax, eax + sbb edx, edx + mov ecx, eax + shr ecx, 24 + and eax, 00ffe000h + shr eax, 11 + sub cl, 2 + mov eax, dword ptr _reciptable[eax] + shr eax, cl + xor eax, edx + mov edx, _asm1 + mov ecx, _globalx3 + mov _asm1, eax + sub eax, edx + mov edx, _globaly3 + imul ecx, eax + imul eax, edx + + fadd dword ptr _asm2 + + cmp ebx, BITSOFPRECISIONPOW + mov _asm4, ebx + mov cl, bl + jl short slopeskipmin + mov cl, BITSOFPRECISIONPOW +slopeskipmin: + +;eax: yinc............. +;ebx: 0 0 0 ? +;ecx: xinc......... cnt +;edx: ? +;esi: xplc............. +;edi: yplc............. +;ebp: videopos + + mov ebx, esi + mov edx, edi + +beginnerslopeloop: +slopmach1: shr ebx, 20 + add esi, ecx +slopmach2: shr edx, 26 +slopmach7: and ebx, 88888888h + add edi, eax +slopmach5: add ebp, 88888888h ;pinc +slopmach3: mov dl, byte ptr [ebx+edx+88888888h] ;ptr +slopmach4: mov ebx, dword ptr [esp+88888888h] + sub esp, 4 + dec cl + mov al, byte ptr [ebx+edx] ;tptr + mov ebx, esi + mov [ebp], al + mov edx, edi + jnz short beginnerslopeloop + + mov ebx, _asm4 + sub ebx, BITSOFPRECISIONPOW + jg bigslopeloop + + ffree st(0) + + mov esp, _espbak + mov ebp, _ebpbak + ret + + +ALIGN 16 +PUBLIC setuprhlineasm4_ +setuprhlineasm4_: + mov dword ptr [rmach1a+2], eax + mov dword ptr [rmach1b+2], eax + mov dword ptr [rmach1c+2], eax + mov dword ptr [rmach1d+2], eax + mov dword ptr [rmach1e+2], eax + + mov dword ptr [rmach2a+2], ebx + mov dword ptr [rmach2b+2], ebx + mov dword ptr [rmach2c+2], ebx + mov dword ptr [rmach2d+2], ebx + mov dword ptr [rmach2e+2], ebx + + mov dword ptr [rmach3a+2], ecx + mov dword ptr [rmach3b+2], ecx + mov dword ptr [rmach3c+2], ecx + mov dword ptr [rmach3d+2], ecx + mov dword ptr [rmach3e+2], ecx + + mov dword ptr [rmach4a+2], edx + mov dword ptr [rmach4b+2], edx + mov dword ptr [rmach4c+2], edx + mov dword ptr [rmach4d+2], edx + mov dword ptr [rmach4e+2], edx + + mov dword ptr [rmach5a+2], esi + mov dword ptr [rmach5b+2], esi + mov dword ptr [rmach5c+2], esi + mov dword ptr [rmach5d+2], esi + mov dword ptr [rmach5e+2], esi + ret + + ;Non power of 2, non masking, with palookup method #1 (6 clock cycles) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: xlo + ;esi: ylo + ;edi: videopos/cnt + ;ebp: tempvar + ;esp: +ALIGN 16 +PUBLIC rhlineasm4_ +rhlineasm4_: + push ebp + + cmp eax, 0 + jle endrhline + + lea ebp, [edi-4] + sub ebp, eax + mov dword ptr [rmach6a+2], ebp + add ebp, 3 + mov dword ptr [rmach6b+2], ebp + mov edi, eax + test edi, 3 + jz short begrhline + jmp short startrhline1 + +ALIGN 16 +startrhline1: + mov cl, byte ptr [ebx] ;bufplc +rmach1e: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2e: sub esi, 88888888h ;ylo +rmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach4e: mov al, byte ptr [ecx+88888888h] ;palookup +rmach5e: and ebp, 88888888h ;tilesizy +rmach6b: mov byte ptr [edi+88888888h], al ;vidcntoffs + sub ebx, ebp + dec edi + test edi, 3 + jnz short startrhline1 + test edi, edi + jz endrhline + +begrhline: + mov cl, byte ptr [ebx] ;bufplc +rmach1a: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2a: sub esi, 88888888h ;ylo +rmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5a: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1b: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4a: mov ah, byte ptr [ecx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc +rmach2b: sub esi, 88888888h ;ylo +rmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5b: and ebp, 88888888h ;tilesizy +rmach4b: mov al, byte ptr [ecx+88888888h] ;palookup + sub ebx, ebp + + shl eax, 16 + + mov cl, byte ptr [ebx] ;bufplc +rmach1c: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach2c: sub esi, 88888888h ;ylo +rmach3c: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5c: and ebp, 88888888h ;tilesizy + sub ebx, ebp + +rmach1d: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmach4c: mov ah, byte ptr [ecx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc +rmach2d: sub esi, 88888888h ;ylo +rmach3d: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmach5d: and ebp, 88888888h ;tilesizy +rmach4d: mov al, byte ptr [ecx+88888888h] ;palookup + sub ebx, ebp + +rmach6a: mov dword ptr [edi+88888888h], eax ;vidcntoffs + sub edi, 4 + jnz begrhline +endrhline: + pop ebp + ret + +ALIGN 16 +PUBLIC setuprmhlineasm4_ +setuprmhlineasm4_: + mov dword ptr [rmmach1+2], eax + mov dword ptr [rmmach2+2], ebx + mov dword ptr [rmmach3+2], ecx + mov dword ptr [rmmach4+2], edx + mov dword ptr [rmmach5+2], esi + ret + +ALIGN 16 +PUBLIC rmhlineasm4_ +rmhlineasm4_: + push ebp + + cmp eax, 0 + jle short endrmhline + + lea ebp, [edi-1] + sub ebp, eax + mov dword ptr [rmmach6+2], ebp + mov edi, eax + jmp short begrmhline + +ALIGN 16 +begrmhline: + mov cl, byte ptr [ebx] ;bufplc +rmmach1: sub edx, 88888888h ;xlo + sbb ebp, ebp +rmmach2: sub esi, 88888888h ;ylo +rmmach3: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +rmmach5: and ebp, 88888888h ;tilesizy + cmp cl, 255 + je short rmskip +rmmach4: mov al, byte ptr [ecx+88888888h] ;palookup +rmmach6: mov byte ptr [edi+88888888h], al ;vidcntoffs +rmskip: + sub ebx, ebp + dec edi + jnz short begrmhline +endrmhline: + pop ebp + ret + +ALIGN 16 +PUBLIC setupqrhlineasm4_ +setupqrhlineasm4_: + mov dword ptr [qrmach2e+2], ebx + mov dword ptr [qrmach3e+2], ecx + xor edi, edi + sub edi, ecx + mov dword ptr [qrmach7a+2], edi + mov dword ptr [qrmach7b+2], edi + + add ebx, ebx + adc ecx, ecx + mov dword ptr [qrmach2a+2], ebx + mov dword ptr [qrmach2b+2], ebx + mov dword ptr [qrmach3a+2], ecx + mov dword ptr [qrmach3b+2], ecx + + mov dword ptr [qrmach4a+2], edx + mov dword ptr [qrmach4b+2], edx + mov dword ptr [qrmach4c+2], edx + mov dword ptr [qrmach4d+2], edx + mov dword ptr [qrmach4e+2], edx + ret + + ;Non power of 2, non masking, with palookup method (FASTER BUT NO SBB'S) + ;eax: dat dat dat dat + ;ebx: bufplc + ;ecx: 0 dat + ;edx: 0 dat + ;esi: ylo + ;edi: videopos/cnt + ;ebp: ? + ;esp: +ALIGN 16 +PUBLIC qrhlineasm4_ ;4 pixels in 9 cycles! 2.25 cycles/pixel +qrhlineasm4_: + push ebp + + cmp eax, 0 + jle endqrhline + + mov ebp, eax + test ebp, 3 + jz short skipqrhline1 + jmp short startqrhline1 + +ALIGN 16 +startqrhline1: + mov cl, byte ptr [ebx] ;bufplc + dec edi +qrmach2e: sub esi, 88888888h ;ylo + dec ebp +qrmach3e: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4e: mov al, byte ptr [ecx+88888888h] ;palookup + mov byte ptr [edi], al ;vidcntoffs + test ebp, 3 + jnz short startqrhline1 + test ebp, ebp + jz short endqrhline + +skipqrhline1: + mov cl, byte ptr [ebx] ;bufplc + jmp short begqrhline +ALIGN 16 +begqrhline: +qrmach7a: mov dl, byte ptr [ebx+88888888h] ;bufplc +qrmach2a: sub esi, 88888888h ;ylo +qrmach3a: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4a: mov ah, byte ptr [ecx+88888888h] ;palookup +qrmach4b: mov al, byte ptr [edx+88888888h] ;palookup + sub edi, 4 + shl eax, 16 + mov cl, byte ptr [ebx] ;bufplc +qrmach7b: mov dl, byte ptr [ebx+88888888h] ;bufplc +qrmach2b: sub esi, 88888888h ;ylo +qrmach3b: sbb ebx, 88888888h ;xhi*tilesizy + yhi+ycarry +qrmach4c: mov ah, byte ptr [ecx+88888888h] ;palookup +qrmach4d: mov al, byte ptr [edx+88888888h] ;palookup + mov cl, byte ptr [ebx] ;bufplc + mov dword ptr [edi], eax + sub ebp, 4 + jnz short begqrhline + +endqrhline: + pop ebp + ret + + +PUBLIC setupdrawslab_ +setupdrawslab_: + mov dword ptr [voxbpl1+2], eax + mov dword ptr [voxbpl2+2], eax + mov dword ptr [voxbpl3+2], eax + mov dword ptr [voxbpl4+2], eax + mov dword ptr [voxbpl5+2], eax + mov dword ptr [voxbpl6+2], eax + mov dword ptr [voxbpl7+2], eax + mov dword ptr [voxbpl8+2], eax + + mov dword ptr [voxpal1+2], ebx + mov dword ptr [voxpal2+2], ebx + mov dword ptr [voxpal3+2], ebx + mov dword ptr [voxpal4+2], ebx + mov dword ptr [voxpal5+2], ebx + mov dword ptr [voxpal6+2], ebx + mov dword ptr [voxpal7+2], ebx + mov dword ptr [voxpal8+2], ebx + ret + +ALIGN 16 +PUBLIC drawslab_ +drawslab_: + push ebp + cmp eax, 2 + je voxbegdraw2 + ja voxskip2 + xor eax, eax +voxbegdraw1: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + dec ecx + mov al, byte ptr [esi+ebp] +voxpal1: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl1: lea edi, [edi+88888888h] + jnz voxbegdraw1 + pop ebp + ret + +voxbegdraw2: + mov ebp, ebx + shr ebp, 16 + add ebx, edx + xor eax, eax + dec ecx + mov al, byte ptr [esi+ebp] +voxpal2: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl2: lea edi, [edi+88888888h] + jnz voxbegdraw2 + pop ebp + ret + +voxskip2: + cmp eax, 4 + jne voxskip4 + xor eax, eax +voxbegdraw4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal3: mov al, byte ptr [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword ptr [edi], eax +voxbpl3: add edi, 88888888h + dec ecx + jnz voxbegdraw4 + pop ebp + ret + +voxskip4: + add eax, edi + + test edi, 1 + jz voxskipslab1 + cmp edi, eax + je voxskipslab1 + + push eax + push ebx + push ecx + push edi +voxbegslab1: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal4: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl4: add edi, 88888888h + dec ecx + jnz voxbegslab1 + pop edi + pop ecx + pop ebx + pop eax + inc edi + +voxskipslab1: + push eax + test edi, 2 + jz voxskipslab2 + dec eax + cmp edi, eax + jge voxskipslab2 + + push ebx + push ecx + push edi +voxbegslab2: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal5: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl5: add edi, 88888888h + dec ecx + jnz voxbegslab2 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab2: + mov eax, [esp] + + sub eax, 3 + cmp edi, eax + jge voxskipslab3 + +voxprebegslab3: + push ebx + push ecx + push edi +voxbegslab3: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal6: mov al, byte ptr [eax+88888888h] + mov ah, al + shl eax, 8 + mov al, ah + shl eax, 8 + mov al, ah + mov dword ptr [edi], eax +voxbpl6: add edi, 88888888h + dec ecx + jnz voxbegslab3 + pop edi + pop ecx + pop ebx + add edi, 4 + + mov eax, [esp] + + sub eax, 3 + cmp edi, eax + jl voxprebegslab3 + +voxskipslab3: + mov eax, [esp] + + dec eax + cmp edi, eax + jge voxskipslab4 + + push ebx + push ecx + push edi +voxbegslab4: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal7: mov al, byte ptr [eax+88888888h] + mov ah, al + mov word ptr [edi], ax +voxbpl7: add edi, 88888888h + dec ecx + jnz voxbegslab4 + pop edi + pop ecx + pop ebx + add edi, 2 + +voxskipslab4: + pop eax + + cmp edi, eax + je voxskipslab5 + +voxbegslab5: + mov ebp, ebx + add ebx, edx + shr ebp, 16 + xor eax, eax + mov al, byte ptr [esi+ebp] +voxpal8: mov al, byte ptr [eax+88888888h] + mov byte ptr [edi], al +voxbpl8: add edi, 88888888h + dec ecx + jnz voxbegslab5 + +voxskipslab5: + pop ebp + ret + +;modify: loinc +;eax: | dat | dat | dat | dat | +;ebx: | loplc1 | +;ecx: | loplc2 | cnthi | cntlo | +;edx: |--------|--------|--------| hiplc1 | +;esi: |--------|--------|--------| hiplc2 | +;edi: |--------|--------|--------| vidplc | +;ebp: |--------|--------|--------| hiinc | + +PUBLIC stretchhline_ +stretchhline_: + push ebp + + mov eax, ebx + shl ebx, 16 + sar eax, 16 + and ecx, 0000ffffh + or ecx, ebx + + add esi, eax + mov eax, edx + mov edx, esi + + mov ebp, eax + shl eax, 16 + sar ebp, 16 + + add ecx, eax + adc esi, ebp + + add eax, eax + adc ebp, ebp + mov dword ptr [loinc1+2], eax + mov dword ptr [loinc2+2], eax + mov dword ptr [loinc3+2], eax + mov dword ptr [loinc4+2], eax + + inc ch + + jmp begloop + +begloop: + mov al, [edx] +loinc1: sub ebx, 88888888h + sbb edx, ebp + mov ah, [esi] +loinc2: sub ecx, 88888888h + sbb esi, ebp + sub edi, 4 + shl eax, 16 +loinc3: sub ebx, 88888888h + mov al, [edx] + sbb edx, ebp + mov ah, [esi] +loinc4: sub ecx, 88888888h + sbb esi, ebp + mov [edi], eax + dec cl + jnz begloop + dec ch + jnz begloop + + pop ebp + ret + + +PUBLIC mmxoverlay_ +mmxoverlay_: + pushfd ;Check if CPUID is available + pop eax + mov ebx, eax + xor eax, 00200000h + push eax + popfd + pushfd + pop eax + cmp eax, ebx + je pentium + xor eax, eax + dw 0a20fh + test eax, eax + jz pentium + mov eax, 1 + dw 0a20fh + and eax, 00000f00h + test edx, 00800000h ;Check if MMX is available + jz nommx + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumii + jmp pentiummmx +nommx: + cmp eax, 00000600h ;Check if P6 Family or not + jae pentiumpro +pentium: + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM II Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumii: + ;Hline overlay (MMX doens't help) + mov byte ptr [sethlinesizes_], 0xe9 + mov dword ptr [sethlinesizes_+1], (offset prosethlinesizes_)-(offset sethlinesizes_)-5 + mov byte ptr [setpalookupaddress_], 0xe9 + mov dword ptr [setpalookupaddress_+1], (offset prosetpalookupaddress_)-(offset setpalookupaddress_)-5 + mov byte ptr [setuphlineasm4_], 0xc3 ;ret (no code required) + mov byte ptr [hlineasm4_], 0xe9 + mov dword ptr [hlineasm4_+1], (offset prohlineasm4_)-(offset hlineasm4_)-5 + + ;Vline overlay + mov byte ptr [setupvlineasm_], 0xe9 + mov dword ptr [setupvlineasm_+1], (offset prosetupvlineasm_)-(offset setupvlineasm_)-5 + mov byte ptr [vlineasm4_], 0xe9 + mov dword ptr [vlineasm4_+1], (offset provlineasm4_)-(offset vlineasm4_)-5 + + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM MMX Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiummmx: + ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ PENTIUM PRO Overlays ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +pentiumpro: + ;Hline overlay (MMX doens't help) + mov byte ptr [sethlinesizes_], 0xe9 + mov dword ptr [sethlinesizes_+1], (offset prosethlinesizes_)-(offset sethlinesizes_)-5 + mov byte ptr [setpalookupaddress_], 0xe9 + mov dword ptr [setpalookupaddress_+1], (offset prosetpalookupaddress_)-(offset setpalookupaddress_)-5 + mov byte ptr [setuphlineasm4_], 0xc3 ;ret (no code required) + mov byte ptr [hlineasm4_], 0xe9 + mov dword ptr [hlineasm4_+1], (offset prohlineasm4_)-(offset hlineasm4_)-5 + + ;Vline overlay + mov byte ptr [setupvlineasm_], 0xe9 + mov dword ptr [setupvlineasm_+1], (offset prosetupvlineasm_)-(offset setupvlineasm_)-5 + mov byte ptr [vlineasm4_], 0xe9 + mov dword ptr [vlineasm4_+1], (offset provlineasm4_)-(offset vlineasm4_)-5 + + ret + +CODE ENDS +END diff --git a/polymer/build/src/baselayer.c b/polymer/build/src/baselayer.c new file mode 100644 index 000000000..66e567bf1 --- /dev/null +++ b/polymer/build/src/baselayer.c @@ -0,0 +1,206 @@ +#include "compat.h" +#include "osd.h" +#include "build.h" +#include "engineinfo.h" +#include "baselayer.h" + +#ifdef RENDERTYPEWIN +#include "winlayer.h" +#endif + +#ifdef USE_OPENGL +struct glinfo glinfo = { + "Unknown", // vendor + "Unknown", // renderer + "0.0.0", // version + "", // extensions + + 1.0, // max anisotropy + 0, // brga texture format + 0, // clamp-to-edge support + 0, // texture compression + 0, // non-power-of-two textures + 0, // multisampling + 0, // nvidia multisampling hint +}; +#endif + +static int osdfunc_dumpbuildinfo(const osdfuncparm_t *parm) +{ + OSD_Printf( + "Build engine compilation:\n" + " CFLAGS: %s\n" + " LIBS: %s\n" + " Host: %s\n" + " Compiler: %s\n" + " Built: %s\n", + _engine_cflags, + _engine_libs, + _engine_uname, + _engine_compiler, + _engine_date); + + return OSDCMD_OK; +} + +static void onvideomodechange(int newmode) { } +void (*baselayer_onvideomodechange)(int) = onvideomodechange; + +static int osdfunc_setrendermode(const osdfuncparm_t *parm) +{ + int m; + char *p; + + char *modestrs[] = { + "classic software", "polygonal flat-shaded software", + "polygonal textured software", "polygonal OpenGL" + }; + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + m = Bstrtol(parm->parms[0], &p, 10); + + if (m < 0 || m > 3) return OSDCMD_SHOWHELP; + + setrendermode(m); + OSD_Printf("Rendering method changed to %s\n", modestrs[ getrendermode() ] ); + + return OSDCMD_OK; +} + +#if defined(POLYMOST) && defined(USE_OPENGL) +#ifdef DEBUGGINGAIDS +static int osdcmd_hicsetpalettetint(const osdfuncparm_t *parm) +{ + long pal, cols[3], eff; + char *p; + + if (parm->numparms != 5) return OSDCMD_SHOWHELP; + + pal = Batol(parm->parms[0]); + cols[0] = Batol(parm->parms[1]); + cols[1] = Batol(parm->parms[2]); + cols[2] = Batol(parm->parms[3]); + eff = Batol(parm->parms[4]); + + hicsetpalettetint(pal,cols[0],cols[1],cols[2],eff); + + return OSDCMD_OK; +} +#endif + +static int osdcmd_glinfo(const osdfuncparm_t *parm) +{ + char *s,*t,*u,i; + + if (bpp == 8) { + OSD_Printf("glinfo: Not in OpenGL mode.\n"); + return OSDCMD_OK; + } + + OSD_Printf("OpenGL Information:\n" + " Version: %s\n" + " Vendor: %s\n" + " Renderer: %s\n" + " Maximum anisotropy: %.1f%s\n" + " BGRA textures: %s\n" + " Non-x^2 textures: %s\n" + " Texure compression: %s\n" + " Clamp-to-edge: %s\n" + " Multisampling: %s\n" + " Nvidia multisample hint: %s\n" + " Extensions:\n", + glinfo.version, + glinfo.vendor, + glinfo.renderer, + glinfo.maxanisotropy, glinfo.maxanisotropy>1.0?"":" (no anisotropic filtering)", + glinfo.bgra ? "supported": "not supported", + glinfo.texnpot ? "supported": "not supported", + glinfo.texcompr ? "supported": "not supported", + glinfo.clamptoedge ? "supported": "not supported", + glinfo.multisample ? "supported": "not supported", + glinfo.nvmultisamplehint ? "supported": "not supported" + ); + + s = Bstrdup(glinfo.extensions); + if (!s) OSD_Printf(glinfo.extensions); + else { + i = 0; t = u = s; + while (*t) { + if (*t == ' ') { + if (i&1) { + *t = 0; + OSD_Printf(" %s\n",u); + u = t+1; + } + i++; + } + t++; + } + if (i&1) OSD_Printf(" %s\n",u); + Bfree(s); + } + + return OSDCMD_OK; +} +#endif + +static int osdcmd_vars(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms < 1); + + if (!Bstrcasecmp(parm->name, "screencaptureformat")) { + const char *fmts[2][2] = { {"TGA", "PCX"}, {"0", "1"} }; + if (showval) { OSD_Printf("captureformat is %s\n", fmts[captureformat]); } + else { + int i,j; + for (j=0; j<2; j++) + for (i=0; i<2; i++) + if (!Bstrcasecmp(parm->parms[0], fmts[j][i])) break; + if (j == 2) return OSDCMD_SHOWHELP; + captureformat = i; + } + return OSDCMD_OK; + } +#ifdef SUPERBUILD + else if (!Bstrcasecmp(parm->name, "novoxmips")) { + if (showval) { OSD_Printf("novoxmips is %d\n", novoxmips); } + else { novoxmips = (atoi(parm->parms[0]) != 0); } + } + else if (!Bstrcasecmp(parm->name, "usevoxels")) { + if (showval) { OSD_Printf("usevoxels is %d\n", usevoxels); } + else { usevoxels = (atoi(parm->parms[0]) != 0); } + } +#endif + return OSDCMD_SHOWHELP; +} + +int baselayer_init(void) +{ +#ifdef POLYMOST + OSD_RegisterFunction("setrendermode","setrendermode : sets the engine's rendering mode.\n" + "Mode numbers are:\n" + " 0 - Classic Build software\n" + " 1 - Polygonal flat-shaded software\n" + " 2 - Polygonal textured software\n" +#ifdef USE_OPENGL + " 3 - Polygonal OpenGL\n" +#endif + , + osdfunc_setrendermode); +#endif + OSD_RegisterFunction("dumpbuildinfo","dumpbuildinfo: outputs engine compilation information",osdfunc_dumpbuildinfo); + OSD_RegisterFunction("screencaptureformat","screencaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars); +#ifdef SUPERBUILD + OSD_RegisterFunction("novoxmips","novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels",osdcmd_vars); + OSD_RegisterFunction("usevoxels","usevoxels: enable/disable automatic sprite->voxel rendering",osdcmd_vars); +#endif +#if defined(POLYMOST) && defined(USE_OPENGL) +#ifdef DEBUGGINGAIDS + OSD_RegisterFunction("hicsetpalettetint","hicsetpalettetint: sets palette tinting values",osdcmd_hicsetpalettetint); +#endif + OSD_RegisterFunction("glinfo","glinfo: shows OpenGL information about the current OpenGL mode",osdcmd_glinfo); +#endif + + return 0; +} + diff --git a/polymer/build/src/bstub.c b/polymer/build/src/bstub.c new file mode 100644 index 000000000..41c89f872 --- /dev/null +++ b/polymer/build/src/bstub.c @@ -0,0 +1,574 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "a.h" +#include "build.h" +#include "editor.h" +#include "pragmas.h" +#include "baselayer.h" +#include "names.h" +#include "osd.h" +#include "cache1d.h" + + +static char tempbuf[256]; + +#define NUMOPTIONS 9 +char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0,0}; +char keys[NUMBUILDKEYS] = +{ + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x33,0x34, + 0x9c,0x1c,0xd,0xc,0xf,0x45 +}; + + + +//static long hang = 0; +//static long rollangle = 0; + +//Detecting 2D / 3D mode: +// qsetmode is 200 in 3D mode +// qsetmode is 350/480 in 2D mode +// +//You can read these variables when F5-F8 is pressed in 3D mode only: +// +// If (searchstat == 0) WALL searchsector=sector, searchwall=wall +// If (searchstat == 1) CEILING searchsector=sector +// If (searchstat == 2) FLOOR searchsector=sector +// If (searchstat == 3) SPRITE searchsector=sector, searchwall=sprite +// If (searchstat == 4) MASKED WALL searchsector=sector, searchwall=wall +// +// searchsector is the sector of the selected item for all 5 searchstat's +// +// searchwall is undefined if searchstat is 1 or 2 +// searchwall is the wall if searchstat = 0 or 4 +// searchwall is the sprite if searchstat = 3 (Yeah, I know - it says wall, +// but trust me, it's the sprite number) + +long averagefps; +#define AVERAGEFRAMES 32 +static unsigned long frameval[AVERAGEFRAMES]; +static long framecnt = 0; + +char *defsfilename = "kenbuild.def"; +char *startwin_labeltext = "Starting Build Editor..."; +int nextvoxid = 0; + +int ExtPreInit(int *argc,char ***argv) +{ + return 0; +} + +int ExtInit(void) +{ + long i, rv = 0; + + /*printf("------------------------------------------------------------------------------\n"); + printf(" BUILD.EXE copyright(c) 1996 by Ken Silverman. You are granted the\n"); + printf(" right to use this software for your personal use only. This is a\n"); + printf(" special version to be used with \"Happy Fun KenBuild\" and may not work\n"); + printf(" properly with other Build engine games. Please refer to license.doc\n"); + printf(" for distribution rights\n"); + printf("------------------------------------------------------------------------------\n"); + getch(); + */ + + initgroupfile("stuff.dat"); + bpp = 8; + if (loadsetup("build.cfg") < 0) initprintf("Configuration file not found, using defaults.\n"), rv = 1; + Bmemcpy((void *)buildkeys,(void *)keys,NUMBUILDKEYS); //Trick to make build use setup.dat keys + if (option[4] > 0) option[4] = 0; + if (initengine()) { + wm_msgbox("Build Engine Initialisation Error", + "There was a problem initialising the Build engine: %s", engineerrstr); + return -1; + } + initinput(); + initmouse(); + + //You can load your own palette lookup tables here if you just + //copy the right code! + for(i=0;i<256;i++) + tempbuf[i] = ((i+32)&255); //remap colors for screwy palette sectors + makepalookup(16,tempbuf,0,0,0,1); + + kensplayerheight = 32; + zmode = 0; + defaultspritecstat = 0; + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + +#ifdef SUPERBUILD + tiletovox[PLAYER] = nextvoxid++; + tiletovox[BROWNMONSTER] = nextvoxid++; +#endif + +#ifdef _WIN32 +// allowtaskswitching(0); +#endif + return rv; +} + +void ExtUnInit(void) +{ + uninitgroupfile(); + writesetup("build.cfg"); +} + +void ExtSetupSpecialSpriteCols(void) +{ + return; +} + +//static long daviewingrange, daaspect, horizval1, horizval2; +void ExtPreCheckKeys(void) +{ + long /*cosang, sinang, dx, dy, mindx,*/ i, j, k; + + if (keystatus[0x3e]) //F4 - screen re-size + { + keystatus[0x3e] = 0; + + //cycle through all vesa modes, then screen-buffer mode + if (keystatus[0x2a]|keystatus[0x36]) { + setgamemode(!fullscreen, xdim, ydim, bpp); + } else { + + //cycle through all modes + j=-1; + + // work out a mask to select the mode + for (i=0; i> 3) + (xdim >> 4) + (xdim >> 6)) & (~7); + dy = (ydim + (ydim >> 3) + (ydim >> 4) + (ydim >> 6)) & (~7); + i = scale(320,ydim,xdim); + + if (waloff[4094] == 0) allocache(&waloff[4094],/*240L*384L*/dx*dy,&walock[4094]); + setviewtotile(4094,/*240L,384L*/dy,dx); + + cosang = sintable[(hang+512)&2047]; + sinang = sintable[hang&2047]; + + dx = dmulscale1(320,cosang,i,sinang); mindx = dx; + dy = dmulscale1(-i,cosang,320,sinang); + horizval1 = dy*(320>>1)/dx-1; + + dx = dmulscale1(320,cosang,-i,sinang); mindx = min(dx,mindx); + dy = dmulscale1(i,cosang,320,sinang); + horizval2 = dy*(320>>1)/dx+1; + + daviewingrange = scale(65536,16384*(xdim>>1),mindx-16); + daaspect = scale(daviewingrange,scale(320,tilesizx[4094],tilesizy[4094]),horizval2+6-horizval1); + setaspect(daviewingrange,scale(daaspect,ydim*320,xdim*i)); + horiz = 100-divscale15(horizval1+horizval2,daviewingrange); + } +#endif +} + +#ifdef SUPERBUILD +#define MAXVOXMIPS 5 +extern char *voxoff[][MAXVOXMIPS]; +void ExtAnalyzeSprites(void) +{ + long i, *longptr; + spritetype *tspr; + + for(i=0,tspr=&tsprite[0];ipicnum] >= 0) + { + switch(tspr->picnum) + { + case PLAYER: + if (!voxoff[ tiletovox[PLAYER] ][0]) { + if (qloadkvx(tiletovox[PLAYER],"voxel000.kvx")) { + tiletovox[PLAYER] = -1; + break; + } + } + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + longptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; + tspr->xrepeat = scale(tspr->xrepeat,56,longptr[2]); + tspr->yrepeat = scale(tspr->yrepeat,56,longptr[2]); + tspr->shade -= 6; + break; + case BROWNMONSTER: + if (!voxoff[ tiletovox[BROWNMONSTER] ][0]) { + if (qloadkvx(tiletovox[BROWNMONSTER],"voxel001.kvx")) { + tiletovox[BROWNMONSTER] = -1; + break; + } + } + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + break; + } + } + + tspr->shade += 6; + if (sector[tspr->sectnum].ceilingstat&1) + tspr->shade += sector[tspr->sectnum].ceilingshade; + else + tspr->shade += sector[tspr->sectnum].floorshade; + } +} +#endif + +void ExtCheckKeys(void) +{ + long i;//, p, y, dx, dy, cosang, sinang, bufplc, tsizy, tsizyup15; + long j; + + if (qsetmode == 200) //In 3D mode + { +#if 0 + if (hang != 0) + { + bufplc = waloff[4094]+(mulscale16(horiz-100,xdimenscale)+(tilesizx[4094]>>1))*tilesizy[4094]; + setviewback(); + cosang = sintable[(hang+512)&2047]; + sinang = sintable[hang&2047]; + dx = dmulscale1(xdim,cosang,ydim,sinang); + dy = dmulscale1(-ydim,cosang,xdim,sinang); + + begindrawing(); + tsizy = tilesizy[4094]; + tsizyup15 = (tsizy<<15); + dx = mulscale14(dx,daviewingrange); + dy = mulscale14(dy,daaspect); + sinang = mulscale14(sinang,daviewingrange); + cosang = mulscale14(cosang,daaspect); + p = ylookup[windowy1]+frameplace+windowx2+1; + for(y=windowy1;y<=windowy2;y++) + { + i = divscale16(tsizyup15,dx); + stretchhline(0,(xdim>>1)*i+tsizyup15,xdim>>2,i,mulscale32(i,dy)*tsizy+bufplc,p); + dx -= sinang; dy += cosang; p += ylookup[1]; + } + walock[4094] = 1; + + Bsprintf(tempbuf,"%d",(hang*180)>>10); + printext256(0L,8L,31,-1,tempbuf,1); + enddrawing(); + } +#endif + if (keystatus[0xa]) setaspect(viewingrange+(viewingrange>>8),yxaspect+(yxaspect>>8)); + if (keystatus[0xb]) setaspect(viewingrange-(viewingrange>>8),yxaspect-(yxaspect>>8)); + if (keystatus[0xc]) setaspect(viewingrange,yxaspect-(yxaspect>>8)); + if (keystatus[0xd]) setaspect(viewingrange,yxaspect+(yxaspect>>8)); + //if (keystatus[0x38]) setrollangle(rollangle+=((keystatus[0x2a]|keystatus[0x36])*6+2)); + //if (keystatus[0xb8]) setrollangle(rollangle-=((keystatus[0x2a]|keystatus[0x36])*6+2)); + //if (keystatus[0x1d]|keystatus[0x9d]) setrollangle(rollangle=0); + + begindrawing(); + + i = frameval[framecnt&(AVERAGEFRAMES-1)]; + j = frameval[framecnt&(AVERAGEFRAMES-1)] = getticks(); framecnt++; + if (i != j) averagefps = ((mul3(averagefps)+((AVERAGEFRAMES*1000)/(j-i)) )>>2); + Bsprintf(tempbuf,"%ld",averagefps); + printext256(0L,0L,31,-1,tempbuf,1); + + enddrawing(); + editinput(); + } + else + { + } +} + +void ExtCleanUp(void) +{ +} + +void ExtPreLoadMap(void) +{ +} + +void ExtLoadMap(const char *mapname) +{ + char title[256]; + Bsprintf(title, "BUILD by Ken Silverman - %s", mapname); + wm_setapptitle(title); +} + +void ExtPreSaveMap(void) +{ +} + +void ExtSaveMap(const char *mapname) +{ +} + +const char *ExtGetSectorCaption(short sectnum) +{ + if ((sector[sectnum].lotag|sector[sectnum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sector[sectnum].hitag, + (unsigned short)sector[sectnum].lotag); + } + return(tempbuf); +} + +const char *ExtGetWallCaption(short wallnum) +{ + if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)wall[wallnum].hitag, + (unsigned short)wall[wallnum].lotag); + } + return(tempbuf); +} + +const char *ExtGetSpriteCaption(short spritenum) +{ + if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sprite[spritenum].hitag, + (unsigned short)sprite[spritenum].lotag); + } + return(tempbuf); +} + +//printext16 parameters: +//printext16(long xpos, long ypos, short col, short backcol, +// char name[82], char fontsize) +// xpos 0-639 (top left) +// ypos 0-479 (top left) +// col 0-15 +// backcol 0-15, -1 is transparent background +// name +// fontsize 0=8*8, 1=3*5 + +//drawline16 parameters: +// drawline16(long x1, long y1, long x2, long y2, char col) +// x1, x2 0-639 +// y1, y2 0-143 (status bar is 144 high, origin is top-left of STATUS BAR) +// col 0-15 + +void ExtShowSectorData(short sectnum) //F5 +{ + int i; + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Sector %d",sectnum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + + printext16(8,ydim16+48,11,-1,"8*8 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",0); + printext16(8,ydim16+56,11,-1,"3*5 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",1); + + i=ydim16; ydim16=ydim; + drawline16(320,i+68,344,i+80,4); //Draw house + drawline16(344,i+80,344,i+116,4); + drawline16(344,i+116,296,i+116,4); + drawline16(296,i+116,296,i+80,4); + drawline16(296,i+80,320,i+68,4); + ydim16=i; + enddrawing(); + } +} + +void ExtShowWallData(short wallnum) //F6 +{ + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Wall %d",wallnum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + enddrawing(); + } +} + +void ExtShowSpriteData(short spritenum) //F6 +{ + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Sprite %d",spritenum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + enddrawing(); + } +} + +void ExtEditSectorData(short sectnum) //F7 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + //Ceiling + if (searchstat == 1) + sector[searchsector].ceilingpicnum++; //Just a stupid example + + //Floor + if (searchstat == 2) + sector[searchsector].floorshade++; //Just a stupid example + } + else //In 2D mode + { + Bsprintf(tempbuf,"Sector (%d) Nick's variable: ",sectnum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowSectorData(sectnum); + } +} + +void ExtEditWallData(short wallnum) //F8 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + } + else + { + Bsprintf(tempbuf,"Wall (%d) Nick's variable: ",wallnum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowWallData(wallnum); + } +} + +void ExtEditSpriteData(short spritenum) //F8 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + } + else + { + Bsprintf(tempbuf,"Sprite (%d) Nick's variable: ",spritenum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + printmessage16(""); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowSpriteData(spritenum); + } +} + +void faketimerhandler(void) +{ + sampletimer(); +} + + //Just thought you might want my getnumber16 code +/* +getnumber16(char namestart[80], short num, long maxnumber) +{ + char buffer[80]; + long j, k, n, danum, oldnum; + + danum = (long)num; + oldnum = danum; + while ((keystatus[0x1c] != 2) && (keystatus[0x1] == 0)) //Enter, ESC + { + sprintf(&buffer,"%s%ld_ ",namestart,danum); + printmessage16(buffer); + + for(j=2;j<=11;j++) //Scan numbers 0-9 + if (keystatus[j] > 0) + { + keystatus[j] = 0; + k = j-1; + if (k == 10) k = 0; + n = (danum*10)+k; + if (n < maxnumber) danum = n; + } + if (keystatus[0xe] > 0) // backspace + { + danum /= 10; + keystatus[0xe] = 0; + } + if (keystatus[0x1c] == 1) //L. enter + { + oldnum = danum; + keystatus[0x1c] = 2; + asksave = 1; + } + } + keystatus[0x1c] = 0; + keystatus[0x1] = 0; + return((short)oldnum); +} +*/ + +/* + * vim:ts=4: + */ + diff --git a/polymer/build/src/build.c b/polymer/build/src/build.c new file mode 100644 index 000000000..99d54b40a --- /dev/null +++ b/polymer/build/src/build.c @@ -0,0 +1,7422 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "build.h" +#include "compat.h" +#include "pragmas.h" +#include "osd.h" +#include "cache1d.h" +#include "editor.h" + +#define VERSION "("__DATE__" "__TIME__")" + +#include "baselayer.h" +#ifdef RENDERTYPEWIN +#include "winlayer.h" +#endif + + +#define TIMERINTSPERSECOND 120 + +#define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat])) +static long crctable[256]; +static char kensig[24]; + +extern int ExtInit(void); +extern int ExtPreInit(int *argc,char ***argv); +extern void ExtUnInit(void); +extern void ExtPreCheckKeys(void); +#ifdef SUPERBUILD +extern void ExtAnalyzeSprites(void); +#endif +extern void ExtCheckKeys(void); +extern void ExtLoadMap(const char *mapname); +extern void ExtSaveMap(const char *mapname); +extern const char *ExtGetSectorCaption(short sectnum); +extern const char *ExtGetWallCaption(short wallnum); +extern const char *ExtGetSpriteCaption(short spritenum); +extern void ExtShowSectorData(short sectnum); +extern void ExtShowWallData(short wallnum); +extern void ExtShowSpriteData(short spritenum); +extern void ExtEditSectorData(short sectnum); +extern void ExtEditWallData(short wallnum); +extern void ExtEditSpriteData(short spritenum); +extern char ExtCustomSpriteColor(short picnum); +extern void ExtSetupSpecialSpriteCols(void); + +extern char spritecol2d[MAXTILES][2]; + +char noclip=0; + +void _printmessage16(char name[82]); + +long vel, svel, angvel; + +char buildkeys[NUMBUILDKEYS] = +{ + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x33,0x34, + 0x9c,0x1c,0xd,0xc,0xf,0x45 +}; + +long posx, posy, posz, horiz = 100; +long mousexsurp = 0, mouseysurp = 0; +short ang, cursectnum; +long hvel; + +long grponlymode = 0; +extern long editorgridextent; // in engine.c +extern double msens; + +long synctics = 0, lockclock = 0; + +extern char vgacompatible; + +extern char picsiz[MAXTILES]; +extern long startposx, startposy, startposz; +extern short startang, startsectnum; +extern long frameplace, ydim16, halfxdim16, midydim16; +long xdim2d = 640, ydim2d = 480, xdimgame = 640, ydimgame = 480, bppgame = 8; + +extern long cachesize, artsize; + +static short oldmousebstatus = 0; +short brightness = 0; +long zlock = 0x7fffffff, zmode = 0, whitecol, kensplayerheight = 32; +short defaultspritecstat = 0; + +static short localartfreq[MAXTILES]; +static short localartlookup[MAXTILES], localartlookupnum; + +char tempbuf[4096]; + +char names[MAXTILES][25]; + +short asksave = 0; +extern short editstatus, searchit; +extern long searchx, searchy; //search input +extern short searchsector, searchwall, searchstat; //search output +long osearchx, osearchy; //old search input + +extern long pointhighlight, linehighlight, highlightcnt; +short grid = 3, gridlock = 1, showtags = 1; +long zoom = 768, gettilezoom = 1; +long lastpm16time; + +long numsprites; +extern long mapversion; + +short highlight[MAXWALLS]; +short highlightsector[MAXSECTORS], highlightsectorcnt = -1; +extern char textfont[128][8]; + +static char pskysearch[MAXSECTORS]; + +short temppicnum, tempcstat, templotag, temphitag, tempextra; +char tempshade, temppal, tempvis, tempxrepeat, tempyrepeat; +char somethingintab = 255; + +char mlook = 0; + +static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH]; + +static CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL; +static int numdirs=0, numfiles=0; +static int currentlist=0; + +static long repeatcountx, repeatcounty; + +static long fillist[640]; + +long mousx, mousy; + +static char scantoasc[128] = +{ + 0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0, + 'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s', + 'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v', + 'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0, + 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', + '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +static char scantoascwithshift[128] = +{ + 0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0, + 'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S', + 'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V', + 'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0, + 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', + '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + + + +char changechar(char dachar, long dadir, char smooshyalign, char boundcheck); +long adjustmark(long *xplc, long *yplc, short danumwalls); +long checkautoinsert(long dax, long day, short danumwalls); +void keytimerstuff(void); +long clockdir(short wallstart); +void flipwalls(short numwalls, short newnumwalls); +void insertpoint(short linehighlight, long dax, long day); +void deletepoint(short point); +long deletesector(short sucksect); +long checksectorpointer(short i, short sectnum); +void fixrepeats(short i); +short loopinside(long x, long y, short startwall); +long fillsector(short sectnum, char fillcolor); +short whitelinescan(short dalinehighlight); +void printcoords16(long posxe, long posye, short ange); +void copysector(short soursector, short destsector, short deststartwall, char copystat); +void showsectordata(short sectnum); +void showwalldata(short wallnum); +void showspritedata(short spritenum); +long drawtilescreen(long pictopleft, long picbox); +void overheadeditor(void); +long getlinehighlight(long xplc, long yplc); +void fixspritesectors(void); +long movewalls(long start, long offs); +long loadnames(void); +void updatenumsprites(void); +void getclosestpointonwall(long x, long y, long dawall, long *nx, long *ny); +void initcrc(void); +void AutoAlignWalls(long nWall0, long ply); +long gettile(long tilenum); + +long menuselect(void); +long getfilenames(char *path, char kind[6]); +void clearfilenames(void); + +void clearkeys(void) { memset(keystatus,0,sizeof(keystatus)); } + +static int osdcmd_restartvid(const osdfuncparm_t *parm) +{ + extern long qsetmode; + + if (qsetmode != 200) return OSDCMD_OK; + + resetvideomode(); + if (setgamemode(fullscreen,xdim,ydim,bpp)) + OSD_Printf("restartvid: Reset failed...\n"); + + return OSDCMD_OK; +} + +static int osdcmd_vidmode(const osdfuncparm_t *parm) +{ + long newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; + extern long qsetmode; + + if (qsetmode != 200) return OSDCMD_OK; + + switch (parm->numparms) { + case 1: // bpp switch + newbpp = Batol(parm->parms[0]); + break; + case 4: // fs, res, bpp switch + newfullscreen = (Batol(parm->parms[3]) != 0); + case 3: // res & bpp switch + newbpp = Batol(parm->parms[2]); + case 2: // res switch + newx = Batol(parm->parms[0]); + newy = Batol(parm->parms[1]); + break; + default: return OSDCMD_SHOWHELP; + } + + if (setgamemode(newfullscreen,newx,newy,newbpp)) + OSD_Printf("vidmode: Mode change failed!\n"); + xdimgame = newx; ydimgame = newy; bppgame = newbpp; fullscreen = newfullscreen; + return OSDCMD_OK; +} + +#ifdef RENDERTYPEWIN +int DoLaunchWindow(int initval); // buildstartwin.c +#endif + +extern char *defsfilename; // set in bstub.c +int app_main(int argc, char **argv) +{ + char ch, quitflag, forcesetup = 0, grpstoadd = 0; + char **grps = NULL; + long i, j, k; + + pathsearchmode = 1; // unrestrict findfrompath so that full access to the filesystem can be had + +#ifdef USE_OPENGL + OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid); + OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); +#endif + + wm_setapptitle("Mapster32"); + + if ((i = ExtPreInit(&argc,&argv)) < 0) return -1; + +#ifdef RENDERTYPEWIN + backgroundidle = 1; +#endif + + editstatus = 1; + boardfilename[0] = 0; + for (i=1; i 0) { + for (i=0;i k) { k = j; whitecol = i; } + } + + for(i=0;i 0) + { + keystatus[1] = 0; + begindrawing(); //{{{ + printext256(0,0,whitecol,0,"Are you sure you want to quit?",0); + enddrawing(); //}}} + + showframe(1); + synctics = totalclock-lockclock; + lockclock += synctics; + + while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) + { + if (handleevents()) { + if (quitevent) { + quitflag = 1; + break; + } + } + + if (keystatus[0x15] != 0) { + keystatus[0x15] = 0; + quitflag = 1; break; + } + } + while(keystatus[1]) + { + keystatus[1] = 0; + quitevent = 0; + goto CANCEL; + } + } + } + + if (asksave) + { + begindrawing(); //{{{ + printext256(0,8,whitecol,0,"Save changes?",0); + showframe(1); //}}} + + while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]|keystatus[0x2e]) == 0) + { + if (handleevents()) if (quitevent) break; // like saying no + + if (keystatus[0x15] != 0) { + keystatus[0x15] = 0; + + updatesector(startposx,startposy,&startsectnum); + ExtPreSaveMap(); + saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap(boardfilename); + break; + } + } + while(keystatus[1]||keystatus[0x2e]) + { + keystatus[1] = 0; + keystatus[0x2e] = 0; + quitevent = 0; + goto CANCEL; + } + } + + + clearfilenames(); + ExtUnInit(); + uninitengine(); + + Bprintf("Memory status: %ld(%ld) bytes\n",cachesize,artsize); + Bprintf("%s\n",kensig); + return(0); +} + +void showmouse(void) +{ + int i; + + for(i=1;i<=4;i++) + { + plotpixel(searchx+i,searchy,whitecol); + plotpixel(searchx-i,searchy,whitecol); + plotpixel(searchx,searchy-i,whitecol); + plotpixel(searchx,searchy+i,whitecol); + } +} + +void editinput(void) +{ + char smooshyalign, repeatpanalign, *ptr, buffer[80]; + short sectnum, nextsectnum, startwall, endwall, dasector, daang; + long mousz, bstatus; + long i, j, k, cnt, templong=0, doubvel, changedir, wallfind[2], daz[2]; + long dashade[2], goalz, xvect, yvect, hiz, loz; + short hitsect, hitwall, hitsprite; + long hitx, hity, hitz, dax, day, hihit, lohit; + + if (keystatus[0x57] > 0) //F11 - brightness + { + keystatus[0x57] = 0; + brightness++; + if (brightness >= 16) brightness = 0; + setbrightness(brightness,palette,0); + } + if (keystatus[88] > 0) //F12 + { + screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); + keystatus[88] = 0; + } + + mousz = 0; + getmousevalues(&mousx,&mousy,&bstatus); + mousx = (mousx<<16)+mousexsurp; + mousy = (mousy<<16)+mouseysurp; + { + ldiv_t ld; + ld = ldiv((long)((double)mousx*msens), (1<<16)); mousx = ld.quot; mousexsurp = ld.rem; + ld = ldiv((long)((double)mousy*msens), (1<<16)); mousy = ld.quot; mouseysurp = ld.rem; + } + + if (mlook == 1) + { + ang += (mousx); + horiz -= (mousy+mouseysurp); + if (horiz > 299) + horiz = 299; + if (horiz < -99) + horiz = -99; + searchx = (xdim/2); + searchy = (ydim/2); + osearchx = searchx-mousx; + osearchy = searchy-(mousy+mouseysurp); + } + else + { + osearchx = searchx; + osearchy = searchy; + searchx += mousx; + searchy += mousy; + if (searchx < 4) searchx = 4; + if (searchy < 4) searchy = 4; + if (searchx > xdim-5) searchx = xdim-5; + if (searchy > ydim-5) searchy = ydim-5; + } + + showmouse(); + + if (keystatus[0x3b] > 0) posx--; + if (keystatus[0x3c] > 0) posx++; + if (keystatus[0x3d] > 0) posy--; + if (keystatus[0x3e] > 0) posy++; + if (keystatus[0x43] > 0) ang--; + if (keystatus[0x44] > 0) ang++; + + if (angvel != 0) //ang += angvel * constant + { //ENGINE calculates angvel for you + doubvel = synctics; + if (keystatus[buildkeys[4]] > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (synctics>>1); + ang += ((angvel*doubvel)>>4); + ang = (ang+2048)&2047; + } + if ((vel|svel) != 0) + { + doubvel = synctics; + if (keystatus[buildkeys[4]] > 0) //Lt. shift doubles forward velocity + doubvel += synctics; + xvect = 0, yvect = 0; + if (vel != 0) + { + xvect += ((vel*doubvel*(long)sintable[(ang+2560)&2047])>>3); + yvect += ((vel*doubvel*(long)sintable[(ang+2048)&2047])>>3); + } + if (svel != 0) + { + xvect += ((svel*doubvel*(long)sintable[(ang+2048)&2047])>>3); + yvect += ((svel*doubvel*(long)sintable[(ang+1536)&2047])>>3); + } + if (noclip) + { + posx += xvect>>14; + posy += yvect>>14; + updatesector(posx,posy,&cursectnum); + } + else clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L,4L<<8,4L<<8,CLIPMASK0); + } + getzrange(posx,posy,posz,cursectnum,&hiz,&hihit,&loz,&lohit,128L,CLIPMASK0); + + if (keystatus[0x3a] > 0) + { + zmode++; + if (zmode == 3) zmode = 0; + if (zmode == 1) zlock = (loz-posz)&0xfffffc00; + keystatus[0x3a] = 0; + } + + if (zmode == 0) + { + goalz = loz-(kensplayerheight<<8); //playerheight pixels above floor + if (goalz < hiz+(16<<8)) //ceiling&floor too close + goalz = ((loz+hiz)>>1); + goalz += mousz; + if (keystatus[buildkeys[8]] > 0) //A (stand high) + { + if (keystatus[0x1d] > 0) + horiz = max(-100,horiz-((keystatus[buildkeys[4]]+1)*synctics*2)); + else + { + goalz -= (16<<8); + if (keystatus[buildkeys[4]] > 0) //Either shift key + goalz -= (24<<8); + } + } + if (keystatus[buildkeys[9]] > 0) //Z (stand low) + { + if (keystatus[0x1d] > 0) + horiz = min(300,horiz+((keystatus[buildkeys[4]]+1)*synctics*2)); + else + { + goalz += (12<<8); + if (keystatus[buildkeys[4]] > 0) //Either shift key + goalz += (12<<8); + } + } + + if (goalz != posz) + { + if (posz < goalz) hvel += 32; + if (posz > goalz) hvel = ((goalz-posz)>>3); + + posz += hvel; + if (posz > loz-(4<<8)) posz = loz-(4<<8), hvel = 0; + if (posz < hiz+(4<<8)) posz = hiz+(4<<8), hvel = 0; + } + } + else + { + goalz = posz; + if (keystatus[buildkeys[8]] > 0) //A + { + if (keystatus[0x1d] > 0) { + horiz = max(-100,horiz-((keystatus[buildkeys[4]]+1)*synctics*2)); + } else { + if (zmode != 1) + goalz -= (8<<8); + else + { + zlock += (4<<8); + keystatus[buildkeys[8]] = 0; + } + } + } + if (keystatus[buildkeys[9]] > 0) //Z (stand low) + { + if (keystatus[0x1d] > 0) { + horiz = min(300,horiz+((keystatus[buildkeys[4]]+1)*synctics*2)); + } else { + if (zmode != 1) + goalz += (8<<8); + else if (zlock > 0) + { + zlock -= (4<<8); + keystatus[buildkeys[9]] = 0; + } + } + } + + if (goalz < hiz+(4<<8)) goalz = hiz+(4<<8); + if (goalz > loz-(4<<8)) goalz = loz-(4<<8); + if (zmode == 1) goalz = loz-zlock; + if (goalz < hiz+(4<<8)) goalz = ((loz+hiz)>>1); //ceiling&floor too close + if (zmode == 1) posz = goalz; + + if (goalz != posz) + { + //if (posz < goalz) hvel += (32< goalz) hvel -= (32< goalz) hvel = ((synctics*-192)< loz-(4<<8)) posz = loz-(4<<8), hvel = 0; + if (posz < hiz+(4<<8)) posz = hiz+(4<<8), hvel = 0; + } + else + hvel = 0; + } + + searchit = 2; + if (searchstat >= 0) + { + if ((bstatus&(1|2|4)) > 0) + searchit = 0; + if (keystatus[0x4a] > 0) // - + { + keystatus[0x4a] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL + { + if (visibility < 16384) visibility += visibility; + } + else + { + if ((keystatus[0x2a]|keystatus[0x36]) == 0) + k = 16; else k = 1; + + if (highlightsectorcnt >= 0) + for(i=0;i 0) + { + for(i=0;i 0) + { + sector[searchsector].visibility++; + if (sector[searchsector].visibility == 240) + sector[searchsector].visibility = 239; + k--; + } + asksave = 1; + } + } + else + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) // + + { + keystatus[0x4e] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL + { + if (visibility > 32) visibility >>= 1; + } + else + { + if ((keystatus[0x2a]|keystatus[0x36]) == 0) + k = 16; else k = 1; + + if (highlightsectorcnt >= 0) + for(i=0;i 0) + { + for(i=0;i 0) + { + sector[searchsector].visibility--; + if (sector[searchsector].visibility == 239) + sector[searchsector].visibility = 240; + k--; + } + asksave = 1; + } + } + else + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) // PGUP + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) //CTRL - put sprite on ceiling + { + sprite[searchwall].z = getceilzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y); + if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1); + if ((sprite[searchwall].cstat&48) != 32) + sprite[searchwall].z += ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<2); + } + else + { + k = 0; + if (highlightcnt >= 0) + for(i=0;i 0) // PGDN + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i sector[searchsector].floorz) + sector[searchsector].ceilingz = sector[searchsector].floorz; + if (searchstat == 3) + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL - put sprite on ground + { + sprite[searchwall].z = getflorzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y); + if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1); + } + else + { + k = 0; + if (highlightcnt >= 0) + for(i=0;i 0) //TAB + { + if (searchstat == 0) + { + temppicnum = wall[searchwall].picnum; + tempshade = wall[searchwall].shade; + temppal = wall[searchwall].pal; + tempxrepeat = wall[searchwall].xrepeat; + tempyrepeat = wall[searchwall].yrepeat; + tempcstat = wall[searchwall].cstat; + templotag = wall[searchwall].lotag; + temphitag = wall[searchwall].hitag; + tempextra = wall[searchwall].extra; + } + if (searchstat == 1) + { + temppicnum = sector[searchsector].ceilingpicnum; + tempshade = sector[searchsector].ceilingshade; + temppal = sector[searchsector].ceilingpal; + tempvis = sector[searchsector].visibility; + tempxrepeat = sector[searchsector].ceilingxpanning; + tempyrepeat = sector[searchsector].ceilingypanning; + tempcstat = sector[searchsector].ceilingstat; + templotag = sector[searchsector].lotag; + temphitag = sector[searchsector].hitag; + tempextra = sector[searchsector].extra; + } + if (searchstat == 2) + { + temppicnum = sector[searchsector].floorpicnum; + tempshade = sector[searchsector].floorshade; + temppal = sector[searchsector].floorpal; + tempvis = sector[searchsector].visibility; + tempxrepeat = sector[searchsector].floorxpanning; + tempyrepeat = sector[searchsector].floorypanning; + tempcstat = sector[searchsector].floorstat; + templotag = sector[searchsector].lotag; + temphitag = sector[searchsector].hitag; + tempextra = sector[searchsector].extra; + } + if (searchstat == 3) + { + temppicnum = sprite[searchwall].picnum; + tempshade = sprite[searchwall].shade; + temppal = sprite[searchwall].pal; + tempxrepeat = sprite[searchwall].xrepeat; + tempyrepeat = sprite[searchwall].yrepeat; + tempcstat = sprite[searchwall].cstat; + templotag = sprite[searchwall].lotag; + temphitag = sprite[searchwall].hitag; + tempextra = sprite[searchwall].extra; + } + if (searchstat == 4) + { + temppicnum = wall[searchwall].overpicnum; + tempshade = wall[searchwall].shade; + temppal = wall[searchwall].pal; + tempxrepeat = wall[searchwall].xrepeat; + tempyrepeat = wall[searchwall].yrepeat; + tempcstat = wall[searchwall].cstat; + templotag = wall[searchwall].lotag; + temphitag = wall[searchwall].hitag; + tempextra = wall[searchwall].extra; + } + somethingintab = searchstat; + keystatus[0x0f] = 0; + } + if (keystatus[0x1c] > 0) //Left ENTER + { + if ((keystatus[0x2a]|keystatus[0x36]) > 0) //Either shift key + { + if (((searchstat == 0) || (searchstat == 4)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0)) //Ctrl-shift Enter (auto-shade) + { + dashade[0] = 127; + dashade[1] = -128; + i = searchwall; + do + { + if ((long)wall[i].shade < dashade[0]) dashade[0] = wall[i].shade; + if ((long)wall[i].shade > dashade[1]) dashade[1] = wall[i].shade; + + i = wall[i].point2; + } + while (i != searchwall); + + daang = getangle(wall[wall[searchwall].point2].x-wall[searchwall].x,wall[wall[searchwall].point2].y-wall[searchwall].y); + i = searchwall; + do + { + j = getangle(wall[wall[i].point2].x-wall[i].x,wall[wall[i].point2].y-wall[i].y); + k = ((j+2048-daang)&2047); + if (k > 1024) + k = 2048-k; + wall[i].shade = dashade[0]+mulscale10(k,dashade[1]-dashade[0]); + + i = wall[i].point2; + } + while (i != searchwall); + } + else if (somethingintab < 255) + { + if (searchstat == 0) wall[searchwall].shade = tempshade, wall[searchwall].pal = temppal; + if (searchstat == 1) + { + sector[searchsector].ceilingshade = tempshade, sector[searchsector].ceilingpal = temppal; + if ((somethingintab == 1) || (somethingintab == 2)) + sector[searchsector].visibility = tempvis; + } + if (searchstat == 2) + { + sector[searchsector].floorshade = tempshade, sector[searchsector].floorpal = temppal; + if ((somethingintab == 1) || (somethingintab == 2)) + sector[searchsector].visibility = tempvis; + } + if (searchstat == 3) sprite[searchwall].shade = tempshade, sprite[searchwall].pal = temppal; + if (searchstat == 4) wall[searchwall].shade = tempshade, wall[searchwall].pal = temppal; + } + } + else if (((searchstat == 0) || (searchstat == 4)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0) && (somethingintab < 255)) //Either ctrl key + { + i = searchwall; + do + { + wall[i].picnum = temppicnum; + wall[i].shade = tempshade; + wall[i].pal = temppal; + if ((somethingintab == 0) || (somethingintab == 4)) + { + wall[i].xrepeat = tempxrepeat; + wall[i].yrepeat = tempyrepeat; + wall[i].cstat = tempcstat; + } + fixrepeats((short)i); + i = wall[i].point2; + } + while (i != searchwall); + } + else if (((searchstat == 1) || (searchstat == 2)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0) && (somethingintab < 255)) //Either ctrl key + { + clearbuf(&pskysearch[0],(long)((numsectors+3)>>2),0L); + if (searchstat == 1) + { + i = searchsector; + if ((sector[i].ceilingstat&1) > 0) + pskysearch[i] = 1; + + while (pskysearch[i] == 1) + { + sector[i].ceilingpicnum = temppicnum; + sector[i].ceilingshade = tempshade; + sector[i].ceilingpal = temppal; + if ((somethingintab == 1) || (somethingintab == 2)) + { + sector[i].ceilingxpanning = tempxrepeat; + sector[i].ceilingypanning = tempyrepeat; + sector[i].ceilingstat = tempcstat; + } + pskysearch[i] = 2; + + startwall = sector[i].wallptr; + endwall = startwall + sector[i].wallnum - 1; + for(j=startwall;j<=endwall;j++) + { + k = wall[j].nextsector; + if (k >= 0) + if ((sector[k].ceilingstat&1) > 0) + if (pskysearch[k] == 0) + pskysearch[k] = 1; + } + + for(j=0;j 0) + pskysearch[i] = 1; + + while (pskysearch[i] == 1) + { + sector[i].floorpicnum = temppicnum; + sector[i].floorshade = tempshade; + sector[i].floorpal = temppal; + if ((somethingintab == 1) || (somethingintab == 2)) + { + sector[i].floorxpanning = tempxrepeat; + sector[i].floorypanning = tempyrepeat; + sector[i].floorstat = tempcstat; + } + pskysearch[i] = 2; + + startwall = sector[i].wallptr; + endwall = startwall + sector[i].wallnum - 1; + for(j=startwall;j<=endwall;j++) + { + k = wall[j].nextsector; + if (k >= 0) + if ((sector[k].floorstat&1) > 0) + if (pskysearch[k] == 0) + pskysearch[k] = 1; + } + + for(j=0;j 0) && (tilesizy[k] > 0)) + { + j = k; + break; + } + sprite[searchwall].picnum = j; + } + sprite[searchwall].shade = tempshade; + sprite[searchwall].pal = temppal; + if (somethingintab == 3) + { + sprite[searchwall].xrepeat = tempxrepeat; + sprite[searchwall].yrepeat = tempyrepeat; + if (sprite[searchwall].xrepeat < 1) sprite[searchwall].xrepeat = 1; + if (sprite[searchwall].yrepeat < 1) sprite[searchwall].yrepeat = 1; + sprite[searchwall].cstat = tempcstat; + sprite[searchwall].lotag = templotag; + sprite[searchwall].hitag = temphitag; + sprite[searchwall].extra = tempextra; + } + } + if (searchstat == 4) + { + wall[searchwall].overpicnum = temppicnum; + if (wall[searchwall].nextwall >= 0) + wall[wall[searchwall].nextwall].overpicnum = temppicnum; + wall[searchwall].shade = tempshade; + wall[searchwall].pal = temppal; + if (somethingintab == 4) + { + wall[searchwall].xrepeat = tempxrepeat; + wall[searchwall].yrepeat = tempyrepeat; + wall[searchwall].cstat = tempcstat; + wall[searchwall].lotag = templotag; + wall[searchwall].hitag = temphitag; + wall[searchwall].extra = tempextra; + } + fixrepeats(searchwall); + } + } + asksave = 1; + keystatus[0x1c] = 0; + } + if (keystatus[0x2e] > 0) //C + { + keystatus[0x2e] = 0; + if (keystatus[0x38] > 0) //Alt-C + { + if (somethingintab < 255) + { + switch(searchstat) + { + case 0: + j = wall[searchwall].picnum; + for(i=0;i 0) //V + { + if (searchstat == 0) templong = wall[searchwall].picnum; + if (searchstat == 1) templong = sector[searchsector].ceilingpicnum; + if (searchstat == 2) templong = sector[searchsector].floorpicnum; + if (searchstat == 3) templong = sprite[searchwall].picnum; + if (searchstat == 4) templong = wall[searchwall].overpicnum; + templong = gettile(templong); + if (searchstat == 0) wall[searchwall].picnum = templong; + if (searchstat == 1) sector[searchsector].ceilingpicnum = templong; + if (searchstat == 2) sector[searchsector].floorpicnum = templong; + if (searchstat == 3) sprite[searchwall].picnum = templong; + if (searchstat == 4) + { + wall[searchwall].overpicnum = templong; + if (wall[searchwall].nextwall >= 0) + wall[wall[searchwall].nextwall].overpicnum = templong; + } + asksave = 1; + keystatus[0x2f] = 0; + } + + if (keystatus[0x1a]) // [ + { + keystatus[0x1a] = 0; + if (keystatus[0x38]|keystatus[0xb8]) + { + i = wall[searchwall].nextsector; + if (i >= 0) + switch(searchstat) + { + case 0: case 1: case 4: + alignceilslope(searchsector,wall[searchwall].x,wall[searchwall].y,getceilzofslope(i,wall[searchwall].x,wall[searchwall].y)); + break; + case 2: + alignflorslope(searchsector,wall[searchwall].x,wall[searchwall].y,getflorzofslope(i,wall[searchwall].x,wall[searchwall].y)); + break; + } + } + else + { + i = 512; + if (keystatus[0x36]) i = 8; + if (keystatus[0x2a]) i = 1; + + if (searchstat == 1) + { + if (!(sector[searchsector].ceilingstat&2)) + sector[searchsector].ceilingheinum = 0; + sector[searchsector].ceilingheinum = max(sector[searchsector].ceilingheinum-i,-32768); + } + if (searchstat == 2) + { + if (!(sector[searchsector].floorstat&2)) + sector[searchsector].floorheinum = 0; + sector[searchsector].floorheinum = max(sector[searchsector].floorheinum-i,-32768); + } + } + + if (sector[searchsector].ceilingheinum == 0) + sector[searchsector].ceilingstat &= ~2; + else + sector[searchsector].ceilingstat |= 2; + + if (sector[searchsector].floorheinum == 0) + sector[searchsector].floorstat &= ~2; + else + sector[searchsector].floorstat |= 2; + asksave = 1; + } + if (keystatus[0x1b]) // ] + { + keystatus[0x1b] = 0; + if (keystatus[0x38]|keystatus[0xb8]) + { + i = wall[searchwall].nextsector; + if (i >= 0) + switch(searchstat) + { + case 1: + alignceilslope(searchsector,wall[searchwall].x,wall[searchwall].y,getceilzofslope(i,wall[searchwall].x,wall[searchwall].y)); + break; + case 0: case 2: case 4: + alignflorslope(searchsector,wall[searchwall].x,wall[searchwall].y,getflorzofslope(i,wall[searchwall].x,wall[searchwall].y)); + break; + } + } + else + { + i = 512; + if (keystatus[0x36]) i = 8; + if (keystatus[0x2a]) i = 1; + + if (searchstat == 1) + { + if (!(sector[searchsector].ceilingstat&2)) + sector[searchsector].ceilingheinum = 0; + sector[searchsector].ceilingheinum = min(sector[searchsector].ceilingheinum+i,32767); + } + if (searchstat == 2) + { + if (!(sector[searchsector].floorstat&2)) + sector[searchsector].floorheinum = 0; + sector[searchsector].floorheinum = min(sector[searchsector].floorheinum+i,32767); + } + } + + if (sector[searchsector].ceilingheinum == 0) + sector[searchsector].ceilingstat &= ~2; + else + sector[searchsector].ceilingstat |= 2; + + if (sector[searchsector].floorheinum == 0) + sector[searchsector].floorstat &= ~2; + else + sector[searchsector].floorstat |= 2; + + asksave = 1; + } + + smooshyalign = keystatus[0x4c]; + repeatpanalign = (keystatus[0x2a]|keystatus[0x36]); + if ((keystatus[0x4b]|keystatus[0x4d]) > 0) // 4 & 6 (keypad) + { + if ((repeatcountx == 0) || (repeatcountx > 16)) + { + changedir = 0; + if (keystatus[0x4b] > 0) changedir = -1; + if (keystatus[0x4d] > 0) changedir = 1; + + if ((searchstat == 0) || (searchstat == 4)) + { + if (repeatpanalign == 0) + wall[searchwall].xrepeat = changechar(wall[searchwall].xrepeat,changedir,smooshyalign,1); + else + wall[searchwall].xpanning = changechar(wall[searchwall].xpanning,changedir,smooshyalign,0); + } + if ((searchstat == 1) || (searchstat == 2)) + { + if (searchstat == 1) + sector[searchsector].ceilingxpanning = changechar(sector[searchsector].ceilingxpanning,changedir,smooshyalign,0); + else + sector[searchsector].floorxpanning = changechar(sector[searchsector].floorxpanning,changedir,smooshyalign,0); + } + if (searchstat == 3) + { + sprite[searchwall].xrepeat = changechar(sprite[searchwall].xrepeat,changedir,smooshyalign,1); + if (sprite[searchwall].xrepeat < 4) + sprite[searchwall].xrepeat = 4; + } + asksave = 1; + repeatcountx = max(1,repeatcountx); + } + repeatcountx += (synctics>>1); + } + else + repeatcountx = 0; + + if ((keystatus[0x48]|keystatus[0x50]) > 0) // 2 & 8 (keypad) + { + if ((repeatcounty == 0) || (repeatcounty > 16)) + { + changedir = 0; + if (keystatus[0x48] > 0) changedir = -1; + if (keystatus[0x50] > 0) changedir = 1; + + if ((searchstat == 0) || (searchstat == 4)) + { + if (repeatpanalign == 0) + wall[searchwall].yrepeat = changechar(wall[searchwall].yrepeat,changedir,smooshyalign,1); + else + wall[searchwall].ypanning = changechar(wall[searchwall].ypanning,changedir,smooshyalign,0); + } + if ((searchstat == 1) || (searchstat == 2)) + { + if (searchstat == 1) + sector[searchsector].ceilingypanning = changechar(sector[searchsector].ceilingypanning,changedir,smooshyalign,0); + else + sector[searchsector].floorypanning = changechar(sector[searchsector].floorypanning,changedir,smooshyalign,0); + } + if (searchstat == 3) + { + sprite[searchwall].yrepeat = changechar(sprite[searchwall].yrepeat,changedir,smooshyalign,1); + if (sprite[searchwall].yrepeat < 4) + sprite[searchwall].yrepeat = 4; + } + asksave = 1; + repeatcounty = max(1,repeatcounty); + } + repeatcounty += (synctics>>1); + //} + } + else + repeatcounty = 0; + + if (keystatus[0x33] > 0) // , Search & fix panning to the left (3D) + { + if (searchstat == 3) + { + i = searchwall; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048-1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048-128)&2047); + keystatus[0x33] = 0; + } + } + } + if (keystatus[0x34] > 0) // . Search & fix panning to the right (3D) + { + if ((searchstat == 0) || (searchstat == 4)) + { + AutoAlignWalls((long)searchwall,0L); + + /*wallfind[0] = searchwall; + cnt = 4096; + do + { + wallfind[1] = wall[wallfind[0]].point2; + j = -1; + if (wall[wallfind[1]].picnum == wall[searchwall].picnum) + j = wallfind[1]; + k = wallfind[1]; + + while ((wall[wallfind[1]].nextwall >= 0) && (wall[wall[wallfind[1]].nextwall].point2 != k)) + { + i = wall[wall[wallfind[1]].nextwall].point2; //break if going around in circles on red lines with same picture on both sides + if (wallfind[1] == wall[wall[i].nextwall].point2) + break; + + wallfind[1] = wall[wall[wallfind[1]].nextwall].point2; + if (wall[wallfind[1]].picnum == wall[searchwall].picnum) + j = wallfind[1]; + } + wallfind[1] = j; + + if ((j >= 0) && (wallfind[1] != searchwall)) + { + j = (wall[wallfind[0]].xpanning+(wall[wallfind[0]].xrepeat<<3)) % tilesizx[wall[wallfind[0]].picnum]; + wall[wallfind[1]].cstat &= ~8; //Set to non-flip + wall[wallfind[1]].cstat |= 4; //Set y-orientation + wall[wallfind[1]].xpanning = j; + + for(k=0;k<2;k++) + { + sectnum = sectorofwall((short)wallfind[k]); + nextsectnum = wall[wallfind[k]].nextsector; + + if (nextsectnum == -1) + { + if ((wall[wallfind[k]].cstat&4) == 0) + daz[k] = sector[sectnum].ceilingz; + else + daz[k] = sector[sectnum].floorz; + } + else //topstep + { + if (sector[nextsectnum].ceilingz > sector[sectnum].ceilingz) + daz[k] = sector[nextsectnum].ceilingz; + else if (sector[nextsectnum].floorz < sector[sectnum].floorz) + daz[k] = sector[nextsectnum].floorz; + } + } + + j = (picsiz[wall[searchwall].picnum]>>4); + if ((1<>(j+3)))&255); + wall[wallfind[1]].ypanning = j; + wall[wallfind[1]].yrepeat = wall[wallfind[0]].yrepeat; + if (nextsectnum >= 0) + if (sector[nextsectnum].ceilingz >= sector[sectnum].ceilingz) + if (sector[nextsectnum].floorz <= sector[sectnum].floorz) + { + if (wall[wall[wallfind[1]].nextwall].picnum == wall[searchwall].picnum) + { + wall[wall[wallfind[1]].nextwall].yrepeat = wall[wallfind[0]].yrepeat; + if ((wall[wall[wallfind[1]].nextwall].cstat&4) == 0) + daz[1] = sector[nextsectnum].floorz; + else + daz[1] = sector[sectnum].ceilingz; + wall[wall[wallfind[1]].nextwall].ypanning = j; + } + } + } + wallfind[0] = wallfind[1]; + cnt--; + } + while ((wall[wallfind[0]].picnum == wall[searchwall].picnum) && (wallfind[0] != searchwall) && (cnt > 0)); + */ + + keystatus[0x34] = 0; + } + if (searchstat == 3) + { + i = searchwall; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048+1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048+128)&2047); + keystatus[0x34] = 0; + } + } + } + if (keystatus[0x35] > 0) // /? Reset panning&repeat to 0 + { + if ((searchstat == 0) || (searchstat == 4)) + { + wall[searchwall].xpanning = 0; + wall[searchwall].ypanning = 0; + wall[searchwall].xrepeat = 8; + wall[searchwall].yrepeat = 8; + wall[searchwall].cstat = 0; + fixrepeats((short)searchwall); + } + if (searchstat == 1) + { + sector[searchsector].ceilingxpanning = 0; + sector[searchsector].ceilingypanning = 0; + sector[searchsector].ceilingstat &= ~2; + sector[searchsector].ceilingheinum = 0; + } + if (searchstat == 2) + { + sector[searchsector].floorxpanning = 0; + sector[searchsector].floorypanning = 0; + sector[searchsector].floorstat &= ~2; + sector[searchsector].floorheinum = 0; + } + if (searchstat == 3) + { + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + { + sprite[searchwall].xrepeat = sprite[searchwall].yrepeat; + } + else + { + sprite[searchwall].xrepeat = 64; + sprite[searchwall].yrepeat = 64; + } + } + keystatus[0x35] = 0; + asksave = 1; + } + + if (keystatus[0x19] > 0) // P (parallaxing sky) + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) + { + parallaxtype++; + if (parallaxtype == 3) + parallaxtype = 0; + } + else if ((keystatus[0x38]|keystatus[0xb8]) > 0) + { + switch (searchstat) + { + case 0: case 4: + Bstrcpy(buffer,"Wall pal: "); + wall[searchwall].pal = getnumber256(buffer,wall[searchwall].pal,256L,0); + break; + case 1: + Bstrcpy(buffer,"Ceiling pal: "); + sector[searchsector].ceilingpal = getnumber256(buffer,sector[searchsector].ceilingpal,256L,0); + break; + case 2: + Bstrcpy(buffer,"Floor pal: "); + sector[searchsector].floorpal = getnumber256(buffer,sector[searchsector].floorpal,256L,0); + break; + case 3: + Bstrcpy(buffer,"Sprite pal: "); + sprite[searchwall].pal = getnumber256(buffer,sprite[searchwall].pal,256L,0); + break; + } + } + else + { + if ((searchstat == 0) || (searchstat == 1) || (searchstat == 4)) + { + sector[searchsector].ceilingstat ^= 1; + asksave = 1; + } + else if (searchstat == 2) + { + sector[searchsector].floorstat ^= 1; + asksave = 1; + } + } + keystatus[0x19] = 0; + } + + if (keystatus[0x20] != 0) //Alt-D (adjust sprite[].clipdist) + { + keystatus[0x20] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) + { + if (searchstat == 3) + { + Bstrcpy(buffer,"Sprite clipdist: "); + sprite[searchwall].clipdist = getnumber256(buffer,sprite[searchwall].clipdist,256L,0); + } + } + } + + if (keystatus[0x30] > 0) // B (clip Blocking xor) (3D) + { + if (searchstat == 3) + { + sprite[searchwall].cstat ^= 1; + sprite[searchwall].cstat &= ~256; + sprite[searchwall].cstat |= ((sprite[searchwall].cstat&1)<<8); + asksave = 1; + } + else + { + wall[searchwall].cstat ^= 1; + wall[searchwall].cstat &= ~64; + if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[searchwall].nextwall].cstat &= ~(1+64); + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&1); + } + asksave = 1; + } + keystatus[0x30] = 0; + } + if (keystatus[0x14] > 0) // T (transluscence for sprites/masked walls) + { + /*if (searchstat == 1) //Set masked/transluscent ceilings/floors + { + i = (sector[searchsector].ceilingstat&(128+256)); + sector[searchsector].ceilingstat &= ~(128+256); + switch(i) + { + case 0: sector[searchsector].ceilingstat |= 128; break; + case 128: sector[searchsector].ceilingstat |= 256; break; + case 256: sector[searchsector].ceilingstat |= 384; break; + case 384: sector[searchsector].ceilingstat |= 0; break; + } + asksave = 1; + } + if (searchstat == 2) + { + i = (sector[searchsector].floorstat&(128+256)); + sector[searchsector].floorstat &= ~(128+256); + switch(i) + { + case 0: sector[searchsector].floorstat |= 128; break; + case 128: sector[searchsector].floorstat |= 256; break; + case 256: sector[searchsector].floorstat |= 384; break; + case 384: sector[searchsector].floorstat |= 0; break; + } + asksave = 1; + }*/ + if (searchstat == 3) + { + if ((sprite[searchwall].cstat&2) == 0) + sprite[searchwall].cstat |= 2; + else if ((sprite[searchwall].cstat&512) == 0) + sprite[searchwall].cstat |= 512; + else + sprite[searchwall].cstat &= ~(2+512); + asksave = 1; + } + if (searchstat == 4) + { + if ((wall[searchwall].cstat&128) == 0) + wall[searchwall].cstat |= 128; + else if ((wall[searchwall].cstat&512) == 0) + wall[searchwall].cstat |= 512; + else + wall[searchwall].cstat &= ~(128+512); + + if (wall[searchwall].nextwall >= 0) + { + wall[wall[searchwall].nextwall].cstat &= ~(128+512); + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&(128+512)); + } + asksave = 1; + } + keystatus[0x14] = 0; + } + + if (keystatus[0x2] > 0) // 1 (make 1-way wall) + { + if (searchstat != 3) + { + wall[searchwall].cstat ^= 32; + asksave = 1; + } + else + { + sprite[searchwall].cstat ^= 64; + i = sprite[searchwall].cstat; + if ((i&48) == 32) + { + sprite[searchwall].cstat &= ~8; + if ((i&64) > 0) + if (posz > sprite[searchwall].z) + sprite[searchwall].cstat |= 8; + } + asksave = 1; + } + keystatus[0x2] = 0; + } + if (keystatus[0x3] > 0) // 2 (bottom wall swapping) + { + if (searchstat != 3) + { + wall[searchwall].cstat ^= 2; + asksave = 1; + } + keystatus[0x3] = 0; + } + if (keystatus[0x18] > 0) // O (top/bottom orientation - for doors) + { + if ((searchstat == 0) || (searchstat == 4)) + { + wall[searchwall].cstat ^= 4; + asksave = 1; + } + if (searchstat == 3) // O (ornament onto wall) (2D) + { + asksave = 1; + i = searchwall; + + hitscan(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum, + sintable[(sprite[i].ang+2560+1024)&2047], + sintable[(sprite[i].ang+2048+1024)&2047], + 0, + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + sprite[i].x = hitx; + sprite[i].y = hity; + sprite[i].z = hitz; + changespritesect(i,hitsect); + if (hitwall >= 0) + sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047); + + //Make sure sprite's in right sector + if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0) + { + j = wall[hitwall].point2; + sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y); + sprite[i].y += ksgn(wall[j].x-wall[hitwall].x); + } + } + keystatus[0x18] = 0; + } + if (keystatus[0x32] > 0) // M (masking walls) + { + if (searchstat != 3) + { + i = wall[searchwall].nextwall; + templong = (keystatus[0x2a]|keystatus[0x36]); + if (i >= 0) + { + wall[searchwall].cstat ^= 16; + if ((wall[searchwall].cstat&16) > 0) + { + wall[searchwall].cstat &= ~8; + if (templong == 0) + { + wall[i].cstat |= 8; //auto other-side flip + wall[i].cstat |= 16; + wall[i].overpicnum = wall[searchwall].overpicnum; + } + } + else + { + wall[searchwall].cstat &= ~8; + if (templong == 0) + { + wall[i].cstat &= ~8; //auto other-side unflip + wall[i].cstat &= ~16; + } + } + wall[searchwall].cstat &= ~32; + if (templong == 0) wall[i].cstat &= ~32; + asksave = 1; + } + } + keystatus[0x32] = 0; + } + if (keystatus[0x23] > 0) // H (hitscan sensitivity) + { + if (searchstat == 3) + { + sprite[searchwall].cstat ^= 256; + asksave = 1; + } + else + { + wall[searchwall].cstat ^= 64; + if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[searchwall].nextwall].cstat &= ~64; + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&64); + } + asksave = 1; + } + keystatus[0x23] = 0; + } + if (keystatus[0x12] > 0) // E (expand) + { + if (searchstat == 1) + { + sector[searchsector].ceilingstat ^= 8; + asksave = 1; + } + if (searchstat == 2) + { + sector[searchsector].floorstat ^= 8; + asksave = 1; + } + keystatus[0x12] = 0; + } + if (keystatus[0x13] > 0) // R (relative alignment, rotation) + { + if (searchstat == 1) + { + sector[searchsector].ceilingstat ^= 64; + asksave = 1; + } + if (searchstat == 2) + { + sector[searchsector].floorstat ^= 64; + asksave = 1; + } + if (searchstat == 3) + { + i = sprite[searchwall].cstat; + if ((i&48) < 32) i += 16; else i &= ~48; + sprite[searchwall].cstat = i; + asksave = 1; + } + keystatus[0x13] = 0; + } + if (keystatus[0x21] > 0) //F (Flip) + { + keystatus[0x21] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT-F (relative alignmment flip) + { + if (searchstat != 3) + { + setfirstwall(searchsector,searchwall); + asksave = 1; + } + } + else + { + if ((searchstat == 0) || (searchstat == 4)) + { + i = wall[searchwall].cstat; + i = ((i>>3)&1)+((i>>7)&2); //3-x,8-y + switch(i) + { + case 0: i = 1; break; + case 1: i = 3; break; + case 2: i = 0; break; + case 3: i = 2; break; + } + i = ((i&1)<<3)+((i&2)<<7); + wall[searchwall].cstat &= ~0x0108; + wall[searchwall].cstat |= i; + asksave = 1; + } + if (searchstat == 1) //8-way ceiling flipping (bits 2,4,5) + { + i = sector[searchsector].ceilingstat; + i = (i&0x4)+((i>>4)&3); + switch(i) + { + case 0: i = 6; break; + case 6: i = 3; break; + case 3: i = 5; break; + case 5: i = 1; break; + case 1: i = 7; break; + case 7: i = 2; break; + case 2: i = 4; break; + case 4: i = 0; break; + } + i = (i&0x4)+((i&3)<<4); + sector[searchsector].ceilingstat &= ~0x34; + sector[searchsector].ceilingstat |= i; + asksave = 1; + } + if (searchstat == 2) //8-way floor flipping (bits 2,4,5) + { + i = sector[searchsector].floorstat; + i = (i&0x4)+((i>>4)&3); + switch(i) + { + case 0: i = 6; break; + case 6: i = 3; break; + case 3: i = 5; break; + case 5: i = 1; break; + case 1: i = 7; break; + case 7: i = 2; break; + case 2: i = 4; break; + case 4: i = 0; break; + } + i = (i&0x4)+((i&3)<<4); + sector[searchsector].floorstat &= ~0x34; + sector[searchsector].floorstat |= i; + asksave = 1; + } + if (searchstat == 3) + { + i = sprite[searchwall].cstat; + if (((i&48) == 32) && ((i&64) == 0)) + { + sprite[searchwall].cstat &= ~0xc; + sprite[searchwall].cstat |= (i&4)^4; + } + else + { + i = ((i>>2)&3); + switch(i) + { + case 0: i = 1; break; + case 1: i = 3; break; + case 2: i = 0; break; + case 3: i = 2; break; + } + i <<= 2; + sprite[searchwall].cstat &= ~0xc; + sprite[searchwall].cstat |= i; + } + asksave = 1; + } + } + } + if (keystatus[0x1f] > 0) //S (insert sprite) (3D) + { + dax = 16384; + day = divscale14(searchx-(xdim>>1),xdim>>1); + rotatepoint(0,0,dax,day,ang,&dax,&day); + + hitscan(posx,posy,posz,cursectnum, //Start position + dax,day,(scale(searchy,200,ydim)-horiz)*2000, //vector of 3D ang + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + if (hitsect >= 0) + { + dax = hitx; + day = hity; + if ((gridlock > 0) && (grid > 0)) + { + if ((searchstat == 0) || (searchstat == 4)) + { + hitz = (hitz&0xfffffc00); + } + else + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + } + + i = insertsprite(hitsect,0); + sprite[i].x = dax, sprite[i].y = day; + sprite[i].cstat = defaultspritecstat; + sprite[i].shade = 0; + sprite[i].pal = 0; + sprite[i].xrepeat = 64, sprite[i].yrepeat = 64; + sprite[i].xoffset = 0, sprite[i].yoffset = 0; + sprite[i].ang = 1536; + sprite[i].xvel = 0; sprite[i].yvel = 0; sprite[i].zvel = 0; + sprite[i].owner = -1; + sprite[i].clipdist = 32; + sprite[i].lotag = 0; + sprite[i].hitag = 0; + sprite[i].extra = -1; + + for(k=0;k localartfreq[j]) + j = k; + if (localartfreq[j] > 0) + sprite[i].picnum = j; + else + sprite[i].picnum = 0; + + if (somethingintab == 3) + { + sprite[i].picnum = temppicnum; + if ((tilesizx[temppicnum] <= 0) || (tilesizy[temppicnum] <= 0)) + { + j = 0; + for(k=0;k 0) && (tilesizy[k] > 0)) + { + j = k; + break; + } + sprite[i].picnum = j; + } + sprite[i].shade = tempshade; + sprite[i].pal = temppal; + sprite[i].xrepeat = tempxrepeat; + sprite[i].yrepeat = tempyrepeat; + if (sprite[i].xrepeat < 1) sprite[i].xrepeat = 1; + if (sprite[i].yrepeat < 1) sprite[i].yrepeat = 1; + sprite[i].cstat = tempcstat; + } + + j = ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); + if ((sprite[i].cstat&128) == 0) + sprite[i].z = min(max(hitz,getceilzofslope(hitsect,hitx,hity)+(j<<1)),getflorzofslope(hitsect,hitx,hity)); + else + sprite[i].z = min(max(hitz,getceilzofslope(hitsect,hitx,hity)+j),getflorzofslope(hitsect,hitx,hity)-j); + + if ((searchstat == 0) || (searchstat == 4)) + { + sprite[i].cstat = (sprite[i].cstat&~48)|(16+64); + if (hitwall >= 0) + sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047); + + //Make sure sprite's in right sector + if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0) + { + j = wall[hitwall].point2; + sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y); + sprite[i].y += ksgn(wall[j].x-wall[hitwall].x); + } + } + else + { + if (tilesizy[sprite[i].picnum] >= 32) sprite[i].cstat |= 1; + } + + updatenumsprites(); + asksave = 1; + } + + keystatus[0x1f] = 0; + } + if (keystatus[0xd3] > 0) + { + if (searchstat == 3) + { + deletesprite(searchwall); + updatenumsprites(); + asksave = 1; + } + keystatus[0xd3] = 0; + } + + if ((keystatus[0x3f]|keystatus[0x40]) > 0) //F5,F6 + { + switch(searchstat) + { + case 1: case 2: ExtShowSectorData(searchsector); break; + case 0: case 4: ExtShowWallData(searchwall); break; + case 3: ExtShowSpriteData(searchwall); break; + } + keystatus[0x3f] = 0, keystatus[0x40] = 0; + } + if ((keystatus[0x41]|keystatus[0x42]) > 0) //F7,F8 + { + switch(searchstat) + { + case 1: case 2: ExtEditSectorData(searchsector); break; + case 0: case 4: ExtEditWallData(searchwall); break; + case 3: ExtEditSpriteData(searchwall); break; + } + keystatus[0x41] = 0, keystatus[0x42] = 0; + } + + } + if (keystatus[buildkeys[14]] > 0) // Enter + { + overheadeditor(); + keystatus[buildkeys[14]] = 0; + } +} + +char changechar(char dachar, long dadir, char smooshyalign, char boundcheck) +{ + if (dadir < 0) + { + if ((dachar > 0) || (boundcheck == 0)) + { + dachar--; + if (smooshyalign > 0) + dachar = (dachar&0xf8); + } + } + else if (dadir > 0) + { + if ((dachar < 255) || (boundcheck == 0)) + { + dachar++; + if (smooshyalign > 0) + { + if (dachar >= 256-8) dachar = 255; + else dachar = ((dachar+7)&0xf8); + } + } + } + return(dachar); +} + +long gettile(long tilenum) +{ + char snotbuf[80], ch; + long i, j, k, otilenum, topleft, gap, temp, templong; + long xtiles, ytiles, tottiles; + + if (tilenum < 0) tilenum = 0; + + xtiles = (xdim>>6); ytiles = (ydim>>6); tottiles = xtiles*ytiles; + otilenum = tilenum; + + keystatus[0x2f] = 0; + for(i=0;i>1); + do + { + for(i=0;i= 0)) + { + templong = localartfreq[temp]; + localartfreq[temp] = localartfreq[temp+gap]; + localartfreq[temp+gap] = templong; + templong = localartlookup[temp]; + localartlookup[temp] = localartlookup[temp+gap]; + localartlookup[temp+gap] = templong; + + if (tilenum == temp) + tilenum = temp+gap; + else if (tilenum == temp+gap) + tilenum = temp; + + temp -= gap; + } + } + gap >>= 1; + } + while (gap > 0); + localartlookupnum = 0; + while (localartfreq[localartlookupnum] > 0) + localartlookupnum++; + + if (localartfreq[0] == 0) + { + tilenum = otilenum; + localartlookupnum = MAXTILES; + for(i=0;i MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); + while ((keystatus[0x1c]|keystatus[1]) == 0) + { + drawtilescreen(topleft,tilenum); + + if (handleevents()) { + if (quitevent) quitevent = 0; + } + + synctics = totalclock-lockclock; + lockclock += synctics; + + if ((keystatus[0x37] > 0) && (gettilezoom < 2)) + { + gettilezoom++; + topleft = ((tilenum/(xtiles< MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); + keystatus[0x37] = 0; + } + if ((keystatus[0xb5] > 0) && (gettilezoom > 0)) + { + gettilezoom--; + topleft = ((tilenum/(xtiles< MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); + keystatus[0xb5] = 0; + } + if ((keystatus[0xcb] > 0) && (tilenum > 0)) + tilenum--, keystatus[0xcb] = 0; + if ((keystatus[0xcd] > 0) && (tilenum < MAXTILES-1)) + tilenum++, keystatus[0xcd] = 0; + if ((keystatus[0xc8] > 0) && (tilenum >= (xtiles< 0) && (tilenum < MAXTILES-(xtiles< 0) && (tilenum >= (xtiles< 0) && (tilenum < MAXTILES-(xtiles<= MAXTILES) tilenum = MAXTILES-1; + keystatus[0xd1] = 0; + } + if (keystatus[0x2f] > 0) //V + { + keystatus[0x2f] = 0; + if (tilenum < localartlookupnum) + tilenum = localartlookup[tilenum]; + else + tilenum = 0; + localartlookupnum = MAXTILES; + for(i=0;i 0) //G (goto) + { + if (tilenum < localartlookupnum) //Automatically press 'V' + tilenum = localartlookup[tilenum]; + else + tilenum = 0; + localartlookupnum = MAXTILES; + for(i=0;i= '0' && ch <= '9') { + i = (j*10)+(ch-'0'); + if (i < MAXTILES) j = i; + } else if (ch == 8) { + j /= 10; + } else if (ch == 13) { + tilenum = j; + break; + } + } + clearkeys(); + } + while (tilenum < topleft) topleft -= (xtiles<= topleft+(tottiles<<(gettilezoom<<1))) topleft += (xtiles< MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); + } + + if (keystatus[0x1c] == 0) + { + tilenum = otilenum; + } + else + { + if (tilenum < localartlookupnum) + { + tilenum = localartlookup[tilenum]; + if ((tilesizx[tilenum] == 0) || (tilesizy[tilenum] == 0)) + tilenum = otilenum; + } + else + tilenum = otilenum; + } + keystatus[0x1] = 0; + keystatus[0x1c] = 0; + return(tilenum); +} + +long drawtilescreen(long pictopleft, long picbox) +{ + long i, j, vidpos, vidpos2, dat, wallnum, xdime, ydime, cnt, pinc; + long dax, day, scaledown, xtiles, ytiles, tottiles; + char *picptr, snotbuf[80]; + + xtiles = (xdim>>6); ytiles = (ydim>>6); tottiles = xtiles*ytiles; + + begindrawing(); //{{{ + + setpolymost2dview(); // JBF 20040205: set to 2d rendering + + pinc = ylookup[1]; + clearview(0L); + for(cnt=0;cnt<(tottiles<<(gettilezoom<<1));cnt++) //draw the 5*3 grid of tiles + { + wallnum = cnt+pictopleft; + if (wallnum < localartlookupnum) + { + wallnum = localartlookup[wallnum]; + if ((tilesizx[wallnum] != 0) && (tilesizy[wallnum] != 0)) + { + if (waloff[wallnum] == 0) loadtile(wallnum); + picptr = (char *)(waloff[wallnum]); + xdime = tilesizx[wallnum]; + ydime = tilesizy[wallnum]; + + dax = ((cnt%(xtiles<>gettilezoom)) { + vidpos = ylookup[day]+dax+frameplace; + if ((xdime <= (64>>gettilezoom)) && (ydime <= (64>>gettilezoom))) + { + for(i=0;i 64 + { + if (xdime > ydime) + scaledown = ((xdime+(63>>gettilezoom))>>(6-gettilezoom)); + else + scaledown = ((ydime+(63>>gettilezoom))>>(6-gettilezoom)); + + for(i=0;i>gettilezoom);i++) + { + plotpixel(dax+i,day,whitecol); + plotpixel(dax+i,day+(63>>gettilezoom),whitecol); + plotpixel(dax,day+i,whitecol); + plotpixel(dax+(63>>gettilezoom),day+i,whitecol); + } + + i = localartlookup[picbox]; + Bsprintf(snotbuf,"%ld",i); + printext256(0L,ydim-8,whitecol,-1,snotbuf,0); + printext256(xdim-(Bstrlen(names[i])<<3),ydim-8,whitecol,-1,names[i],0); + + Bsprintf(snotbuf,"%dx%d",tilesizx[i],tilesizy[i]); + printext256(xdim>>2,ydim-8,whitecol,-1,snotbuf,0); + + enddrawing(); //}}} + showframe(1); + + return(0); +} + +void overheadeditor(void) +{ + char buffer[80], *dabuffer, ch; + long i, j, k, m=0, mousxplc, mousyplc, firstx=0, firsty=0, oposz, col; + long templong, templong1, templong2, doubvel; + long startwall=0, endwall, dax, day, daz, x1, y1, x2, y2, x3, y3, x4, y4; + long highlightx1, highlighty1, highlightx2, highlighty2, xvect, yvect; + short pag, suckwall=0, sucksect, newnumwalls, newnumsectors, split=0, bad; + short splitsect=0, danumwalls, secondstartwall, joinsector[2], joinsectnum; + short splitstartwall=0, splitendwall, loopnum; + long mousx, mousy, bstatus; + long centerx, centery, circlerad; + short circlewall, circlepoints, circleang1, circleang2, circleangdir; + long sectorhighlightx=0, sectorhighlighty=0; + short cursectorhighlight, sectorhighlightstat; + short hitsect, hitwall, hitsprite; + long hitx, hity, hitz; + walltype *wal; + + //qsetmode640480(); + qsetmodeany(xdim2d,ydim2d); + xdim2d = xdim; + ydim2d = ydim; + + osearchx = searchx; + osearchy = searchy; + + searchx = scale(searchx,xdim2d,xdimgame); + searchy = scale(searchy,ydim2d-STATUS2DSIZ,ydimgame); + oposz = posz; + + begindrawing(); //{{{ + clearbuf((char *)(frameplace + (ydim16*bytesperline)), (bytesperline*STATUS2DSIZ) >> 2, 0x00000000l); + clearbuf((char *)frameplace, (ydim16*bytesperline) >> 2, 0L); + + ydim16 = ydim; + drawline16(0,ydim-STATUS2DSIZ,xdim-1,ydim-STATUS2DSIZ,1); + drawline16(0,ydim-1,xdim-1,ydim-1,1); + drawline16(0,ydim-STATUS2DSIZ,0,ydim-1,1); + drawline16(xdim-1,ydim-STATUS2DSIZ,xdim-1,ydim-1,1); + drawline16(0,ydim-STATUS2DSIZ+24,xdim-1,ydim-STATUS2DSIZ+24,1); + drawline16(192,ydim-STATUS2DSIZ,192,ydim-STATUS2DSIZ+24,1); + if (totalclock < 120*5) printext16(8L,ydim-STATUS2DSIZ+32L,9,-1,kensig,0); + + Bsprintf(tempbuf,"Mapster32"); + printext16(9L,ydim-STATUS2DSIZ+9L,4,-1,tempbuf,0); + printext16(8L,ydim-STATUS2DSIZ+8L,12,-1,tempbuf,0); +// printmessage16("Version: "VERSION); + if (totalclock < 30) printmessage16("Press F1 for help"); + drawline16(0,ydim-1-20,xdim-1,ydim-1-20,1); + drawline16(256,ydim-1-20,256,ydim-1,1); + ydim16 = ydim-STATUS2DSIZ; + enddrawing(); //}}} + + pag = 0; + highlightcnt = -1; + cursectorhighlight = -1; + lastpm16time = -1; + + //White out all bordering lines of grab that are + //not highlighted on both sides + for(i=highlightsectorcnt-1;i>=0;i--) + { + startwall = sector[highlightsector[i]].wallptr; + endwall = startwall + sector[highlightsector[i]].wallnum; + for(j=startwall;j= 0) + { + for(k=highlightsectorcnt-1;k>=0;k--) + if (highlightsector[k] == wall[j].nextsector) + break; + if (k < 0) + { + wall[wall[j].nextwall].nextwall = -1; + wall[wall[j].nextwall].nextsector = -1; + wall[j].nextwall = -1; + wall[j].nextsector = -1; + } + } + } + } + + for(i=0;i<(MAXWALLS>>3);i++) //Clear all highlights + show2dwall[i] = 0; + for(i=0;i<(MAXSPRITES>>3);i++) + show2dsprite[i] = 0; + + sectorhighlightstat = -1; + newnumwalls = -1; + joinsector[0] = -1; + circlewall = -1; + circlepoints = 7; + bstatus = 0; + keystatus[buildkeys[14]] = 0; + while ((keystatus[buildkeys[14]]>>1) == 0) + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + OSD_DispatchQueued(); + + oldmousebstatus = bstatus; + getmousevalues(&mousx,&mousy,&bstatus); + mousx = (mousx<<16)+mousexsurp; + mousy = (mousy<<16)+mouseysurp; + { + ldiv_t ld; + ld = ldiv((long)((double)mousx*msens), (1<<16)); mousx = ld.quot; mousexsurp = ld.rem; + ld = ldiv((long)((double)mousy*msens), (1<<16)); mousy = ld.quot; mouseysurp = ld.rem; + } + searchx += mousx; + searchy += mousy; + if (searchx < 8) searchx = 8; + if (searchx > xdim-8-1) searchx = xdim-8-1; + if (searchy < 8) searchy = 8; + if (searchy > ydim-8-1) searchy = ydim-8-1; + +/* if (keystatus[0x3b] > 0) posx--, keystatus[0x3b] = 0; + if (keystatus[0x3c] > 0) posx++, keystatus[0x3c] = 0; + if (keystatus[0x3d] > 0) posy--, keystatus[0x3d] = 0; + if (keystatus[0x3e] > 0) posy++, keystatus[0x3e] = 0; + if (keystatus[0x43] > 0) ang--, keystatus[0x43] = 0; + if (keystatus[0x44] > 0) ang++, keystatus[0x44] = 0; */ + if (angvel != 0) //ang += angvel * constant + { //ENGINE calculates angvel for you + doubvel = synctics; + if (keystatus[buildkeys[4]] > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (synctics>>1); + ang += ((angvel*doubvel)>>4); + ang = (ang+2048)&2047; + } + if ((vel|svel) != 0) + { + doubvel = synctics; + if (keystatus[buildkeys[4]] > 0) //Lt. shift doubles forward velocity + doubvel += synctics; + xvect = 0, yvect = 0; + if (vel != 0) + { + xvect += ((vel*doubvel*(long)sintable[(ang+2560)&2047])>>3); + yvect += ((vel*doubvel*(long)sintable[(ang+2048)&2047])>>3); + } + if (svel != 0) + { + xvect += ((svel*doubvel*(long)sintable[(ang+2048)&2047])>>3); + yvect += ((svel*doubvel*(long)sintable[(ang+1536)&2047])>>3); + } + if (noclip) + { + posx += xvect>>14; + posy += yvect>>14; + updatesector(posx,posy,&cursectnum); + } + else clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L,4L<<8,4L<<8,CLIPMASK0); + } + + getpoint(searchx,searchy,&mousxplc,&mousyplc); + linehighlight = getlinehighlight(mousxplc, mousyplc); + + if (newnumwalls >= numwalls) + { + dax = mousxplc; + day = mousyplc; + adjustmark(&dax,&day,newnumwalls); + wall[newnumwalls].x = dax; + wall[newnumwalls].y = day; + } + + ydim16 = ydim - STATUS2DSIZ; + + templong = numwalls; + numwalls = newnumwalls; + if (numwalls < 0) numwalls = templong; + + clear2dscreen(); + draw2dgrid(posx,posy,ang,zoom,grid); + + x2 = mulscale14(startposx-posx,zoom); //Draw brown arrow (start) + y2 = mulscale14(startposy-posy,zoom); + if (((halfxdim16+x2) >= 2) && ((halfxdim16+x2) <= xdim-3)) + if (((midydim16+y2) >= 2) && ((midydim16+y2) <= ydim16-3)) + { + x1 = mulscale11(sintable[(startang+2560)&2047],zoom) / 768; + y1 = mulscale11(sintable[(startang+2048)&2047],zoom) / 768; + begindrawing(); //{{{ + drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)-x1,(midydim16+y2)-y1,2); + drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)+y1,(midydim16+y2)-x1,2); + drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)-y1,(midydim16+y2)+x1,2); + enddrawing(); //}}} + } + + draw2dscreen(posx,posy,ang,zoom,grid); + + begindrawing(); //{{{ + if ((showtags == 1) && (zoom >= 768)) + { + for(i=0;i startwall) + { + dax /= (endwall-startwall+1); + day /= (endwall-startwall+1); + } + + dax = mulscale14(dax-posx,zoom); + day = mulscale14(day-posy,zoom); + + x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1); + y1 = midydim16+day-4; + x2 = x1 + (Bstrlen(dabuffer)<<2)+2; + y2 = y1 + 7; + if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16)) + printext16(x1,y1,0,7,dabuffer,1); + } + } + + x3 = divscale14(-halfxdim16,zoom)+posx; + y3 = divscale14(-(midydim16-4),zoom)+posy; + x4 = divscale14(halfxdim16,zoom)+posx; + y4 = divscale14(ydim16-(midydim16-4),zoom)+posy; + + for(i=numwalls-1,wal=&wall[i];i>=0;i--,wal--) + { + //Get average point of wall + dax = ((wal->x+wall[wal->point2].x)>>1); + day = ((wal->y+wall[wal->point2].y)>>1); + if ((dax > x3) && (dax < x4) && (day > y3) && (day < y4)) + { + dabuffer = (char *)ExtGetWallCaption(i); + if (dabuffer[0] != 0) + { + dax = mulscale14(dax-posx,zoom); + day = mulscale14(day-posy,zoom); + x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1); + y1 = midydim16+day-4; + x2 = x1 + (Bstrlen(dabuffer)<<2)+2; + y2 = y1 + 7; + if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16)) + printext16(x1,y1,0,4,dabuffer,1); + } + } + } + + i = 0; j = numsprites; + while ((j > 0) && (i < MAXSPRITES)) + { + if (sprite[i].statnum < MAXSTATUS) + { + dabuffer = (char *)ExtGetSpriteCaption(i); + if (dabuffer[0] != 0) + { + //Get average point of sprite + dax = sprite[i].x; + day = sprite[i].y; + + dax = mulscale14(dax-posx,zoom); + day = mulscale14(day-posy,zoom); + + x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1); + y1 = midydim16+day-4; + x2 = x1 + (Bstrlen(dabuffer)<<2)+2; + y2 = y1 + 7; + if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16)) + { + col = 3; + if (spritecol2d[sprite[i].picnum][0]) + col = spritecol2d[sprite[i].picnum][0]; + if ((sprite[i].cstat&1) > 0) + { + col = 5; + if (spritecol2d[sprite[i].picnum][1]) + col = spritecol2d[sprite[i].picnum][1]; + } + + if ((i == pointhighlight-16384) && (totalclock & 32)) col += (2<<2); + + printext16(x1,y1,0,col,dabuffer,1); + } + } + j--; + } + i++; + } + } + + printcoords16(posx,posy,ang); + + numwalls = templong; + + if (highlightsectorcnt > 0) + for(i=0;i= 0) + drawline16(halfxdim16+x2,midydim16+y2,halfxdim16+x2,midydim16+y2,15); + else + drawline16(halfxdim16+x2,midydim16+y2,halfxdim16+x2,midydim16+y2,5); + enddrawing(); //}}} + + OSD_Draw(); + + ExtCheckKeys(); // TX 20050101, it makes more sense to have this here so keys can be overwritten with new functions in bstub.c + +// Flip/mirror sector Ed Coolidge + if (keystatus[0x2d] > 0) // X (2D) + { + if (highlightsectorcnt > 0) + { + k = 0; + dax = 0; + day = 0; + for(i=0;i 0) + { + dax /= k; + day /= k; + } + + k = (keystatus[0x38]|keystatus[0xb8]); //ALT-X mirror sector in x + + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); +// dax = ((dax+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1)); +// day = ((day+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1)); + } + + for(i=0;i>1; + for(w=1;w<=numtoswap;w++) + { + Bmemcpy(&tempwall,&wall[startofloop+w],sizeof(walltype)); + Bmemcpy(&wall[startofloop+w],&wall[endofloop-w+1],sizeof(walltype)); + Bmemcpy(&wall[endofloop-w+1],&tempwall,sizeof(walltype)); + } + + //make point2 point to next wall in loop + for(w=startofloop;w 0) // Y (2D) + { + if (highlightsectorcnt > 0) + { + k = 0; + dax = 0; + day = 0; + for(i=0;i 0) + { + dax /= k; + day /= k; + } + + k = (keystatus[0x38]|keystatus[0xb8]); //ALT-Y mirror sectors in y + + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); +// dax = ((dax+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1)); +// day = ((day+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1)); + } + + for(i=0;i>1; + for(w=1;w<=numtoswap;w++) + { + Bmemcpy(&tempwall,&wall[startofloop+w],sizeof(walltype)); + Bmemcpy(&wall[startofloop+w],&wall[endofloop-w+1],sizeof(walltype)); + Bmemcpy(&wall[endofloop-w+1],&tempwall,sizeof(walltype)); + } + + //make point2 point to next wall in loop + for(w=startofloop;w 0) //F12 + { + keystatus[88] = 0; + /* + j = ydim16; ydim16 = ydim; + clear2dscreen(); + draw2dgrid(posx,posy,ang,zoom,grid); + draw2dscreen(posx,posy,ang,zoom,grid); + */ + + screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); + + /* + ydim16 = j; + clear2dscreen(); + draw2dgrid(posx,posy,ang,zoom,grid); + draw2dscreen(posx,posy,ang,zoom,grid); + */ + showframe(1); + } + if (keystatus[0x30] > 0) // B (clip Blocking xor) (2D) + { + pointhighlight = getpointhighlight(mousxplc, mousyplc); + linehighlight = getlinehighlight(mousxplc, mousyplc); + + if ((pointhighlight&0xc000) == 16384) + { + sprite[pointhighlight&16383].cstat ^= 1; + sprite[pointhighlight&16383].cstat &= ~256; + sprite[pointhighlight&16383].cstat |= ((sprite[pointhighlight&16383].cstat&1)<<8); + asksave = 1; + } + else if (linehighlight >= 0) + { + wall[linehighlight].cstat ^= 1; + wall[linehighlight].cstat &= ~64; + if ((wall[linehighlight].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[linehighlight].nextwall].cstat &= ~(1+64); + wall[wall[linehighlight].nextwall].cstat |= (wall[linehighlight].cstat&1); + } + asksave = 1; + } + keystatus[0x30] = 0; + } + if (keystatus[0x21] > 0) //F (F alone does nothing in 2D right now) + { + keystatus[0x21] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT-F (relative alignmment flip) + { + linehighlight = getlinehighlight(mousxplc, mousyplc); + if (linehighlight >= 0) + { + setfirstwall(sectorofwall(linehighlight),linehighlight); + asksave = 1; + printmessage16("This wall now sector's first wall (sector[].wallptr)"); + } + } + } + + if (keystatus[0x18] > 0) // O (ornament onto wall) (2D) + { + keystatus[0x18] = 0; + if ((pointhighlight&0xc000) == 16384) + { + asksave = 1; + i = (pointhighlight&16383); + + hitscan(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum, + sintable[(sprite[i].ang+2560+1024)&2047], + sintable[(sprite[i].ang+2048+1024)&2047], + 0, + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + sprite[i].x = hitx; + sprite[i].y = hity; + sprite[i].z = hitz; + changespritesect(i,hitsect); + if (hitwall >= 0) + sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047); + + //Make sure sprite's in right sector + if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0) + { + j = wall[hitwall].point2; + sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y); + sprite[i].y += ksgn(wall[j].x-wall[hitwall].x); + } + } + } + + if (keystatus[0x33] > 0) // , (2D) + { + if (highlightsectorcnt > 0) + { + k = 0; + dax = 0; + day = 0; + for(i=0;i 0) + { + dax /= k; + day /= k; + } + + k = (keystatus[0x2a]|keystatus[0x36]); + + if (k == 0) + { + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + } + + for(i=0;i= 16384) + { + i = pointhighlight-16384; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048-1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048-128)&2047); + keystatus[0x33] = 0; + } + + clearmidstatbar16(); + showspritedata((short)pointhighlight-16384); + } + } + } + if (keystatus[0x34] > 0) // . (2D) + { + if (highlightsectorcnt > 0) + { + k = 0; + dax = 0; + day = 0; + for(i=0;i 0) + { + dax /= k; + day /= k; + } + + k = (keystatus[0x2a]|keystatus[0x36]); + + if (k == 0) + { + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + } + + for(i=0;i= 16384) + { + i = pointhighlight-16384; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048+1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048+128)&2047); + keystatus[0x34] = 0; + } + + clearmidstatbar16(); + showspritedata((short)pointhighlight-16384); + } + } + } + if (keystatus[0x46] > 0) //Scroll lock (set starting position) + { + startposx = posx; + startposy = posy; + startposz = posz; + startang = ang; + startsectnum = cursectnum; + keystatus[0x46] = 0; + asksave = 1; + } + + if (keystatus[0x3f] > 0) //F5 + { + keystatus[0x3f] = 0; + + for (i=0;i 0) //F6 + { + keystatus[0x40] = 0; + + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + + ydim16 = STATUS2DSIZ; + ExtShowSpriteData((short)i); + ydim16 = ydim-STATUS2DSIZ; + } + else if (linehighlight >= 0) + { + i = linehighlight; + + ydim16 = STATUS2DSIZ; + ExtShowWallData((short)i); + ydim16 = ydim-STATUS2DSIZ; + } + } + if (keystatus[0x41] > 0) //F7 + { + keystatus[0x41] = 0; + + for (i=0;i 0) //F8 + { + keystatus[0x42] = 0; + + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + + ydim16 = STATUS2DSIZ; + ExtEditSpriteData((short)i); + ydim16 = ydim-STATUS2DSIZ; + } + else if (linehighlight >= 0) + { + i = linehighlight; + + ydim16 = STATUS2DSIZ; + ExtEditWallData((short)i); + ydim16 = ydim-STATUS2DSIZ; + } + } + + if (keystatus[0x14] > 0) // T (tag) + { + keystatus[0x14] = 0; + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //Ctrl-T + { + showtags ^= 1; + if (showtags == 0) + printmessage16("Show tags OFF"); + else + printmessage16("Show tags ON"); + } + else if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + Bsprintf(buffer,"Sprite (%ld) Lo-tag: ",i); + sprite[i].lotag = getnumber16(buffer,sprite[i].lotag,65536L,0); + clearmidstatbar16(); + showspritedata((short)i); + } + else if (linehighlight >= 0) + { + i = linehighlight; + Bsprintf(buffer,"Wall (%ld) Lo-tag: ",i); + wall[i].lotag = getnumber16(buffer,wall[i].lotag,65536L,0); + clearmidstatbar16(); + showwalldata((short)i); + } + printmessage16(""); + } + else + { + for (i=0;i 0) //H (Hi 16 bits of tag) + { + keystatus[0x23] = 0; + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //Ctrl-H + { + pointhighlight = getpointhighlight(mousxplc, mousyplc); + linehighlight = getlinehighlight(mousxplc, mousyplc); + + if ((pointhighlight&0xc000) == 16384) + { + sprite[pointhighlight&16383].cstat ^= 256; + asksave = 1; + } + else if (linehighlight >= 0) + { + wall[linehighlight].cstat ^= 64; + if ((wall[linehighlight].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[linehighlight].nextwall].cstat &= ~64; + wall[wall[linehighlight].nextwall].cstat |= (wall[linehighlight].cstat&64); + } + asksave = 1; + } + } + else if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + Bsprintf(buffer,"Sprite (%ld) Hi-tag: ",i); + sprite[i].hitag = getnumber16(buffer,sprite[i].hitag,65536L,0); + clearmidstatbar16(); + showspritedata((short)i); + } + else if (linehighlight >= 0) + { + i = linehighlight; + Bsprintf(buffer,"Wall (%ld) Hi-tag: ",i); + wall[i].hitag = getnumber16(buffer,wall[i].hitag,65536L,0); + clearmidstatbar16(); + showwalldata((short)i); + } + } + else + { + for (i=0;i 0) // P (palookup #) + { + keystatus[0x19] = 0; + + for (i=0;i 0) // E (status list) + { + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + Bsprintf(buffer,"Sprite (%ld) Status list: ",i); + changespritestat(i,getnumber16(buffer,sprite[i].statnum,65536L,0)); + clearmidstatbar16(); + showspritedata((short)i); + } + + printmessage16(""); + + keystatus[0x12] = 0; + } + + if (keystatus[0x0f] > 0) //TAB + { + clearmidstatbar16(); + + if ((keystatus[0x38]|keystatus[0xb8]|keystatus[0x1d]|keystatus[0x9d]) > 0) //ALT or CTRL + { + if (pointhighlight >= 16384) + showspritedata((short)pointhighlight-16384); + else if (linehighlight >= 0) + showwalldata((short)linehighlight); + } + else + { + for (i=0;i 0) //Right shift (point highlighting) + { + if (highlightcnt == 0) + { + highlightx2 = searchx, highlighty2 = searchy; + ydim16 = ydim-STATUS2DSIZ; + drawline16(highlightx2,highlighty1,highlightx1,highlighty1,5); + drawline16(highlightx2,highlighty2,highlightx1,highlighty2,5); + drawline16(highlightx1,highlighty2,highlightx1,highlighty1,5); + drawline16(highlightx2,highlighty2,highlightx2,highlighty1,5); + } + if (highlightcnt != 0) + { + highlightx1 = searchx; + highlighty1 = searchy; + highlightx2 = searchx; + highlighty2 = searchx; + highlightcnt = 0; + + for(i=0;i<(MAXWALLS>>3);i++) //Clear all highlights + show2dwall[i] = 0; + for(i=0;i<(MAXSPRITES>>3);i++) + show2dsprite[i] = 0; + } + } + else + { + if (highlightcnt == 0) + { + getpoint(highlightx1,highlighty1,&highlightx1,&highlighty1); + getpoint(highlightx2,highlighty2,&highlightx2,&highlighty2); + if (highlightx1 > highlightx2) + { + templong = highlightx1; highlightx1 = highlightx2; highlightx2 = templong; + } + if (highlighty1 > highlighty2) + { + templong = highlighty1; highlighty1 = highlighty2; highlighty2 = templong; + } + + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) + { + if ((linehighlight >= 0) && (linehighlight < MAXWALLS)) + { + i = linehighlight; + do + { + highlight[highlightcnt++] = i; + show2dwall[i>>3] |= (1<<(i&7)); + + for(j=0;j>3] |= (1<<(j&7)); + } + + i = wall[i].point2; + } + while (i != linehighlight); + } + } + else + { + for(i=0;i= highlightx1) && (wall[i].x <= highlightx2)) + if ((wall[i].y >= highlighty1) && (wall[i].y <= highlighty2)) + { + highlight[highlightcnt++] = i; + show2dwall[i>>3] |= (1<<(i&7)); + } + for(i=0;i= highlightx1) && (sprite[i].x <= highlightx2)) + if ((sprite[i].y >= highlighty1) && (sprite[i].y <= highlighty2)) + { + highlight[highlightcnt++] = i+16384; + show2dsprite[i>>3] |= (1<<(i&7)); + } + } + + if (highlightcnt <= 0) + highlightcnt = -1; + } + } + } + if (highlightcnt < 0) + { + if (keystatus[0xb8] > 0) //Right alt (sector highlighting) + { + if (highlightsectorcnt == 0) + { + highlightx2 = searchx, highlighty2 = searchy; + ydim16 = ydim-STATUS2DSIZ; + begindrawing(); //{{{ + drawline16(highlightx2,highlighty1,highlightx1,highlighty1,10); + drawline16(highlightx2,highlighty2,highlightx1,highlighty2,10); + drawline16(highlightx1,highlighty2,highlightx1,highlighty1,10); + drawline16(highlightx2,highlighty2,highlightx2,highlighty1,10); + enddrawing(); //}}} + } + if (highlightsectorcnt != 0) + { + for(i=0;i= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,highlightsector[i]); + } + } + highlightx1 = searchx; + highlighty1 = searchy; + highlightx2 = searchx; + highlighty2 = searchx; + highlightsectorcnt = 0; + } + } + else + { + if (highlightsectorcnt == 0) + { + getpoint(highlightx1,highlighty1,&highlightx1,&highlighty1); + getpoint(highlightx2,highlighty2,&highlightx2,&highlighty2); + if (highlightx1 > highlightx2) + { + templong = highlightx1; highlightx1 = highlightx2; highlightx2 = templong; + } + if (highlighty1 > highlighty2) + { + templong = highlighty1; highlighty1 = highlighty2; highlighty2 = templong; + } + + for(i=0;i highlightx2) bad = 1; + if (wall[j].y < highlighty1) bad = 1; + if (wall[j].y > highlighty2) bad = 1; + if (bad == 1) break; + } + if (bad == 0) + highlightsector[highlightsectorcnt++] = i; + } + if (highlightsectorcnt <= 0) + highlightsectorcnt = -1; + + //White out all bordering lines of grab that are + //not highlighted on both sides + for(i=highlightsectorcnt-1;i>=0;i--) + { + startwall = sector[highlightsector[i]].wallptr; + endwall = startwall + sector[highlightsector[i]].wallnum; + for(j=startwall;j= 0) + { + for(k=highlightsectorcnt-1;k>=0;k--) + if (highlightsector[k] == wall[j].nextsector) + break; + if (k < 0) + { + wall[wall[j].nextwall].nextwall = -1; + wall[wall[j].nextwall].nextsector = -1; + wall[j].nextwall = -1; + wall[j].nextsector = -1; + } + } + } + } + + } + } + } + + if (((bstatus&1) < (oldmousebstatus&1)) && (highlightsectorcnt < 0)) //after dragging + { + j = 1; + if (highlightcnt > 0) + for (i=0;i=0;i--) //delete points + { + if (wall[i].x == wall[wall[i].point2].x) + if (wall[i].y == wall[wall[i].point2].y) + { + deletepoint((short)i); + printmessage16("Point deleted."); + asksave = 1; + } + } + for(i=0;i 0) //drag points + { + if (highlightsectorcnt > 0) + { + if ((bstatus&1) > (oldmousebstatus&1)) + { + newnumwalls = -1; + sectorhighlightstat = -1; + updatesector(mousxplc,mousyplc,&cursectorhighlight); + + if ((cursectorhighlight >= 0) && (cursectorhighlight < numsectors)) + { + for (i=0;i 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + sectorhighlightx = dax; + sectorhighlighty = day; + break; + } + } + } + else if (sectorhighlightstat == 1) + { + dax = mousxplc; + day = mousyplc; + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + + dax -= sectorhighlightx; + day -= sectorhighlighty; + sectorhighlightx += dax; + sectorhighlighty += day; + + for(i=0;i=0;j=nextspritesect[j]) + { sprite[j].x += dax; sprite[j].y += day; } + } + + //for(i=0;i= 0) + // checksectorpointer(wall[j].nextwall,wall[j].nextsector); + // checksectorpointer((short)j,highlightsector[i]); + // } + //} + asksave = 1; + } + + } + else + { + if ((bstatus&1) > (oldmousebstatus&1)) + pointhighlight = getpointhighlight(mousxplc, mousyplc); + + if (pointhighlight >= 0) + { + dax = mousxplc; + day = mousyplc; + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + + j = 1; + if (highlightcnt > 0) + for (i=0;i= getceilzofslope(i,dax,day)) + if (sprite[pointhighlight&16383].z-daz <= getflorzofslope(i,dax,day)) + { + sprite[pointhighlight&16383].x = dax; + sprite[pointhighlight&16383].y = day; + if (sprite[pointhighlight&16383].sectnum != i) + changespritesect(pointhighlight&16383,(short)i); + break; + } + } + } + asksave = 1; + } + } + } + else + { + pointhighlight = getpointhighlight(mousxplc, mousyplc); + sectorhighlightstat = -1; + } + + if ((bstatus&6) > 0) + { + searchx = halfxdim16; + searchy = midydim16; + posx = mousxplc; + posy = mousyplc; + } + + if (((keystatus[buildkeys[8]] > 0) || (bstatus&16)) && (zoom < 16384)) zoom += synctics*(zoom>>4); + if (((keystatus[buildkeys[9]] > 0) || (bstatus&32)) && (zoom > 24)) zoom -= synctics*(zoom>>4); + if (zoom < 24) zoom = 24; + if (zoom > 16384) zoom = 16384; + + if (keystatus[0x22] > 0) // G (grid on/off) + { + grid++; + if (grid == 7) grid = 0; + keystatus[0x22] = 0; + } + if (keystatus[0x26] > 0) // L (grid lock) + { + gridlock = 1-gridlock, keystatus[0x26] = 0; + if (gridlock == 0) + printmessage16("Grid locking OFF"); + else + printmessage16("Grid locking ON"); + } + + if (keystatus[0x24] > 0) // J (join sectors) + { + if (joinsector[0] >= 0) + { + joinsector[1] = -1; + for(i=0;i= 0) && (joinsector[0] != joinsector[1])) + { + newnumwalls = numwalls; + + for(k=0;k<2;k++) + { + startwall = sector[joinsector[k]].wallptr; + endwall = startwall + sector[joinsector[k]].wallnum - 1; + for(j=startwall;j<=endwall;j++) + { + if (wall[j].cstat == 255) + continue; + joinsectnum = k; + if (wall[j].nextsector == joinsector[1-joinsectnum]) + { + wall[j].cstat = 255; + continue; + } + + i = j; + m = newnumwalls; + do + { + Bmemcpy(&wall[newnumwalls],&wall[i],sizeof(walltype)); + wall[newnumwalls].point2 = newnumwalls+1; + newnumwalls++; + wall[i].cstat = 255; + + i = wall[i].point2; + if (wall[i].nextsector == joinsector[1-joinsectnum]) + { + i = wall[wall[i].nextwall].point2; + joinsectnum = 1 - joinsectnum; + } + } + while ((wall[i].cstat != 255) && (wall[i].nextsector != joinsector[1-joinsectnum])); + wall[newnumwalls-1].point2 = m; + } + } + + if (newnumwalls > numwalls) + { + Bmemcpy(§or[numsectors],§or[joinsector[0]],sizeof(sectortype)); + sector[numsectors].wallptr = numwalls; + sector[numsectors].wallnum = newnumwalls-numwalls; + + //fix sprites + for(i=0;i<2;i++) + { + j = headspritesect[joinsector[i]]; + while (j != -1) + { + k = nextspritesect[j]; + changespritesect(j,numsectors); + j = k; + } + } + + numsectors++; + + for(i=numwalls;i= 0) + { + wall[wall[i].nextwall].nextwall = i; + wall[wall[i].nextwall].nextsector = numsectors-1; + } + } + + numwalls = newnumwalls; + newnumwalls = -1; + + for(k=0;k<2;k++) + { + startwall = sector[joinsector[k]].wallptr; + endwall = startwall + sector[joinsector[k]].wallnum - 1; + for(j=startwall;j<=endwall;j++) + { + wall[j].nextwall = -1; + wall[j].nextsector = -1; + } + } + + deletesector((short)joinsector[0]); + if (joinsector[0] < joinsector[1]) + joinsector[1]--; + deletesector((short)joinsector[1]); + printmessage16("Sectors joined."); + } + } + joinsector[0] = -1; + } + else + { + joinsector[0] = -1; + for(i=0;i 0) //ALT-S + { + if ((linehighlight >= 0) && (wall[linehighlight].nextwall == -1)) + { + if ((newnumwalls = whitelinescan(linehighlight)) < numwalls) + { + printmessage16("Can't make a sector out there."); + } + else + { + for(i=numwalls;i 0) //S + { + sucksect = -1; + for(i=0;i= 0) + { + dax = mousxplc; + day = mousyplc; + if ((gridlock > 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + + i = insertsprite(sucksect,0); + sprite[i].x = dax, sprite[i].y = day; + sprite[i].cstat = defaultspritecstat; + sprite[i].shade = 0; + sprite[i].pal = 0; + sprite[i].xrepeat = 64, sprite[i].yrepeat = 64; + sprite[i].xoffset = 0, sprite[i].yoffset = 0; + sprite[i].ang = 1536; + sprite[i].xvel = 0; sprite[i].yvel = 0; sprite[i].zvel = 0; + sprite[i].owner = -1; + sprite[i].clipdist = 32; + sprite[i].lotag = 0; + sprite[i].hitag = 0; + sprite[i].extra = -1; + + sprite[i].z = getflorzofslope(sucksect,dax,day); + if ((sprite[i].cstat&128) != 0) + sprite[i].z -= ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); + + for(k=0;k localartfreq[j]) + j = k; + if (localartfreq[j] > 0) + sprite[i].picnum = j; + else + sprite[i].picnum = 0; + + if (somethingintab == 3) + { + sprite[i].picnum = temppicnum; + if ((tilesizx[temppicnum] <= 0) || (tilesizy[temppicnum] <= 0)) + { + j = 0; + for(k=0;k 0) && (tilesizy[k] > 0)) + { + j = k; + break; + } + sprite[i].picnum = j; + } + sprite[i].shade = tempshade; + sprite[i].pal = temppal; + sprite[i].xrepeat = tempxrepeat; + sprite[i].yrepeat = tempyrepeat; + if (sprite[i].xrepeat < 1) sprite[i].xrepeat = 1; + if (sprite[i].yrepeat < 1) sprite[i].yrepeat = 1; + sprite[i].cstat = tempcstat; + } + + if (tilesizy[sprite[i].picnum] >= 32) + sprite[i].cstat |= 1; + + printmessage16("Sprite inserted."); + updatenumsprites(); + asksave = 1; + } + + keystatus[0x1f] = 0; + } + + if (keystatus[0x2e] > 0) // C (make circle of points) + { + if (highlightsectorcnt >= 0) + { + newnumsectors = numsectors; + newnumwalls = numwalls; + for(i=0;i= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,highlightsector[i]); + } + highlightsector[i] = numsectors+i; + } + numsectors = newnumsectors; + numwalls = newnumwalls; + + newnumwalls = -1; + newnumsectors = -1; + + updatenumsprites(); + printmessage16("Sectors duplicated and stamped."); + asksave = 1; + } + else if (highlightcnt >= 0) + { + for(i=0;i= 0) + { + circlewall = -1; + } + else + { + if (linehighlight >= 0) + circlewall = linehighlight; + } + keystatus[0x2e] = 0; + } + if (keystatus[0x4a] > 0) // - + { + if (circlepoints > 1) + circlepoints--; + keystatus[0x4a] = 0; + } + if (keystatus[0x4e] > 0) // + + { + if (circlepoints < 63) + circlepoints++; + keystatus[0x4e] = 0; + } + + bad = (keystatus[0x39] > 0); //Gotta do this to save lots of 3 spaces! + + if (circlewall >= 0) + { + x1 = wall[circlewall].x; + y1 = wall[circlewall].y; + x2 = wall[wall[circlewall].point2].x; + y2 = wall[wall[circlewall].point2].y; + x3 = mousxplc; + y3 = mousyplc; + adjustmark(&x3,&y3,newnumwalls); + templong1 = dmulscale4(x3-x2,x1-x3,y1-y3,y3-y2); + templong2 = dmulscale4(y1-y2,x1-x3,y1-y3,x2-x1); + if (templong2 != 0) + { + centerx = (((x1+x2) + scale(y1-y2,templong1,templong2))>>1); + centery = (((y1+y2) + scale(x2-x1,templong1,templong2))>>1); + + dax = mulscale14(centerx-posx,zoom); + day = mulscale14(centery-posy,zoom); + drawline16(halfxdim16+dax-2,midydim16+day-2,halfxdim16+dax+2,midydim16+day+2,14); + drawline16(halfxdim16+dax-2,midydim16+day+2,halfxdim16+dax+2,midydim16+day-2,14); + + circleang1 = getangle(x1-centerx,y1-centery); + circleang2 = getangle(x2-centerx,y2-centery); + + circleangdir = 1; + k = ((circleang2-circleang1)&2047); + if (mulscale4(x3-x1,y2-y1) < mulscale4(x2-x1,y3-y1)) + { + circleangdir = -1; + k = -((circleang1-circleang2)&2047); + } + + circlerad = (ksqrt(dmulscale4(centerx-x1,centerx-x1,centery-y1,centery-y1))<<2); + + for(i=circlepoints;i>0;i--) + { + j = ((circleang1 + scale(i,k,circlepoints+1))&2047); + dax = centerx+mulscale14(sintable[(j+512)&2047],circlerad); + day = centery+mulscale14(sintable[j],circlerad); + + if (dax <= -editorgridextent) dax = -editorgridextent; + if (dax >= editorgridextent) dax = editorgridextent; + if (day <= -editorgridextent) day = -editorgridextent; + if (day >= editorgridextent) day = editorgridextent; + + if (bad > 0) + { + m = 0; + if (wall[circlewall].nextwall >= 0) + if (wall[circlewall].nextwall < circlewall) m = 1; + insertpoint(circlewall,dax,day); + circlewall += m; + } + dax = mulscale14(dax-posx,zoom); + day = mulscale14(day-posy,zoom); + drawline16(halfxdim16+dax-2,midydim16+day-2,halfxdim16+dax+2,midydim16+day-2,14); + drawline16(halfxdim16+dax+2,midydim16+day-2,halfxdim16+dax+2,midydim16+day+2,14); + drawline16(halfxdim16+dax+2,midydim16+day+2,halfxdim16+dax-2,midydim16+day+2,14); + drawline16(halfxdim16+dax-2,midydim16+day+2,halfxdim16+dax-2,midydim16+day-2,14); + } + if (bad > 0) + { + bad = 0; + keystatus[0x39] = 0; + asksave = 1; + printmessage16("Circle points inserted."); + circlewall = -1; + } + } + } + + if (bad > 0) //Space bar test + { + keystatus[0x39] = 0; + adjustmark(&mousxplc,&mousyplc,newnumwalls); + if (checkautoinsert(mousxplc,mousyplc,newnumwalls) == 1) + { + printmessage16("You must insert a point there first."); + bad = 0; + } + } + + if (bad > 0) //Space + { + if ((newnumwalls < numwalls) && (numwalls < MAXWALLS-1)) + { + firstx = mousxplc, firsty = mousyplc; //Make first point + newnumwalls = numwalls; + suckwall = -1; + split = 0; + + //clearbufbyte(&wall[newnumwalls],sizeof(walltype),0L); + memset(&wall[newnumwalls],0,sizeof(walltype)); + wall[newnumwalls].extra = -1; + + wall[newnumwalls].x = mousxplc; + wall[newnumwalls].y = mousyplc; + wall[newnumwalls].nextsector = -1; + wall[newnumwalls].nextwall = -1; + for(i=0;i>1); + day = ((wall[numwalls].y+mousyplc)>>1); + for(i=0;i= 0) + if ((wall[wall[k].point2].x != mousxplc) || (wall[wall[k].point2].y != mousyplc)) + if ((wall[lastwall((short)k)].x != mousxplc) || (wall[lastwall((short)k)].y != mousyplc)) + { + split = 1; + splitsect = i; + splitstartwall = m; + break; + } + } + } + + //make new point + + //make sure not drawing over old red line + bad = 0; + for(i=0;i= 0) + { + if ((wall[i].x == mousxplc) && (wall[i].y == mousyplc)) + if ((wall[wall[i].point2].x == wall[newnumwalls-1].x) && (wall[wall[i].point2].y == wall[newnumwalls-1].y)) + bad = 1; + if ((wall[i].x == wall[newnumwalls-1].x) && (wall[i].y == wall[newnumwalls-1].y)) + if ((wall[wall[i].point2].x == mousxplc) && (wall[wall[i].point2].y == mousyplc)) + bad = 1; + } + } + + if (bad == 0) + { + //clearbufbyte(&wall[newnumwalls],sizeof(walltype),0L); + memset(&wall[newnumwalls],0,sizeof(walltype)); + wall[newnumwalls].extra = -1; + + wall[newnumwalls].x = mousxplc; + wall[newnumwalls].y = mousyplc; + wall[newnumwalls].nextsector = -1; + wall[newnumwalls].nextwall = -1; + for(i=0;i= numwalls+3)) + { + wall[newnumwalls-1].point2 = numwalls; + + if (suckwall == -1) //if no connections to other sectors + { + k = -1; + for(i=0;i= suckwall) + wall[i].nextwall += j; + if (wall[i].point2 >= suckwall) + wall[i].point2 += j; + } + + for(i=newnumwalls-1;i>=suckwall;i--) + Bmemcpy(&wall[i+j],&wall[i],sizeof(walltype)); + for(i=0;inumwalls;j--) + { + Bmemcpy(&wall[danumwalls],&wall[j],sizeof(walltype)); + wall[danumwalls].nextwall = -1; + wall[danumwalls].nextsector = -1; + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + } + m = splitstartwall; //copy rest of loop next + while (m != splitendwall) + { + Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype)); + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + m = wall[m].point2; + } + wall[danumwalls-1].point2 = secondstartwall; + + //Add other loops for 2nd sector + loopnum = loopnumofsector(splitsect,splitstartwall); + i = loopnum; + for(j=startwall;j<=endwall;j++) + { + k = loopnumofsector(splitsect,(short)j); + if ((k != i) && (k != loopnum)) + { + i = k; + if (loopinside(wall[j].x,wall[j].y,secondstartwall) == 1) + { + m = j; //copy loop + k = danumwalls; + do + { + Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype)); + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + m = wall[m].point2; + } + while (m != j); + wall[danumwalls-1].point2 = k; + } + } + } + + //fix all next pointers on old sector line + for(j=numwalls;j= 0) + { + wall[wall[j].nextwall].nextwall = j; + if (j < secondstartwall) + wall[wall[j].nextwall].nextsector = numsectors; + else + wall[wall[j].nextwall].nextsector = numsectors+1; + } + } + //set all next pointers on split + for(j=numwalls;j= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,sectorofwall((short)j)); + } + + //k now safe to use as temp + + for(m=numsectors-2;mnumwalls;j--) + { + Bmemcpy(&wall[danumwalls],&wall[j],sizeof(walltype)); + wall[danumwalls].nextwall = -1; + wall[danumwalls].nextsector = -1; + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + } + + m = splitstartwall; //copy rest of loop next + do + { + Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype)); + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + m = wall[m].point2; + } while (m != splitstartwall); + wall[danumwalls-1].point2 = numwalls; + + //Add other loops to sector + loopnum = loopnumofsector(splitsect,splitstartwall); + i = loopnum; + for(j=startwall;j<=endwall;j++) + { + k = loopnumofsector(splitsect,(short)j); + if ((k != i) && (k != loopnumofsector(splitsect,splitstartwall)) && (k != loopnumofsector(splitsect,splitendwall))) + { + i = k; + m = j; k = danumwalls; //copy loop + do + { + Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype)); + wall[danumwalls].point2 = danumwalls+1; + danumwalls++; + m = wall[m].point2; + } while (m != j); + wall[danumwalls-1].point2 = k; + } + } + + //fix all next pointers on old sector line + for(j=numwalls;j= 0) + { + wall[wall[j].nextwall].nextwall = j; + wall[wall[j].nextwall].nextsector = numsectors; + } + } + + //copy sector attributes & fix wall pointers + Bmemcpy(§or[numsectors],§or[splitsect],sizeof(sectortype)); + sector[numsectors].wallptr = numwalls; + sector[numsectors].wallnum = danumwalls-numwalls; + + //fix sprites + j = headspritesect[splitsect]; + while (j != -1) + { + k = nextspritesect[j]; + changespritesect(j,numsectors); + j = k; + } + + numsectors++; + + //Back of number of walls of new sector for later + k = danumwalls-numwalls; + + //clear out old sector's next pointers for clean deletesector + numwalls = danumwalls; + for(j=startwall;j<=endwall;j++) + { + wall[j].nextwall = -1; + wall[j].nextsector = -1; + } + deletesector(splitsect); + + //Check pointers + for(j=numwalls-k;j= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,numsectors-1); + } + + newnumwalls = -1; + printmessage16("Loops joined."); + break; + } + } + } + } + } + + if (keystatus[0x1c] > 0) //Left Enter + { + keystatus[0x1c] = 0; + if (keystatus[0x2a]&keystatus[0x1d]) + { + printmessage16("CHECKING ALL POINTERS!"); + for(i=0;i=0;i--) + sector[i].wallnum = sector[i+1].wallptr-sector[i].wallptr; + sector[numsectors-1].wallnum = numwalls-sector[numsectors-1].wallptr; + + for(i=0;i= 0) + { + checksectorpointer(linehighlight,sectorofwall(linehighlight)); + printmessage16("Highlighted line pointers checked."); + asksave = 1; + } + } + } + + if ((keystatus[0x0e] > 0) && (newnumwalls >= numwalls)) //Backspace + { + if (newnumwalls > numwalls) + { + newnumwalls--; + asksave = 1; + keystatus[0x0e] = 0; + } + if (newnumwalls == numwalls) + { + newnumwalls = -1; + asksave = 1; + keystatus[0x0e] = 0; + } + } + + if ((keystatus[0xd3] > 0) && (keystatus[0x9d] > 0) && (numwalls >= 0)) + { //sector delete + keystatus[0xd3] = 0; + + sucksect = -1; + for(i=0;i= 0) + for(j=0;j=0;j--) + { + deletesector(highlightsector[j]); + for(k=j-1;k>=0;k--) + if (highlightsector[k] >= highlightsector[j]) + highlightsector[k]--; + } + printmessage16("Highlighted sectors deleted."); + newnumwalls = -1; + k = 1; + highlightsectorcnt = -1; + break; + } + if (k == 0) + { + deletesector((short)i); + highlightsectorcnt = -1; + printmessage16("Sector deleted."); + } + newnumwalls = -1; + asksave = 1; + break; + } + } + + if ((keystatus[0xd3] > 0) && (pointhighlight >= 0)) + { + if ((pointhighlight&0xc000) == 16384) //Sprite Delete + { + deletesprite(pointhighlight&16383); + printmessage16("Sprite deleted."); + updatenumsprites(); + asksave = 1; + } + keystatus[0xd3] = 0; + } + + if (keystatus[0xd2] > 0) //InsertPoint + { + if (highlightsectorcnt >= 0) + { + newnumsectors = numsectors; + newnumwalls = numwalls; + for(i=0;i= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,highlightsector[i]); + } + highlightsector[i] = numsectors+i; + } + numsectors = newnumsectors; + numwalls = newnumwalls; + + newnumwalls = -1; + newnumsectors = -1; + + updatenumsprites(); + printmessage16("Sectors duplicated and stamped."); + asksave = 1; + } + else if (highlightcnt >= 0) + { + for(i=0;i= 0) + { + getclosestpointonwall(mousxplc,mousyplc,(long)linehighlight,&dax,&day); + adjustmark(&dax,&day,newnumwalls); + insertpoint(linehighlight,dax,day); + printmessage16("Point inserted."); + + j = 0; + //Check to see if point was inserted over another point + for(i=numwalls-1;i>=0;i--) //delete points + if (wall[i].x == wall[wall[i].point2].x) + if (wall[i].y == wall[wall[i].point2].y) + { + deletepoint((short)i); + j++; + } + for(i=0;i>1); + // day = ((wall[linehighlight].y + wall[wall[linehighlight].point2].y)>>1); + // if ((dax != wall[linehighlight].x) || (day != wall[linehighlight].y)) + // if ((dax != wall[wall[linehighlight].point2].x) || (day != wall[wall[linehighlight].point2].y)) + // { + // insertpoint(linehighlight,dax,day); + // printmessage16("Point inserted at midpoint."); + // } + //} + + asksave = 1; + } + keystatus[0xd2] = 0; + } + + /*j = 0; + for(i=22-1;i>=0;i--) updatecrc16(j,kensig[i]); + if ((j&0xffff) != 0xebf) + { + printf("Don't screw with my name.\n"); + exit(0); + }*/ + //printext16(9L,336+9L,4,-1,kensig,0); + //printext16(8L,336+8L,12,-1,kensig,0); + + showframe(1); + synctics = totalclock-lockclock; + lockclock += synctics; + + if (keystatus[buildkeys[14]] > 0) + { + updatesector(posx,posy,&cursectnum); + if (cursectnum >= 0) + keystatus[buildkeys[14]] = 2; + else + printmessage16("Arrow must be inside a sector before entering 3D mode."); + } + CANCEL: + if (keystatus[1] > 0) + { + keystatus[1] = 0; + printmessage16("(N)ew, (L)oad, (S)ave, save (A)s, (Q)uit"); + showframe(1); + bflushchars(); + bad = 1; + while (bad == 1) + { + if (handleevents()) { + if (quitevent) { + quitevent = 0; + } + } + + ch = bgetchar(); + + if (keystatus[1] > 0) + { + keystatus[1] = 0; + bad = 0; + printmessage16(""); + } + else if (ch == 'n' || ch == 'N') //N + { + bad = 0; + printmessage16("Are you sure you want to start a new board? (Y/N)"); + showframe(1); + bflushchars(); ch = 0; + while (keystatus[1] == 0) + { + if (handleevents()) { + if (quitevent) { + quitevent = 0; + } + } + + ch = bgetchar(); + + if (ch == 'Y' || ch == 'y') + { + highlightsectorcnt = -1; + highlightcnt = -1; + + for(i=0;i<(MAXWALLS>>3);i++) //Clear all highlights + show2dwall[i] = 0; + for(i=0;i<(MAXSPRITES>>3);i++) + show2dsprite[i] = 0; + + for(i=0;i= 0) + { + j = 0; k = 0; + for(i=0;i MAXSECTORS) || (numwalls+j > MAXWALLS) || (numsprites+k > MAXSPRITES)) + { + highlightsectorcnt = -1; + } + else + { + //Put sectors&walls to end of lists + j = MAXWALLS; + for(i=0;i=0;i--) + if (sprite[i].statnum < MAXSTATUS) + { + k = sprite[i].sectnum; + for(j=0;j= 0) + { + if ((numsectors+highlightsectorcnt > MAXSECTORS) || (sector[MAXSECTORS-highlightsectorcnt].wallptr < numwalls)) + { + highlightsectorcnt = -1; + } + else + { + //Re-attach sectors&walls + for(i=0;i= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,highlightsector[i]); + } + } + + } + } + + if (mapversion < 7) printmessage16("Map loaded successfully and autoconverted to V7!"); + else printmessage16("Map loaded successfully."); + } + updatenumsprites(); + startposx = posx; //this is same + startposy = posy; + startposz = posz; + startang = ang; + startsectnum = cursectnum; + } + showframe(1); + keystatus[0x1c] = 0; + } + else if (ch == 'a' || ch == 'A') //A + { + bad = 0; + + Bstrcpy(selectedboardfilename, boardfilename); + if (Bstrrchr(boardfilename, '/')) + Bstrcpy(boardfilename, Bstrrchr(boardfilename, '/')+1); + + i = 0; + while ((boardfilename[i] != 0) && (i < 64)) + i++; + if (boardfilename[i-4] == '.') + i -= 4; + boardfilename[i] = 0; + + bflushchars(); + while (bad == 0) + { + Bsprintf(buffer,"Save as: %s_", boardfilename); + printmessage16(buffer); + showframe(1); + + if (handleevents()) { + if (quitevent) quitevent = 0; + } + + ch = bgetchar(); + + if (keystatus[1] > 0) bad = 1; + else if (ch == 13) bad = 2; + else if (ch > 0) { + if (i > 0 && (ch == 8 || ch == 127)) { + i--; + boardfilename[i] = 0; + } + else if (i < 8 && ch > 32 && ch < 128) + { + boardfilename[i++] = ch; + boardfilename[i] = 0; + } + } + } + if (bad == 1) + { + Bstrcpy(boardfilename, selectedboardfilename); + keystatus[1] = 0; + printmessage16("Operation cancelled"); + showframe(1); + } + if (bad == 2) + { + char *f; + keystatus[0x1c] = 0; + + boardfilename[i] = '.'; + boardfilename[i+1] = 'm'; + boardfilename[i+2] = 'a'; + boardfilename[i+3] = 'p'; + boardfilename[i+4] = 0; + + if (Bstrrchr(selectedboardfilename,'/')) + Bstrcpy(Bstrrchr(selectedboardfilename, '/')+1, boardfilename); + else + Bstrcpy(selectedboardfilename, boardfilename); + if (pathsearchmode) f = selectedboardfilename; + else { + // virtual filesystem mode can't save to directories so drop the file into + // the current directory + f = strrchr(selectedboardfilename, '/'); + if (!f) f = selectedboardfilename; else f++; + } + Bsprintf(buffer,"Saving to %s...",f); + printmessage16(buffer); + showframe(1); + + fixspritesectors(); //Do this before saving! + updatesector(startposx,startposy,&startsectnum); + ExtPreSaveMap(); + saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap(f); + printmessage16("Board saved."); + Bstrcpy(boardfilename, selectedboardfilename); + } + bad = 0; + } + else if (ch == 's' || ch == 'S') //S + { + char *f; + bad = 0; + printmessage16("Saving board..."); + showframe(1); + fixspritesectors(); //Do this before saving! + updatesector(startposx,startposy,&startsectnum); + if (pathsearchmode) f = boardfilename; + else { + // virtual filesystem mode can't save to directories so drop the file into + // the current directory + f = strrchr(boardfilename, '/'); + if (!f) f = boardfilename; else f++; + } + ExtPreSaveMap(); + saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap(f); + printmessage16("Board saved."); + showframe(1); + } + else if (ch == 'q' || ch == 'Q') //Q + { + bad = 0; + printmessage16("Are you sure you want to quit?"); + showframe(1); + bflushchars(); + while ((keystatus[1]|keystatus[0x2e]) == 0) + { + if (handleevents()) { + if (quitevent) quitevent = 0; + } + + ch = bgetchar(); + + if (ch == 'y' || ch == 'Y') + { + //QUIT! + + printmessage16("Save changes?"); + showframe(1); + while ((keystatus[1]|keystatus[0x2e]) == 0) + { + if (handleevents()) { + if (quitevent) break; // like saying no + } + + ch = bgetchar(); + + if (ch == 'y' || ch == 'Y') + { + char *f; + fixspritesectors(); //Do this before saving! + updatesector(startposx,startposy,&startsectnum); + ExtPreSaveMap(); + if (pathsearchmode) f = boardfilename; + else { + // virtual filesystem mode can't save to directories so drop the file into + // the current directory + f = strrchr(boardfilename, '/'); + if (!f) f = boardfilename; else f++; + } + saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap(f); + break; + } else if (ch == 'n' || ch == 'N' || ch == 13 || ch == ' ') { + break; + } + } + while(keystatus[1] || keystatus[0x2e]) + { + keystatus[1] = 0; + keystatus[0x2e] = 0; + quitevent = 0; + printmessage16("Operation cancelled"); + showframe(1); + goto CANCEL; + } + clearfilenames(); + uninittimer(); + uninitinput(); + ExtUnInit(); + uninitengine(); + printf("Memory status: %ld(%ld) bytes\n",cachesize,artsize); + printf("%s\n",kensig); + exit(0); + } else if (ch == 'n' || ch == 'N' || ch == 13 || ch == ' ') { + break; + } + } + printmessage16(""); + showframe(1); + } + } + clearkeys(); + } + + //nextpage(); + } + + for(i=0;i= 0) + checksectorpointer(wall[j].nextwall,wall[j].nextsector); + checksectorpointer((short)j,highlightsector[i]); + } + } + + fixspritesectors(); + + if (setgamemode(fullscreen,xdimgame,ydimgame,bppgame) < 0) + { + ExtUnInit(); + uninitinput(); + uninittimer(); + uninitsystem(); + clearfilenames(); + printf("%ld * %ld not supported in this graphics mode\n",xdim,ydim); + exit(0); + } + + posz = oposz; + searchx = scale(searchx,xdimgame,xdim2d); + searchy = scale(searchy,ydimgame,ydim2d-STATUS2DSIZ); +} + +void getpoint(long searchxe, long searchye, long *x, long *y) +{ + if (posx <= -editorgridextent) posx = -editorgridextent; + if (posx >= editorgridextent) posx = editorgridextent; + if (posy <= -editorgridextent) posy = -editorgridextent; + if (posy >= editorgridextent) posy = editorgridextent; + + *x = posx + divscale14(searchxe-halfxdim16,zoom); + *y = posy + divscale14(searchye-midydim16,zoom); + + if (*x <= -editorgridextent) *x = -editorgridextent; + if (*x >= editorgridextent) *x = editorgridextent; + if (*y <= -editorgridextent) *y = -editorgridextent; + if (*y >= editorgridextent) *y = editorgridextent; +} + +long getlinehighlight(long xplc, long yplc) +{ + long i, dst, dist, closest, x1, y1, x2, y2, nx, ny; + + if (numwalls == 0) + return(-1); + dist = 1024; + closest = numwalls-1; + for(i=0;i= 0) + { //if red line, allow highlighting of both sides + x1 = wall[closest].x; + y1 = wall[closest].y; + x2 = wall[wall[closest].point2].x; + y2 = wall[wall[closest].point2].y; + if (dmulscale32(xplc-x1,y2-y1,-(x2-x1),yplc-y1) >= 0) + closest = wall[closest].nextwall; + } + if ((pointhighlight&0xc000) == 16384) return (-1); + else return(closest); + +} + +long getpointhighlight(long xplc, long yplc) +{ + long i, dst, dist, closest; + + if (numwalls == 0) + return(-1); + + dist = 0; + if (grid > 0) + dist = 512; + + closest = -1; + for(i=0;i= 256) + for(i=0;i 0) && (gridlock > 0)) + pointlockdist = (128>>grid); + + dist = pointlockdist; + dax = *xplc; + day = *yplc; + for(i=0;i 0) && (grid > 0)) + { + dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); + day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); + } + + *xplc = dax; + *yplc = day; + return(0); +} + +long checkautoinsert(long dax, long day, short danumwalls) +{ + long i, x1, y1, x2, y2; + + if (danumwalls < 0) + danumwalls = numwalls; + for(i=0;i= y2) && (y1 <= y0)) return(0); + if ((y1 >= y0) && (y1 <= y2)) return(1); + + templong = (x0-x1)*(y2-y1) - (x2-x1)*(y0-y1); + if (templong < 0) + return(0); + else + return(1); +} + +void flipwalls(short numwalls, short newnumwalls) +{ + long i, j, nume, templong; + + nume = newnumwalls-numwalls; + + for(i=numwalls;i>1);i++) + { + j = numwalls+newnumwalls-i-1; + templong = wall[i].x; wall[i].x = wall[j].x; wall[j].x = templong; + templong = wall[i].y; wall[i].y = wall[j].y; wall[j].y = templong; + } +} + +void insertpoint(short linehighlight, long dax, long day) +{ + short sucksect; + long i, j, k; + + j = linehighlight; + sucksect = sectorofwall((short)j); + + sector[sucksect].wallnum++; + for(i=sucksect+1;i= 0) + { + k = wall[j].nextwall; + + sucksect = sectorofwall((short)k); + + sector[sucksect].wallnum++; + for(i=sucksect+1;i= 0) + { + wall[wall[j].nextwall].nextwall = -1; + wall[wall[j].nextwall].nextsector = -1; + } + if (wall[point].nextwall >= 0) + { + wall[wall[point].nextwall].nextwall = -1; + wall[wall[point].nextwall].nextsector = -1; + } + movewalls((long)point,-1L); + + checksectorpointer((short)j,(short)sucksect); +} + +long deletesector(short sucksect) +{ + long i, j, k, nextk, startwall, endwall; + + while (headspritesect[sucksect] >= 0) + deletesprite(headspritesect[sucksect]); + updatenumsprites(); + + startwall = sector[sucksect].wallptr; + endwall = startwall + sector[sucksect].wallnum - 1; + j = sector[sucksect].wallnum; + + for(i=sucksect;i= startwall) + wall[i].nextsector--; + return(0); +} + +void fixspritesectors(void) +{ + long i, j, dax, day, daz; + + for(i=numsectors-1;i>=0;i--) + if ((sector[i].wallnum <= 0) || (sector[i].wallptr >= numwalls)) + deletesector((short)i); + + for(i=0;i= getceilzofslope(j,dax,day)) + if (sprite[i].z-daz <= getflorzofslope(j,dax,day)) + { + changespritesect((short)i,(short)j); + break; + } + } + } +} + +long movewalls(long start, long offs) +{ + long i; + + if (offs < 0) //Delete + { + for(i=start;i 0) //Insert + { + for(i=numwalls+offs-1;i>=start+offs;i--) + Bmemcpy(&wall[i],&wall[i-offs],sizeof(walltype)); + } + numwalls += offs; + for(i=0;i= start) wall[i].nextwall += offs; + if (wall[i].point2 >= start) wall[i].point2 += offs; + } + return(0); +} + +long checksectorpointer(short i, short sectnum) +{ + long j, k, startwall, endwall, x1, y1, x2, y2; + + x1 = wall[i].x; + y1 = wall[i].y; + x2 = wall[wall[i].point2].x; + y2 = wall[wall[i].point2].y; + + if (wall[i].nextwall >= 0) //Check for early exit + { + k = wall[i].nextwall; + if ((wall[k].x == x2) && (wall[k].y == y2)) + if ((wall[wall[k].point2].x == x1) && (wall[wall[k].point2].y == y1)) + return(0); + } + + wall[i].nextsector = -1; + wall[i].nextwall = -1; + for(j=0;j> 2, 0x08080808l); + clearbuf((char *)(frameplace + (bytesperline*(ydim-STATUS2DSIZ+25L))),(bytesperline*(STATUS2DSIZ+2-(25<<1))) >> 2, 0x00000000l); + drawline16(0,ydim-STATUS2DSIZ,0,ydim-1,7); + drawline16(xdim-1,ydim-STATUS2DSIZ,xdim-1,ydim-1,7); + ydim16 = ydim-STATUS2DSIZ; + enddrawing(); +} + +short loopinside(long x, long y, short startwall) +{ + long x1, y1, x2, y2, templong; + short i, cnt; + + cnt = clockdir(startwall); + i = startwall; + do + { + x1 = wall[i].x; x2 = wall[wall[i].point2].x; + if ((x1 >= x) || (x2 >= x)) + { + y1 = wall[i].y; y2 = wall[wall[i].point2].y; + if (y1 > y2) + { + templong = x1, x1 = x2, x2 = templong; + templong = y1, y1 = y2, y2 = templong; + } + if ((y1 <= y) && (y2 > y)) + if (x1*(y-y2)+x2*(y1-y) <= x*(y1-y2)) + cnt ^= 1; + } + i = wall[i].point2; + } + while (i != startwall); + return(cnt); +} + +long numloopsofsector(short sectnum) +{ + long i, numloops, startwall, endwall; + + numloops = 0; + startwall = sector[sectnum].wallptr; + endwall = startwall + sector[sectnum].wallnum; + for(i=startwall;i= '0' && ch <= '9') { + if (danum >= 0) + { + n = (danum*10)+(ch-'0'); + if (n <= maxnumber) danum = n; + } + else if (sign) // this extra check isn't hurting anything + { + n = (danum*10)-(ch-'0'); + if (n >= -maxnumber) danum = n; + } + } else if (ch == 8 || ch == 127) { // backspace + danum /= 10; + } else if (ch == 13) { + oldnum = danum; + asksave = 1; + break; + } else if (ch == '-' && sign) { // negate + danum = -danum; + } + } + clearkeys(); + return(oldnum); +} + +long getnumber256(char namestart[80], long num, long maxnumber, char sign) +{ + char buffer[80], ch; + long j, k, n, danum, oldnum; + + danum = num; + oldnum = danum; + bflushchars(); + while (keystatus[0x1] == 0) + { + if (handleevents()) { + if (quitevent) quitevent = 0; + } + + drawrooms(posx,posy,posz,ang,horiz,cursectnum); +#ifdef SUPERBUILD + ExtAnalyzeSprites(); +#endif + drawmasks(); + + ch = bgetchar(); + + Bsprintf(buffer,"%s%ld_ ",namestart,danum); + printmessage256(buffer); + showframe(1); + + if (ch >= '0' && ch <= '9') { + if (danum >= 0) + { + n = (danum*10)+(ch-'0'); + if (n <= maxnumber) danum = n; + } + else if (sign) + { + n = (danum*10)-(ch-'0'); + if (n >= -maxnumber) danum = n; + } + } else if (ch == 8 || ch == 127) { // backspace + danum /= 10; + } else if (ch == 13) { + oldnum = danum; + asksave = 1; + break; + } else if (ch == '-' && sign) { // negate + danum = -danum; + } + } + clearkeys(); + + lockclock = totalclock; //Reset timing + + return(oldnum); +} + +void clearfilenames(void) +{ + klistfree(finddirs); + klistfree(findfiles); + finddirs = findfiles = NULL; + numfiles = numdirs = 0; +} + +long getfilenames(char *path, char kind[6]) +{ + CACHE1D_FIND_REC *r; + + clearfilenames(); + finddirs = klistpath(path,"*",CACHE1D_FIND_DIR|CACHE1D_FIND_DRIVE|(!pathsearchmode&&grponlymode?CACHE1D_OPT_NOSTACK:0)); + findfiles = klistpath(path,kind,CACHE1D_FIND_FILE|(!pathsearchmode&&grponlymode?CACHE1D_OPT_NOSTACK:0)); + for (r = finddirs; r; r=r->next) numdirs++; + for (r = findfiles; r; r=r->next) numfiles++; + + finddirshigh = finddirs; + findfileshigh = findfiles; + currentlist = 0; + if (findfileshigh) currentlist = 1; + + return(0); +} + +long menuselect(void) +{ + int listsize; + long i, j, topplc; + char ch, buffer[78], *sb; + static char oldpath[BMAX_PATH]; + CACHE1D_FIND_REC *dir; + + int bakpathsearchmode = pathsearchmode; + + listsize = (ydim16-32)/8; + + Bstrcpy(selectedboardfilename, oldpath); + if (pathsearchmode) + Bcanonicalisefilename(selectedboardfilename, 1); // clips off the last token and compresses relative path + else + Bcorrectfilename(selectedboardfilename, 1); + + getfilenames(selectedboardfilename, "*.map"); + + begindrawing(); + printmessage16("Select map file with arrow keys and enter."); + enddrawing(); + + do { + begindrawing(); + clearbuf((char *)frameplace, (bytesperline*ydim16) >> 2, 0l); + + if (pathsearchmode) { + strcpy(buffer,"Local filesystem mode; press F for game filesystem."); + } else { + sprintf(buffer,"Game filesystem %smode; press F for local filesystem or G for %s.", + grponlymode?"GRP-only ":"", grponlymode?"all files":"GRP contents only"); + } + printext16(halfxdim16-(8*strlen(buffer)/2), 4, 12,0,buffer,0); + + Bsnprintf(buffer,78,"(%d dirs, %d files) %s",numdirs,numfiles,selectedboardfilename); + buffer[sizeof(buffer)-1] = 0; + printext16(1,ydim16-8-1,8,0,buffer,0); + + if (finddirshigh) { + dir = finddirshigh; + for(i=listsize/2-1; i>=0; i--) if (!dir->prev) break; else dir=dir->prev; + for(i=0; inext) { + int c = dir->type == CACHE1D_FIND_DIR ? 4 : 3; + memset(buffer,0,sizeof(buffer)); + strncpy(buffer,dir->name,25); + if (strlen(buffer) == 25) + buffer[21] = buffer[22] = buffer[23] = '.', buffer[24] = 0; + if (dir == finddirshigh) { + if (currentlist == 0) printext16(8,16+8*i,c|8,0,"->",0); + printext16(32,16+8*i,c|8,0,buffer,0); + } else { + printext16(32,16+8*i,c,0,buffer,0); + } + } + } + + if (findfileshigh) { + dir = findfileshigh; + for(i=listsize/2-1; i>=0; i--) if (!dir->prev) break; else dir=dir->prev; + for(i=0; inext) { + if (dir == findfileshigh) { + if (currentlist == 1) printext16(240,16+8*i,7|8,0,"->",0); + printext16(240+24,16+8*i,7|8,0,dir->name,0); + } else { + printext16(240+24,16+8*i,7,0,dir->name,0); + } + } + } + enddrawing(); + showframe(1); + + keystatus[0xcb] = 0; + keystatus[0xcd] = 0; + keystatus[0xc8] = 0; + keystatus[0xd0] = 0; + keystatus[0x1c] = 0; //enter + keystatus[0xf] = 0; //tab + keystatus[1] = 0; //esc + ch = 0; //Interesting fakery of ch = getch() + while (ch == 0) + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + ch = bgetchar(); + { // JBF 20040208: seek to first name matching pressed character + CACHE1D_FIND_REC *seeker = currentlist ? findfiles : finddirs; + if((keystatus[0xc7]|keystatus[0xcf]) > 0) // home/end + { + while(keystatus[0xcf]?seeker->next:seeker->prev) + seeker = keystatus[0xcf]?seeker->next:seeker->prev; + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + } + ch = keystatus[0xcf]?80:72; + keystatus[0xc7] = keystatus[0xcf] = 0; + } + else if((keystatus[0xc9]|keystatus[0xd1]) > 0) // page up/down + { + seeker = currentlist?findfileshigh:finddirshigh; + i = (ydim2d-STATUS2DSIZ-48)>>3; + while(i>0) { + if(keystatus[0xd1]?seeker->next:seeker->prev) + seeker = keystatus[0xd1]?seeker->next:seeker->prev; + i--; + } + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + } + ch = keystatus[0xd1]?80:72; + keystatus[0xc9] = keystatus[0xd1] = 0; + } + else + { + char ch2; + if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) { + if (ch >= 'a') ch -= ('a'-'A'); + while (seeker) { + ch2 = seeker->name[0]; + if (ch2 >= 'a' && ch2 <= 'z') ch2 -= ('a'-'A'); + if (ch2 == ch) break; + seeker = seeker->next; + } + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + continue; + } + } + } + } + if (keystatus[0xcb] > 0) ch = 9; // left arr + if (keystatus[0xcd] > 0) ch = 9; // right arr + if (keystatus[0xc8] > 0) ch = 72; // up arr + if (keystatus[0xd0] > 0) ch = 80; // down arr + } + if (ch == 'f' || ch == 'F') { + currentlist = 0; + pathsearchmode = 1-pathsearchmode; + if (pathsearchmode) { + strcpy(selectedboardfilename, ""); + Bcanonicalisefilename(selectedboardfilename, 0); + } else strcpy(selectedboardfilename, "/"); + getfilenames(selectedboardfilename, "*.map"); + Bstrcpy(oldpath,selectedboardfilename); + } else if (ch == 'g' || ch == 'G') { + if (!pathsearchmode) { + grponlymode = 1-grponlymode; + getfilenames(selectedboardfilename, "*.map"); + Bstrcpy(oldpath,selectedboardfilename); + } + } else if (ch == 9) { + if ((currentlist == 0 && findfiles) || (currentlist == 1 && finddirs)) + currentlist = 1-currentlist; + } else if ((ch == 75) || (ch == 72)) { + if (currentlist == 0) { + if (finddirshigh && finddirshigh->prev) finddirshigh = finddirshigh->prev; + } else { + if (findfileshigh && findfileshigh->prev) findfileshigh = findfileshigh->prev; + } + } else if ((ch == 77) || (ch == 80)) { + if (currentlist == 0) { + if (finddirshigh && finddirshigh->next) finddirshigh = finddirshigh->next; + } else { + if (findfileshigh && findfileshigh->next) findfileshigh = findfileshigh->next; + } + } else if ((ch == 13) && (currentlist == 0)) { + if (finddirshigh->type == CACHE1D_FIND_DRIVE) { + strcpy(selectedboardfilename, finddirshigh->name); + } else { + strcat(selectedboardfilename, finddirshigh->name); + } + strcat(selectedboardfilename, "/"); + if (pathsearchmode) + Bcanonicalisefilename(selectedboardfilename, 1); + else + Bcorrectfilename(selectedboardfilename, 1); + + Bstrcpy(oldpath,selectedboardfilename); + //printf("Changing directories to: %s\n", selectedboardfilename); + + getfilenames(selectedboardfilename, "*.map"); + ch = 0; + + begindrawing(); + clearbuf((char *)frameplace, (bytesperline*ydim16) >> 2, 0l); + enddrawing(); + showframe(1); + } + if (ch == 13 && !findfileshigh) ch = 0; + } + while ((ch != 13) && (ch != 27)); + if (ch == 13) + { + Bstrcat(selectedboardfilename, findfileshigh->name); + //printf("Selected file: %s\n", selectedboardfilename); + + return(0); + } + pathsearchmode = bakpathsearchmode; + return(-1); +} + +long fillsector(short sectnum, char fillcolor) +{ + long x1, x2, y1, y2, sy, y, templong; + long lborder, rborder, uborder, dborder, miny, maxy, dax; + short z, zz, startwall, endwall, fillcnt; + + lborder = 0; rborder = xdim; + uborder = 0; dborder = ydim16; + + if (sectnum == -1) + return(0); + miny = dborder-1; + maxy = uborder; + startwall = sector[sectnum].wallptr; + endwall = startwall + sector[sectnum].wallnum - 1; + for(z=startwall;z<=endwall;z++) + { + y1 = (((wall[z].y-posy)*zoom)>>14)+midydim16; + y2 = (((wall[wall[z].point2].y-posy)*zoom)>>14)+midydim16; + if (y1 < miny) miny = y1; + if (y2 < miny) miny = y2; + if (y1 > maxy) maxy = y1; + if (y2 > maxy) maxy = y2; + } + if (miny < uborder) miny = uborder; + if (maxy >= dborder) maxy = dborder-1; + + for(sy=miny+((totalclock>>2)&3);sy<=maxy;sy+=3) // JBF 20040116: numframes%3 -> (totalclock>>2)&3 + { + y = posy+(((sy-midydim16)<<14)/zoom); + + fillist[0] = lborder; fillcnt = 1; + for(z=startwall;z<=endwall;z++) + { + x1 = wall[z].x; x2 = wall[wall[z].point2].x; + y1 = wall[z].y; y2 = wall[wall[z].point2].y; + if (y1 > y2) + { + templong = x1; x1 = x2; x2 = templong; + templong = y1; y1 = y2; y2 = templong; + } + if ((y1 <= y) && (y2 > y)) + //if (x1*(y-y2) + x2*(y1-y) <= 0) + { + dax = x1+scale(y-y1,x2-x1,y2-y1); + dax = (((dax-posx)*zoom)>>14)+halfxdim16; + if (dax >= lborder) + fillist[fillcnt++] = dax; + } + } + if (fillcnt > 0) + { + for(z=1;z rborder) break; + if (fillist[z+1] > rborder) + fillist[z+1] = rborder; + drawline16(fillist[z],sy,fillist[z+1],sy,fillcolor); + } + } + } + return(0); +} + +short whitelinescan(short dalinehighlight) +{ + long i, j, k; + short sucksect, newnumwalls; + + sucksect = sectorofwall(dalinehighlight); + + Bmemcpy(§or[numsectors],§or[sucksect],sizeof(sectortype)); + sector[numsectors].wallptr = numwalls; + sector[numsectors].wallnum = 0; + i = dalinehighlight; + newnumwalls = numwalls; + do + { + j = lastwall((short)i); + if (wall[j].nextwall >= 0) + { + j = wall[j].point2; + for(k=0;k 32); + + buffercnt = 0; + do + { + loadbyte(fil,tempbuf,bufplc,ch); + if (ch > 32) buffer[buffercnt++] = ch; + } + while (ch > 32); + + num = 0; + do + { + loadbyte(fil,tempbuf,bufplc,ch); + if ((ch >= 48) && (ch <= 57)) num = num*10+(ch-48); + } + while (ch != 13); + for(i=0;i= 1) { + if (a > 1) + if (buffer[a-2] == '\r') buffer[a-2] = 0; + if (buffer[a-1] == '\n') buffer[a-1] = 0; + } + + p = buffer; + line++; + while (*p == 32) p++; + if (*p == 0) continue; // blank line + + if (*p == '#') { + p++; + while (*p == 32) p++; + if (*p == 0) continue; // null directive + + if (!Bstrncmp(p, "define ", 7)) { + // #define_... + p += 7; + while (*p == 32) p++; + if (*p == 0) { + printf("Error: Malformed #define at line %d\n", line-1); + continue; + } + + name = p; + while (*p != 32 && *p != 0) p++; + if (*p == 32) { + *(p++) = 0; + while (*p == 32) p++; + if (*p == 0) { // #define_NAME with no number + printf("Error: No number given for name \"%s\" (line %d)\n", name, line-1); + continue; + } + + number = p; + while (*p != 0) p++; + if (*p != 0) *p = 0; + + // add to list + num = Bstrtol(number, &endptr, 10); + if (*endptr != 0) { + p = endptr; + goto badline; + } + //printf("Grokked \"%s\" -> \"%d\"\n", name, num); + if (num < 0 || num >= MAXTILES) { + printf("Error: Constant %d for name \"%s\" out of range (line %d)\n", num, name, line-1); + continue; + } + + if (Bstrlen(name) > 24) + printf("Warning: Name \"%s\" longer than 24 characters (line %d). Truncating.\n", name, line-1); + + Bstrncpy(names[num], name, 24); + names[num][24] = 0; + + syms++; + + continue; + + } else { // #define_NAME with no number + printf("Error: No number given for name \"%s\" (line %d)\n", name, line-1); + continue; + } + } else goto badline; + } else if (*p == '/') { + if (*(p+1) == '/') continue; // comment + } +badline: + printf("Error: Invalid statement found at character %d on line %d\n", (p-buffer), line-1); + } + printf("Read %d lines, loaded %d names.\n", line, syms); + + Bfclose(fp); + return 0; +} + +void printcoords16(long posxe, long posye, short ange) +{ + char snotbuf[80]; + long i,m; + + Bsprintf(snotbuf,"x=%ld y=%ld ang=%d",posxe,posye,ange); + i = 0; + while ((snotbuf[i] != 0) && (i < 30)) + i++; + while (i < 30) + { + snotbuf[i] = 32; + i++; + } + snotbuf[30] = 0; + + m = (numsectors > MAXSECTORSV7 || numwalls > MAXWALLSV7 || numsprites > MAXSPRITESV7); + + printext16(8, ydim-STATUS2DSIZ+128+2, 9, 0, snotbuf,0); + + Bsprintf(snotbuf,"%d/%d sect. %d/%d walls %ld/%d spri.", + numsectors,m?MAXSECTORSV8:MAXSECTORSV7, + numwalls,m?MAXWALLSV8:MAXWALLSV7, + numsprites,m?MAXSPRITESV8:MAXSPRITESV7); + i = 0; + while ((snotbuf[i] != 0) && (i < 46)) + i++; + while (i < 46) + { + snotbuf[i] = 32; + i++; + } + snotbuf[46] = 0; + + printext16(264, ydim-STATUS2DSIZ+128+2, 9+m, 0, snotbuf,0); +} + +void updatenumsprites(void) +{ + long i; + + numsprites = 0; + for(i=0;i= 0) + { + wall[newnumwalls].nextwall += deststartwall-startwall; + wall[newnumwalls].nextsector += destsector-soursector; + } + newnumwalls++; + } + + //for(j=deststartwall;j= 0) + // checksectorpointer(wall[j].nextwall,wall[j].nextsector); + // checksectorpointer((short)j,destsector); + //} + + if (newnumwalls > deststartwall) + { + //duplicate sectors + Bmemcpy(§or[destsector],§or[soursector],sizeof(sectortype)); + sector[destsector].wallptr = deststartwall; + sector[destsector].wallnum = newnumwalls-deststartwall; + + if (copystat == 1) + { + //duplicate sprites + j = headspritesect[soursector]; + while (j >= 0) + { + k = nextspritesect[j]; + + m = insertsprite(destsector,sprite[j].statnum); + Bmemcpy(&sprite[m],&sprite[j],sizeof(spritetype)); + sprite[m].sectnum = destsector; //Don't let memcpy overwrite sector! + + j = k; + } + } + + } +} + +void showsectordata(short sectnum) +{ + char snotbuf[80]; + + Bsprintf(snotbuf,"Sector %d",sectnum); + printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Firstwall: %d",sector[sectnum].wallptr); + printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Numberofwalls: %d",sector[sectnum].wallnum); + printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Firstsprite: %d",headspritesect[sectnum]); + printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Tags: %d, %d",sector[sectnum].hitag,sector[sectnum].lotag); + printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf," (0x%x), (0x%x)",sector[sectnum].hitag,sector[sectnum].lotag); + printext16(8,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Extra: %d",sector[sectnum].extra); + printext16(8,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Visibility: %d",sector[sectnum].visibility); + printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Pixel height: %ld",(sector[sectnum].floorz-sector[sectnum].ceilingz)>>8); + printext16(8,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0); + + printext16(200,ydim-STATUS2DSIZ+32,11,-1,"CEILINGS:",0); + Bsprintf(snotbuf,"Flags (hex): %x",sector[sectnum].ceilingstat); + printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].ceilingxpanning,sector[sectnum].ceilingypanning); + printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Shade byte: %d",sector[sectnum].ceilingshade); + printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].ceilingz); + printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Tile number: %d",sector[sectnum].ceilingpicnum); + printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Ceiling heinum: %d",sector[sectnum].ceilingheinum); + printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Palookup number: %d",sector[sectnum].ceilingpal); + printext16(200,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + + printext16(400,ydim-STATUS2DSIZ+32,11,-1,"FLOORS:",0); + Bsprintf(snotbuf,"Flags (hex): %x",sector[sectnum].floorstat); + printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].floorxpanning,sector[sectnum].floorypanning); + printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Shade byte: %d",sector[sectnum].floorshade); + printext16(400,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].floorz); + printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Tile number: %d",sector[sectnum].floorpicnum); + printext16(400,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Floor heinum: %d",sector[sectnum].floorheinum); + printext16(400,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Palookup number: %d",sector[sectnum].floorpal); + printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); +} + +void showwalldata(short wallnum) +{ + long dax, day, dist; + char snotbuf[80]; + + Bsprintf(snotbuf,"Wall %d",wallnum); + printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0); + Bsprintf(snotbuf,"X-coordinate: %ld",wall[wallnum].x); + printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Y-coordinate: %ld",wall[wallnum].y); + printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Point2: %d",wall[wallnum].point2); + printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Sector: %ld",sectorofwall(wallnum)); + printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"Tags: %d, %d",wall[wallnum].hitag,wall[wallnum].lotag); + printext16(8,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf," (0x%x), (0x%x)",wall[wallnum].hitag,wall[wallnum].lotag); + printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + + printext16(200,ydim-STATUS2DSIZ+32,11,-1,names[wall[wallnum].picnum],0); + Bsprintf(snotbuf,"Flags (hex): %x",wall[wallnum].cstat); + printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Shade: %d",wall[wallnum].shade); + printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Pal: %d",wall[wallnum].pal); + printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)repeat: %d, %d",wall[wallnum].xrepeat,wall[wallnum].yrepeat); + printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)pan: %d, %d",wall[wallnum].xpanning,wall[wallnum].ypanning); + printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Tile number: %d",wall[wallnum].picnum); + printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf,"OverTile number: %d",wall[wallnum].overpicnum); + printext16(200,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"nextsector: %d",wall[wallnum].nextsector); + printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"nextwall: %d",wall[wallnum].nextwall); + printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"Extra: %d",wall[wallnum].extra); + printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + + dax = wall[wallnum].x-wall[wall[wallnum].point2].x; + day = wall[wallnum].y-wall[wall[wallnum].point2].y; + dist = ksqrt(dax*dax+day*day); + +// TX 20050102 I'm not sure what unit dist<<4 is supposed to be, but dist itself is correct in terms of game coordinates as one would expect + + Bsprintf(snotbuf,"Wall length: %ld",dist); + printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + + dax = (long)sectorofwall(wallnum); + Bsprintf(snotbuf,"Pixel height: %ld",(sector[dax].floorz-sector[dax].ceilingz)>>8); + printext16(400,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0); +} + +void showspritedata(short spritenum) +{ + char snotbuf[80]; + + Bsprintf(snotbuf,"Sprite %d",spritenum); + printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0); + Bsprintf(snotbuf,"X-coordinate: %ld",sprite[spritenum].x); + printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Y-coordinate: %ld",sprite[spritenum].y); + printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Z-coordinate: %ld",sprite[spritenum].z); + printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"Sectnum: %d",sprite[spritenum].sectnum); + printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Statnum: %d",sprite[spritenum].statnum); + printext16(8,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"Tags: %d, %d",sprite[spritenum].hitag,sprite[spritenum].lotag); + printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); + Bsprintf(snotbuf," (0x%x), (0x%x)",sprite[spritenum].hitag,sprite[spritenum].lotag); + printext16(8,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0); + + printext16(200,ydim-STATUS2DSIZ+32,11,-1,names[sprite[spritenum].picnum],0); + Bsprintf(snotbuf,"Flags (hex): %x",sprite[spritenum].cstat); + printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Shade: %d",sprite[spritenum].shade); + printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Pal: %d",sprite[spritenum].pal); + printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)repeat: %d, %d",sprite[spritenum].xrepeat,sprite[spritenum].yrepeat); + printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"(X,Y)offset: %d, %d",sprite[spritenum].xoffset,sprite[spritenum].yoffset); + printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Tile number: %d",sprite[spritenum].picnum); + printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + + Bsprintf(snotbuf,"Angle (2048 degrees): %d",sprite[spritenum].ang); + printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0); + Bsprintf(snotbuf,"X-Velocity: %d",sprite[spritenum].xvel); + printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Y-Velocity: %d",sprite[spritenum].yvel); + printext16(400,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Z-Velocity: %d",sprite[spritenum].zvel); + printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Owner: %d",sprite[spritenum].owner); + printext16(400,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Clipdist: %d",sprite[spritenum].clipdist); + printext16(400,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0); + Bsprintf(snotbuf,"Extra: %d",sprite[spritenum].extra); + printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0); +} + +void keytimerstuff(void) +{ + static long ltotalclock=0; + int i; + if (totalclock == ltotalclock) return; + ltotalclock=totalclock; + + if (keystatus[buildkeys[5]] == 0) + { + if (keystatus[buildkeys[2]] > 0) angvel = max(angvel-16,-128); + if (keystatus[buildkeys[3]] > 0) angvel = min(angvel+16,127); + } + else + { + if (keystatus[buildkeys[2]] > 0) svel = min(svel+8,127); + if (keystatus[buildkeys[3]] > 0) svel = max(svel-8,-128); + } + if (keystatus[buildkeys[0]] > 0) vel = min(vel+8,127); + if (keystatus[buildkeys[1]] > 0) vel = max(vel-8,-128); +/* if (keystatus[buildkeys[12]] > 0) svel = min(svel+8,127); + if (keystatus[buildkeys[13]] > 0) svel = max(svel-8,-128); */ + + if (angvel < 0) angvel = min(angvel+12,0); + if (angvel > 0) angvel = max(angvel-12,0); + if (svel < 0) svel = min(svel+2,0); + if (svel > 0) svel = max(svel-2,0); + if (vel < 0) vel = min(vel+2,0); + if (vel > 0) vel = max(vel-2,0); + if(mlook) + posz -= (horiz-101)*(vel/40); +} + +void _printmessage16(char name[82]) +{ + char snotbuf[60]; + long i; + + i = 0; + while ((name[i] != 0) && (i < 54)) + { + snotbuf[i] = name[i]; + i++; + } + while (i < 54) + { + snotbuf[i] = 32; + i++; + } + snotbuf[54] = 0; + begindrawing(); + printext16(200L, ydim-STATUS2DSIZ+8L, 9, 0, snotbuf, 0); + enddrawing(); +} + +void printmessage16(char name[82]) +{ + _printmessage16(name); + lastpm16time = totalclock; +} + + +void printmessage256(char name[82]) +{ + char snotbuf[40]; + long i; + + i = 0; + while ((name[i] != 0) && (i < 38)) + { + snotbuf[i] = name[i]; + i++; + } + while (i < 38) + { + snotbuf[i] = 32; + i++; + } + snotbuf[38] = 0; + printext256(2L,2L,0,-1,snotbuf,0); + printext256(0L,0L,whitecol,-1,snotbuf,0); +} + + //Find closest point (*dax, *day) on wall (dawall) to (x, y) +void getclosestpointonwall(long x, long y, long dawall, long *nx, long *ny) +{ + walltype *wal; + long i, j, dx, dy; + + wal = &wall[dawall]; + dx = wall[wal->point2].x-wal->x; + dy = wall[wal->point2].y-wal->y; + i = dx*(x-wal->x) + dy*(y-wal->y); + if (i <= 0) { *nx = wal->x; *ny = wal->y; return; } + j = dx*dx+dy*dy; + if (i >= j) { *nx = wal->x+dx; *ny = wal->y+dy; return; } + i = divscale30(i,j); + *nx = wal->x + mulscale30(dx,i); + *ny = wal->y + mulscale30(dy,i); +} + +void initcrc(void) +{ + long i, j, k, a; + + for(j=0;j<256;j++) //Calculate CRC table + { + k = (j<<8); a = 0; + for(i=7;i>=0;i--) + { + if (((k^a)&0x8000) > 0) + a = ((a<<1)&65535) ^ 0x1021; //0x1021 = genpoly + else + a = ((a<<1)&65535); + k = ((k<<1)&65535); + } + crctable[j] = (a&65535); + } +} + +static char visited[MAXWALLS]; + +long GetWallZPeg(long nWall) +{ + long z=0, nSector, nNextSector; + + nSector = sectorofwall((short)nWall); + nNextSector = wall[nWall].nextsector; + if (nNextSector == -1) + { + //1-sided wall + if (wall[nWall].cstat&4) z = sector[nSector].floorz; + else z = sector[nSector].ceilingz; + } + else + { + //2-sided wall + if (wall[nWall].cstat&4) + z = sector[nSector].ceilingz; + else + { + if (sector[nNextSector].ceilingz > sector[nSector].ceilingz) + z = sector[nNextSector].ceilingz; //top step + if (sector[nNextSector].floorz < sector[nSector].floorz) + z = sector[nNextSector].floorz; //bottom step + } + } + return(z); +} + +void AlignWalls(long nWall0, long z0, long nWall1, long z1, long nTile) +{ + long n; + + //do the x alignment + wall[nWall1].cstat &= ~0x0108; //Set to non-flip + wall[nWall1].xpanning = (char)((wall[nWall0].xpanning+(wall[nWall0].xrepeat<<3))%tilesizx[nTile]); + + z1 = GetWallZPeg(nWall1); + + for(n=(picsiz[nTile]>>4);((1<>(n+3))); +} + +void AutoAlignWalls(long nWall0, long ply) +{ + long z0, z1, nTile, nWall1, branch, visible, nNextSector, nSector; + + nTile = wall[nWall0].picnum; + branch = 0; + if (ply == 0) + { + //clear visited bits + memset(visited,0,sizeof(visited)); + visited[nWall0] = 1; + } + + z0 = GetWallZPeg(nWall0); + + nWall1 = wall[nWall0].point2; + + //loop through walls at this vertex in CCW order + while (1) + { + //break if this wall would connect us in a loop + if (visited[nWall1]) break; + + visited[nWall1] = 1; + + //break if reached back of left wall + if (wall[nWall1].nextwall == nWall0) break; + + if (wall[nWall1].picnum == nTile) + { + z1 = GetWallZPeg(nWall1); + visible = 0; + + nNextSector = wall[nWall1].nextsector; + if (nNextSector < 0) + visible = 1; + else + { + //ignore two sided walls that have no visible face + nSector = wall[wall[nWall1].nextwall].nextsector; + if (getceilzofslope((short)nSector,wall[nWall1].x,wall[nWall1].y) < + getceilzofslope((short)nNextSector,wall[nWall1].x,wall[nWall1].y)) + visible = 1; + + if (getflorzofslope((short)nSector,wall[nWall1].x,wall[nWall1].y) > + getflorzofslope((short)nNextSector,wall[nWall1].x,wall[nWall1].y)) + visible = 1; + } + + if (visible) + { + branch++; + AlignWalls(nWall0,z0,nWall1,z1,nTile); + + //if wall was 1-sided, no need to recurse + if (wall[nWall1].nextwall < 0) + { + nWall0 = nWall1; + z0 = GetWallZPeg(nWall0); + nWall1 = wall[nWall0].point2; + branch = 0; + continue; + } + else + AutoAlignWalls(nWall1,ply+1); + } + } + + if (wall[nWall1].nextwall < 0) break; + nWall1 = wall[wall[nWall1].nextwall].point2; + } +} + + +/* + * vim:ts=4: + */ + diff --git a/polymer/build/src/buildstartwin.c b/polymer/build/src/buildstartwin.c new file mode 100644 index 000000000..3df25c7b6 --- /dev/null +++ b/polymer/build/src/buildstartwin.c @@ -0,0 +1,178 @@ +#ifndef RENDERTYPEWIN +#error Only for Windows +#endif + +#include "build.h" +#include "editor.h" +#include "winlayer.h" +#include "compat.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + + +#define IDCFULLSCREEN 100 +#define IDC2DVMODE 101 +#define IDC3DVMODE 102 + +static void PopulateVideoModeLists(int fs, HWND list2d, HWND list3d) +{ + int i,j; + char buf[64]; + + ComboBox_ResetContent(list2d); + ComboBox_ResetContent(list3d); + for (i=0; i 0) { + if (!IsWindow(hwndLaunch) || quitevent) break; + if (IsDialogMessage(hwndStart, &msg) /*|| IsDialogMessage(hwndLaunch, &msg)*/) continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } +#else + while (IsWindow(hwndLaunch) && !quitevent) { + x = win_getstartupcommand(); + if (x != 0) LaunchWindowProc(hwndLaunch, WM_COMMAND, x, 0); + handleevents(); + } +#endif + EnableWindow(GetDlgItem(hwndStart,WIN_STARTWIN_ITEMLIST),TRUE); + } + if (quitevent) return 1; + return 0; +} + diff --git a/polymer/build/src/cache1d.c b/polymer/build/src/cache1d.c new file mode 100644 index 000000000..abe2902c2 --- /dev/null +++ b/polymer/build/src/cache1d.c @@ -0,0 +1,1301 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#define WITHKPLIB + +#include "compat.h" +#include "cache1d.h" +#include "pragmas.h" +#include "baselayer.h" + +#ifdef WITHKPLIB +#include "kplib.h" + + //Insert '|' in front of filename + //Doing this tells kzopen to load the file only if inside a .ZIP file +static long kzipopen(char *filnam) +{ + unsigned int i; + char newst[BMAX_PATH+4]; + + newst[0] = '|'; + for(i=0;filnam[i] && (i < sizeof(newst)-2);i++) newst[i+1] = filnam[i]; + newst[i+1] = 0; + return(kzopen(newst)); +} + +#endif + + +// This module keeps track of a standard linear cacheing system. +// To use this module, here's all you need to do: +// +// Step 1: Allocate a nice BIG buffer, like from 1MB-4MB and +// Call initcache(long cachestart, long cachesize) where +// +// cachestart = (long)(pointer to start of BIG buffer) +// cachesize = length of BIG buffer +// +// Step 2: Call allocache(long *bufptr, long bufsiz, char *lockptr) +// whenever you need to allocate a buffer, where: +// +// *bufptr = pointer to 4-byte pointer to buffer +// Confused? Using this method, cache2d can remove +// previously allocated things from the cache safely by +// setting the 4-byte pointer to 0. +// bufsiz = number of bytes to allocate +// *lockptr = pointer to locking char which tells whether +// the region can be removed or not. If *lockptr = 0 then +// the region is not locked else its locked. +// +// Step 3: If you need to remove everything from the cache, or every +// unlocked item from the cache, you can call uninitcache(); +// Call uninitcache(0) to remove all unlocked items, or +// Call uninitcache(1) to remove everything. +// After calling uninitcache, it is still ok to call allocache +// without first calling initcache. + +#define MAXCACHEOBJECTS 9216 + +static long cachesize = 0; +long cachecount = 0; +char zerochar = 0; +long cachestart = 0, cacnum = 0, agecount = 0; +typedef struct { long *hand, leng; char *lock; } cactype; +cactype cac[MAXCACHEOBJECTS]; +static long lockrecip[200]; + +static char toupperlookup[256]; + +extern void *kmalloc(size_t); +extern void kfree(void *); + +static void reportandexit(char *errormessage); + +extern char pow2char[8]; + + +void initcache(long dacachestart, long dacachesize) +{ + long i; + + for(i=1;i<200;i++) lockrecip[i] = (1<<28)/(200-i); + + cachestart = dacachestart; + cachesize = dacachesize; + + cac[0].leng = cachesize; + cac[0].lock = &zerochar; + cacnum = 1; + + initprintf("initcache(): Initialised with %d bytes\n", dacachesize); +} + +void allocache(long *newhandle, long newbytes, char *newlockptr) +{ + long i, /*j,*/ z, zz, bestz=0, daval, bestval, besto=0, o1, o2, sucklen, suckz; + + newbytes = ((newbytes+15)&0xfffffff0); + + if ((unsigned)newbytes > (unsigned)cachesize) + { + Bprintf("Cachesize: %ld\n",cachesize); + Bprintf("*Newhandle: 0x%lx, Newbytes: %ld, *Newlock: %d\n",(long)newhandle,newbytes,*newlockptr); + reportandexit("BUFFER TOO BIG TO FIT IN CACHE!"); + } + + if (*newlockptr == 0) + { + reportandexit("ALLOCACHE CALLED WITH LOCK OF 0!"); + } + + //Find best place + bestval = 0x7fffffff; o1 = cachesize; + for(z=cacnum-1;z>=0;z--) + { + o1 -= cac[z].leng; + o2 = o1+newbytes; if (o2 > cachesize) continue; + + daval = 0; + for(i=o1,zz=z;i= 200) { daval = 0x7fffffff; break; } + daval += mulscale32(cac[zz].leng+65536,lockrecip[*cac[zz].lock]); + if (daval >= bestval) break; + } + if (daval < bestval) + { + bestval = daval; besto = o1; bestz = z; + if (bestval == 0) break; + } + } + + //printf("%ld %ld %ld\n",besto,newbytes,*newlockptr); + + if (bestval == 0x7fffffff) + reportandexit("CACHE SPACE ALL LOCKED UP!"); + + //Suck things out + for(sucklen=-newbytes,suckz=bestz;sucklen<0;sucklen+=cac[suckz++].leng) + if (*cac[suckz].lock) *cac[suckz].hand = 0; + + //Remove all blocks except 1 + suckz -= (bestz+1); cacnum -= suckz; + copybufbyte(&cac[bestz+suckz],&cac[bestz],(cacnum-bestz)*sizeof(cactype)); + cac[bestz].hand = newhandle; *newhandle = cachestart+besto; + cac[bestz].leng = newbytes; + cac[bestz].lock = newlockptr; + cachecount++; + + //Add new empty block if necessary + if (sucklen <= 0) return; + + bestz++; + if (bestz == cacnum) + { + cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); + cac[bestz].leng = sucklen; + cac[bestz].lock = &zerochar; + return; + } + + if (*cac[bestz].lock == 0) { cac[bestz].leng += sucklen; return; } + + cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); + for(z=cacnum-1;z>bestz;z--) cac[z] = cac[z-1]; + cac[bestz].leng = sucklen; + cac[bestz].lock = &zerochar; +} + +void suckcache(long *suckptr) +{ + long i; + + //Can't exit early, because invalid pointer might be same even though lock = 0 + for(i=0;i 0) && (*cac[i-1].lock == 0)) + { + cac[i-1].leng += cac[i].leng; + cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); + } + else if ((i < cacnum-1) && (*cac[i+1].lock == 0)) + { + cac[i+1].leng += cac[i].leng; + cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); + } + } +} + +void agecache(void) +{ + long cnt; + char ch; + + if (agecount >= cacnum) agecount = cacnum-1; + if (agecount < 0) return; + for(cnt=(cacnum>>4);cnt>=0;cnt--) + { + ch = (*cac[agecount].lock); + if (((ch-2)&255) < 198) + (*cac[agecount].lock) = ch-1; + + agecount--; if (agecount < 0) agecount = cacnum-1; + } +} + +static void reportandexit(char *errormessage) +{ + long i, j; + + //setvmode(0x3); + j = 0; + for(i=0;i + +typedef struct _searchpath { + struct _searchpath *next; + char *path; + size_t pathlen; // to save repeated calls to strlen() +} searchpath_t; +static searchpath_t *searchpathhead = NULL; +static size_t maxsearchpathlen = 0; +int pathsearchmode = 0; + +int addsearchpath(const char *p) +{ + struct stat st; + char *s; + searchpath_t *srch; + int i; + + if (Bstat(p, &st) < 0) { + if (errno == ENOENT) return -2; + return -1; + } + if (!(st.st_mode & BS_IFDIR)) return -1; + + srch = (searchpath_t*)malloc(sizeof(searchpath_t)); + if (!srch) return -1; + + srch->next = searchpathhead; + srch->pathlen = strlen(p)+1; + srch->path = (char*)malloc(srch->pathlen + 1); + if (!srch->path) { + free(srch); + return -1; + } + strcpy(srch->path, p); + for (s=srch->path; *s; s++) ; s--; if (spath || toupperlookup[*s] != '/') strcat(srch->path, "/"); + + searchpathhead = srch; + if (srch->pathlen > maxsearchpathlen) maxsearchpathlen = srch->pathlen; + initprintf("addsearchpath(): Added %s\n", srch->path); + + return 0; +} + +int findfrompath(const char *fn, char **where) +{ + searchpath_t *sp; + char *pfn, *ffn; + int allocsiz; + + // pathsearchmode == 0: tests current dir and then the dirs of the path stack + // pathsearchmode == 1: tests fn without modification, then like for pathsearchmode == 0 + + if (pathsearchmode) { + // test unmolested filename first + if (access(fn, F_OK) >= 0) { + *where = strdup(fn); + return 0; + } + } + + for (pfn = (char*)fn; toupperlookup[*pfn] == '/'; pfn++); + ffn = strdup(pfn); + if (!ffn) return -1; + Bcorrectfilename(ffn,0); // compress relative paths + + allocsiz = max(maxsearchpathlen, 2); // "./" (aka. curdir) + allocsiz += strlen(ffn); + allocsiz += 1; // a nul + + pfn = (char *)malloc(allocsiz); + if (!pfn) { free(ffn); return -1; } + + strcpy(pfn, "./"); + strcat(pfn, ffn); + if (access(pfn, F_OK) >= 0) { + *where = pfn; + free(ffn); + return 0; + } + + for (sp = searchpathhead; sp; sp = sp->next) { + strcpy(pfn, sp->path); + strcat(pfn, ffn); + //initprintf("Trying %s\n", pfn); + if (access(pfn, F_OK) >= 0) { + *where = pfn; + free(ffn); + return 0; + } + } + free(pfn); free(ffn); + return -1; +} + +int openfrompath(const char *fn, int flags, int mode) +{ + char *pfn; + int h; + + if (findfrompath(fn, &pfn) < 0) return -1; + h = Bopen(pfn, flags, mode); + free(pfn); + + return h; +} + +BFILE* fopenfrompath(const char *fn, const char *mode) +{ + int fh; + BFILE *h; + int bmode = 0, smode = 0; + const char *c; + + for (c=mode; c[0]; ) { + if (c[0] == 'r' && c[1] == '+') { bmode = BO_RDWR; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'r') { bmode = BO_RDONLY; smode = BS_IREAD; c+=1; } + else if (c[0] == 'w' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'w') { bmode = BO_WRONLY|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'a' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'a') { bmode = BO_WRONLY|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=1; } + else if (c[0] == 'b') { bmode |= BO_BINARY; c+=1; } + else if (c[1] == 't') { bmode |= BO_TEXT; c+=1; } + else c++; + } + fh = openfrompath(fn,bmode,smode); + if (fh < 0) return NULL; + + h = fdopen(fh,mode); + if (!h) close(fh); + + return h; +} + + +#define MAXGROUPFILES 4 //Warning: Fix groupfil if this is changed +#define MAXOPENFILES 64 //Warning: Fix filehan if this is changed + +static char toupperlookup[256] = +{ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, + 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, + 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff +}; + +static long numgroupfiles = 0; +static long gnumfiles[MAXGROUPFILES]; +static long groupfil[MAXGROUPFILES] = {-1,-1,-1,-1}; +static long groupfilpos[MAXGROUPFILES]; +static char *gfilelist[MAXGROUPFILES]; +static long *gfileoffs[MAXGROUPFILES]; + +static char filegrp[MAXOPENFILES]; +static long filepos[MAXOPENFILES]; +static long filehan[MAXOPENFILES] = +{ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 +}; +#ifdef WITHKPLIB +static char filenamsav[MAXOPENFILES][260]; +static long kzcurhand = -1; +#endif + +long initgroupfile(char *filename) +{ + char buf[16]; + long i, j, k; +#ifdef WITHKPLIB + char *zfn; + searchpath_t *sp = NULL; +#endif + +#ifdef _WIN32 + // on Windows, translate all backslashes (0x5c) to forward slashes (0x2f) + toupperlookup[0x5c] = 0x2f; +#endif + +#ifdef WITHKPLIB + if (findfrompath(filename, &zfn) < 0) return -1; + + // check to see if the file passed is a ZIP and pass it on to kplib if it is + i = Bopen(zfn,BO_BINARY|BO_RDONLY,BS_IREAD); + if (i < 0) { free(zfn); return -1; } + + Bread(i, buf, 4); + if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x03 && buf[3] == 0x04) { + Bclose(i); + j = kzaddstack(zfn); + free(zfn); + return j; + } + free(zfn); + + if (numgroupfiles >= MAXGROUPFILES) return(-1); + + Blseek(i,0,BSEEK_SET); + groupfil[numgroupfiles] = i; +#else + groupfil[numgroupfiles] = openfrompath(filename,BO_BINARY|BO_RDONLY,BS_IREAD); + if (groupfil[numgroupfiles] != -1) +#endif + { + groupfilpos[numgroupfiles] = 0; + Bread(groupfil[numgroupfiles],buf,16); + if ((buf[0] != 'K') || (buf[1] != 'e') || (buf[2] != 'n') || + (buf[3] != 'S') || (buf[4] != 'i') || (buf[5] != 'l') || + (buf[6] != 'v') || (buf[7] != 'e') || (buf[8] != 'r') || + (buf[9] != 'm') || (buf[10] != 'a') || (buf[11] != 'n')) + { + Bclose(groupfil[numgroupfiles]); + groupfil[numgroupfiles] = -1; + return(-1); + } + gnumfiles[numgroupfiles] = B_LITTLE32(*((long *)&buf[12])); + + if ((gfilelist[numgroupfiles] = (char *)kmalloc(gnumfiles[numgroupfiles]<<4)) == 0) + { Bprintf("Not enough memory for file grouping system\n"); exit(0); } + if ((gfileoffs[numgroupfiles] = (long *)kmalloc((gnumfiles[numgroupfiles]+1)<<2)) == 0) + { Bprintf("Not enough memory for file grouping system\n"); exit(0); } + + Bread(groupfil[numgroupfiles],gfilelist[numgroupfiles],gnumfiles[numgroupfiles]<<4); + + j = 0; + for(i=0;i=0;i--) + if (groupfil[i] != -1 && groupfil[i] == grphandle) + { + kfree(gfilelist[i]); + kfree(gfileoffs[i]); + Bclose(groupfil[i]); + groupfil[i] = -1; + grpnum = i; + break; + } + + if (grpnum == -1) return; + + // JBF 20040111 + numgroupfiles--; + + // move any group files following this one back + for (i=grpnum+1; i= 254) // external file (255) or ZIPped file (254) + continue; + else if (filegrp[i] == grpnum) // close file in group we closed + filehan[i] = -1; + else if (filegrp[i] > grpnum) // move back a file in a group after the one we closed + filegrp[i]--; + } +} + +void uninitgroupfile(void) +{ + long i; + + for(i=numgroupfiles-1;i>=0;i--) + if (groupfil[i] != -1) + { + kfree(gfilelist[i]); + kfree(gfileoffs[i]); + Bclose(groupfil[i]); + groupfil[i] = -1; + } + numgroupfiles = 0; + + // JBF 20040111: "close" any files open in groups + for(i=0;i= 0) + { + filegrp[newhandle] = 255; + filehan[newhandle] = fil; + filepos[newhandle] = 0; + return(newhandle); + } + + for (; toupperlookup[*filename] == '/'; filename++); + +#ifdef WITHKPLIB + if ((kzcurhand != newhandle) && (kztell() >= 0)) + { + if (kzcurhand >= 0) filepos[kzcurhand] = kztell(); + kzclose(); + } + if (searchfirst != 1 && (i = kzipopen(filename)) != 0) { + kzcurhand = newhandle; + filegrp[newhandle] = 254; + filehan[newhandle] = i; + filepos[newhandle] = 0; + strcpy(filenamsav[newhandle],filename); + return newhandle; + } +#endif + + for(k=numgroupfiles-1;k>=0;k--) + { + if (searchfirst == 1) k = 0; + if (groupfil[k] >= 0) + { + for(i=gnumfiles[k]-1;i>=0;i--) + { + gfileptr = (char *)&gfilelist[k][i<<4]; + + bad = 0; + for(j=0;j<13;j++) + { + if (!filename[j]) break; + if (toupperlookup[filename[j]] != toupperlookup[gfileptr[j]]) + { bad = 1; break; } + } + if (bad) continue; + if (j<13 && gfileptr[j]) continue; // JBF: because e1l1.map might exist before e1l1 + if (j==13 && filename[j]) continue; // JBF: long file name + + filegrp[newhandle] = k; + filehan[newhandle] = i; + filepos[newhandle] = 0; + return(newhandle); + } + } + } + return(-1); +} + +long kread(long handle, void *buffer, long leng) +{ + long i, filenum, groupnum; + + filenum = filehan[handle]; + groupnum = filegrp[handle]; + if (groupnum == 255) return(Bread(filenum,buffer,leng)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return(kzread(buffer,leng)); + } +#endif + + if (groupfil[groupnum] != -1) + { + i = gfileoffs[groupnum][filenum]+filepos[handle]; + if (i != groupfilpos[groupnum]) + { + Blseek(groupfil[groupnum],i+((gnumfiles[groupnum]+1)<<4),BSEEK_SET); + groupfilpos[groupnum] = i; + } + leng = min(leng,(gfileoffs[groupnum][filenum+1]-gfileoffs[groupnum][filenum])-filepos[handle]); + leng = Bread(groupfil[groupnum],buffer,leng); + filepos[handle] += leng; + groupfilpos[groupnum] += leng; + return(leng); + } + + return(0); +} + +long klseek(long handle, long offset, long whence) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + + if (groupnum == 255) return(Blseek(filehan[handle],offset,whence)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return(kzseek(offset,whence)); + } +#endif + + if (groupfil[groupnum] != -1) + { + switch(whence) + { + case BSEEK_SET: filepos[handle] = offset; break; + case BSEEK_END: i = filehan[handle]; + filepos[handle] = (gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i])+offset; + break; + case BSEEK_CUR: filepos[handle] += offset; break; + } + return(filepos[handle]); + } + return(-1); +} + +long kfilelength(long handle) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + if (groupnum == 255) { + // return(filelength(filehan[handle])) + return Bfilelength(filehan[handle]); + } +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return kzfilelength(); + } +#endif + i = filehan[handle]; + return(gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i]); +} + +long ktell(long handle) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + + if (groupnum == 255) return(Blseek(filehan[handle],0,BSEEK_CUR)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return kztell(); + } +#endif + if (groupfil[groupnum] != -1) + return filepos[handle]; + return(-1); +} + +void kclose(long handle) +{ + if (handle < 0) return; + if (filegrp[handle] == 255) Bclose(filehan[handle]); +#ifdef WITHKPLIB + else if (filegrp[handle] == 254) + { + kzclose(); + kzcurhand = -1; + } +#endif + filehan[handle] = -1; +} + +static int klistaddentry(CACHE1D_FIND_REC **rec, char *name, int type, int source) +{ + CACHE1D_FIND_REC *r = NULL, *attach = NULL; + + if (*rec) { + int insensitive, v; + CACHE1D_FIND_REC *last = NULL; + + for (attach = *rec; attach; last = attach, attach = attach->next) { + if (type == CACHE1D_FIND_DRIVE) continue; // we just want to get to the end for drives +#ifdef _WIN32 + insensitive = 1; +#else + if (source == CACHE1D_SOURCE_GRP || attach->source == CACHE1D_SOURCE_GRP) + insensitive = 1; + else if (source == CACHE1D_SOURCE_ZIP || attach->source == CACHE1D_SOURCE_ZIP) + insensitive = 1; + else + insensitive = 0; +#endif + if (insensitive) v = Bstrcasecmp(name, attach->name); + else v = Bstrcmp(name, attach->name); + + // sorted list + if (v > 0) continue; // item to add is bigger than the current one + // so look for something bigger than us + if (v < 0) { // item to add is smaller than the current one + attach = NULL; // so wedge it between the current item and the one before + break; + } + + // matched + if (source >= attach->source) return 1; // item to add is of lower priority + r = attach; + break; + } + + // wasn't found in the list, so attach to the end + if (!attach) attach = last; + } + + if (r) { + r->type = type; + r->source = source; + return 0; + } + + r = (CACHE1D_FIND_REC *)malloc(sizeof(CACHE1D_FIND_REC)+strlen(name)+1); + if (!r) return -1; + r->name = (char*)r + sizeof(CACHE1D_FIND_REC); strcpy(r->name, name); + r->type = type; + r->source = source; + r->usera = r->userb = NULL; + + if (!attach) { // we are the first item + r->prev = NULL; + r->next = *rec; + if (*rec) (*rec)->prev = r; + *rec = r; + } else { + r->prev = attach; + r->next = attach->next; + if (attach->next) attach->next->prev = r; + attach->next = r; + } + + return 0; +} + +void klistfree(CACHE1D_FIND_REC *rec) +{ + CACHE1D_FIND_REC *n; + + while (rec) { + n = rec->next; + free(rec); + rec = n; + } +} + +CACHE1D_FIND_REC *klistpath(const char *_path, const char *mask, int type) +{ + CACHE1D_FIND_REC *rec = NULL; + char *path; + + // pathsearchmode == 0: enumerates a path in the virtual filesystem + // pathsearchmode == 1: enumerates the system filesystem path passed in + + path = strdup(_path); + if (!path) return NULL; + + // we don't need any leading dots and slashes or trailing slashes either + { + int i,j; + for (i=0; path[i] == '.' || toupperlookup[path[i]] == '/'; ) i++; + for (j=0; path[j] = path[i]; j++,i++) ; + while (j>0 && toupperlookup[path[j-1]] == '/') j--; + path[j] = 0; + //initprintf("Cleaned up path = \"%s\"\n",path); + } + + if (*path && (type & CACHE1D_FIND_DIR)) { + if (klistaddentry(&rec, "..", CACHE1D_FIND_DIR, CACHE1D_SOURCE_CURDIR) < 0) goto failure; + } + + if (!(type & CACHE1D_OPT_NOSTACK)) { // current directory and paths in the search stack + searchpath_t *search = NULL; + BDIR *dir; + struct Bdirent *dirent; + const char *d = "."; + int stackdepth = CACHE1D_SOURCE_CURDIR; + char buf[BMAX_PATH]; + + if (pathsearchmode) d = _path; + + do { + if (!pathsearchmode) { + strcpy(buf, path); + if (*path) strcat(buf, "/"); + strcat(buf, d); + } else strcpy(buf, d); + dir = Bopendir(buf); + if (dir) { + while ((dirent = Breaddir(dir))) { + if ((dirent->name[0] == '.' && dirent->name[1] == 0) || + (dirent->name[0] == '.' && dirent->name[1] == '.' && dirent->name[2] == 0)) + continue; + if ((type & CACHE1D_FIND_DIR) && !(dirent->mode & BS_IFDIR)) continue; + if ((type & CACHE1D_FIND_FILE) && (dirent->mode & BS_IFDIR)) continue; + if (!Bwildmatch(dirent->name, mask)) continue; + switch (klistaddentry(&rec, dirent->name, + (dirent->mode & BS_IFDIR) ? CACHE1D_FIND_DIR : CACHE1D_FIND_FILE, + stackdepth)) { + case -1: goto failure; + //case 1: initprintf("%s:%s dropped for lower priority\n", d,dirent->name); break; + //case 0: initprintf("%s:%s accepted\n", d,dirent->name); break; + default: break; + } + } + Bclosedir(dir); + } + + if (pathsearchmode) break; + + if (!search) { + search = searchpathhead; + stackdepth = CACHE1D_SOURCE_PATH; + } else { + search = search->next; + stackdepth++; + } + if (search) d = search->path; + } while (search); + } + + if (!pathsearchmode) { // next, zip files + char buf[BMAX_PATH], *p; + int i, j, ftype; + strcpy(buf,path); + if (*path) strcat(buf,"/"); + strcat(buf,mask); + for (kzfindfilestart(buf); kzfindfile(buf); ) { + if (buf[0] != '|') continue; // local files we don't need + + // scan for the end of the string and shift + // everything left a char in the process + for (i=1; (buf[i-1]=buf[i]); i++) ; i-=2; + + // if there's a slash at the end, this is a directory entry + if (toupperlookup[buf[i]] == '/') { ftype = CACHE1D_FIND_DIR; buf[i] = 0; } + else ftype = CACHE1D_FIND_FILE; + + // skip over the common characters at the beginning of the base path and the zip entry + for (j=0; buf[j] && path[j]; j++) { + if (toupperlookup[ path[j] ] == toupperlookup[ buf[j] ]) continue; + break; + } + // we've now hopefully skipped the common path component at the beginning. + // if that's true, we should be staring at a null byte in path and either any character in buf + // if j==0, or a slash if j>0 + if ((!path[0] && buf[j]) || (!path[j] && toupperlookup[ buf[j] ] == '/')) { + if (j>0) j++; + + // yep, so now we shift what follows back to the start of buf and while we do that, + // keep an eye out for any more slashes which would mean this entry has sub-entities + // and is useless to us. + for (i = 0; (buf[i] = buf[j]) && toupperlookup[buf[j]] != '/'; i++,j++) ; + if (toupperlookup[buf[j]] == '/') continue; // damn, try next entry + } else { + // if we're here it means we have a situation where: + // path = foo + // buf = foobar... + // or + // path = foobar + // buf = foo... + // which would mean the entry is higher up in the directory tree and is also useless + continue; + } + + if ((type & CACHE1D_FIND_DIR) && ftype != CACHE1D_FIND_DIR) continue; + if ((type & CACHE1D_FIND_FILE) && ftype != CACHE1D_FIND_FILE) continue; + + // the entry is in the clear + switch (klistaddentry(&rec, buf, ftype, CACHE1D_SOURCE_ZIP)) { + case -1: goto failure; + //case 1: initprintf(":%s dropped for lower priority\n", buf); break; + //case 0: initprintf(":%s accepted\n", buf); break; + default: break; + } + } + } + + // then, grp files + if (!pathsearchmode && !*path && (type & CACHE1D_FIND_FILE)) { + char buf[13]; + int i,j; + buf[12] = 0; + for (i=0;i=0;j--) + { + Bmemcpy(buf,&gfilelist[i][j<<4],12); + if (!Bwildmatch(buf,mask)) continue; + switch (klistaddentry(&rec, buf, CACHE1D_FIND_FILE, CACHE1D_SOURCE_GRP)) { + case -1: goto failure; + //case 1: initprintf(":%s dropped for lower priority\n", workspace); break; + //case 0: initprintf(":%s accepted\n", workspace); break; + default: break; + } + } + } + } + + if (pathsearchmode && (type & CACHE1D_FIND_DRIVE)) { + char *drives, *drp; + drives = Bgetsystemdrives(); + if (drives) { + for (drp=drives; *drp; drp+=strlen(drp)+1) { + if (klistaddentry(&rec, drp, CACHE1D_FIND_DRIVE, CACHE1D_SOURCE_DRIVE) < 0) { + free(drives); + goto failure; + } + } + free(drives); + } + } + + free(path); + return rec; +failure: + free(path); + klistfree(rec); + return NULL; +} + + //Internal LZW variables +#define LZWSIZE 16384 //Watch out for shorts! +static char *lzwbuf1, *lzwbuf4, *lzwbuf5, lzwbuflock[5]; +static short *lzwbuf2, *lzwbuf3; + +static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf); +static long lzwuncompress(char *lzwinbuf, long compleng, char *lzwoutbuf); + +int kdfread(void *buffer, bsize_t dasizeof, bsize_t count, long fil) +{ + unsigned long i, j, k, kgoal; + short leng; + char *ptr; + + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; + if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); + if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + + copybufbyte(lzwbuf4,ptr,(long)dasizeof); + k += (long)dasizeof; + + for(i=1;i= kgoal) + { + if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); + if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + } + for(j=0;j>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); + if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + + copybufbyte(lzwbuf4,ptr,(long)dasizeof); + k += (long)dasizeof; + + for(i=1;i= kgoal) + { + if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); + if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + } + for(j=0;j>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + copybufbyte(ptr,lzwbuf4,(long)dasizeof); + k = dasizeof; + + if (k > LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + + for(i=1;i LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + ptr += dasizeof; + } + if (k > 0) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; +} + +void dfwrite(void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil) +{ + unsigned long i, j, k; + short leng, swleng; + char *ptr; + + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; + if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + copybufbyte(ptr,lzwbuf4,(long)dasizeof); + k = dasizeof; + + if (k > LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + + for(i=1;i LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + ptr += dasizeof; + } + if (k > 0) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; +} + +static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf) +{ + long i, addr, newaddr, addrcnt, zx, *intptr; + long bytecnt1, bitcnt, numbits, oneupnumbits; + short *shortptr; + + for(i=255;i>=0;i--) { lzwbuf1[i] = i; lzwbuf3[i] = (i+1)&255; } + clearbuf(lzwbuf2,256>>1,0xffffffff); + clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L); + + addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3); + numbits = 8; oneupnumbits = (1<<8); + do + { + addr = lzwinbuf[bytecnt1]; + do + { + bytecnt1++; + if (bytecnt1 == uncompleng) break; + if (lzwbuf2[addr] < 0) {lzwbuf2[addr] = addrcnt; break;} + newaddr = lzwbuf2[addr]; + while (lzwbuf1[newaddr] != lzwinbuf[bytecnt1]) + { + zx = lzwbuf3[newaddr]; + if (zx < 0) {lzwbuf3[newaddr] = addrcnt; break;} + newaddr = zx; + } + if (lzwbuf3[newaddr] == addrcnt) break; + addr = newaddr; + } while (addr >= 0); + lzwbuf1[addrcnt] = lzwinbuf[bytecnt1]; + lzwbuf2[addrcnt] = -1; + lzwbuf3[addrcnt] = -1; + + intptr = (long *)&lzwoutbuf[bitcnt>>3]; + intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); + bitcnt += numbits; + if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) + bitcnt--; + + addrcnt++; + if (addrcnt > oneupnumbits) { numbits++; oneupnumbits <<= 1; } + } while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3))); + + intptr = (long *)&lzwoutbuf[bitcnt>>3]; + intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); + bitcnt += numbits; + if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) + bitcnt--; + + shortptr = (short *)lzwoutbuf; + shortptr[0] = B_LITTLE16((short)uncompleng); + if (((bitcnt+7)>>3) < uncompleng) + { + shortptr[1] = B_LITTLE16((short)addrcnt); + return((bitcnt+7)>>3); + } + shortptr[1] = (short)0; + for(i=0;i>2); + return((long)B_LITTLE16(shortptr[0])); //uncompleng + } + for(i=255;i>=0;i--) { lzwbuf2[i] = i; lzwbuf3[i] = i; } + currstr = 256; bitcnt = (4<<3); outbytecnt = 0; + numbits = 8; oneupnumbits = (1<<8); + do + { + intptr = (long *)&lzwinbuf[bitcnt>>3]; + dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1)); + bitcnt += numbits; + if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1))) + { dat &= ((oneupnumbits>>1)-1); bitcnt--; } + + lzwbuf3[currstr] = dat; + + for(leng=0;dat>=256;leng++,dat=lzwbuf3[dat]) + lzwbuf1[leng] = lzwbuf2[dat]; + + lzwoutbuf[outbytecnt++] = dat; + for(i=leng-1;i>=0;i--) lzwoutbuf[outbytecnt++] = lzwbuf1[i]; + + lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat; + currstr++; + if (currstr > oneupnumbits) { numbits++; oneupnumbits <<= 1; } + } while (currstr < strtot); + return((long)B_LITTLE16(shortptr[0])); //uncompleng +} + +/* + * vim:ts=4:sw=4: + */ diff --git a/polymer/build/src/compat.c b/polymer/build/src/compat.c new file mode 100644 index 000000000..0b9454d4d --- /dev/null +++ b/polymer/build/src/compat.c @@ -0,0 +1,716 @@ +/* + * Playing-field leveller for Build + * by Jonathon Fowler + * + * A note about this: + * 1. There is some kind of problem somewhere in the functions below because + * compiling with __compat_h_macrodef__ disabled makes stupid things happen. + * 2. The functions below, aside from the ones which aren't trivial, were never + * really intended to be used for anything except tracking anr removing ties + * to the standard C library from games. Using the Bxx versions of functions + * means we can redefine those names to link up with different runtime library + * names. + */ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define _WIN32_IE 0x0400 +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__WATCOMC__) +# include +#elif defined(_MSC_VER) +# include +#else +# include +#endif + +#include "compat.h" + + +#ifndef __compat_h_macrodef__ + +int Brand(void) +{ + return rand(); +} + +void *Bmalloc(bsize_t size) +{ + return malloc(size); +} + +void Bfree(void *ptr) +{ + free(ptr); +} + +int Bopen(const char *pathname, int flags, unsigned mode) +{ + int n=0,o=0; + + if (flags&BO_BINARY) n|=O_BINARY; else n|=O_TEXT; + if ((flags&BO_RDWR)==BO_RDWR) n|=O_RDWR; + else if ((flags&BO_RDWR)==BO_WRONLY) n|=O_WRONLY; + else if ((flags&BO_RDWR)==BO_RDONLY) n|=O_RDONLY; + if (flags&BO_APPEND) n|=O_APPEND; + if (flags&BO_CREAT) n|=O_CREAT; + if (flags&BO_TRUNC) n|=O_TRUNC; + if (mode&BS_IREAD) o|=S_IREAD; + if (mode&BS_IWRITE) o|=S_IWRITE; + if (mode&BS_IEXEC) o|=S_IEXEC; + + return open(pathname,n,o); +} + +int Bclose(int fd) +{ + return close(fd); +} + +bssize_t Bwrite(int fd, const void *buf, bsize_t count) +{ + return write(fd,buf,count); +} + +bssize_t Bread(int fd, void *buf, bsize_t count) +{ + return read(fd,buf,count); +} + +int Blseek(int fildes, int offset, int whence) +{ + switch (whence) { + case BSEEK_SET: whence=SEEK_SET; break; + case BSEEK_CUR: whence=SEEK_CUR; break; + case BSEEK_END: whence=SEEK_END; break; + } + return lseek(fildes,offset,whence); +} + +BFILE *Bfopen(const char *path, const char *mode) +{ + return (BFILE*)fopen(path,mode); +} + +int Bfclose(BFILE *stream) +{ + return fclose((FILE*)stream); +} + +void Brewind(BFILE *stream) +{ + rewind((FILE*)stream); +} + +int Bfgetc(BFILE *stream) +{ + return fgetc((FILE*)stream); +} + +char *Bfgets(char *s, int size, BFILE *stream) +{ + return fgets(s,size,(FILE*)stream); +} + +int Bfputc(int c, BFILE *stream) +{ + return fputc(c,(FILE*)stream); +} + +int Bfputs(const char *s, BFILE *stream) +{ + return fputs(s,(FILE*)stream); +} + +bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) +{ + return fread(ptr,size,nmemb,(FILE*)stream); +} + +bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) +{ + return fwrite(ptr,size,nmemb,(FILE*)stream); +} + + +char *Bstrdup(const char *s) +{ + return strdup(s); +} + +char *Bstrcpy(char *dest, const char *src) +{ + return strcpy(dest,src); +} + +char *Bstrncpy(char *dest, const char *src, bsize_t n) +{ + return strncpy(dest,src,n); +} + +int Bstrcmp(const char *s1, const char *s2) +{ + return strcmp(s1,s2); +} + +int Bstrncmp(const char *s1, const char *s2, bsize_t n) +{ + return strncmp(s1,s2,n); +} + +int Bstrcasecmp(const char *s1, const char *s2) +{ +#ifdef _MSC_VER + return stricmp(s1,s2); +#else + return strcasecmp(s1,s2); +#endif +} + +int Bstrncasecmp(const char *s1, const char *s2, bsize_t n) +{ +#ifdef _MSC_VER + return strnicmp(s1,s2,n); +#else + return strncasecmp(s1,s2,n); +#endif +} + +char *Bstrcat(char *dest, const char *src) +{ + return strcat(dest,src); +} + +char *Bstrncat(char *dest, const char *src, bsize_t n) +{ + return strncat(dest,src,n); +} + +bsize_t Bstrlen(const char *s) +{ + return strlen(s); +} + +char *Bstrchr(const char *s, int c) +{ + return strchr(s,c); +} + +char *Bstrrchr(const char *s, int c) +{ + return strrchr(s,c); +} + +int Batoi(const char *nptr) +{ + return atoi(nptr); +} + +long Batol(const char *nptr) +{ + return atol(nptr); +} + +long int Bstrtol(const char *nptr, char **endptr, int base) +{ + return strtol(nptr,endptr,base); +} + +unsigned long int Bstrtoul(const char *nptr, char **endptr, int base) +{ + return strtoul(nptr,endptr,base); +} + +void *Bmemcpy(void *dest, const void *src, bsize_t n) +{ + return memcpy(dest,src,n); +} + +void *Bmemmove(void *dest, const void *src, bsize_t n) +{ + return memmove(dest,src,n); +} + +void *Bmemchr(const void *s, int c, bsize_t n) +{ + return memchr(s,c,n); +} + +void *Bmemset(void *s, int c, bsize_t n) +{ + return memset(s,c,n); +} + +int Bprintf(const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vprintf(format,ap); +#else + r = vprintf(format,ap); +#endif + va_end(ap); + return r; +} + +int Bsprintf(char *str, const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vsprintf(str,format,ap); +#else + r = vsprintf(str,format,ap); +#endif + va_end(ap); + return r; +} + +int Bsnprintf(char *str, bsize_t size, const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vsnprintf(str,size,format,ap); +#else + r = vsnprintf(str,size,format,ap); +#endif + va_end(ap); + return r; +} + +int Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap) +{ +#ifdef _MSC_VER + return _vsnprintf(str,size,format,ap); +#else + return vsnprintf(str,size,format,ap); +#endif +} + +char *Bgetenv(const char *name) +{ + return getenv(name); +} + +char *Bgetcwd(char *buf, bsize_t size) +{ + return getcwd(buf,size); +} + +#endif // __compat_h_macrodef__ + + +// +// Stuff which must be a function +// + +char *Bgethomedir(void) +{ +#ifdef _WIN32 + TCHAR appdata[MAX_PATH]; + +//# if defined SHGetFolderPath +// if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, appdata))) +//# if defined SHGetSpecialFolderPath + if (SUCCEEDED(SHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE))) +//# else +//# error Cannot find SHGetFolderPath or SHGetSpecialFolderPath. Perhaps your shlobj.h is ancient? +//# endif + return strdup(appdata); + return NULL; +#else + char *e = getenv("HOME"); + if (!e) return NULL; + return strdup(e); +#endif +} + +int Bcorrectfilename(char *filename, int removefn) +{ + char *fn; + char *tokarr[64], *first, *next, *token; + int i, ntok = 0, leadslash = 0, trailslash = 0; + + fn = strdup(filename); + if (!fn) return -1; + + for (first=fn; *first; first++) { +#ifdef _WIN32 + if (*first == '\\') *first = '/'; +#endif + } + leadslash = (*fn == '/'); + trailslash = (first>fn && first[-1] == '/'); + + first = fn; + do { + token = Bstrtoken(first, "/", &next, 1); + first = NULL; + if (!token) break; + else if (token[0] == 0) continue; + else if (token[0] == '.' && token[1] == 0) continue; + else if (token[0] == '.' && token[1] == '.' && token[2] == 0) ntok = max(0,ntok-1); + else tokarr[ntok++] = token; + } while (1); + + if (!trailslash && removefn) { ntok = max(0,ntok-1); trailslash = 1; } + if (ntok == 0 && trailslash && leadslash) trailslash = 0; + + first = filename; + if (leadslash) *(first++) = '/'; + for (i=0; i0) *(first++) = '/'; + for (token=tokarr[i]; *token; token++) + *(first++) = *token; + } + if (trailslash) *(first++) = '/'; + *(first++) = 0; + + return 0; +} + +int Bcanonicalisefilename(char *filename, int removefn) +{ + char cwd[BMAX_PATH], fn[BMAX_PATH], *p; + char *fnp = filename; +#ifdef _WIN32 + int drv = 0; +#endif + +#ifdef _WIN32 + { + if (filename[0] && filename[1] == ':') { + // filename is prefixed with a drive + drv = toupper(filename[0])-'A' + 1; + fnp += 2; + } + if (!_getdcwd(drv, cwd, sizeof(cwd))) return -1; + for (p=cwd; *p; p++) if (*p == '\\') *p = '/'; + } +#else + if (!getcwd(cwd,sizeof(cwd))) return -1; +#endif + p = strrchr(cwd,'/'); if (!p || p[1]) strcat(cwd, "/"); + + strcpy(fn, fnp); +#ifdef _WIN32 + for (p=fn; *p; p++) if (*p == '\\') *p = '/'; +#endif + + if (fn[0] != '/') { + // we are dealing with a path relative to the current directory + strcpy(filename, cwd); + strcat(filename, fn); + } else { +#ifdef _WIN32 + filename[0] = cwd[0]; + filename[1] = ':'; + filename[2] = 0; +#else + filename[0] = 0; +#endif + strcat(filename, fn); + } + fnp = filename; +#ifdef _WIN32 + fnp += 2; // skip the drive +#endif + + return Bcorrectfilename(fnp,1); +} + +char *Bgetsystemdrives(void) +{ +#ifdef _WIN32 + char *str, *p; + DWORD drv, mask; + int number=0; + + drv = GetLogicalDrives(); + if (drv == 0) return NULL; + + for (mask=1; mask<0x8000000l; mask<<=1) { + if ((drv&mask) == 0) continue; + number++; + } + + str = p = (char *)malloc(1 + (3*number)); + if (!str) return NULL; + + number = 0; + for (mask=1; mask<0x8000000l; mask<<=1, number++) { + if ((drv&mask) == 0) continue; + *(p++) = 'A' + number; + *(p++) = ':'; + *(p++) = 0; + } + *(p++) = 0; + + return str; +#else + // Perhaps have Unix OS's put /, /home/user, and /mnt/* in the "drives" list? + return NULL; +#endif +} + + +long Bfilelength(int fd) +{ + struct stat st; + if (fstat(fd, &st) < 0) return -1; + return(long)(st.st_size); +} + + +typedef struct { +#ifdef _MSC_VER + long dir; + struct _finddata_t fid; +#else + DIR *dir; +#endif + struct Bdirent info; + int status; + char name[1]; +} BDIR_real; + +BDIR* Bopendir(const char *name) +{ + BDIR_real *dirr; +#ifdef _MSC_VER + char *t,*tt; + t = (char*)malloc(strlen(name)+1+4); + if (!t) return NULL; +#endif + + dirr = (BDIR_real*)malloc(sizeof(BDIR_real) + strlen(name)); + if (!dirr) { +#ifdef _MSC_VER + free(t); +#endif + return NULL; + } + +#ifdef _MSC_VER + strcpy(t,name); + tt = t+strlen(name)-1; + while (*tt == ' ' && tt>t) tt--; + if (*tt != '/' && *tt != '\\') *(++tt) = '/'; + *(++tt) = '*'; + *(++tt) = '.'; + *(++tt) = '*'; + *(++tt) = 0; + + dirr->dir = _findfirst(t,&dirr->fid); + free(t); + if (dirr->dir == -1) { + free(dirr); + return NULL; + } +#else + dirr->dir = opendir(name); + if (dirr->dir == NULL) { + free(dirr); + return NULL; + } +#endif + + dirr->status = 0; + strcpy(dirr->name, name); + + return (BDIR*)dirr; +} + +struct Bdirent* Breaddir(BDIR *dir) +{ + BDIR_real *dirr = (BDIR_real*)dir; + struct dirent *de; + struct stat st; + char *fn; + +#ifdef _MSC_VER + if (dirr->status > 0) { + if (_findnext(dirr->dir,&dirr->fid) != 0) { + dirr->status = -1; + return NULL; + } + } + dirr->info.namlen = strlen(dirr->fid.name); + dirr->info.name = dirr->fid.name; + dirr->status++; +#else + de = readdir(dirr->dir); + if (de == NULL) { + dirr->status = -1; + return NULL; + } else { + dirr->status++; + } +//# if defined(__WATCOMC__) || defined(__linux) || defined(__BEOS__) || defined(__QNX__) || defined(SKYOS) + dirr->info.namlen = strlen(de->d_name); +//# else +// dirr->info.namlen = de->d_namlen; +//# endif + dirr->info.name = de->d_name; +#endif + dirr->info.mode = 0; + dirr->info.size = 0; + dirr->info.mtime = 0; + + fn = (char *)malloc(strlen(dirr->name) + 1 + dirr->info.namlen + 1); + if (fn) { + sprintf(fn,"%s/%s",dirr->name,dirr->info.name); + if (!stat(fn, &st)) { + dirr->info.mode = st.st_mode; + dirr->info.size = st.st_size; + dirr->info.mtime = st.st_mtime; + } + free(fn); + } + + return &dirr->info; +} + +int Bclosedir(BDIR *dir) +{ + BDIR_real *dirr = (BDIR_real*)dir; + +#ifdef _MSC_VER + _findclose(dirr->dir); +#else + closedir(dirr->dir); +#endif + free(dirr); + + return 0; +} + + +char *Bstrtoken(char *s, char *delim, char **ptrptr, int chop) +{ + char *p, *start; + + if (!ptrptr) return NULL; + + if (s) p = s; + else p = *ptrptr; + + if (!p) return NULL; + + while (*p != 0 && strchr(delim, *p)) p++; + if (*p == 0) { + *ptrptr = NULL; + return NULL; + } + start = p; + while (*p != 0 && !strchr(delim, *p)) p++; + if (*p == 0) *ptrptr = NULL; + else { + if (chop) *(p++) = 0; + *ptrptr = p; + } + + return start; +} + + + //Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher + //Given: string i and string j. string j can have wildcards + //Returns: 1:matches, 0:doesn't match +long Bwildmatch (const char *i, const char *j) +{ + const char *k; + char c0, c1; + + if (!*j) return(1); + do + { + if (*j == '*') + { + for(k=i,j++;*k;k++) if (Bwildmatch(k,j)) return(1); + continue; + } + if (!*i) return(0); + if (*j == '?') { i++; j++; continue; } + c0 = *i; if ((c0 >= 'a') && (c0 <= 'z')) c0 -= 32; + c1 = *j; if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32; +#ifdef _WIN32 + if (c0 == '/') c0 = '\\'; + if (c1 == '/') c1 = '\\'; +#endif + if (c0 != c1) return(0); + i++; j++; + } while (*j); + return(!*i); +} + +#if !defined(_WIN32) +char *Bstrlwr(char *s) +{ + char *t = s; + if (!s) return s; + while (*t) { *t = Btolower(*t); t++; } + return s; +} + +char *Bstrupr(char *s) +{ + char *t = s; + if (!s) return s; + while (*t) { *t = Btoupper(*t); t++; } + return s; +} +#endif + + +// +// getsysmemsize() -- gets the amount of system memory in the machine +// +unsigned int Bgetsysmemsize(void) +{ +#ifdef _WIN32 + MEMORYSTATUS memst; + GlobalMemoryStatus(&memst); + return (unsigned int)memst.dwTotalPhys; +#elif (defined(_SC_PAGE_SIZE) || defined(_SC_PAGESIZE)) && defined(_SC_PHYS_PAGES) + unsigned int siz = 0x7fffffff; + long scpagesiz, scphyspages; + +#ifdef _SC_PAGE_SIZE + scpagesiz = sysconf(_SC_PAGE_SIZE); +#else + scpagesiz = sysconf(_SC_PAGESIZE); +#endif + scphyspages = sysconf(_SC_PHYS_PAGES); + if (scpagesiz >= 0 && scphyspages >= 0) + siz = (unsigned int)min(longlong(0x7fffffff), (int64)scpagesiz * (int64)scphyspages); + + //initprintf("Bgetsysmemsize(): %d pages of %d bytes, %d bytes of system memory\n", + // scphyspages, scpagesiz, siz); + + return siz; +#else + return 0x7fffffff; +#endif +} + + + diff --git a/polymer/build/src/config.c b/polymer/build/src/config.c new file mode 100644 index 000000000..642f9707f --- /dev/null +++ b/polymer/build/src/config.c @@ -0,0 +1,307 @@ +// Evil and Nasty Configuration File Reader for KenBuild +// by Jonathon Fowler + +#include "compat.h" +#include "build.h" +#include "editor.h" +#include "osd.h" + +#ifdef RENDERTYPEWIN +#include "winlayer.h" +#endif +#include "baselayer.h" + +static long vesares[13][2] = {{320,200},{360,200},{320,240},{360,240},{320,400}, + {360,400},{640,350},{640,400},{640,480},{800,600}, + {1024,768},{1280,1024},{1600,1200}}; + +static int readconfig(BFILE *fp, const char *key, char *value, unsigned len) +{ + char buf[1000], *k, *v, *eq; + int x=0; + + if (len < 1) return 0; + + Brewind(fp); + + while (1) { + if (!Bfgets(buf, 1000, fp)) return 0; + + if (buf[0] == ';') continue; + + eq = Bstrchr(buf, '='); + if (!eq) continue; + + k = buf; + v = eq+1; + + while (*k == ' ' || *k == '\t') k++; + *(eq--) = 0; + while ((*eq == ' ' || *eq == '\t') && eq>=k) *(eq--) = 0; + + if (Bstrcasecmp(k, key)) continue; + + while (*v == ' ' || *k == '\t') v++; + eq = v + Bstrlen(v)-1; + + while ((*eq == ' ' || *eq == '\t' || *eq == '\r' || *eq == '\n') && eq>=v) *(eq--) = 0; + + value[--len] = 0; + do value[x] = v[x]; while (v[x++] != 0 && len-- > 0); + + return x-1; + } +} + +extern short brightness; +extern long fullscreen; +extern char option[8]; +extern char keys[NUMBUILDKEYS]; +extern double msens; + +/* + * SETUP.DAT + * 0 = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue) + * 1 = sound (0:none) + * 2 = music (0:none) + * 3 = input (0:keyboard 1:+mouse) + * 4 = multiplayer (0:single 1-4:com 5-11:ipx) + * 5&0xf0 = com speed + * 5&0x0f = com irq + * 6&0xf0 = chained y-res + * 6&0x0f = chained x-res or vesa mode + * 7&0xf0 = sound samplerate + * 7&0x01 = sound quality + * 7&0x02 = 8/16 bit + * 7&0x04 = mono/stereo + * + * bytes 8 to 26 are key settings: + * 0 = Forward (0xc8) + * 1 = Backward (0xd0) + * 2 = Turn left (0xcb) + * 3 = Turn right (0xcd) + * 4 = Run (0x2a) + * 5 = Strafe (0x9d) + * 6 = Fire (0x1d) + * 7 = Use (0x39) + * 8 = Stand high (0x1e) + * 9 = Stand low (0x2c) + * 10 = Look up (0xd1) + * 11 = Look down (0xc9) + * 12 = Strafe left (0x33) + * 13 = Strafe right (0x34) + * 14 = 2D/3D switch (0x9c) + * 15 = View cycle (0x1c) + * 16 = 2D Zoom in (0xd) + * 17 = 2D Zoom out (0xc) + * 18 = Chat (0xf) + */ + +int loadsetup(const char *fn) +{ + BFILE *fp; +#define VL 32 + char val[VL]; + int i; + + if ((fp = Bfopen(fn, "rt")) == NULL) return -1; + + if (readconfig(fp, "fullscreen", val, VL) > 0) { if (Batoi(val) != 0) fullscreen = 1; else fullscreen = 0; } + if (readconfig(fp, "resolution", val, VL) > 0) { + i = Batoi(val) & 0x0f; + if ((unsigned)i<13) { xdimgame = xdim2d = vesares[i][0]; ydimgame = ydim2d = vesares[i][1]; } + } + if (readconfig(fp, "2dresolution", val, VL) > 0) { + i = Batoi(val) & 0x0f; + if ((unsigned)i<13) { xdim2d = vesares[i][0]; ydim2d = vesares[i][1]; } + } + if (readconfig(fp, "xdim2d", val, VL) > 0) xdim2d = Batoi(val); + if (readconfig(fp, "ydim2d", val, VL) > 0) ydim2d = Batoi(val); + if (readconfig(fp, "xdim3d", val, VL) > 0) xdimgame = Batoi(val); + if (readconfig(fp, "ydim3d", val, VL) > 0) ydimgame = Batoi(val); + if (readconfig(fp, "samplerate", val, VL) > 0) option[7] = (Batoi(val) & 0x0f) << 4; + if (readconfig(fp, "music", val, VL) > 0) { if (Batoi(val) != 0) option[2] = 1; else option[2] = 0; } + if (readconfig(fp, "mouse", val, VL) > 0) { if (Batoi(val) != 0) option[3] = 1; else option[3] = 0; } + if (readconfig(fp, "bpp", val, VL) > 0) bppgame = Batoi(val); + if (readconfig(fp, "renderer", val, VL) > 0) { i = Batoi(val); setrendermode(i); } + if (readconfig(fp, "brightness", val, VL) > 0) brightness = min(max(Batoi(val),0),15); + +#ifdef RENDERTYPEWIN + if (readconfig(fp, "maxrefreshfreq", val, VL) > 0) maxrefreshfreq = Batoi(val); +#endif + glusetexcache = glusetexcachecompression = -1; + if (readconfig(fp, "glusetexcache", val, VL) > 0) { + if (Batoi(val) != 0) glusetexcache = 1; + else glusetexcache = 0; + } + if (readconfig(fp, "glusetexcachecompression", val, VL) > 0) { + if (Batoi(val) != 0) glusetexcachecompression = 1; + else glusetexcachecompression = 0; + } + if(glusetexcache == -1 && glusetexcachecompression == -1) + { + i=wm_ynbox("Texture caching", + "Would you like to enable the on-disk texture cache? " + "This feature may use up to 200 megabytes of disk " + "space if you have a great deal of high resolution " + "textures and skins, but textures will load exponentially " + "faster after the first time they are loaded."); + if (i) i = 'y'; + if(i == 'y' || i == 'Y' ) + glusetexcompr = glusetexcache = glusetexcachecompression = 1; + else glusetexcache = glusetexcachecompression = 0; + } + + option[0] = 1; // vesa all the way... + option[1] = 1; // sound all the way... + option[4] = 0; // no multiplayer + option[5] = 0; + + if (readconfig(fp, "keyforward", val, VL) > 0) keys[0] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keybackward", val, VL) > 0) keys[1] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyturnleft", val, VL) > 0) keys[2] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyturnright", val, VL) > 0) keys[3] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyrun", val, VL) > 0) keys[4] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystrafe", val, VL) > 0) keys[5] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyfire", val, VL) > 0) keys[6] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyuse", val, VL) > 0) keys[7] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystandhigh", val, VL) > 0) keys[8] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystandlow", val, VL) > 0) keys[9] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keylookup", val, VL) > 0) keys[10] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keylookdown", val, VL) > 0) keys[11] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystrafeleft", val, VL) > 0) keys[12] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystraferight", val, VL) > 0) keys[13] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dmode", val, VL) > 0) keys[14] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyviewcycle", val, VL) > 0) keys[15] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dzoomin", val, VL) > 0) keys[16] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dzoomout", val, VL) > 0) keys[17] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keychat", val, VL) > 0) keys[18] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyconsole", val, VL) > 0) { keys[19] = Bstrtol(val, NULL, 16); OSD_CaptureKey(keys[19]); } + + if (readconfig(fp, "mousesensitivity", val, VL) > 0) msens = Bstrtod(val, NULL); + + Bfclose(fp); + + return 0; +} + +int writesetup(const char *fn) +{ + BFILE *fp; + + fp = Bfopen(fn,"wt"); + if (!fp) return -1; + + Bfprintf(fp, + "; Video mode selection\n" + "; 0 - Windowed\n" + "; 1 - Fullscreen\n" + "fullscreen = %ld\n" + "\n" + "; Video resolution\n" + "xdim2d = %ld\n" + "ydim2d = %ld\n" + "xdim3d = %ld\n" + "ydim3d = %ld\n" + "\n" + "; 3D-mode colour depth\n" + "bpp = %ld\n" + "\n" + "; OpenGL mode options\n" + "glusetexcache = %ld\n" + "glusetexcachecompression = %ld\n" + "\n" +#ifdef RENDERTYPEWIN + "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n" + "maxrefreshfreq = %d\n" + "\n" +#endif + "; 3D mode brightness setting\n" + "; 0 - lowest\n" + "; 15 - highest\n" + "brightness = %d\n" + "\n" + "; Sound sample frequency\n" + "; 0 - 6 KHz\n" + "; 1 - 8 KHz\n" + "; 2 - 11.025 KHz\n" + "; 3 - 16 KHz\n" + "; 4 - 22.05 KHz\n" + "; 5 - 32 KHz\n" + "; 6 - 44.1 KHz\n" + "samplerate = %d\n" + "\n" + "; Music playback\n" + "; 0 - Off\n" + "; 1 - On\n" + "music = %d\n" + "\n" + "; Enable mouse\n" + "; 0 - No\n" + "; 1 - Yes\n" + "mouse = %d\n" + "\n" + "; Mouse sensitivity\n" + "mousesensitivity = %g\n" + "\n" + "; Key Settings\n" + "; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n" + "; +---------------------------------------------------------------------------------------------+\n" + "; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 |\n" + "; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL |\n" + "; | |\n" + "; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A |\n" + "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- |\n" + "; | |\n" + "; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E |\n" + "; |TAB Q W E R T Y U I O P [ ] \\ DEL END PGDN KP7 KP8 KP9 KP+ |\n" + "; | |\n" + "; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D |\n" + "; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C |\n" + "; | KPENTER|\n" + "; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 |\n" + "; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 |\n" + "; | |\n" + "; | 1D 38 39 B8 9D CB D0 CD 52 53 |\n" + "; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. |\n" + "; +---------------------------------------------------------------------------------------------+\n" + "\n" + "keyforward = %X\n" + "keybackward = %X\n" + "keyturnleft = %X\n" + "keyturnright = %X\n" + "keyrun = %X\n" + "keystrafe = %X\n" + "keyfire = %X\n" + "keyuse = %X\n" + "keystandhigh = %X\n" + "keystandlow = %X\n" + "keylookup = %X\n" + "keylookdown = %X\n" + "keystrafeleft = %X\n" + "keystraferight = %X\n" + "key2dmode = %X\n" + "keyviewcycle = %X\n" + "key2dzoomin = %X\n" + "key2dzoomout = %X\n" + "keychat = %X\n" + "keyconsole = %X\n" + "\n", + + fullscreen, xdim2d, ydim2d, xdimgame, ydimgame, bppgame, + glusetexcache, glusetexcachecompression, +#ifdef RENDERTYPEWIN + maxrefreshfreq, +#endif + brightness, option[7]>>4, option[2], + option[3], msens, + keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], + keys[6], keys[7], keys[8], keys[9], keys[10], keys[11], + keys[12], keys[13], keys[14], keys[15], keys[16], keys[17], + keys[18], keys[19] + ); + + Bfclose(fp); + + return 0; +} diff --git a/polymer/build/src/crc32.c b/polymer/build/src/crc32.c new file mode 100644 index 000000000..5966dcfd3 --- /dev/null +++ b/polymer/build/src/crc32.c @@ -0,0 +1,104 @@ +#include "crc32.h" + +/* +// this table of numbers is borrowed from the InfoZip source. +static unsigned long crc32table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +*/ + +static unsigned long crc32table[256]; + +void initcrc32table(void) +{ + unsigned long i,j,k; + + // algorithm and polynomial same as that used by infozip's zip + for (i=0; i<256; i++) { + j = i; + for (k=8; k; k--) + j = (j&1) ? (0xedb88320L ^ (j>>1)) : (j>>1); + crc32table[i] = j; + } +} + + +unsigned long crc32once(unsigned char *blk, unsigned long len) +{ + unsigned long crc; + + crc32init(&crc); + crc32block(&crc, blk, len); + return crc32finish(&crc); +} + +void crc32init(unsigned long *crcvar) +{ + if (!crcvar) return; + *crcvar = 0xffffffffl; +} + +void crc32block(unsigned long *crcvar, unsigned char *blk, unsigned long len) +{ + unsigned long crc = *crcvar; + while (len--) crc = crc32table[(crc ^ *(blk++)) & 0xffl] ^ (crc >> 8); + *crcvar = crc; +} + +unsigned long crc32finish(unsigned long *crcvar) +{ + *crcvar = *crcvar ^ 0xffffffffl; + return *crcvar; +} + diff --git a/polymer/build/src/defs.c b/polymer/build/src/defs.c new file mode 100644 index 000000000..171bc546f --- /dev/null +++ b/polymer/build/src/defs.c @@ -0,0 +1,1072 @@ +/* + * Definitions file parser for Build + * by Jonathon Fowler (jonof@edgenetwork.org) + * Remixed substantially by Ken Silverman + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "build.h" +#include "compat.h" +#include "baselayer.h" +#include "scriptfile.h" +#include "cache1d.h" + +enum { + T_EOF = -2, + T_ERROR = -1, + T_INCLUDE = 0, + T_DEFINE, + T_DEFINETEXTURE, + T_DEFINESKYBOX, + T_DEFINETINT, + T_DEFINEMODEL, + T_DEFINEMODELFRAME, + T_DEFINEMODELANIM, + T_DEFINEMODELSKIN, + T_SELECTMODELSKIN, + T_DEFINEVOXEL, + T_DEFINEVOXELTILES, + T_MODEL, + T_FILE, + T_SCALE, + T_SHADE, + T_FRAME, + T_ANIM, + T_SKIN, + T_SURF, + T_TILE, + T_TILE0, + T_TILE1, + T_FRAME0, + T_FRAME1, + T_FPS, + T_FLAGS, + T_PAL, + T_HUD, + T_XADD, + T_YADD, + T_ZADD, + T_ANGADD, + T_FLIPPED, + T_HIDE, + T_NOBOB, + T_NODEPTH, + T_VOXEL, + T_SKYBOX, + T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM, + T_TINT,T_RED,T_GREEN,T_BLUE, + T_TEXTURE,T_ALPHACUT,T_NOCOMPRESS, + T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE, + T_ALPHAHACK,T_ALPHAHACKRANGE, + T_SPRITECOL,T_2DCOL, + T_FOGPAL, + T_LOADGRP, +}; + +typedef struct { char *text; int tokenid; } tokenlist; +static tokenlist basetokens[] = +{ + { "include", T_INCLUDE }, + { "#include", T_INCLUDE }, + { "define", T_DEFINE }, + { "#define", T_DEFINE }, + + // deprecated style + { "definetexture", T_DEFINETEXTURE }, + { "defineskybox", T_DEFINESKYBOX }, + { "definetint", T_DEFINETINT }, + { "definemodel", T_DEFINEMODEL }, + { "definemodelframe",T_DEFINEMODELFRAME }, + { "definemodelanim", T_DEFINEMODELANIM }, + { "definemodelskin", T_DEFINEMODELSKIN }, + { "selectmodelskin", T_SELECTMODELSKIN }, + { "definevoxel", T_DEFINEVOXEL }, + { "definevoxeltiles",T_DEFINEVOXELTILES }, + + // new style + + { "model", T_MODEL }, + { "voxel", T_VOXEL }, + { "skybox", T_SKYBOX }, + { "tint", T_TINT }, + { "texture", T_TEXTURE }, + { "tile", T_TEXTURE }, + + // other stuff + { "undefmodel", T_UNDEFMODEL }, + { "undefmodelrange", T_UNDEFMODELRANGE }, + { "undefmodelof", T_UNDEFMODELOF }, + { "undeftexture", T_UNDEFTEXTURE }, + { "undeftexturerange", T_UNDEFTEXTURERANGE }, + { "alphahack", T_ALPHAHACK }, + { "alphahackrange", T_ALPHAHACKRANGE }, + { "spritecol", T_SPRITECOL }, + { "2dcol", T_2DCOL }, + { "fogpal", T_FOGPAL }, + { "loadgrp", T_LOADGRP }, +}; + +static tokenlist modeltokens[] = { + { "scale", T_SCALE }, + { "shade", T_SHADE }, + { "zadd", T_ZADD }, + { "frame", T_FRAME }, + { "anim", T_ANIM }, + { "skin", T_SKIN }, + { "hud", T_HUD }, +}; + +static tokenlist modelframetokens[] = { + { "frame", T_FRAME }, + { "name", T_FRAME }, + { "tile", T_TILE }, + { "tile0", T_TILE0 }, + { "tile1", T_TILE1 }, +}; + +static tokenlist modelanimtokens[] = { + { "frame0", T_FRAME0 }, + { "frame1", T_FRAME1 }, + { "fps", T_FPS }, + { "flags", T_FLAGS }, +}; + +static tokenlist modelskintokens[] = { + { "pal", T_PAL }, + { "file", T_FILE }, + { "surf", T_SURF }, + { "surface",T_SURF }, +}; + +static tokenlist modelhudtokens[] = { + { "tile", T_TILE }, + { "tile0", T_TILE0 }, + { "tile1", T_TILE1 }, + { "xadd", T_XADD }, + { "yadd", T_YADD }, + { "zadd", T_ZADD }, + { "angadd", T_ANGADD }, + { "hide", T_HIDE }, + { "nobob", T_NOBOB }, + { "flipped",T_FLIPPED}, + { "nodepth",T_NODEPTH}, +}; + +static tokenlist voxeltokens[] = { + { "tile", T_TILE }, + { "tile0", T_TILE0 }, + { "tile1", T_TILE1 }, + { "scale", T_SCALE }, +}; + +static tokenlist skyboxtokens[] = { + { "tile" ,T_TILE }, + { "pal" ,T_PAL }, + { "ft" ,T_FRONT },{ "front" ,T_FRONT },{ "forward",T_FRONT }, + { "rt" ,T_RIGHT },{ "right" ,T_RIGHT }, + { "bk" ,T_BACK },{ "back" ,T_BACK }, + { "lf" ,T_LEFT },{ "left" ,T_LEFT },{ "lt" ,T_LEFT }, + { "up" ,T_TOP },{ "top" ,T_TOP },{ "ceiling",T_TOP },{ "ceil" ,T_TOP }, + { "dn" ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor" ,T_BOTTOM },{ "down" ,T_BOTTOM } +}; + +static tokenlist tinttokens[] = { + { "pal", T_PAL }, + { "red", T_RED },{ "r", T_RED }, + { "green", T_GREEN },{ "g", T_GREEN }, + { "blue", T_BLUE },{ "b", T_BLUE }, + { "flags", T_FLAGS } +}; + +static tokenlist texturetokens[] = { + { "pal", T_PAL }, +}; +static tokenlist texturetokens_pal[] = { + { "file", T_FILE },{ "name", T_FILE }, + { "alphacut", T_ALPHACUT }, + { "nocompress",T_NOCOMPRESS }, +}; + +static int getatoken(scriptfile *sf, tokenlist *tl, int ntokens) +{ + char *tok; + int i; + + if (!sf) return T_ERROR; + tok = scriptfile_gettoken(sf); + if (!tok) return T_EOF; + + for(i=0;iltextptr; + switch (tokn) { + case T_ERROR: + initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr)); + break; + case T_EOF: + return(0); + case T_INCLUDE: + { + char *fn; + if (!scriptfile_getstring(script,&fn)) { + scriptfile *included; + + included = scriptfile_fromfile(fn); + if (!included) { + initprintf("Warning: Failed including %s on line %s:%d\n", + fn, script->filename,scriptfile_getlinum(script,cmdtokptr)); + } else { + defsparser(included); + scriptfile_close(included); + } + } + break; + } + case T_DEFINE: + { + char *name; + int number; + + if (scriptfile_getstring(script,&name)) break; + if (scriptfile_getsymbol(script,&number)) break; + + if (scriptfile_addsymbolvalue(name,number) < 0) + initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n", + name,number,script->filename,scriptfile_getlinum(script,cmdtokptr)); + break; + } + + // OLD (DEPRECATED) DEFINITION SYNTAX + case T_DEFINETEXTURE: + { + int tile,pal,fnoo; + char *fn; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getnumber(script,&fnoo)) break; //x-center + if (scriptfile_getnumber(script,&fnoo)) break; //y-center + if (scriptfile_getnumber(script,&fnoo)) break; //x-size + if (scriptfile_getnumber(script,&fnoo)) break; //y-size + if (scriptfile_getstring(script,&fn)) break; + hicsetsubsttex(tile,pal,fn,-1.0,0); + } + break; + case T_DEFINESKYBOX: + { + int tile,pal,i; + char *fn[6]; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getsymbol(script,&i)) break; //future expansion + for (i=0;i<6;i++) if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces + if (i < 6) break; + hicsetskybox(tile,pal,fn); + } + break; + case T_DEFINETINT: + { + int pal, r,g,b,f; + + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&b)) break; + if (scriptfile_getnumber(script,&f)) break; //effects + hicsetpalettetint(pal,r,g,b,f); + } + break; + case T_ALPHAHACK: + { + int tile; + double alpha; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getdouble(script,&alpha)) break; + if ((unsigned long)tile < MAXTILES) alphahackarray[tile] = alpha; + } + break; + case T_ALPHAHACKRANGE: + { + int tilenume1,tilenume2,i; + double alpha; + + if (scriptfile_getsymbol(script,&tilenume1)) break; + if (scriptfile_getsymbol(script,&tilenume2)) break; + if (scriptfile_getdouble(script,&alpha)) break; + if (tilenume2 < tilenume1) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + i = tilenume2; + tilenume2 = tilenume1; + tilenume1 = i; + } + if ((tilenume1 >= 0 && tilenume1 < MAXTILES) && (tilenume2 >= 0 && tilenume2 < MAXTILES)) + { + for (i=tilenume1;i<=tilenume2;i++) + { + if ((unsigned long)i < MAXTILES) + alphahackarray[i] = alpha; + } + } + } + break; + case T_SPRITECOL: + { + int tile,col,type; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getnumber(script,&col)) break; + if (scriptfile_getnumber(script,&type)) break; + if ((unsigned long)tile < MAXTILES) spritecol2d[tile][type] = col; + } + break; + case T_2DCOL: + { + int col,b,g,r; + + if (scriptfile_getnumber(script,&col)) break; + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&b)) break; + + if (col < 256) { + vgapal16[col*4+0] = b; // blue + vgapal16[col*4+1] = g; // green + vgapal16[col*4+2] = r; // red + } + } + break; + case T_FOGPAL: + { + int p,r,g,b,j; + char tempbuf[256]; + + if (scriptfile_getnumber(script,&p)) break; + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&b)) break; + + for (j = 0; j < 256; j++) + tempbuf[j] = j; + makepalookup(p, tempbuf, r, g, b, 1); + } + break; + case T_LOADGRP: + { + char *fn; + if (!scriptfile_getstring(script,&fn)) + { + int j = initgroupfile(fn); + + if( j == -1 ) + initprintf("Could not find GRP file %s.\n",fn); + else + initprintf("Using GRP file %s.\n",fn); + } + break; + } + case T_DEFINEMODEL: + { + char *modelfn; + double scale; + int shadeoffs; + + if (scriptfile_getstring(script,&modelfn)) break; + if (scriptfile_getdouble(script,&scale)) break; + if (scriptfile_getnumber(script,&shadeoffs)) break; + +#if defined(POLYMOST) && defined(USE_OPENGL) + lastmodelid = md_loadmodel(modelfn); + if (lastmodelid < 0) { + initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); + break; + } + md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0); +#endif + modelskin = lastmodelskin = 0; + seenframe = 0; + } + break; + case T_DEFINEMODELFRAME: + { + char *framename, happy=1; + int ftilenume, ltilenume, tilex; + + if (scriptfile_getstring(script,&framename)) break; + if (scriptfile_getnumber(script,&ftilenume)) break; //first tile number + if (scriptfile_getnumber(script,<ilenume)) break; //last tile number (inclusive) + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + happy = 0; + break; + } + } +#endif + seenframe = 1; + } + break; + case T_DEFINEMODELANIM: + { + char *startframe, *endframe; + int flags; + double dfps; + + if (scriptfile_getstring(script,&startframe)) break; + if (scriptfile_getstring(script,&endframe)) break; + if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate + if (scriptfile_getnumber(script,&flags)) break; + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring animation definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid starting frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -3: initprintf("Invalid ending frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } +#endif + } + break; + case T_DEFINEMODELSKIN: + { + int palnum, palnumer; + char *skinfn; + + if (scriptfile_getsymbol(script,&palnum)) break; + if (scriptfile_getstring(script,&skinfn)) break; //skin filename + + // if we see a sequence of definemodelskin, then a sequence of definemodelframe, + // and then a definemodelskin, we need to increment the skin counter. + // + // definemodel "mymodel.md2" 1 1 + // definemodelskin 0 "normal.png" // skin 0 + // definemodelskin 21 "normal21.png" + // definemodelframe "foo" 1000 1002 // these use skin 0 + // definemodelskin 0 "wounded.png" // skin 1 + // definemodelskin 21 "wounded21.png" + // definemodelframe "foo2" 1003 1004 // these use skin 1 + // selectmodelskin 0 // resets to skin 0 + // definemodelframe "foo3" 1005 1006 // these use skin 0 + if (seenframe) { modelskin = ++lastmodelskin; } + seenframe = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid skin filename on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -3: initprintf("Invalid palette number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } +#endif + } + break; + case T_SELECTMODELSKIN: + { + if (scriptfile_getsymbol(script,&modelskin)) break; + } + break; + case T_DEFINEVOXEL: + { + char *fn; + + if (scriptfile_getstring(script,&fn)) break; //voxel filename + + if (nextvoxid == MAXVOXELS) { + initprintf("Maximum number of voxels already defined.\n"); + break; + } + +#ifdef SUPERBUILD + if (qloadkvx(nextvoxid, fn)) { + initprintf("Failure loading voxel file \"%s\"\n",fn); + break; + } + + lastvoxid = nextvoxid++; +#endif + } + break; + case T_DEFINEVOXELTILES: + { + int ftilenume, ltilenume, tilex; + + if (scriptfile_getnumber(script,&ftilenume)) break; //1st tile # + if (scriptfile_getnumber(script,<ilenume)) break; //last tile # + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + if (ltilenume < 0 || ftilenume >= MAXTILES) { + initprintf("Invalid tile range on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + + if (lastvoxid < 0) { + initprintf("Warning: Ignoring voxel tiles definition.\n"); + break; + } +#ifdef SUPERBUILD + for (tilex = ftilenume; tilex <= ltilenume; tilex++) { + tiletovox[tilex] = lastvoxid; + } +#endif + } + break; + + // NEW (ENCOURAGED) DEFINITION SYNTAX + case T_MODEL: + { + char *modelend, *modelfn; + double scale=1.0, mzadd=0.0; + int shadeoffs=0; + + modelskin = lastmodelskin = 0; + seenframe = 0; + + if (scriptfile_getstring(script,&modelfn)) break; + +#if defined(POLYMOST) && defined(USE_OPENGL) + lastmodelid = md_loadmodel(modelfn); + if (lastmodelid < 0) { + initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); + break; + } +#endif + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,modeltokens,sizeof(modeltokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break; + case T_SCALE: scriptfile_getdouble(script,&scale); break; + case T_SHADE: scriptfile_getnumber(script,&shadeoffs); break; + case T_ZADD: scriptfile_getdouble(script,&mzadd); break; + case T_FRAME: + { + char *frametokptr = script->ltextptr; + char *frameend, *framename = 0, happy=1; + int ftilenume = -1, ltilenume = -1, tilex = 0; + + if (scriptfile_getbraces(script,&frameend)) break; + while (script->textptr < frameend) { + switch(getatoken(script,modelframetokens,sizeof(modelframetokens)/sizeof(tokenlist))) { + case T_FRAME: scriptfile_getstring(script,&framename); break; + case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; + case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number + case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) + } + } + + if (ftilenume < 0) initprintf("Error: missing 'first tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; + if (ltilenume < 0) initprintf("Error: missing 'last tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; + if (!happy) break; + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,frametokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,frametokptr)); + happy = 0; + break; + } + } +#endif + seenframe = 1; + } + break; + case T_ANIM: + { + char *animtokptr = script->ltextptr; + char *animend, *startframe = 0, *endframe = 0, happy=1; + int flags = 0; + double dfps = 1.0; + + if (scriptfile_getbraces(script,&animend)) break; + while (script->textptr < animend) { + switch(getatoken(script,modelanimtokens,sizeof(modelanimtokens)/sizeof(tokenlist))) { + case T_FRAME0: scriptfile_getstring(script,&startframe); break; + case T_FRAME1: scriptfile_getstring(script,&endframe); break; + case T_FPS: scriptfile_getdouble(script,&dfps); break; //animation frame rate + case T_FLAGS: scriptfile_getsymbol(script,&flags); break; + } + } + + if (!startframe) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; + if (!endframe) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; + if (!happy) break; + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring animation definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid starting frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + case -3: initprintf("Invalid ending frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + } +#endif + } break; + case T_SKIN: + { + char *skintokptr = script->ltextptr; + char *skinend, *skinfn = 0; + int palnum = 0, surfnum = 0; + + if (scriptfile_getbraces(script,&skinend)) break; + while (script->textptr < skinend) { + switch(getatoken(script,modelskintokens,sizeof(modelskintokens)/sizeof(tokenlist))) { + case T_PAL: scriptfile_getsymbol(script,&palnum); break; + case T_FILE: scriptfile_getstring(script,&skinfn); break; //skin filename + case T_SURF: scriptfile_getnumber(script,&surfnum); break; + } + } + + if (!skinfn) { + initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr)); + break; + } + + if (seenframe) { modelskin = ++lastmodelskin; } + seenframe = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid skin filename on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + case -3: initprintf("Invalid palette number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + } +#endif + } break; + case T_HUD: + { + char *hudtokptr = script->ltextptr; + char happy=1, *frameend; + int ftilenume = -1, ltilenume = -1, tilex = 0, flags = 0; + double xadd = 0.0, yadd = 0.0, zadd = 0.0, angadd = 0.0; + + if (scriptfile_getbraces(script,&frameend)) break; + while (script->textptr < frameend) { + switch(getatoken(script,modelhudtokens,sizeof(modelhudtokens)/sizeof(tokenlist))) { + case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; + case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number + case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) + case T_XADD: scriptfile_getdouble(script,&xadd); break; + case T_YADD: scriptfile_getdouble(script,&yadd); break; + case T_ZADD: scriptfile_getdouble(script,&zadd); break; + case T_ANGADD:scriptfile_getdouble(script,&angadd); break; + case T_HIDE: flags |= 1; break; + case T_NOBOB: flags |= 2; break; + case T_FLIPPED: flags |= 4; break; + case T_NODEPTH: flags |= 8; break; + } + } + + if (ftilenume < 0) initprintf("Error: missing 'first tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; + if (ltilenume < 0) initprintf("Error: missing 'last tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; + if (!happy) break; + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_definehud(lastmodelid, tilex, xadd, yadd, zadd, angadd, flags)) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,hudtokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,hudtokptr)); + happy = 0; + break; + } + } +#endif + } break; + } + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd); +#endif + + modelskin = lastmodelskin = 0; + seenframe = 0; + + } + break; + case T_VOXEL: + { + char *voxeltokptr = script->ltextptr; + char *fn, *modelend; + int tile0 = MAXTILES, tile1 = -1, tilex = -1; + + if (scriptfile_getstring(script,&fn)) break; //voxel filename + if (nextvoxid == MAXVOXELS) { initprintf("Maximum number of voxels already defined.\n"); break; } +#ifdef SUPERBUILD + if (qloadkvx(nextvoxid, fn)) { initprintf("Failure loading voxel file \"%s\"\n",fn); break; } + lastvoxid = nextvoxid++; +#endif + + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,voxeltokens,sizeof(voxeltokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break; + case T_TILE: + scriptfile_getsymbol(script,&tilex); +#ifdef SUPERBUILD + if ((unsigned long)tilex < MAXTILES) tiletovox[tilex] = lastvoxid; + else initprintf("Invalid tile number on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); +#endif + break; + case T_TILE0: + scriptfile_getsymbol(script,&tile0); break; //1st tile # + case T_TILE1: + scriptfile_getsymbol(script,&tile1); + if (tile0 > tile1) + { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,voxeltokptr)); + tilex = tile0; tile0 = tile1; tile1 = tilex; + } + if ((tile1 < 0) || (tile0 >= MAXTILES)) + { initprintf("Invalid tile range on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); break; } +#ifdef SUPERBUILD + for(tilex=tile0;tilex<=tile1;tilex++) tiletovox[tilex] = lastvoxid; +#endif + break; //last tile number (inclusive) + case T_SCALE: { + double scale=1.0; + scriptfile_getdouble(script,&scale); +#ifdef SUPERBUILD + voxscale[lastvoxid] = 65536*scale; +#endif + break; + } + } + } + lastvoxid = -1; + } + break; + case T_SKYBOX: + { + char *skyboxtokptr = script->ltextptr; + char *fn[6] = {0,0,0,0,0,0}, *modelend, happy=1; + int i, tile = -1, pal = 0; + + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,skyboxtokens,sizeof(skyboxtokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break; + case T_TILE: scriptfile_getsymbol(script,&tile ); break; + case T_PAL: scriptfile_getsymbol(script,&pal ); break; + case T_FRONT: scriptfile_getstring(script,&fn[0]); break; + case T_RIGHT: scriptfile_getstring(script,&fn[1]); break; + case T_BACK: scriptfile_getstring(script,&fn[2]); break; + case T_LEFT: scriptfile_getstring(script,&fn[3]); break; + case T_TOP: scriptfile_getstring(script,&fn[4]); break; + case T_BOTTOM:scriptfile_getstring(script,&fn[5]); break; + } + } + + if (tile < 0) initprintf("Error: missing 'tile number' for skybox definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy=0; + for (i=0;i<6;i++) { + if (!fn[i]) initprintf("Error: missing '%s filename' for skybox definition near line %s:%d\n", skyfaces[i], script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy = 0; + } + + if (!happy) break; + + hicsetskybox(tile,pal,fn); + } + break; + case T_TINT: + { + char *tinttokptr = script->ltextptr; + int red=255, green=255, blue=255, pal=-1, flags=0; + char *tintend; + + if (scriptfile_getbraces(script,&tintend)) break; + while (script->textptr < tintend) { + switch (getatoken(script,tinttokens,sizeof(tinttokens)/sizeof(tokenlist))) { + case T_PAL: scriptfile_getsymbol(script,&pal); break; + case T_RED: scriptfile_getnumber(script,&red); red = min(255,max(0,red)); break; + case T_GREEN: scriptfile_getnumber(script,&green); green = min(255,max(0,green)); break; + case T_BLUE: scriptfile_getnumber(script,&blue); blue = min(255,max(0,blue)); break; + case T_FLAGS: scriptfile_getsymbol(script,&flags); break; + } + } + + if (pal < 0) { + initprintf("Error: missing 'palette number' for tint definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,tinttokptr)); + break; + } + + hicsetpalettetint(pal,red,green,blue,flags); + } + break; + case T_TEXTURE: + { + char *texturetokptr = script->ltextptr, *textureend; + int tile=-1; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getbraces(script,&textureend)) break; + while (script->textptr < textureend) { + switch (getatoken(script,texturetokens,sizeof(texturetokens)/sizeof(tokenlist))) { + case T_PAL: { + char *paltokptr = script->ltextptr, *palend; + int pal=-1; + char *fn = NULL; + double alphacut = -1.0; + char flags = 0; + + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getbraces(script,&palend)) break; + while (script->textptr < palend) { + switch (getatoken(script,texturetokens_pal,sizeof(texturetokens_pal)/sizeof(tokenlist))) { + case T_FILE: scriptfile_getstring(script,&fn); break; + case T_ALPHACUT: scriptfile_getdouble(script,&alphacut); break; + case T_NOCOMPRESS: flags |= 1; break; + default: break; + } + } + + if ((unsigned)tile > (unsigned)MAXTILES) break; // message is printed later + if ((unsigned)pal > (unsigned)MAXPALOOKUPS) { + initprintf("Error: missing or invalid 'palette number' for texture definition near " + "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr)); + break; + } + if (!fn) { + initprintf("Error: missing 'file name' for texture definition near line %s:%d\n", + script->filename, scriptfile_getlinum(script,paltokptr)); + break; + } + hicsetsubsttex(tile,pal,fn,alphacut,flags); + } break; + default: break; + } + } + + if ((unsigned)tile >= (unsigned)MAXTILES) { + initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n", + script->filename, scriptfile_getlinum(script,texturetokptr)); + break; + } + } + break; + + case T_UNDEFMODEL: + case T_UNDEFMODELRANGE: + { + int r0,r1; + + if (scriptfile_getsymbol(script,&r0)) break; + if (tokn == T_UNDEFMODELRANGE) { + if (scriptfile_getsymbol(script,&r1)) break; + if (r1 < r0) { + int t = r1; + r1 = r0; + r0 = t; + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + } + if (r0 < 0 || r1 >= MAXTILES) { + initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } else { + r1 = r0; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (; r0 <= r1; r0++) md_undefinetile(r0); +#endif + } + break; + + case T_UNDEFMODELOF: + { + int mid,r0; + + if (scriptfile_getsymbol(script,&r0)) break; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + mid = md_tilehasmodel(r0); + if (mid < 0) break; + + md_undefinemodel(mid); +#endif + } + break; + + case T_UNDEFTEXTURE: + case T_UNDEFTEXTURERANGE: + { + int r0,r1,i; + + if (scriptfile_getsymbol(script,&r0)) break; + if (tokn == T_UNDEFTEXTURERANGE) { + if (scriptfile_getsymbol(script,&r1)) break; + if (r1 < r0) { + int t = r1; + r1 = r0; + r0 = t; + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + } + if (r0 < 0 || r1 >= MAXTILES) { + initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } else { + r1 = r0; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } + + for (; r0 <= r1; r0++) + for (i=MAXPALOOKUPS-1; i>=0; i--) + hicclearsubst(r0,i); + } + break; + + default: + initprintf("Unknown token.\n"); break; + } + } + return 0; +} + + +int loaddefinitionsfile(char *fn) +{ + scriptfile *script; + + script = scriptfile_fromfile(fn); + if (!script) return -1; + + defsparser(script); + + scriptfile_close(script); + scriptfile_clearsymbols(); + + return 0; +} + +// vim:ts=4: diff --git a/polymer/build/src/engine.c b/polymer/build/src/engine.c new file mode 100644 index 000000000..539b9832a --- /dev/null +++ b/polymer/build/src/engine.c @@ -0,0 +1,11240 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + + +//#define POLYMOST +//#define SUPERBUILD +#define ENGINE + +#include "compat.h" +#include "build.h" +#include "pragmas.h" +#include "cache1d.h" +#include "a.h" +#include "osd.h" +#include "crc32.h" + +#include "baselayer.h" + +#ifdef POLYMOST +# ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# endif +# ifdef USE_OPENGL +# include "glbuild.h" +# endif +#endif + +#include + +#define MAXCLIPNUM 1024 +#define MAXPERMS 512 +#define MAXTILEFILES 256 +#define MAXYSAVES ((MAXXDIM*MAXSPRITES)>>7) +#define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM! +#define MAXWALLSB 2048 +#define MAXCLIPDIST 1024 + + +void *kmalloc(bsize_t size) { return(Bmalloc(size)); } +#define kkmalloc kmalloc + +void kfree(void *buffer) { Bfree(buffer); } +#define kkfree kfree + +#ifdef SUPERBUILD +void loadvoxel(long voxindex) { voxindex=0; } +long tiletovox[MAXTILES]; +long usevoxels = 1; +#define kloadvoxel loadvoxel + +long novoxmips = 0; +long editorgridextent = 131072; + + //These variables need to be copied into BUILD +#define MAXXSIZ 256 +#define MAXYSIZ 256 +#define MAXZSIZ 255 +#define MAXVOXMIPS 5 +long voxoff[MAXVOXELS][MAXVOXMIPS]; char voxlock[MAXVOXELS][MAXVOXMIPS]; +long voxscale[MAXVOXELS]; + +static long ggxinc[MAXXSIZ+1], ggyinc[MAXXSIZ+1]; +static long lowrecip[1024], nytooclose, nytoofar; +static unsigned long distrecip[65536]; +#endif + +static long *lookups = NULL; +static char lookupsalloctype = 255; +long dommxoverlay = 1, beforedrawrooms = 1; + +static long oxdimen = -1, oviewingrange = -1, oxyaspect = -1; + +long curbrightness = 0, gammabrightness = 0; + + //Textured Map variables +static char globalpolytype; +static short *dotp1[MAXYDIM], *dotp2[MAXYDIM]; + +static unsigned char tempbuf[MAXWALLS]; + +long ebpbak, espbak; +long slopalookup[16384]; // was 2048 +#if defined(USE_OPENGL) +static palette_t palookupfog[MAXPALOOKUPS]; +#endif + +static char permanentlock = 255; +long artversion, mapversion=7L; // JBF 20040211: default mapversion to 7 +void *pic = NULL; +char picsiz[MAXTILES], tilefilenum[MAXTILES]; +long lastageclock; +long tilefileoffs[MAXTILES]; + +long artsize = 0, cachesize = 0; + +static short radarang[1280], radarang2[MAXXDIM]; +static unsigned short sqrtable[4096], shlookup[4096+256]; +char pow2char[8] = {1,2,4,8,16,32,64,128}; +long pow2long[32] = +{ + 1L,2L,4L,8L, + 16L,32L,64L,128L, + 256L,512L,1024L,2048L, + 4096L,8192L,16384L,32768L, + 65536L,131072L,262144L,524288L, + 1048576L,2097152L,4194304L,8388608L, + 16777216L,33554432L,67108864L,134217728L, + 268435456L,536870912L,1073741824L,2147483647L +}; +long reciptable[2048], fpuasm; + +char britable[16][256]; // JBF 20040207: full 8bit precision +//char textfont[1024], smalltextfont[1024]; +#include "textfont.c" +#include "smalltextfont.c" + +static char kensmessage[128]; +char *engineerrstr = "No error"; + + +#if defined(NOASM) + +static inline unsigned long nsqrtasm(unsigned long a) +{ // JBF 20030901: This was a damn lot simpler to reverse engineer than + // msqrtasm was. Really, it was just like simplifying an algebra equation. + unsigned short c; + + if (a & 0xff000000) { // test eax, 0xff000000 / jnz short over24 + c = shlookup[(a >> 24) + 4096]; // mov ebx, eax + // over24: shr ebx, 24 + // mov cx, word ptr shlookup[ebx*2+8192] + } else { + c = shlookup[a >> 12]; // mov ebx, eax + // shr ebx, 12 + // mov cx, word ptr shlookup[ebx*2] + // jmp short under24 + } + a >>= c&0xff; // under24: shr eax, cl + a = (a&0xffff0000)|(sqrtable[a]); // mov ax, word ptr sqrtable[eax*2] + a >>= ((c&0xff00) >> 8); // mov cl, ch + // shr eax, cl + return a; +} + +static inline long msqrtasm(unsigned long c) +{ + unsigned long a,b; + + a = 0x40000000l; // mov eax, 0x40000000 + b = 0x20000000l; // mov ebx, 0x20000000 + do { // begit: + if (c >= a) { // cmp ecx, eax / jl skip + c -= a; // sub ecx, eax + a += b*4; // lea eax, [eax+ebx*4] + } // skip: + a -= b; // sub eax, ebx + a >>= 1; // shr eax, 1 + b >>= 2; // shr ebx, 2 + } while (b); // jnz begit + if (c >= a) // cmp ecx, eax + a++; // sbb eax, -1 + a >>= 1; // shr eax, 1 + return a; +} + +static inline void setgotpic(long tilenume) +{ + if (walock[tilenume] < 200) walock[tilenume] = 199; + gotpic[tilenume>>3] |= pow2char[tilenume&7]; +} + +static inline long krecipasm(long i) +{ // Ken did this + float f = (float)i; i = *(long *)&f; + return((reciptable[(i>>12)&2047]>>(((i-0x3f800000)>>23)&31))^(i>>31)); +} + + +static inline long getclipmask(long a, long b, long c, long d) +{ // Ken did this + d = ((a<0)*8) + ((b<0)*4) + ((c<0)*2) + (d<0); + return(((d<<4)^0xf0)|d); +} + +inline long getkensmessagecrc(long b) +{ + return 0x56c764d4l; + b=b; +} + +#elif defined(__WATCOMC__) + +// +// Watcom Inline Assembly Routines +// + +#pragma aux nsqrtasm =\ + "test eax, 0xff000000",\ + "mov ebx, eax",\ + "jnz short over24",\ + "shr ebx, 12",\ + "mov cx, word ptr shlookup[ebx*2]",\ + "jmp short under24",\ + "over24: shr ebx, 24",\ + "mov cx, word ptr shlookup[ebx*2+8192]",\ + "under24: shr eax, cl",\ + "mov cl, ch",\ + "mov ax, word ptr sqrtable[eax*2]",\ + "shr eax, cl",\ + parm nomemory [eax]\ + modify exact [eax ebx ecx] +unsigned long nsqrtasm(unsigned long); + +#pragma aux msqrtasm =\ + "mov eax, 0x40000000",\ + "mov ebx, 0x20000000",\ + "begit: cmp ecx, eax",\ + "jl skip",\ + "sub ecx, eax",\ + "lea eax, [eax+ebx*4]",\ + "skip: sub eax, ebx",\ + "shr eax, 1",\ + "shr ebx, 2",\ + "jnz begit",\ + "cmp ecx, eax",\ + "sbb eax, -1",\ + "shr eax, 1",\ + parm nomemory [ecx]\ + modify exact [eax ebx ecx] +long msqrtasm(unsigned long); + + //0x007ff000 is (11<<13), 0x3f800000 is (127<<23) +#pragma aux krecipasm =\ + "mov fpuasm, eax",\ + "fild dword ptr fpuasm",\ + "add eax, eax",\ + "fstp dword ptr fpuasm",\ + "sbb ebx, ebx",\ + "mov eax, fpuasm",\ + "mov ecx, eax",\ + "and eax, 0x007ff000",\ + "shr eax, 10",\ + "sub ecx, 0x3f800000",\ + "shr ecx, 23",\ + "mov eax, dword ptr reciptable[eax]",\ + "sar eax, cl",\ + "xor eax, ebx",\ + parm [eax]\ + modify exact [eax ebx ecx] +long krecipasm(long); + +#pragma aux setgotpic =\ + "mov ebx, eax",\ + "cmp byte ptr walock[eax], 200",\ + "jae skipit",\ + "mov byte ptr walock[eax], 199",\ + "skipit: shr eax, 3",\ + "and ebx, 7",\ + "mov dl, byte ptr gotpic[eax]",\ + "mov bl, byte ptr pow2char[ebx]",\ + "or dl, bl",\ + "mov byte ptr gotpic[eax], dl",\ + parm [eax]\ + modify exact [eax ebx ecx edx] +void setgotpic(long); + +#pragma aux getclipmask =\ + "sar eax, 31",\ + "add ebx, ebx",\ + "adc eax, eax",\ + "add ecx, ecx",\ + "adc eax, eax",\ + "add edx, edx",\ + "adc eax, eax",\ + "mov ebx, eax",\ + "shl ebx, 4",\ + "or al, 0xf0",\ + "xor eax, ebx",\ + parm [eax][ebx][ecx][edx]\ + modify exact [eax ebx ecx edx] +long getclipmask(long,long,long,long); + +#pragma aux getkensmessagecrc =\ + "xor eax, eax",\ + "mov ecx, 32",\ + "beg: mov edx, dword ptr [ebx+ecx*4-4]",\ + "ror edx, cl",\ + "adc eax, edx",\ + "bswap eax",\ + "loop short beg",\ + parm [ebx]\ + modify exact [eax ebx ecx edx] +long getkensmessagecrc(long); + +#elif defined(_MSC_VER) // __WATCOMC__ + +// +// Microsoft C Inline Assembly Routines +// + +static inline long nsqrtasm(long a) +{ + _asm { + push ebx + mov eax, a + test eax, 0xff000000 + mov ebx, eax + jnz short over24 + shr ebx, 12 + mov cx, word ptr shlookup[ebx*2] + jmp short under24 + over24: + shr ebx, 24 + mov cx, word ptr shlookup[ebx*2+8192] + under24: + shr eax, cl + mov cl, ch + mov ax, word ptr sqrtable[eax*2] + shr eax, cl + pop ebx + } +} + +static inline long msqrtasm(long c) +{ + _asm { + push ebx + mov ecx, c + mov eax, 0x40000000 + mov ebx, 0x20000000 + begit: + cmp ecx, eax + jl skip + sub ecx, eax + lea eax, [eax+ebx*4] + skip: + sub eax, ebx + shr eax, 1 + shr ebx, 2 + jnz begit + cmp ecx, eax + sbb eax, -1 + shr eax, 1 + pop ebx + } +} + + //0x007ff000 is (11<<13), 0x3f800000 is (127<<23) +static inline long krecipasm(long a) +{ + _asm { + push ebx + mov eax, a + mov fpuasm, eax + fild dword ptr fpuasm + add eax, eax + fstp dword ptr fpuasm + sbb ebx, ebx + mov eax, fpuasm + mov ecx, eax + and eax, 0x007ff000 + shr eax, 10 + sub ecx, 0x3f800000 + shr ecx, 23 + mov eax, dword ptr reciptable[eax] + sar eax, cl + xor eax, ebx + pop ebx + } +} + +static inline void setgotpic(long a) +{ + _asm { + push ebx + mov eax, a + mov ebx, eax + cmp byte ptr walock[eax], 200 + jae skipit + mov byte ptr walock[eax], 199 + skipit: + shr eax, 3 + and ebx, 7 + mov dl, byte ptr gotpic[eax] + mov bl, byte ptr pow2char[ebx] + or dl, bl + mov byte ptr gotpic[eax], dl + pop ebx + } +} + +static inline long getclipmask(long a, long b, long c, long d) +{ + _asm { + push ebx + mov eax, a + mov ebx, b + mov ecx, c + mov edx, d + sar eax, 31 + add ebx, ebx + adc eax, eax + add ecx, ecx + adc eax, eax + add edx, edx + adc eax, eax + mov ebx, eax + shl ebx, 4 + or al, 0xf0 + xor eax, ebx + pop ebx + } +} + +static inline long getkensmessagecrc(void *b) +{ + _asm { + push ebx + mov ebx, b + xor eax, eax + mov ecx, 32 + beg: + mov edx, dword ptr [ebx+ecx*4-4] + ror edx, cl + adc eax, edx + bswap eax + loop short beg + pop ebx + } +} + +#elif defined(__GNUC__) && defined(__i386__) // _MSC_VER + +// +// GCC "Inline" Assembly Routines +// + +#define nsqrtasm(a) \ + ({ long __r, __a=(a); \ + __asm__ __volatile__ ( \ + "testl $0xff000000, %%eax\n\t" \ + "movl %%eax, %%ebx\n\t" \ + "jnz 0f\n\t" \ + "shrl $12, %%ebx\n\t" \ + "movw "ASMSYM("shlookup")"(,%%ebx,2), %%cx\n\t" \ + "jmp 1f\n\t" \ + "0:\n\t" \ + "shrl $24, %%ebx\n\t" \ + "movw ("ASMSYM("shlookup")"+8192)(,%%ebx,2), %%cx\n\t" \ + "1:\n\t" \ + "shrl %%cl, %%eax\n\t" \ + "movb %%ch, %%cl\n\t" \ + "movw "ASMSYM("sqrtable")"(,%%eax,2), %%ax\n\t" \ + "shrl %%cl, %%eax" \ + : "=a" (__r) : "a" (__a) : "ebx", "ecx", "cc"); \ + __r; }) + + // edx is blown by this code somehow?! +#define msqrtasm(c) \ + ({ long __r, __c=(c); \ + __asm__ __volatile__ ( \ + "movl $0x40000000, %%eax\n\t" \ + "movl $0x20000000, %%ebx\n\t" \ + "0:\n\t" \ + "cmpl %%eax, %%ecx\n\t" \ + "jl 1f\n\t" \ + "subl %%eax, %%ecx\n\t" \ + "leal (%%eax,%%ebx,4), %%eax\n\t" \ + "1:\n\t" \ + "subl %%ebx, %%eax\n\t" \ + "shrl $1, %%eax\n\t" \ + "shrl $2, %%ebx\n\t" \ + "jnz 0b\n\t" \ + "cmpl %%eax, %%ecx\n\t" \ + "sbbl $-1, %%eax\n\t" \ + "shrl $1, %%eax" \ + : "=a" (__r) : "c" (__c) : "edx","ebx", "cc"); \ + __r; }) + +#define setgotpic(a) \ + ({ long __a=(a); \ + __asm__ __volatile__ ( \ + "movl %%eax, %%ebx\n\t" \ + "cmpb $200, "ASMSYM("walock")"(%%eax)\n\t" \ + "jae 0f\n\t" \ + "movb $199, "ASMSYM("walock")"(%%eax)\n\t" \ + "0:\n\t" \ + "shrl $3, %%eax\n\t" \ + "andl $7, %%ebx\n\t" \ + "movb "ASMSYM("gotpic")"(%%eax), %%dl\n\t" \ + "movb "ASMSYM("pow2char")"(%%ebx), %%bl\n\t" \ + "orb %%bl, %%dl\n\t" \ + "movb %%dl, "ASMSYM("gotpic")"(%%eax)" \ + : "=a" (__a) : "a" (__a) \ + : "ebx", "edx", "memory", "cc"); \ + __a; }) + +#define krecipasm(a) \ + ({ long __a=(a); \ + __asm__ __volatile__ ( \ + "movl %%eax, ("ASMSYM("fpuasm")"); fildl ("ASMSYM("fpuasm")"); " \ + "addl %%eax, %%eax; fstps ("ASMSYM("fpuasm")"); sbbl %%ebx, %%ebx; " \ + "movl ("ASMSYM("fpuasm")"), %%eax; movl %%eax, %%ecx; " \ + "andl $0x007ff000, %%eax; shrl $10, %%eax; subl $0x3f800000, %%ecx; " \ + "shrl $23, %%ecx; movl "ASMSYM("reciptable")"(%%eax), %%eax; " \ + "sarl %%cl, %%eax; xorl %%ebx, %%eax" \ + : "=a" (__a) : "a" (__a) : "ebx", "ecx", "memory", "cc"); \ + __a; }) + +#define getclipmask(a,b,c,d) \ + ({ long __a=(a), __b=(b), __c=(c), __d=(d); \ + __asm__ __volatile__ ("sarl $31, %%eax; addl %%ebx, %%ebx; adcl %%eax, %%eax; " \ + "addl %%ecx, %%ecx; adcl %%eax, %%eax; addl %%edx, %%edx; " \ + "adcl %%eax, %%eax; movl %%eax, %%ebx; shl $4, %%ebx; " \ + "orb $0xf0, %%al; xorl %%ebx, %%eax" \ + : "=a" (__a), "=b" (__b), "=c" (__c), "=d" (__d) \ + : "a" (__a), "b" (__b), "c" (__c), "d" (__d) : "cc"); \ + __a; }) + + +#define getkensmessagecrc(b) \ + ({ long __a, __b=(b); \ + __asm__ __volatile__ ( \ + "xorl %%eax, %%eax\n\t" \ + "movl $32, %%ecx\n\t" \ + "0:\n\t" \ + "movl -4(%%ebx,%%ecx,4), %%edx\n\t" \ + "rorl %%cl, %%edx\n\t" \ + "adcl %%edx, %%eax\n\t" \ + "bswapl %%eax\n\t" \ + "loop 0b" \ + : "=a" (__a) : "b" (__b) : "ecx", "edx" \ + __a; }) + +#else // __GNUC__ && __i386__ + +#error Unsupported compiler or architecture. + +#endif + + +static long xb1[MAXWALLSB], yb1[MAXWALLSB], xb2[MAXWALLSB], yb2[MAXWALLSB]; +static long rx1[MAXWALLSB], ry1[MAXWALLSB], rx2[MAXWALLSB], ry2[MAXWALLSB]; +static short p2[MAXWALLSB], thesector[MAXWALLSB], thewall[MAXWALLSB]; + +static short bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; + +static short smost[MAXYSAVES], smostcnt; +static short smoststart[MAXWALLSB]; +static char smostwalltype[MAXWALLSB]; +static long smostwall[MAXWALLSB], smostwallcnt = -1L; + +static short maskwall[MAXWALLSB], maskwallcnt; +static long spritesx[MAXSPRITESONSCREEN]; +static long spritesy[MAXSPRITESONSCREEN+1]; +static long spritesz[MAXSPRITESONSCREEN]; +static spritetype *tspriteptr[MAXSPRITESONSCREEN]; + +short umost[MAXXDIM], dmost[MAXXDIM]; +static short bakumost[MAXXDIM], bakdmost[MAXXDIM]; +short uplc[MAXXDIM], dplc[MAXXDIM]; +static short uwall[MAXXDIM], dwall[MAXXDIM]; +static long swplc[MAXXDIM], lplc[MAXXDIM]; +static long swall[MAXXDIM], lwall[MAXXDIM+4]; +long xdimen = -1, xdimenrecip, halfxdimen, xdimenscale, xdimscale; +long wx1, wy1, wx2, wy2, ydimen; +long /*viewoffset,*/ frameoffset; + +static long nrx1[8], nry1[8], nrx2[8], nry2[8]; // JBF 20031206: Thanks Ken + +static long rxi[8], ryi[8], rzi[8], rxi2[8], ryi2[8], rzi2[8]; +static long xsi[8], ysi[8], *horizlookup=0, *horizlookup2=0, horizycent; + +long globalposx, globalposy, globalposz, globalhoriz; +short globalang, globalcursectnum; +long globalpal, cosglobalang, singlobalang; +long cosviewingrangeglobalang, sinviewingrangeglobalang; +char *globalpalwritten; +long globaluclip, globaldclip, globvis; +long globalvisibility, globalhisibility, globalpisibility, globalcisibility; +char globparaceilclip, globparaflorclip; + +long xyaspect, viewingrangerecip; + +long asm1, asm2, asm3, asm4; +long vplce[4], vince[4], palookupoffse[4], bufplce[4]; +char globalxshift, globalyshift; +long globalxpanning, globalypanning, globalshade; +short globalpicnum, globalshiftval; +long globalzd, globalbufplc, globalyscale, globalorientation; +long globalx1, globaly1, globalx2, globaly2, globalx3, globaly3, globalzx; +long globalx, globaly, globalz; + +static short sectorborder[256], sectorbordercnt; +static char tablesloaded = 0; +long pageoffset, ydim16, qsetmode = 0; +long startposx, startposy, startposz; +short startang, startsectnum; +short pointhighlight, linehighlight, highlightcnt; +static long lastx[MAXYDIM]; +char *transluc = NULL, paletteloaded = 0; + +long halfxdim16, midydim16; + +#define FASTPALGRIDSIZ 8 +static long rdist[129], gdist[129], bdist[129]; +static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3]; +static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)]; +static long colnext[256]; +static char coldist[8] = {0,1,2,3,4,3,2,1}; +static long colscan[27]; + +static short clipnum, hitwalls[4]; +long hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1; +#ifdef POLYMOST +static long hitallsprites = 0; +#endif + +typedef struct { long x1, y1, x2, y2; } linetype; +static linetype clipit[MAXCLIPNUM]; +static short clipsectorlist[MAXCLIPNUM], clipsectnum; +static short clipobjectval[MAXCLIPNUM]; + +typedef struct +{ + long sx, sy, z; + short a, picnum; + signed char dashade; + char dapalnum, dastat, pagesleft; + long cx1, cy1, cx2, cy2; + long uniqid; //JF extension +} permfifotype; +static permfifotype permfifo[MAXPERMS]; +static long permhead = 0, permtail = 0; + +short numscans, numhits, numbunches; +static short posfil, capturecount = 0, hitcnt; + +char vgapal16[4*256] = +{ + 00,00,00,00, 42,00,00,00, 00,42,00,00, 42,42,00,00, 00,00,42,00, + 42,00,42,00, 00,21,42,00, 42,42,42,00, 21,21,21,00, 63,21,21,00, + 21,63,21,00, 63,63,21,00, 21,21,63,00, 63,21,63,00, 21,63,63,00, + 63,63,63,00 +}; + +short editstatus = 0; +short searchit; +long searchx = -1, searchy; //search input +short searchsector, searchwall, searchstat; //search output +double msens = 1.0; + +static char artfilename[20]; +static long numtilefiles, artfil = -1, artfilnum, artfilplc; + +static char inpreparemirror = 0; +static long mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2; + +static long setviewcnt = 0; // interface layers use this now +static long bakframeplace[4], bakxsiz[4], bakysiz[4]; +static long bakwindowx1[4], bakwindowy1[4]; +static long bakwindowx2[4], bakwindowy2[4]; +#ifdef POLYMOST +static long bakrendmode,baktile; +#endif + +long totalclocklock; + +char apptitle[256] = "Build Engine"; +palette_t curpalette[256]; // the current palette, unadjusted for brightness or tint +palette_t curpalettefaded[256]; // the current palette, adjusted for brightness and tint (ie. what gets sent to the card) +palette_t palfadergb = { 0,0,0,0 }; +char palfadedelta = 0; + + + +// +// Internal Engine Functions +// +//long cacheresets = 0,cacheinvalidates = 0; + + +//============================================================================= //POLYMOST BEGINS +#ifdef POLYMOST +static void scansector(short sectnum); +#include "hightile.c" +#include "polymost.c" +#else +void hicsetpalettetint(long palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect) { } +int hicsetsubsttex(long picnum, long palnum, char *filen, float alphacut) { return 0; } +int hicsetskybox(long picnum, long palnum, char *faces[6]) { return 0; } +int hicclearsubst(long picnum, long palnum) { return 0; } +long polymost_drawtilescreen (long tilex, long tiley, long wallnum, long dimen) { return -1; } +#endif +//============================================================================= //POLYMOST ENDS + + +// +// getpalookup (internal) +// +static inline long getpalookup(long davis, long dashade) +{ + return(min(max(dashade+(davis>>8),0),numpalookups-1)); +} + + +// +// scansector (internal) +// +static void scansector(short sectnum) +{ + walltype *wal, *wal2; + spritetype *spr; + long xs, ys, x1, y1, x2, y2, xp1, yp1, xp2=0, yp2=0, templong; + short z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst; + short nextsectnum; + + if (sectnum < 0) return; + + if (automapping) show2dsector[sectnum>>3] |= pow2char[sectnum&7]; + + sectorborder[0] = sectnum, sectorbordercnt = 1; + do + { + sectnum = sectorborder[--sectorbordercnt]; + + for(z=headspritesect[sectnum];z>=0;z=nextspritesect[z]) + { + spr = &sprite[z]; + if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) && + (spr->xrepeat > 0) && (spr->yrepeat > 0) && + (spritesortcnt < MAXSPRITESONSCREEN)) + { + xs = spr->x-globalposx; ys = spr->y-globalposy; + if ((spr->cstat&48) || (xs*cosglobalang+ys*singlobalang > 0)) + { + copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); + tsprite[spritesortcnt++].owner = z; + } + } + } + + gotsector[sectnum>>3] |= pow2char[sectnum&7]; + + bunchfrst = numbunches; + numscansbefore = numscans; + + startwall = sector[sectnum].wallptr; + endwall = startwall + sector[sectnum].wallnum; + scanfirst = numscans; + for(z=startwall,wal=&wall[z];znextsector; + + wal2 = &wall[wal->point2]; + x1 = wal->x-globalposx; y1 = wal->y-globalposy; + x2 = wal2->x-globalposx; y2 = wal2->y-globalposy; + + if ((nextsectnum >= 0) && ((wal->cstat&32) == 0)) + if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0) + { + templong = x1*y2-x2*y1; + if (((unsigned)templong+262144) < 524288) + if (mulscale5(templong,templong) <= (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) + sectorborder[sectorbordercnt++] = nextsectnum; + } + + if ((z == startwall) || (wall[z-1].point2 != z)) + { + xp1 = dmulscale6(y1,cosglobalang,-x1,singlobalang); + yp1 = dmulscale6(x1,cosviewingrangeglobalang,y1,sinviewingrangeglobalang); + } + else + { + xp1 = xp2; + yp1 = yp2; + } + xp2 = dmulscale6(y2,cosglobalang,-x2,singlobalang); + yp2 = dmulscale6(x2,cosviewingrangeglobalang,y2,sinviewingrangeglobalang); + if ((yp1 < 256) && (yp2 < 256)) goto skipitaddwall; + + //If wall's NOT facing you + if (dmulscale32(xp1,yp2,-xp2,yp1) >= 0) goto skipitaddwall; + + if (xp1 >= -yp1) + { + if ((xp1 > yp1) || (yp1 == 0)) goto skipitaddwall; + xb1[numscans] = halfxdimen + scale(xp1,halfxdimen,yp1); + if (xp1 >= 0) xb1[numscans]++; //Fix for SIGNED divide + if (xb1[numscans] >= xdimen) xb1[numscans] = xdimen-1; + yb1[numscans] = yp1; + } + else + { + if (xp2 < -yp2) goto skipitaddwall; + xb1[numscans] = 0; + templong = yp1-yp2+xp1-xp2; + if (templong == 0) goto skipitaddwall; + yb1[numscans] = yp1 + scale(yp2-yp1,xp1+yp1,templong); + } + if (yb1[numscans] < 256) goto skipitaddwall; + + if (xp2 <= yp2) + { + if ((xp2 < -yp2) || (yp2 == 0)) goto skipitaddwall; + xb2[numscans] = halfxdimen + scale(xp2,halfxdimen,yp2) - 1; + if (xp2 >= 0) xb2[numscans]++; //Fix for SIGNED divide + if (xb2[numscans] >= xdimen) xb2[numscans] = xdimen-1; + yb2[numscans] = yp2; + } + else + { + if (xp1 > yp1) goto skipitaddwall; + xb2[numscans] = xdimen-1; + templong = xp2-xp1+yp1-yp2; + if (templong == 0) goto skipitaddwall; + yb2[numscans] = yp1 + scale(yp2-yp1,yp1-xp1,templong); + } + if ((yb2[numscans] < 256) || (xb1[numscans] > xb2[numscans])) goto skipitaddwall; + + //Made it all the way! + thesector[numscans] = sectnum; thewall[numscans] = z; + rx1[numscans] = xp1; ry1[numscans] = yp1; + rx2[numscans] = xp2; ry2[numscans] = yp2; + p2[numscans] = numscans+1; + numscans++; +skipitaddwall: + + if ((wall[z].point2 < z) && (scanfirst < numscans)) + p2[numscans-1] = scanfirst, scanfirst = numscans; + } + + for(z=numscansbefore;z= xb1[p2[z]])) + bunchfirst[numbunches++] = p2[z], p2[z] = -1; + + for(z=bunchfrst;z=0;zz=p2[zz]); + bunchlast[z] = zz; + } + } while (sectorbordercnt > 0); +} + + +// +// maskwallscan (internal) +// +static void maskwallscan(long x1, long x2, short *uwal, short *dwal, long *swal, long *lwal) +{ + long i, x, startx, xnice, ynice, fpalookup; + long y1ve[4], y2ve[4], u4, d4, dax, z, p, tsizx, tsizy; + char bad; + + tsizx = tilesizx[globalpicnum]; + tsizy = tilesizy[globalpicnum]; + setgotpic(globalpicnum); + if ((tsizx <= 0) || (tsizy <= 0)) return; + if ((uwal[x1] > ydimen) && (uwal[x2] > ydimen)) return; + if ((dwal[x1] < 0) && (dwal[x2] < 0)) return; + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + + startx = x1; + + xnice = (pow2long[picsiz[globalpicnum]&15] == tsizx); + if (xnice) tsizx = (tsizx-1); + ynice = (pow2long[picsiz[globalpicnum]>>4] == tsizy); + if (ynice) tsizy = (picsiz[globalpicnum]>>4); + + fpalookup = FP_OFF(palookup[globalpal]); + + setupmvlineasm(globalshiftval); + +#ifndef ENGINE_USING_A_C + + x = startx; + while ((startumost[x+windowx1] > startdmost[x+windowx1]) && (x <= x2)) x++; + + p = x+frameoffset; + + for(;(x<=x2)&&(p&3);x++,p++) + { + y1ve[0] = max(uwal[x],startumost[x+windowx1]-windowy1); + y2ve[0] = min(dwal[x],startdmost[x+windowx1]-windowy1); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],p+ylookup[y1ve[0]]); + } + for(;x<=x2-3;x+=4,p+=4) + { + bad = 0; + for(z=3,dax=x+3;z>=0;z--,dax--) + { + y1ve[z] = max(uwal[dax],startumost[dax+windowx1]-windowy1); + y2ve[z] = min(dwal[dax],startdmost[dax+windowx1]-windowy1)-1; + if (y2ve[z] < y1ve[z]) { bad += pow2char[z]; continue; } + + i = lwal[dax] + globalxpanning; + if (i >= tsizx) { if (xnice == 0) i %= tsizx; else i &= tsizx; } + if (ynice == 0) i *= tsizy; else i <<= tsizy; + bufplce[z] = waloff[globalpicnum]+i; + + vince[z] = swal[dax]*globalyscale; + vplce[z] = globalzd + vince[z]*(y1ve[z]-globalhoriz+1); + } + if (bad == 15) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + palookupoffse[3] = fpalookup+(getpalookup((long)mulscale16(swal[x+3],globvis),globalshade)<<8); + + if ((palookupoffse[0] == palookupoffse[3]) && ((bad&0x9) == 0)) + { + palookupoffse[1] = palookupoffse[0]; + palookupoffse[2] = palookupoffse[0]; + } + else + { + palookupoffse[1] = fpalookup+(getpalookup((long)mulscale16(swal[x+1],globvis),globalshade)<<8); + palookupoffse[2] = fpalookup+(getpalookup((long)mulscale16(swal[x+2],globvis),globalshade)<<8); + } + + u4 = max(max(y1ve[0],y1ve[1]),max(y1ve[2],y1ve[3])); + d4 = min(min(y2ve[0],y2ve[1]),min(y2ve[2],y2ve[3])); + + if ((bad > 0) || (u4 >= d4)) + { + if (!(bad&1)) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (!(bad&2)) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (!(bad&4)) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (!(bad&8)) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + continue; + } + + if (u4 > y1ve[0]) vplce[0] = mvlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (u4 > y1ve[1]) vplce[1] = mvlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (u4 > y1ve[2]) vplce[2] = mvlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (u4 > y1ve[3]) vplce[3] = mvlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + + if (d4 >= u4) mvlineasm4(d4-u4+1,ylookup[u4]+p); + + i = p+ylookup[d4+1]; + if (y2ve[0] > d4) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); + if (y2ve[1] > d4) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); + if (y2ve[2] > d4) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); + if (y2ve[3] > d4) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); + } + for(;x<=x2;x++,p++) + { + y1ve[0] = max(uwal[x],startumost[x+windowx1]-windowy1); + y2ve[0] = min(dwal[x],startdmost[x+windowx1]-windowy1); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],p+ylookup[y1ve[0]]); + } + +#else // ENGINE_USING_A_C + + p = startx+frameoffset; + for(x=startx;x<=x2;x++,p++) + { + y1ve[0] = max(uwal[x],startumost[x+windowx1]-windowy1); + y2ve[0] = min(dwal[x],startdmost[x+windowx1]-windowy1); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],p+ylookup[y1ve[0]]); + } + +#endif + + faketimerhandler(); +} + + +// +// wallfront (internal) +// +static long wallfront(long l1, long l2) +{ + walltype *wal; + long x11, y11, x21, y21, x12, y12, x22, y22, dx, dy, t1, t2; + + wal = &wall[thewall[l1]]; x11 = wal->x; y11 = wal->y; + wal = &wall[wal->point2]; x21 = wal->x; y21 = wal->y; + wal = &wall[thewall[l2]]; x12 = wal->x; y12 = wal->y; + wal = &wall[wal->point2]; x22 = wal->x; y22 = wal->y; + + dx = x21-x11; dy = y21-y11; + t1 = dmulscale2(x12-x11,dy,-dx,y12-y11); //p1(l2) vs. l1 + t2 = dmulscale2(x22-x11,dy,-dx,y22-y11); //p2(l2) vs. l1 + if (t1 == 0) { t1 = t2; if (t1 == 0) return(-1); } + if (t2 == 0) t2 = t1; + if ((t1^t2) >= 0) + { + t2 = dmulscale2(globalposx-x11,dy,-dx,globalposy-y11); //pos vs. l1 + return((t2^t1) >= 0); + } + + dx = x22-x12; dy = y22-y12; + t1 = dmulscale2(x11-x12,dy,-dx,y11-y12); //p1(l1) vs. l2 + t2 = dmulscale2(x21-x12,dy,-dx,y21-y12); //p2(l1) vs. l2 + if (t1 == 0) { t1 = t2; if (t1 == 0) return(-1); } + if (t2 == 0) t2 = t1; + if ((t1^t2) >= 0) + { + t2 = dmulscale2(globalposx-x12,dy,-dx,globalposy-y12); //pos vs. l2 + return((t2^t1) < 0); + } + return(-2); +} + + +// +// spritewallfront (internal) +// +static long spritewallfront(spritetype *s, long w) +{ + walltype *wal; + long x1, y1; + + wal = &wall[w]; x1 = wal->x; y1 = wal->y; + wal = &wall[wal->point2]; + return (dmulscale32(wal->x-x1,s->y-y1,-(s->x-x1),wal->y-y1) >= 0); +} + +// +// spritebehindwall(internal) +// +static long spriteobstructswall(spritetype *s, long w) +{ + walltype *wal; + long x, y; + long x1, y1; + long x2, y2; + double a1, b1, c1; + double a2, b2, c2; + double d1, d2; + + // wall line equation + wal = &wall[w]; x1 = wal->x - globalposx; y1 = wal->y - globalposy; + wal = &wall[wal->point2]; x2 = wal->x - globalposx; y2 = wal->y - globalposy; + if ((x2 - x1) != 0) + a1 = (float)(y2 - y1)/(x2 - x1); + else + a1 = 1e+37; // not infinite, but almost ;) + b1 = -1; + c1 = (y1 - (a1 * x1)); + + // player to sprite line equation + if ((s->x - globalposx) != 0) + a2 = (float)(s->y - globalposy)/(s->x - globalposx); + else + a2 = 1e+37; + b2 = -1; + c2 = 0; + + // intersection point + d1 = (float)(1) / (a1*b2 - a2*b1); + x = ((b1*c2 - b2*c1) * d1); + y = ((a2*c1 - a1*c2) * d1); + + // distance between the sprite and the player + a1 = s->x - globalposx; + b1 = s->y - globalposy; + d1 = (a1 * a1 + b1 * b1); + + // distance between the intersection point and the player + d2 = (x * x + y * y); + + // check if the sprite obstructs the wall + if ((d1 < d2) && (min(x1, x2) <= x) && (x <= max(x1, x2)) && (min(y1, y2) <= y) && (y <= max(y1, y2))) + return (1); + else + return (0); +} + +// +// bunchfront (internal) +// +static long bunchfront(long b1, long b2) +{ + long x1b1, x2b1, x1b2, x2b2, b1f, b2f, i; + + b1f = bunchfirst[b1]; x1b1 = xb1[b1f]; x2b2 = xb2[bunchlast[b2]]+1; + if (x1b1 >= x2b2) return(-1); + b2f = bunchfirst[b2]; x1b2 = xb1[b2f]; x2b1 = xb2[bunchlast[b1]]+1; + if (x1b2 >= x2b1) return(-1); + + if (x1b1 >= x1b2) + { + for(i=b2f;xb2[i] xr) return; + r = horizlookup2[yp-globalhoriz+horizycent]; + asm1 = globalx1*r; + asm2 = globaly2*r; + s = ((long)getpalookup((long)mulscale16(r,globvis),globalshade)<<8); + + hlineasm4(xr-xl,0L,s,globalx2*r+globalypanning,globaly1*r+globalxpanning, + ylookup[yp]+xr+frameoffset); +} + + +// +// slowhline (internal) +// +static void slowhline(long xr, long yp) +{ + long xl, r; + + xl = lastx[yp]; if (xl > xr) return; + r = horizlookup2[yp-globalhoriz+horizycent]; + asm1 = globalx1*r; + asm2 = globaly2*r; + + asm3 = (long)globalpalwritten + ((long)getpalookup((long)mulscale16(r,globvis),globalshade)<<8); + if (!(globalorientation&256)) + { + mhline(globalbufplc,globaly1*r+globalxpanning-asm1*(xr-xl),(xr-xl)<<16,0L, + globalx2*r+globalypanning-asm2*(xr-xl),ylookup[yp]+xl+frameoffset); + return; + } + thline(globalbufplc,globaly1*r+globalxpanning-asm1*(xr-xl),(xr-xl)<<16,0L, + globalx2*r+globalypanning-asm2*(xr-xl),ylookup[yp]+xl+frameoffset); +} + + +// +// prepwall (internal) +// +static void prepwall(long z, walltype *wal) +{ + long i, l=0, ol=0, splc, sinc, x, topinc, top, botinc, bot, walxrepeat; + + walxrepeat = (wal->xrepeat<<3); + + //lwall calculation + i = xb1[z]-halfxdimen; + topinc = -(ry1[z]>>2); + botinc = ((ry2[z]-ry1[z])>>8); + top = mulscale5(rx1[z],xdimen)+mulscale2(topinc,i); + bot = mulscale11(rx1[z]-rx2[z],xdimen)+mulscale2(botinc,i); + + splc = mulscale19(ry1[z],xdimscale); + sinc = mulscale16(ry2[z]-ry1[z],xdimscale); + + x = xb1[z]; + if (bot != 0) + { + l = divscale12(top,bot); + swall[x] = mulscale21(l,sinc)+splc; + l *= walxrepeat; + lwall[x] = (l>>18); + } + while (x+4 <= xb2[z]) + { + top += topinc; bot += botinc; + if (bot != 0) + { + ol = l; l = divscale12(top,bot); + swall[x+4] = mulscale21(l,sinc)+splc; + l *= walxrepeat; + lwall[x+4] = (l>>18); + } + i = ((ol+l)>>1); + lwall[x+2] = (i>>18); + lwall[x+1] = ((ol+i)>>19); + lwall[x+3] = ((l+i)>>19); + swall[x+2] = ((swall[x]+swall[x+4])>>1); + swall[x+1] = ((swall[x]+swall[x+2])>>1); + swall[x+3] = ((swall[x+4]+swall[x+2])>>1); + x += 4; + } + if (x+2 <= xb2[z]) + { + top += (topinc>>1); bot += (botinc>>1); + if (bot != 0) + { + ol = l; l = divscale12(top,bot); + swall[x+2] = mulscale21(l,sinc)+splc; + l *= walxrepeat; + lwall[x+2] = (l>>18); + } + lwall[x+1] = ((l+ol)>>19); + swall[x+1] = ((swall[x]+swall[x+2])>>1); + x += 2; + } + if (x+1 <= xb2[z]) + { + bot += (botinc>>2); + if (bot != 0) + { + l = divscale12(top+(topinc>>2),bot); + swall[x+1] = mulscale21(l,sinc)+splc; + lwall[x+1] = mulscale18(l,walxrepeat); + } + } + + if (lwall[xb1[z]] < 0) lwall[xb1[z]] = 0; + if ((lwall[xb2[z]] >= walxrepeat) && (walxrepeat)) lwall[xb2[z]] = walxrepeat-1; + if (wal->cstat&8) + { + walxrepeat--; + for(x=xb1[z];x<=xb2[z];x++) lwall[x] = walxrepeat-lwall[x]; + } +} + + +// +// animateoffs (internal) +// +static long animateoffs(short tilenum, short fakevar) +{ + long i, k, offs; + + offs = 0; + i = (totalclocklock>>((picanm[tilenum]>>24)&15)); + if ((picanm[tilenum]&63) > 0) + { + switch(picanm[tilenum]&192) + { + case 64: + k = (i%((picanm[tilenum]&63)<<1)); + if (k < (picanm[tilenum]&63)) + offs = k; + else + offs = (((picanm[tilenum]&63)<<1)-k); + break; + case 128: + offs = (i%((picanm[tilenum]&63)+1)); + break; + case 192: + offs = -(i%((picanm[tilenum]&63)+1)); + } + } + return(offs); +} + + +// +// owallmost (internal) +// +static long owallmost(short *mostbuf, long w, long z) +{ + long bad, inty, xcross, y, yinc; + long s1, s2, s3, s4, ix1, ix2, iy1, iy2, t; + long i; + + z <<= 7; + s1 = mulscale20(globaluclip,yb1[w]); s2 = mulscale20(globaluclip,yb2[w]); + s3 = mulscale20(globaldclip,yb1[w]); s4 = mulscale20(globaldclip,yb2[w]); + bad = (zs3)<<2)+((z>s4)<<3); + + ix1 = xb1[w]; iy1 = yb1[w]; + ix2 = xb2[w]; iy2 = yb2[w]; + + if ((bad&3) == 3) + { + //clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),0L); + for (i=ix1; i<=ix2; i++) mostbuf[i] = 0; + return(bad); + } + + if ((bad&12) == 12) + { + //clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=ix1; i<=ix2; i++) mostbuf[i] = ydimen; + return(bad); + } + + if (bad&3) + { + t = divscale30(z-s1,s2-s1); + inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); + + if ((bad&3) == 2) + { + if (xb1[w] <= xcross) { iy2 = inty; ix2 = xcross; } + //clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),0L); + for (i=xcross+1; i<=xb2[w]; i++) mostbuf[i] = 0; + } + else + { + if (xcross <= xb2[w]) { iy1 = inty; ix1 = xcross; } + //clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),0L); + for (i=xb1[w]; i<=xcross; i++) mostbuf[i] = 0; + } + } + + if (bad&12) + { + t = divscale30(z-s3,s4-s3); + inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); + + if ((bad&12) == 8) + { + if (xb1[w] <= xcross) { iy2 = inty; ix2 = xcross; } + //clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=xcross+1; i<=xb2[w]; i++) mostbuf[i] = ydimen; + } + else + { + if (xcross <= xb2[w]) { iy1 = inty; ix1 = xcross; } + //clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=xb1[w]; i<=xcross; i++) mostbuf[i] = ydimen; + } + } + + y = (scale(z,xdimenscale,iy1)<<4); + yinc = ((scale(z,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); + qinterpolatedown16short((long)&mostbuf[ix1],ix2-ix1+1,y+(globalhoriz<<16),yinc); + + if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; + if (mostbuf[ix1] > ydimen) mostbuf[ix1] = ydimen; + if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; + if (mostbuf[ix2] > ydimen) mostbuf[ix2] = ydimen; + + return(bad); +} + + +// +// wallmost (internal) +// +static long wallmost(short *mostbuf, long w, long sectnum, char dastat) +{ + long bad, i, j, t, y, z, inty, intz, xcross, yinc, fw; + long x1, y1, z1, x2, y2, z2, xv, yv, dx, dy, dasqr, oz1, oz2; + long s1, s2, s3, s4, ix1, ix2, iy1, iy2; + //char datempbuf[256]; + + if (dastat == 0) + { + z = sector[sectnum].ceilingz-globalposz; + if ((sector[sectnum].ceilingstat&2) == 0) return(owallmost(mostbuf,w,z)); + } + else + { + z = sector[sectnum].floorz-globalposz; + if ((sector[sectnum].floorstat&2) == 0) return(owallmost(mostbuf,w,z)); + } + + i = thewall[w]; + if (i == sector[sectnum].wallptr) return(owallmost(mostbuf,w,z)); + + x1 = wall[i].x; x2 = wall[wall[i].point2].x-x1; + y1 = wall[i].y; y2 = wall[wall[i].point2].y-y1; + + fw = sector[sectnum].wallptr; i = wall[fw].point2; + dx = wall[i].x-wall[fw].x; dy = wall[i].y-wall[fw].y; + dasqr = krecipasm(nsqrtasm(dx*dx+dy*dy)); + + if (xb1[w] == 0) + { xv = cosglobalang+sinviewingrangeglobalang; yv = singlobalang-cosviewingrangeglobalang; } + else + { xv = x1-globalposx; yv = y1-globalposy; } + i = xv*(y1-globalposy)-yv*(x1-globalposx); j = yv*x2-xv*y2; + if (klabs(j) > klabs(i>>3)) i = divscale28(i,j); + if (dastat == 0) + { + t = mulscale15(sector[sectnum].ceilingheinum,dasqr); + z1 = sector[sectnum].ceilingz; + } + else + { + t = mulscale15(sector[sectnum].floorheinum,dasqr); + z1 = sector[sectnum].floorz; + } + z1 = dmulscale24(dx*t,mulscale20(y2,i)+((y1-wall[fw].y)<<8), + -dy*t,mulscale20(x2,i)+((x1-wall[fw].x)<<8))+((z1-globalposz)<<7); + + + if (xb2[w] == xdimen-1) + { xv = cosglobalang-sinviewingrangeglobalang; yv = singlobalang+cosviewingrangeglobalang; } + else + { xv = (x2+x1)-globalposx; yv = (y2+y1)-globalposy; } + i = xv*(y1-globalposy)-yv*(x1-globalposx); j = yv*x2-xv*y2; + if (klabs(j) > klabs(i>>3)) i = divscale28(i,j); + if (dastat == 0) + { + t = mulscale15(sector[sectnum].ceilingheinum,dasqr); + z2 = sector[sectnum].ceilingz; + } + else + { + t = mulscale15(sector[sectnum].floorheinum,dasqr); + z2 = sector[sectnum].floorz; + } + z2 = dmulscale24(dx*t,mulscale20(y2,i)+((y1-wall[fw].y)<<8), + -dy*t,mulscale20(x2,i)+((x1-wall[fw].x)<<8))+((z2-globalposz)<<7); + + + s1 = mulscale20(globaluclip,yb1[w]); s2 = mulscale20(globaluclip,yb2[w]); + s3 = mulscale20(globaldclip,yb1[w]); s4 = mulscale20(globaldclip,yb2[w]); + bad = (z1s3)<<2)+((z2>s4)<<3); + + ix1 = xb1[w]; ix2 = xb2[w]; + iy1 = yb1[w]; iy2 = yb2[w]; + oz1 = z1; oz2 = z2; + + if ((bad&3) == 3) + { + //clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),0L); + for (i=ix1; i<=ix2; i++) mostbuf[i] = 0; + return(bad); + } + + if ((bad&12) == 12) + { + //clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=ix1; i<=ix2; i++) mostbuf[i] = ydimen; + return(bad); + } + + if (bad&3) + { + //inty = intz / (globaluclip>>16) + t = divscale30(oz1-s1,s2-s1+oz1-oz2); + inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + intz = oz1 + mulscale30(oz2-oz1,t); + xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); + + //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); + //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + //intz = z1 + mulscale30(z2-z1,t); + + if ((bad&3) == 2) + { + if (xb1[w] <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + //clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),0L); + for (i=xcross+1; i<=xb2[w]; i++) mostbuf[i] = 0; + } + else + { + if (xcross <= xb2[w]) { z1 = intz; iy1 = inty; ix1 = xcross; } + //clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),0L); + for (i=xb1[w]; i<=xcross; i++) mostbuf[i] = 0; + } + } + + if (bad&12) + { + //inty = intz / (globaldclip>>16) + t = divscale30(oz1-s3,s4-s3+oz1-oz2); + inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + intz = oz1 + mulscale30(oz2-oz1,t); + xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); + + //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); + //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); + //intz = z1 + mulscale30(z2-z1,t); + + if ((bad&12) == 8) + { + if (xb1[w] <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + //clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=xcross+1; i<=xb2[w]; i++) mostbuf[i] = ydimen; + } + else + { + if (xcross <= xb2[w]) { z1 = intz; iy1 = inty; ix1 = xcross; } + //clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); + for (i=xb1[w]; i<=xcross; i++) mostbuf[i] = ydimen; + } + } + + y = (scale(z1,xdimenscale,iy1)<<4); + yinc = ((scale(z2,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); + qinterpolatedown16short((long)&mostbuf[ix1],ix2-ix1+1,y+(globalhoriz<<16),yinc); + + if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; + if (mostbuf[ix1] > ydimen) mostbuf[ix1] = ydimen; + if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; + if (mostbuf[ix2] > ydimen) mostbuf[ix2] = ydimen; + + return(bad); +} + + +// +// ceilscan (internal) +// +static void ceilscan(long x1, long x2, long sectnum) +{ + long i, j, ox, oy, x, y1, y2, twall, bwall; + sectortype *sec; + + sec = §or[sectnum]; + if (palookup[sec->ceilingpal] != globalpalwritten) + { + globalpalwritten = palookup[sec->ceilingpal]; + if (!globalpalwritten) globalpalwritten = palookup[globalpal]; // JBF: fixes null-pointer crash + setpalookupaddress(globalpalwritten); + } + + globalzd = sec->ceilingz-globalposz; + if (globalzd > 0) return; + globalpicnum = sec->ceilingpicnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs((short)globalpicnum,(short)sectnum); + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + globalbufplc = waloff[globalpicnum]; + + globalshade = (long)sec->ceilingshade; + globvis = globalcisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalorientation = (long)sec->ceilingstat; + + + if ((globalorientation&64) == 0) + { + globalx1 = singlobalang; globalx2 = singlobalang; + globaly1 = cosglobalang; globaly2 = cosglobalang; + globalxpanning = (globalposx<<20); + globalypanning = -(globalposy<<20); + } + else + { + j = sec->wallptr; + ox = wall[wall[j].point2].x - wall[j].x; + oy = wall[wall[j].point2].y - wall[j].y; + i = nsqrtasm(ox*ox+oy*oy); if (i == 0) i = 1024; else i = 1048576/i; + globalx1 = mulscale10(dmulscale10(ox,singlobalang,-oy,cosglobalang),i); + globaly1 = mulscale10(dmulscale10(ox,cosglobalang,oy,singlobalang),i); + globalx2 = -globalx1; + globaly2 = -globaly1; + + ox = ((wall[j].x-globalposx)<<6); oy = ((wall[j].y-globalposy)<<6); + i = dmulscale14(oy,cosglobalang,-ox,singlobalang); + j = dmulscale14(ox,cosglobalang,oy,singlobalang); + ox = i; oy = j; + globalxpanning = globalx1*ox - globaly1*oy; + globalypanning = globaly2*ox + globalx2*oy; + } + globalx2 = mulscale16(globalx2,viewingrangerecip); + globaly1 = mulscale16(globaly1,viewingrangerecip); + globalxshift = (8-(picsiz[globalpicnum]&15)); + globalyshift = (8-(picsiz[globalpicnum]>>4)); + if (globalorientation&8) { globalxshift++; globalyshift++; } + + if ((globalorientation&0x4) > 0) + { + i = globalxpanning; globalxpanning = globalypanning; globalypanning = i; + i = globalx2; globalx2 = -globaly1; globaly1 = -i; + i = globalx1; globalx1 = globaly2; globaly2 = i; + } + if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalxpanning = -globalxpanning; + if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalypanning = -globalypanning; + globalx1 <<= globalxshift; globaly1 <<= globalxshift; + globalx2 <<= globalyshift; globaly2 <<= globalyshift; + globalxpanning <<= globalxshift; globalypanning <<= globalyshift; + globalxpanning += (((long)sec->ceilingxpanning)<<24); + globalypanning += (((long)sec->ceilingypanning)<<24); + globaly1 = (-globalx1-globaly1)*halfxdimen; + globalx2 = (globalx2-globaly2)*halfxdimen; + + sethlinesizes(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4,globalbufplc); + + globalx2 += globaly2*(x1-1); + globaly1 += globalx1*(x1-1); + globalx1 = mulscale16(globalx1,globalzd); + globalx2 = mulscale16(globalx2,globalzd); + globaly1 = mulscale16(globaly1,globalzd); + globaly2 = mulscale16(globaly2,globalzd); + globvis = klabs(mulscale10(globvis,globalzd)); + + if (!(globalorientation&0x180)) + { + y1 = umost[x1]; y2 = y1; + for(x=x1;x<=x2;x++) + { + twall = umost[x]-1; bwall = min(uplc[x],dmost[x]); + if (twall < bwall-1) + { + if (twall >= y2) + { + while (y1 < y2-1) hline(x-1,++y1); + y1 = twall; + } + else + { + while (y1 < twall) hline(x-1,++y1); + while (y1 > twall) lastx[y1--] = x; + } + while (y2 > bwall) hline(x-1,--y2); + while (y2 < bwall) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) hline(x-1,++y1); + if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } + y1 = umost[x+1]; y2 = y1; + } + globalx2 += globaly2; globaly1 += globalx1; + } + while (y1 < y2-1) hline(x2,++y1); + faketimerhandler(); + return; + } + + switch(globalorientation&0x180) + { + case 128: + msethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + case 256: + settransnormal(); + tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + case 384: + settransreverse(); + tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + } + + y1 = umost[x1]; y2 = y1; + for(x=x1;x<=x2;x++) + { + twall = umost[x]-1; bwall = min(uplc[x],dmost[x]); + if (twall < bwall-1) + { + if (twall >= y2) + { + while (y1 < y2-1) slowhline(x-1,++y1); + y1 = twall; + } + else + { + while (y1 < twall) slowhline(x-1,++y1); + while (y1 > twall) lastx[y1--] = x; + } + while (y2 > bwall) slowhline(x-1,--y2); + while (y2 < bwall) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) slowhline(x-1,++y1); + if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } + y1 = umost[x+1]; y2 = y1; + } + globalx2 += globaly2; globaly1 += globalx1; + } + while (y1 < y2-1) slowhline(x2,++y1); + faketimerhandler(); +} + + +// +// florscan (internal) +// +static void florscan(long x1, long x2, long sectnum) +{ + long i, j, ox, oy, x, y1, y2, twall, bwall; + sectortype *sec; + + sec = §or[sectnum]; + if (palookup[sec->floorpal] != globalpalwritten) + { + globalpalwritten = palookup[sec->floorpal]; + if (!globalpalwritten) globalpalwritten = palookup[globalpal]; // JBF: fixes null-pointer crash + setpalookupaddress(globalpalwritten); + } + + globalzd = globalposz-sec->floorz; + if (globalzd > 0) return; + globalpicnum = sec->floorpicnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs((short)globalpicnum,(short)sectnum); + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + globalbufplc = waloff[globalpicnum]; + + globalshade = (long)sec->floorshade; + globvis = globalcisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalorientation = (long)sec->floorstat; + + + if ((globalorientation&64) == 0) + { + globalx1 = singlobalang; globalx2 = singlobalang; + globaly1 = cosglobalang; globaly2 = cosglobalang; + globalxpanning = (globalposx<<20); + globalypanning = -(globalposy<<20); + } + else + { + j = sec->wallptr; + ox = wall[wall[j].point2].x - wall[j].x; + oy = wall[wall[j].point2].y - wall[j].y; + i = nsqrtasm(ox*ox+oy*oy); if (i == 0) i = 1024; else i = 1048576/i; + globalx1 = mulscale10(dmulscale10(ox,singlobalang,-oy,cosglobalang),i); + globaly1 = mulscale10(dmulscale10(ox,cosglobalang,oy,singlobalang),i); + globalx2 = -globalx1; + globaly2 = -globaly1; + + ox = ((wall[j].x-globalposx)<<6); oy = ((wall[j].y-globalposy)<<6); + i = dmulscale14(oy,cosglobalang,-ox,singlobalang); + j = dmulscale14(ox,cosglobalang,oy,singlobalang); + ox = i; oy = j; + globalxpanning = globalx1*ox - globaly1*oy; + globalypanning = globaly2*ox + globalx2*oy; + } + globalx2 = mulscale16(globalx2,viewingrangerecip); + globaly1 = mulscale16(globaly1,viewingrangerecip); + globalxshift = (8-(picsiz[globalpicnum]&15)); + globalyshift = (8-(picsiz[globalpicnum]>>4)); + if (globalorientation&8) { globalxshift++; globalyshift++; } + + if ((globalorientation&0x4) > 0) + { + i = globalxpanning; globalxpanning = globalypanning; globalypanning = i; + i = globalx2; globalx2 = -globaly1; globaly1 = -i; + i = globalx1; globalx1 = globaly2; globaly2 = i; + } + if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalxpanning = -globalxpanning; + if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalypanning = -globalypanning; + globalx1 <<= globalxshift; globaly1 <<= globalxshift; + globalx2 <<= globalyshift; globaly2 <<= globalyshift; + globalxpanning <<= globalxshift; globalypanning <<= globalyshift; + globalxpanning += (((long)sec->floorxpanning)<<24); + globalypanning += (((long)sec->floorypanning)<<24); + globaly1 = (-globalx1-globaly1)*halfxdimen; + globalx2 = (globalx2-globaly2)*halfxdimen; + + sethlinesizes(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4,globalbufplc); + + globalx2 += globaly2*(x1-1); + globaly1 += globalx1*(x1-1); + globalx1 = mulscale16(globalx1,globalzd); + globalx2 = mulscale16(globalx2,globalzd); + globaly1 = mulscale16(globaly1,globalzd); + globaly2 = mulscale16(globaly2,globalzd); + globvis = klabs(mulscale10(globvis,globalzd)); + + if (!(globalorientation&0x180)) + { + y1 = max(dplc[x1],umost[x1]); y2 = y1; + for(x=x1;x<=x2;x++) + { + twall = max(dplc[x],umost[x])-1; bwall = dmost[x]; + if (twall < bwall-1) + { + if (twall >= y2) + { + while (y1 < y2-1) hline(x-1,++y1); + y1 = twall; + } + else + { + while (y1 < twall) hline(x-1,++y1); + while (y1 > twall) lastx[y1--] = x; + } + while (y2 > bwall) hline(x-1,--y2); + while (y2 < bwall) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) hline(x-1,++y1); + if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } + y1 = max(dplc[x+1],umost[x+1]); y2 = y1; + } + globalx2 += globaly2; globaly1 += globalx1; + } + while (y1 < y2-1) hline(x2,++y1); + faketimerhandler(); + return; + } + + switch(globalorientation&0x180) + { + case 128: + msethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + case 256: + settransnormal(); + tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + case 384: + settransreverse(); + tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); + break; + } + + y1 = max(dplc[x1],umost[x1]); y2 = y1; + for(x=x1;x<=x2;x++) + { + twall = max(dplc[x],umost[x])-1; bwall = dmost[x]; + if (twall < bwall-1) + { + if (twall >= y2) + { + while (y1 < y2-1) slowhline(x-1,++y1); + y1 = twall; + } + else + { + while (y1 < twall) slowhline(x-1,++y1); + while (y1 > twall) lastx[y1--] = x; + } + while (y2 > bwall) slowhline(x-1,--y2); + while (y2 < bwall) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) slowhline(x-1,++y1); + if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } + y1 = max(dplc[x+1],umost[x+1]); y2 = y1; + } + globalx2 += globaly2; globaly1 += globalx1; + } + while (y1 < y2-1) slowhline(x2,++y1); + faketimerhandler(); +} + + +// +// wallscan (internal) +// +static void wallscan(long x1, long x2, short *uwal, short *dwal, long *swal, long *lwal) +{ + long i, x, xnice, ynice, fpalookup; + long y1ve[4], y2ve[4], u4, d4, z, tsizx, tsizy; + char bad; + + tsizx = tilesizx[globalpicnum]; + tsizy = tilesizy[globalpicnum]; + setgotpic(globalpicnum); + if ((tsizx <= 0) || (tsizy <= 0)) return; + if ((uwal[x1] > ydimen) && (uwal[x2] > ydimen)) return; + if ((dwal[x1] < 0) && (dwal[x2] < 0)) return; + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + + xnice = (pow2long[picsiz[globalpicnum]&15] == tsizx); + if (xnice) tsizx--; + ynice = (pow2long[picsiz[globalpicnum]>>4] == tsizy); + if (ynice) tsizy = (picsiz[globalpicnum]>>4); + + fpalookup = FP_OFF(palookup[globalpal]); + + setupvlineasm(globalshiftval); + +#ifndef ENGINE_USING_A_C + + x = x1; + while ((umost[x] > dmost[x]) && (x <= x2)) x++; + + for(;(x<=x2)&&((x+frameoffset)&3);x++) + { + y1ve[0] = max(uwal[x],umost[x]); + y2ve[0] = min(dwal[x],dmost[x]); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + vlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],x+frameoffset+ylookup[y1ve[0]]); + } + for(;x<=x2-3;x+=4) + { + bad = 0; + for(z=3;z>=0;z--) + { + y1ve[z] = max(uwal[x+z],umost[x+z]); + y2ve[z] = min(dwal[x+z],dmost[x+z])-1; + if (y2ve[z] < y1ve[z]) { bad += pow2char[z]; continue; } + + i = lwal[x+z] + globalxpanning; + if (i >= tsizx) { if (xnice == 0) i %= tsizx; else i &= tsizx; } + if (ynice == 0) i *= tsizy; else i <<= tsizy; + bufplce[z] = waloff[globalpicnum]+i; + + vince[z] = swal[x+z]*globalyscale; + vplce[z] = globalzd + vince[z]*(y1ve[z]-globalhoriz+1); + } + if (bad == 15) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + palookupoffse[3] = fpalookup+(getpalookup((long)mulscale16(swal[x+3],globvis),globalshade)<<8); + + if ((palookupoffse[0] == palookupoffse[3]) && ((bad&0x9) == 0)) + { + palookupoffse[1] = palookupoffse[0]; + palookupoffse[2] = palookupoffse[0]; + } + else + { + palookupoffse[1] = fpalookup+(getpalookup((long)mulscale16(swal[x+1],globvis),globalshade)<<8); + palookupoffse[2] = fpalookup+(getpalookup((long)mulscale16(swal[x+2],globvis),globalshade)<<8); + } + + u4 = max(max(y1ve[0],y1ve[1]),max(y1ve[2],y1ve[3])); + d4 = min(min(y2ve[0],y2ve[1]),min(y2ve[2],y2ve[3])); + + if ((bad != 0) || (u4 >= d4)) + { + if (!(bad&1)) prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+x+frameoffset+0); + if (!(bad&2)) prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+x+frameoffset+1); + if (!(bad&4)) prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+x+frameoffset+2); + if (!(bad&8)) prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+x+frameoffset+3); + continue; + } + + if (u4 > y1ve[0]) vplce[0] = prevlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+x+frameoffset+0); + if (u4 > y1ve[1]) vplce[1] = prevlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+x+frameoffset+1); + if (u4 > y1ve[2]) vplce[2] = prevlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+x+frameoffset+2); + if (u4 > y1ve[3]) vplce[3] = prevlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+x+frameoffset+3); + + if (d4 >= u4) vlineasm4(d4-u4+1,ylookup[u4]+x+frameoffset); + + i = x+frameoffset+ylookup[d4+1]; + if (y2ve[0] > d4) prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); + if (y2ve[1] > d4) prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); + if (y2ve[2] > d4) prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); + if (y2ve[3] > d4) prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); + } + for(;x<=x2;x++) + { + y1ve[0] = max(uwal[x],umost[x]); + y2ve[0] = min(dwal[x],dmost[x]); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + vlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],x+frameoffset+ylookup[y1ve[0]]); + } + +#else // ENGINE_USING_A_C + + for(x=x1;x<=x2;x++) + { + y1ve[0] = max(uwal[x],umost[x]); + y2ve[0] = min(dwal[x],dmost[x]); + if (y2ve[0] <= y1ve[0]) continue; + + palookupoffse[0] = fpalookup+(getpalookup((long)mulscale16(swal[x],globvis),globalshade)<<8); + + bufplce[0] = lwal[x] + globalxpanning; + if (bufplce[0] >= tsizx) { if (xnice == 0) bufplce[0] %= tsizx; else bufplce[0] &= tsizx; } + if (ynice == 0) bufplce[0] *= tsizy; else bufplce[0] <<= tsizy; + + vince[0] = swal[x]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + + vlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+waloff[globalpicnum],x+frameoffset+ylookup[y1ve[0]]); + } + +#endif + + faketimerhandler(); +} + + +// +// transmaskvline (internal) +// +static void transmaskvline(long x) +{ + long vplc, vinc, p, i, palookupoffs, bufplc; + short y1v, y2v; + + if ((x < 0) || (x >= xdimen)) return; + + y1v = max(uwall[x],startumost[x+windowx1]-windowy1); + y2v = min(dwall[x],startdmost[x+windowx1]-windowy1); + y2v--; + if (y2v < y1v) return; + + palookupoffs = FP_OFF(palookup[globalpal]) + (getpalookup((long)mulscale16(swall[x],globvis),globalshade)<<8); + + vinc = swall[x]*globalyscale; + vplc = globalzd + vinc*(y1v-globalhoriz+1); + + i = lwall[x]+globalxpanning; + if (i >= tilesizx[globalpicnum]) i %= tilesizx[globalpicnum]; + bufplc = waloff[globalpicnum]+i*tilesizy[globalpicnum]; + + p = ylookup[y1v]+x+frameoffset; + + tvlineasm1(vinc,palookupoffs,y2v-y1v,vplc,bufplc,p); +} + + +// +// transmaskvline2 (internal) +// +#ifndef ENGINE_USING_A_C +static void transmaskvline2(long x) +{ + long i, y1, y2, x2; + short y1ve[2], y2ve[2]; + + if ((x < 0) || (x >= xdimen)) return; + if (x == xdimen-1) { transmaskvline(x); return; } + + x2 = x+1; + + y1ve[0] = max(uwall[x],startumost[x+windowx1]-windowy1); + y2ve[0] = min(dwall[x],startdmost[x+windowx1]-windowy1)-1; + if (y2ve[0] < y1ve[0]) { transmaskvline(x2); return; } + y1ve[1] = max(uwall[x2],startumost[x2+windowx1]-windowy1); + y2ve[1] = min(dwall[x2],startdmost[x2+windowx1]-windowy1)-1; + if (y2ve[1] < y1ve[1]) { transmaskvline(x); return; } + + palookupoffse[0] = FP_OFF(palookup[globalpal]) + (getpalookup((long)mulscale16(swall[x],globvis),globalshade)<<8); + palookupoffse[1] = FP_OFF(palookup[globalpal]) + (getpalookup((long)mulscale16(swall[x2],globvis),globalshade)<<8); + + setuptvlineasm2(globalshiftval,palookupoffse[0],palookupoffse[1]); + + vince[0] = swall[x]*globalyscale; + vince[1] = swall[x2]*globalyscale; + vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); + vplce[1] = globalzd + vince[1]*(y1ve[1]-globalhoriz+1); + + i = lwall[x] + globalxpanning; + if (i >= tilesizx[globalpicnum]) i %= tilesizx[globalpicnum]; + bufplce[0] = waloff[globalpicnum]+i*tilesizy[globalpicnum]; + + i = lwall[x2] + globalxpanning; + if (i >= tilesizx[globalpicnum]) i %= tilesizx[globalpicnum]; + bufplce[1] = waloff[globalpicnum]+i*tilesizy[globalpicnum]; + + y1 = max(y1ve[0],y1ve[1]); + y2 = min(y2ve[0],y2ve[1]); + + i = x+frameoffset; + + if (y1ve[0] != y1ve[1]) + { + if (y1ve[0] < y1) + vplce[0] = tvlineasm1(vince[0],palookupoffse[0],y1-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+i); + else + vplce[1] = tvlineasm1(vince[1],palookupoffse[1],y1-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+i+1); + } + + if (y2 > y1) + { + asm1 = vince[1]; + asm2 = ylookup[y2]+i+1; + tvlineasm2(vplce[1],vince[0],bufplce[0],bufplce[1],vplce[0],ylookup[y1]+i); + } + else + { + asm1 = vplce[0]; + asm2 = vplce[1]; + } + + if (y2ve[0] > y2ve[1]) + tvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y2-1,asm1,bufplce[0],ylookup[y2+1]+i); + else if (y2ve[0] < y2ve[1]) + tvlineasm1(vince[1],palookupoffse[1],y2ve[1]-y2-1,asm2,bufplce[1],ylookup[y2+1]+i+1); + + faketimerhandler(); +} +#endif + +// +// transmaskwallscan (internal) +// +static void transmaskwallscan(long x1, long x2) +{ + long x; + + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + + setuptvlineasm(globalshiftval); + + x = x1; + while ((startumost[x+windowx1] > startdmost[x+windowx1]) && (x <= x2)) x++; +#ifndef ENGINE_USING_A_C + if ((x <= x2) && (x&1)) transmaskvline(x), x++; + while (x < x2) transmaskvline2(x), x += 2; +#endif + while (x <= x2) transmaskvline(x), x++; + faketimerhandler(); +} + + +// +// ceilspritehline (internal) +// +static void ceilspritehline(long x2, long y) +{ + long x1, v, bx, by; + + //x = x1 + (x2-x1)t + (y1-y2)u ~ x = 160v + //y = y1 + (y2-y1)t + (x2-x1)u ~ y = (scrx-160)v + //z = z1 = z2 ~ z = posz + (scry-horiz)v + + x1 = lastx[y]; if (x2 < x1) return; + + v = mulscale20(globalzd,horizlookup[y-globalhoriz+horizycent]); + bx = mulscale14(globalx2*x1+globalx1,v) + globalxpanning; + by = mulscale14(globaly2*x1+globaly1,v) + globalypanning; + asm1 = mulscale14(globalx2,v); + asm2 = mulscale14(globaly2,v); + + asm3 = FP_OFF(palookup[globalpal]) + (getpalookup((long)mulscale28(klabs(v),globvis),globalshade)<<8); + + if ((globalorientation&2) == 0) + mhline(globalbufplc,bx,(x2-x1)<<16,0L,by,ylookup[y]+x1+frameoffset); + else + { + thline(globalbufplc,bx,(x2-x1)<<16,0L,by,ylookup[y]+x1+frameoffset); + } +} + + +// +// ceilspritescan (internal) +// +static void ceilspritescan(long x1, long x2) +{ + long x, y1, y2, twall, bwall; + + y1 = uwall[x1]; y2 = y1; + for(x=x1;x<=x2;x++) + { + twall = uwall[x]-1; bwall = dwall[x]; + if (twall < bwall-1) + { + if (twall >= y2) + { + while (y1 < y2-1) ceilspritehline(x-1,++y1); + y1 = twall; + } + else + { + while (y1 < twall) ceilspritehline(x-1,++y1); + while (y1 > twall) lastx[y1--] = x; + } + while (y2 > bwall) ceilspritehline(x-1,--y2); + while (y2 < bwall) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) ceilspritehline(x-1,++y1); + if (x == x2) break; + y1 = uwall[x+1]; y2 = y1; + } + } + while (y1 < y2-1) ceilspritehline(x2,++y1); + faketimerhandler(); +} + + +// +// grouscan (internal) +// +#define BITSOFPRECISION 3 //Don't forget to change this in A.ASM also! +static void grouscan(long dax1, long dax2, long sectnum, char dastat) +{ + long i, j, l, x, y, dx, dy, wx, wy, y1, y2, daz; + long daslope, dasqr; + long shoffs, shinc, m1, m2, *mptr1, *mptr2, *nptr1, *nptr2; + walltype *wal; + sectortype *sec; + + sec = §or[sectnum]; + + if (dastat == 0) + { + if (globalposz <= getceilzofslope(sectnum,globalposx,globalposy)) + return; //Back-face culling + globalorientation = sec->ceilingstat; + globalpicnum = sec->ceilingpicnum; + globalshade = sec->ceilingshade; + globalpal = sec->ceilingpal; + daslope = sec->ceilingheinum; + daz = sec->ceilingz; + } + else + { + if (globalposz >= getflorzofslope(sectnum,globalposx,globalposy)) + return; //Back-face culling + globalorientation = sec->floorstat; + globalpicnum = sec->floorpicnum; + globalshade = sec->floorshade; + globalpal = sec->floorpal; + daslope = sec->floorheinum; + daz = sec->floorz; + } + + if ((picanm[globalpicnum]&192) != 0) globalpicnum += animateoffs(globalpicnum,sectnum); + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + + wal = &wall[sec->wallptr]; + wx = wall[wal->point2].x - wal->x; + wy = wall[wal->point2].y - wal->y; + dasqr = krecipasm(nsqrtasm(wx*wx+wy*wy)); + i = mulscale21(daslope,dasqr); + wx *= i; wy *= i; + + globalx = -mulscale19(singlobalang,xdimenrecip); + globaly = mulscale19(cosglobalang,xdimenrecip); + globalx1 = (globalposx<<8); + globaly1 = -(globalposy<<8); + i = (dax1-halfxdimen)*xdimenrecip; + globalx2 = mulscale16(cosglobalang<<4,viewingrangerecip) - mulscale27(singlobalang,i); + globaly2 = mulscale16(singlobalang<<4,viewingrangerecip) + mulscale27(cosglobalang,i); + globalzd = (xdimscale<<9); + globalzx = -dmulscale17(wx,globaly2,-wy,globalx2) + mulscale10(1-globalhoriz,globalzd); + globalz = -dmulscale25(wx,globaly,-wy,globalx); + + if (globalorientation&64) //Relative alignment + { + dx = mulscale14(wall[wal->point2].x-wal->x,dasqr); + dy = mulscale14(wall[wal->point2].y-wal->y,dasqr); + + i = nsqrtasm(daslope*daslope+16777216); + + x = globalx; y = globaly; + globalx = dmulscale16(x,dx,y,dy); + globaly = mulscale12(dmulscale16(-y,dx,x,dy),i); + + x = ((wal->x-globalposx)<<8); y = ((wal->y-globalposy)<<8); + globalx1 = dmulscale16(-x,dx,-y,dy); + globaly1 = mulscale12(dmulscale16(-y,dx,x,dy),i); + + x = globalx2; y = globaly2; + globalx2 = dmulscale16(x,dx,y,dy); + globaly2 = mulscale12(dmulscale16(-y,dx,x,dy),i); + } + if (globalorientation&0x4) + { + i = globalx; globalx = -globaly; globaly = -i; + i = globalx1; globalx1 = globaly1; globaly1 = i; + i = globalx2; globalx2 = -globaly2; globaly2 = -i; + } + if (globalorientation&0x10) { globalx1 = -globalx1, globalx2 = -globalx2, globalx = -globalx; } + if (globalorientation&0x20) { globaly1 = -globaly1, globaly2 = -globaly2, globaly = -globaly; } + + daz = dmulscale9(wx,globalposy-wal->y,-wy,globalposx-wal->x) + ((daz-globalposz)<<8); + globalx2 = mulscale20(globalx2,daz); globalx = mulscale28(globalx,daz); + globaly2 = mulscale20(globaly2,-daz); globaly = mulscale28(globaly,-daz); + + i = 8-(picsiz[globalpicnum]&15); j = 8-(picsiz[globalpicnum]>>4); + if (globalorientation&8) { i++; j++; } + globalx1 <<= (i+12); globalx2 <<= i; globalx <<= i; + globaly1 <<= (j+12); globaly2 <<= j; globaly <<= j; + + if (dastat == 0) + { + globalx1 += (((long)sec->ceilingxpanning)<<24); + globaly1 += (((long)sec->ceilingypanning)<<24); + } + else + { + globalx1 += (((long)sec->floorxpanning)<<24); + globaly1 += (((long)sec->floorypanning)<<24); + } + + asm1 = -(globalzd>>(16-BITSOFPRECISION)); + + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globvis = mulscale13(globvis,daz); + globvis = mulscale16(globvis,xdimscale); + j = FP_OFF(palookup[globalpal]); + + setupslopevlin(((long)(picsiz[globalpicnum]&15))+(((long)(picsiz[globalpicnum]>>4))<<8),waloff[globalpicnum],-ylookup[1]); + + l = (globalzd>>16); + + shinc = mulscale16(globalz,xdimenscale); + if (shinc > 0) shoffs = (4<<15); else shoffs = ((16380-ydimen)<<15); // JBF: was 2044 + if (dastat == 0) y1 = umost[dax1]; else y1 = max(umost[dax1],dplc[dax1]); + m1 = mulscale16(y1,globalzd) + (globalzx>>6); + //Avoid visibility overflow by crossing horizon + if (globalzd > 0) m1 += (globalzd>>16); else m1 -= (globalzd>>16); + m2 = m1+l; + mptr1 = (long *)&slopalookup[y1+(shoffs>>15)]; mptr2 = mptr1+1; + + for(x=dax1;x<=dax2;x++) + { + if (dastat == 0) { y1 = umost[x]; y2 = min(dmost[x],uplc[x])-1; } + else { y1 = max(umost[x],dplc[x]); y2 = dmost[x]-1; } + if (y1 <= y2) + { + nptr1 = (long *)&slopalookup[y1+(shoffs>>15)]; + nptr2 = (long *)&slopalookup[y2+(shoffs>>15)]; + while (nptr1 <= mptr1) + { + *mptr1-- = j + (getpalookup((long)mulscale24(krecipasm(m1),globvis),globalshade)<<8); + m1 -= l; + } + while (nptr2 >= mptr2) + { + *mptr2++ = j + (getpalookup((long)mulscale24(krecipasm(m2),globvis),globalshade)<<8); + m2 += l; + } + + globalx3 = (globalx2>>10); + globaly3 = (globaly2>>10); + asm3 = mulscale16(y2,globalzd) + (globalzx>>6); + slopevlin(ylookup[y2]+x+frameoffset,krecipasm(asm3>>3),(long)nptr2,y2-y1+1,globalx1,globaly1); + + if ((x&15) == 0) faketimerhandler(); + } + globalx2 += globalx; + globaly2 += globaly; + globalzx += globalz; + shoffs += shinc; + } +} + + +// +// parascan (internal) +// +static void parascan(long dax1, long dax2, long sectnum, char dastat, long bunch) +{ + sectortype *sec; + long j, k, l, m, n, x, z, wallnum, nextsectnum, globalhorizbak; + short *topptr, *botptr; + + sectnum = thesector[bunchfirst[bunch]]; sec = §or[sectnum]; + + globalhorizbak = globalhoriz; + if (parallaxyscale != 65536) + globalhoriz = mulscale16(globalhoriz-(ydimen>>1),parallaxyscale) + (ydimen>>1); + globvis = globalpisibility; + //globalorientation = 0L; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + + if (dastat == 0) + { + globalpal = sec->ceilingpal; + globalpicnum = sec->ceilingpicnum; + globalshade = (long)sec->ceilingshade; + globalxpanning = (long)sec->ceilingxpanning; + globalypanning = (long)sec->ceilingypanning; + topptr = umost; + botptr = uplc; + } + else + { + globalpal = sec->floorpal; + globalpicnum = sec->floorpicnum; + globalshade = (long)sec->floorshade; + globalxpanning = (long)sec->floorxpanning; + globalypanning = (long)sec->floorypanning; + topptr = dplc; + botptr = dmost; + } + + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)sectnum); + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalzd = (((tilesizy[globalpicnum]>>1)+parallaxyoffs)<=0;z=p2[z]) + { + wallnum = thewall[z]; nextsectnum = wall[wallnum].nextsector; + + if (dastat == 0) j = sector[nextsectnum].ceilingstat; + else j = sector[nextsectnum].floorstat; + + if ((nextsectnum < 0) || (wall[wallnum].cstat&32) || ((j&1) == 0)) + { + if (x == -1) x = xb1[z]; + + if (parallaxtype == 0) + { + n = mulscale16(xdimenrecip,viewingrange); + for(j=xb1[z];j<=xb2[z];j++) + lplc[j] = (((mulscale23(j-halfxdimen,n)+globalang)&2047)>>k); + } + else + { + for(j=xb1[z];j<=xb2[z];j++) + lplc[j] = ((((long)radarang2[j]+globalang)&2047)>>k); + } + if (parallaxtype == 2) + { + n = mulscale16(xdimscale,viewingrange); + for(j=xb1[z];j<=xb2[z];j++) + swplc[j] = mulscale14(sintable[((long)radarang2[j]+512)&2047],n); + } + else + clearbuf(&swplc[xb1[z]],xb2[z]-xb1[z]+1,mulscale16(xdimscale,viewingrange)); + } + else if (x >= 0) + { + l = globalpicnum; m = (picsiz[globalpicnum]&15); + globalpicnum = l+pskyoff[lplc[x]>>m]; + + if (((lplc[x]^lplc[xb1[z]-1])>>m) == 0) + wallscan(x,xb1[z]-1,topptr,botptr,swplc,lplc); + else + { + j = x; + while (x < xb1[z]) + { + n = l+pskyoff[lplc[x]>>m]; + if (n != globalpicnum) + { + wallscan(j,x-1,topptr,botptr,swplc,lplc); + j = x; + globalpicnum = n; + } + x++; + } + if (j < x) + wallscan(j,x-1,topptr,botptr,swplc,lplc); + } + + globalpicnum = l; + x = -1; + } + } + + if (x >= 0) + { + l = globalpicnum; m = (picsiz[globalpicnum]&15); + globalpicnum = l+pskyoff[lplc[x]>>m]; + + if (((lplc[x]^lplc[xb2[bunchlast[bunch]]])>>m) == 0) + wallscan(x,xb2[bunchlast[bunch]],topptr,botptr,swplc,lplc); + else + { + j = x; + while (x <= xb2[bunchlast[bunch]]) + { + n = l+pskyoff[lplc[x]>>m]; + if (n != globalpicnum) + { + wallscan(j,x-1,topptr,botptr,swplc,lplc); + j = x; + globalpicnum = n; + } + x++; + } + if (j <= x) + wallscan(j,x,topptr,botptr,swplc,lplc); + } + globalpicnum = l; + } + globalhoriz = globalhorizbak; +} + + +// +// drawalls (internal) +// +static void drawalls(long bunch) +{ + sectortype *sec, *nextsec; + walltype *wal; + long i, x, x1, x2, cz[5], fz[5]; + long z, wallnum, sectnum, nextsectnum; + long startsmostwallcnt, startsmostcnt, gotswall; + char andwstat1, andwstat2; + + z = bunchfirst[bunch]; + sectnum = thesector[z]; sec = §or[sectnum]; + + andwstat1 = 0xff; andwstat2 = 0xff; + for(;z>=0;z=p2[z]) //uplc/dplc calculation + { + andwstat1 &= wallmost(uplc,z,sectnum,(char)0); + andwstat2 &= wallmost(dplc,z,sectnum,(char)1); + } + + if ((andwstat1&3) != 3) //draw ceilings + { + if ((sec->ceilingstat&3) == 2) + grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0); + else if ((sec->ceilingstat&1) == 0) + ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); + else + parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch); + } + if ((andwstat2&12) != 12) //draw floors + { + if ((sec->floorstat&3) == 2) + grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1); + else if ((sec->floorstat&1) == 0) + florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); + else + parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch); + } + + //DRAW WALLS SECTION! + for(z=bunchfirst[bunch];z>=0;z=p2[z]) + { + x1 = xb1[z]; x2 = xb2[z]; + if (umost[x2] >= dmost[x2]) + { + for(x=x1;x= x2) + { + smostwall[smostwallcnt] = z; + smostwalltype[smostwallcnt] = 0; + smostwallcnt++; + continue; + } + } + + wallnum = thewall[z]; wal = &wall[wallnum]; + nextsectnum = wal->nextsector; nextsec = §or[nextsectnum]; + + gotswall = 0; + + startsmostwallcnt = smostwallcnt; + startsmostcnt = smostcnt; + + if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) + { + if (searchy <= uplc[searchx]) //ceiling + { + searchsector = sectnum; searchwall = wallnum; + searchstat = 1; searchit = 1; + } + else if (searchy >= dplc[searchx]) //floor + { + searchsector = sectnum; searchwall = wallnum; + searchstat = 2; searchit = 1; + } + } + + if (nextsectnum >= 0) + { + getzsofslope((short)sectnum,wal->x,wal->y,&cz[0],&fz[0]); + getzsofslope((short)sectnum,wall[wal->point2].x,wall[wal->point2].y,&cz[1],&fz[1]); + getzsofslope((short)nextsectnum,wal->x,wal->y,&cz[2],&fz[2]); + getzsofslope((short)nextsectnum,wall[wal->point2].x,wall[wal->point2].y,&cz[3],&fz[3]); + getzsofslope((short)nextsectnum,globalposx,globalposy,&cz[4],&fz[4]); + + if ((wal->cstat&48) == 16) maskwall[maskwallcnt++] = z; + + if (((sec->ceilingstat&1) == 0) || ((nextsec->ceilingstat&1) == 0)) + { + if ((cz[2] <= cz[0]) && (cz[3] <= cz[1])) + { + if (globparaceilclip) + for(x=x1;x<=x2;x++) + if (uplc[x] > umost[x]) + if (umost[x] <= dmost[x]) + { + umost[x] = uplc[x]; + if (umost[x] > dmost[x]) numhits--; + } + } + else + { + wallmost(dwall,z,nextsectnum,(char)0); + if ((cz[2] > fz[0]) || (cz[3] > fz[1])) + for(i=x1;i<=x2;i++) if (dwall[i] > dplc[i]) dwall[i] = dplc[i]; + + if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) + if (searchy <= dwall[searchx]) //wall + { + searchsector = sectnum; searchwall = wallnum; + searchstat = 0; searchit = 1; + } + + globalorientation = (long)wal->cstat; + globalpicnum = wal->picnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = (long)wal->xpanning; + globalypanning = (long)wal->ypanning; + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)wallnum+16384); + globalshade = (long)wal->shade; + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalpal = (long)wal->pal; + if (palookup[globalpal] == 0) globalpal = 0; // JBF: fixes crash + globalyscale = (wal->yrepeat<<(globalshiftval-19)); + if ((globalorientation&4) == 0) + globalzd = (((globalposz-nextsec->ceilingz)*globalyscale)<<8); + else + globalzd = (((globalposz-sec->ceilingz)*globalyscale)<<8); + globalzd += (globalypanning<<24); + if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; + + if (gotswall == 0) { gotswall = 1; prepwall(z,wal); } + wallscan(x1,x2,uplc,dwall,swall,lwall); + + if ((cz[2] >= cz[0]) && (cz[3] >= cz[1])) + { + for(x=x1;x<=x2;x++) + if (dwall[x] > umost[x]) + if (umost[x] <= dmost[x]) + { + umost[x] = dwall[x]; + if (umost[x] > dmost[x]) numhits--; + } + } + else + { + for(x=x1;x<=x2;x++) + if (umost[x] <= dmost[x]) + { + i = max(uplc[x],dwall[x]); + if (i > umost[x]) + { + umost[x] = i; + if (umost[x] > dmost[x]) numhits--; + } + } + } + } + if ((cz[2] < cz[0]) || (cz[3] < cz[1]) || (globalposz < cz[4])) + { + i = x2-x1+1; + if (smostcnt+i < MAXYSAVES) + { + smoststart[smostwallcnt] = smostcnt; + smostwall[smostwallcnt] = z; + smostwalltype[smostwallcnt] = 1; //1 for umost + smostwallcnt++; + copybufbyte(&umost[x1],&smost[smostcnt],i*sizeof(smost[0])); + smostcnt += i; + } + } + } + if (((sec->floorstat&1) == 0) || ((nextsec->floorstat&1) == 0)) + { + if ((fz[2] >= fz[0]) && (fz[3] >= fz[1])) + { + if (globparaflorclip) + for(x=x1;x<=x2;x++) + if (dplc[x] < dmost[x]) + if (umost[x] <= dmost[x]) + { + dmost[x] = dplc[x]; + if (umost[x] > dmost[x]) numhits--; + } + } + else + { + wallmost(uwall,z,nextsectnum,(char)1); + if ((fz[2] < cz[0]) || (fz[3] < cz[1])) + for(i=x1;i<=x2;i++) if (uwall[i] < uplc[i]) uwall[i] = uplc[i]; + + if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) + if (searchy >= uwall[searchx]) //wall + { + searchsector = sectnum; searchwall = wallnum; + if ((wal->cstat&2) > 0) searchwall = wal->nextwall; + searchstat = 0; searchit = 1; + } + + if ((wal->cstat&2) > 0) + { + wallnum = wal->nextwall; wal = &wall[wallnum]; + globalorientation = (long)wal->cstat; + globalpicnum = wal->picnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = (long)wal->xpanning; + globalypanning = (long)wal->ypanning; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)wallnum+16384); + globalshade = (long)wal->shade; + globalpal = (long)wal->pal; + wallnum = thewall[z]; wal = &wall[wallnum]; + } + else + { + globalorientation = (long)wal->cstat; + globalpicnum = wal->picnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = (long)wal->xpanning; + globalypanning = (long)wal->ypanning; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)wallnum+16384); + globalshade = (long)wal->shade; + globalpal = (long)wal->pal; + } + if (palookup[globalpal] == 0) globalpal = 0; // JBF: fixes crash + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalyscale = (wal->yrepeat<<(globalshiftval-19)); + if ((globalorientation&4) == 0) + globalzd = (((globalposz-nextsec->floorz)*globalyscale)<<8); + else + globalzd = (((globalposz-sec->ceilingz)*globalyscale)<<8); + globalzd += (globalypanning<<24); + if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; + + if (gotswall == 0) { gotswall = 1; prepwall(z,wal); } + wallscan(x1,x2,uwall,dplc,swall,lwall); + + if ((fz[2] <= fz[0]) && (fz[3] <= fz[1])) + { + for(x=x1;x<=x2;x++) + if (uwall[x] < dmost[x]) + if (umost[x] <= dmost[x]) + { + dmost[x] = uwall[x]; + if (umost[x] > dmost[x]) numhits--; + } + } + else + { + for(x=x1;x<=x2;x++) + if (umost[x] <= dmost[x]) + { + i = min(dplc[x],uwall[x]); + if (i < dmost[x]) + { + dmost[x] = i; + if (umost[x] > dmost[x]) numhits--; + } + } + } + } + if ((fz[2] > fz[0]) || (fz[3] > fz[1]) || (globalposz > fz[4])) + { + i = x2-x1+1; + if (smostcnt+i < MAXYSAVES) + { + smoststart[smostwallcnt] = smostcnt; + smostwall[smostwallcnt] = z; + smostwalltype[smostwallcnt] = 2; //2 for dmost + smostwallcnt++; + copybufbyte(&dmost[x1],&smost[smostcnt],i*sizeof(smost[0])); + smostcnt += i; + } + } + } + if (numhits < 0) return; + if ((!(wal->cstat&32)) && ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)) + { + if (umost[x2] < dmost[x2]) + scansector(nextsectnum); + else + { + for(x=x1;xcstat&32)) //White/1-way wall + { + globalorientation = (long)wal->cstat; + if (nextsectnum < 0) globalpicnum = wal->picnum; + else globalpicnum = wal->overpicnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = (long)wal->xpanning; + globalypanning = (long)wal->ypanning; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)wallnum+16384); + globalshade = (long)wal->shade; + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalpal = (long)wal->pal; + if (palookup[globalpal] == 0) globalpal = 0; // JBF: fixes crash + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalyscale = (wal->yrepeat<<(globalshiftval-19)); + if (nextsectnum >= 0) + { + if ((globalorientation&4) == 0) globalzd = globalposz-nextsec->ceilingz; + else globalzd = globalposz-sec->ceilingz; + } + else + { + if ((globalorientation&4) == 0) globalzd = globalposz-sec->ceilingz; + else globalzd = globalposz-sec->floorz; + } + globalzd = ((globalzd*globalyscale)<<8) + (globalypanning<<24); + if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; + + if (gotswall == 0) { gotswall = 1; prepwall(z,wal); } + wallscan(x1,x2,uplc,dplc,swall,lwall); + + for(x=x1;x<=x2;x++) + if (umost[x] <= dmost[x]) + { umost[x] = 1; dmost[x] = 0; numhits--; } + smostwall[smostwallcnt] = z; + smostwalltype[smostwallcnt] = 0; + smostwallcnt++; + + if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) + { + searchit = 1; searchsector = sectnum; searchwall = wallnum; + if (nextsectnum < 0) searchstat = 0; else searchstat = 4; + } + } + } +} + + +// +// drawvox +// +#ifdef SUPERBUILD +static void drawvox(long dasprx, long daspry, long dasprz, long dasprang, + long daxscale, long dayscale, char daindex, + signed char dashade, char dapal, long *daumost, long *dadmost) +{ + long i, j, k, x, y, syoff, ggxstart, ggystart, nxoff; + long cosang, sinang, sprcosang, sprsinang, backx, backy, gxinc, gyinc; + long daxsiz, daysiz, dazsiz, daxpivot, daypivot, dazpivot; + long daxscalerecip, dayscalerecip, cnt, gxstart, gystart, odayscale; + long l1, l2, slabxoffs, xyvoxoffs, *longptr; + long lx, rx, nx, ny, x1=0, y1=0, z1, x2=0, y2=0, z2, yplc, yinc=0; + long yoff, xs=0, ys=0, xe, ye, xi=0, yi=0, cbackx, cbacky, dagxinc, dagyinc; + short *shortptr; + char *voxptr, *voxend, *davoxptr, oand, oand16, oand32; + + cosang = sintable[(globalang+512)&2047]; + sinang = sintable[globalang&2047]; + sprcosang = sintable[(dasprang+512)&2047]; + sprsinang = sintable[dasprang&2047]; + + i = klabs(dmulscale6(dasprx-globalposx,cosang,daspry-globalposy,sinang)); + j = (long)(getpalookup((long)mulscale21(globvis,i),(long)dashade)<<8); + setupdrawslab(ylookup[1],FP_OFF(palookup[dapal])+j); + j = 1310720; + j *= min(daxscale,dayscale); j >>= 6; //New hacks (for sized-down voxels) + for(k=0;k= MAXVOXMIPS) i = MAXVOXMIPS-1; + + if (novoxmips) i = 0; + davoxptr = (char *)voxoff[daindex][i]; + if (!davoxptr && i > 0) { davoxptr = (char *)voxoff[daindex][0]; i = 0; } + if (!davoxptr) return; + + if (voxscale[daindex] == 65536) + { daxscale <<= (i+8); dayscale <<= (i+8); } + else + { + daxscale = mulscale8(daxscale<>8); + backy = ((dmulscale10(y,sprcosang,x,-sprsinang)+daypivot)>>8); + cbackx = min(max(backx,0),daxsiz-1); + cbacky = min(max(backy,0),daysiz-1); + + sprcosang = mulscale14(daxscale,sprcosang); + sprsinang = mulscale14(daxscale,sprsinang); + + x = (dasprx-globalposx) - dmulscale18(daxpivot,sprcosang,daypivot,-sprsinang); + y = (daspry-globalposy) - dmulscale18(daypivot,sprcosang,daxpivot,sprsinang); + + cosang = mulscale16(cosang,dayscalerecip); + sinang = mulscale16(sinang,dayscalerecip); + + gxstart = y*cosang - x*sinang; + gystart = x*cosang + y*sinang; + gxinc = dmulscale10(sprsinang,cosang,sprcosang,-sinang); + gyinc = dmulscale10(sprcosang,cosang,sprsinang,sinang); + + x = 0; y = 0; j = max(daxsiz,daysiz); + for(i=0;i<=j;i++) + { + ggxinc[i] = x; x += gxinc; + ggyinc[i] = y; y += gyinc; + } + + if ((klabs(globalposz-dasprz)>>10) >= klabs(odayscale)) return; + syoff = divscale21(globalposz-dasprz,odayscale) + (dazpivot<<7); + yoff = ((klabs(gxinc)+klabs(gyinc))>>1); + longptr = (long *)davoxptr; + xyvoxoffs = ((daxsiz+1)<<2); + + begindrawing(); //{{{ + + for(cnt=0;cnt<8;cnt++) + { + switch(cnt) + { + case 0: xs = 0; ys = 0; xi = 1; yi = 1; break; + case 1: xs = daxsiz-1; ys = 0; xi = -1; yi = 1; break; + case 2: xs = 0; ys = daysiz-1; xi = 1; yi = -1; break; + case 3: xs = daxsiz-1; ys = daysiz-1; xi = -1; yi = -1; break; + case 4: xs = 0; ys = cbacky; xi = 1; yi = 2; break; + case 5: xs = daxsiz-1; ys = cbacky; xi = -1; yi = 2; break; + case 6: xs = cbackx; ys = 0; xi = 2; yi = 1; break; + case 7: xs = cbackx; ys = daysiz-1; xi = 2; yi = -1; break; + } + xe = cbackx; ye = cbacky; + if (cnt < 4) + { + if ((xi < 0) && (xe >= xs)) continue; + if ((xi > 0) && (xe <= xs)) continue; + if ((yi < 0) && (ye >= ys)) continue; + if ((yi > 0) && (ye <= ys)) continue; + } + else + { + if ((xi < 0) && (xe > xs)) continue; + if ((xi > 0) && (xe < xs)) continue; + if ((yi < 0) && (ye > ys)) continue; + if ((yi > 0) && (ye < ys)) continue; + xe += xi; ye += yi; + } + + i = ksgn(ys-backy)+ksgn(xs-backx)*3+4; + switch(i) + { + case 6: case 7: x1 = 0; y1 = 0; break; + case 8: case 5: x1 = gxinc; y1 = gyinc; break; + case 0: case 3: x1 = gyinc; y1 = -gxinc; break; + case 2: case 1: x1 = gxinc+gyinc; y1 = gyinc-gxinc; break; + } + switch(i) + { + case 2: case 5: x2 = 0; y2 = 0; break; + case 0: case 1: x2 = gxinc; y2 = gyinc; break; + case 8: case 7: x2 = gyinc; y2 = -gxinc; break; + case 6: case 3: x2 = gxinc+gyinc; y2 = gyinc-gxinc; break; + } + oand = pow2char[(xs 0) { dagxinc = gxinc; dagyinc = mulscale16(gyinc,viewingrangerecip); } + else { dagxinc = -gxinc; dagyinc = -mulscale16(gyinc,viewingrangerecip); } + + //Fix for non 90 degree viewing ranges + nxoff = mulscale16(x2-x1,viewingrangerecip); + x1 = mulscale16(x1,viewingrangerecip); + + ggxstart = gxstart+ggyinc[ys]; + ggystart = gystart-ggxinc[ys]; + + for(x=xs;x!=xe;x+=xi) + { + slabxoffs = (long)&davoxptr[B_LITTLE32(longptr[x])]; + shortptr = (short *)&davoxptr[((x*(daysiz+1))<<1)+xyvoxoffs]; + + nx = mulscale16(ggxstart+ggxinc[x],viewingrangerecip)+x1; + ny = ggystart+ggyinc[x]; + for(y=ys;y!=ye;y+=yi,nx+=dagyinc,ny-=dagxinc) + { + if ((ny <= nytooclose) || (ny >= nytoofar)) continue; + voxptr = (char *)(B_LITTLE16(shortptr[y])+slabxoffs); + voxend = (char *)(B_LITTLE16(shortptr[y+1])+slabxoffs); + if (voxptr == voxend) continue; + + lx = mulscale32(nx>>3,distrecip[(ny+y1)>>14])+halfxdimen; + if (lx < 0) lx = 0; + rx = mulscale32((nx+nxoff)>>3,distrecip[(ny+y2)>>14])+halfxdimen; + if (rx > xdimen) rx = xdimen; + if (rx <= lx) continue; + rx -= lx; + + l1 = distrecip[(ny-yoff)>>14]; + l2 = distrecip[(ny+yoff)>>14]; + for(;voxptr= 1024) yinc = divscale16(voxptr[1],z2-z1); + else if (z2 > z1) yinc = (lowrecip[z2-z1]*voxptr[1]>>8); + if (z1 < daumost[lx]) { yplc = yinc*(daumost[lx]-z1); z1 = daumost[lx]; } else yplc = 0; + } + if (z2 > dadmost[lx]) z2 = dadmost[lx]; + z2 -= z1; if (z2 <= 0) continue; + + drawslab(rx,yplc,z2,yinc,(long)&voxptr[3],ylookup[z1]+lx+frameoffset); + } + } + } + } + + enddrawing(); //}}} +} +#endif + + +// +// drawsprite (internal) +// +static void drawsprite(long snum) +{ + spritetype *tspr; + sectortype *sec; + long startum, startdm, sectnum, xb, yp, cstat; + long siz, xsiz, ysiz, xoff, yoff, xspan, yspan; + long x1, y1, x2, y2, lx, rx, dalx2, darx2, i, j, k, x, linum, linuminc; + long yinc, z, z1, z2, xp1, yp1, xp2, yp2; + long xv, yv, top, topinc, bot, botinc, hplc, hinc; + long cosang, sinang, dax, day, lpoint, lmax, rpoint, rmax, dax1, dax2, y; + long npoints, npoints2, zz, t, zsgn, zzsgn, *longptr; + long tilenum, vtilenum = 0, spritenum; + char swapped, daclip; + + //============================================================================= //POLYMOST BEGINS +#ifdef POLYMOST + if (rendmode) { polymost_drawsprite(snum); return; } +#endif + //============================================================================= //POLYMOST ENDS + + tspr = tspriteptr[snum]; + + xb = spritesx[snum]; + yp = spritesy[snum]; + tilenum = tspr->picnum; + spritenum = tspr->owner; + cstat = tspr->cstat; + +#ifdef SUPERBUILD + if ((cstat&48)==48) vtilenum = tilenum; // if the game wants voxels, it gets voxels + else if ((cstat&48)!=48 && (usevoxels) && (tiletovox[tilenum] != -1) +#if defined(POLYMOST) && defined(USE_OPENGL) + && (!(spriteext[tspr->owner].flags&SPREXT_NOTMD)) +#endif + ) { + vtilenum = tiletovox[tilenum]; + cstat |= 48; + } +#endif + + if ((cstat&48) != 48) + { + if (picanm[tilenum]&192) tilenum += animateoffs(tilenum,spritenum+32768); + if ((tilesizx[tilenum] <= 0) || (tilesizy[tilenum] <= 0) || (spritenum < 0)) + return; + } + if ((tspr->xrepeat <= 0) || (tspr->yrepeat <= 0)) return; + + sectnum = tspr->sectnum; sec = §or[sectnum]; + globalpal = tspr->pal; + if (palookup[globalpal] == 0) globalpal = 0; // JBF: fixes null-pointer crash + globalshade = tspr->shade; + if (cstat&2) + { + if (cstat&512) settransreverse(); else settransnormal(); + } + + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)tspr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)tspr->yoffset); + + if ((cstat&48) == 0) + { + if (yp <= (4<<8)) return; + + siz = divscale19(xdimenscale,yp); + + xv = mulscale16(((long)tspr->xrepeat)<<16,xyaspect); + + xspan = tilesizx[tilenum]; + yspan = tilesizy[tilenum]; + xsiz = mulscale30(siz,xv*xspan); + ysiz = mulscale14(siz,tspr->yrepeat*yspan); + + if (((tilesizx[tilenum]>>11) >= xsiz) || (yspan >= (ysiz>>1))) + return; //Watch out for divscale overflow + + x1 = xb-(xsiz>>1); + if (xspan&1) x1 += mulscale31(siz,xv); //Odd xspans + i = mulscale30(siz,xv*xoff); + if ((cstat&4) == 0) x1 -= i; else x1 += i; + + y1 = mulscale16(tspr->z-globalposz,siz); + y1 -= mulscale14(siz,tspr->yrepeat*yoff); + y1 += (globalhoriz<<8)-ysiz; + if (cstat&128) + { + y1 += (ysiz>>1); + if (yspan&1) y1 += mulscale15(siz,tspr->yrepeat); //Odd yspans + } + + x2 = x1+xsiz-1; + y2 = y1+ysiz-1; + if ((y1|255) >= (y2|255)) return; + + lx = (x1>>8)+1; if (lx < 0) lx = 0; + rx = (x2>>8); if (rx >= xdimen) rx = xdimen-1; + if (lx > rx) return; + + yinc = divscale32(yspan,ysiz); + + if ((sec->ceilingstat&3) == 0) + startum = globalhoriz+mulscale24(siz,sec->ceilingz-globalposz)-1; + else + startum = 0; + if ((sec->floorstat&3) == 0) + startdm = globalhoriz+mulscale24(siz,sec->floorz-globalposz)+1; + else + startdm = 0x7fffffff; + if ((y1>>8) > startum) startum = (y1>>8); + if ((y2>>8) < startdm) startdm = (y2>>8); + + if (startum < -32768) startum = -32768; + if (startdm > 32767) startdm = 32767; + if (startum >= startdm) return; + + if ((cstat&4) == 0) + { + linuminc = divscale24(xspan,xsiz); + linum = mulscale8((lx<<8)-x1,linuminc); + } + else + { + linuminc = -divscale24(xspan,xsiz); + linum = mulscale8((lx<<8)-x2,linuminc); + } + if ((cstat&8) > 0) + { + yinc = -yinc; + i = y1; y1 = y2; y2 = i; + } + + for(x=lx;x<=rx;x++) + { + uwall[x] = max(startumost[x+windowx1]-windowy1,(short)startum); + dwall[x] = min(startdmost[x+windowx1]-windowy1,(short)startdm); + } + daclip = 0; + for(i=smostwallcnt-1;i>=0;i--) + { + if (smostwalltype[i]&daclip) continue; + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + if (spritewallfront(tspr,(long)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; + + dalx2 = max(xb1[j],lx); darx2 = min(xb2[j],rx); + + switch(smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (k=dalx2; k<=darx2; k++) dwall[k] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + if ((dalx2 == lx) && (darx2 == rx)) daclip |= 1; + break; + case 2: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + if ((dalx2 == lx) && (darx2 == rx)) daclip |= 2; + break; + } + } + + if (uwall[rx] >= dwall[rx]) + { + for(x=lx;x= 1) && (searchx >= lx) && (searchx <= rx)) + if ((searchy >= uwall[searchx]) && (searchy < dwall[searchx])) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + + z2 = tspr->z - ((yoff*tspr->yrepeat)<<2); + if (cstat&128) + { + z2 += ((yspan*tspr->yrepeat)<<1); + if (yspan&1) z2 += (tspr->yrepeat<<1); //Odd yspans + } + z1 = z2 - ((yspan*tspr->yrepeat)<<2); + + globalorientation = 0; + globalpicnum = tilenum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = 0L; + globalypanning = 0L; + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalyscale = divscale(512,tspr->yrepeat,globalshiftval-19); + globalzd = (((globalposz-z1)*globalyscale)<<8); + if ((cstat&8) > 0) + { + globalyscale = -globalyscale; + globalzd = (((globalposz-z2)*globalyscale)<<8); + } + + qinterpolatedown16((long)&lwall[lx],rx-lx+1,linum,linuminc); + clearbuf(&swall[lx],rx-lx+1,mulscale19(yp,xdimscale)); + + if ((cstat&2) == 0) + maskwallscan(lx,rx,uwall,dwall,swall,lwall); + else + transmaskwallscan(lx,rx); + } + else if ((cstat&48) == 16) + { + if ((cstat&4) > 0) xoff = -xoff; + if ((cstat&8) > 0) yoff = -yoff; + + xspan = tilesizx[tilenum]; yspan = tilesizy[tilenum]; + xv = tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]; + yv = tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]; + i = (xspan>>1)+xoff; + x1 = tspr->x-globalposx-mulscale16(xv,i); x2 = x1+mulscale16(xv,xspan); + y1 = tspr->y-globalposy-mulscale16(yv,i); y2 = y1+mulscale16(yv,xspan); + + yp1 = dmulscale6(x1,cosviewingrangeglobalang,y1,sinviewingrangeglobalang); + yp2 = dmulscale6(x2,cosviewingrangeglobalang,y2,sinviewingrangeglobalang); + if ((yp1 <= 0) && (yp2 <= 0)) return; + xp1 = dmulscale6(y1,cosglobalang,-x1,singlobalang); + xp2 = dmulscale6(y2,cosglobalang,-x2,singlobalang); + + x1 += globalposx; y1 += globalposy; + x2 += globalposx; y2 += globalposy; + + swapped = 0; + if (dmulscale32(xp1,yp2,-xp2,yp1) >= 0) //If wall's NOT facing you + { + if ((cstat&64) != 0) return; + i = xp1, xp1 = xp2, xp2 = i; + i = yp1, yp1 = yp2, yp2 = i; + i = x1, x1 = x2, x2 = i; + i = y1, y1 = y2, y2 = i; + swapped = 1; + } + + if (xp1 >= -yp1) + { + if (xp1 > yp1) return; + + if (yp1 == 0) return; + xb1[MAXWALLSB-1] = halfxdimen + scale(xp1,halfxdimen,yp1); + if (xp1 >= 0) xb1[MAXWALLSB-1]++; //Fix for SIGNED divide + if (xb1[MAXWALLSB-1] >= xdimen) xb1[MAXWALLSB-1] = xdimen-1; + yb1[MAXWALLSB-1] = yp1; + } + else + { + if (xp2 < -yp2) return; + xb1[MAXWALLSB-1] = 0; + i = yp1-yp2+xp1-xp2; + if (i == 0) return; + yb1[MAXWALLSB-1] = yp1 + scale(yp2-yp1,xp1+yp1,i); + } + if (xp2 <= yp2) + { + if (xp2 < -yp2) return; + + if (yp2 == 0) return; + xb2[MAXWALLSB-1] = halfxdimen + scale(xp2,halfxdimen,yp2) - 1; + if (xp2 >= 0) xb2[MAXWALLSB-1]++; //Fix for SIGNED divide + if (xb2[MAXWALLSB-1] >= xdimen) xb2[MAXWALLSB-1] = xdimen-1; + yb2[MAXWALLSB-1] = yp2; + } + else + { + if (xp1 > yp1) return; + + xb2[MAXWALLSB-1] = xdimen-1; + i = xp2-xp1+yp1-yp2; + if (i == 0) return; + yb2[MAXWALLSB-1] = yp1 + scale(yp2-yp1,yp1-xp1,i); + } + + if ((yb1[MAXWALLSB-1] < 256) || (yb2[MAXWALLSB-1] < 256) || (xb1[MAXWALLSB-1] > xb2[MAXWALLSB-1])) + return; + + topinc = -mulscale10(yp1,xspan); + top = (((mulscale10(xp1,xdimen) - mulscale9(xb1[MAXWALLSB-1]-halfxdimen,yp1))*xspan)>>3); + botinc = ((yp2-yp1)>>8); + bot = mulscale11(xp1-xp2,xdimen) + mulscale2(xb1[MAXWALLSB-1]-halfxdimen,botinc); + + j = xb2[MAXWALLSB-1]+3; + z = mulscale20(top,krecipasm(bot)); + lwall[xb1[MAXWALLSB-1]] = (z>>8); + for(x=xb1[MAXWALLSB-1]+4;x<=j;x+=4) + { + top += topinc; bot += botinc; + zz = z; z = mulscale20(top,krecipasm(bot)); + lwall[x] = (z>>8); + i = ((z+zz)>>1); + lwall[x-2] = (i>>8); + lwall[x-3] = ((i+zz)>>9); + lwall[x-1] = ((i+z)>>9); + } + + if (lwall[xb1[MAXWALLSB-1]] < 0) lwall[xb1[MAXWALLSB-1]] = 0; + if (lwall[xb2[MAXWALLSB-1]] >= xspan) lwall[xb2[MAXWALLSB-1]] = xspan-1; + + if ((swapped^((cstat&4)>0)) > 0) + { + j = xspan-1; + for(x=xb1[MAXWALLSB-1];x<=xb2[MAXWALLSB-1];x++) + lwall[x] = j-lwall[x]; + } + + rx1[MAXWALLSB-1] = xp1; ry1[MAXWALLSB-1] = yp1; + rx2[MAXWALLSB-1] = xp2; ry2[MAXWALLSB-1] = yp2; + + hplc = divscale19(xdimenscale,yb1[MAXWALLSB-1]); + hinc = divscale19(xdimenscale,yb2[MAXWALLSB-1]); + hinc = (hinc-hplc)/(xb2[MAXWALLSB-1]-xb1[MAXWALLSB-1]+1); + + z2 = tspr->z - ((yoff*tspr->yrepeat)<<2); + if (cstat&128) + { + z2 += ((yspan*tspr->yrepeat)<<1); + if (yspan&1) z2 += (tspr->yrepeat<<1); //Odd yspans + } + z1 = z2 - ((yspan*tspr->yrepeat)<<2); + + globalorientation = 0; + globalpicnum = tilenum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = 0L; + globalypanning = 0L; + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalyscale = divscale(512,tspr->yrepeat,globalshiftval-19); + globalzd = (((globalposz-z1)*globalyscale)<<8); + if ((cstat&8) > 0) + { + globalyscale = -globalyscale; + globalzd = (((globalposz-z2)*globalyscale)<<8); + } + + if (((sec->ceilingstat&1) == 0) && (z1 < sec->ceilingz)) + z1 = sec->ceilingz; + if (((sec->floorstat&1) == 0) && (z2 > sec->floorz)) + z2 = sec->floorz; + + owallmost(uwall,(long)(MAXWALLSB-1),z1-globalposz); + owallmost(dwall,(long)(MAXWALLSB-1),z2-globalposz); + for(i=xb1[MAXWALLSB-1];i<=xb2[MAXWALLSB-1];i++) + { swall[i] = (krecipasm(hplc)<<2); hplc += hinc; } + + for(i=smostwallcnt-1;i>=0;i--) + { + j = smostwall[i]; + + if ((xb1[j] > xb2[MAXWALLSB-1]) || (xb2[j] < xb1[MAXWALLSB-1])) continue; + + dalx2 = xb1[j]; darx2 = xb2[j]; + if (max(yb1[MAXWALLSB-1],yb2[MAXWALLSB-1]) > min(yb1[j],yb2[j])) + { + if (min(yb1[MAXWALLSB-1],yb2[MAXWALLSB-1]) > max(yb1[j],yb2[j])) + { + x = 0x80000000; + } + else + { + x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; + x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; + + z1 = (xp2-xp1)*(y1-yp1) - (yp2-yp1)*(x1-xp1); + z2 = (xp2-xp1)*(y2-yp1) - (yp2-yp1)*(x2-xp1); + if ((z1^z2) >= 0) + x = (z1+z2); + else + { + z1 = (x2-x1)*(yp1-y1) - (y2-y1)*(xp1-x1); + z2 = (x2-x1)*(yp2-y1) - (y2-y1)*(xp2-x1); + + if ((z1^z2) >= 0) + x = -(z1+z2); + else + { + if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) + { + if (wall[thewall[j]].nextsector == tspr->sectnum) + x = 0x80000000; + else + x = 0x7fffffff; + } + else + { //INTERSECTION! + x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2); + y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2); + + yp1 = dmulscale14(x,cosglobalang,y,singlobalang); + if (yp1 > 0) + { + xp1 = dmulscale14(y,cosglobalang,-x,singlobalang); + + x = halfxdimen + scale(xp1,halfxdimen,yp1); + if (xp1 >= 0) x++; //Fix for SIGNED divide + + if (z1 < 0) + { if (dalx2 < x) dalx2 = x; } + else + { if (darx2 > x) darx2 = x; } + x = 0x80000001; + } + else + x = 0x7fffffff; + } + } + } + } + if (x < 0) + { + if (dalx2 < xb1[MAXWALLSB-1]) dalx2 = xb1[MAXWALLSB-1]; + if (darx2 > xb2[MAXWALLSB-1]) darx2 = xb2[MAXWALLSB-1]; + switch(smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == xb1[MAXWALLSB-1]) && (darx2 == xb2[MAXWALLSB-1])) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (k=dalx2; k<=darx2; k++) dwall[k] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + break; + } + } + } + } + + //sprite + if ((searchit >= 1) && (searchx >= xb1[MAXWALLSB-1]) && (searchx <= xb2[MAXWALLSB-1])) + if ((searchy >= uwall[searchx]) && (searchy <= dwall[searchx])) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + + if ((cstat&2) == 0) { + maskwallscan(xb1[MAXWALLSB-1],xb2[MAXWALLSB-1],uwall,dwall,swall,lwall); + } else { + transmaskwallscan(xb1[MAXWALLSB-1],xb2[MAXWALLSB-1]); + } + } + else if ((cstat&48) == 32) + { + if ((cstat&64) != 0) + if ((globalposz > tspr->z) == ((cstat&8)==0)) + return; + + if ((cstat&4) > 0) xoff = -xoff; + if ((cstat&8) > 0) yoff = -yoff; + xspan = tilesizx[tilenum]; + yspan = tilesizy[tilenum]; + + //Rotate center point + dax = tspr->x-globalposx; + day = tspr->y-globalposy; + rzi[0] = dmulscale10(cosglobalang,dax,singlobalang,day); + rxi[0] = dmulscale10(cosglobalang,day,-singlobalang,dax); + + //Get top-left corner + i = ((tspr->ang+2048-globalang)&2047); + cosang = sintable[(i+512)&2047]; sinang = sintable[i]; + dax = ((xspan>>1)+xoff)*tspr->xrepeat; + day = ((yspan>>1)+yoff)*tspr->yrepeat; + rzi[0] += dmulscale12(sinang,dax,cosang,day); + rxi[0] += dmulscale12(sinang,day,-cosang,dax); + + //Get other 3 corners + dax = xspan*tspr->xrepeat; + day = yspan*tspr->yrepeat; + rzi[1] = rzi[0]-mulscale12(sinang,dax); + rxi[1] = rxi[0]+mulscale12(cosang,dax); + dax = -mulscale12(cosang,day); + day = -mulscale12(sinang,day); + rzi[2] = rzi[1]+dax; rxi[2] = rxi[1]+day; + rzi[3] = rzi[0]+dax; rxi[3] = rxi[0]+day; + + //Put all points on same z + ryi[0] = scale((tspr->z-globalposz),yxaspect,320<<8); + if (ryi[0] == 0) return; + ryi[1] = ryi[2] = ryi[3] = ryi[0]; + + if ((cstat&4) == 0) + { z = 0; z1 = 1; z2 = 3; } + else + { z = 1; z1 = 0; z2 = 2; } + + dax = rzi[z1]-rzi[z]; day = rxi[z1]-rxi[z]; + bot = dmulscale8(dax,dax,day,day); + if (((klabs(dax)>>13) >= bot) || ((klabs(day)>>13) >= bot)) return; + globalx1 = divscale18(dax,bot); + globalx2 = divscale18(day,bot); + + dax = rzi[z2]-rzi[z]; day = rxi[z2]-rxi[z]; + bot = dmulscale8(dax,dax,day,day); + if (((klabs(dax)>>13) >= bot) || ((klabs(day)>>13) >= bot)) return; + globaly1 = divscale18(dax,bot); + globaly2 = divscale18(day,bot); + + //Calculate globals for hline texture mapping function + globalxpanning = (rxi[z]<<12); + globalypanning = (rzi[z]<<12); + globalzd = (ryi[z]<<12); + + rzi[0] = mulscale16(rzi[0],viewingrange); + rzi[1] = mulscale16(rzi[1],viewingrange); + rzi[2] = mulscale16(rzi[2],viewingrange); + rzi[3] = mulscale16(rzi[3],viewingrange); + + if (ryi[0] < 0) //If ceilsprite is above you, reverse order of points + { + i = rxi[1]; rxi[1] = rxi[3]; rxi[3] = i; + i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i; + } + + + //Clip polygon in 3-space + npoints = 4; + + //Clip edge 1 + npoints2 = 0; + zzsgn = rxi[0]+rzi[0]; + for(z=0;z= 0) + { + rxi2[npoints2] = rxi[z]; ryi2[npoints2] = ryi[z]; rzi2[npoints2] = rzi[z]; + npoints2++; + } + if ((zsgn^zzsgn) < 0) + { + t = divscale30(zsgn,zsgn-zzsgn); + rxi2[npoints2] = rxi[z] + mulscale30(t,rxi[zz]-rxi[z]); + ryi2[npoints2] = ryi[z] + mulscale30(t,ryi[zz]-ryi[z]); + rzi2[npoints2] = rzi[z] + mulscale30(t,rzi[zz]-rzi[z]); + npoints2++; + } + } + if (npoints2 <= 2) return; + + //Clip edge 2 + npoints = 0; + zzsgn = rxi2[0]-rzi2[0]; + for(z=0;z= 0) + { + rxi2[npoints2] = rxi[z]; + ryi2[npoints2] = ryi[z]; + rzi2[npoints2] = rzi[z]; + npoints2++; + } + if ((zsgn^zzsgn) < 0) + { + t = divscale30(zsgn,zsgn-zzsgn); + rxi2[npoints2] = rxi[z] + mulscale30(t,rxi[zz]-rxi[z]); + ryi2[npoints2] = ryi[z] + mulscale30(t,ryi[zz]-ryi[z]); + rzi2[npoints2] = rzi[z] + mulscale30(t,rzi[zz]-rzi[z]); + npoints2++; + } + } + if (npoints2 <= 2) return; + + //Clip edge 4 + npoints = 0; + zzsgn = ryi2[0]*halfxdimen + (rzi2[0]*(globalhoriz-ydimen)); + for(z=0;z (xdimen<<16)) xsi[z] = (xdimen<<16); + if (ysi[z] < ((long)0<<16)) ysi[z] = ((long)0<<16); + if (ysi[z] > ((long)ydimen<<16)) ysi[z] = ((long)ydimen<<16); + if (xsi[z] < lmax) lmax = xsi[z], lpoint = z; + if (xsi[z] > rmax) rmax = xsi[z], rpoint = z; + } + + //Get uwall arrays + for(z=lpoint;z!=rpoint;z=zz) + { + zz = z+1; if (zz == npoints) zz = 0; + + dax1 = ((xsi[z]+65535)>>16); + dax2 = ((xsi[zz]+65535)>>16); + if (dax2 > dax1) + { + yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); + y = ysi[z] + mulscale16((dax1<<16)-xsi[z],yinc); + qinterpolatedown16short((long)(&uwall[dax1]),dax2-dax1,y,yinc); + } + } + + //Get dwall arrays + for(;z!=lpoint;z=zz) + { + zz = z+1; if (zz == npoints) zz = 0; + + dax1 = ((xsi[zz]+65535)>>16); + dax2 = ((xsi[z]+65535)>>16); + if (dax2 > dax1) + { + yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); + y = ysi[zz] + mulscale16((dax1<<16)-xsi[zz],yinc); + qinterpolatedown16short((long)(&dwall[dax1]),dax2-dax1,y,yinc); + } + } + + + lx = ((lmax+65535)>>16); + rx = ((rmax+65535)>>16); + for(x=lx;x<=rx;x++) + { + uwall[x] = max(uwall[x],startumost[x+windowx1]-windowy1); + dwall[x] = min(dwall[x],startdmost[x+windowx1]-windowy1); + } + + //Additional uwall/dwall clipping goes here + for(i=smostwallcnt-1;i>=0;i--) + { + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + + //if (spritewallfront(tspr,thewall[j]) == 0) + x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; + x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; + x = (xp2-xp1)*(tspr->y-yp1)-(tspr->x-xp1)*(yp2-yp1); + if ((yp > yb1[j]) && (yp > yb2[j])) x = -1; + if ((x >= 0) && ((x != 0) || (wall[thewall[j]].nextsector != tspr->sectnum))) continue; + + dalx2 = max(xb1[j],lx); darx2 = min(xb2[j],rx); + + switch(smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (x=dalx2; x<=darx2; x++) dwall[x] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + break; + } + } + + //sprite + if ((searchit >= 1) && (searchx >= lx) && (searchx <= rx)) + if ((searchy >= uwall[searchx]) && (searchy <= dwall[searchx])) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + + globalorientation = cstat; + globalpicnum = tilenum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + //if (picanm[globalpicnum]&192) globalpicnum += animateoffs((short)globalpicnum,spritenum+32768); + + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + setgotpic(globalpicnum); + globalbufplc = waloff[globalpicnum]; + + globvis = mulscale16(globalhisibility,viewingrange); + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + + x = picsiz[globalpicnum]; y = ((x>>4)&15); x &= 15; + if (pow2long[x] != xspan) + { + x++; + globalx1 = mulscale(globalx1,xspan,x); + globalx2 = mulscale(globalx2,xspan,x); + } + + dax = globalxpanning; day = globalypanning; + globalxpanning = -dmulscale6(globalx1,day,globalx2,dax); + globalypanning = -dmulscale6(globaly1,day,globaly2,dax); + + globalx2 = mulscale16(globalx2,viewingrange); + globaly2 = mulscale16(globaly2,viewingrange); + globalzd = mulscale16(globalzd,viewingrangerecip); + + globalx1 = (globalx1-globalx2)*halfxdimen; + globaly1 = (globaly1-globaly2)*halfxdimen; + + if ((cstat&2) == 0) + msethlineshift(x,y); + else + tsethlineshift(x,y); + + //Draw it! + ceilspritescan(lx,rx-1); + } +#ifdef SUPERBUILD + else if ((cstat&48) == 48) + { + long nxrepeat, nyrepeat; + + lx = 0; rx = xdim-1; + for(x=lx;x<=rx;x++) + { + lwall[x] = (long)startumost[x+windowx1]-windowy1; + swall[x] = (long)startdmost[x+windowx1]-windowy1; + } + for(i=smostwallcnt-1;i>=0;i--) + { + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + if (spritewallfront(tspr,(long)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; + + dalx2 = max(xb1[j],lx); darx2 = min(xb2[j],rx); + + switch(smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&swall[dalx2],(darx2-dalx2+1)*sizeof(swall[0]),0L); + for (x=dalx2; x<=darx2; x++) swall[x] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + for(x=dalx2;x<=darx2;x++) + if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; + break; + } + } + + if (lwall[rx] >= swall[rx]) + { + for(x=lx;xxrepeat)<<16); + nyrepeat = (((long)tspr->yrepeat)<<16); + } + else + { + nxrepeat = ((long)tspr->xrepeat)*voxscale[vtilenum]; + nyrepeat = ((long)tspr->yrepeat)*voxscale[vtilenum]; + } + + if (!(cstat&128)) tspr->z -= mulscale22(B_LITTLE32(longptr[5]),nyrepeat); + yoff = (long)((signed char)((picanm[sprite[tspr->owner].picnum]>>16)&255))+((long)tspr->yoffset); + tspr->z -= mulscale14(yoff,nyrepeat); + + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + + if ((searchit >= 1) && (yp > (4<<8)) && (searchy >= lwall[searchx]) && (searchy < swall[searchx])) + { + siz = divscale19(xdimenscale,yp); + + xv = mulscale16(nxrepeat,xyaspect); + + xspan = ((B_LITTLE32(longptr[0])+B_LITTLE32(longptr[1]))>>1); + yspan = B_LITTLE32(longptr[2]); + xsiz = mulscale30(siz,xv*xspan); + ysiz = mulscale30(siz,nyrepeat*yspan); + + //Watch out for divscale overflow + if (((xspan>>11) < xsiz) && (yspan < (ysiz>>1))) + { + x1 = xb-(xsiz>>1); + if (xspan&1) x1 += mulscale31(siz,xv); //Odd xspans + i = mulscale30(siz,xv*xoff); + if ((cstat&4) == 0) x1 -= i; else x1 += i; + + y1 = mulscale16(tspr->z-globalposz,siz); + //y1 -= mulscale30(siz,nyrepeat*yoff); + y1 += (globalhoriz<<8)-ysiz; + //if (cstat&128) //Already fixed up above + y1 += (ysiz>>1); + + x2 = x1+xsiz-1; + y2 = y1+ysiz-1; + if (((y1|255) < (y2|255)) && (searchx >= (x1>>8)+1) && (searchx <= (x2>>8))) + { + if ((sec->ceilingstat&3) == 0) + startum = globalhoriz+mulscale24(siz,sec->ceilingz-globalposz)-1; + else + startum = 0; + if ((sec->floorstat&3) == 0) + startdm = globalhoriz+mulscale24(siz,sec->floorz-globalposz)+1; + else + startdm = 0x7fffffff; + + //sprite + if ((searchy >= max(startum,(y1>>8))) && (searchy < min(startdm,(y2>>8)))) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + } + } + } + + i = (long)tspr->ang+1536; +#if defined(POLYMOST) && defined(USE_OPENGL) + i += spriteext[tspr->owner].angoff; +#endif + drawvox(tspr->x,tspr->y,tspr->z,i,(long)tspr->xrepeat,(long)tspr->yrepeat,vtilenum,tspr->shade,tspr->pal,lwall,swall); + } +#endif + if (automapping == 1) show2dsprite[spritenum>>3] |= pow2char[spritenum&7]; +} + + +// +// drawmaskwall (internal) +// +static void drawmaskwall(short damaskwallcnt) +{ + long i, j, k, x, z, sectnum, z1, z2, lx, rx; + sectortype *sec, *nsec; + walltype *wal; + + //============================================================================= //POLYMOST BEGINS +#ifdef POLYMOST + if (rendmode) { polymost_drawmaskwall(damaskwallcnt); return; } +#endif + //============================================================================= //POLYMOST ENDS + + z = maskwall[damaskwallcnt]; + wal = &wall[thewall[z]]; + sectnum = thesector[z]; sec = §or[sectnum]; + nsec = §or[wal->nextsector]; + z1 = max(nsec->ceilingz,sec->ceilingz); + z2 = min(nsec->floorz,sec->floorz); + + wallmost(uwall,z,sectnum,(char)0); + wallmost(uplc,z,(long)wal->nextsector,(char)0); + for(x=xb1[z];x<=xb2[z];x++) if (uplc[x] > uwall[x]) uwall[x] = uplc[x]; + wallmost(dwall,z,sectnum,(char)1); + wallmost(dplc,z,(long)wal->nextsector,(char)1); + for(x=xb1[z];x<=xb2[z];x++) if (dplc[x] < dwall[x]) dwall[x] = dplc[x]; + prepwall(z,wal); + + globalorientation = (long)wal->cstat; + globalpicnum = wal->overpicnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + globalxpanning = (long)wal->xpanning; + globalypanning = (long)wal->ypanning; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)thewall[z]+16384); + globalshade = (long)wal->shade; + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalpal = (long)wal->pal; + globalshiftval = (picsiz[globalpicnum]>>4); + if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++; + globalshiftval = 32-globalshiftval; + globalyscale = (wal->yrepeat<<(globalshiftval-19)); + if ((globalorientation&4) == 0) + globalzd = (((globalposz-z1)*globalyscale)<<8); + else + globalzd = (((globalposz-z2)*globalyscale)<<8); + globalzd += (globalypanning<<24); + if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; + + for(i=smostwallcnt-1;i>=0;i--) + { + j = smostwall[i]; + if ((xb1[j] > xb2[z]) || (xb2[j] < xb1[z])) continue; + if (wallfront(j,z)) continue; + + lx = max(xb1[j],xb1[z]); rx = min(xb2[j],xb2[z]); + + switch(smostwalltype[i]) + { + case 0: + if (lx <= rx) + { + if ((lx == xb1[z]) && (rx == xb2[z])) return; + //clearbufbyte(&dwall[lx],(rx-lx+1)*sizeof(dwall[0]),0L); + for (x=lx; x<=rx; x++) dwall[x] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for(x=lx;x<=rx;x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + for(x=lx;x<=rx;x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + break; + } + } + + //maskwall + if ((searchit >= 1) && (searchx >= xb1[z]) && (searchx <= xb2[z])) + if ((searchy >= uwall[searchx]) && (searchy <= dwall[searchx])) + { + searchsector = sectnum; searchwall = thewall[z]; + searchstat = 4; searchit = 1; + } + + if ((globalorientation&128) == 0) + maskwallscan(xb1[z],xb2[z],uwall,dwall,swall,lwall); + else + { + if (globalorientation&128) + { + if (globalorientation&512) settransreverse(); else settransnormal(); + } + transmaskwallscan(xb1[z],xb2[z]); + } +} + + +// +// fillpolygon (internal) +// +static void fillpolygon(long npoints) +{ + long z, zz, x1, y1, x2, y2, miny, maxy, y, xinc, cnt; + long ox, oy, bx, by, p, day1, day2; + short *ptr, *ptr2; + +#if defined POLYMOST && defined USE_OPENGL + if (rendmode == 3) { polymost_fillpolygon(npoints); return; } +#endif + + miny = 0x7fffffff; maxy = 0x80000000; + for(z=npoints-1;z>=0;z--) + { y = ry1[z]; miny = min(miny,y); maxy = max(maxy,y); } + miny = (miny>>12); maxy = (maxy>>12); + if (miny < 0) miny = 0; + if (maxy >= ydim) maxy = ydim-1; + ptr = smost; //They're pointers! - watch how you optimize this thing + for(y=miny;y<=maxy;y++) + { + dotp1[y] = ptr; dotp2[y] = ptr+(MAXNODESPERLINE>>1); + ptr += MAXNODESPERLINE; + } + + for(z=npoints-1;z>=0;z--) + { + zz = xb1[z]; + y1 = ry1[z]; day1 = (y1>>12); + y2 = ry1[zz]; day2 = (y2>>12); + if (day1 != day2) + { + x1 = rx1[z]; x2 = rx1[zz]; + xinc = divscale12(x2-x1,y2-y1); + if (day2 > day1) + { + x1 += mulscale12((day1<<12)+4095-y1,xinc); + for(y=day1;y>12); x1 += xinc; } + } + else + { + x2 += mulscale12((day2<<12)+4095-y2,xinc); + for(y=day2;y>12); x2 += xinc; } + } + } + } + + globalx1 = mulscale16(globalx1,xyaspect); + globaly2 = mulscale16(globaly2,xyaspect); + + oy = miny+1-(ydim>>1); + globalposx += oy*globalx1; + globalposy += oy*globaly2; + + setuphlineasm4(asm1,asm2); + + ptr = smost; + for(y=miny;y<=maxy;y++) + { + cnt = dotp1[y]-ptr; ptr2 = ptr+(MAXNODESPERLINE>>1); + for(z=cnt-1;z>=0;z--) + { + day1 = 0; day2 = 0; + for(zz=z;zz>0;zz--) + { + if (ptr[zz] < ptr[day1]) day1 = zz; + if (ptr2[zz] < ptr2[day2]) day2 = zz; + } + x1 = ptr[day1]; ptr[day1] = ptr[z]; + x2 = ptr2[day2]-1; ptr2[day2] = ptr2[z]; + if (x1 > x2) continue; + + if (globalpolytype < 1) + { + //maphline + ox = x2+1-(xdim>>1); + bx = ox*asm1 + globalposx; + by = ox*asm2 - globalposy; + + p = ylookup[y]+x2+frameplace; + hlineasm4(x2-x1,-1L,globalshade<<8,by,bx,p); + } + else + { + //maphline + ox = x1+1-(xdim>>1); + bx = ox*asm1 + globalposx; + by = ox*asm2 - globalposy; + + p = ylookup[y]+x1+frameplace; + if (globalpolytype == 1) + mhline(globalbufplc,bx,(x2-x1)<<16,0L,by,p); + else + { + thline(globalbufplc,bx,(x2-x1)<<16,0L,by,p); + } + } + } + globalposx += globalx1; + globalposy += globaly2; + ptr += MAXNODESPERLINE; + } + faketimerhandler(); +} + + +// +// clippoly (internal) +// +static long clippoly(long npoints, long clipstat) +{ + long z, zz, s1, s2, t, npoints2, start2, z1, z2, z3, z4, splitcnt; + long cx1, cy1, cx2, cy2; + + cx1 = windowx1; + cy1 = windowy1; + cx2 = windowx2+1; + cy2 = windowy2+1; + cx1 <<= 12; cy1 <<= 12; cx2 <<= 12; cy2 <<= 12; + + if (clipstat&0xa) //Need to clip top or left + { + npoints2 = 0; start2 = 0; z = 0; splitcnt = 0; + do + { + s2 = cx1-rx1[z]; + do + { + zz = xb1[z]; xb1[z] = -1; + s1 = s2; s2 = cx1-rx1[zz]; + if (s1 < 0) + { + rx2[npoints2] = rx1[z]; ry2[npoints2] = ry1[z]; + xb2[npoints2] = npoints2+1; npoints2++; + } + if ((s1^s2) < 0) + { + rx2[npoints2] = rx1[z]+scale(rx1[zz]-rx1[z],s1,s1-s2); + ry2[npoints2] = ry1[z]+scale(ry1[zz]-ry1[z],s1,s1-s2); + if (s1 < 0) p2[splitcnt++] = npoints2; + xb2[npoints2] = npoints2+1; + npoints2++; + } + z = zz; + } while (xb1[z] >= 0); + + if (npoints2 >= start2+3) + xb2[npoints2-1] = start2, start2 = npoints2; + else + npoints2 = start2; + + z = 1; + while ((z < npoints) && (xb1[z] < 0)) z++; + } while (z < npoints); + if (npoints2 <= 2) return(0); + + for(z=1;z= 0); + + if (npoints >= start2+3) + xb1[npoints-1] = start2, start2 = npoints; + else + npoints = start2; + + z = 1; + while ((z < npoints2) && (xb2[z] < 0)) z++; + } while (z < npoints2); + if (npoints <= 2) return(0); + + for(z=1;z= 0); + + if (npoints2 >= start2+3) + xb2[npoints2-1] = start2, start2 = npoints2; + else + npoints2 = start2; + + z = 1; + while ((z < npoints) && (xb1[z] < 0)) z++; + } while (z < npoints); + if (npoints2 <= 2) return(0); + + for(z=1;z= 0); + + if (npoints >= start2+3) + xb1[npoints-1] = start2, start2 = npoints; + else + npoints = start2; + + z = 1; + while ((z < npoints2) && (xb2[z] < 0)) z++; + } while (z < npoints2); + if (npoints <= 2) return(0); + + for(z=1;z xres-1) cx2 = xres-1; + if (cy2 > yres-1) cy2 = yres-1; + + xsiz = tilesizx[picnum]; ysiz = tilesizy[picnum]; + if (dastat&16) { xoff = 0; yoff = 0; } + else + { + xoff = (long)((signed char)((picanm[picnum]>>8)&255))+(xsiz>>1); + yoff = (long)((signed char)((picanm[picnum]>>16)&255))+(ysiz>>1); + } + + if (dastat&4) yoff = ysiz-yoff; + + cosang = sintable[(a+512)&2047]; sinang = sintable[a&2047]; + + if ((dastat&2) != 0) //Auto window size scaling + { + if ((dastat&8) == 0) + { + x = xdimenscale; //= scale(xdimen,yxaspect,320); + sx = ((cx1+cx2+2)<<15)+scale(sx-(320<<15),xdimen,320); + sy = ((cy1+cy2+2)<<15)+mulscale16(sy-(200<<15),x); + } + else + { + //If not clipping to startmosts, & auto-scaling on, as a + //hard-coded bonus, scale to full screen instead + x = scale(xdim,yxaspect,320); + sx = (xdim<<15)+32768+scale(sx-(320<<15),xdim,320); + sy = (ydim<<15)+32768+mulscale16(sy-(200<<15),x); + } + z = mulscale16(z,x); + } + + xv = mulscale14(cosang,z); + yv = mulscale14(sinang,z); + if (((dastat&2) != 0) || ((dastat&8) == 0)) //Don't aspect unscaled perms + { + xv2 = mulscale16(xv,xyaspect); + yv2 = mulscale16(yv,xyaspect); + } + else + { + xv2 = xv; + yv2 = yv; + } + + nry1[0] = sy - (yv*xoff + xv*yoff); + nry1[1] = nry1[0] + yv*xsiz; + nry1[3] = nry1[0] + xv*ysiz; + nry1[2] = nry1[1]+nry1[3]-nry1[0]; + i = (cy1<<16); if ((nry1[0]i) && (nry1[1]>i) && (nry1[2]>i) && (nry1[3]>i)) return; + + nrx1[0] = sx - (xv2*xoff - yv2*yoff); + nrx1[1] = nrx1[0] + xv2*xsiz; + nrx1[3] = nrx1[0] - yv2*ysiz; + nrx1[2] = nrx1[1]+nrx1[3]-nrx1[0]; + i = (cx1<<16); if ((nrx1[0]i) && (nrx1[1]>i) && (nrx1[2]>i) && (nrx1[3]>i)) return; + + gx1 = nrx1[0]; gy1 = nry1[0]; //back up these before clipping + + if ((npoints = clippoly4(cx1<<16,cy1<<16,(cx2+1)<<16,(cy2+1)<<16)) < 3) return; + + lx = nrx1[0]; rx = nrx1[0]; + + nextv = 0; + for(v=npoints-1;v>=0;v--) + { + x1 = nrx1[v]; x2 = nrx1[nextv]; + dax1 = (x1>>16); if (x1 < lx) lx = x1; + dax2 = (x2>>16); if (x1 > rx) rx = x1; + if (dax1 != dax2) + { + y1 = nry1[v]; y2 = nry1[nextv]; + yinc = divscale16(y2-y1,x2-x1); + if (dax2 > dax1) + { + yplc = y1 + mulscale16((dax1<<16)+65535-x1,yinc); + qinterpolatedown16short((long)(&uplc[dax1]),dax2-dax1,yplc,yinc); + } + else + { + yplc = y2 + mulscale16((dax2<<16)+65535-x2,yinc); + qinterpolatedown16short((long)(&dplc[dax2]),dax1-dax2,yplc,yinc); + } + } + nextv = v; + } + + if (waloff[picnum] == 0) loadtile(picnum); + setgotpic(picnum); + bufplc = waloff[picnum]; + + palookupoffs = FP_OFF(palookup[dapalnum]) + (getpalookup(0L,(long)dashade)<<8); + + i = divscale32(1L,z); + xv = mulscale14(sinang,i); + yv = mulscale14(cosang,i); + if (((dastat&2) != 0) || ((dastat&8) == 0)) //Don't aspect unscaled perms + { + yv2 = mulscale16(-xv,yxaspect); + xv2 = mulscale16(yv,yxaspect); + } + else + { + yv2 = -xv; + xv2 = yv; + } + + x1 = (lx>>16); x2 = (rx>>16); + + oy = 0; + x = (x1<<16)-1-gx1; y = (oy<<16)+65535-gy1; + bx = dmulscale16(x,xv2,y,xv); + by = dmulscale16(x,yv2,y,yv); + if (dastat&4) { yv = -yv; yv2 = -yv2; by = (ysiz<<16)-1-by; } + +/* if (origbuffermode == 0) + { + if (dastat&128) + { + obuffermode = buffermode; + buffermode = 0; + setactivepage(activepage); + } + } + else if (dastat&8) + permanentupdate = 1; */ + +#ifndef ENGINE_USING_A_C + + if ((dastat&1) == 0) + { + if (((a&1023) == 0) && (ysiz <= 256)) //vlineasm4 has 256 high limit! + { + if (dastat&64) setupvlineasm(24L); else setupmvlineasm(24L); + by <<= 8; yv <<= 8; yv2 <<= 8; + + palookupoffse[0] = palookupoffse[1] = palookupoffse[2] = palookupoffse[3] = palookupoffs; + vince[0] = vince[1] = vince[2] = vince[3] = yv; + + for(x=x1;x y1) y1 = startumost[x+xx]; + if (startdmost[x+xx] < y2) y2 = startdmost[x+xx]; + } + if (y2 <= y1) continue; + + by += yv*(y1-oy); oy = y1; + + bufplce[xx] = (bx>>16)*ysiz+bufplc; + vplce[xx] = by; + y1ve[xx] = y1; + y2ve[xx] = y2-1; + bad &= ~pow2char[xx]; + } + + p = x+frameplace; + + u4 = max(max(y1ve[0],y1ve[1]),max(y1ve[2],y1ve[3])); + d4 = min(min(y2ve[0],y2ve[1]),min(y2ve[2],y2ve[3])); + + if (dastat&64) + { + if ((bad != 0) || (u4 >= d4)) + { + if (!(bad&1)) prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (!(bad&2)) prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (!(bad&4)) prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (!(bad&8)) prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + continue; + } + + if (u4 > y1ve[0]) vplce[0] = prevlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (u4 > y1ve[1]) vplce[1] = prevlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (u4 > y1ve[2]) vplce[2] = prevlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (u4 > y1ve[3]) vplce[3] = prevlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + + if (d4 >= u4) vlineasm4(d4-u4+1,ylookup[u4]+p); + + i = p+ylookup[d4+1]; + if (y2ve[0] > d4) prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); + if (y2ve[1] > d4) prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); + if (y2ve[2] > d4) prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); + if (y2ve[3] > d4) prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); + } + else + { + if ((bad != 0) || (u4 >= d4)) + { + if (!(bad&1)) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (!(bad&2)) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (!(bad&4)) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (!(bad&8)) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + continue; + } + + if (u4 > y1ve[0]) vplce[0] = mvlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); + if (u4 > y1ve[1]) vplce[1] = mvlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); + if (u4 > y1ve[2]) vplce[2] = mvlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); + if (u4 > y1ve[3]) vplce[3] = mvlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); + + if (d4 >= u4) mvlineasm4(d4-u4+1,ylookup[u4]+p); + + i = p+ylookup[d4+1]; + if (y2ve[0] > d4) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); + if (y2ve[1] > d4) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); + if (y2ve[2] > d4) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); + if (y2ve[3] > d4) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); + } + + faketimerhandler(); + } + } + else + { + if (dastat&64) + { + if ((xv2&0x0000ffff) == 0) + { + qlinemode = 1; + setupqrhlineasm4(0L,yv2<<16,(xv2>>16)*ysiz+(yv2>>16),palookupoffs,0L,0L); + } + else + { + qlinemode = 0; + setuprhlineasm4(xv2<<16,yv2<<16,(xv2>>16)*ysiz+(yv2>>16),palookupoffs,ysiz,0L); + } + } + else + setuprmhlineasm4(xv2<<16,yv2<<16,(xv2>>16)*ysiz+(yv2>>16),palookupoffs,ysiz,0L); + + y1 = uplc[x1]; + if (((dastat&8) == 0) && (startumost[x1] > y1)) y1 = startumost[x1]; + y2 = y1; + for(x=x1;x ny1) ny1 = startumost[x]-1; + if (startdmost[x] < ny2) ny2 = startdmost[x]; + } + + if (ny1 < ny2-1) + { + if (ny1 >= y2) + { + while (y1 < y2-1) + { + y1++; if ((y1&31) == 0) faketimerhandler(); + + //x,y1 + bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; + if (dastat&64) { + if (qlinemode) qrhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,0L ,by<<16,ylookup[y1]+x+frameplace); + else rhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } else rmhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } + y1 = ny1; + } + else + { + while (y1 < ny1) + { + y1++; if ((y1&31) == 0) faketimerhandler(); + + //x,y1 + bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; + if (dastat&64) { + if (qlinemode) qrhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,0L ,by<<16,ylookup[y1]+x+frameplace); + else rhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } else rmhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } + while (y1 > ny1) lastx[y1--] = x; + } + while (y2 > ny2) + { + y2--; if ((y2&31) == 0) faketimerhandler(); + + //x,y2 + bx += xv*(y2-oy); by += yv*(y2-oy); oy = y2; + if (dastat&64) { + if (qlinemode) qrhlineasm4(x-lastx[y2],(bx>>16)*ysiz+(by>>16)+bufplc,0L,0L ,by<<16,ylookup[y2]+x+frameplace); + else rhlineasm4(x-lastx[y2],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y2]+x+frameplace); + } else rmhlineasm4(x-lastx[y2],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y2]+x+frameplace); + } + while (y2 < ny2) lastx[y2++] = x; + } + else + { + while (y1 < y2-1) + { + y1++; if ((y1&31) == 0) faketimerhandler(); + + //x,y1 + bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; + if (dastat&64) { + if (qlinemode) qrhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,0L ,by<<16,ylookup[y1]+x+frameplace); + else rhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } else rmhlineasm4(x-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x+frameplace); + } + if (x == x2-1) { bx += xv2; by += yv2; break; } + y1 = uplc[x+1]; + if (((dastat&8) == 0) && (startumost[x+1] > y1)) y1 = startumost[x+1]; + y2 = y1; + } + bx += xv2; by += yv2; + } + while (y1 < y2-1) + { + y1++; if ((y1&31) == 0) faketimerhandler(); + + //x2,y1 + bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; + if (dastat&64) { + if (qlinemode) qrhlineasm4(x2-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,0L,by<<16,ylookup[y1]+x2+frameplace); + else rhlineasm4(x2-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x2+frameplace); + } else rmhlineasm4(x2-lastx[y1],(bx>>16)*ysiz+(by>>16)+bufplc,0L,bx<<16,by<<16,ylookup[y1]+x2+frameplace); + } + } + } + else + { + if ((dastat&1) == 0) + { + if (dastat&64) + setupspritevline(palookupoffs,(xv>>16)*ysiz,xv<<16,ysiz,yv,0L); + else + msetupspritevline(palookupoffs,(xv>>16)*ysiz,xv<<16,ysiz,yv,0L); + } + else + { + tsetupspritevline(palookupoffs,(xv>>16)*ysiz,xv<<16,ysiz,yv,0L); + if (dastat&32) settransreverse(); else settransnormal(); + } + for(x=x1;x y1) y1 = startumost[x]; + if (startdmost[x] < y2) y2 = startdmost[x]; + } + if (y2 <= y1) continue; + + switch(y1-oy) + { + case -1: bx -= xv; by -= yv; oy = y1; break; + case 0: break; + case 1: bx += xv; by += yv; oy = y1; break; + default: bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; break; + } + + p = ylookup[y1]+x+frameplace; + + if ((dastat&1) == 0) + { + if (dastat&64) + spritevline(0L,by<<16,y2-y1+1,bx<<16,(bx>>16)*ysiz+(by>>16)+bufplc,p); + else + mspritevline(0L,by<<16,y2-y1+1,bx<<16,(bx>>16)*ysiz+(by>>16)+bufplc,p); + } + else + { + tspritevline(0L,by<<16,y2-y1+1,bx<<16,(bx>>16)*ysiz+(by>>16)+bufplc,p); + } + faketimerhandler(); + } + } + +#else // ENGINE_USING_A_C + + if ((dastat&1) == 0) + { + if (dastat&64) + setupspritevline(palookupoffs,xv,yv,ysiz); + else + msetupspritevline(palookupoffs,xv,yv,ysiz); + } + else + { + tsetupspritevline(palookupoffs,xv,yv,ysiz); + if (dastat&32) settransreverse(); else settransnormal(); + } + for(x=x1;x y1) y1 = startumost[x]; + if (startdmost[x] < y2) y2 = startdmost[x]; + } + if (y2 <= y1) continue; + + switch(y1-oy) + { + case -1: bx -= xv; by -= yv; oy = y1; break; + case 0: break; + case 1: bx += xv; by += yv; oy = y1; break; + default: bx += xv*(y1-oy); by += yv*(y1-oy); oy = y1; break; + } + + p = ylookup[y1]+x+frameplace; + + if ((dastat&1) == 0) + { + if (dastat&64) + spritevline(bx&65535,by&65535,y2-y1+1,(bx>>16)*ysiz+(by>>16)+bufplc,p); + else + mspritevline(bx&65535,by&65535,y2-y1+1,(bx>>16)*ysiz+(by>>16)+bufplc,p); + } + else + { + tspritevline(bx&65535,by&65535,y2-y1+1,(bx>>16)*ysiz+(by>>16)+bufplc,p); + //transarea += (y2-y1); + } + faketimerhandler(); + } + +#endif + +/* if ((dastat&128) && (origbuffermode == 0)) + { + buffermode = obuffermode; + setactivepage(activepage); + }*/ +} + + +// +// initksqrt (internal) +// +static void initksqrt(void) +{ + long i, j, k; + + j = 1; k = 0; + for(i=0;i<4096;i++) + { + if (i >= j) { j <<= 2; k++; } + sqrtable[i] = (unsigned short)(msqrtasm((i<<18)+131072)<<1); + shlookup[i] = (k<<1)+((10-k)<<8); + if (i < 256) shlookup[i+4096] = ((k+6)<<1)+((10-(k+6))<<8); + } +} + + +// +// dosetaspect +// +static void dosetaspect(void) +{ + long i, j, k, x, xinc,a; + + if (xyaspect != oxyaspect) + { + oxyaspect = xyaspect; + j = xyaspect*320; + horizlookup2[horizycent-1] = divscale26(131072,j); + for(i=ydim*4-1;i>=0;i--) + if (i != (horizycent-1)) + { + horizlookup[i] = divscale28(1,i-(horizycent-1)); + horizlookup2[i] = divscale14(klabs(horizlookup[i]),j); + } + } + if ((xdimen != oxdimen) || (viewingrange != oviewingrange)) + { + oxdimen = xdimen; + oviewingrange = viewingrange; + xinc = mulscale32(viewingrange*320,xdimenrecip); + x = (640<<16)-mulscale1(xinc,xdimen); + for(i=0;i>16); x += xinc; + if (j != 0) j = mulscale16((long)radarang[k+1]-(long)radarang[k],j); + radarang2[i] = (short)(((long)radarang[k]+j)>>6); + } +#ifdef SUPERBUILD + for(i=1;i<65536;i++) distrecip[i] = divscale20(xdimen,i); + nytooclose = xdimen*2100; + nytoofar = 65536*16384-1048576; +#endif + } +} + + +// +// loadtables (internal) +// +static void calcbritable(void) +{ + int i,j; + double a,b; + for(i=0;i<16;i++) { + a = (double)8 / ((double)i+8); + b = (double)255 / pow((double)255,a); + for(j=0;j<256;j++) // JBF 20040207: full 8bit precision + britable[i][j] = (char)(pow((double)j,a)*b); + } +} + +static int loadtables(void) +{ + long i, fil; + + if (tablesloaded == 0) + { + initksqrt(); + + for(i=0;i<2048;i++) reciptable[i] = divscale30(2048L,i+2048); + + if ((fil = kopen4load("tables.dat",0)) != -1) + { + kread(fil,sintable,2048*2); for (i=2048-1; i>=0; i--) sintable[i] = B_LITTLE16(sintable[i]); + kread(fil,radarang,640*2); for (i=640-1; i>=0; i--) radarang[i] = B_LITTLE16(radarang[i]); + for(i=0;i<640;i++) radarang[1279-i] = -radarang[i]; + //kread(fil,textfont,1024); + //kread(fil,smalltextfont,1024); + //kread(fil,britable,1024); + calcbritable(); + + kclose(fil); + } else { + engineerrstr = "Failed to load TABLES.DAT!"; + initprintf("ERROR: %s\n", engineerrstr); + return 1; + } + tablesloaded = 1; + } + + return 0; +} + + +// +// initfastcolorlookup (internal) +// +static void initfastcolorlookup(long rscale, long gscale, long bscale) +{ + long i, j, x, y, z; + char *pal1; + + j = 0; + for(i=64;i>=0;i--) + { + //j = (i-64)*(i-64); + rdist[i] = rdist[128-i] = j*rscale; + gdist[i] = gdist[128-i] = j*gscale; + bdist[i] = bdist[128-i] = j*bscale; + j += 129-(i<<1); + } + + //clearbufbyte(colhere,sizeof(colhere),0L); + //clearbufbyte(colhead,sizeof(colhead),0L); + Bmemset(colhere,0,sizeof(colhere)); + Bmemset(colhead,0,sizeof(colhead)); + + pal1 = (char *)&palette[768-3]; + for(i=255;i>=0;i--,pal1-=3) + { + j = (pal1[0]>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(pal1[1]>>3)*FASTPALGRIDSIZ+(pal1[2]>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1; + if (colhere[j>>3]&pow2char[j&7]) colnext[i] = colhead[j]; else colnext[i] = -1; + colhead[j] = i; + colhere[j>>3] |= pow2char[j&7]; + } + + i = 0; + for(x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ;x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ;x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ) + for(y=-FASTPALGRIDSIZ;y<=FASTPALGRIDSIZ;y+=FASTPALGRIDSIZ) + for(z=-1;z<=1;z++) + colscan[i++] = x+y+z; + i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i; +} + + +// +// loadpalette (internal) +// +static void loadpalette(void) +{ + long fil,i; + + if (paletteloaded != 0) return; + if ((fil = kopen4load("palette.dat",0)) == -1) return; + + kread(fil,palette,768); + kread(fil,&numpalookups,2); numpalookups = B_LITTLE16(numpalookups); + + if ((palookup[0] = (char *)kkmalloc(numpalookups<<8)) == NULL) + allocache((long*)&palookup[0],numpalookups<<8,&permanentlock); + if ((transluc = (char *)kkmalloc(65536L)) == NULL) + allocache((long*)&transluc,65536,&permanentlock); + + globalpalwritten = palookup[0]; globalpal = 0; + setpalookupaddress(globalpalwritten); + + fixtransluscence(FP_OFF(transluc)); + + kread(fil,palookup[globalpal],numpalookups<<8); + kread(fil,transluc,65536); + kclose(fil); + + initfastcolorlookup(30L,59L,11L); + + paletteloaded = 1; +} + + +// +// getclosestcol (internal) +// +static long getclosestcol(long r, long g, long b) +{ + long i, j, k, dist, mindist, retcol; + char *pal1; + + j = (r>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(g>>3)*FASTPALGRIDSIZ+(b>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1; + mindist = min(rdist[coldist[r&7]+64+8],gdist[coldist[g&7]+64+8]); + mindist = min(mindist,bdist[coldist[b&7]+64+8]); + mindist++; + + r = 64-r; g = 64-g; b = 64-b; + + retcol = -1; + for(k=26;k>=0;k--) + { + i = colscan[k]+j; if ((colhere[i>>3]&pow2char[i&7]) == 0) continue; + i = colhead[i]; + do + { + pal1 = (char *)&palette[i*3]; + dist = gdist[pal1[1]+g]; + if (dist < mindist) + { + dist += rdist[pal1[0]+r]; + if (dist < mindist) + { + dist += bdist[pal1[2]+b]; + if (dist < mindist) { mindist = dist; retcol = i; } + } + } + i = colnext[i]; + } while (i >= 0); + } + if (retcol >= 0) return(retcol); + + mindist = 0x7fffffff; + pal1 = (char *)&palette[768-3]; + for(i=255;i>=0;i--,pal1-=3) + { + dist = gdist[pal1[1]+g]; if (dist >= mindist) continue; + dist += rdist[pal1[0]+r]; if (dist >= mindist) continue; + dist += bdist[pal1[2]+b]; if (dist >= mindist) continue; + mindist = dist; retcol = i; + } + return(retcol); +} + + +// +// insertspritesect (internal) +// +static long insertspritesect(short sectnum) +{ + short blanktouse; + + if ((sectnum >= MAXSECTORS) || (headspritesect[MAXSECTORS] == -1)) + return(-1); //list full + + blanktouse = headspritesect[MAXSECTORS]; + + headspritesect[MAXSECTORS] = nextspritesect[blanktouse]; + if (headspritesect[MAXSECTORS] >= 0) + prevspritesect[headspritesect[MAXSECTORS]] = -1; + + prevspritesect[blanktouse] = -1; + nextspritesect[blanktouse] = headspritesect[sectnum]; + if (headspritesect[sectnum] >= 0) + prevspritesect[headspritesect[sectnum]] = blanktouse; + headspritesect[sectnum] = blanktouse; + + sprite[blanktouse].sectnum = sectnum; + + return(blanktouse); +} + + +// +// insertspritestat (internal) +// +static long insertspritestat(short statnum) +{ + short blanktouse; + + if ((statnum >= MAXSTATUS) || (headspritestat[MAXSTATUS] == -1)) + return(-1); //list full + + blanktouse = headspritestat[MAXSTATUS]; + + headspritestat[MAXSTATUS] = nextspritestat[blanktouse]; + if (headspritestat[MAXSTATUS] >= 0) + prevspritestat[headspritestat[MAXSTATUS]] = -1; + + prevspritestat[blanktouse] = -1; + nextspritestat[blanktouse] = headspritestat[statnum]; + if (headspritestat[statnum] >= 0) + prevspritestat[headspritestat[statnum]] = blanktouse; + headspritestat[statnum] = blanktouse; + + sprite[blanktouse].statnum = statnum; + + return(blanktouse); +} + + +// +// deletespritesect (internal) +// +static long deletespritesect(short deleteme) +{ + if (sprite[deleteme].sectnum == MAXSECTORS) + return(-1); + + if (headspritesect[sprite[deleteme].sectnum] == deleteme) + headspritesect[sprite[deleteme].sectnum] = nextspritesect[deleteme]; + + if (prevspritesect[deleteme] >= 0) nextspritesect[prevspritesect[deleteme]] = nextspritesect[deleteme]; + if (nextspritesect[deleteme] >= 0) prevspritesect[nextspritesect[deleteme]] = prevspritesect[deleteme]; + + if (headspritesect[MAXSECTORS] >= 0) prevspritesect[headspritesect[MAXSECTORS]] = deleteme; + prevspritesect[deleteme] = -1; + nextspritesect[deleteme] = headspritesect[MAXSECTORS]; + headspritesect[MAXSECTORS] = deleteme; + + sprite[deleteme].sectnum = MAXSECTORS; + return(0); +} + + +// +// deletespritestat (internal) +// +static long deletespritestat(short deleteme) +{ + if (sprite[deleteme].statnum == MAXSTATUS) + return(-1); + + if (headspritestat[sprite[deleteme].statnum] == deleteme) + headspritestat[sprite[deleteme].statnum] = nextspritestat[deleteme]; + + if (prevspritestat[deleteme] >= 0) nextspritestat[prevspritestat[deleteme]] = nextspritestat[deleteme]; + if (nextspritestat[deleteme] >= 0) prevspritestat[nextspritestat[deleteme]] = prevspritestat[deleteme]; + + if (headspritestat[MAXSTATUS] >= 0) prevspritestat[headspritestat[MAXSTATUS]] = deleteme; + prevspritestat[deleteme] = -1; + nextspritestat[deleteme] = headspritestat[MAXSTATUS]; + headspritestat[MAXSTATUS] = deleteme; + + sprite[deleteme].statnum = MAXSTATUS; + return(0); +} + + +// +// lintersect (internal) +// +static long lintersect(long x1, long y1, long z1, long x2, long y2, long z2, long x3, + long y3, long x4, long y4, long *intx, long *inty, long *intz) +{ //p1 to p2 is a line segment + long x21, y21, x34, y34, x31, y31, bot, topt, topu, t; + + x21 = x2-x1; x34 = x3-x4; + y21 = y2-y1; y34 = y3-y4; + bot = x21*y34 - y21*x34; + if (bot >= 0) + { + if (bot == 0) return(0); + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; if ((topt < 0) || (topt >= bot)) return(0); + topu = x21*y31 - y21*x31; if ((topu < 0) || (topu >= bot)) return(0); + } + else + { + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; if ((topt > 0) || (topt <= bot)) return(0); + topu = x21*y31 - y21*x31; if ((topu > 0) || (topu <= bot)) return(0); + } + t = divscale24(topt,bot); + *intx = x1 + mulscale24(x21,t); + *inty = y1 + mulscale24(y21,t); + *intz = z1 + mulscale24(z2-z1,t); + return(1); +} + + +// +// rintersect (internal) +// +static long rintersect(long x1, long y1, long z1, long vx, long vy, long vz, long x3, + long y3, long x4, long y4, long *intx, long *inty, long *intz) +{ //p1 towards p2 is a ray + long x34, y34, x31, y31, bot, topt, topu, t; + + x34 = x3-x4; y34 = y3-y4; + bot = vx*y34 - vy*x34; + if (bot >= 0) + { + if (bot == 0) return(0); + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; if (topt < 0) return(0); + topu = vx*y31 - vy*x31; if ((topu < 0) || (topu >= bot)) return(0); + } + else + { + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; if (topt > 0) return(0); + topu = vx*y31 - vy*x31; if ((topu > 0) || (topu <= bot)) return(0); + } + t = divscale16(topt,bot); + *intx = x1 + mulscale16(vx,t); + *inty = y1 + mulscale16(vy,t); + *intz = z1 + mulscale16(vz,t); + return(1); +} + + +// +// keepaway (internal) +// +static void keepaway (long *x, long *y, long w) +{ + long dx, dy, ox, oy, x1, y1; + char first; + + x1 = clipit[w].x1; dx = clipit[w].x2-x1; + y1 = clipit[w].y1; dy = clipit[w].y2-y1; + ox = ksgn(-dy); oy = ksgn(dx); + first = (klabs(dx) <= klabs(dy)); + while (1) + { + if (dx*(*y-y1) > (*x-x1)*dy) return; + if (first == 0) *x += ox; else *y += oy; + first ^= 1; + } +} + + +// +// raytrace (internal) +// +static long raytrace(long x3, long y3, long *x4, long *y4) +{ + long x1, y1, x2, y2, bot, topu, nintx, ninty, cnt, z, hitwall; + long x21, y21, x43, y43; + + hitwall = -1; + for(z=clipnum-1;z>=0;z--) + { + x1 = clipit[z].x1; x2 = clipit[z].x2; x21 = x2-x1; + y1 = clipit[z].y1; y2 = clipit[z].y2; y21 = y2-y1; + + topu = x21*(y3-y1) - (x3-x1)*y21; if (topu <= 0) continue; + if (x21*(*y4-y1) > (*x4-x1)*y21) continue; + x43 = *x4-x3; y43 = *y4-y3; + if (x43*(y1-y3) > (x1-x3)*y43) continue; + if (x43*(y2-y3) <= (x2-x3)*y43) continue; + bot = x43*y21 - x21*y43; if (bot == 0) continue; + + cnt = 256; + do + { + cnt--; if (cnt < 0) { *x4 = x3; *y4 = y3; return(z); } + nintx = x3 + scale(x43,topu,bot); + ninty = y3 + scale(y43,topu,bot); + topu--; + } while (x21*(ninty-y1) <= (nintx-x1)*y21); + + if (klabs(x3-nintx)+klabs(y3-ninty) < klabs(x3-*x4)+klabs(y3-*y4)) + { *x4 = nintx; *y4 = ninty; hitwall = z; } + } + return(hitwall); +} + + + +// +// Exported Engine Functions +// + +#if !defined _WIN32 && defined DEBUGGINGAIDS +#include +static void sighandler(int sig, const siginfo_t *info, void *ctx) +{ + const char *s; + switch (sig) { + case SIGFPE: + switch (info->si_code) { + case FPE_INTDIV: s = "FPE_INTDIV (integer divide by zero)"; break; + case FPE_INTOVF: s = "FPE_INTOVF (integer overflow)"; break; + case FPE_FLTDIV: s = "FPE_FLTDIV (floating-point divide by zero)"; break; + case FPE_FLTOVF: s = "FPE_FLTOVF (floating-point overflow)"; break; + case FPE_FLTUND: s = "FPE_FLTUND (floating-point underflow)"; break; + case FPE_FLTRES: s = "FPE_FLTRES (floating-point inexact result)"; break; + case FPE_FLTINV: s = "FPE_FLTINV (floating-point invalid operation)"; break; + case FPE_FLTSUB: s = "FPE_FLTSUB (floating-point subscript out of range)"; break; + default: s = "?! (unknown)"; break; + } + fprintf(stderr, "Caught SIGFPE at address %p, code %s. Aborting.\n", info->si_addr, s); + break; + default: break; + } + abort(); +} +#endif + +// +// initengine +// +int initengine(void) +{ + long i, j; + char *e; + +#if !defined _WIN32 && defined DEBUGGINGAIDS + struct sigaction sigact, oldact; + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_sigaction = sighandler; + sigact.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sigact, &oldact); +#endif + + if (initsystem()) exit(1); + + if ((e = Bgetenv("BUILD_NOP6")) != NULL) + if (!Bstrcasecmp(e, "TRUE")) { + Bprintf("Disabling P6 optimizations.\n"); + dommxoverlay = 0; + } + if (dommxoverlay) mmxoverlay(); + + if (loadtables()) return 1; + + xyaspect = -1; + + pskyoff[0] = 0; pskybits = 0; + + parallaxtype = 2; parallaxyoffs = 0L; parallaxyscale = 65536; + showinvisibility = 0; + +#ifdef SUPERBUILD + for(i=1;i<1024;i++) lowrecip[i] = ((1<<24)-1)/i; + for(i=0;i>2,65536L); +#endif + +#ifdef POLYMOST + polymost_initosdfuncs(); +#endif + + paletteloaded = 0; + + searchit = 0; searchstat = -1; + + for(i=0;i>5),0L); + clearbuf(&show2dsprite[0],(long)((MAXSPRITES+3)>>5),0L); + clearbuf(&show2dwall[0],(long)((MAXWALLS+3)>>5),0L); + automapping = 0; + + validmodecnt = 0; + + pointhighlight = -1; + linehighlight = -1; + highlightcnt = 0; + + totalclock = 0; + visibility = 512; + parallaxvisibility = 512; + + captureformat = 0; + + loadpalette(); + getvalidmodes(); +#if defined(POLYMOST) && defined(USE_OPENGL) + if (!hicfirstinit) hicinit(); + if (!mdinited) mdinit(); +#endif + + initcrc32table(); + + return 0; +} + + +// +// uninitengine +// +void uninitengine(void) +{ + long i; + + //OSD_Printf("cacheresets = %d, cacheinvalidates = %d\n", cacheresets, cacheinvalidates); + +#if defined(POLYMOST) && defined(USE_OPENGL) + polymost_glreset(); + hicinit(); + freeallmodels(); +#endif + + uninitsystem(); + if (artfil != -1) kclose(artfil); + + if (transluc != NULL) { kkfree(transluc); transluc = NULL; } + if (pic != NULL) { kkfree(pic); pic = NULL; } + if (lookups != NULL) + { + if (lookupsalloctype == 0) kkfree((void *)lookups); + //if (lookupsalloctype == 1) suckcache(lookups); //Cache already gone + lookups = NULL; + } + for(i=0;i>1); + + globaluclip = (0-globalhoriz)*xdimscale; + globaldclip = (ydimen-globalhoriz)*xdimscale; + + i = mulscale16(xdimenscale,viewingrangerecip); + globalpisibility = mulscale16(parallaxvisibility,i); + globalvisibility = mulscale16(visibility,i); + globalhisibility = mulscale16(globalvisibility,xyaspect); + globalcisibility = mulscale8(globalhisibility,320); + + globalcursectnum = dacursectnum; + totalclocklock = totalclock; + + cosglobalang = sintable[(globalang+512)&2047]; + singlobalang = sintable[globalang&2047]; + cosviewingrangeglobalang = mulscale16(cosglobalang,viewingrange); + sinviewingrangeglobalang = mulscale16(singlobalang,viewingrange); + + if ((xyaspect != oxyaspect) || (xdimen != oxdimen) || (viewingrange != oviewingrange)) + dosetaspect(); + + //clearbufbyte(&gotsector[0],(long)((numsectors+7)>>3),0L); + Bmemset(&gotsector[0],0,(long)((numsectors+7)>>3)); + + shortptr1 = (short *)&startumost[windowx1]; + shortptr2 = (short *)&startdmost[windowx1]; + i = xdimen-1; + do + { + umost[i] = shortptr1[i]-windowy1; + dmost[i] = shortptr2[i]-windowy1; + i--; + } while (i != 0); + umost[0] = shortptr1[0]-windowy1; + dmost[0] = shortptr2[0]-windowy1; + + //============================================================================= //POLYMOST BEGINS +#ifdef POLYMOST + polymost_drawrooms(); if (rendmode) { return; } +#endif + //============================================================================= //POLYMOST ENDS + + begindrawing(); //{{{ + + //frameoffset = frameplace + viewoffset; + frameoffset = frameplace + windowy1*bytesperline + windowx1; + + //if (smostwallcnt < 0) + // if (getkensmessagecrc(FP_OFF(kensmessage)) != 0x56c764d4) + // { /* setvmode(0x3);*/ printOSD("Nice try.\n"); exit(0); } + + numhits = xdimen; numscans = 0; numbunches = 0; + maskwallcnt = 0; smostwallcnt = 0; smostcnt = 0; spritesortcnt = 0; + + if (globalcursectnum >= MAXSECTORS) + globalcursectnum -= MAXSECTORS; + else + { + i = globalcursectnum; + updatesector(globalposx,globalposy,&globalcursectnum); + if (globalcursectnum < 0) globalcursectnum = i; + } + + globparaceilclip = 1; + globparaflorclip = 1; + getzsofslope(globalcursectnum,globalposx,globalposy,&cz,&fz); + if (globalposz < cz) globparaceilclip = 0; + if (globalposz > fz) globparaflorclip = 0; + + scansector(globalcursectnum); + + if (inpreparemirror) + { + inpreparemirror = 0; + mirrorsx1 = xdimen-1; mirrorsx2 = 0; + for(i=numscans-1;i>=0;i--) + { + if (wall[thewall[i]].nextsector < 0) continue; + if (xb1[i] < mirrorsx1) mirrorsx1 = xb1[i]; + if (xb2[i] > mirrorsx2) mirrorsx2 = xb2[i]; + } + + for(i=0;i 0) && (numhits > 0)) + { + clearbuf(&tempbuf[0],(long)((numbunches+3)>>2),0L); + tempbuf[0] = 1; + + closest = 0; //Almost works, but not quite :( + for(i=1;i=0;z=p2[z]) + show2dwall[thewall[z]>>3] |= pow2char[thewall[z]&7]; + } + + numbunches--; + bunchfirst[closest] = bunchfirst[numbunches]; + bunchlast[closest] = bunchlast[numbunches]; + } + + enddrawing(); //}}} +} + + +// +// drawmasks +// +void drawmasks(void) +{ + long i, j, k, l, gap, xs, ys, xp, yp, yoff, yspan; + // PLAG: sorting stuff + long *indexes, *wallindexes, *depths, *walldepths; + long x, y; + + for(i=spritesortcnt-1;i>=0;i--) tspriteptr[i] = &tsprite[i]; + for(i=spritesortcnt-1;i>=0;i--) + { + xs = tspriteptr[i]->x-globalposx; ys = tspriteptr[i]->y-globalposy; + yp = dmulscale6(xs,cosviewingrangeglobalang,ys,sinviewingrangeglobalang); + if (yp > (4<<8)) + { + xp = dmulscale6(ys,cosglobalang,-xs,singlobalang); + if (mulscale24(labs(xp+yp),xdimen) >= yp) goto killsprite; + spritesx[i] = scale(xp+yp,xdimen<<7,yp); + } + else if ((tspriteptr[i]->cstat&48) == 0) + { +killsprite: + spritesortcnt--; //Delete face sprite if on wrong side! + if (i != spritesortcnt) + { + tspriteptr[i] = tspriteptr[spritesortcnt]; + spritesx[i] = spritesx[spritesortcnt]; + spritesy[i] = spritesy[spritesortcnt]; + } + continue; + } + spritesy[i] = yp; + } + + gap = 1; while (gap < spritesortcnt) gap = (gap<<1)+1; + for(gap>>=1;gap>0;gap>>=1) //Sort sprite list + for(i=0;i=0;l-=gap) + { + if (spritesy[l] <= spritesy[l+gap]) break; + swaplong(&tspriteptr[l],&tspriteptr[l+gap]); + swaplong(&spritesx[l],&spritesx[l+gap]); + swaplong(&spritesy[l],&spritesy[l+gap]); + } + + if (spritesortcnt > 0) + spritesy[spritesortcnt] = (spritesy[spritesortcnt-1]^1); + + ys = spritesy[0]; i = 0; + for(j=1;j<=spritesortcnt;j++) + { + if (spritesy[j] == ys) continue; + ys = spritesy[j]; + if (j > i+1) + { + for(k=i;kz; + if ((tspriteptr[k]->cstat&48) != 32) + { + yoff = (long)((signed char)((picanm[tspriteptr[k]->picnum]>>16)&255))+((long)tspriteptr[k]->yoffset); + spritesz[k] -= ((yoff*tspriteptr[k]->yrepeat)<<2); + yspan = (tilesizy[tspriteptr[k]->picnum]*tspriteptr[k]->yrepeat<<2); + if (!(tspriteptr[k]->cstat&128)) spritesz[k] -= (yspan>>1); + if (klabs(spritesz[k]-globalposz) < (yspan>>1)) spritesz[k] = globalposz; + } + } + for(k=i+1;kstatnum < tspriteptr[l]->statnum) + { + swaplong(&tspriteptr[k],&tspriteptr[l]); + swaplong(&spritesx[k],&spritesx[l]); + swaplong(&spritesy[k],&spritesy[l]); + } + } + i = j; + } + + begindrawing(); //{{{ + + /*for(i=spritesortcnt-1;i>=0;i--) + { + xs = tspriteptr[i].x-globalposx; + ys = tspriteptr[i].y-globalposy; + zs = tspriteptr[i].z-globalposz; + + xp = ys*cosglobalang-xs*singlobalang; + yp = (zs<<1); + zp = xs*cosglobalang+ys*singlobalang; + + xs = scale(xp,halfxdimen<<12,zp)+((halfxdimen+windowx1)<<12); + ys = scale(yp,xdimenscale<<12,zp)+((globalhoriz+windowy1)<<12); + + drawline256(xs-65536,ys-65536,xs+65536,ys+65536,31); + drawline256(xs+65536,ys-65536,xs-65536,ys+65536,31); + }*/ + + +#if 0 + { // Removing previous sorting code +#ifdef POLYMOST + //Hack to make it draw all opaque quads first. This should reduce the chances of + //bad sorting causing transparent quads knocking out opaque quads behind it. + // + //Need to store alpha flag with all textures before this works right! + if (rendmode == 3) + { + for(i=spritesortcnt-1;i>=0;i--) + if ((!(tspriteptr[i]->cstat&2)) +#ifdef USE_OPENGL + && (!gltexmayhavealpha(tspriteptr[i]->picnum,tspriteptr[i]->pal)) +#endif + ) + { drawsprite(i); tspriteptr[i] = 0; } //draw only if it is fully opaque + for(i=j=0;i=0;i--) + { + k = thewall[maskwall[i]]; + if ((!(wall[k].cstat&128)) +#ifdef USE_OPENGL + && (!gltexmayhavealpha(wall[k].overpicnum,wall[k].pal)) +#endif + ) + { drawmaskwall(i); maskwall[i] = -1; } //draw only if it is fully opaque + } + for(i=j=0;i 0) && (maskwallcnt > 0)) //While BOTH > 0 + { + j = maskwall[maskwallcnt-1]; + if (spritewallfront(tspriteptr[spritesortcnt-1],(long)thewall[j]) == 0) + drawsprite(--spritesortcnt); + else + { + //Check to see if any sprites behind the masked wall... + k = -1; + gap = 0; + for(i=spritesortcnt-2;i>=0;i--) + if ((xb1[j] <= (spritesx[i]>>8)) && ((spritesx[i]>>8) <= xb2[j])) + if (spritewallfront(tspriteptr[i],(long)thewall[j]) == 0) + { + drawsprite(i); + tspriteptr[i]->owner = -1; + k = i; + gap++; + } + if (k >= 0) //remove holes in sprite list + { + for(i=k;iowner >= 0) + { + if (i > k) + { + tspriteptr[k] = tspriteptr[i]; + spritesx[k] = spritesx[i]; + spritesy[k] = spritesy[i]; + } + k++; + } + spritesortcnt -= gap; + } + + //finally safe to draw the masked wall + drawmaskwall(--maskwallcnt); + } + } + while (spritesortcnt > 0) drawsprite(--spritesortcnt); + while (maskwallcnt > 0) drawmaskwall(--maskwallcnt); + } +#else + // PLAG : The heart of good transparency -> sorted rendering on all layers. + // that's why this code interleaves the drawing of all possible transparent entities + // bubblesort is used, shouldn't cause any problems cpu-wise since the lists are small + + // SPRITES PREPROCESSING + l = spritesortcnt; + indexes = malloc(l * sizeof(long)); + depths = malloc(l * sizeof(long)); + + // first pass to set base indexes and depths + i = l; + while (i > 0) + { + i--; + indexes[i] = --spritesortcnt; + depths[i] = (tspriteptr[spritesortcnt]->x - globalposx) * (tspriteptr[spritesortcnt]->x - globalposx) + + (tspriteptr[spritesortcnt]->y - globalposy) * (tspriteptr[spritesortcnt]->y - globalposy); + } + + // second pass (and possibly more) to z-sort + j = 0; + while (j == 0) + { + j = 1; + for(i=l-1;i>0;i--) + { + if (depths[i] < depths[i-1]) + { + swaplong(&indexes[i-1], &indexes[i]); + swaplong(&depths[i-1], &depths[i]); + j = 0; + } + } + } + + // MASKS PREPROCESSING + k = maskwallcnt; + wallindexes = malloc(k * sizeof(long)); + walldepths = malloc(k * sizeof(long)); + + // first pass to set base indexes and depths + i = k; + while (i > 0) + { + i--; + wallindexes[i] = --maskwallcnt; + + xs = wall[thewall[maskwall[wallindexes[i]]]].x; + ys = wall[thewall[maskwall[wallindexes[i]]]].y; + xp = wall[wall[thewall[maskwall[wallindexes[i]]]].point2].x; + yp = wall[wall[thewall[maskwall[wallindexes[i]]]].point2].y; + + x = ((xs + xp) / 2) - globalposx; + y = ((ys + yp) / 2) - globalposy; + walldepths[i] = (x * x) + (y * y); + } + + // second pass (and possibly more) to sort + j = 0; + while (j == 0) + { + j = 1; + for(i=k-1;i>0;i--) + { + if (walldepths[i] < walldepths[i-1]) + { + swaplong(&wallindexes[i-1], &wallindexes[i]); + swaplong(&walldepths[i-1], &walldepths[i]); + j = 0; + } + } + } + + // DRAWING + // in this code all sprites are drawn, and masks are inserted when needed + i = l - 1; + while (i >= 0) + { + j = k; + while (j > 0) + { + j--; + // if a mask is farther than the sprite which is about to be drawn, we draw it before then discard it from the stack + if ((wallindexes[j] >= 0) && (spriteobstructswall(tspriteptr[indexes[i]],(long)thewall[maskwall[wallindexes[j]]]))) + { + //OSD_Printf("masked - %i\n", walldepths[j]); + drawmaskwall(wallindexes[j]); + wallindexes[j] = -1; + } + } + //OSD_Printf("sprite - %i\n", depths[i]); + drawsprite(indexes[i]); + i--; + } + + // this codes draws the remaining (if any) masked walls, meaning those that are directly before the player + while (k > 0) + { + k--; + if (wallindexes[k] >= 0) + { + //OSD_Printf("masked - %i\n", walldepths[k]); + drawmaskwall(wallindexes[k]); + } + } + free(indexes); + free(wallindexes); + free(depths); + free(walldepths); +#endif /* goodalpha */ + + enddrawing(); //}}} +} + + +// +// drawmapview +// +void drawmapview(long dax, long day, long zoome, short ang) +{ + walltype *wal; + sectortype *sec; + spritetype *spr; + long tilenum, xoff, yoff, i, j, k, l, cosang, sinang, xspan, yspan; + long xrepeat, yrepeat, x, y, x1, y1, x2, y2, x3, y3, x4, y4, bakx1, baky1; + long s, w, ox, oy, startwall, cx1, cy1, cx2, cy2; + long bakgxvect, bakgyvect, sortnum, gap, npoints; + long xvect, yvect, xvect2, yvect2, daslope; + +#ifdef POLYMOST + //if (rendmode == 3) return; +#endif + + beforedrawrooms = 0; + + clearbuf(&gotsector[0],(long)((numsectors+31)>>5),0L); + + cx1 = (windowx1<<12); cy1 = (windowy1<<12); + cx2 = ((windowx2+1)<<12)-1; cy2 = ((windowy2+1)<<12)-1; + zoome <<= 8; + bakgxvect = divscale28(sintable[(1536-ang)&2047],zoome); + bakgyvect = divscale28(sintable[(2048-ang)&2047],zoome); + xvect = mulscale8(sintable[(2048-ang)&2047],zoome); + yvect = mulscale8(sintable[(1536-ang)&2047],zoome); + xvect2 = mulscale16(xvect,yxaspect); + yvect2 = mulscale16(yvect,yxaspect); + + sortnum = 0; + + begindrawing(); //{{{ + + for(s=0,sec=§or[s];s>3]&pow2char[s&7]) + { + npoints = 0; i = 0; + startwall = sec->wallptr; +#if 0 + for(w=sec->wallnum,wal=&wall[startwall];w>0;w--,wal++) + { + ox = wal->x - dax; oy = wal->y - day; + x = dmulscale16(ox,xvect,-oy,yvect) + (xdim<<11); + y = dmulscale16(oy,xvect2,ox,yvect2) + (ydim<<11); + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[npoints] = x; + ry1[npoints] = y; + xb1[npoints] = wal->point2 - startwall; + npoints++; + } +#else + j = startwall; l = 0; + for(w=sec->wallnum,wal=&wall[startwall];w>0;w--,wal++,j++) + { + k = lastwall(j); + if ((k > j) && (npoints > 0)) { xb1[npoints-1] = l; l = npoints; } //overwrite point2 + //wall[k].x wal->x wall[wal->point2].x + //wall[k].y wal->y wall[wal->point2].y + if (!dmulscale1(wal->x-wall[k].x,wall[wal->point2].y-wal->y,-(wal->y-wall[k].y),wall[wal->point2].x-wal->x)) continue; + ox = wal->x - dax; oy = wal->y - day; + x = dmulscale16(ox,xvect,-oy,yvect) + (xdim<<11); + y = dmulscale16(oy,xvect2,ox,yvect2) + (ydim<<11); + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[npoints] = x; + ry1[npoints] = y; + xb1[npoints] = npoints+1; + npoints++; + } + if (npoints > 0) xb1[npoints-1] = l; //overwrite point2 +#endif + if ((i&0xf0) != 0xf0) continue; + bakx1 = rx1[0]; baky1 = mulscale16(ry1[0]-(ydim<<11),xyaspect)+(ydim<<11); + if (i&0x0f) + { + npoints = clippoly(npoints,i); + if (npoints < 3) continue; + } + + //Collect floor sprites to draw + for(i=headspritesect[s];i>=0;i=nextspritesect[i]) + if ((sprite[i].cstat&48) == 32) + { + if ((sprite[i].cstat&(64+8)) == (64+8)) continue; + tsprite[sortnum++].owner = i; + } + + gotsector[s>>3] |= pow2char[s&7]; + + globalorientation = (long)sec->floorstat; + if ((globalorientation&1) != 0) continue; + + if (palookup[sec->floorpal] != globalpalwritten) + { + globalpalwritten = palookup[sec->floorpal]; + if (!globalpalwritten) globalpalwritten = palookup[globalpal]; // JBF: fixes null-pointer crash + setpalookupaddress(globalpalwritten); + } + globalpicnum = sec->floorpicnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) continue; + if ((picanm[globalpicnum]&192) != 0) globalpicnum += animateoffs((short)globalpicnum,s); + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + globalbufplc = waloff[globalpicnum]; + globalshade = max(min(sec->floorshade,numpalookups-1),0); + globvis = globalhisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalpolytype = 0; + if ((globalorientation&64) == 0) + { + globalposx = dax; globalx1 = bakgxvect; globaly1 = bakgyvect; + globalposy = day; globalx2 = bakgxvect; globaly2 = bakgyvect; + } + else + { + ox = wall[wall[startwall].point2].x - wall[startwall].x; + oy = wall[wall[startwall].point2].y - wall[startwall].y; + i = nsqrtasm(ox*ox+oy*oy); if (i == 0) continue; + i = 1048576/i; + globalx1 = mulscale10(dmulscale10(ox,bakgxvect,oy,bakgyvect),i); + globaly1 = mulscale10(dmulscale10(ox,bakgyvect,-oy,bakgxvect),i); + ox = (bakx1>>4)-(xdim<<7); oy = (baky1>>4)-(ydim<<7); + globalposx = dmulscale28(-oy,globalx1,-ox,globaly1); + globalposy = dmulscale28(-ox,globalx1,oy,globaly1); + globalx2 = -globalx1; + globaly2 = -globaly1; + + daslope = sector[s].floorheinum; + i = nsqrtasm(daslope*daslope+16777216); + globalposy = mulscale12(globalposy,i); + globalx2 = mulscale12(globalx2,i); + globaly2 = mulscale12(globaly2,i); + } + globalxshift = (8-(picsiz[globalpicnum]&15)); + globalyshift = (8-(picsiz[globalpicnum]>>4)); + if (globalorientation&8) {globalxshift++; globalyshift++; } + + sethlinesizes(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4,globalbufplc); + + if ((globalorientation&0x4) > 0) + { + i = globalposx; globalposx = -globalposy; globalposy = -i; + i = globalx2; globalx2 = globaly1; globaly1 = i; + i = globalx1; globalx1 = -globaly2; globaly2 = -i; + } + if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx; + if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalposy = -globalposy; + asm1 = (globaly1<floorxpanning)<<24); + globalposy = (globalposy<<(20+globalyshift))-(((long)sec->floorypanning)<<24); + + fillpolygon(npoints); + } + + //Sort sprite list + gap = 1; while (gap < sortnum) gap = (gap<<1)+1; + for(gap>>=1;gap>0;gap>>=1) + for(i=0;i=0;j-=gap) + { + if (sprite[tsprite[j].owner].z <= sprite[tsprite[j+gap].owner].z) break; + swapshort(&tsprite[j].owner,&tsprite[j+gap].owner); + } + + for(s=sortnum-1;s>=0;s--) + { + spr = &sprite[tsprite[s].owner]; + if ((spr->cstat&48) == 32) + { + npoints = 0; + + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + if ((spr->cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; sinang = sintable[k]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + ox = ((xspan>>1)+xoff)*xrepeat; oy = ((yspan>>1)+yoff)*yrepeat; + x1 = spr->x + mulscale(sinang,ox,16) + mulscale(cosang,oy,16); + y1 = spr->y + mulscale(sinang,oy,16) - mulscale(cosang,ox,16); + l = xspan*xrepeat; + x2 = x1 - mulscale(sinang,l,16); + y2 = y1 + mulscale(cosang,l,16); + l = yspan*yrepeat; + k = -mulscale(cosang,l,16); x3 = x2+k; x4 = x1+k; + k = -mulscale(sinang,l,16); y3 = y2+k; y4 = y1+k; + + xb1[0] = 1; xb1[1] = 2; xb1[2] = 3; xb1[3] = 0; + npoints = 4; + + i = 0; + + ox = x1 - dax; oy = y1 - day; + x = dmulscale16(ox,xvect,-oy,yvect) + (xdim<<11); + y = dmulscale16(oy,xvect2,ox,yvect2) + (ydim<<11); + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[0] = x; ry1[0] = y; + + ox = x2 - dax; oy = y2 - day; + x = dmulscale16(ox,xvect,-oy,yvect) + (xdim<<11); + y = dmulscale16(oy,xvect2,ox,yvect2) + (ydim<<11); + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[1] = x; ry1[1] = y; + + ox = x3 - dax; oy = y3 - day; + x = dmulscale16(ox,xvect,-oy,yvect) + (xdim<<11); + y = dmulscale16(oy,xvect2,ox,yvect2) + (ydim<<11); + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[2] = x; ry1[2] = y; + + x = rx1[0]+rx1[2]-rx1[1]; + y = ry1[0]+ry1[2]-ry1[1]; + i |= getclipmask(x-cx1,cx2-x,y-cy1,cy2-y); + rx1[3] = x; ry1[3] = y; + + if ((i&0xf0) != 0xf0) continue; + bakx1 = rx1[0]; baky1 = mulscale16(ry1[0]-(ydim<<11),xyaspect)+(ydim<<11); + if (i&0x0f) + { + npoints = clippoly(npoints,i); + if (npoints < 3) continue; + } + + globalpicnum = spr->picnum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + setgotpic(globalpicnum); + if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) continue; + if ((picanm[globalpicnum]&192) != 0) globalpicnum += animateoffs((short)globalpicnum,s); + if (waloff[globalpicnum] == 0) loadtile(globalpicnum); + globalbufplc = waloff[globalpicnum]; + if ((sector[spr->sectnum].ceilingstat&1) > 0) + globalshade = ((long)sector[spr->sectnum].ceilingshade); + else + globalshade = ((long)sector[spr->sectnum].floorshade); + globalshade = max(min(globalshade+spr->shade+6,numpalookups-1),0); + asm3 = FP_OFF(palookup[spr->pal]+(globalshade<<8)); + globvis = globalhisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); + globalpolytype = ((spr->cstat&2)>>1)+1; + + //relative alignment stuff + ox = x2-x1; oy = y2-y1; + i = ox*ox+oy*oy; if (i == 0) continue; i = (65536*16384)/i; + globalx1 = mulscale10(dmulscale10(ox,bakgxvect,oy,bakgyvect),i); + globaly1 = mulscale10(dmulscale10(ox,bakgyvect,-oy,bakgxvect),i); + ox = y1-y4; oy = x4-x1; + i = ox*ox+oy*oy; if (i == 0) continue; i = (65536*16384)/i; + globalx2 = mulscale10(dmulscale10(ox,bakgxvect,oy,bakgyvect),i); + globaly2 = mulscale10(dmulscale10(ox,bakgyvect,-oy,bakgxvect),i); + + ox = picsiz[globalpicnum]; oy = ((ox>>4)&15); ox &= 15; + if (pow2long[ox] != xspan) + { + ox++; + globalx1 = mulscale(globalx1,xspan,ox); + globaly1 = mulscale(globaly1,xspan,ox); + } + + bakx1 = (bakx1>>4)-(xdim<<7); baky1 = (baky1>>4)-(ydim<<7); + globalposx = dmulscale28(-baky1,globalx1,-bakx1,globaly1); + globalposy = dmulscale28(bakx1,globalx2,-baky1,globaly2); + + if ((spr->cstat&2) == 0) + msethlineshift(ox,oy); + else { + if (spr->cstat&512) settransreverse(); else settransnormal(); + tsethlineshift(ox,oy); + } + + if ((spr->cstat&0x4) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx; + asm1 = (globaly1<<2); globalx1 <<= 2; globalposx <<= (20+2); + asm2 = (globalx2<<2); globaly2 <<= 2; globalposy <<= (20+2); + + globalorientation = ((spr->cstat&2)<<7) | ((spr->cstat&512)>>2); // so polymost can get the translucency. ignored in software mode. + fillpolygon(npoints); + } + } + + enddrawing(); //}}} +} + + +// +// loadboard +// +long loadboard(char *filename, char fromwhere, long *daposx, long *daposy, long *daposz, + short *daang, short *dacursectnum) +{ + short fil, i, numsprites; + + i = strlen(filename)-1; + if (filename[i] == 255) { filename[i] = 0; fromwhere = 1; } // JBF 20040119: "compatibility" + if ((fil = kopen4load(filename,fromwhere)) == -1) + { mapversion = 7L; return(-1); } + + kread(fil,&mapversion,4); mapversion = B_LITTLE32(mapversion); + if (mapversion != 7L && mapversion != 8L) { kclose(fil); return(-2); } + + /* + // Enable this for doing map checksum tests + clearbufbyte(&wall, sizeof(wall), 0); + clearbufbyte(§or, sizeof(sector), 0); + clearbufbyte(&sprite, sizeof(sprite), 0); + */ + + initspritelists(); + +#define MYMAXSECTORS (mapversion==7l?MAXSECTORSV7:MAXSECTORSV8) +#define MYMAXWALLS (mapversion==7l?MAXWALLSV7:MAXWALLSV8) +#define MYMAXSPRITES (mapversion==7l?MAXSPRITESV7:MAXSPRITESV8) + + clearbuf(&show2dsector[0],(long)((MYMAXSECTORS+3)>>5),0L); + clearbuf(&show2dsprite[0],(long)((MYMAXSPRITES+3)>>5),0L); + clearbuf(&show2dwall[0],(long)((MYMAXWALLS+3)>>5),0L); + + kread(fil,daposx,4); *daposx = B_LITTLE32(*daposx); + kread(fil,daposy,4); *daposy = B_LITTLE32(*daposy); + kread(fil,daposz,4); *daposz = B_LITTLE32(*daposz); + kread(fil,daang,2); *daang = B_LITTLE16(*daang); + kread(fil,dacursectnum,2); *dacursectnum = B_LITTLE16(*dacursectnum); + + kread(fil,&numsectors,2); numsectors = B_LITTLE16(numsectors); + if (numsectors > MYMAXSECTORS) { kclose(fil); return(-1); } + kread(fil,§or[0],sizeof(sectortype)*numsectors); + for (i=numsectors-1; i>=0; i--) { + sector[i].wallptr = B_LITTLE16(sector[i].wallptr); + sector[i].wallnum = B_LITTLE16(sector[i].wallnum); + sector[i].ceilingz = B_LITTLE32(sector[i].ceilingz); + sector[i].floorz = B_LITTLE32(sector[i].floorz); + sector[i].ceilingstat = B_LITTLE16(sector[i].ceilingstat); + sector[i].floorstat = B_LITTLE16(sector[i].floorstat); + sector[i].ceilingpicnum = B_LITTLE16(sector[i].ceilingpicnum); + sector[i].ceilingheinum = B_LITTLE16(sector[i].ceilingheinum); + sector[i].floorpicnum = B_LITTLE16(sector[i].floorpicnum); + sector[i].floorheinum = B_LITTLE16(sector[i].floorheinum); + sector[i].lotag = B_LITTLE16(sector[i].lotag); + sector[i].hitag = B_LITTLE16(sector[i].hitag); + sector[i].extra = B_LITTLE16(sector[i].extra); + } + + kread(fil,&numwalls,2); numwalls = B_LITTLE16(numwalls); + if (numwalls > MYMAXWALLS) { kclose(fil); return(-1); } + kread(fil,&wall[0],sizeof(walltype)*numwalls); + for (i=numwalls-1; i>=0; i--) { + wall[i].x = B_LITTLE32(wall[i].x); + wall[i].y = B_LITTLE32(wall[i].y); + wall[i].point2 = B_LITTLE16(wall[i].point2); + wall[i].nextwall = B_LITTLE16(wall[i].nextwall); + wall[i].nextsector = B_LITTLE16(wall[i].nextsector); + wall[i].cstat = B_LITTLE16(wall[i].cstat); + wall[i].picnum = B_LITTLE16(wall[i].picnum); + wall[i].overpicnum = B_LITTLE16(wall[i].overpicnum); + wall[i].lotag = B_LITTLE16(wall[i].lotag); + wall[i].hitag = B_LITTLE16(wall[i].hitag); + wall[i].extra = B_LITTLE16(wall[i].extra); + } + + kread(fil,&numsprites,2); numsprites = B_LITTLE16(numsprites); + if (numsprites > MYMAXSPRITES) { kclose(fil); return(-1); } + kread(fil,&sprite[0],sizeof(spritetype)*numsprites); + for (i=numsprites-1; i>=0; i--) { + sprite[i].x = B_LITTLE32(sprite[i].x); + sprite[i].y = B_LITTLE32(sprite[i].y); + sprite[i].z = B_LITTLE32(sprite[i].z); + sprite[i].cstat = B_LITTLE16(sprite[i].cstat); + sprite[i].picnum = B_LITTLE16(sprite[i].picnum); + sprite[i].sectnum = B_LITTLE16(sprite[i].sectnum); + sprite[i].statnum = B_LITTLE16(sprite[i].statnum); + sprite[i].ang = B_LITTLE16(sprite[i].ang); + sprite[i].owner = B_LITTLE16(sprite[i].owner); + sprite[i].xvel = B_LITTLE16(sprite[i].xvel); + sprite[i].yvel = B_LITTLE16(sprite[i].yvel); + sprite[i].zvel = B_LITTLE16(sprite[i].zvel); + sprite[i].lotag = B_LITTLE16(sprite[i].lotag); + sprite[i].hitag = B_LITTLE16(sprite[i].hitag); + sprite[i].extra = B_LITTLE16(sprite[i].extra); + } + + for(i=0;i= startwall) && (theline <= endwall)) + { + sucksect = i; + break; + } + } + return(sucksect); +} + +static void convertv5sectv6(struct sectortypev5 *from, struct sectortypev6 *to) +{ + to->wallptr = from->wallptr; + to->wallnum = from->wallnum; + to->ceilingpicnum = from->ceilingpicnum; + to->floorpicnum = from->floorpicnum; + to->ceilingheinum = from->ceilingheinum; + to->floorheinum = from->floorheinum; + to->ceilingz = from->ceilingz; + to->floorz = from->floorz; + to->ceilingshade = from->ceilingshade; + to->floorshade = from->floorshade; + to->ceilingxpanning = from->ceilingxpanning; + to->floorxpanning = from->floorxpanning; + to->ceilingypanning = from->ceilingypanning; + to->floorypanning = from->floorypanning; + to->ceilingstat = from->ceilingstat; + to->floorstat = from->floorstat; + to->ceilingpal = from->ceilingpal; + to->floorpal = from->floorpal; + to->visibility = from->visibility; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +static void convertv5wallv6(struct walltypev5 *from, struct walltypev6 *to, long i) +{ + to->x = from->x; + to->y = from->y; + to->point2 = from->point2; + to->nextsector = from->nextsector1; + to->nextwall = from->nextwall1; + to->picnum = from->picnum; + to->overpicnum = from->overpicnum; + to->shade = from->shade; + to->pal = sector[sectorofwallv5((short)i)].floorpal; + to->cstat = from->cstat; + to->xrepeat = from->xrepeat; + to->yrepeat = from->yrepeat; + to->xpanning = from->xpanning; + to->ypanning = from->ypanning; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +static void convertv5sprv6(struct spritetypev5 *from, struct spritetypev6 *to) +{ + short j; + to->x = from->x; + to->y = from->y; + to->z = from->z; + to->cstat = from->cstat; + to->shade = from->shade; + + j = from->sectnum; + if ((sector[j].ceilingstat&1) > 0) + to->pal = sector[j].ceilingpal; + else + to->pal = sector[j].floorpal; + + to->clipdist = 32; + to->xrepeat = from->xrepeat; + to->yrepeat = from->yrepeat; + to->xoffset = 0; + to->yoffset = 0; + to->picnum = from->picnum; + to->ang = from->ang; + to->xvel = from->xvel; + to->yvel = from->yvel; + to->zvel = from->zvel; + to->owner = from->owner; + to->sectnum = from->sectnum; + to->statnum = from->statnum; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +static void convertv6sectv7(struct sectortypev6 *from, sectortype *to) +{ + to->ceilingz = from->ceilingz; + to->floorz = from->floorz; + to->wallptr = from->wallptr; + to->wallnum = from->wallnum; + to->ceilingpicnum = from->ceilingpicnum; + to->ceilingheinum = max(min(((long)from->ceilingheinum)<<5,32767),-32768); + if ((from->ceilingstat&2) == 0) to->ceilingheinum = 0; + to->ceilingshade = from->ceilingshade; + to->ceilingpal = from->ceilingpal; + to->ceilingxpanning = from->ceilingxpanning; + to->ceilingypanning = from->ceilingypanning; + to->floorpicnum = from->floorpicnum; + to->floorheinum = max(min(((long)from->floorheinum)<<5,32767),-32768); + if ((from->floorstat&2) == 0) to->floorheinum = 0; + to->floorshade = from->floorshade; + to->floorpal = from->floorpal; + to->floorxpanning = from->floorxpanning; + to->floorypanning = from->floorypanning; + to->ceilingstat = from->ceilingstat; + to->floorstat = from->floorstat; + to->visibility = from->visibility; + to->filler = 0; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +static void convertv6wallv7(struct walltypev6 *from, walltype *to) +{ + to->x = from->x; + to->y = from->y; + to->point2 = from->point2; + to->nextwall = from->nextwall; + to->nextsector = from->nextsector; + to->cstat = from->cstat; + to->picnum = from->picnum; + to->overpicnum = from->overpicnum; + to->shade = from->shade; + to->pal = from->pal; + to->xrepeat = from->xrepeat; + to->yrepeat = from->yrepeat; + to->xpanning = from->xpanning; + to->ypanning = from->ypanning; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +static void convertv6sprv7(struct spritetypev6 *from, spritetype *to) +{ + to->x = from->x; + to->y = from->y; + to->z = from->z; + to->cstat = from->cstat; + to->picnum = from->picnum; + to->shade = from->shade; + to->pal = from->pal; + to->clipdist = from->clipdist; + to->filler = 0; + to->xrepeat = from->xrepeat; + to->yrepeat = from->yrepeat; + to->xoffset = from->xoffset; + to->yoffset = from->yoffset; + to->sectnum = from->sectnum; + to->statnum = from->statnum; + to->ang = from->ang; + to->owner = from->owner; + to->xvel = from->xvel; + to->yvel = from->yvel; + to->zvel = from->zvel; + to->lotag = from->lotag; + to->hitag = from->hitag; + to->extra = from->extra; +} + +// Powerslave uses v6 +// Witchaven 1 and TekWar use v5 +long loadoldboard(char *filename, char fromwhere, long *daposx, long *daposy, long *daposz, + short *daang, short *dacursectnum) +{ + short fil, i, numsprites; + struct sectortypev5 v5sect; + struct walltypev5 v5wall; + struct spritetypev5 v5spr; + struct sectortypev6 v6sect; + struct walltypev6 v6wall; + struct spritetypev6 v6spr; + + i = strlen(filename)-1; + if (filename[i] == 255) { filename[i] = 0; fromwhere = 1; } // JBF 20040119: "compatibility" + if ((fil = kopen4load(filename,fromwhere)) == -1) + { mapversion = 5L; return(-1); } + + kread(fil,&mapversion,4); mapversion = B_LITTLE32(mapversion); + if (mapversion != 5L && mapversion != 6L) { kclose(fil); return(-2); } + + initspritelists(); + + clearbuf(&show2dsector[0],(long)((MAXSECTORS+3)>>5),0L); + clearbuf(&show2dsprite[0],(long)((MAXSPRITES+3)>>5),0L); + clearbuf(&show2dwall[0],(long)((MAXWALLS+3)>>5),0L); + + kread(fil,daposx,4); *daposx = B_LITTLE32(*daposx); + kread(fil,daposy,4); *daposy = B_LITTLE32(*daposy); + kread(fil,daposz,4); *daposz = B_LITTLE32(*daposz); + kread(fil,daang,2); *daang = B_LITTLE16(*daang); + kread(fil,dacursectnum,2); *dacursectnum = B_LITTLE16(*dacursectnum); + + kread(fil,&numsectors,2); numsectors = B_LITTLE16(numsectors); + if (numsectors > MAXSECTORS) { kclose(fil); return(-1); } + for (i=0; i MAXWALLS) { kclose(fil); return(-1); } + for (i=0; i MAXSPRITES) { kclose(fil); return(-1); } + for (i=0; iltextptr; + switch (legaltokens[i].tokenid) { + case 0: // sprite + if (scriptfile_getnumber(script, &whichsprite)) break; + + if ((unsigned)whichsprite >= (unsigned)MAXSPRITES) { + // sprite number out of range + initprintf("Sprite number out of range 0-%d on line %s:%d\n", + MAXSPRITES-1,script->filename, scriptfile_getlinum(script,cmdtokptr)); + whichsprite = -1; + break; + } + + break; + case 1: // angoff + { + int ang; + if (scriptfile_getnumber(script, &ang)) break; + + if (whichsprite < 0) { + // no sprite directive preceeding + initprintf("Ignoring angle offset directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + spriteext[whichsprite].angoff = (short)ang; + } + break; + case 2: // notmd + if (whichsprite < 0) { + // no sprite directive preceeding + initprintf("Ignoring not-MD2/MD3 directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + spriteext[whichsprite].flags |= SPREXT_NOTMD; + break; + case 3: // nomdanim + if (whichsprite < 0) { + // no sprite directive preceeding + initprintf("Ignoring no-MD2/MD3-anim directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + spriteext[whichsprite].flags |= SPREXT_NOMDANIM; + break; + default: + // unrecognised token + break; + } + } + + scriptfile_close(script); + return 0; +} +#else +long loadmaphack(char *filename) { return -1; } +#endif + + +// +// saveboard +// +long saveboard(char *filename, long *daposx, long *daposy, long *daposz, + short *daang, short *dacursectnum) +{ + short fil, i, j, numsprites, ts; + long tl; + sectortype tsect; + walltype twall; + spritetype tspri; + + if ((fil = Bopen(filename,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) + return(-1); + + numsprites = 0; + for(j=0;j MAXSECTORSV7 || numwalls > MAXWALLSV7 || numsprites > MAXSPRITESV7) + mapversion = 8; + else + mapversion = 7; + tl = B_LITTLE32(mapversion); Bwrite(fil,&tl,4); + + tl = B_LITTLE32(*daposx); Bwrite(fil,&tl,4); + tl = B_LITTLE32(*daposy); Bwrite(fil,&tl,4); + tl = B_LITTLE32(*daposz); Bwrite(fil,&tl,4); + ts = B_LITTLE16(*daang); Bwrite(fil,&ts,2); + ts = B_LITTLE16(*dacursectnum); Bwrite(fil,&ts,2); + + ts = B_LITTLE16(numsectors); Bwrite(fil,&ts,2); + for (i=0; i 8) rendmode = 3; // GL renderer + else if (dabpp == 8 && j > 8) rendmode = 0; // going from GL to software activates softpolymost +#endif + + xdim = daxdim; ydim = daydim; + + j = ydim*4*sizeof(long); //Leave room for horizlookup&horizlookup2 + + if (lookups != NULL) + { + if (lookupsalloctype == 0) kkfree((void *)lookups); + if (lookupsalloctype == 1) suckcache((long *)lookups); + lookups = NULL; + } + lookupsalloctype = 0; + if ((lookups = (long *)kkmalloc(j<<1)) == NULL) + { + allocache((long *)&lookups,j<<1,&permanentlock); + lookupsalloctype = 1; + } + + horizlookup = (long *)(lookups); + horizlookup2 = (long *)(FP_OFF(lookups)+j); + horizycent = ((ydim*4)>>1); + + //Force drawrooms to call dosetaspect & recalculate stuff + oxyaspect = oxdimen = oviewingrange = -1; + + setvlinebpl(bytesperline); + j = 0; + for(i=0;i<=ydim;i++) ylookup[i] = j, j += bytesperline; + + setview(0L,0L,xdim-1,ydim-1); + clearallviews(0L); + setbrightness((char)curbrightness,(char *)&palette[0],0); + + if (searchx < 0) { searchx = halfxdimen; searchy = (ydimen>>1); } + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3) { + polymost_glinit(); + polymost_glreset(); + } +#endif + qsetmode = 200; + return(0); +} + + +// +// nextpage +// +void nextpage(void) +{ + long i; + permfifotype *per; + + //char snotbuf[32]; + //j = 0; k = 0; + //for(i=0;i<4096;i++) + // if (waloff[i] != 0) + // { + // sprintf(snotbuf,"%ld-%ld",i,tilesizx[i]*tilesizy[i]); + // printext256((j>>5)*40+32,(j&31)*6,walock[i]>>3,-1,snotbuf,1); + // k += tilesizx[i]*tilesizy[i]; + // j++; + // } + //sprintf(snotbuf,"Total: %ld",k); + //printext256((j>>5)*40+32,(j&31)*6,31,-1,snotbuf,1); + + switch(qsetmode) + { + case 200: + begindrawing(); //{{{ + for(i=permtail;i!=permhead;i=((i+1)&(MAXPERMS-1))) + { + per = &permfifo[i]; + if ((per->pagesleft > 0) && (per->pagesleft <= numpages)) + dorotatesprite(per->sx,per->sy,per->z,per->a,per->picnum, + per->dashade,per->dapalnum,per->dastat, + per->cx1,per->cy1,per->cx2,per->cy2,per->uniqid); + } + enddrawing(); //}}} + + OSD_Draw(); + showframe(0); + + begindrawing(); //{{{ + for(i=permtail;i!=permhead;i=((i+1)&(MAXPERMS-1))) + { + per = &permfifo[i]; + if (per->pagesleft >= 130) + dorotatesprite(per->sx,per->sy,per->z,per->a,per->picnum, + per->dashade,per->dapalnum,per->dastat, + per->cx1,per->cy1,per->cx2,per->cy2,per->uniqid); + + if (per->pagesleft&127) per->pagesleft--; + if (((per->pagesleft&127) == 0) && (i == permtail)) + permtail = ((permtail+1)&(MAXPERMS-1)); + } + enddrawing(); //}}} + break; + + case 350: + case 480: + break; + } + faketimerhandler(); + + if ((totalclock >= lastageclock+8) || (totalclock < lastageclock)) + { lastageclock = totalclock; agecache(); } + +#ifdef USE_OPENGL + omdtims = mdtims; mdtims = getticks(); + if (((unsigned long)(mdtims-omdtims)) > 10000) omdtims = mdtims; +#endif + + beforedrawrooms = 1; + numframes++; +} + + +// +// loadpics +// +long loadpics(char *filename, long askedsize) +{ + long offscount, localtilestart, localtileend, dasiz; + short fil, i, j, k; + + Bstrcpy(artfilename,filename); + + for(i=0;i>5),0L); + + //try dpmi_DETERMINEMAXREALALLOC! + + cachesize = min((long)((Bgetsysmemsize()/100)*60),max(artsize,askedsize)); + while ((pic = kkmalloc(cachesize)) == NULL) + { + cachesize -= 65536L; + if (cachesize < 65536) return(-1); + } + initcache((FP_OFF(pic)+15)&0xfffffff0,(cachesize-((-FP_OFF(pic))&15))&0xfffffff0); + + for(i=0;i 1) && (pow2long[j] > tilesizx[i])) j--; + picsiz[i] = ((char)j); + j = 15; + while ((j > 1) && (pow2long[j] > tilesizy[i])) j--; + picsiz[i] += ((char)(j<<4)); + } + + artfil = -1; + artfilnum = -1; + artfilplc = 0L; + + return(0); +} + + +// +// loadtile +// +char cachedebug = 0; +void loadtile(short tilenume) +{ + char *ptr; + long i, dasiz; + + if ((unsigned)tilenume >= (unsigned)MAXTILES) return; + dasiz = tilesizx[tilenume]*tilesizy[tilenume]; + if (dasiz <= 0) return; + + i = tilefilenum[tilenume]; + if (i != artfilnum) + { + if (artfil != -1) kclose(artfil); + artfilnum = i; + artfilplc = 0L; + + artfilename[7] = (i%10)+48; + artfilename[6] = ((i/10)%10)+48; + artfilename[5] = ((i/100)%10)+48; + artfil = kopen4load(artfilename,0); + faketimerhandler(); + } + + if (cachedebug) printOSD("Tile:%d\n",tilenume); + + if (waloff[tilenume] == 0) + { + walock[tilenume] = 199; + allocache(&waloff[tilenume],dasiz,&walock[tilenume]); + } + + if (artfilplc != tilefileoffs[tilenume]) + { + klseek(artfil,tilefileoffs[tilenume]-artfilplc,BSEEK_CUR); + faketimerhandler(); + } + ptr = (char *)waloff[tilenume]; + kread(artfil,ptr,dasiz); + faketimerhandler(); + artfilplc = tilefileoffs[tilenume]+dasiz; +} + + +// +// allocatepermanenttile +// +long allocatepermanenttile(short tilenume, long xsiz, long ysiz) +{ + long j, dasiz; + + if ((xsiz <= 0) || (ysiz <= 0) || ((unsigned)tilenume >= (unsigned)MAXTILES)) + return(0); + + dasiz = xsiz*ysiz; + + walock[tilenume] = 255; + allocache(&waloff[tilenume],dasiz,&walock[tilenume]); + + tilesizx[tilenume] = xsiz; + tilesizy[tilenume] = ysiz; + picanm[tilenume] = 0; + + j = 15; while ((j > 1) && (pow2long[j] > xsiz)) j--; + picsiz[tilenume] = ((char)j); + j = 15; while ((j > 1) && (pow2long[j] > ysiz)) j--; + picsiz[tilenume] += ((char)(j<<4)); + + return(waloff[tilenume]); +} + + +// +// copytilepiece +// +void copytilepiece(long tilenume1, long sx1, long sy1, long xsiz, long ysiz, + long tilenume2, long sx2, long sy2) +{ + char *ptr1, *ptr2, dat; + long xsiz1, ysiz1, xsiz2, ysiz2, i, j, x1, y1, x2, y2; + + xsiz1 = tilesizx[tilenume1]; ysiz1 = tilesizy[tilenume1]; + xsiz2 = tilesizx[tilenume2]; ysiz2 = tilesizy[tilenume2]; + if ((xsiz1 > 0) && (ysiz1 > 0) && (xsiz2 > 0) && (ysiz2 > 0)) + { + if (waloff[tilenume1] == 0) loadtile(tilenume1); + if (waloff[tilenume2] == 0) loadtile(tilenume2); + + x1 = sx1; + for(i=0;i= 0) && (y2 >= 0) && (x2 < xsiz2) && (y2 < ysiz2)) + { + ptr1 = (char *)(waloff[tilenume1] + x1*ysiz1 + y1); + ptr2 = (char *)(waloff[tilenume2] + x2*ysiz2 + y2); + dat = *ptr1; + if (dat != 255) + *ptr2 = *ptr1; + } + + y1++; if (y1 >= ysiz1) y1 = 0; + } + x1++; if (x1 >= xsiz1) x1 = 0; + } + } +} + + +// +// qloadkvx +// +#ifdef SUPERBUILD +long qloadkvx(long voxindex, char *filename) +{ + long i, fil, dasiz, lengcnt, lengtot; + char *ptr; + + if ((fil = kopen4load(filename,0)) == -1) return -1; + + lengcnt = 0; + lengtot = kfilelength(fil); + + for(i=0;i= lengtot-768) break; + } + kclose(fil); + +#if defined POLYMOST && defined USE_OPENGL + if (voxmodels[voxindex]) { + voxfree(voxmodels[voxindex]); + voxmodels[voxindex] = NULL; + } + voxmodels[voxindex] = voxload(filename); +#endif + return 0; +} +#endif + + +// +// clipinsidebox +// +long clipinsidebox(long x, long y, short wallnum, long walldist) +{ + walltype *wal; + long x1, y1, x2, y2, r; + + r = (walldist<<1); + wal = &wall[wallnum]; x1 = wal->x+walldist-x; y1 = wal->y+walldist-y; + wal = &wall[wal->point2]; x2 = wal->x+walldist-x; y2 = wal->y+walldist-y; + + if ((x1 < 0) && (x2 < 0)) return(0); + if ((y1 < 0) && (y2 < 0)) return(0); + if ((x1 >= r) && (x2 >= r)) return(0); + if ((y1 >= r) && (y2 >= r)) return(0); + + x2 -= x1; y2 -= y1; + if (x2*(walldist-y1) >= y2*(walldist-x1)) //Front + { + if (x2 > 0) x2 *= (0-y1); else x2 *= (r-y1); + if (y2 > 0) y2 *= (r-x1); else y2 *= (0-x1); + return(x2 < y2); + } + if (x2 > 0) x2 *= (r-y1); else x2 *= (0-y1); + if (y2 > 0) y2 *= (0-x1); else y2 *= (r-x1); + return((x2 >= y2)<<1); +} + + +// +// clipinsideboxline +// +long clipinsideboxline(long x, long y, long x1, long y1, long x2, long y2, long walldist) +{ + long r; + + r = (walldist<<1); + + x1 += walldist-x; x2 += walldist-x; + if ((x1 < 0) && (x2 < 0)) return(0); + if ((x1 >= r) && (x2 >= r)) return(0); + + y1 += walldist-y; y2 += walldist-y; + if ((y1 < 0) && (y2 < 0)) return(0); + if ((y1 >= r) && (y2 >= r)) return(0); + + x2 -= x1; y2 -= y1; + if (x2*(walldist-y1) >= y2*(walldist-x1)) //Front + { + if (x2 > 0) x2 *= (0-y1); else x2 *= (r-y1); + if (y2 > 0) y2 *= (r-x1); else y2 *= (0-x1); + return(x2 < y2); + } + if (x2 > 0) x2 *= (r-y1); else x2 *= (0-y1); + if (y2 > 0) y2 *= (0-x1); else y2 *= (r-x1); + return((x2 >= y2)<<1); +} + + +// +// inside +// +long inside(long x, long y, short sectnum) +{ + walltype *wal; + long i, x1, y1, x2, y2; + unsigned long cnt; + + if ((sectnum < 0) || (sectnum >= numsectors)) return(-1); + + cnt = 0; + wal = &wall[sector[sectnum].wallptr]; + i = sector[sectnum].wallnum; + do + { + y1 = wal->y-y; y2 = wall[wal->point2].y-y; + if ((y1^y2) < 0) + { + x1 = wal->x-x; x2 = wall[wal->point2].x-x; + if ((x1^x2) >= 0) cnt ^= x1; else cnt ^= (x1*y2-x2*y1)^y2; + } + wal++; i--; + } while (i); + return(cnt>>31); +} + + +// +// getangle +// +long getangle(long xvect, long yvect) +{ + if ((xvect|yvect) == 0) return(0); + if (xvect == 0) return(512+((yvect<0)<<10)); + if (yvect == 0) return(((xvect<0)<<10)); + if (xvect == yvect) return(256+((xvect<0)<<10)); + if (xvect == -yvect) return(768+((xvect>0)<<10)); + if (klabs(xvect) > klabs(yvect)) + return(((radarang[640+scale(160,yvect,xvect)]>>6)+((xvect<0)<<10))&2047); + return(((radarang[640-scale(160,xvect,yvect)]>>6)+512+((yvect<0)<<10))&2047); +} + + +// +// ksqrt +// +long ksqrt(long num) +{ + return(nsqrtasm(num)); +} + + +// +// krecip +// +long krecip(long num) +{ + return(krecipasm(num)); +} + +// +// setsprite +// +long setsprite(short spritenum, long newx, long newy, long newz) +{ + short tempsectnum; + + sprite[spritenum].x = newx; + sprite[spritenum].y = newy; + sprite[spritenum].z = newz; + + tempsectnum = sprite[spritenum].sectnum; +#ifdef SETSPRITEZ + updatesectorz(newx,newy,newz,&tempsectnum); +#else + updatesector(newx,newy,&tempsectnum); +#endif + if (tempsectnum < 0) + return(-1); + if (tempsectnum != sprite[spritenum].sectnum) + changespritesect(spritenum,tempsectnum); + + return(0); +} + + +// +// insertsprite +// +long insertsprite(short sectnum, short statnum) +{ + insertspritestat(statnum); + return(insertspritesect(sectnum)); +} + + +// +// deletesprite +// +long deletesprite(short spritenum) +{ + deletespritestat(spritenum); + return(deletespritesect(spritenum)); +} + + +// +// changespritesect +// +long changespritesect(short spritenum, short newsectnum) +{ + if ((newsectnum < 0) || (newsectnum > MAXSECTORS)) return(-1); + if (sprite[spritenum].sectnum == newsectnum) return(0); + if (sprite[spritenum].sectnum == MAXSECTORS) return(-1); + if (deletespritesect(spritenum) < 0) return(-1); + insertspritesect(newsectnum); + return(0); +} + + +// +// changespritestat +// +long changespritestat(short spritenum, short newstatnum) +{ + if ((newstatnum < 0) || (newstatnum > MAXSTATUS)) return(-1); + if (sprite[spritenum].statnum == newstatnum) return(0); + if (sprite[spritenum].statnum == MAXSTATUS) return(-1); + if (deletespritestat(spritenum) < 0) return(-1); + insertspritestat(newstatnum); + return(0); +} + + +// +// nextsectorneighborz +// +long nextsectorneighborz(short sectnum, long thez, short topbottom, short direction) +{ + walltype *wal; + long i, testz, nextz; + short sectortouse; + + if (direction == 1) nextz = 0x7fffffff; else nextz = 0x80000000; + + sectortouse = -1; + + wal = &wall[sector[sectnum].wallptr]; + i = sector[sectnum].wallnum; + do + { + if (wal->nextsector >= 0) + { + if (topbottom == 1) + { + testz = sector[wal->nextsector].floorz; + if (direction == 1) + { + if ((testz > thez) && (testz < nextz)) + { + nextz = testz; + sectortouse = wal->nextsector; + } + } + else + { + if ((testz < thez) && (testz > nextz)) + { + nextz = testz; + sectortouse = wal->nextsector; + } + } + } + else + { + testz = sector[wal->nextsector].ceilingz; + if (direction == 1) + { + if ((testz > thez) && (testz < nextz)) + { + nextz = testz; + sectortouse = wal->nextsector; + } + } + else + { + if ((testz < thez) && (testz > nextz)) + { + nextz = testz; + sectortouse = wal->nextsector; + } + } + } + } + wal++; + i--; + } while (i != 0); + + return(sectortouse); +} + + +// +// cansee +// +long cansee(long x1, long y1, long z1, short sect1, long x2, long y2, long z2, short sect2) +{ + sectortype *sec; + walltype *wal, *wal2; + long i, cnt, nexts, x, y, z, cz, fz, dasectnum, dacnt, danum; + long x21, y21, z21, x31, y31, x34, y34, bot, t; + + if ((x1 == x2) && (y1 == y2)) return(sect1 == sect2); + + x21 = x2-x1; y21 = y2-y1; z21 = z2-z1; + + clipsectorlist[0] = sect1; danum = 1; + for(dacnt=0;dacntwallnum,wal=&wall[sec->wallptr];cnt>0;cnt--,wal++) + { + wal2 = &wall[wal->point2]; + x31 = wal->x-x1; x34 = wal->x-wal2->x; + y31 = wal->y-y1; y34 = wal->y-wal2->y; + + bot = y21*x34-x21*y34; if (bot <= 0) continue; + t = y21*x31-x21*y31; if ((unsigned)t >= (unsigned)bot) continue; + t = y31*x34-x31*y34; if ((unsigned)t >= (unsigned)bot) continue; + + nexts = wal->nextsector; + if ((nexts < 0) || (wal->cstat&32)) return(0); + + t = divscale24(t,bot); + x = x1 + mulscale24(x21,t); + y = y1 + mulscale24(y21,t); + z = z1 + mulscale24(z21,t); + + getzsofslope((short)dasectnum,x,y,&cz,&fz); + if ((z <= cz) || (z >= fz)) return(0); + getzsofslope((short)nexts,x,y,&cz,&fz); + if ((z <= cz) || (z >= fz)) return(0); + + for(i=danum-1;i>=0;i--) if (clipsectorlist[i] == nexts) break; + if (i < 0) clipsectorlist[danum++] = nexts; + } + } + for(i=danum-1;i>=0;i--) if (clipsectorlist[i] == sect2) return(1); + return(0); +} + + +// +// hitscan +// +long hitscan(long xs, long ys, long zs, short sectnum, long vx, long vy, long vz, + short *hitsect, short *hitwall, short *hitsprite, + long *hitx, long *hity, long *hitz, unsigned long cliptype) +{ + sectortype *sec; + walltype *wal, *wal2; + spritetype *spr; + long z, zz, x1, y1=0, z1=0, x2, y2, x3, y3, x4, y4, intx, inty, intz; + long topt, topu, bot, dist, offx, offy, cstat; + long i, j, k, l, tilenum, xoff, yoff, dax, day, daz, daz2; + long ang, cosang, sinang, xspan, yspan, xrepeat, yrepeat; + long dawalclipmask, dasprclipmask; + short tempshortcnt, tempshortnum, dasector, startwall, endwall; + short nextsector; + char clipyou; + + *hitsect = -1; *hitwall = -1; *hitsprite = -1; + if (sectnum < 0) return(-1); + + *hitx = hitscangoalx; *hity = hitscangoaly; + + dawalclipmask = (cliptype&65535); + dasprclipmask = (cliptype>>16); + + clipsectorlist[0] = sectnum; + tempshortcnt = 0; tempshortnum = 1; + do + { + dasector = clipsectorlist[tempshortcnt]; sec = §or[dasector]; + + x1 = 0x7fffffff; + if (sec->ceilingstat&2) + { + wal = &wall[sec->wallptr]; wal2 = &wall[wal->point2]; + dax = wal2->x-wal->x; day = wal2->y-wal->y; + i = nsqrtasm(dax*dax+day*day); if (i == 0) continue; + i = divscale15(sec->ceilingheinum,i); + dax *= i; day *= i; + + j = (vz<<8)-dmulscale15(dax,vy,-day,vx); + if (j != 0) + { + i = ((sec->ceilingz-zs)<<8)+dmulscale15(dax,ys-wal->y,-day,xs-wal->x); + if (((i^j) >= 0) && ((klabs(i)>>1) < klabs(j))) + { + i = divscale30(i,j); + x1 = xs + mulscale30(vx,i); + y1 = ys + mulscale30(vy,i); + z1 = zs + mulscale30(vz,i); + } + } + } + else if ((vz < 0) && (zs >= sec->ceilingz)) + { + z1 = sec->ceilingz; i = z1-zs; + if ((klabs(i)>>1) < -vz) + { + i = divscale30(i,vz); + x1 = xs + mulscale30(vx,i); + y1 = ys + mulscale30(vy,i); + } + } + if ((x1 != 0x7fffffff) && (klabs(x1-xs)+klabs(y1-ys) < klabs((*hitx)-xs)+klabs((*hity)-ys))) + if (inside(x1,y1,dasector) != 0) + { + *hitsect = dasector; *hitwall = -1; *hitsprite = -1; + *hitx = x1; *hity = y1; *hitz = z1; + } + + x1 = 0x7fffffff; + if (sec->floorstat&2) + { + wal = &wall[sec->wallptr]; wal2 = &wall[wal->point2]; + dax = wal2->x-wal->x; day = wal2->y-wal->y; + i = nsqrtasm(dax*dax+day*day); if (i == 0) continue; + i = divscale15(sec->floorheinum,i); + dax *= i; day *= i; + + j = (vz<<8)-dmulscale15(dax,vy,-day,vx); + if (j != 0) + { + i = ((sec->floorz-zs)<<8)+dmulscale15(dax,ys-wal->y,-day,xs-wal->x); + if (((i^j) >= 0) && ((klabs(i)>>1) < klabs(j))) + { + i = divscale30(i,j); + x1 = xs + mulscale30(vx,i); + y1 = ys + mulscale30(vy,i); + z1 = zs + mulscale30(vz,i); + } + } + } + else if ((vz > 0) && (zs <= sec->floorz)) + { + z1 = sec->floorz; i = z1-zs; + if ((klabs(i)>>1) < vz) + { + i = divscale30(i,vz); + x1 = xs + mulscale30(vx,i); + y1 = ys + mulscale30(vy,i); + } + } + if ((x1 != 0x7fffffff) && (klabs(x1-xs)+klabs(y1-ys) < klabs((*hitx)-xs)+klabs((*hity)-ys))) + if (inside(x1,y1,dasector) != 0) + { + *hitsect = dasector; *hitwall = -1; *hitsprite = -1; + *hitx = x1; *hity = y1; *hitz = z1; + } + + startwall = sec->wallptr; endwall = startwall + sec->wallnum; + for(z=startwall,wal=&wall[startwall];zpoint2]; + x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y; + + if ((x1-xs)*(y2-ys) < (x2-xs)*(y1-ys)) continue; + if (rintersect(xs,ys,zs,vx,vy,vz,x1,y1,x2,y2,&intx,&inty,&intz) == 0) continue; + + if (klabs(intx-xs)+klabs(inty-ys) >= klabs((*hitx)-xs)+klabs((*hity)-ys)) continue; + + nextsector = wal->nextsector; + if ((nextsector < 0) || (wal->cstat&dawalclipmask)) + { + *hitsect = dasector; *hitwall = z; *hitsprite = -1; + *hitx = intx; *hity = inty; *hitz = intz; + continue; + } + getzsofslope(nextsector,intx,inty,&daz,&daz2); + if ((intz <= daz) || (intz >= daz2)) + { + *hitsect = dasector; *hitwall = z; *hitsprite = -1; + *hitx = intx; *hity = inty; *hitz = intz; + continue; + } + + for(zz=tempshortnum-1;zz>=0;zz--) + if (clipsectorlist[zz] == nextsector) break; + if (zz < 0) clipsectorlist[tempshortnum++] = nextsector; + } + + for(z=headspritesect[dasector];z>=0;z=nextspritesect[z]) + { + spr = &sprite[z]; + cstat = spr->cstat; +#ifdef POLYMOST + if (!hitallsprites) +#endif + if ((cstat&dasprclipmask) == 0) continue; + + x1 = spr->x; y1 = spr->y; z1 = spr->z; + switch(cstat&48) + { + case 0: + topt = vx*(x1-xs) + vy*(y1-ys); if (topt <= 0) continue; + bot = vx*vx + vy*vy; if (bot == 0) continue; + + intz = zs+scale(vz,topt,bot); + + i = (tilesizy[spr->picnum]*spr->yrepeat<<2); + if (cstat&128) z1 += (i>>1); + if (picanm[spr->picnum]&0x00ff0000) z1 -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + if ((intz > z1) || (intz < z1-i)) continue; + topu = vx*(y1-ys) - vy*(x1-xs); + + offx = scale(vx,topu,bot); + offy = scale(vy,topu,bot); + dist = offx*offx + offy*offy; + i = tilesizx[spr->picnum]*spr->xrepeat; i *= i; + if (dist > (i>>7)) continue; + intx = xs + scale(vx,topt,bot); + inty = ys + scale(vy,topt,bot); + + if (klabs(intx-xs)+klabs(inty-ys) > klabs((*hitx)-xs)+klabs((*hity)-ys)) continue; + + *hitsect = dasector; *hitwall = -1; *hitsprite = z; + *hitx = intx; *hity = inty; *hitz = intz; + break; + case 16: + //These lines get the 2 points of the rotated sprite + //Given: (x1, y1) starts out as the center point + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + + if ((cstat&64) != 0) //back side of 1-way sprite + if ((x1-xs)*(y2-ys) < (x2-xs)*(y1-ys)) continue; + + if (rintersect(xs,ys,zs,vx,vy,vz,x1,y1,x2,y2,&intx,&inty,&intz) == 0) continue; + + if (klabs(intx-xs)+klabs(inty-ys) > klabs((*hitx)-xs)+klabs((*hity)-ys)) continue; + + k = ((tilesizy[spr->picnum]*spr->yrepeat)<<2); + if (cstat&128) daz = spr->z+(k>>1); else daz = spr->z; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + if ((intz < daz) && (intz > daz-k)) + { + *hitsect = dasector; *hitwall = -1; *hitsprite = z; + *hitx = intx; *hity = inty; *hitz = intz; + } + break; + case 32: + if (vz == 0) continue; + intz = z1; + if (((intz-zs)^vz) < 0) continue; + if ((cstat&64) != 0) + if ((zs > intz) == ((cstat&8)==0)) continue; + + intx = xs+scale(intz-zs,vx,vz); + inty = ys+scale(intz-zs,vy,vz); + + if (klabs(intx-xs)+klabs(inty-ys) > klabs((*hitx)-xs)+klabs((*hity)-ys)) continue; + + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((cstat&4) > 0) xoff = -xoff; + if ((cstat&8) > 0) yoff = -yoff; + + ang = spr->ang; + cosang = sintable[(ang+512)&2047]; sinang = sintable[ang]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + x1 += dmulscale16(sinang,dax,cosang,day)-intx; + y1 += dmulscale16(sinang,day,-cosang,dax)-inty; + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang,l); + y2 = y1 + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; + k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; + + clipyou = 0; + if ((y1^y2) < 0) + { + if ((x1^x2) < 0) clipyou ^= (x1*y2= 0) clipyou ^= 1; + } + if ((y2^y3) < 0) + { + if ((x2^x3) < 0) clipyou ^= (x2*y3= 0) clipyou ^= 1; + } + if ((y3^y4) < 0) + { + if ((x3^x4) < 0) clipyou ^= (x3*y4= 0) clipyou ^= 1; + } + if ((y4^y1) < 0) + { + if ((x4^x1) < 0) clipyou ^= (x4*y1= 0) clipyou ^= 1; + } + + if (clipyou != 0) + { + *hitsect = dasector; *hitwall = -1; *hitsprite = z; + *hitx = intx; *hity = inty; *hitz = intz; + } + break; + } + } + tempshortcnt++; + } while (tempshortcnt < tempshortnum); + return(0); +} + + +// +// neartag +// +long neartag(long xs, long ys, long zs, short sectnum, short ange, short *neartagsector, short *neartagwall, short *neartagsprite, long *neartaghitdist, long neartagrange, char tagsearch) +{ + walltype *wal, *wal2; + spritetype *spr; + long i, z, zz, xe, ye, ze, x1, y1, z1, x2, y2, intx, inty, intz; + long topt, topu, bot, dist, offx, offy, vx, vy, vz; + short tempshortcnt, tempshortnum, dasector, startwall, endwall; + short nextsector, good; + + *neartagsector = -1; *neartagwall = -1; *neartagsprite = -1; + *neartaghitdist = 0; + + if (sectnum < 0) return(0); + if ((tagsearch < 1) || (tagsearch > 3)) return(0); + + vx = mulscale14(sintable[(ange+2560)&2047],neartagrange); xe = xs+vx; + vy = mulscale14(sintable[(ange+2048)&2047],neartagrange); ye = ys+vy; + vz = 0; ze = 0; + + clipsectorlist[0] = sectnum; + tempshortcnt = 0; tempshortnum = 1; + + do + { + dasector = clipsectorlist[tempshortcnt]; + + startwall = sector[dasector].wallptr; + endwall = startwall + sector[dasector].wallnum - 1; + for(z=startwall,wal=&wall[startwall];z<=endwall;z++,wal++) + { + wal2 = &wall[wal->point2]; + x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y; + + nextsector = wal->nextsector; + + good = 0; + if (nextsector >= 0) + { + if ((tagsearch&1) && sector[nextsector].lotag) good |= 1; + if ((tagsearch&2) && sector[nextsector].hitag) good |= 1; + } + if ((tagsearch&1) && wal->lotag) good |= 2; + if ((tagsearch&2) && wal->hitag) good |= 2; + + if ((good == 0) && (nextsector < 0)) continue; + if ((x1-xs)*(y2-ys) < (x2-xs)*(y1-ys)) continue; + + if (lintersect(xs,ys,zs,xe,ye,ze,x1,y1,x2,y2,&intx,&inty,&intz) == 1) + { + if (good != 0) + { + if (good&1) *neartagsector = nextsector; + if (good&2) *neartagwall = z; + *neartaghitdist = dmulscale14(intx-xs,sintable[(ange+2560)&2047],inty-ys,sintable[(ange+2048)&2047]); + xe = intx; ye = inty; ze = intz; + } + if (nextsector >= 0) + { + for(zz=tempshortnum-1;zz>=0;zz--) + if (clipsectorlist[zz] == nextsector) break; + if (zz < 0) clipsectorlist[tempshortnum++] = nextsector; + } + } + } + + for(z=headspritesect[dasector];z>=0;z=nextspritesect[z]) + { + spr = &sprite[z]; + + good = 0; + if ((tagsearch&1) && spr->lotag) good |= 1; + if ((tagsearch&2) && spr->hitag) good |= 1; + if (good != 0) + { + x1 = spr->x; y1 = spr->y; z1 = spr->z; + + topt = vx*(x1-xs) + vy*(y1-ys); + if (topt > 0) + { + bot = vx*vx + vy*vy; + if (bot != 0) + { + intz = zs+scale(vz,topt,bot); + i = tilesizy[spr->picnum]*spr->yrepeat; + if (spr->cstat&128) z1 += (i<<1); + if (picanm[spr->picnum]&0x00ff0000) z1 -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + if ((intz <= z1) && (intz >= z1-(i<<2))) + { + topu = vx*(y1-ys) - vy*(x1-xs); + + offx = scale(vx,topu,bot); + offy = scale(vy,topu,bot); + dist = offx*offx + offy*offy; + i = (tilesizx[spr->picnum]*spr->xrepeat); i *= i; + if (dist <= (i>>7)) + { + intx = xs + scale(vx,topt,bot); + inty = ys + scale(vy,topt,bot); + if (klabs(intx-xs)+klabs(inty-ys) < klabs(xe-xs)+klabs(ye-ys)) + { + *neartagsprite = z; + *neartaghitdist = dmulscale14(intx-xs,sintable[(ange+2560)&2047],inty-ys,sintable[(ange+2048)&2047]); + xe = intx; + ye = inty; + ze = intz; + } + } + } + } + } + } + } + + tempshortcnt++; + } while (tempshortcnt < tempshortnum); + return(0); +} + + +// +// dragpoint +// +void dragpoint(short pointhighlight, long dax, long day) +{ + short cnt, tempshort; + + wall[pointhighlight].x = dax; + wall[pointhighlight].y = day; + + cnt = MAXWALLS; + tempshort = pointhighlight; //search points CCW + do + { + if (wall[tempshort].nextwall >= 0) + { + tempshort = wall[wall[tempshort].nextwall].point2; + wall[tempshort].x = dax; + wall[tempshort].y = day; + } + else + { + tempshort = pointhighlight; //search points CW if not searched all the way around + do + { + if (wall[lastwall(tempshort)].nextwall >= 0) + { + tempshort = wall[lastwall(tempshort)].nextwall; + wall[tempshort].x = dax; + wall[tempshort].y = day; + } + else + { + break; + } + cnt--; + } + while ((tempshort != pointhighlight) && (cnt > 0)); + break; + } + cnt--; + } + while ((tempshort != pointhighlight) && (cnt > 0)); +} + + +// +// lastwall +// +long lastwall(short point) +{ + long i, j, cnt; + + if ((point > 0) && (wall[point-1].point2 == point)) return(point-1); + i = point; + cnt = MAXWALLS; + do + { + j = wall[i].point2; + if (j == point) return(i); + i = j; + cnt--; + } while (cnt > 0); + return(point); +} + + + +#define addclipline(dax1, day1, dax2, day2, daoval) \ +{ \ + if (clipnum < MAXCLIPNUM) { \ + clipit[clipnum].x1 = dax1; clipit[clipnum].y1 = day1; \ + clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2; \ + clipobjectval[clipnum] = daoval; \ + clipnum++; \ + } \ +} \ + +long clipmoveboxtracenum = 3; + +// +// clipmove +// +long clipmove (long *x, long *y, long *z, short *sectnum, + long xvect, long yvect, + long walldist, long ceildist, long flordist, unsigned long cliptype) +{ + walltype *wal, *wal2; + spritetype *spr; + sectortype *sec, *sec2; + long i, j, templong1, templong2; + long oxvect, oyvect, goalx, goaly, intx, inty, lx, ly, retval; + long k, l, clipsectcnt, startwall, endwall, cstat, dasect; + long x1, y1, x2, y2, cx, cy, rad, xmin, ymin, xmax, ymax, daz, daz2; + long bsz, dax, day, xoff, yoff, xspan, yspan, cosang, sinang, tilenum; + long xrepeat, yrepeat, gx, gy, dx, dy, dasprclipmask, dawalclipmask; + long hitwall, cnt, clipyou; + + if (((xvect|yvect) == 0) || (*sectnum < 0)) return(0); + retval = 0; + + oxvect = xvect; + oyvect = yvect; + + goalx = (*x) + (xvect>>14); + goaly = (*y) + (yvect>>14); + + + clipnum = 0; + + cx = (((*x)+goalx)>>1); + cy = (((*y)+goaly)>>1); + //Extra walldist for sprites on sector lines + gx = goalx-(*x); gy = goaly-(*y); + rad = nsqrtasm(gx*gx + gy*gy) + MAXCLIPDIST+walldist + 8; + xmin = cx-rad; ymin = cy-rad; + xmax = cx+rad; ymax = cy+rad; + + dawalclipmask = (cliptype&65535); //CLIPMASK0 = 0x00010001 + dasprclipmask = (cliptype>>16); //CLIPMASK1 = 0x01000040 + + clipsectorlist[0] = (*sectnum); + clipsectcnt = 0; clipsectnum = 1; + do + { + dasect = clipsectorlist[clipsectcnt++]; + sec = §or[dasect]; + startwall = sec->wallptr; endwall = startwall + sec->wallnum; + for(j=startwall,wal=&wall[startwall];jpoint2]; + if ((wal->x < xmin) && (wal2->x < xmin)) continue; + if ((wal->x > xmax) && (wal2->x > xmax)) continue; + if ((wal->y < ymin) && (wal2->y < ymin)) continue; + if ((wal->y > ymax) && (wal2->y > ymax)) continue; + + x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y; + + dx = x2-x1; dy = y2-y1; + if (dx*((*y)-y1) < ((*x)-x1)*dy) continue; //If wall's not facing you + + if (dx > 0) dax = dx*(ymin-y1); else dax = dx*(ymax-y1); + if (dy > 0) day = dy*(xmax-x1); else day = dy*(xmin-x1); + if (dax >= day) continue; + + clipyou = 0; + if ((wal->nextsector < 0) || (wal->cstat&dawalclipmask)) clipyou = 1; + else if (editstatus == 0) + { + if (rintersect(*x,*y,0,gx,gy,0,x1,y1,x2,y2,&dax,&day,&daz) == 0) + dax = *x, day = *y; + daz = getflorzofslope((short)dasect,dax,day); + daz2 = getflorzofslope(wal->nextsector,dax,day); + + sec2 = §or[wal->nextsector]; + if (daz2 < daz-(1<<8)) + if ((sec2->floorstat&1) == 0) + if ((*z) >= daz2-(flordist-1)) clipyou = 1; + if (clipyou == 0) + { + daz = getceilzofslope((short)dasect,dax,day); + daz2 = getceilzofslope(wal->nextsector,dax,day); + if (daz2 > daz+(1<<8)) + if ((sec2->ceilingstat&1) == 0) + if ((*z) <= daz2+(ceildist-1)) clipyou = 1; + } + } + + if (clipyou) + { + //Add 2 boxes at endpoints + bsz = walldist; if (gx < 0) bsz = -bsz; + addclipline(x1-bsz,y1-bsz,x1-bsz,y1+bsz,(short)j+32768); + addclipline(x2-bsz,y2-bsz,x2-bsz,y2+bsz,(short)j+32768); + bsz = walldist; if (gy < 0) bsz = -bsz; + addclipline(x1+bsz,y1-bsz,x1-bsz,y1-bsz,(short)j+32768); + addclipline(x2+bsz,y2-bsz,x2-bsz,y2-bsz,(short)j+32768); + + dax = walldist; if (dy > 0) dax = -dax; + day = walldist; if (dx < 0) day = -day; + addclipline(x1+dax,y1+day,x2+dax,y2+day,(short)j+32768); + } + else + { + for(i=clipsectnum-1;i>=0;i--) + if (wal->nextsector == clipsectorlist[i]) break; + if (i < 0) clipsectorlist[clipsectnum++] = wal->nextsector; + } + } + + for(j=headspritesect[dasect];j>=0;j=nextspritesect[j]) + { + spr = &sprite[j]; + cstat = spr->cstat; + if ((cstat&dasprclipmask) == 0) continue; + x1 = spr->x; y1 = spr->y; + switch(cstat&48) + { + case 0: + if ((x1 >= xmin) && (x1 <= xmax) && (y1 >= ymin) && (y1 <= ymax)) + { + k = ((tilesizy[spr->picnum]*spr->yrepeat)<<2); + if (cstat&128) daz = spr->z+(k>>1); else daz = spr->z; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + if (((*z) < daz+ceildist) && ((*z) > daz-k-flordist)) + { + bsz = (spr->clipdist<<2)+walldist; if (gx < 0) bsz = -bsz; + addclipline(x1-bsz,y1-bsz,x1-bsz,y1+bsz,(short)j+49152); + bsz = (spr->clipdist<<2)+walldist; if (gy < 0) bsz = -bsz; + addclipline(x1+bsz,y1-bsz,x1-bsz,y1-bsz,(short)j+49152); + } + } + break; + case 16: + k = ((tilesizy[spr->picnum]*spr->yrepeat)<<2); + if (cstat&128) daz = spr->z+(k>>1); else daz = spr->z; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + daz2 = daz-k; + daz += ceildist; daz2 -= flordist; + if (((*z) < daz) && ((*z) > daz2)) + { + //These lines get the 2 points of the rotated sprite + //Given: (x1, y1) starts out as the center point + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + if (clipinsideboxline(cx,cy,x1,y1,x2,y2,rad) != 0) + { + dax = mulscale14(sintable[(spr->ang+256+512)&2047],walldist); + day = mulscale14(sintable[(spr->ang+256)&2047],walldist); + + if ((x1-(*x))*(y2-(*y)) >= (x2-(*x))*(y1-(*y))) //Front + { + addclipline(x1+dax,y1+day,x2+day,y2-dax,(short)j+49152); + } + else + { + if ((cstat&64) != 0) continue; + addclipline(x2-dax,y2-day,x1-day,y1+dax,(short)j+49152); + } + + //Side blocker + if ((x2-x1)*((*x)-x1) + (y2-y1)*((*y)-y1) < 0) + { addclipline(x1-day,y1+dax,x1+dax,y1+day,(short)j+49152); } + else if ((x1-x2)*((*x)-x2) + (y1-y2)*((*y)-y2) < 0) + { addclipline(x2+day,y2-dax,x2-dax,y2-day,(short)j+49152); } + } + } + break; + case 32: + daz = spr->z+ceildist; + daz2 = spr->z-flordist; + if (((*z) < daz) && ((*z) > daz2)) + { + if ((cstat&64) != 0) + if (((*z) > spr->z) == ((cstat&8)==0)) continue; + + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((cstat&4) > 0) xoff = -xoff; + if ((cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; sinang = sintable[k]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + rxi[0] = x1 + dmulscale16(sinang,dax,cosang,day); + ryi[0] = y1 + dmulscale16(sinang,day,-cosang,dax); + l = xspan*xrepeat; + rxi[1] = rxi[0] - mulscale16(sinang,l); + ryi[1] = ryi[0] + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); rxi[2] = rxi[1]+k; rxi[3] = rxi[0]+k; + k = -mulscale16(sinang,l); ryi[2] = ryi[1]+k; ryi[3] = ryi[0]+k; + + dax = mulscale14(sintable[(spr->ang-256+512)&2047],walldist); + day = mulscale14(sintable[(spr->ang-256)&2047],walldist); + + if ((rxi[0]-(*x))*(ryi[1]-(*y)) < (rxi[1]-(*x))*(ryi[0]-(*y))) + { + if (clipinsideboxline(cx,cy,rxi[1],ryi[1],rxi[0],ryi[0],rad) != 0) + addclipline(rxi[1]-day,ryi[1]+dax,rxi[0]+dax,ryi[0]+day,(short)j+49152); + } + else if ((rxi[2]-(*x))*(ryi[3]-(*y)) < (rxi[3]-(*x))*(ryi[2]-(*y))) + { + if (clipinsideboxline(cx,cy,rxi[3],ryi[3],rxi[2],ryi[2],rad) != 0) + addclipline(rxi[3]+day,ryi[3]-dax,rxi[2]-dax,ryi[2]-day,(short)j+49152); + } + + if ((rxi[1]-(*x))*(ryi[2]-(*y)) < (rxi[2]-(*x))*(ryi[1]-(*y))) + { + if (clipinsideboxline(cx,cy,rxi[2],ryi[2],rxi[1],ryi[1],rad) != 0) + addclipline(rxi[2]-dax,ryi[2]-day,rxi[1]-day,ryi[1]+dax,(short)j+49152); + } + else if ((rxi[3]-(*x))*(ryi[0]-(*y)) < (rxi[0]-(*x))*(ryi[3]-(*y))) + { + if (clipinsideboxline(cx,cy,rxi[0],ryi[0],rxi[3],ryi[3],rad) != 0) + addclipline(rxi[0]+dax,ryi[0]+day,rxi[3]+day,ryi[3]-dax,(short)j+49152); + } + } + break; + } + } + } while (clipsectcnt < clipsectnum); + + + hitwall = 0; + cnt = clipmoveboxtracenum; + do + { + intx = goalx; inty = goaly; + if ((hitwall = raytrace(*x, *y, &intx, &inty)) >= 0) + { + lx = clipit[hitwall].x2-clipit[hitwall].x1; + ly = clipit[hitwall].y2-clipit[hitwall].y1; + templong2 = lx*lx + ly*ly; + if (templong2 > 0) + { + templong1 = (goalx-intx)*lx + (goaly-inty)*ly; + + if ((klabs(templong1)>>11) < templong2) + i = divscale20(templong1,templong2); + else + i = 0; + goalx = mulscale20(lx,i)+intx; + goaly = mulscale20(ly,i)+inty; + } + + templong1 = dmulscale6(lx,oxvect,ly,oyvect); + for(i=cnt+1;i<=clipmoveboxtracenum;i++) + { + j = hitwalls[i]; + templong2 = dmulscale6(clipit[j].x2-clipit[j].x1,oxvect,clipit[j].y2-clipit[j].y1,oyvect); + if ((templong1^templong2) < 0) + { + updatesector(*x,*y,sectnum); + return(retval); + } + } + + keepaway(&goalx, &goaly, hitwall); + xvect = ((goalx-intx)<<14); + yvect = ((goaly-inty)<<14); + + if (cnt == clipmoveboxtracenum) retval = clipobjectval[hitwall]; + hitwalls[cnt] = hitwall; + } + cnt--; + + *x = intx; + *y = inty; + } while (((xvect|yvect) != 0) && (hitwall >= 0) && (cnt > 0)); + + for(j=0;j=0;j--) + if (inside(*x,*y,j) == 1) + { + if (sector[j].ceilingstat&2) + templong2 = (getceilzofslope((short)j,*x,*y)-(*z)); + else + templong2 = (sector[j].ceilingz-(*z)); + + if (templong2 > 0) + { + if (templong2 < templong1) + { *sectnum = j; templong1 = templong2; } + } + else + { + if (sector[j].floorstat&2) + templong2 = ((*z)-getflorzofslope((short)j,*x,*y)); + else + templong2 = ((*z)-sector[j].floorz); + + if (templong2 <= 0) + { + *sectnum = j; + return(retval); + } + if (templong2 < templong1) + { *sectnum = j; templong1 = templong2; } + } + } + + return(retval); +} + + +// +// pushmove +// +long pushmove (long *x, long *y, long *z, short *sectnum, + long walldist, long ceildist, long flordist, unsigned long cliptype) +{ + sectortype *sec, *sec2; + walltype *wal, *wal2; + spritetype *spr; + long i, j, k, t, dx, dy, dax, day, daz, daz2, bad, dir; + long dasprclipmask, dawalclipmask; + short startwall, endwall, clipsectcnt; + char bad2; + + if ((*sectnum) < 0) return(-1); + + dawalclipmask = (cliptype&65535); + dasprclipmask = (cliptype>>16); + + k = 32; + dir = 1; + do + { + bad = 0; + + clipsectorlist[0] = *sectnum; + clipsectcnt = 0; clipsectnum = 1; + do + { + /*Push FACE sprites + for(i=headspritesect[clipsectorlist[clipsectcnt]];i>=0;i=nextspritesect[i]) + { + spr = &sprite[i]; + if (((spr->cstat&48) != 0) && ((spr->cstat&48) != 48)) continue; + if ((spr->cstat&dasprclipmask) == 0) continue; + + dax = (*x)-spr->x; day = (*y)-spr->y; + t = (spr->clipdist<<2)+walldist; + if ((klabs(dax) < t) && (klabs(day) < t)) + { + t = ((tilesizy[spr->picnum]*spr->yrepeat)<<2); + if (spr->cstat&128) daz = spr->z+(t>>1); else daz = spr->z; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + if (((*z) < daz+ceildist) && ((*z) > daz-t-flordist)) + { + t = (spr->clipdist<<2)+walldist; + + j = getangle(dax,day); + dx = (sintable[(j+512)&2047]>>11); + dy = (sintable[(j)&2047]>>11); + bad2 = 16; + do + { + *x = (*x) + dx; *y = (*y) + dy; + bad2--; if (bad2 == 0) break; + } while ((klabs((*x)-spr->x) < t) && (klabs((*y)-spr->y) < t)); + bad = -1; + k--; if (k <= 0) return(bad); + updatesector(*x,*y,sectnum); + } + } + }*/ + + sec = §or[clipsectorlist[clipsectcnt]]; + if (dir > 0) + startwall = sec->wallptr, endwall = startwall + sec->wallnum; + else + endwall = sec->wallptr, startwall = endwall + sec->wallnum; + + for(i=startwall,wal=&wall[startwall];i!=endwall;i+=dir,wal+=dir) + if (clipinsidebox(*x,*y,i,walldist-4) == 1) + { + j = 0; + if (wal->nextsector < 0) j = 1; + if (wal->cstat&dawalclipmask) j = 1; + if (j == 0) + { + sec2 = §or[wal->nextsector]; + + + //Find closest point on wall (dax, day) to (*x, *y) + dax = wall[wal->point2].x-wal->x; + day = wall[wal->point2].y-wal->y; + daz = dax*((*x)-wal->x) + day*((*y)-wal->y); + if (daz <= 0) + t = 0; + else + { + daz2 = dax*dax+day*day; + if (daz >= daz2) t = (1<<30); else t = divscale30(daz,daz2); + } + dax = wal->x + mulscale30(dax,t); + day = wal->y + mulscale30(day,t); + + + daz = getflorzofslope(clipsectorlist[clipsectcnt],dax,day); + daz2 = getflorzofslope(wal->nextsector,dax,day); + if ((daz2 < daz-(1<<8)) && ((sec2->floorstat&1) == 0)) + if (*z >= daz2-(flordist-1)) j = 1; + + daz = getceilzofslope(clipsectorlist[clipsectcnt],dax,day); + daz2 = getceilzofslope(wal->nextsector,dax,day); + if ((daz2 > daz+(1<<8)) && ((sec2->ceilingstat&1) == 0)) + if (*z <= daz2+(ceildist-1)) j = 1; + } + if (j != 0) + { + j = getangle(wall[wal->point2].x-wal->x,wall[wal->point2].y-wal->y); + dx = (sintable[(j+1024)&2047]>>11); + dy = (sintable[(j+512)&2047]>>11); + bad2 = 16; + do + { + *x = (*x) + dx; *y = (*y) + dy; + bad2--; if (bad2 == 0) break; + } while (clipinsidebox(*x,*y,i,walldist-4) != 0); + bad = -1; + k--; if (k <= 0) return(bad); + updatesector(*x,*y,sectnum); + } + else + { + for(j=clipsectnum-1;j>=0;j--) + if (wal->nextsector == clipsectorlist[j]) break; + if (j < 0) clipsectorlist[clipsectnum++] = wal->nextsector; + } + } + + clipsectcnt++; + } while (clipsectcnt < clipsectnum); + dir = -dir; + } while (bad != 0); + + return(bad); +} + + +// +// updatesector[z] +// +void updatesector(long x, long y, short *sectnum) +{ + walltype *wal; + long i, j; + + if (inside(x,y,*sectnum) == 1) return; + + if ((*sectnum >= 0) && (*sectnum < numsectors)) + { + wal = &wall[sector[*sectnum].wallptr]; + j = sector[*sectnum].wallnum; + do + { + i = wal->nextsector; + if (i >= 0) + if (inside(x,y,(short)i) == 1) + { + *sectnum = i; + return; + } + wal++; + j--; + } while (j != 0); + } + + for(i=numsectors-1;i>=0;i--) + if (inside(x,y,(short)i) == 1) + { + *sectnum = i; + return; + } + + *sectnum = -1; +} + +void updatesectorz(long x, long y, long z, short *sectnum) +{ + walltype *wal; + long i, j, cz, fz; + + getzsofslope(*sectnum, x, y, &cz, &fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,*sectnum) != 0) return; + + if ((*sectnum >= 0) && (*sectnum < numsectors)) + { + wal = &wall[sector[*sectnum].wallptr]; + j = sector[*sectnum].wallnum; + do + { + i = wal->nextsector; + if (i >= 0) + { + getzsofslope(i, x, y, &cz, &fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + wal++; j--; + } while (j != 0); + } + + for (i=numsectors-1;i>=0;i--) + { + getzsofslope(i, x, y, &cz, &fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + + *sectnum = -1; +} + + +// +// rotatepoint +// +void rotatepoint(long xpivot, long ypivot, long x, long y, short daang, long *x2, long *y2) +{ + long dacos, dasin; + + dacos = sintable[(daang+2560)&2047]; + dasin = sintable[(daang+2048)&2047]; + x -= xpivot; + y -= ypivot; + *x2 = dmulscale14(x,dacos,-y,dasin) + xpivot; + *y2 = dmulscale14(y,dacos,x,dasin) + ypivot; +} + + +// +// getmousevalues +// + +void getmousevalues(long *mousx, long *mousy, long *bstatus) +{ + readmousexy(mousx,mousy); + readmousebstatus(bstatus); +} + + +// +// krand +// +long krand(void) +{ + randomseed = (randomseed*27584621)+1; + return(((unsigned long)randomseed)>>16); +} + + +// +// getzrange +// +void getzrange(long x, long y, long z, short sectnum, + long *ceilz, long *ceilhit, long *florz, long *florhit, + long walldist, unsigned long cliptype) +{ + sectortype *sec; + walltype *wal, *wal2; + spritetype *spr; + long clipsectcnt, startwall, endwall, tilenum, xoff, yoff, dax, day; + long xmin, ymin, xmax, ymax, i, j, k, l, daz, daz2, dx, dy; + long x1, y1, x2, y2, x3, y3, x4, y4, ang, cosang, sinang; + long xspan, yspan, xrepeat, yrepeat, dasprclipmask, dawalclipmask; + short cstat; + char clipyou; + + if (sectnum < 0) + { + *ceilz = 0x80000000; *ceilhit = -1; + *florz = 0x7fffffff; *florhit = -1; + return; + } + + //Extra walldist for sprites on sector lines + i = walldist+MAXCLIPDIST+1; + xmin = x-i; ymin = y-i; + xmax = x+i; ymax = y+i; + + getzsofslope(sectnum,x,y,ceilz,florz); + *ceilhit = sectnum+16384; *florhit = sectnum+16384; + + dawalclipmask = (cliptype&65535); + dasprclipmask = (cliptype>>16); + + clipsectorlist[0] = sectnum; + clipsectcnt = 0; clipsectnum = 1; + + do //Collect sectors inside your square first + { + sec = §or[clipsectorlist[clipsectcnt]]; + startwall = sec->wallptr; endwall = startwall + sec->wallnum; + for(j=startwall,wal=&wall[startwall];jnextsector; + if (k >= 0) + { + wal2 = &wall[wal->point2]; + x1 = wal->x; x2 = wal2->x; + if ((x1 < xmin) && (x2 < xmin)) continue; + if ((x1 > xmax) && (x2 > xmax)) continue; + y1 = wal->y; y2 = wal2->y; + if ((y1 < ymin) && (y2 < ymin)) continue; + if ((y1 > ymax) && (y2 > ymax)) continue; + + dx = x2-x1; dy = y2-y1; + if (dx*(y-y1) < (x-x1)*dy) continue; //back + if (dx > 0) dax = dx*(ymin-y1); else dax = dx*(ymax-y1); + if (dy > 0) day = dy*(xmax-x1); else day = dy*(xmin-x1); + if (dax >= day) continue; + + if (wal->cstat&dawalclipmask) continue; + sec = §or[k]; + if (editstatus == 0) + { + if (((sec->ceilingstat&1) == 0) && (z <= sec->ceilingz+(3<<8))) continue; + if (((sec->floorstat&1) == 0) && (z >= sec->floorz-(3<<8))) continue; + } + + for(i=clipsectnum-1;i>=0;i--) if (clipsectorlist[i] == k) break; + if (i < 0) clipsectorlist[clipsectnum++] = k; + + if ((x1 < xmin+MAXCLIPDIST) && (x2 < xmin+MAXCLIPDIST)) continue; + if ((x1 > xmax-MAXCLIPDIST) && (x2 > xmax-MAXCLIPDIST)) continue; + if ((y1 < ymin+MAXCLIPDIST) && (y2 < ymin+MAXCLIPDIST)) continue; + if ((y1 > ymax-MAXCLIPDIST) && (y2 > ymax-MAXCLIPDIST)) continue; + if (dx > 0) dax += dx*MAXCLIPDIST; else dax -= dx*MAXCLIPDIST; + if (dy > 0) day -= dy*MAXCLIPDIST; else day += dy*MAXCLIPDIST; + if (dax >= day) continue; + + //It actually got here, through all the continue's!!! + getzsofslope((short)k,x,y,&daz,&daz2); + if (daz > *ceilz) { *ceilz = daz; *ceilhit = k+16384; } + if (daz2 < *florz) { *florz = daz2; *florhit = k+16384; } + } + } + clipsectcnt++; + } while (clipsectcnt < clipsectnum); + + for(i=0;i=0;j=nextspritesect[j]) + { + spr = &sprite[j]; + cstat = spr->cstat; + if (cstat&dasprclipmask) + { + x1 = spr->x; y1 = spr->y; + + clipyou = 0; + switch(cstat&48) + { + case 0: + k = walldist+(spr->clipdist<<2)+1; + if ((klabs(x1-x) <= k) && (klabs(y1-y) <= k)) + { + daz = spr->z; + k = ((tilesizy[spr->picnum]*spr->yrepeat)<<1); + if (cstat&128) daz += k; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + daz2 = daz - (k<<1); + clipyou = 1; + } + break; + case 16: + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + if (clipinsideboxline(x,y,x1,y1,x2,y2,walldist+1) != 0) + { + daz = spr->z; k = ((tilesizy[spr->picnum]*spr->yrepeat)<<1); + if (cstat&128) daz += k; + if (picanm[spr->picnum]&0x00ff0000) daz -= ((long)((signed char)((picanm[spr->picnum]>>16)&255))*spr->yrepeat<<2); + daz2 = daz-(k<<1); + clipyou = 1; + } + break; + case 32: + daz = spr->z; daz2 = daz; + + if ((cstat&64) != 0) + if ((z > daz) == ((cstat&8)==0)) continue; + + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((cstat&4) > 0) xoff = -xoff; + if ((cstat&8) > 0) yoff = -yoff; + + ang = spr->ang; + cosang = sintable[(ang+512)&2047]; sinang = sintable[ang]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + x1 += dmulscale16(sinang,dax,cosang,day)-x; + y1 += dmulscale16(sinang,day,-cosang,dax)-y; + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang,l); + y2 = y1 + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; + k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; + + dax = mulscale14(sintable[(spr->ang-256+512)&2047],walldist+4); + day = mulscale14(sintable[(spr->ang-256)&2047],walldist+4); + x1 += dax; x2 -= day; x3 -= dax; x4 += day; + y1 += day; y2 += dax; y3 -= day; y4 -= dax; + + if ((y1^y2) < 0) + { + if ((x1^x2) < 0) clipyou ^= (x1*y2= 0) clipyou ^= 1; + } + if ((y2^y3) < 0) + { + if ((x2^x3) < 0) clipyou ^= (x2*y3= 0) clipyou ^= 1; + } + if ((y3^y4) < 0) + { + if ((x3^x4) < 0) clipyou ^= (x3*y4= 0) clipyou ^= 1; + } + if ((y4^y1) < 0) + { + if ((x4^x1) < 0) clipyou ^= (x4*y1= 0) clipyou ^= 1; + } + break; + } + + if (clipyou != 0) + { + if ((z > daz) && (daz > *ceilz)) { *ceilz = daz; *ceilhit = j+49152; } + if ((z < daz2) && (daz2 < *florz)) { *florz = daz2; *florhit = j+49152; } + } + } + } + } +} + + +// +// setview +// +void setview(long x1, long y1, long x2, long y2) +{ + long i; + + windowx1 = x1; wx1 = (x1<<12); + windowy1 = y1; wy1 = (y1<<12); + windowx2 = x2; wx2 = ((x2+1)<<12); + windowy2 = y2; wy2 = ((y2+1)<<12); + + xdimen = (x2-x1)+1; halfxdimen = (xdimen>>1); + xdimenrecip = divscale32(1L,xdimen); + ydimen = (y2-y1)+1; + + setaspect(65536L,(long)divscale16(ydim*320L,xdim*200L)); + + for(i=0;i cx2) || (cy1 > cy2)) return; + if (z <= 16) return; + if (picanm[picnum]&192) picnum += animateoffs(picnum,(short)0xc000); + if ((tilesizx[picnum] <= 0) || (tilesizy[picnum] <= 0)) return; + + if (((dastat&128) == 0) || (numpages < 2) || (beforedrawrooms != 0)) { + begindrawing(); //{{{ + dorotatesprite(sx,sy,z,a,picnum,dashade,dapalnum,dastat,cx1,cy1,cx2,cy2,guniqhudid); + enddrawing(); //}}} + } + + if ((dastat&64) && (cx1 <= 0) && (cy1 <= 0) && (cx2 >= xdim-1) && (cy2 >= ydim-1) && + (sx == (160<<16)) && (sy == (100<<16)) && (z == 65536L) && (a == 0) && ((dastat&1) == 0)) + permhead = permtail = 0; + + if ((dastat&128) == 0) return; + if (numpages >= 2) + { + per = &permfifo[permhead]; + per->sx = sx; per->sy = sy; per->z = z; per->a = a; + per->picnum = picnum; + per->dashade = dashade; per->dapalnum = dapalnum; + per->dastat = dastat; + per->pagesleft = numpages+((beforedrawrooms&1)<<7); + per->cx1 = cx1; per->cy1 = cy1; per->cx2 = cx2; per->cy2 = cy2; + per->uniqid = guniqhudid; //JF extension + + //Would be better to optimize out true bounding boxes + if (dastat&64) //If non-masking write, checking for overlapping cases + { + for(i=permtail;i!=permhead;i=((i+1)&(MAXPERMS-1))) + { + per2 = &permfifo[i]; + if ((per2->pagesleft&127) == 0) continue; + if (per2->sx != per->sx) continue; + if (per2->sy != per->sy) continue; + if (per2->z != per->z) continue; + if (per2->a != per->a) continue; + if (tilesizx[per2->picnum] > tilesizx[per->picnum]) continue; + if (tilesizy[per2->picnum] > tilesizy[per->picnum]) continue; + if (per2->cx1 < per->cx1) continue; + if (per2->cy1 < per->cy1) continue; + if (per2->cx2 > per->cx2) continue; + if (per2->cy2 > per->cy2) continue; + per2->pagesleft = 0; + } + if ((per->z == 65536) && (per->a == 0)) + for(i=permtail;i!=permhead;i=((i+1)&(MAXPERMS-1))) + { + per2 = &permfifo[i]; + if ((per2->pagesleft&127) == 0) continue; + if (per2->z != 65536) continue; + if (per2->a != 0) continue; + if (per2->cx1 < per->cx1) continue; + if (per2->cy1 < per->cy1) continue; + if (per2->cx2 > per->cx2) continue; + if (per2->cy2 > per->cy2) continue; + if ((per2->sx>>16) < (per->sx>>16)) continue; + if ((per2->sy>>16) < (per->sy>>16)) continue; + if ((per2->sx>>16)+tilesizx[per2->picnum] > (per->sx>>16)+tilesizx[per->picnum]) continue; + if ((per2->sy>>16)+tilesizy[per2->picnum] > (per->sy>>16)+tilesizy[per->picnum]) continue; + per2->pagesleft = 0; + } + } + + permhead = ((permhead+1)&(MAXPERMS-1)); + } +} + + +// +// makepalookup +// +void makepalookup(long palnum, char *remapbuf, signed char r, signed char g, signed char b, char dastat) +{ + long i, j, palscale; + char *ptr, *ptr2; + + if (paletteloaded == 0) return; + + if (palookup[palnum] == NULL) + { + //Allocate palookup buffer + if ((palookup[palnum] = (char *)kkmalloc(numpalookups<<8)) == NULL) + allocache((long*)&palookup[palnum],numpalookups<<8,&permanentlock); + } + + if (dastat == 0) return; + if ((r|g|b|63) != 63) return; + + if ((r|g|b) == 0) + { + for(i=0;i<256;i++) + { + ptr = (char *)(FP_OFF(palookup[0])+remapbuf[i]); + ptr2 = (char *)(FP_OFF(palookup[palnum])+i); + for(j=0;j> 6 ) ) >> 2; + tempbuf[k++] = + (curpalettefaded[i].g = + p.g + ( ( ( (long)palfadergb.g - (long)p.g ) * (long)offset ) >> 6 ) ) >> 2; + tempbuf[k++] = + (curpalettefaded[i].r = + p.r + ( ( ( (long)palfadergb.r - (long)p.r ) * (long)offset ) >> 6 ) ) >> 2; + tempbuf[k++] = curpalettefaded[i].f = 0; + } + + setpalette(0,256,(char*)tempbuf); +} + + +// +// clearview +// +void clearview(long dacol) +{ + long p, y, dx; + + if (qsetmode != 200) return; + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3) { + palette_t p; + if (gammabrightness) p = curpalette[dacol]; + else { + p.r = britable[curbrightness][ curpalette[dacol].r ]; + p.g = britable[curbrightness][ curpalette[dacol].g ]; + p.b = britable[curbrightness][ curpalette[dacol].b ]; + } + bglClearColor(((float)p.r)/255.0, + ((float)p.g)/255.0, + ((float)p.b)/255.0, + 0); + bglClear(GL_COLOR_BUFFER_BIT); + return; + } +#endif + + begindrawing(); //{{{ + dx = windowx2-windowx1+1; + //dacol += (dacol<<8); dacol += (dacol<<16); + p = frameplace+ylookup[windowy1]+windowx1; + for(y=windowy1;y<=windowy2;y++) { + //clearbufbyte((void*)p,dx,dacol); + Bmemset((void*)p,dacol,dx); + p += ylookup[1]; + } + enddrawing(); //}}} + + faketimerhandler(); +} + + +// +// clearallviews +// +void clearallviews(long dacol) +{ + if (qsetmode != 200) return; + //dacol += (dacol<<8); dacol += (dacol<<16); + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3) { + palette_t p; + if (gammabrightness) p = curpalette[dacol]; + else { + p.r = britable[curbrightness][ curpalette[dacol].r ]; + p.g = britable[curbrightness][ curpalette[dacol].g ]; + p.b = britable[curbrightness][ curpalette[dacol].b ]; + } + bglViewport(0,0,xdim,ydim); glox1 = -1; + bglClearColor(((float)p.r)/255.0, + ((float)p.g)/255.0, + ((float)p.b)/255.0, + 0); + bglClear(GL_COLOR_BUFFER_BIT); + return; + } +#endif + + begindrawing(); //{{{ + //clearbufbyte((void*)frameplace,imageSize,0L); + Bmemset((void*)frameplace,dacol,imageSize); + enddrawing(); //}}} + //nextpage(); + + faketimerhandler(); +} + + +// +// plotpixel +// +void plotpixel(long x, long y, char col) +{ +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3 && qsetmode == 200) { + palette_t p; + if (gammabrightness) p = curpalette[col]; + else { + p.r = britable[curbrightness][ curpalette[col].r ]; + p.g = britable[curbrightness][ curpalette[col].g ]; + p.b = britable[curbrightness][ curpalette[col].b ]; + } + + setpolymost2dview(); // JBF 20040205: more efficient setup + + bglBegin(GL_POINTS); + bglColor4ub(p.r,p.g,p.b,255); + bglVertex2i(x,y); + bglEnd(); + + return; + } +#endif + + begindrawing(); //{{{ + drawpixel((void*)(ylookup[y]+x+frameplace),(long)col); + enddrawing(); //}}} +} + + +// +// getpixel +// +char getpixel(long x, long y) +{ + char r; + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3 && qsetmode == 200) return 0; +#endif + + begindrawing(); //{{{ + r = readpixel((void*)(ylookup[y]+x+frameplace)); + enddrawing(); //}}} + return(r); +} + + + //MUST USE RESTOREFORDRAWROOMS AFTER DRAWING + +// +// setviewtotile +// +void setviewtotile(short tilenume, long xsiz, long ysiz) +{ + long i, j; + + //DRAWROOMS TO TILE BACKUP&SET CODE + tilesizx[tilenume] = xsiz; tilesizy[tilenume] = ysiz; + bakxsiz[setviewcnt] = xsiz; bakysiz[setviewcnt] = ysiz; + bakframeplace[setviewcnt] = frameplace; frameplace = waloff[tilenume]; + bakwindowx1[setviewcnt] = windowx1; bakwindowy1[setviewcnt] = windowy1; + bakwindowx2[setviewcnt] = windowx2; bakwindowy2[setviewcnt] = windowy2; +#ifdef POLYMOST + if (setviewcnt == 0) { + bakrendmode = rendmode; + baktile = tilenume; + } + rendmode = 0;//2; +#endif + copybufbyte(&startumost[windowx1],&bakumost[windowx1],(windowx2-windowx1+1)*sizeof(bakumost[0])); + copybufbyte(&startdmost[windowx1],&bakdmost[windowx1],(windowx2-windowx1+1)*sizeof(bakdmost[0])); + setviewcnt++; + + offscreenrendering = 1; + setview(0,0,ysiz-1,xsiz-1); + setaspect(65536,65536); + j = 0; for(i=0;i<=xsiz;i++) { ylookup[i] = j, j += ysiz; } + setvlinebpl(ysiz); +} + + +// +// setviewback +// +extern char modechange; +void setviewback(void) +{ + long i, j, k; + + if (setviewcnt <= 0) return; + setviewcnt--; + + offscreenrendering = (setviewcnt>0); +#ifdef POLYMOST + if (setviewcnt == 0) { + rendmode = bakrendmode; + invalidatetile(baktile,-1,-1); + } +#endif + + setview(bakwindowx1[setviewcnt],bakwindowy1[setviewcnt], + bakwindowx2[setviewcnt],bakwindowy2[setviewcnt]); + copybufbyte(&bakumost[windowx1],&startumost[windowx1],(windowx2-windowx1+1)*sizeof(startumost[0])); + copybufbyte(&bakdmost[windowx1],&startdmost[windowx1],(windowx2-windowx1+1)*sizeof(startdmost[0])); + frameplace = bakframeplace[setviewcnt]; + if (setviewcnt == 0) + k = bakxsiz[0]; + else + k = max(bakxsiz[setviewcnt-1],bakxsiz[setviewcnt]); + j = 0; for(i=0;i<=k;i++) ylookup[i] = j, j += bytesperline; + setvlinebpl(bytesperline); + modechange=1; +} + + +// +// squarerotatetile +// +void squarerotatetile(short tilenume) +{ + long i, j, k, xsiz, ysiz; + char *ptr1, *ptr2; + + xsiz = tilesizx[tilenume]; ysiz = tilesizy[tilenume]; + + //supports square tiles only for rotation part + if (xsiz == ysiz) + { + k = (xsiz<<1); + for(i=xsiz-1;i>=0;i--) + { + ptr1 = (char *)(waloff[tilenume]+i*(xsiz+1)); ptr2 = ptr1; + if ((i&1) != 0) { ptr1--; ptr2 -= xsiz; swapchar(ptr1,ptr2); } + for(j=(i>>1)-1;j>=0;j--) + { ptr1 -= 2; ptr2 -= k; swapchar2(ptr1,ptr2,xsiz); } + } + } +} + + +// +// preparemirror +// +void preparemirror(long dax, long day, long daz, short daang, long dahoriz, short dawall, short dasector, long *tposx, long *tposy, short *tang) +{ + long i, j, x, y, dx, dy; + + x = wall[dawall].x; dx = wall[wall[dawall].point2].x-x; + y = wall[dawall].y; dy = wall[wall[dawall].point2].y-y; + j = dx*dx + dy*dy; if (j == 0) return; + i = (((dax-x)*dx + (day-y)*dy)<<1); + *tposx = (x<<1) + scale(dx,i,j) - dax; + *tposy = (y<<1) + scale(dy,i,j) - day; + *tang = (((getangle(dx,dy)<<1)-daang)&2047); + + inpreparemirror = 1; +} + + +// +// completemirror +// +void completemirror(void) +{ + long i, dy, p; + +#ifdef POLYMOST + if (rendmode) return; +#endif + + //Can't reverse with uninitialized data + if (inpreparemirror) { inpreparemirror = 0; return; } + if (mirrorsx1 > 0) mirrorsx1--; + if (mirrorsx2 < windowx2-windowx1-1) mirrorsx2++; + if (mirrorsx2 < mirrorsx1) return; + + begindrawing(); + p = frameplace+ylookup[windowy1+mirrorsy1]+windowx1+mirrorsx1; + i = windowx2-windowx1-mirrorsx2-mirrorsx1; mirrorsx2 -= mirrorsx1; + for(dy=mirrorsy2-mirrorsy1-1;dy>=0;dy--) + { + copybufbyte((void*)(p+1),tempbuf,mirrorsx2+1); + tempbuf[mirrorsx2] = tempbuf[mirrorsx2-1]; + copybufreverse(&tempbuf[mirrorsx2],(void*)(p+i),mirrorsx2+1); + p += ylookup[1]; + faketimerhandler(); + } + enddrawing(); +} + + +// +// sectorofwall +// +long sectorofwall(short theline) +{ + long i, gap; + + if ((theline < 0) || (theline >= numwalls)) return(-1); + i = wall[theline].nextwall; if (i >= 0) return(wall[i].nextsector); + + gap = (numsectors>>1); i = gap; + while (gap > 1) + { + gap >>= 1; + if (sector[i].wallptr < theline) i += gap; else i -= gap; + } + while (sector[i].wallptr > theline) i--; + while (sector[i].wallptr+sector[i].wallnum <= theline) i++; + return(i); +} + + +// +// getceilzofslope +// +long getceilzofslope(short sectnum, long dax, long day) +{ + long dx, dy, i, j; + walltype *wal; + + if (!(sector[sectnum].ceilingstat&2)) return(sector[sectnum].ceilingz); + wal = &wall[sector[sectnum].wallptr]; + dx = wall[wal->point2].x-wal->x; dy = wall[wal->point2].y-wal->y; + i = (nsqrtasm(dx*dx+dy*dy)<<5); if (i == 0) return(sector[sectnum].ceilingz); + j = dmulscale3(dx,day-wal->y,-dy,dax-wal->x); + return(sector[sectnum].ceilingz+scale(sector[sectnum].ceilingheinum,j,i)); +} + + +// +// getflorzofslope +// +long getflorzofslope(short sectnum, long dax, long day) +{ + long dx, dy, i, j; + walltype *wal; + + if (!(sector[sectnum].floorstat&2)) return(sector[sectnum].floorz); + wal = &wall[sector[sectnum].wallptr]; + dx = wall[wal->point2].x-wal->x; dy = wall[wal->point2].y-wal->y; + i = (nsqrtasm(dx*dx+dy*dy)<<5); if (i == 0) return(sector[sectnum].floorz); + j = dmulscale3(dx,day-wal->y,-dy,dax-wal->x); + return(sector[sectnum].floorz+scale(sector[sectnum].floorheinum,j,i)); +} + + +// +// getzsofslope +// +void getzsofslope(short sectnum, long dax, long day, long *ceilz, long *florz) +{ + long dx, dy, i, j; + walltype *wal, *wal2; + sectortype *sec; + + sec = §or[sectnum]; + *ceilz = sec->ceilingz; *florz = sec->floorz; + if ((sec->ceilingstat|sec->floorstat)&2) + { + wal = &wall[sec->wallptr]; wal2 = &wall[wal->point2]; + dx = wal2->x-wal->x; dy = wal2->y-wal->y; + i = (nsqrtasm(dx*dx+dy*dy)<<5); if (i == 0) return; + j = dmulscale3(dx,day-wal->y,-dy,dax-wal->x); + if (sec->ceilingstat&2) *ceilz = (*ceilz)+scale(sec->ceilingheinum,j,i); + if (sec->floorstat&2) *florz = (*florz)+scale(sec->floorheinum,j,i); + } +} + + +// +// alignceilslope +// +void alignceilslope(short dasect, long x, long y, long z) +{ + long i, dax, day; + walltype *wal; + + wal = &wall[sector[dasect].wallptr]; + dax = wall[wal->point2].x-wal->x; + day = wall[wal->point2].y-wal->y; + + i = (y-wal->y)*dax - (x-wal->x)*day; if (i == 0) return; + sector[dasect].ceilingheinum = scale((z-sector[dasect].ceilingz)<<8, + nsqrtasm(dax*dax+day*day),i); + + if (sector[dasect].ceilingheinum == 0) sector[dasect].ceilingstat &= ~2; + else sector[dasect].ceilingstat |= 2; +} + + +// +// alignflorslope +// +void alignflorslope(short dasect, long x, long y, long z) +{ + long i, dax, day; + walltype *wal; + + wal = &wall[sector[dasect].wallptr]; + dax = wall[wal->point2].x-wal->x; + day = wall[wal->point2].y-wal->y; + + i = (y-wal->y)*dax - (x-wal->x)*day; if (i == 0) return; + sector[dasect].floorheinum = scale((z-sector[dasect].floorz)<<8, + nsqrtasm(dax*dax+day*day),i); + + if (sector[dasect].floorheinum == 0) sector[dasect].floorstat &= ~2; + else sector[dasect].floorstat |= 2; +} + + +// +// loopnumofsector +// +long loopnumofsector(short sectnum, short wallnum) +{ + long i, numloops, startwall, endwall; + + numloops = 0; + startwall = sector[sectnum].wallptr; + endwall = startwall + sector[sectnum].wallnum; + for(i=startwall;i= startwall+danumwalls)) return; + for(i=0;i 0) + { + j = 0; + while (loopnumofsector(sectnum,j+startwall) != dagoalloop) j++; + for(i=0;i= danumwalls) k -= danumwalls; + Bmemcpy(&wall[startwall+i],&wall[numwalls+k],sizeof(walltype)); + + wall[startwall+i].point2 += danumwalls-startwall-j; + if (wall[startwall+i].point2 >= danumwalls) + wall[startwall+i].point2 -= danumwalls; + wall[startwall+i].point2 += startwall; + } + newfirstwall += danumwalls-j; + if (newfirstwall >= startwall+danumwalls) newfirstwall -= danumwalls; + } + + for(i=0;i= numwallsofloop) k -= numwallsofloop; + Bmemcpy(&wall[startwall+i],&wall[numwalls+k],sizeof(walltype)); + + wall[startwall+i].point2 += numwallsofloop-newfirstwall; + if (wall[startwall+i].point2 >= numwallsofloop) + wall[startwall+i].point2 -= numwallsofloop; + wall[startwall+i].point2 += startwall; + } + + for(i=startwall;i= 0) wall[wall[i].nextwall].nextwall = i; +} + + +// +// drawline256 +// +void drawline256(long x1, long y1, long x2, long y2, char col) +{ + long dx, dy, i, j, p, inc, plc, daend; + + col = palookup[0][col]; + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode == 3) + { + palette_t p; + if (gammabrightness) p = curpalette[col]; + else { + p.r = britable[curbrightness][ curpalette[col].r ]; + p.g = britable[curbrightness][ curpalette[col].g ]; + p.b = britable[curbrightness][ curpalette[col].b ]; + } + + setpolymost2dview(); // JBF 20040205: more efficient setup + + bglBegin(GL_LINES); + bglColor4ub(p.r,p.g,p.b,255); + bglVertex2f((float)x1/4096.0,(float)y1/4096.0); + bglVertex2f((float)x2/4096.0,(float)y2/4096.0); + bglEnd(); + + return; + } +#endif + + dx = x2-x1; dy = y2-y1; + if (dx >= 0) + { + if ((x1 >= wx2) || (x2 < wx1)) return; + if (x1 < wx1) y1 += scale(wx1-x1,dy,dx), x1 = wx1; + if (x2 > wx2) y2 += scale(wx2-x2,dy,dx), x2 = wx2; + } + else + { + if ((x2 >= wx2) || (x1 < wx1)) return; + if (x2 < wx1) y2 += scale(wx1-x2,dy,dx), x2 = wx1; + if (x1 > wx2) y1 += scale(wx2-x1,dy,dx), x1 = wx2; + } + if (dy >= 0) + { + if ((y1 >= wy2) || (y2 < wy1)) return; + if (y1 < wy1) x1 += scale(wy1-y1,dx,dy), y1 = wy1; + if (y2 > wy2) x2 += scale(wy2-y2,dx,dy), y2 = wy2; + } + else + { + if ((y2 >= wy2) || (y1 < wy1)) return; + if (y2 < wy1) x2 += scale(wy1-y2,dx,dy), y2 = wy1; + if (y1 > wy2) x1 += scale(wy2-y1,dx,dy), y1 = wy2; + } + + if (klabs(dx) >= klabs(dy)) + { + if (dx == 0) return; + if (dx < 0) + { + i = x1; x1 = x2; x2 = i; + i = y1; y1 = y2; y2 = i; + } + + inc = divscale12(dy,dx); + plc = y1+mulscale12((2047-x1)&4095,inc); + i = ((x1+2048)>>12); daend = ((x2+2048)>>12); + + begindrawing(); //{{{ + for(;i>12); + if ((j >= startumost[i]) && (j < startdmost[i])) + drawpixel((void*)(frameplace+ylookup[j]+i),col); + plc += inc; + } + enddrawing(); //}}} + } + else + { + if (dy < 0) + { + i = x1; x1 = x2; x2 = i; + i = y1; y1 = y2; y2 = i; + } + + inc = divscale12(dx,dy); + plc = x1+mulscale12((2047-y1)&4095,inc); + i = ((y1+2048)>>12); daend = ((y2+2048)>>12); + + begindrawing(); //{{{ + p = ylookup[i]+frameplace; + for(;i>12); + if ((i >= startumost[j]) && (i < startdmost[j])) + drawpixel((void*)(j+p),col); + plc += inc; p += ylookup[1]; + } + enddrawing(); //}}} + } +} + +// +// drawline16 +// +// JBF: Had to add extra tests to make sure x-coordinates weren't winding up -'ve +// after clipping or crashes would ensue +unsigned long drawlinepat = 0xffffffff; + +void drawline16(long x1, long y1, long x2, long y2, char col) +{ + long i, dx, dy, p, pinc, d; + unsigned long patc=0; + + dx = x2-x1; dy = y2-y1; + if (dx >= 0) + { + if ((x1 >= xres) || (x2 < 0)) return; + if (x1 < 0) { if (dy) y1 += scale(0-x1,dy,dx); x1 = 0; } + if (x2 >= xres) { if (dy) y2 += scale(xres-1-x2,dy,dx); x2 = xres-1; } + } + else + { + if ((x2 >= xres) || (x1 < 0)) return; + if (x2 < 0) { if (dy) y2 += scale(0-x2,dy,dx); x2 = 0; } + if (x1 >= xres) { if (dy) y1 += scale(xres-1-x1,dy,dx); x1 = xres-1; } + } + if (dy >= 0) + { + if ((y1 >= ydim16) || (y2 < 0)) return; + if (y1 < 0) { if (dx) x1 += scale(0-y1,dx,dy); y1 = 0; if (x1 < 0) x1 = 0; } + if (y2 >= ydim16) { if (dx) x2 += scale(ydim16-1-y2,dx,dy); y2 = ydim16-1; if (x2 < 0) x2 = 0; } + } + else + { + if ((y2 >= ydim16) || (y1 < 0)) return; + if (y2 < 0) { if (dx) x2 += scale(0-y2,dx,dy); y2 = 0; if (x2 < 0) x2 = 0; } + if (y1 >= ydim16) { if (dx) x1 += scale(ydim16-1-y1,dx,dy); y1 = ydim16-1; if (x1 < 0) x1 = 0; } + } + + dx = klabs(x2-x1)+1; dy = klabs(y2-y1)+1; + if (dx >= dy) + { + if (x2 < x1) + { + i = x1; x1 = x2; x2 = i; + i = y1; y1 = y2; y2 = i; + } + d = 0; + if (y2 > y1) pinc = bytesperline; else pinc = -bytesperline; + + begindrawing(); //{{{ + p = (y1*bytesperline)+x1+frameplace; + if (dy == 0 && drawlinepat == 0xffffffff) { + i = ((long)col<<24)|((long)col<<16)|((long)col<<8)|col; + clearbufbyte((void *)p, dx, i); + } else + for(i=dx;i>0;i--) + { + if (drawlinepat & pow2long[(patc++)&31]) + drawpixel((char *)p, col); + d += dy; + if (d >= dx) { d -= dx; p += pinc; } + p++; + } + enddrawing(); //}}} + return; + } + + if (y2 < y1) + { + i = x1; x1 = x2; x2 = i; + i = y1; y1 = y2; y2 = i; + } + d = 0; + if (x2 > x1) pinc = 1; else pinc = -1; + + begindrawing(); //{{{ + p = (y1*bytesperline)+x1+frameplace; + for(i=dy;i>0;i--) + { + if (drawlinepat & pow2long[(patc++)&31]) + drawpixel((char *)p, col); + d += dx; + if (d >= dy) { d -= dy; p += pinc; } + p += bytesperline; + } + enddrawing(); //}}} +} + +void drawcircle16(long x1, long y1, long r, char col) +{ +#if 1 + long p, xp, yp, xpbpl, ypbpl, d, de, dse, patc=0; + + if (r < 0) r = -r; + if (x1+r < 0 || x1-r >= xres) return; + if (y1+r < 0 || y1-r >= ydim16) return; + + /* + * d + * 6 | 7 + * \ | / + * 5 \|/ 8 + * c----+----a + * 4 /|\ 1 + * / | \ + * 3 | 2 + * b + */ + + xp = 0; + yp = r; + d = 1 - r; + de = 2; + dse = 5 - (r << 1); + + begindrawing(); + p = (y1*bytesperline)+x1+frameplace; + + if (drawlinepat & pow2long[(patc++)&31]) { + if ((unsigned long)y1 < (unsigned long)ydim16 && (unsigned long)(x1+r) < (unsigned long)xres ) + drawpixel((char *)(p+r), col); // a + if ((unsigned long)x1 < (unsigned long)xres && (unsigned long)(y1+r) < (unsigned long)ydim16) + drawpixel((char *)(p+(r*bytesperline)), col); // b + if ((unsigned long)y1 < (unsigned long)ydim16 && (unsigned long)(x1-r) < (unsigned long)xres ) + drawpixel((char *)(p-r), col); // c + if ((unsigned long)x1 < (unsigned long)xres && (unsigned long)(y1-r) < (unsigned long)ydim16) + drawpixel((char *)(p-(r*bytesperline)), col); // d + } + + while (yp > xp) { + if (d < 0) { + d += de; + de += 2; + dse += 2; + xp++; + } else { + d += dse; + de += 2; + dse += 4; + xp++; + yp--; + } + + ypbpl = yp*bytesperline; + xpbpl = xp*bytesperline; + if (drawlinepat & pow2long[(patc++)&31]) { + if ((unsigned long)(x1+yp) < (unsigned long)xres && (unsigned long)(y1+xp) < (unsigned long)ydim16) + drawpixel((char *)(p+yp+xpbpl), col); // 1 + if ((unsigned long)(x1+xp) < (unsigned long)xres && (unsigned long)(y1+yp) < (unsigned long)ydim16) + drawpixel((char *)(p+xp+ypbpl), col); // 2 + if ((unsigned long)(x1-xp) < (unsigned long)xres && (unsigned long)(y1+yp) < (unsigned long)ydim16) + drawpixel((char *)(p-xp+ypbpl), col); // 3 + if ((unsigned long)(x1-yp) < (unsigned long)xres && (unsigned long)(y1+xp) < (unsigned long)ydim16) + drawpixel((char *)(p-yp+xpbpl), col); // 4 + if ((unsigned long)(x1-yp) < (unsigned long)xres && (unsigned long)(y1-xp) < (unsigned long)ydim16) + drawpixel((char *)(p-yp-xpbpl), col); // 5 + if ((unsigned long)(x1-xp) < (unsigned long)xres && (unsigned long)(y1-yp) < (unsigned long)ydim16) + drawpixel((char *)(p-xp-ypbpl), col); // 6 + if ((unsigned long)(x1+xp) < (unsigned long)xres && (unsigned long)(y1-yp) < (unsigned long)ydim16) + drawpixel((char *)(p+xp-ypbpl), col); // 7 + if ((unsigned long)(x1+yp) < (unsigned long)xres && (unsigned long)(y1-xp) < (unsigned long)ydim16) + drawpixel((char *)(p+yp-xpbpl), col); // 8 + } + } + enddrawing(); +#else + // JonoF's rough approximation of a circle + long l,spx,spy,lpx,lpy,px,py; + + spx = lpx = x1+mulscale14(r,sintable[0]); + spy = lpy = y1+mulscale14(r,sintable[512]); + + for (l=64;l<2048;l+=64) { + px = x1+mulscale14(r,sintable[l]); + py = y1+mulscale14(r,sintable[(l+512)&2047]); + + drawline16(lpx,lpy,px,py,col); + + lpx = px; + lpy = py; + } + + drawline16(lpx,lpy,spx,spy,col); +#endif +} + + +// +// qsetmode640350 +// +void qsetmode640350(void) +{ + if (qsetmode != 350) + { + if (setvideomode(640, 350, 8, fullscreen) < 0) { + //fprintf(stderr, "Couldn't set 640x350 video mode for some reason.\n"); + return; + } + + xdim = xres; + ydim = yres; + + setvgapalette(); + + ydim16 = 350; + halfxdim16 = 320; + midydim16 = 146; + + begindrawing(); //{{{ + clearbuf((char *)frameplace, (bytesperline*350L) >> 2, 0); + enddrawing(); //}}} + } + + qsetmode = 350; +} + + +// +// qsetmode640480 +// +void qsetmode640480(void) +{ + if (qsetmode != 480) + { + if (setvideomode(640, 480, 8, fullscreen) < 0) { + //fprintf(stderr, "Couldn't set 640x480 video mode for some reason.\n"); + return; + } + + xdim = xres; + ydim = yres; + + setvgapalette(); + + ydim16 = 336; + halfxdim16 = 320; + midydim16 = 200; + + begindrawing(); //{{{ + clearbuf((char *)(frameplace + (336l*bytesperline)), (bytesperline*144L) >> 2, 0x08080808l); + clearbuf((char *)frameplace, (bytesperline*336L) >> 2, 0L); + enddrawing(); //}}} + } + + qsetmode = 480; +} + + +// +// qsetmodeany +// +void qsetmodeany(long daxdim, long daydim) +{ + if (daxdim < 640) daxdim = 640; + if (daydim < 480) daydim = 480; + + if (qsetmode != ((daxdim<<16)|(daydim&0xffff))) { + if (setvideomode(daxdim, daydim, 8, fullscreen) < 0) + return; + + xdim = xres; + ydim = yres; + + setvgapalette(); + + ydim16 = yres - STATUS2DSIZ; + halfxdim16 = xres >> 1; + midydim16 = scale(200,yres,480); + + begindrawing(); //{{{ + clearbuf((char *)(frameplace + (ydim16*bytesperline)), (bytesperline*STATUS2DSIZ) >> 2, 0x08080808l); + clearbuf((char *)frameplace, (ydim16*bytesperline) >> 2, 0L); + enddrawing(); //}}} + } + + qsetmode = ((daxdim<<16)|(daydim&0xffff)); +} + + +// +// clear2dscreen +// +void clear2dscreen(void) +{ + int clearsz; + + begindrawing(); //{{{ + if (qsetmode == 350) clearsz = 350; + else { + if (ydim16 <= yres-STATUS2DSIZ) clearsz = yres - STATUS2DSIZ; + else clearsz = yres; + } + clearbuf((char *)frameplace, (bytesperline*clearsz) >> 2, 0); + enddrawing(); //}}} +} + + +// +// draw2dgrid +// +void draw2dgrid(long posxe, long posye, short ange, long zoome, short gride) +{ + long i, xp1, yp1, xp2=0, yp2, tempy; + + if (gride > 0) + { + begindrawing(); //{{{ + + yp1 = midydim16-mulscale14(posye+editorgridextent,zoome); + if (yp1 < 0) yp1 = 0; + yp2 = midydim16-mulscale14(posye-editorgridextent,zoome); + if (yp2 >= ydim16) yp2 = ydim16-1; + + if ((yp1 < ydim16) && (yp2 >= 0) && (yp2 >= yp1)) + { + xp1 = halfxdim16-mulscale14(posxe+editorgridextent,zoome); + for(i=-editorgridextent;i<=editorgridextent;i+=(2048>>gride)) + { + xp2 = xp1; + xp1 = halfxdim16-mulscale14(posxe-i,zoome); + if (xp1 >= xdim) break; + if (xp1 >= 0) + { + if (xp1 != xp2) + { + drawline16(xp1,yp1,xp1,yp2,8); + } + } + } + if ((i >= editorgridextent) && (xp1 < xdim)) + xp2 = xp1; + if ((xp2 >= 0) && (xp2 < xdim)) + { + drawline16(xp2,yp1,xp2,yp2,8); + } + } + xp1 = mulscale14(posxe+editorgridextent,zoome); + xp2 = mulscale14(posxe-editorgridextent,zoome); + tempy = 0x80000000l; + for(i=-editorgridextent;i<=editorgridextent;i+=(2048>>gride)) + { + yp1 = (((posye-i)*zoome)>>14); + if (yp1 != tempy) + { + if ((yp1 > midydim16-ydim16) && (yp1 <= midydim16)) + { + drawline16(halfxdim16-xp1,midydim16-yp1,halfxdim16-xp2,midydim16-yp1,8); + tempy = yp1; + } + } + } + enddrawing(); //}}} + } +} + + +// +// draw2dscreen +// + +char spritecol2d[MAXTILES][2]; + +void draw2dscreen(long posxe, long posye, short ange, long zoome, short gride) +{ + walltype *wal; + long i, j, k, xp1, yp1, xp2, yp2, tempy, templong; + char col, mask; + + if (qsetmode == 200) return; + + begindrawing(); //{{{ + + if (editstatus == 0) + { + faketimerhandler(); + clear2dscreen(); + + faketimerhandler(); + draw2dgrid(posxe,posye,ange,zoome,gride); + } + + faketimerhandler(); + for(i=numwalls-1,wal=&wall[i];i>=0;i--,wal--) + { + if (editstatus == 0) + { + if ((show2dwall[i>>3]&pow2char[i&7]) == 0) continue; + j = wal->nextwall; + if ((j >= 0) && (i > j)) + if ((show2dwall[j>>3]&pow2char[j&7]) > 0) continue; + } + else + { + j = wal->nextwall; + if ((j >= 0) && (i > j)) continue; + } + + if (j < 0) + { + col = 7; + if (i == linehighlight) if (totalclock & 16) col += (2<<2); + } + else + { + col = 4; + if ((wal->cstat&1) != 0) col = 5; + if ((i == linehighlight) || ((linehighlight >= 0) && (i == wall[linehighlight].nextwall))) + if (totalclock & 16) col += (2<<2); + } + + xp1 = mulscale14(wal->x-posxe,zoome); + yp1 = mulscale14(wal->y-posye,zoome); + xp2 = mulscale14(wall[wal->point2].x-posxe,zoome); + yp2 = mulscale14(wall[wal->point2].y-posye,zoome); + + if ((wal->cstat&64) > 0) + { + if (klabs(xp2-xp1) >= klabs(yp2-yp1)) + { + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp2,midydim16+yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp2,midydim16+yp2-1,col); + } + else + { + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp2+1,midydim16+yp2,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp2-1,midydim16+yp2,col); + } + col += 8; + } + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp2,midydim16+yp2,col); + if ((zoome >= 256) && (editstatus == 1)) + if (((halfxdim16+xp1) >= 2) && ((halfxdim16+xp1) <= xdim-3)) + if (((midydim16+yp1) >= 2) && ((midydim16+yp1) <= ydim16-3)) + { + char pointsize; + col = 6; + pointsize=2; + if (i == pointhighlight || ((wall[i].x == wall[pointhighlight].x) && (wall[i].y == wall[pointhighlight].y))) + { + if (totalclock & 16) + { + col += (2<<2); // JBF 20040116: two braces is all this needed. man I'm a fool sometimes. + pointsize += 1; + } + } + else if ((highlightcnt > 0) && (editstatus == 1)) + { + if (show2dwall[i>>3]&pow2char[i&7]) + if (totalclock & 16) + { + col += (2<<2); // JBF 20040116: two braces is all this needed. man I'm a fool sometimes. + pointsize += 1; + } + } + + templong = ((midydim16+yp1)*bytesperline)+(halfxdim16+xp1)+frameplace; + + drawline16(halfxdim16+xp1-pointsize,midydim16+yp1+pointsize,halfxdim16+xp1+pointsize,midydim16+yp1+pointsize,col); + drawline16(halfxdim16+xp1+pointsize,midydim16+yp1+pointsize,halfxdim16+xp1+pointsize,midydim16+yp1-pointsize,col); + drawline16(halfxdim16+xp1+pointsize,midydim16+yp1-pointsize,halfxdim16+xp1-pointsize,midydim16+yp1-pointsize,col); + drawline16(halfxdim16+xp1-pointsize,midydim16+yp1-pointsize,halfxdim16+xp1-pointsize,midydim16+yp1+pointsize,col); + + } + } + faketimerhandler(); + + if ((zoome >= 256) || (editstatus == 0)) + for(i=0;i=0;j=nextspritesect[j]) + if ((editstatus == 1) || (show2dsprite[j>>3]&pow2char[j&7])) + { + col = 3; + if (spritecol2d[sprite[j].picnum][0]) + col = spritecol2d[sprite[j].picnum][0]; + if ((sprite[j].cstat&1) > 0) + { + col = 5; + if (spritecol2d[sprite[j].picnum][1]) + col = spritecol2d[sprite[j].picnum][1]; + } + if (editstatus == 1) + { + if (j+16384 == pointhighlight || ((sprite[j].x == sprite[pointhighlight-16384].x) && (sprite[j].y == sprite[pointhighlight-16384].y))) { + if (totalclock & 32) col += (2<<2); + } + else if ((highlightcnt > 0) && (editstatus == 1)) + { + if (show2dsprite[j>>3]&pow2char[j&7]) + if (totalclock & 32) col += (2<<2); + } + } + + xp1 = mulscale14(sprite[j].x-posxe,zoome); + yp1 = mulscale14(sprite[j].y-posye,zoome); + if (((halfxdim16+xp1) >= 4) && ((halfxdim16+xp1) <= xdim-6)) + if (((midydim16+yp1) >= 4) && ((midydim16+yp1) <= ydim16-6)) + { + long temp; + templong = ((midydim16+yp1)*bytesperline)+(halfxdim16+xp1)+frameplace; + + + for (temp=0;temp<2;temp++) + { + drawpixel((char *)(templong+3+(bytesperline*temp)), col); + drawpixel((char *)(templong-3-(bytesperline*temp)), col); + drawpixel((char *)(templong-3+(bytesperline*temp)), col); + drawpixel((char *)(templong+3-(bytesperline*temp)), col); + } + + drawpixel((char *)(templong+2+(bytesperline*2)), col); + drawpixel((char *)(templong-2-(bytesperline*2)), col); + drawpixel((char *)(templong-2+(bytesperline*2)), col); + drawpixel((char *)(templong+2-(bytesperline*2)), col); + + for (temp=0;temp<2;temp++) + { + drawpixel((char *)(templong+temp+(bytesperline*3)), col); + drawpixel((char *)(templong-temp-(bytesperline*3)), col); + drawpixel((char *)(templong-temp+(bytesperline*3)), col); + drawpixel((char *)(templong+temp-(bytesperline*3)), col); + } + + + xp2 = mulscale11(sintable[(sprite[j].ang+2560)&2047],zoome) / 768; + yp2 = mulscale11(sintable[(sprite[j].ang+2048)&2047],zoome) / 768; + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + + if ((sprite[j].cstat&256) > 0) + { + if (((sprite[j].ang+256)&512) == 0) + { + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1+xp2,midydim16+yp1+yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1+xp2,midydim16+yp1+yp2-1,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1+xp2-1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1+xp2+1,midydim16+yp1+yp2,col); + + } + else + { + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1+xp2,midydim16+yp1+yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1+xp2,midydim16+yp1+yp2-1,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1+xp2-1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1+xp2+1,midydim16+yp1+yp2,col); + + } + + if ((sprite[j].cstat&32) > 0) { + long fx = mulscale6(tilesizx[sprite[j].picnum], sprite[j].xrepeat); + long fy = mulscale6(tilesizy[sprite[j].picnum], sprite[j].yrepeat); + long co[4][2], ii; + long sinang = sintable[(sprite[j].ang+512+1024)&2047]; + long cosang = sintable[(sprite[j].ang+1024)&2047]; + long r,s; + + fx = mulscale10(fx,zoome) >> 1; + fy = mulscale10(fy,zoome) >> 1; + + co[0][0] = -fx; + co[0][1] = -fy; + co[1][0] = fx; + co[1][1] = -fy; + co[2][0] = fx; + co[2][1] = fy; + co[3][0] = -fx; + co[3][1] = fy; + + for (ii=0;ii<4;ii++) { + r = mulscale14(cosang,co[ii][0]) - mulscale14(sinang,co[ii][1]); + s = mulscale14(sinang,co[ii][0]) + mulscale14(cosang,co[ii][1]); + co[ii][0] = r; + co[ii][1] = s; + } + drawlinepat = 0xcfcfcfcf; + for (ii=0;ii<4;ii++) + { + drawline16(halfxdim16 + xp1 + co[ii][0], midydim16 + yp1 - co[ii][1], + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1], + col); + drawline16(halfxdim16 + xp1 + co[ii][0], midydim16 + yp1 - co[ii][1] + 1, + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1] + 1, + col); + drawline16(halfxdim16 + xp1 + co[ii][0], midydim16 + yp1 - co[ii][1] - 1, + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1] - 1, + col); + drawline16(halfxdim16 + xp1 + co[ii][0] + 1, midydim16 + yp1 - co[ii][1], + halfxdim16 + xp1 + co[(ii+1)&3][0] + 1, midydim16 + yp1 - co[(ii+1)&3][1], + col); + drawline16(halfxdim16 + xp1 + co[ii][0] - 1, midydim16 + yp1 - co[ii][1], + halfxdim16 + xp1 + co[(ii+1)&3][0] - 1, midydim16 + yp1 - co[(ii+1)&3][1], + col); + drawline16(halfxdim16 + xp1, midydim16 + yp1, + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1], + col); + } + drawlinepat = 0xffffffff; + } + + else if ((sprite[j].cstat&16) > 0) + { + long fx = mulscale6(tilesizx[sprite[j].picnum], sprite[j].xrepeat); + xp2 = mulscale11(sintable[(sprite[j].ang+2560)&2047],zoome) / 6144; + yp2 = mulscale11(sintable[(sprite[j].ang+2048)&2047],zoome) / 6144; + + + if (((sprite[j].ang+256)&512) == 0) + { + if (!(sprite[j].cstat&64)) + { + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1-xp2,midydim16+yp1-yp2-1,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1-xp2,midydim16+yp1-yp2+1,col); + } + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1+xp2,midydim16+yp1+yp2-1,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1+xp2,midydim16+yp1+yp2+1,col); + xp2 = mulscale10(sintable[(sprite[j].ang+1024)&2047],zoome) * fx / 32768; + yp2 = mulscale10(sintable[(sprite[j].ang+512)&2047],zoome) * fx / 32768; + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1+xp2+1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1-xp2-1,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1+xp2-1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1-xp2+1,midydim16+yp1-yp2,col); + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1+xp2,midydim16+yp1+yp2-1,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1-xp2,midydim16+yp1-yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1+xp2,midydim16+yp1+yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1-xp2,midydim16+yp1-yp2-1,col); + } + else + { + if (!(sprite[j].cstat&64)) + { + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1-xp2-1,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1-xp2+1,midydim16+yp1-yp2,col); + } + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1+xp2-1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1+xp2+1,midydim16+yp1+yp2,col); + xp2 = mulscale10(sintable[(sprite[j].ang+1024)&2047],zoome) * fx / 32768; + yp2 = mulscale10(sintable[(sprite[j].ang+512)&2047],zoome) * fx / 32768; + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1+xp2+1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1-xp2-1,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1-1,midydim16+yp1,halfxdim16+xp1+xp2-1,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1+1,midydim16+yp1,halfxdim16+xp1-xp2+1,midydim16+yp1-yp2,col); + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1+xp2,midydim16+yp1+yp2-1,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1-xp2,midydim16+yp1-yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1+1,halfxdim16+xp1+xp2,midydim16+yp1+yp2+1,col); + drawline16(halfxdim16+xp1,midydim16+yp1-1,halfxdim16+xp1-xp2,midydim16+yp1-yp2-1,col); + } + + } + + col += 8; + } + + else if ((sprite[j].cstat&16) > 0) + { + long fx = mulscale6(tilesizx[sprite[j].picnum], sprite[j].xrepeat); + + xp2 = mulscale11(sintable[(sprite[j].ang+2560)&2047],zoome) / 6144; + yp2 = mulscale11(sintable[(sprite[j].ang+2048)&2047],zoome) / 6144; + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + if (!(sprite[j].cstat&64)) drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + xp2 = mulscale10(sintable[(sprite[j].ang+1024)&2047],zoome) * fx / 32768; + yp2 = mulscale10(sintable[(sprite[j].ang+512)&2047],zoome) * fx / 32768; + + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1+xp2,midydim16+yp1+yp2,col); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+xp1-xp2,midydim16+yp1-yp2,col); + + + col += 8; + } + + else if ((sprite[j].cstat&32) > 0) + { + long fx = mulscale6(tilesizx[sprite[j].picnum], sprite[j].xrepeat); + long fy = mulscale6(tilesizy[sprite[j].picnum], sprite[j].yrepeat); + long co[4][2], ii; + long sinang = sintable[(sprite[j].ang+512+1024)&2047]; + long cosang = sintable[(sprite[j].ang+1024)&2047]; + long r,s; + + fx = mulscale10(fx,zoome) >> 1; + fy = mulscale10(fy,zoome) >> 1; + + co[0][0] = -fx; + co[0][1] = -fy; + co[1][0] = fx; + co[1][1] = -fy; + co[2][0] = fx; + co[2][1] = fy; + co[3][0] = -fx; + co[3][1] = fy; + + for (ii=0;ii<4;ii++) { + r = mulscale14(cosang,co[ii][0]) - mulscale14(sinang,co[ii][1]); + s = mulscale14(sinang,co[ii][0]) + mulscale14(cosang,co[ii][1]); + co[ii][0] = r; + co[ii][1] = s; + } + + drawlinepat = 0xcfcfcfcf; + for (ii=0;ii<4;ii++) { + drawline16(halfxdim16 + xp1 + co[ii][0], midydim16 + yp1 - co[ii][1], + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1], + col); + drawline16(halfxdim16 + xp1, midydim16 + yp1, + halfxdim16 + xp1 + co[(ii+1)&3][0], midydim16 + yp1 - co[(ii+1)&3][1], + col); + } + drawlinepat = 0xffffffff; + } + } + } + + faketimerhandler(); + xp1 = mulscale11(sintable[(ange+2560)&2047],zoome) / 768; //Draw white arrow + yp1 = mulscale11(sintable[(ange+2048)&2047],zoome) / 768; + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16-xp1,midydim16-yp1,15); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16+yp1,midydim16-xp1,15); + drawline16(halfxdim16+xp1,midydim16+yp1,halfxdim16-yp1,midydim16+xp1,15); + + + enddrawing(); //}}} +} + + +// +// printext16 +// +void printext16(long xpos, long ypos, short col, short backcol, char *name, char fontsize) +{ + long stx, i, x, y, charxsiz; + char *fontptr, *letptr, *ptr; + + stx = xpos; + + if (fontsize) { fontptr = smalltextfont; charxsiz = 4; } + else { fontptr = textfont; charxsiz = 8; } + + begindrawing(); //{{{ + for(i=0;name[i];i++) + { + letptr = &fontptr[name[i]<<3]; + ptr = (char *)(bytesperline*(ypos+7)+(stx-fontsize)+frameplace); + for(y=7;y>=0;y--) + { + for(x=charxsiz-1;x>=0;x--) + { + if (letptr[y]&pow2char[7-fontsize-x]) + ptr[x] = (char)col; + else if (backcol >= 0) + ptr[x] = (char)backcol; + } + ptr -= bytesperline; + } + stx += charxsiz; + } + enddrawing(); //}}} +} + + +// +// printext256 +// +void printext256(long xpos, long ypos, short col, short backcol, char *name, char fontsize) +{ + long stx, i, x, y, charxsiz; + char *fontptr, *letptr, *ptr; + + stx = xpos; + + if (fontsize) { fontptr = smalltextfont; charxsiz = 4; } + else { fontptr = textfont; charxsiz = 8; } + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (!polymost_printext256(xpos,ypos,col,backcol,name,fontsize)) return; + + if (rendmode == 3) { + long xx, yy; + int lc=-1; + palette_t p,b; + + if (gammabrightness) { + p = curpalette[col]; + b = curpalette[backcol]; + } else { + p.r = britable[curbrightness][ curpalette[col].r ]; + p.g = britable[curbrightness][ curpalette[col].g ]; + p.b = britable[curbrightness][ curpalette[col].b ]; + b.r = britable[curbrightness][ curpalette[backcol].r ]; + b.g = britable[curbrightness][ curpalette[backcol].g ]; + b.b = britable[curbrightness][ curpalette[backcol].b ]; + } + + setpolymost2dview(); + bglDisable(GL_ALPHA_TEST); + bglDepthMask(GL_FALSE); // disable writing to the z-buffer + + bglBegin(GL_POINTS); + + for(i=0;name[i];i++) { + letptr = &fontptr[name[i]<<3]; + xx = stx-fontsize; + yy = ypos+7 + 2; //+1 is hack! + for(y=7;y>=0;y--) { + for(x=charxsiz-1;x>=0;x--) { + if (letptr[y]&pow2char[7-fontsize-x]) { + if (lc!=col) + bglColor4ub(p.r,p.g,p.b,255); + lc = col; + bglVertex2i(xx+x,yy); + } else if (backcol >= 0) { + if (lc!=backcol) + bglColor4ub(b.r,b.g,b.b,255); + lc = backcol; + bglVertex2i(xx+x,yy); + } + } + yy--; + } + stx += charxsiz; + } + + bglEnd(); + bglDepthMask(GL_TRUE); // re-enable writing to the z-buffer + + return; + } +#endif + + begindrawing(); //{{{ + for(i=0;name[i];i++) + { + letptr = &fontptr[name[i]<<3]; + ptr = (char *)(ylookup[ypos+7]+(stx-fontsize)+frameplace); + for(y=7;y>=0;y--) + { + for(x=charxsiz-1;x>=0;x--) + { + if (letptr[y]&pow2char[7-fontsize-x]) + ptr[x] = (char)col; + else if (backcol >= 0) + ptr[x] = (char)backcol; + } + ptr -= ylookup[1]; + } + stx += charxsiz; + } + enddrawing(); //}}} +} + + +// +// screencapture +// +long screencapture_tga(char *filename, char inverseit) +{ + long i,j; + char *ptr, head[18] = { 0,1,1,0,0,0,1,24,0,0,0,0,0/*wlo*/,0/*whi*/,0/*hlo*/,0/*hhi*/,8,0 }; + //char palette[4*256]; + char *fn = Bstrdup(filename), *inversebuf, c; + BFILE *fil; + + do { // JBF 2004022: So we don't overwrite existing screenshots + if (capturecount > 9999) return -1; + + i = Bstrrchr(fn,'.')-fn-4; + fn[i++] = ((capturecount/1000)%10)+48; + fn[i++] = ((capturecount/100)%10)+48; + fn[i++] = ((capturecount/10)%10)+48; + fn[i++] = (capturecount%10)+48; + i++; + fn[i++] = 't'; + fn[i++] = 'g'; + fn[i++] = 'a'; + + if ((fil = Bfopen(fn,"rb")) == NULL) break; + Bfclose(fil); + capturecount++; + } while (1); + fil = Bfopen(fn,"wb"); + if (fil == NULL) { + Bfree(fn); + return -1; + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode >= 3 && qsetmode == 200) { + head[1] = 0; // no colourmap + head[2] = 2; // uncompressed truecolour + head[3] = 0; // (low) first colourmap index + head[4] = 0; // (high) first colourmap index + head[5] = 0; // (low) number colourmap entries + head[6] = 0; // (high) number colourmap entries + head[7] = 0; // colourmap entry size + head[16] = 24; // 24 bits per pixel + } +#endif + + head[12] = xdim & 0xff; + head[13] = (xdim >> 8) & 0xff; + head[14] = ydim & 0xff; + head[15] = (ydim >> 8) & 0xff; + + Bfwrite(head, 18, 1, fil); + + begindrawing(); //{{{ + ptr = (char *)frameplace; + + // palette first +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode < 3 || (rendmode == 3 && qsetmode != 200)) { +#endif + //getpalette(0,256,palette); + for (i=0; i<256; i++) { + Bfputc(curpalettefaded[i].b, fil); // b + Bfputc(curpalettefaded[i].g, fil); // g + Bfputc(curpalettefaded[i].r, fil); // r + } +#if defined(POLYMOST) && defined(USE_OPENGL) + } +#endif + + // targa renders bottom to top, from left to right + if (inverseit && qsetmode != 200) { + inversebuf = (char *)kmalloc(bytesperline); + if (inversebuf) { + for (i=ydim-1; i>=0; i--) { + copybuf(ptr+i*bytesperline, inversebuf, xdim >> 2); + for (j=0; j < (bytesperline>>2); j++) ((long *)inversebuf)[j] ^= 0x0f0f0f0fL; + Bfwrite(inversebuf, xdim, 1, fil); + } + kfree(inversebuf); + } + } else { +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode >= 3 && qsetmode == 200) { + // 24bit + inversebuf = (char *)kmalloc(xdim*ydim*3); + if (inversebuf) { + bglReadPixels(0,0,xdim,ydim,GL_RGB,GL_UNSIGNED_BYTE,inversebuf); + j = xdim*ydim*3; + for (i=0; i=0; i--) + Bfwrite(ptr+i*bytesperline, xdim, 1, fil); +#if defined(POLYMOST) && defined(USE_OPENGL) + } +#endif + } + + enddrawing(); //}}} + + Bfclose(fil); + OSD_Printf("Saved screenshot to %s\n", fn); + Bfree(fn); + capturecount++; + return(0); +} + +// PCX is nasty, which is why I've lifted these functions from the PCX spec by ZSoft +static int writepcxbyte(char colour, unsigned char count, BFILE *fp) +{ + if (!count) return 0; + if (count == 1 && (colour & 0xc0) != 0xc0) { + Bfputc(colour, fp); + return 1; + } else { + Bfputc(0xc0 | count, fp); + Bfputc(colour, fp); + return 2; + } +} + +static void writepcxline(char *buf, long bytes, long step, BFILE *fp) +{ + char ths, last; + int srcIndex, i; + unsigned char runCount; + + runCount = 1; + last = *buf; + + for (srcIndex=1; srcIndex 9999) return -1; + + i = Bstrrchr(fn,'.')-fn-4; + fn[i++] = ((capturecount/1000)%10)+48; + fn[i++] = ((capturecount/100)%10)+48; + fn[i++] = ((capturecount/10)%10)+48; + fn[i++] = (capturecount%10)+48; + i++; + fn[i++] = 'p'; + fn[i++] = 'c'; + fn[i++] = 'x'; + + if ((fil = Bfopen(fn,"rb")) == NULL) break; + Bfclose(fil); + capturecount++; + } while (1); + fil = Bfopen(fn,"wb"); + if (fil == NULL) { + Bfree(fn); + return -1; + } + + memset(head,0,128); + head[0] = 10; + head[1] = 5; + head[2] = 1; + head[3] = 8; + head[12] = 72; head[13] = 0; + head[14] = 72; head[15] = 0; + head[65] = 1; // 8-bit + head[68] = 1; + +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode >= 3 && qsetmode == 200) { + head[65] = 3; // 24-bit + } +#endif + + head[8] = (xdim-1) & 0xff; + head[9] = ((xdim-1) >> 8) & 0xff; + head[10] = (ydim-1) & 0xff; + head[11] = ((ydim-1) >> 8) & 0xff; + + bpl = xdim + (xdim&1); + + head[66] = bpl & 0xff; + head[67] = (bpl >> 8) & 0xff; + + Bfwrite(head, 128, 1, fil); + + begindrawing(); //{{{ + ptr = (char *)frameplace; + + // targa renders bottom to top, from left to right + if (inverseit && qsetmode != 200) { + inversebuf = (char *)kmalloc(bytesperline); + if (inversebuf) { + for (i=0; i> 2); + for (j=0; j < (bytesperline>>2); j++) ((long *)inversebuf)[j] ^= 0x0f0f0f0fL; + writepcxline(inversebuf, xdim, 1, fil); + } + kfree(inversebuf); + } + } else { +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode >= 3 && qsetmode == 200) { + // 24bit + inversebuf = (char *)kmalloc(xdim*ydim*3); + if (inversebuf) { + bglReadPixels(0,0,xdim,ydim,GL_RGB,GL_UNSIGNED_BYTE,inversebuf); + for (i=ydim-1; i>=0; i--) { + writepcxline(inversebuf+i*xdim*3, xdim, 3, fil); + writepcxline(inversebuf+i*xdim*3+1, xdim, 3, fil); + writepcxline(inversebuf+i*xdim*3+2, xdim, 3, fil); + } + kfree(inversebuf); + } + } else { +#endif + for (i=0; i 2) renderer = 2; + } else { + renderer = 3; + } + + rendmode = renderer; +#endif + + return 0; +} + +// +// getrendermode +// +int getrendermode(void) +{ +#ifndef POLYMOST + return 0; +#else + return rendmode; +#endif +} + + +// +// setrollangle +// +void setrollangle(long rolla) +{ +#ifdef POLYMOST + if (rolla == 0) gtang = 0.0; + else gtang = PI * (double)rolla / 1024.0; +#endif +} + + +// +// invalidatetile +// pal: pass -1 to invalidate all palettes for the tile, or >=0 for a particular palette +// how: pass -1 to invalidate all instances of the tile in texture memory, or a bitfield +// bit 0: opaque or masked (non-translucent) texture, using repeating +// bit 1: ignored +// bit 2: ignored (33% translucence, using repeating) +// bit 3: ignored (67% translucence, using repeating) +// bit 4: opaque or masked (non-translucent) texture, using clamping +// bit 5: ignored +// bit 6: ignored (33% translucence, using clamping) +// bit 7: ignored (67% translucence, using clamping) +// clamping is for sprites, repeating is for walls +// +void invalidatetile(short tilenume, long pal, long how) +{ +#if defined(POLYMOST) && defined(USE_OPENGL) + int numpal, firstpal, np; + int hp; + + if (rendmode < 3) return; + + if (pal < 0) { + numpal = MAXPALOOKUPS; + firstpal = 0; + } else { + numpal = 1; + firstpal = pal % MAXPALOOKUPS; + } + + for (hp = 0; hp < 8; hp+=4) { + if (!(how & pow2long[hp])) continue; + + for (np = firstpal; np < firstpal+numpal; np++) { + gltexinvalidate(tilenume, np, hp); + } + } +#endif +} + + +// +// setpolymost2dview +// Sets OpenGL for 2D drawing +// +void setpolymost2dview(void) +{ +#if defined(POLYMOST) && defined(USE_OPENGL) + if (rendmode < 3) return; + + if (gloy1 != -1) { + bglViewport(0,0,xres,yres); + bglMatrixMode(GL_PROJECTION); + bglLoadIdentity(); + bglOrtho(0,xres,yres,0,-1,1); + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); + } + + gloy1 = -1; + + bglDisable(GL_DEPTH_TEST); + bglDisable(GL_TEXTURE_2D); + bglDisable(GL_BLEND); +#endif +} + + +/* + * vim:ts=8: + */ + diff --git a/polymer/build/src/game.c b/polymer/build/src/game.c new file mode 100644 index 000000000..2c86eacb8 --- /dev/null +++ b/polymer/build/src/game.c @@ -0,0 +1,6297 @@ +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "build.h" +#include "names.h" +#include "pragmas.h" +#include "cache1d.h" +#include "game.h" +#include "osd.h" +#include "mmulti.h" + +#include "baselayer.h" + +#define TIMERINTSPERSECOND 140 //280 +#define MOVESPERSECOND 40 +#define TICSPERFRAME 3 +#define MOVEFIFOSIZ 256 +#define EYEHEIGHT (32<<8) //Normally (32<<8), (51<<8) to make mirrors happy + +// declared in sound.c +void initsb(char,char,long,char,char,char,char); +void uninitsb(void); +void setears(long,long,long,long); +void wsayfollow(char *,long,long,long *,long *,char); +void wsay(char *,long,long,long); +void loadwaves(void); +void loadsong(char *); +void musicon(void); +void musicoff(void); +void refreshaudio(void); + +// declared in config.c +int loadsetup(const char *); +int writesetup(const char *); + + +/*************************************************************************** + KEN'S TAG DEFINITIONS: (Please define your own tags for your games) + + sector[?].lotag = 0 Normal sector + sector[?].lotag = 1 If you are on a sector with this tag, then all sectors + with same hi tag as this are operated. Once. + sector[?].lotag = 2 Same as sector[?].tag = 1 but this is retriggable. + sector[?].lotag = 3 A really stupid sector that really does nothing now. + sector[?].lotag = 4 A sector where you are put closer to the floor + (such as the slime in DOOM1.DAT) + sector[?].lotag = 5 A really stupid sector that really does nothing now. + sector[?].lotag = 6 A normal door - instead of pressing D, you tag the + sector with a 6. The reason I make you edit doors + this way is so that can program the doors + yourself. + sector[?].lotag = 7 A door the goes down to open. + sector[?].lotag = 8 A door that opens horizontally in the middle. + sector[?].lotag = 9 A sliding door that opens vertically in the middle. + -Example of the advantages of not using BSP tree. + sector[?].lotag = 10 A warping sector with floor and walls that shade. + sector[?].lotag = 11 A sector with all walls that do X-panning. + sector[?].lotag = 12 A sector with walls using the dragging function. + sector[?].lotag = 13 A sector with some swinging doors in it. + sector[?].lotag = 14 A revolving door sector. + sector[?].lotag = 15 A subway track. + sector[?].lotag = 16 A true double-sliding door. + + wall[?].lotag = 0 Normal wall + wall[?].lotag = 1 Y-panning wall + wall[?].lotag = 2 Switch - If you flip it, then all sectors with same hi + tag as this are operated. + wall[?].lotag = 3 Marked wall to detemine starting dir. (sector tag 12) + wall[?].lotag = 4 Mark on the shorter wall closest to the pivot point + of a swinging door. (sector tag 13) + wall[?].lotag = 5 Mark where a subway should stop. (sector tag 15) + wall[?].lotag = 6 Mark for true double-sliding doors (sector tag 16) + wall[?].lotag = 7 Water fountain + wall[?].lotag = 8 Bouncy wall! + + sprite[?].lotag = 0 Normal sprite + sprite[?].lotag = 1 If you press space bar on an AL, and the AL is tagged + with a 1, he will turn evil. + sprite[?].lotag = 2 When this sprite is operated, a bomb is shot at its + position. + sprite[?].lotag = 3 Rotating sprite. + sprite[?].lotag = 4 Sprite switch. + sprite[?].lotag = 5 Basketball hoop score. + +KEN'S STATUS DEFINITIONS: (Please define your own statuses for your games) + status = 0 Inactive sprite + status = 1 Active monster sprite + status = 2 Monster that becomes active only when it sees you + status = 3 Smoke on the wall for chainguns + status = 4 Splashing sprites (When you shoot slime) + status = 5 Explosion! + status = 6 Travelling bullet + status = 7 Bomb sprial-out explosion + status = 8 Player! + status = 9 EVILALGRAVE shrinking list + status = 10 EVILAL list + status = 11 Sprite respawning list + status = 12 Sprite which does not respawn (Andy's addition) + status = MAXSTATUS Non-existent sprite (this will be true for your + code also) +**************************************************************************/ + +typedef struct +{ + long x, y, z; +} point3d; + +typedef struct +{ + signed char fvel, svel, avel; + short bits; +} input; + +static long screentilt = 0, oscreentilt = 0; + + +static long fvel, svel, avel; +static long fvel2, svel2, avel2; + +#define NUMOPTIONS 8 +#define NUMKEYS 19 +char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0}; +char keys[NUMKEYS] = +{ + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x33,0x34, + 0x9c,0x1c,0xd,0xc,0xf +}; +long xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480; // JBF 20050318: config.c expects to find these + +static long digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000}; + +static char frame2draw[MAXPLAYERS]; +static long frameskipcnt[MAXPLAYERS]; + +#define LAVASIZ 128 +#define LAVALOGSIZ 7 +#define LAVAMAXDROPS 32 +static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ]; +static long lavanumdrops, lavanumframes; +static long lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS]; +static long lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS]; +static long lavaradx[24][96], lavarady[24][96], lavaradcnt[32]; + + //Shared player variables +static long posx[MAXPLAYERS], posy[MAXPLAYERS], posz[MAXPLAYERS]; +static long horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS]; +static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS]; +static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS]; +static long lastchaingun[MAXPLAYERS]; +static long health[MAXPLAYERS], flytime[MAXPLAYERS]; +static short oflags[MAXPLAYERS]; +static short numbombs[MAXPLAYERS]; +static short numgrabbers[MAXPLAYERS]; // Andy did this +static short nummissiles[MAXPLAYERS]; // Andy did this +static char dimensionmode[MAXPLAYERS]; +static char revolvedoorstat[MAXPLAYERS]; +static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS]; +static long revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS]; + + //ENGINE CONTROLLED MULTIPLAYER VARIABLES: +extern long numplayers, myconnectindex; +extern long connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers) + +static long nummoves; +// Bug: NUMSTATS used to be equal to the greatest tag number, +// so that the last statrate[] entry was random memory junk +// because stats 0-NUMSTATS required NUMSTATS+1 bytes. -Andy +#define NUMSTATS 13 +static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1}; + + //Input structures +static char networkmode; //0 is 2(n-1) mode, 1 is n(n-1) mode +static long locselectedgun, locselectedgun2; +static input loc, oloc, loc2; +static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS]; + //Input faketimerhandler -> movethings fifo +static long movefifoplc, movefifoend[MAXPLAYERS]; +static input baksync[MOVEFIFOSIZ][MAXPLAYERS]; + //Game recording variables +static long reccnt, recstat = 1; +static input recsync[16384][2]; + +//static long myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; +static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; +static long averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}; + +static long fakemovefifoplc; +static long myx, myy, myz, omyx, omyy, omyz, myzvel; +static long myhoriz, omyhoriz; +static short myang, omyang, mycursectnum; +static long myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; +static long myhorizbak[MOVEFIFOSIZ]; +static short myangbak[MOVEFIFOSIZ]; + + //MULTI.OBJ sync state variables +extern char syncstate; + //GAME.C sync state variables +static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ]; +static long syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail; + +static char detailmode = 0, ready2send = 0; +static long ototalclock = 0, gotlastpacketclock = 0, smoothratio; +static long oposx[MAXPLAYERS], oposy[MAXPLAYERS], oposz[MAXPLAYERS]; +static long ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS]; +static short oang[MAXPLAYERS]; + +static point3d osprite[MAXSPRITES]; + +#define MAXINTERPOLATIONS 1024 +static long numinterpolations = 0, startofdynamicinterpolations = 0; +static long oldipos[MAXINTERPOLATIONS]; +static long bakipos[MAXINTERPOLATIONS]; +static long *curipos[MAXINTERPOLATIONS]; + +extern long cachecount; + +static char playerreadyflag[MAXPLAYERS]; + + //Miscellaneous variables +static char packbuf[MAXXDIM]; +static char tempbuf[MAXXDIM], boardfilename[80]; +static short tempshort[MAXSECTORS]; +static short screenpeek = 0, oldmousebstatus = 0; +short brightness = 0; +static short screensize, screensizeflag = 0; +static short neartagsector, neartagwall, neartagsprite; +static long lockclock, neartagdist, neartaghitdist; +extern long pageoffset, ydim16; +static long globhiz, globloz, globhihit, globlohit; + + //Over the shoulder mode variables +static long cameradist = -1, cameraang = 0, cameraclock = 0; + + //Board animation variables +#define MAXMIRRORS 64 +static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt; +static short floormirrorsector[64], floormirrorcnt; +static short turnspritelist[16], turnspritecnt; +static short warpsectorlist[64], warpsectorcnt; +static short xpanningsectorlist[16], xpanningsectorcnt; +static short ypanningwalllist[64], ypanningwallcnt; +static short floorpanninglist[64], floorpanningcnt; +static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; +static long dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; +static short swingcnt, swingwall[32][5], swingsector[32]; +static short swingangopen[32], swingangclosed[32], swingangopendir[32]; +static short swingang[32], swinganginc[32]; +static long swingx[32][8], swingy[32][8]; +static short revolvesector[4], revolveang[4], revolvecnt; +static long revolvex[4][16], revolvey[4][16]; +static long revolvepivotx[4], revolvepivoty[4]; +static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt; +static long subwaystop[4][8], subwaystopcnt[4]; +static long subwaytrackx1[4], subwaytracky1[4]; +static long subwaytrackx2[4], subwaytracky2[4]; +static long subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4]; +static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS]; +static short slimesoundcnt[MAXPLAYERS]; + + //Variables that let you type messages to other player +static char getmessage[162], getmessageleng; +static long getmessagetimeoff; +static char typemessage[162], typemessageleng = 0, typemode = 0; +/* +static char scantoasc[128] = +{ + 0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0, + 'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s', + 'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v', + 'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0, + 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', + '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +static char scantoascwithshift[128] = +{ + 0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0, + 'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S', + 'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V', + 'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0, + 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', + '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +*/ + + //These variables are for animating x, y, or z-coordinates of sectors, + //walls, or sprites (They are NOT to be used for changing the [].picnum's) + //See the setanimation(), and getanimategoal() functions for more details. +#define MAXANIMATES 512 +static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; +static long animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + //These parameters are in exact order of sprite structure in BUILD.H +#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ + clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ + xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ +{ \ + spritetype *spr2; \ + newspriteindex2 = insertsprite(sectnum2,statnum2); \ + spr2 = &sprite[newspriteindex2]; \ + spr2->x = x2; spr2->y = y2; spr2->z = z2; \ + spr2->cstat = cstat2; spr2->shade = shade2; \ + spr2->pal = pal2; spr2->clipdist = clipdist2; \ + spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ + spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ + spr2->picnum = picnum2; spr2->ang = ang2; \ + spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ + spr2->owner = owner2; \ + spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ + copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ + show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ + if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ + show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ + clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteexttype), 0); \ +} +#else +#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ + clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ + xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ +{ \ + spritetype *spr2; \ + newspriteindex2 = insertsprite(sectnum2,statnum2); \ + spr2 = &sprite[newspriteindex2]; \ + spr2->x = x2; spr2->y = y2; spr2->z = z2; \ + spr2->cstat = cstat2; spr2->shade = shade2; \ + spr2->pal = pal2; spr2->clipdist = clipdist2; \ + spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ + spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ + spr2->picnum = picnum2; spr2->ang = ang2; \ + spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ + spr2->owner = owner2; \ + spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ + copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ + show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ + if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ + show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ +} +#endif + +int nextvoxid = 0; + +static int osdcmd_restartvid(const osdfuncparm_t *parm) +{ + resetvideomode(); + if (setgamemode(fullscreen,xdim,ydim,bpp)) + OSD_Printf("restartvid: Reset failed...\n"); + + return OSDCMD_OK; +} + +static int osdcmd_vidmode(const osdfuncparm_t *parm) +{ + long newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; + + if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP; + + switch (parm->numparms) { + case 1: // bpp switch + newbpp = Batol(parm->parms[0]); + break; + case 2: // res switch + newx = Batol(parm->parms[0]); + newy = Batol(parm->parms[1]); + break; + case 3: // res & bpp switch + case 4: + newx = Batol(parm->parms[0]); + newy = Batol(parm->parms[1]); + newbpp = Batol(parm->parms[2]); + if (parm->numparms == 4) + newfullscreen = (Batol(parm->parms[3]) != 0); + break; + } + + if (setgamemode(newfullscreen,newx,newy,newbpp)) + OSD_Printf("vidmode: Mode change failed!\n"); + screensize = xdim+1; + return OSDCMD_OK; +} + +#ifdef RENDERTYPEWIN +int DoLaunchWindow(void); // gamestartwin.c +#endif + +char *startwin_labeltext = "Starting KenBuild..."; + +long app_main(long argc, char *argv[]) +{ + long i, j, k, l, fil, waitplayers, x1, y1, x2, y2; + long other, packleng, netparm; + +#ifdef USE_OPENGL + OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid); + OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); +#endif + + wm_setapptitle("KenBuild by Ken Silverman"); + + Bstrcpy(boardfilename, "nukeland.map"); + j = 0; netparm = argc; + for (i=1;i= 2); + + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + + loadpics("tiles000.art",1048576); //Load artwork +#ifdef SUPERBUILD + if (!qloadkvx(nextvoxid,"voxel000.kvx")) + tiletovox[PLAYER] = nextvoxid++; + if (!qloadkvx(nextvoxid,"voxel001.kvx")) + tiletovox[BROWNMONSTER] = nextvoxid++; +#endif + if (!loaddefinitionsfile("kenbuild.def")) initprintf("Definitions file loaded.\n"); + + //Here's an example of TRUE ornamented walls + //The allocatepermanenttile should be called right after loadpics + //Since it resets the tile cache for each call. + if (allocatepermanenttile(SLIME,128,128) == 0) //If enough memory + { + printf("Not enough memory for slime!\n"); + exit(0); + } + if (allocatepermanenttile(MAXTILES-1,64,64) != 0) //If enough memory + { + //My face with an explosion written over it + copytilepiece(KENPICTURE,0,0,64,64,MAXTILES-1,0,0); + copytilepiece(EXPLOSION,0,0,64,64,MAXTILES-1,0,0); + } + + initlava(); + + for(j=0;j<256;j++) + tempbuf[j] = ((j+32)&255); //remap colors for screwy palette sectors + makepalookup(16,tempbuf,0,0,0,1); + + for(j=0;j<256;j++) tempbuf[j] = j; + makepalookup(17,tempbuf,24,24,24,1); + + for(j=0;j<256;j++) tempbuf[j] = j; //(j&31)+32; + makepalookup(18,tempbuf,8,8,48,1); + + prepareboard(boardfilename); //Load board + + initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1); + //if (Bstrcmp(boardfilename,"klab.map") == 0) + // loadsong("klabsong.kdm"); + //else + loadsong("neatsong.ogg"); + musicon(); + + /* + if (option[4] > 0) + { + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + + drawtilebackground(0L,0L,BACKGROUND,8,x1,y1,x2,y2,0); + + sendlogon(); + + if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3; + while (numplayers < waitplayers) + { + sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers); + printext256(68L,84L,31,0,tempbuf,0); + nextpage(); + + if (getpacket(&other,packbuf) > 0) + if (packbuf[0] == 255) + keystatus[1] = 1; + + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + if (keystatus[1]) + { + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + } + screenpeek = myconnectindex; + + if (numplayers <= 3) + networkmode = 1; + else + networkmode = 0; + + j = 1; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (myconnectindex == i) break; + j++; + } + sprintf(getmessage,"Player %ld",j); + if (networkmode == 0) + { + if (j == 1) Bstrcat(getmessage," (Master)"); + else Bstrcat(getmessage," (Slave)"); + } else + Bstrcat(getmessage," (Even)"); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+120; + } + */ + screenpeek = myconnectindex; + reccnt = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + waitforeverybody(); + totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0; + + ready2send = 1; + drawscreen(screenpeek,65536L); + + while (!keystatus[1]) //Main loop starts here + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + refreshaudio(); + OSD_DispatchQueued(); + + // backslash (useful only with KDM) +// if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); } + + if ((networkmode == 1) || (myconnectindex != connecthead)) + while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); + + getpackets(); + + if (typemode == 0) //if normal game keys active + { + if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0) //Sh.Sh.R (replay) + { + keystatus[0x13] = 0; + playback(); + } + + if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game + { + keystatus[0x26] = 0; + loadgame(); + drawstatusbar(screenpeek); // Andy did this + } + + if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game + { + keystatus[0x1f] = 0; + savegame(); + } + } + + if ((networkmode == 0) || (option[4] == 0)) + { + while (movefifoplc != movefifoend[0]) domovethings(); + } + else + { + j = connecthead; + if (j == myconnectindex) j = connectpoint2[j]; + averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3); + j = max(averagelag[j]>>9,1); + while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j) + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (movefifoplc == movefifoend[i]) break; + if (i >= 0) break; + if (myconnectindex != connecthead) + { + k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255); + if (k > 128+1) ototalclock++; + if (k < 128-1) ototalclock--; + } + domovethings(); + } + } + i = (totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND)); + + drawscreen(screenpeek,i); + } + + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + + return(0); +} + +void operatesector(short dasector) +{ //Door code + long i, j, k, s, nexti, good, cnt, datag; + long dax, day, daz, dax2, day2, daz2, centx, centy; + short startwall, endwall, wallfind[2]; + + datag = sector[dasector].lotag; + + startwall = sector[dasector].wallptr; + endwall = startwall + sector[dasector].wallnum; + centx = 0L, centy = 0L; + for(i=startwall;i= 0) //If door already moving, reverse its direction + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].floorz; + + if (animategoal[i] == daz) + animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; + else + animategoal[i] = daz; + animatevel[i] = 0; + } + else //else insert the door's ceiling on the animation list + { + if (sector[dasector].ceilingz == sector[dasector].floorz) + daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; + else + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].floorz; + } + if ((j = setanimation(§or[dasector].ceilingz,daz,6L,6L)) >= 0) + wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); + } + } + //Simple door that moves down + if ((datag == 7) || (datag == 8)) //If the sector in front's elevator + { + i = getanimationgoal((long)§or[dasector].floorz); + if (i >= 0) //If elevator already moving, reverse its direction + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].ceilingz; + + if (animategoal[i] == daz) + animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; + else + animategoal[i] = daz; + animatevel[i] = 0; + } + else //else insert the elevator's ceiling on the animation list + { + if (sector[dasector].floorz == sector[dasector].ceilingz) + daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; + else + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].ceilingz; + } + if ((j = setanimation(§or[dasector].floorz,daz,6L,6L)) >= 0) + wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); + } + } + + if (datag == 9) //Smooshy-wall sideways double-door + { + //find any points with either same x or same y coordinate + // as center (centx, centy) - should be 2 points found. + wallfind[0] = -1; + wallfind[1] = -1; + for(i=startwall;i>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + dax2 = wall[wall[wall[wallfind[j]].point2].point2].x; + dax2 -= wall[wall[wallfind[j]].point2].x; + setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); + setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); + } + else if (day2 != 0) + { + day2 = wall[wall[wall[wallfind[j]].point2].point2].y; + day2 -= wall[wall[wallfind[j]].point2].y; + setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); + setanimation(&wall[i].y,wall[i].y+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); + } + } + else + { + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + setanimation(&wall[wallfind[j]].x,centx,4L,0L); + setanimation(&wall[i].x,centx+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L); + } + else if (day2 != 0) + { + setanimation(&wall[wallfind[j]].y,centy,4L,0L); + setanimation(&wall[i].y,centy+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L); + } + } + } + wsayfollow("updowndr.wav",4096L-256L,256L,¢x,¢y,0); + wsayfollow("updowndr.wav",4096L+256L,256L,¢x,¢y,0); + } + + if (datag == 13) //Swinging door + { + for(i=0;i>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy)) + { //door was closed + //find what direction door should open + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = wall[i].x-wall[wallfind[j]].x; + day2 = wall[i].y-wall[wallfind[j]].y; + if (dax2 != 0) + { + dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x; + dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x; + setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); + setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L); + } + else if (day2 != 0) + { + day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y; + day2 -= wall[wall[wall[wallfind[j]].point2].point2].y; + setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); + setanimation(&wall[i].y,wall[i].y+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L); + } + } + else + { //door was not closed + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = wall[i].x-wall[wallfind[j]].x; + day2 = wall[i].y-wall[wallfind[j]].y; + if (dax2 != 0) + { + setanimation(&wall[wallfind[j]].x,centx,4L,0L); + setanimation(&wall[i].x,centx+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L); + } + else if (day2 != 0) + { + setanimation(&wall[wallfind[j]].y,centy,4L,0L); + setanimation(&wall[i].y,centy+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L); + } + } + } + wsayfollow("updowndr.wav",4096L-64L,256L,¢x,¢y,0); + wsayfollow("updowndr.wav",4096L+64L,256L,¢x,¢y,0); + } +} + +void operatesprite(short dasprite) +{ + long datag; + + datag = sprite[dasprite].lotag; + + if (datag == 2) //A sprite that shoots a bomb + { + shootgun(dasprite, + sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z, + sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2); + } +} + +long changehealth(short snum, short deltahealth) +{ + long dax, day; + short good, k, startwall, endwall, s; + + if (health[snum] > 0) + { + health[snum] += deltahealth; + if (health[snum] > 999) health[snum] = 999; + + if (health[snum] <= 0) + { + health[snum] = -1; + wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + sprite[playersprite[snum]].picnum = SKELETON; + } + + if ((snum == screenpeek) && (screensize <= xdim)) + { + if (health[snum] > 0) + sprintf(tempbuf,"Health:%3ld",health[snum]); + else + sprintf(tempbuf,"YOU STINK!"); + + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); + } + } + return(health[snum] <= 0); //You were just injured +} + +void changenumbombs(short snum, short deltanumbombs) { // Andy did this + numbombs[snum] += deltanumbombs; + if (numbombs[snum] > 999) numbombs[snum] = 999; + if (numbombs[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + numbombs[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"B:%3d",numbombs[snum]); + printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); + } +} + +void changenummissiles(short snum, short deltanummissiles) { // Andy did this + nummissiles[snum] += deltanummissiles; + if (nummissiles[snum] > 999) nummissiles[snum] = 999; + if (nummissiles[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + nummissiles[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"M:%3d",nummissiles[snum]); + printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); + } +} + +void changenumgrabbers(short snum, short deltanumgrabbers) { // Andy did this + numgrabbers[snum] += deltanumgrabbers; + if (numgrabbers[snum] > 999) numgrabbers[snum] = 999; + if (numgrabbers[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + numgrabbers[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"G:%3d",numgrabbers[snum]); + printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); + } +} + +static long ostatusflytime = 0x80000000; +void drawstatusflytime(short snum) { // Andy did this + long nstatusflytime; + + if ((snum == screenpeek) && (screensize <= xdim)) { + nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); + if (nstatusflytime > 1000) nstatusflytime = 1000; + else if (nstatusflytime < 0) nstatusflytime = 0; + if (nstatusflytime != ostatusflytime) { + if (nstatusflytime > 999) sprintf(tempbuf,"FT:BIG"); + else sprintf(tempbuf,"FT:%3ld",nstatusflytime); + printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); + ostatusflytime = nstatusflytime; + } + } +} + +void drawstatusbar(short snum) { // Andy did this + long nstatusflytime; + + if ((snum == screenpeek) && (screensize <= xdim)) { + Bsprintf(tempbuf,"Deaths:%d",deaths[snum]); + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"Health:%3ld",health[snum]); + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); + + Bsprintf(tempbuf,"B:%3d",numbombs[snum]); + printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"M:%3d",nummissiles[snum]); + printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"G:%3d",numgrabbers[snum]); + printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); + + nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); + if (nstatusflytime < 0) { + Bsprintf(tempbuf,"FT: 0"); + ostatusflytime = 0; + } + else if (nstatusflytime > 999) { + Bsprintf(tempbuf,"FT:BIG"); + ostatusflytime = 999; + } + else { + Bsprintf(tempbuf,"FT:%3ld",nstatusflytime); + ostatusflytime = nstatusflytime; + } + printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); + } +} + +void prepareboard(char *daboardfilename) +{ + short startwall, endwall, dasector; + long i, j, k=0, s, dax, day, daz, dax2, day2; + + getmessageleng = 0; + typemessageleng = 0; + + randomseed = 17L; + + //Clear (do)animation's list + animatecnt = 0; + typemode = 0; + locselectedgun = 0; + locselectedgun2 = 0; + + if (loadboard(daboardfilename,0,&posx[0],&posy[0],&posz[0],&ang[0],&cursectnum[0]) == -1) + { + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + printf("Board not found\n"); + exit(0); + } else { + char *fp; + + strcpy(tempbuf, daboardfilename); + fp = strrchr(tempbuf,'.'); + if (fp) *fp = 0; + strcat(tempbuf,".mhk"); + + loadmaphack(tempbuf); + } + + setup3dscreen(); + + for(i=0;i dax2) dax2 = wall[j].x; + if (wall[j].y > day2) day2 = wall[j].y; + if (wall[j].lotag == 3) k = j; + } + if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16; + if (wall[k].y == day) dragydir[dragsectorcnt] = -16; + if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16; + if (wall[k].y == day2) dragydir[dragsectorcnt] = 16; + + dasector = wall[startwall].nextsector; + dragx1[dragsectorcnt] = 0x7fffffff; + dragy1[dragsectorcnt] = 0x7fffffff; + dragx2[dragsectorcnt] = 0x80000000; + dragy2[dragsectorcnt] = 0x80000000; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(j=startwall;j dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x; + if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y; + + setinterpolation(§or[dasector].floorz); + setinterpolation(&wall[j].x); + setinterpolation(&wall[j].y); + setinterpolation(&wall[wall[j].nextwall].x); + setinterpolation(&wall[wall[j].nextwall].y); + } + + dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax); + dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day); + dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x); + dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y); + + dragfloorz[dragsectorcnt] = sector[i].floorz; + + dragsectorlist[dragsectorcnt++] = i; + break; + case 13: + startwall = sector[i].wallptr; + endwall = startwall+sector[i].wallnum; + for(j=startwall;j dax2) dax2 = wall[j].x; + if (wall[j].y > day2) day2 = wall[j].y; + } + for(j=startwall;j dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2)) + { + subwayx[subwaytrackcnt] = wall[j].x; + } + else + { + subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x; + subwaystopcnt[subwaytrackcnt]++; + } + } + } + + for(j=1;j subwaytrackx1[subwaytrackcnt]) + if (wall[startwall].y > subwaytracky1[subwaytrackcnt]) + if (wall[startwall].x < subwaytrackx2[subwaytrackcnt]) + if (wall[startwall].y < subwaytracky2[subwaytrackcnt]) + { + if (sector[j].floorz != sector[i].floorz) + { + sector[j].ceilingstat |= 64; + sector[j].floorstat |= 64; + } + subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j; + subwaynumsectors[subwaytrackcnt]++; + } + } + + subwayvel[subwaytrackcnt] = 64; + subwaypausetime[subwaytrackcnt] = 720; + + startwall = sector[i].wallptr; + endwall = startwall+sector[i].wallnum; + for(k=startwall;k subwaytrackx1[subwaytrackcnt]) + if (wall[k].y > subwaytracky1[subwaytrackcnt]) + if (wall[k].x < subwaytrackx2[subwaytrackcnt]) + if (wall[k].y < subwaytracky2[subwaytrackcnt]) + setinterpolation(&wall[k].x); + + for(j=1;j=0;k=nextspritesect[k]) + if (statrate[sprite[k].statnum] < 0) + setinterpolation(&sprite[k].x); + } + + + subwaytrackcnt++; + break; + } + if (sector[i].floorpicnum == FLOORMIRROR) + floormirrorsector[mirrorcnt++] = i; + //if (sector[i].ceilingpicnum == FLOORMIRROR) floormirrorsector[mirrorcnt++] = i; //SOS + } + + //Scan wall tags + + mirrorcnt = 0; + tilesizx[MIRROR] = 0; + tilesizy[MIRROR] = 0; + for(i=0;i= 0) && (wall[i].overpicnum == MIRROR) && (wall[i].cstat&32)) + { + if ((sector[s].floorstat&1) == 0) + { + wall[i].overpicnum = MIRRORLABEL+mirrorcnt; + sector[s].ceilingpicnum = MIRRORLABEL+mirrorcnt; + sector[s].floorpicnum = MIRRORLABEL+mirrorcnt; + sector[s].floorstat |= 1; + mirrorwall[mirrorcnt] = i; + mirrorsector[mirrorcnt] = s; + mirrorcnt++; + } + else + wall[i].overpicnum = sector[s].ceilingpicnum; + } + } + + //Invalidate textures in sector behind mirror + for(i=0;i=0;i--) copybuf(&sprite[i].x,&osprite[i].x,3); + + searchmap(cursectnum[connecthead]); + + lockclock = 0; + ototalclock = 0; + gotlastpacketclock = 0; + + screensize = xdim; + dax = ((xdim-screensize)>>1); + dax2 = dax+screensize-1; + day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + day2 = day + scale(screensize,ydim-32,xdim)-1; + setview(dax,day,dax2,day2); + + startofdynamicinterpolations = numinterpolations; + + /* + for(i=connecthead;i>=0;i=connectpoint2[i]) myminlag[i] = 0; + otherminlag = mymaxlag = 0; + */ +} + +void checktouchsprite(short snum, short sectnum) +{ + long i, nexti; + + if ((sectnum < 0) || (sectnum >= numsectors)) return; + + for(i=headspritesect[sectnum];i>=0;i=nexti) + { + nexti = nextspritesect[i]; + if (sprite[i].cstat&0x8000) continue; + if ((klabs(posx[snum]-sprite[i].x)+klabs(posy[snum]-sprite[i].y) < 512) && (klabs((posz[snum]>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) + { + switch(sprite[i].picnum) + { + case COIN: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,5); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*60; + changespritestat((short)i,11); + } + break; + case DIAMONDS: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,15); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*120; + changespritestat((short)i,11); + } + break; + case COINSTACK: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,25); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*180; + changespritestat((short)i,11); + } + break; + case GIFTBOX: + wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case CANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[4] = 1; + changenumbombs(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case LAUNCHER: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[5] = 1; + changenummissiles(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case GRABCANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[6] = 1; + changenumgrabbers(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case AIRPLANE: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (flytime[snum] < lockclock) flytime[snum] = lockclock; + flytime[snum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); + drawstatusflytime(snum); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + } + } + } +} + +void checkgrabbertouchsprite(short snum, short sectnum) // Andy did this +{ + long i, nexti; + short onum; + + if ((sectnum < 0) || (sectnum >= numsectors)) return; + onum = (sprite[snum].owner & (MAXSPRITES - 1)); + + for(i=headspritesect[sectnum];i>=0;i=nexti) + { + nexti = nextspritesect[i]; + if (sprite[i].cstat&0x8000) continue; + if ((klabs(sprite[snum].x-sprite[i].x)+klabs(sprite[snum].y-sprite[i].y) < 512) && (klabs((sprite[snum].z>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) + { + switch(sprite[i].picnum) + { + case COIN: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,5); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*60; + changespritestat((short)i,11); + } + break; + case DIAMONDS: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,15); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*120; + changespritestat((short)i,11); + } + break; + case COINSTACK: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,25); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*180; + changespritestat((short)i,11); + } + break; + case GIFTBOX: + wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case CANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[4] = 1; + changenumbombs(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case LAUNCHER: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[5] = 1; + changenummissiles(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case GRABCANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[6] = 1; + changenumgrabbers(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case AIRPLANE: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (flytime[snum] < lockclock) flytime[snum] = lockclock; + flytime[onum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); + drawstatusflytime(onum); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + } + } + } +} + +void shootgun(short snum, long x, long y, long z, + short daang, long dahoriz, short dasectnum, char guntype) +{ + short hitsect, hitwall, hitsprite, daang2; + long i, j, daz2, hitx, hity, hitz; + + switch(guntype) + { + case 0: //Shoot chain gun + daang2 = ((daang + (krand()&31)-16)&2047); + daz2 = ((100-dahoriz)*2000) + ((krand()-32768)>>1); + + hitscan(x,y,z,dasectnum, //Start position + sintable[(daang2+512)&2047], //X vector of 3D ang + sintable[daang2&2047], //Y vector of 3D ang + daz2, //Z vector of 3D ang + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + if (wall[hitwall].picnum == KENPICTURE) + { + if (waloff[MAXTILES-1] != 0) wall[hitwall].picnum = MAXTILES-1; + wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&wall[hitwall].x,&wall[hitwall].y,0); + } + else if (((hitwall < 0) && (hitsprite < 0) && (hitz >= z) && ((sector[hitsect].floorpicnum == SLIME) || (sector[hitsect].floorpicnum == FLOORMIRROR))) || ((hitwall >= 0) && (wall[hitwall].picnum == SLIME))) + { //If you shoot slime, make a splash + wsayfollow("splash.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); + spawnsprite(j,hitx,hity,hitz,2,0,0,32,64,64,0,0,SPLASH,daang, + 0,0,0,snum+4096,hitsect,4,63,0,0); //63=time left for splash + } + else + { + wsayfollow("shoot.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + + if ((hitsprite >= 0) && (sprite[hitsprite].statnum < MAXSTATUS)) + switch(sprite[hitsprite].picnum) + { + case BROWNMONSTER: + if (sprite[hitsprite].lotag > 0) sprite[hitsprite].lotag -= 10; + if (sprite[hitsprite].lotag > 0) + { + wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); + if (sprite[hitsprite].lotag <= 25) + sprite[hitsprite].cstat |= 2; + } + else + { + wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + sprite[hitsprite].z += ((tilesizy[sprite[hitsprite].picnum]*sprite[hitsprite].yrepeat)<<1); + sprite[hitsprite].picnum = GIFTBOX; + sprite[hitsprite].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(hitsprite,12); + + spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64, + 0,0,EXPLOSION,daang,0,0,0,snum+4096, + hitsect,5,31,0,0); + } + break; + case EVILAL: + wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + sprite[hitsprite].picnum = EVILALGRAVE; + sprite[hitsprite].cstat = 0; + sprite[hitsprite].xvel = (krand()&255)-128; + sprite[hitsprite].yvel = (krand()&255)-128; + sprite[hitsprite].zvel = (krand()&4095)-3072; + changespritestat(hitsprite,9); + + spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64,0, + 0,EXPLOSION,daang,0,0,0,snum+4096,hitsect,5,31,0,0); + //31=time left for explosion + + break; + case PLAYER: + for(j=connecthead;j>=0;j=connectpoint2[j]) + if (playersprite[j] == hitsprite) + { + wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + changehealth(j,-10); + break; + } + break; + } + + spawnsprite(j,hitx,hity,hitz+(8<<8),2,-4,0,32,16,16,0,0, + EXPLOSION,daang,0,0,0,snum+4096,hitsect,3,63,0,0); + + //Sprite starts out with center exactly on wall. + //This moves it back enough to see it at all angles. + movesprite((short)j,-(((long)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),-(((long)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,CLIPMASK1); + } + break; + case 1: //Shoot silver sphere bullet + spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,BULLET,daang, + sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, + (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot2.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); + break; + case 2: //Shoot bomb + spawnsprite(j,x,y,z,128,0,0,12,16,16,0,0,BOMB,daang, + sintable[(daang+512)&2047]*5>>8,sintable[daang&2047]*5>>8, + (80-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); + break; + case 3: //Shoot missile (Andy did this) + spawnsprite(j,x,y,z,1+128,0,0,16,32,32,0,0,MISSILE,daang, + sintable[(daang+512)&2047]>>4,sintable[daang&2047]>>4, + (100-dahoriz)<<7,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); + break; + case 4: //Shoot grabber (Andy did this) + spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,GRABBER,daang, + sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, + (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot4.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); + break; + } +} + +#define MAXVOXMIPS 5 +extern char *voxoff[][MAXVOXMIPS]; +void analyzesprites(long dax, long day) +{ + long i, j=0, k, *intptr; + point3d *ospr; + spritetype *tspr; + + //This function is called between drawrooms() and drawmasks() + //It has a list of possible sprites that may be drawn on this frame + + for(i=0,tspr=&tsprite[0];ipicnum] >= 0) + switch(tspr->picnum) + { + case PLAYER: + // //Get which of the 8 angles of the sprite to draw (0-7) + // //k ranges from 0-7 + //k = getangle(tspr->x-dax,tspr->y-day); + //k = (((tspr->ang+3072+128-k)&2047)>>8)&7; + // //This guy has only 5 pictures for 8 angles (3 are x-flipped) + //if (k <= 4) + //{ + // tspr->picnum += (k<<2); + // tspr->cstat &= ~4; //clear x-flipping bit + //} + //else + //{ + // tspr->picnum += ((8-k)<<2); + // tspr->cstat |= 4; //set x-flipping bit + //} + + if ((tspr->cstat&2) == 0) + { + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + intptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; + tspr->xrepeat = scale(tspr->xrepeat,56,intptr[2]); + tspr->yrepeat = scale(tspr->yrepeat,56,intptr[2]); + tspr->shade -= 6; + } + break; + case BROWNMONSTER: + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + break; + } +#endif + + k = statrate[tspr->statnum]; + if (k >= 0) //Interpolate moving sprite + { + ospr = &osprite[tspr->owner]; + switch(k) + { + case 0: j = smoothratio; break; + case 1: j = (smoothratio>>1)+(((nummoves-tspr->owner)&1)<<15); break; + case 3: j = (smoothratio>>2)+(((nummoves-tspr->owner)&3)<<14); break; + case 7: j = (smoothratio>>3)+(((nummoves-tspr->owner)&7)<<13); break; + case 15: j = (smoothratio>>4)+(((nummoves-tspr->owner)&15)<<12); break; + } + k = tspr->x-ospr->x; tspr->x = ospr->x; + if (k != 0) tspr->x += mulscale16(k,j); + k = tspr->y-ospr->y; tspr->y = ospr->y; + if (k != 0) tspr->y += mulscale16(k,j); + k = tspr->z-ospr->z; tspr->z = ospr->z; + if (k != 0) tspr->z += mulscale16(k,j); + } + + //Don't allow close explosion sprites to be transluscent + k = tspr->statnum; + if ((k == 3) || (k == 4) || (k == 5) || (k == 7)) + if (klabs(dax-tspr->x) < 256) + if (klabs(day-tspr->y) < 256) + tspr->cstat &= ~2; + + tspr->shade += 6; + if (sector[tspr->sectnum].ceilingstat&1) + tspr->shade += sector[tspr->sectnum].ceilingshade; + else + tspr->shade += sector[tspr->sectnum].floorshade; + } +} + +void tagcode(void) +{ + long i, nexti, j, k, l, s, dax, day, daz, dax2, day2, cnt, good; + short startwall, endwall, dasector, p, oldang; + + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + if (sector[cursectnum[p]].lotag == 1) + { + activatehitag(sector[cursectnum[p]].hitag); + sector[cursectnum[p]].lotag = 0; + sector[cursectnum[p]].hitag = 0; + } + if ((sector[cursectnum[p]].lotag == 2) && (cursectnum[p] != ocursectnum[p])) + activatehitag(sector[cursectnum[p]].hitag); + } + + for(i=0;i>2); + if (j >= 16) j = 31-j; + { + sector[dasector].ceilingshade = j; + sector[dasector].floorshade = j; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(s=startwall;s=0;p=connectpoint2[p]) + if (sector[cursectnum[p]].lotag == 10) //warp sector + { + if (cursectnum[p] != ocursectnum[p]) + { + warpsprite(playersprite[p]); + posx[p] = sprite[playersprite[p]].x; + posy[p] = sprite[playersprite[p]].y; + posz[p] = sprite[playersprite[p]].z; + ang[p] = sprite[playersprite[p]].ang; + cursectnum[p] = sprite[playersprite[p]].sectnum; + + sprite[playersprite[p]].z += EYEHEIGHT; + + //warp(&posx[p],&posy[p],&posz[p],&ang[p],&cursectnum[p]); + //Update sprite representation of player + //setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + //sprite[playersprite[p]].ang = ang[p]; + } + } + + for(i=0;i>2)&255); + } + + for(i=0;i>2)&255); + sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255); + } + + for(i=0;i dragx2[i]) dragxdir[i] = -16; + if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16; + + for(j=startwall;j>3); + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (cursectnum[p] == dasector) + { + posx[p] += dragxdir[i]; + posy[p] += dragydir[i]; + if (p == myconnectindex) + { myx += dragxdir[i]; myy += dragydir[i]; } + //posz[p] += (sector[dasector].floorz-j); + + //Update sprite representation of player + setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + sprite[playersprite[p]].ang = ang[p]; + } + } + + for(i=0;i=0;p=connectpoint2[p]) + if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1)) + { + cnt = 256; + do + { + good = 1; + + //swingangopendir is -1 if forwards, 1 is backwards + l = (swingangopendir[i] > 0); + for(k=l+3;k>=l;k--) + if (clipinsidebox(posx[p],posy[p],swingwall[i][k],128L) != 0) + { + good = 0; + break; + } + if (good == 0) + { + if (cnt == 256) + { + swinganginc[i] = -swinganginc[i]; + swingang[i] = oldang; + } + else + { + swingang[i] = ((swingang[i]-swinganginc[i])&2047); + } + for(k=1;k<=3;k++) + rotatepoint(swingx[i][0],swingy[i][0],swingx[i][k],swingy[i][k],swingang[i],&wall[swingwall[i][k]].x,&wall[swingwall[i][k]].y); + if (swingang[i] == swingangclosed[i]) + { + wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0); + swinganginc[i] = 0; + break; + } + if (swingang[i] == swingangopen[i]) + { + swinganginc[i] = 0; + break; + } + cnt--; + } + } while ((good == 0) && (cnt > 0)); + } + } + } + if (swinganginc[i] == 0) + for(j=1;j<=3;j++) + { + stopinterpolation(&wall[swingwall[i][j]].x); + stopinterpolation(&wall[swingwall[i][j]].y); + } + } + + for(i=0;i 2)) + { + dasector = subwaytracksector[i][0]; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(k=startwall;k subwaytrackx1[i]) + if (wall[k].y > subwaytracky1[i]) + if (wall[k].x < subwaytrackx2[i]) + if (wall[k].y < subwaytracky2[i]) + wall[k].x += subwayvel[i]; + + for(j=1;j=0;s=nextspritesect[s]) + sprite[s].x += subwayvel[i]; + } + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (cursectnum[p] != subwaytracksector[i][0]) + if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz) + if (posx[p] > subwaytrackx1[i]) + if (posy[p] > subwaytracky1[i]) + if (posx[p] < subwaytrackx2[i]) + if (posy[p] < subwaytracky2[i]) + { + posx[p] += subwayvel[i]; + if (p == myconnectindex) + { myx += subwayvel[i]; } + + //Update sprite representation of player + setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + sprite[playersprite[p]].ang = ang[p]; + } + + subwayx[i] += subwayvel[i]; + } + + j = subwayvel[i]; + k = subwaystop[i][subwaygoalstop[i]] - subwayx[i]; + if (k > 0) + { + if (k > 4096) + { + if (subwayvel[i] < 256) subwayvel[i]++; + } + else + subwayvel[i] = (k>>4)+1; + } + else if (k < 0) + { + if (k < -4096) + { + if (subwayvel[i] > -256) subwayvel[i]--; + } + else + subwayvel[i] = (k>>4)-1; + } + if ((j < 0) && (subwayvel[i] >= 0)) subwayvel[i] = -1; + if ((j > 0) && (subwayvel[i] <= 0)) subwayvel[i] = 1; + + if ((subwayvel[i] <= 2) && (subwayvel[i] >= -2) && (klabs(k) < 2048)) + { + //Open / close doors + if ((subwaypausetime[i] == 720) || ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))) + activatehitag(sector[subwaytracksector[i][0]].hitag); + + subwaypausetime[i] -= TICSPERFRAME; + if (subwaypausetime[i] < 0) + { + subwaypausetime[i] = 720; + if (subwayvel[i] < 0) + { + subwaygoalstop[i]--; + if (subwaygoalstop[i] < 0) + { + subwaygoalstop[i] = 1; + subwayvel[i] = 1; + } + } + else if (subwayvel[i] > 0) + { + subwaygoalstop[i]++; + if (subwaygoalstop[i] >= subwaystopcnt[i]) + { + subwaygoalstop[i] = subwaystopcnt[i]-2; + subwayvel[i] = -1; + } + } + } + } + } +} + +void statuslistcode(void) +{ + short p, target, hitobject, daang, osectnum, movestat; + long i, nexti, j, nextj, k, l, dax, day, daz, dist, ox, oy, mindist; + long doubvel, xvect, yvect; + + //Go through active BROWNMONSTER list + for(i=headspritestat[1];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + k = krand(); + + //Choose a target player + mindist = 0x7fffffff; target = connecthead; + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); + if (dist < mindist) mindist = dist, target = p; + } + + //brown monster decides to shoot bullet + if ((k&63) == 23) + { + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 0) + { + if ((k&0xf00) == 0xb00) changespritestat(i,2); + } + else + { + wsayfollow("monshoot.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + + doubvel = (TICSPERFRAME<<((ssync[target].bits&256)>0)); + xvect = 0, yvect = 0; + if (ssync[target].fvel != 0) + { + xvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[(ang[target]+512)&2047])>>3); + yvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[ang[target]&2047])>>3); + } + if (ssync[target].svel != 0) + { + xvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[ang[target]&2047])>>3); + yvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[(ang[target]+1536)&2047])>>3); + } + + ox = posx[target]; oy = posy[target]; + + //distance is j + j = ksqrt((ox-sprite[i].x)*(ox-sprite[i].x)+(oy-sprite[i].y)*(oy-sprite[i].y)); + + switch((sprite[i].extra>>11)&3) + { + case 1: j = -(j>>1); break; + case 3: j = 0; break; + case 0: case 2: break; + } + sprite[i].extra += 2048; + + //rate is (TICSPERFRAME<<19) + xvect = scale(xvect,j,TICSPERFRAME<<19); + yvect = scale(yvect,j,TICSPERFRAME<<19); + clipmove(&ox,&oy,&posz[target],&cursectnum[target],xvect<<14,yvect<<14,128L,4<<8,4<<8,CLIPMASK0); + ox -= sprite[i].x; + oy -= sprite[i].y; + + daang = ((getangle(ox,oy)+(krand()&7)-4)&2047); + + dax = (sintable[(daang+512)&2047]>>6); + day = (sintable[daang&2047]>>6); + daz = 0; + if (ox != 0) + daz = scale(dax,posz[target]+(8<<8)-sprite[i].z,ox); + else if (oy != 0) + daz = scale(day,posz[target]+(8<<8)-sprite[i].z,oy); + + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,128,0,0, + 16,sprite[i].xrepeat,sprite[i].yrepeat,0,0,BULLET,daang,dax,day,daz,i,sprite[i].sectnum,6,0,0,0); + + sprite[i].extra &= (~2047); + } + } + + //Move brown monster + dax = sprite[i].x; //Back up old x&y if stepping off cliff + day = sprite[i].y; + + doubvel = max(mulscale7(sprite[i].xrepeat,sprite[i].yrepeat),4); + + osectnum = sprite[i].sectnum; + movestat = movesprite((short)i,(long)sintable[(sprite[i].ang+512)&2047]*doubvel,(long)sintable[sprite[i].ang]*doubvel,0L,4L<<8,4L<<8,CLIPMASK0); + if (globloz > sprite[i].z+(48<<8)) + { sprite[i].x = dax; sprite[i].y = day; movestat = 1; } + else + sprite[i].z = globloz-((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); + + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { warpsprite((short)i); movestat = 0; } + + if ((movestat != 0) || ((k&63) == 1)) + { + if (sprite[i].ang == (sprite[i].extra&2047)) + { + daang = (getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y)&2047); + daang = ((daang+(krand()&1023)-512)&2047); + sprite[i].extra = ((sprite[i].extra&(~2047))|daang); + } + if ((sprite[i].extra-sprite[i].ang)&1024) + { + sprite[i].ang = ((sprite[i].ang-32)&2047); + if (!((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); + } + else + { + sprite[i].ang = ((sprite[i].ang+32)&2047); + if (((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); + } + } + } + + for(i=headspritestat[10];i>=0;i=nexti) //EVILAL list + { + nexti = nextspritestat[i]; + + if (sprite[i].yrepeat < 38) continue; + if (sprite[i].yrepeat < 64) + { + sprite[i].xrepeat++; + sprite[i].yrepeat++; + continue; + } + + if ((nummoves-i)&statrate[10]) continue; + + //Choose a target player + mindist = 0x7fffffff; target = connecthead; + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); + if (dist < mindist) mindist = dist, target = p; + } + + k = (krand()&255); + + if ((sprite[i].lotag&32) && (k < 48)) //Al decides to reproduce + { + l = 0; + if ((sprite[i].lotag&64) && (k < 2)) //Give him a chance to reproduce without seeing you + l = 1; + else if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) + l = 1; + if (l != 0) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].cstat,sprite[i].shade,sprite[i].pal, + sprite[i].clipdist,38,38,sprite[i].xoffset,sprite[i].yoffset,sprite[i].picnum,krand()&2047,0,0,0,i, + sprite[i].sectnum,10,sprite[i].lotag,sprite[i].hitag,sprite[i].extra); + switch(krand()&31) //Mutations! + { + case 0: sprite[i].cstat ^= 2; break; + case 1: sprite[i].cstat ^= 512; break; + case 2: sprite[i].shade++; break; + case 3: sprite[i].shade--; break; + case 4: sprite[i].pal ^= 16; break; + case 5: case 6: case 7: sprite[i].lotag ^= (1<<(krand()&7)); break; + case 8: sprite[i].lotag = (krand()&255); break; + } + } + } + if (k >= 208+((sprite[i].lotag&128)>>2)) //Al decides to shoot bullet + { + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) + { + wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + + spawnsprite(j,sprite[i].x,sprite[i].y, + sector[sprite[i].sectnum].floorz-(24<<8), + 0,0,0,16,32,32,0,0,BULLET, + (getangle(posx[target]-sprite[j].x, + posy[target]-sprite[j].y)+(krand()&15)-8)&2047, + sintable[(sprite[j].ang+512)&2047]>>6, + sintable[sprite[j].ang&2047]>>6, + ((posz[target]+(8<<8)-sprite[j].z)<<8) / + (ksqrt((posx[target]-sprite[j].x) * + (posx[target]-sprite[j].x) + + (posy[target]-sprite[j].y) * + (posy[target]-sprite[j].y))+1), + i,sprite[i].sectnum,6,0,0,0); + } + } + + //Move Al + l = (((sprite[i].lotag&3)+2)<<8); + if (sprite[i].lotag&4) l = -l; + dax = sintable[(sprite[i].ang+512)&2047]*l; + day = sintable[sprite[i].ang]*l; + + osectnum = sprite[i].sectnum; + movestat = movesprite((short)i,dax,day,0L,-8L<<8,-8L<<8,CLIPMASK0); + sprite[i].z = globloz; + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { + warpsprite((short)i); + movestat = 0; + } + + if (sprite[i].lotag&16) + { + if (((k&124) >= 120) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) + sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); + else + sprite[i].ang = (krand()&2047); + } + + if (movestat != 0) + { + if ((k&2) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) + sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); + else + sprite[i].ang = (krand()&2047); + + if ((movestat&49152) == 49152) + if (sprite[movestat&16383].picnum == EVILAL) + if ((k&31) >= 30) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + + if (sprite[i].lotag&8) + if ((k&31) >= 30) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + + if (movestat == -1) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + } + } + + //Go through travelling bullet sprites + for(i=headspritestat[6];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + if ((nummoves-i)&statrate[6]) continue; + + //If the sprite is a bullet then... + if ((sprite[i].picnum == BULLET) || (sprite[i].picnum == GRABBER) || (sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) + { + dax = ((((long)sprite[i].xvel)*TICSPERFRAME)<<12); + day = ((((long)sprite[i].yvel)*TICSPERFRAME)<<12); + daz = ((((long)sprite[i].zvel)*TICSPERFRAME)>>2); + if (sprite[i].picnum == BOMB) daz = 0; + + osectnum = sprite[i].sectnum; + hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,CLIPMASK1); + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { + warpsprite((short)i); + hitobject = 0; + } + + if (sprite[i].picnum == GRABBER) { // Andy did this (& Ken) !Homing! + checkgrabbertouchsprite(i,sprite[i].sectnum); + l = 0x7fffffff; + for (j = connecthead; j >= 0; j = connectpoint2[j]) // Players + if (j != (sprite[i].owner & (MAXSPRITES - 1))) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j])) { + k = ksqrt(sqr(posx[j] - sprite[i].x) + sqr(posy[j] - sprite[i].y) + (sqr(posz[j] - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (posx[j] - sprite[i].x); + day = (posy[j] - sprite[i].y); + daz = (posz[j] - sprite[i].z); + } + } + for(j = headspritestat[1]; j >= 0; j = nextj) { // Active monsters + nextj = nextspritestat[j]; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { + k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (sprite[j].x - sprite[i].x); + day = (sprite[j].y - sprite[i].y); + daz = (sprite[j].z - sprite[i].z); + } + } + } + for(j = headspritestat[2]; j >= 0; j = nextj) { // Inactive monsters + nextj = nextspritestat[j]; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { + k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (sprite[j].x - sprite[i].x); + day = (sprite[j].y - sprite[i].y); + daz = (sprite[j].z - sprite[i].z); + } + } + } + if (l != 0x7fffffff) { + sprite[i].xvel = (divscale7(dax,l) + sprite[i].xvel); // 1/5 of velocity is homing, 4/5 is momentum + sprite[i].yvel = (divscale7(day,l) + sprite[i].yvel); // 1/5 of velocity is homing, 4/5 is momentum + sprite[i].zvel = (divscale7(daz,l) + sprite[i].zvel); // 1/5 of velocity is homing, 4/5 is momentum + l = ksqrt((sprite[i].xvel * sprite[i].xvel) + (sprite[i].yvel * sprite[i].yvel) + ((sprite[i].zvel * sprite[i].zvel) >> 8)); + sprite[i].xvel = divscale9(sprite[i].xvel,l); + sprite[i].yvel = divscale9(sprite[i].yvel,l); + sprite[i].zvel = divscale9(sprite[i].zvel,l); + sprite[i].ang = getangle(sprite[i].xvel,sprite[i].yvel); + } + } + + if (sprite[i].picnum == BOMB) + { + j = sprite[i].sectnum; + if ((sector[j].floorstat&2) && (sprite[i].z > globloz-(8<<8))) + { + k = sector[j].wallptr; + daang = getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y); + sprite[i].xvel += mulscale22(sintable[(daang+1024)&2047],sector[j].floorheinum); + sprite[i].yvel += mulscale22(sintable[(daang+512)&2047],sector[j].floorheinum); + } + } + + if (sprite[i].picnum == BOMB) + { + sprite[i].z += sprite[i].zvel; + sprite[i].zvel += (TICSPERFRAME<<7); + if (sprite[i].z < globhiz+(tilesizy[BOMB]<<6)) + { + sprite[i].z = globhiz+(tilesizy[BOMB]<<6); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > globloz-(tilesizy[BOMB]<<6)) + { + sprite[i].z = globloz-(tilesizy[BOMB]<<6); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + dax = sprite[i].xvel; day = sprite[i].yvel; + dist = dax*dax+day*day; + if (dist < 512) + { + bombexplode(i); + goto bulletisdeletedskip; + } + if (dist < 4096) + { + sprite[i].xrepeat = ((4096+2048)*16) / (dist+2048); + sprite[i].yrepeat = sprite[i].xrepeat; + sprite[i].xoffset = (krand()&15)-8; + sprite[i].yoffset = (krand()&15)-8; + } + if (mulscale30(krand(),dist) == 0) + { + sprite[i].xvel -= ksgn(sprite[i].xvel); + sprite[i].yvel -= ksgn(sprite[i].yvel); + sprite[i].zvel -= ksgn(sprite[i].zvel); + } + } + + //Check for bouncy objects before killing bullet + if ((hitobject&0xc000) == 16384) //Bullet hit a ceiling/floor + { + k = sector[hitobject&(MAXSECTORS-1)].wallptr; l = wall[k].point2; + daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y); + + getzsofslope(hitobject&(MAXSECTORS-1),sprite[i].x,sprite[i].y,&k,&l); + if (sprite[i].z < ((k+l)>>1)) k = sector[hitobject&(MAXSECTORS-1)].ceilingheinum; + else k = sector[hitobject&(MAXSECTORS-1)].floorheinum; + + dax = mulscale14(k,sintable[(daang)&2047]); + day = mulscale14(k,sintable[(daang+1536)&2047]); + daz = 4096; + + k = sprite[i].xvel*dax+sprite[i].yvel*day+mulscale4(sprite[i].zvel,daz); + l = dax*dax+day*day+daz*daz; + if ((klabs(k)>>14) < l) + { + k = divscale17(k,l); + sprite[i].xvel -= mulscale16(dax,k); + sprite[i].yvel -= mulscale16(day,k); + sprite[i].zvel -= mulscale12(daz,k); + } + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,255,&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + sprite[i].owner = -1; //Bullet turns evil! + } + else if ((hitobject&0xc000) == 32768) //Bullet hit a wall + { + if (wall[hitobject&4095].lotag == 8) + { + dax = sprite[i].xvel; day = sprite[i].yvel; + if ((sprite[i].picnum != BOMB) || (dax*dax+day*day >= 512)) + { + k = (hitobject&4095); l = wall[k].point2; + j = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y)+512; + + //k = cos(ang) * sin(ang) * 2 + k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); + //l = cos(ang * 2) + l = sintable[((j<<1)+512)&2047]; + + ox = sprite[i].xvel; oy = sprite[i].yvel; + dax = -ox; day = -oy; + sprite[i].xvel = dmulscale14(day,k,dax,l); + sprite[i].yvel = dmulscale14(dax,k,-day,l); + + if (sprite[i].picnum == BOMB) + { + sprite[i].xvel -= (sprite[i].xvel>>3); + sprite[i].yvel -= (sprite[i].yvel>>3); + sprite[i].zvel -= (sprite[i].zvel>>3); + } + ox -= sprite[i].xvel; oy -= sprite[i].yvel; + dist = ((ox*ox+oy*oy)>>8); + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + sprite[i].owner = -1; //Bullet turns evil! + } + } + } + else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite + { + if (sprite[hitobject&4095].picnum == BOUNCYMAT) + { + if ((sprite[hitobject&4095].cstat&48) == 0) + { + sprite[i].xvel = -sprite[i].xvel; + sprite[i].yvel = -sprite[i].yvel; + sprite[i].zvel = -sprite[i].zvel; + dist = 255; + } + else if ((sprite[hitobject&4095].cstat&48) == 16) + { + j = sprite[hitobject&4095].ang; + + //k = cos(ang) * sin(ang) * 2 + k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); + //l = cos(ang * 2) + l = sintable[((j<<1)+512)&2047]; + + ox = sprite[i].xvel; oy = sprite[i].yvel; + dax = -ox; day = -oy; + sprite[i].xvel = dmulscale14(day,k,dax,l); + sprite[i].yvel = dmulscale14(dax,k,-day,l); + + ox -= sprite[i].xvel; oy -= sprite[i].yvel; + dist = ((ox*ox+oy*oy)>>8); + } + sprite[i].owner = -1; //Bullet turns evil! + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + } + } + + if (hitobject != 0) + { + if ((sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) + { + if ((hitobject&0xc000) == 49152) + if (sprite[hitobject&4095].lotag == 5) //Basketball hoop + { + wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + + bombexplode(i); + goto bulletisdeletedskip; + } + + if ((hitobject&0xc000) == 16384) //Hits a ceiling / floor + { + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + else if ((hitobject&0xc000) == 32768) //Bullet hit a wall + { + if (wall[hitobject&4095].picnum == KENPICTURE) + { + if (waloff[MAXTILES-1] != 0) + wall[hitobject&4095].picnum = MAXTILES-1; + wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); //Ken says, "Hello... how are you today!" + } + else + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + + deletesprite((short)i); + goto bulletisdeletedskip; + } + else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite + { + if ((sprite[hitobject&4095].lotag == 5) && (sprite[i].picnum == GRABBER)) { // Basketball hoop (Andy's addition) + wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + switch (krand() & 63) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: + sprite[i].picnum = COIN; break; + case 10: case 11: case 12: case 13: case 14: case 15: case 16: + sprite[i].picnum = DIAMONDS; break; + case 17: case 18: case 19: + sprite[i].picnum = COINSTACK; break; + case 20: case 21: case 22: case 23: + sprite[i].picnum = GIFTBOX; break; + case 24: case 25: + sprite[i].picnum = GRABCANNON; break; + case 26: case 27: + sprite[i].picnum = LAUNCHER; break; + case 28: case 29: case 30: + sprite[i].picnum = CANNON; break; + case 31: + sprite[i].picnum = AIRPLANE; break; + default: + deletesprite((short)i); + goto bulletisdeletedskip; + } + sprite[i].xvel = sprite[i].yvel = sprite[i].zvel = 0; + sprite[i].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(i,12); + goto bulletisdeletedskip; + } + + //Check if bullet hit a player & find which player it was... + if (sprite[hitobject&4095].picnum == PLAYER) + for(j=connecthead;j>=0;j=connectpoint2[j]) + if (sprite[i].owner != j+4096) + if (playersprite[j] == (hitobject&4095)) + { + wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (sprite[i].picnum == GRABBER) { // Andy did this + k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; + changehealth((sprite[i].owner - 4096),k); + changehealth(j,-k); + } + else changehealth(j,-mulscale8(sprite[i].xrepeat,sprite[i].yrepeat)); + deletesprite((short)i); + goto bulletisdeletedskip; + } + + //Check if bullet hit any monsters... + j = (hitobject&4095); //j is the spritenum that the bullet (spritenum i) hit + if (sprite[i].owner != j) + { + switch(sprite[j].picnum) + { + case BROWNMONSTER: + if (sprite[j].lotag > 0) { + if (sprite[i].picnum == GRABBER) { // Andy did this + k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; + changehealth((sprite[i].owner - 4096),k); + sprite[j].lotag -= k; + } + sprite[j].lotag -= mulscale8(sprite[i].xrepeat,sprite[i].yrepeat); + } + if (sprite[j].lotag > 0) + { + if (sprite[j].lotag <= 25) sprite[j].cstat |= 2; + wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&sprite[i].x,&sprite[i].y,1); + } + else + { + wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); + sprite[j].picnum = GIFTBOX; + sprite[j].cstat &= ~0x83; //Should not clip, foot-z + + spawnsprite(k,sprite[j].x,sprite[j].y,sprite[j].z, + 0,-4,0,32,64,64,0,0,EXPLOSION,sprite[j].ang, + 0,0,0,j,sprite[j].sectnum,5,31,0,0); + //31=Time left for explosion to stay + + changespritestat(j,12); + } + deletesprite((short)i); + goto bulletisdeletedskip; + case EVILAL: + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].picnum = EVILALGRAVE; + sprite[j].cstat = 0; + sprite[j].xvel = (krand()&255)-128; + sprite[j].yvel = (krand()&255)-128; + sprite[j].zvel = (krand()&4095)-3072; + changespritestat(j,9); + + deletesprite((short)i); + goto bulletisdeletedskip; + case AL: + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].xrepeat += 2; + sprite[j].yrepeat += 2; + if (sprite[j].yrepeat >= 38) + { + sprite[j].picnum = EVILAL; + //sprite[j].cstat |= 2; //Make him transluscent + changespritestat(j,10); + } + deletesprite((short)i); + goto bulletisdeletedskip; + default: + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + } + } + } + } +bulletisdeletedskip: continue; + } + + //Go through monster waiting for you list + for(i=headspritestat[2];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + if ((nummoves-i)&15) continue; + + //Use dot product to see if monster's angle is towards a player + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (sintable[(sprite[i].ang+512)&2047]*(posx[p]-sprite[i].x) + sintable[sprite[i].ang&2047]*(posy[p]-sprite[i].y) >= 0) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[p],posy[p],posz[p],cursectnum[p]) == 1) + { + changespritestat(i,1); + //if (sprite[i].lotag == 100) + //{ + wsayfollow("iseeyou.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + // sprite[i].lotag = 99; + //} + } + } + + //Go through smoke sprites + for(i=headspritestat[3];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].z -= (TICSPERFRAME<<6); + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through splash sprites + for(i=headspritestat[4];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + sprite[i].picnum = SPLASH + ((63-sprite[i].lotag)>>4); + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through explosion sprites + for(i=headspritestat[5];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through bomb spriral-explosion sprites + for(i=headspritestat[7];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].xrepeat = (sprite[i].lotag>>2); + sprite[i].yrepeat = (sprite[i].lotag>>2); + sprite[i].lotag -= (TICSPERFRAME<<2); + if (sprite[i].lotag < 0) { deletesprite(i); continue; } + + if ((nummoves-i)&statrate[7]) continue; + + sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>2); + sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>2); + sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>2); + + sprite[i].zvel += (TICSPERFRAME<<9); + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8)) + { + sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8)) + { + sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + } + + //EVILALGRAVE shrinking list + for(i=headspritestat[9];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].xrepeat = (sprite[i].lotag>>2); + sprite[i].yrepeat = (sprite[i].lotag>>2); + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { deletesprite(i); continue; } + + if ((nummoves-i)&statrate[9]) continue; + + sprite[i].x += (sprite[i].xvel*TICSPERFRAME); + sprite[i].y += (sprite[i].yvel*TICSPERFRAME); + sprite[i].z += (sprite[i].zvel*TICSPERFRAME); + + sprite[i].zvel += (TICSPERFRAME<<8); + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz) + { + sprite[i].z = sector[sprite[i].sectnum].ceilingz; + sprite[i].xvel -= (sprite[i].xvel>>2); + sprite[i].yvel -= (sprite[i].yvel>>2); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz) + { + sprite[i].z = sector[sprite[i].sectnum].floorz; + sprite[i].xvel -= (sprite[i].xvel>>2); + sprite[i].yvel -= (sprite[i].yvel>>2); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + } + + //Re-spawning sprite list + for(i=headspritestat[11];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].extra -= TICSPERFRAME; + if (sprite[i].extra < 0) + { + wsayfollow("warp.wav",6144L+(krand()&127)-64,128L,&sprite[i].x,&sprite[i].y,0); + sprite[i].cstat &= ~0x8000; + sprite[i].extra = -1; + changespritestat((short)i,0); + } + } +} + +void activatehitag(short dahitag) +{ + long i, nexti; + + for(i=0;i=0;i=nexti) + { + nexti = nextspritestat[i]; + if (sprite[i].hitag == dahitag) operatesprite(i); + } +} + +void bombexplode(long i) +{ + long j, nextj, k, daang, dax, day, dist; + + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0, + 32,64,64,0,0,EXPLOSION,sprite[i].ang, + 0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,0); + //31=Time left for explosion to stay + + for(k=0;k<12;k++) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, + 32,24,24,0,0,EXPLOSION,sprite[i].ang, + (krand()>>7)-256,(krand()>>7)-256,(krand()>>2)-8192, + sprite[i].owner,sprite[i].sectnum,7,96,0,0); + //96=Time left for smoke to be alive + } + + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + dist = (posx[j]-sprite[i].x)*(posx[j]-sprite[i].x); + dist += (posy[j]-sprite[i].y)*(posy[j]-sprite[i].y); + dist += ((posz[j]-sprite[i].z)>>4)*((posz[j]-sprite[i].z)>>4); + if (dist < 4194304) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j]) == 1) + { + k = ((32768/((dist>>16)+4))>>5); + if (j == myconnectindex) + { + daang = getangle(posx[j]-sprite[i].x,posy[j]-sprite[i].y); + dax = ((k*sintable[(daang+512)&2047])>>14); + day = ((k*sintable[daang&2047])>>14); + fvel += ((dax*sintable[(ang[j]+512)&2047]+day*sintable[ang[j]&2047])>>14); + svel += ((day*sintable[(ang[j]+512)&2047]-dax*sintable[ang[j]&2047])>>14); + } + changehealth(j,-k); //if changehealth returns 1, you're dead + } + } + + for(k=1;k<=2;k++) //Check for hurting monsters + { + for(j=headspritestat[k];j>=0;j=nextj) + { + nextj = nextspritestat[j]; + + dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); + dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); + dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); + if (dist >= 4194304) continue; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) + continue; + if (sprite[j].picnum == BROWNMONSTER) + { + sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); + sprite[j].picnum = GIFTBOX; + sprite[j].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(j,12); + } + } + } + + for(j=headspritestat[10];j>=0;j=nextj) //Check for EVILAL's + { + nextj = nextspritestat[j]; + + dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); + dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); + dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); + if (dist >= 4194304) continue; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) + continue; + + sprite[j].picnum = EVILALGRAVE; + sprite[j].cstat = 0; + sprite[j].xvel = (krand()&255)-128; + sprite[j].yvel = (krand()&255)-128; + sprite[j].zvel = (krand()&4095)-3072; + changespritestat(j,9); + } + + wsayfollow("blowup.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); +} + +void processinput(short snum) +{ + long oldposx, oldposy, nexti; + long i, j, k, doubvel, xvect, yvect, goalz; + long dax, day, dax2, day2, odax, oday, odax2, oday2; + short startwall, endwall; + char *ptr; + + //SHARED KEYS: + //Movement code + if ((ssync[snum].fvel|ssync[snum].svel) != 0) + { + doubvel = (TICSPERFRAME<<((ssync[snum].bits&256)>0)); + + xvect = 0, yvect = 0; + if (ssync[snum].fvel != 0) + { + xvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[(ang[snum]+512)&2047])>>3); + yvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[ang[snum]&2047])>>3); + } + if (ssync[snum].svel != 0) + { + xvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[ang[snum]&2047])>>3); + yvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[(ang[snum]+1536)&2047])>>3); + } + if (flytime[snum] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed + clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); + revolvedoorstat[snum] = 1; + } + else + { + revolvedoorstat[snum] = 0; + } + + sprite[playersprite[snum]].cstat &= ~1; + //Push player away from walls if clipmove doesn't work + if (pushmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],128L,4<<8,4<<8,CLIPMASK0) < 0) + changehealth(snum,-1000); //If this screws up, then instant death!!! + + // Getzrange returns the highest and lowest z's for an entire box, + // NOT just a point. This prevents you from falling off cliffs + // when you step only slightly over the cliff. + getzrange(posx[snum],posy[snum],posz[snum],cursectnum[snum],&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); + sprite[playersprite[snum]].cstat |= 1; + + if (ssync[snum].avel != 0) //ang += avel * constant + { //ENGINE calculates avel for you + doubvel = TICSPERFRAME; + if ((ssync[snum].bits&256) > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (TICSPERFRAME>>1); + ang[snum] += ((((long)ssync[snum].avel)*doubvel)>>4); + ang[snum] &= 2047; + } + + if (health[snum] < 0) + { + health[snum] -= TICSPERFRAME; + if (health[snum] <= -160) + { + hvel[snum] = 0; + if (snum == myconnectindex) + fvel = 0, svel = 0, avel = 0, keystatus[3] = 1; + + deaths[snum]++; + health[snum] = 100; + numbombs[snum] = 0; + numgrabbers[snum] = 0; + nummissiles[snum] = 0; + flytime[snum] = 0; + + findrandomspot(&posx[snum],&posy[snum],&cursectnum[snum]); + posz[snum] = getflorzofslope(cursectnum[snum],posx[snum],posy[snum])-(1<<8); + horiz[snum] = 100; + ang[snum] = (krand()&2047); + + sprite[playersprite[snum]].x = posx[snum]; + sprite[playersprite[snum]].y = posy[snum]; + sprite[playersprite[snum]].z = posz[snum]+EYEHEIGHT; + sprite[playersprite[snum]].picnum = PLAYER; + sprite[playersprite[snum]].ang = ang[snum]; + sprite[playersprite[snum]].xrepeat = 64; + sprite[playersprite[snum]].yrepeat = 64; + changespritesect(playersprite[snum],cursectnum[snum]); + + drawstatusbar(snum); // Andy did this + + i = playersprite[snum]; + wsayfollow("zipguns.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + for(k=0;k<16;k++) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, + 32,24,24,0,0,EXPLOSION,sprite[i].ang, + (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192, + sprite[i].owner,sprite[i].sectnum,7,96,0,0); + //96=Time left for smoke to be alive + } + } + else + { + sprite[playersprite[snum]].xrepeat = max(((128+health[snum])>>1),0); + sprite[playersprite[snum]].yrepeat = max(((128+health[snum])>>1),0); + + hvel[snum] += (TICSPERFRAME<<2); + horiz[snum] = max(horiz[snum]-4,0); + posz[snum] += hvel[snum]; + if (posz[snum] > globloz-(4<<8)) + { + posz[snum] = globloz-(4<<8); + horiz[snum] = min(horiz[snum]+5,200); + hvel[snum] = 0; + } + } + } + + if (((ssync[snum].bits&8) > 0) && (horiz[snum] > 100-(200>>1))) horiz[snum] -= 4; //- + if (((ssync[snum].bits&4) > 0) && (horiz[snum] < 100+(200>>1))) horiz[snum] += 4; //+ + + goalz = globloz-EYEHEIGHT; + if (sector[cursectnum[snum]].lotag == 4) //slime sector + if ((globlohit&0xc000) != 49152) //You're not on a sprite + { + goalz = globloz-(8<<8); + if (posz[snum] >= goalz-(2<<8)) + { + clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); + + if (slimesoundcnt[snum] >= 0) + { + slimesoundcnt[snum] -= TICSPERFRAME; + while (slimesoundcnt[snum] < 0) + { + slimesoundcnt[snum] += 120; + wsayfollow("slime.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + } + } + } + } + if (goalz < globhiz+(16<<8)) //ceiling&floor too close + goalz = ((globloz+globhiz)>>1); + //goalz += mousz; + if (health[snum] >= 0) + { + if ((ssync[snum].bits&1) > 0) //A (stand high) + { + if (flytime[snum] <= lockclock) + { + if (posz[snum] >= globloz-(32<<8)) + { + goalz -= (16<<8); + if (ssync[snum].bits&256) goalz -= (24<<8); + } + } + else + { + hvel[snum] -= 192; + if (ssync[snum].bits&256) hvel[snum] -= 192; + } + } + if ((ssync[snum].bits&2) > 0) //Z (stand low) + { + if (flytime[snum] <= lockclock) + { + goalz += (12<<8); + if (ssync[snum].bits&256) goalz += (12<<8); + } + else + { + hvel[snum] += 192; + if (ssync[snum].bits&256) hvel[snum] += 192; + } + } + } + + if (flytime[snum] <= lockclock) + { + if (posz[snum] < goalz) + hvel[snum] += (TICSPERFRAME<<4); + else + hvel[snum] = (((goalz-posz[snum])*TICSPERFRAME)>>5); + } + else + { + hvel[snum] -= (hvel[snum]>>2); + hvel[snum] -= ksgn(hvel[snum]); + } + + posz[snum] += hvel[snum]; + if (posz[snum] > globloz-(4<<8)) posz[snum] = globloz-(4<<8), hvel[snum] = 0; + if (posz[snum] < globhiz+(4<<8)) posz[snum] = globhiz+(4<<8), hvel[snum] = 0; + + if (dimensionmode[snum] != 3) + { + if (((ssync[snum].bits&32) > 0) && (zoom[snum] > 48)) zoom[snum] -= (zoom[snum]>>4); + if (((ssync[snum].bits&16) > 0) && (zoom[snum] < 4096)) zoom[snum] += (zoom[snum]>>4); + } + + //Update sprite representation of player + // -should be after movement, but before shooting code + setsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT); + sprite[playersprite[snum]].ang = ang[snum]; + + if (health[snum] >= 0) + { + if ((cursectnum[snum] < 0) || (cursectnum[snum] >= numsectors)) + { //How did you get in the wrong sector? + wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); + changehealth(snum,-TICSPERFRAME); + } + else if (globhiz+(8<<8) > globloz) + { //Ceiling and floor are smooshing you! + wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); + changehealth(snum,-TICSPERFRAME); + } + } + + if ((waterfountainwall[snum] >= 0) && (health[snum] >= 0)) + if ((wall[neartagwall].lotag != 7) || ((ssync[snum].bits&1024) == 0)) + { + i = waterfountainwall[snum]; + if (wall[i].overpicnum == USEWATERFOUNTAIN) + wall[i].overpicnum = WATERFOUNTAIN; + else if (wall[i].picnum == USEWATERFOUNTAIN) + wall[i].picnum = WATERFOUNTAIN; + + waterfountainwall[snum] = -1; + } + + if ((ssync[snum].bits&1024) > 0) //Space bar + { + //Continuous triggers... + + neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum],ang[snum],&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1024L,3); + if (neartagsector == -1) + { + i = cursectnum[snum]; + if ((sector[i].lotag|sector[i].hitag) != 0) + neartagsector = i; + } + + if (wall[neartagwall].lotag == 7) //Water fountain + { + if (wall[neartagwall].overpicnum == WATERFOUNTAIN) + { + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + wall[neartagwall].overpicnum = USEWATERFOUNTAIN; + waterfountainwall[snum] = neartagwall; + } + else if (wall[neartagwall].picnum == WATERFOUNTAIN) + { + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + wall[neartagwall].picnum = USEWATERFOUNTAIN; + waterfountainwall[snum] = neartagwall; + } + + if (waterfountainwall[snum] >= 0) + { + waterfountaincnt[snum] -= TICSPERFRAME; + while (waterfountaincnt[snum] < 0) + { + waterfountaincnt[snum] += 120; + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + changehealth(snum,2); + } + } + } + + //1-time triggers... + if ((oflags[snum]&1024) == 0) + { + if (neartagsector >= 0) + if (sector[neartagsector].hitag == 0) + operatesector(neartagsector); + + if (neartagwall >= 0) + if (wall[neartagwall].lotag == 2) //Switch + { + activatehitag(wall[neartagwall].hitag); + + j = wall[neartagwall].overpicnum; + if (j == SWITCH1ON) //1-time switch + { + wall[neartagwall].overpicnum = GIFTBOX; + wall[neartagwall].lotag = 0; + wall[neartagwall].hitag = 0; + } + if (j == GIFTBOX) //1-time switch + { + wall[neartagwall].overpicnum = SWITCH1ON; + wall[neartagwall].lotag = 0; + wall[neartagwall].hitag = 0; + } + if (j == SWITCH2ON) wall[neartagwall].overpicnum = SWITCH2OFF; + if (j == SWITCH2OFF) wall[neartagwall].overpicnum = SWITCH2ON; + if (j == SWITCH3ON) wall[neartagwall].overpicnum = SWITCH3OFF; + if (j == SWITCH3OFF) wall[neartagwall].overpicnum = SWITCH3ON; + + i = wall[neartagwall].point2; + dax = ((wall[neartagwall].x+wall[i].x)>>1); + day = ((wall[neartagwall].y+wall[i].y)>>1); + wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); + } + + if (neartagsprite >= 0) + { + if (sprite[neartagsprite].lotag == 1) + { //if you're shoving innocent little AL around, he gets mad! + if (sprite[neartagsprite].picnum == AL) + { + sprite[neartagsprite].picnum = EVILAL; + sprite[neartagsprite].cstat |= 2; //Make him transluscent + sprite[neartagsprite].xrepeat = 38; + sprite[neartagsprite].yrepeat = 38; + changespritestat(neartagsprite,10); + } + } + if (sprite[neartagsprite].lotag == 4) + { + activatehitag(sprite[neartagsprite].hitag); + + j = sprite[neartagsprite].picnum; + if (j == SWITCH1ON) //1-time switch + { + sprite[neartagsprite].picnum = GIFTBOX; + sprite[neartagsprite].lotag = 0; + sprite[neartagsprite].hitag = 0; + } + if (j == GIFTBOX) //1-time switch + { + sprite[neartagsprite].picnum = SWITCH1ON; + sprite[neartagsprite].lotag = 0; + sprite[neartagsprite].hitag = 0; + } + if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF; + if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON; + if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF; + if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON; + + dax = sprite[neartagsprite].x; + day = sprite[neartagsprite].y; + wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); + } + } + } + } + + if ((ssync[snum].bits & 2048) > 0) { // Shoot a bullet + if ((numbombs[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 2) && (myconnectindex == snum)) + locselectedgun = 0; + if ((nummissiles[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 3) && (myconnectindex == snum)) + locselectedgun = 1; + if ((numgrabbers[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 4) && (myconnectindex == snum)) + locselectedgun = 1; + + if ((health[snum] >= 0) || ((krand() & 127) > -health[snum])) + switch((ssync[snum].bits >> 13) & 7) { + case 0: + if (lockclock > lastchaingun[snum]+8) { + lastchaingun[snum] = lockclock; + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],0); + } + break; + case 1: + if ((oflags[snum] & 2048) == 0) + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],1); + break; + case 2: + if ((oflags[snum] & 2048) == 0) + if (numbombs[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],2); + changenumbombs(snum,-1); + } + break; + case 3: + if ((oflags[snum] & 2048) == 0) + if (nummissiles[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],3); + changenummissiles(snum,-1); + } + break; + case 4: + if ((oflags[snum] & 2048) == 0) + if (numgrabbers[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],4); + changenumgrabbers(snum,-1); + } + break; + } + } + + if ((ssync[snum].bits&4096) > (oflags[snum]&4096)) //Keypad enter + { + dimensionmode[snum]++; + if (dimensionmode[snum] > 3) dimensionmode[snum] = 1; + } + + oflags[snum] = ssync[snum].bits; +} + +void view(short snum, long *vx, long *vy, long *vz, short *vsectnum, short ang, long horiz) +{ + spritetype *sp; + long i, nx, ny, nz, hx, hy, hz, hitx, hity, hitz; + short bakcstat, hitsect, hitwall, hitsprite, daang; + + nx = (sintable[(ang+1536)&2047]>>4); + ny = (sintable[(ang+1024)&2047]>>4); + nz = (horiz-100)*128; + + sp = &sprite[snum]; + + bakcstat = sp->cstat; + sp->cstat &= (short)~0x101; + + updatesectorz(*vx,*vy,*vz,vsectnum); + hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + hx = hitx-(*vx); hy = hity-(*vy); + if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy)) + { + *vsectnum = hitsect; + if (hitwall >= 0) + { + daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x, + wall[wall[hitwall].point2].y-wall[hitwall].y); + + i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047]; + if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i); + else hy -= mulscale28(ny,i); + } + else if (hitsprite < 0) + { + if (klabs(nx) > klabs(ny)) hx -= (nx>>5); + else hy -= (ny>>5); + } + if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx); + else i = divscale16(hy,ny); + if (i < cameradist) cameradist = i; + } + *vx = (*vx)+mulscale16(nx,cameradist); + *vy = (*vy)+mulscale16(ny,cameradist); + *vz = (*vz)+mulscale16(nz,cameradist); + + updatesectorz(*vx,*vy,*vz,vsectnum); + + sp->cstat = bakcstat; +} + +#if 0 // JBF: now in the engine +void updatesectorz(long x, long y, long z, short *sectnum) +{ + walltype *wal; + long i, j, cz, fz; + + getzsofslope(*sectnum,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,*sectnum) != 0) return; + + if ((*sectnum >= 0) && (*sectnum < numsectors)) + { + wal = &wall[sector[*sectnum].wallptr]; + j = sector[*sectnum].wallnum; + do + { + i = wal->nextsector; + if (i >= 0) + { + getzsofslope(i,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + wal++; j--; + } while (j != 0); + } + + for(i=numsectors-1;i>=0;i--) + { + getzsofslope(i,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + + *sectnum = -1; +} +#endif + +void drawscreen(short snum, long dasmoothratio) +{ + long i, j, k=0, l, charsperline, tempint; + long x1, y1, x2, y2, ox1, oy1, ox2, oy2, dist, maxdist; + long cposx, cposy, cposz, choriz, czoom, tposx, tposy; + long tiltlock, *intptr, ovisibility, oparallaxvisibility; + short cang, tang, csect; + char ch, *ptr, *ptr2, *ptr3, *ptr4; + spritetype *tspr; + + smoothratio = max(min(dasmoothratio,65536),0); + + dointerpolations(); + + if ((snum == myconnectindex) && ((networkmode == 1) || (myconnectindex != connecthead))) + { + cposx = omyx+mulscale16(myx-omyx,smoothratio); + cposy = omyy+mulscale16(myy-omyy,smoothratio); + cposz = omyz+mulscale16(myz-omyz,smoothratio); + choriz = omyhoriz+mulscale16(myhoriz-omyhoriz,smoothratio); + cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); + } + else + { + cposx = oposx[snum]+mulscale16(posx[snum]-oposx[snum],smoothratio); + cposy = oposy[snum]+mulscale16(posy[snum]-oposy[snum],smoothratio); + cposz = oposz[snum]+mulscale16(posz[snum]-oposz[snum],smoothratio); + choriz = ohoriz[snum]+mulscale16(horiz[snum]-ohoriz[snum],smoothratio); + cang = oang[snum]+mulscale16(((ang[snum]+1024-oang[snum])&2047)-1024,smoothratio); + } + czoom = ozoom[snum]+mulscale16(zoom[snum]-ozoom[snum],smoothratio); + + setears(cposx,cposy,(long)sintable[(cang+512)&2047]<<14,(long)sintable[cang&2047]<<14); + + if (dimensionmode[myconnectindex] == 3) + { + tempint = screensize; + + if (((loc.bits&32) > (screensizeflag&32)) && (screensize > 64)) + { + ox1 = ((xdim-screensize)>>1); + ox2 = ox1+screensize-1; + oy1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + oy2 = oy1 + scale(screensize,ydim-32,xdim)-1; + screensize -= (screensize>>3); + + if (tempint > xdim) + { + screensize = xdim; + + flushperms(); + + rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1); + while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1)+320; + while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; + if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; + + drawstatusbar(screenpeek); // Andy did this + } + + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + setview(x1,y1,x2,y2); + + // (ox1,oy1)ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + // ³ (x1,y1) ³ + // ³ ÚÄÄÄÄÄ¿ ³ + // ³ ³ ³ ³ + // ³ ÀÄÄÄÄÄÙ ³ + // ³ (x2,y2) ³ + // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ(ox2,oy2) + + drawtilebackground(0L,0L,BACKGROUND,8,ox1,oy1,x1-1,oy2,0); + drawtilebackground(0L,0L,BACKGROUND,8,x2+1,oy1,ox2,oy2,0); + drawtilebackground(0L,0L,BACKGROUND,8,x1,oy1,x2,y1-1,0); + drawtilebackground(0L,0L,BACKGROUND,8,x1,y2+1,x2,oy2,0); + } + if (((loc.bits&16) > (screensizeflag&16)) && (screensize <= xdim)) + { + screensize += (screensize>>3); + if ((screensize > xdim) && (tempint == xdim)) + { + screensize = xdim+1; + x1 = 0; y1 = 0; + x2 = xdim-1; y2 = ydim-1; + } + else + { + if (screensize > xdim) screensize = xdim; + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + } + setview(x1,y1,x2,y2); + } + screensizeflag = loc.bits; + } + + if (dimensionmode[snum] != 2) + { + if ((numplayers > 1) && (option[4] == 0)) + { + //Do not draw other views constantly if they're staying still + //It's a shame this trick will only work in screen-buffer mode + //At least screen-buffer mode covers all the HI hi-res modes + //if (vidoption == 2) + //{ + for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 0; + frame2draw[snum] = 1; + + //2-1,3-1,4-2 + //5-2,6-2,7-2,8-3,9-3,10-3,11-3,12-4,13-4,14-4,15-4,16-5 + x1 = posx[snum]; y1 = posy[snum]; + for(j=(numplayers>>2)+1;j>0;j--) + { + maxdist = 0x80000000; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (frame2draw[i] == 0) + { + x2 = posx[i]-x1; y2 = posy[i]-y1; + dist = dmulscale12(x2,x2,y2,y2); + + if (dist < 64) dist = 16384; + else if (dist > 16384) dist = 64; + else dist = 1048576 / dist; + + dist *= frameskipcnt[i]; + + //Increase frame rate if screen is moving + if ((posx[i] != oposx[i]) || (posy[i] != oposy[i]) || + (posz[i] != oposz[i]) || (ang[i] != oang[i]) || + (horiz[i] != ohoriz[i])) dist += dist; + + if (dist > maxdist) maxdist = dist, k = i; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + frameskipcnt[i] += (frameskipcnt[i]>>3)+1; + frameskipcnt[k] = 0; + + frame2draw[k] = 1; + } + //} + //else + //{ + // for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 1; + //} + + for(i=connecthead,j=0;i>=0;i=connectpoint2[i],j++) + if (frame2draw[i] != 0) + { + if (numplayers <= 4) + { + switch(j) + { + case 0: setview(0,0,(xdim>>1)-1,(ydim>>1)-1); break; + case 1: setview((xdim>>1),0,xdim-1,(ydim>>1)-1); break; + case 2: setview(0,(ydim>>1),(xdim>>1)-1,ydim-1); break; + case 3: setview((xdim>>1),(ydim>>1),xdim-1,ydim-1); break; + } + } + else + { + switch(j) + { + case 0: setview(0,0,(xdim>>2)-1,(ydim>>2)-1); break; + case 1: setview(xdim>>2,0,(xdim>>1)-1,(ydim>>2)-1); break; + case 2: setview(xdim>>1,0,xdim-(xdim>>2)-1,(ydim>>2)-1); break; + case 3: setview(xdim-(xdim>>2),0,xdim-1,(ydim>>2)-1); break; + case 4: setview(0,ydim>>2,(xdim>>2)-1,(ydim>>1)-1); break; + case 5: setview(xdim>>2,ydim>>2,(xdim>>1)-1,(ydim>>1)-1); break; + case 6: setview(xdim>>1,ydim>>2,xdim-(xdim>>2)-1,(ydim>>1)-1); break; + case 7: setview(xdim-(xdim>>2),ydim>>2,xdim-1,(ydim>>1)-1); break; + case 8: setview(0,ydim>>1,(xdim>>2)-1,ydim-(ydim>>2)-1); break; + case 9: setview(xdim>>2,ydim>>1,(xdim>>1)-1,ydim-(ydim>>2)-1); break; + case 10: setview(xdim>>1,ydim>>1,xdim-(xdim>>2)-1,ydim-(ydim>>2)-1); break; + case 11: setview(xdim-(xdim>>2),ydim>>1,xdim-1,ydim-(ydim>>2)-1); break; + case 12: setview(0,ydim-(ydim>>2),(xdim>>2)-1,ydim-1); break; + case 13: setview(xdim>>2,ydim-(ydim>>2),(xdim>>1)-1,ydim-1); break; + case 14: setview(xdim>>1,ydim-(ydim>>2),xdim-(xdim>>2)-1,ydim-1); break; + case 15: setview(xdim-(xdim>>2),ydim-(ydim>>2),xdim-1,ydim-1); break; + } + } + + if (i == snum) + { + sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,cposz,cang,choriz,cursectnum[i]); + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + } + else + { + sprite[playersprite[i]].cstat |= 0x8000; + drawrooms(posx[i],posy[i],posz[i],ang[i],horiz[i],cursectnum[i]); + sprite[playersprite[i]].cstat &= ~0x8000; + analyzesprites(posx[i],posy[i]); + } + drawmasks(); + if ((numgrabbers[i] > 0) || (nummissiles[i] > 0) || (numbombs[i] > 0)) + rotatesprite(160<<16,184L<<16,65536,0,GUNONBOTTOM,sector[cursectnum[i]].floorshade,0,2,windowx1,windowy1,windowx2,windowy2); + + if (lockclock < 384) + { + if (lockclock < 128) + rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + else if (lockclock < 256) + rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); + else + rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + } + + if (health[i] <= 0) + rotatesprite(320<<15,200<<15,(-health[i])<<11,(-health[i])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); + } + } + else + { + //Init for screen rotation + if (getrendermode() == 0) { // JBF 20031220 + tiltlock = screentilt; + if ((tiltlock) || (detailmode)) + { + walock[MAXTILES-2] = 255; + if (waloff[MAXTILES-2] == 0) + allocache(&waloff[MAXTILES-2],320L*320L,&walock[MAXTILES-2]); + if ((tiltlock&1023) == 0) + setviewtotile(MAXTILES-2,200L>>detailmode,320L>>detailmode); + else + setviewtotile(MAXTILES-2,320L>>detailmode,320L>>detailmode); + if ((tiltlock&1023) == 512) + { //Block off unscreen section of 90ø tilted screen + j = ((320-60)>>detailmode); + for(i=(60>>detailmode)-1;i>=0;i--) + { + startumost[i] = 1; startumost[i+j] = 1; + startdmost[i] = 0; startdmost[i+j] = 0; + } + } + + i = (tiltlock&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + setaspect(i>>1,yxaspect); + } + } else { + tiltlock = screentilt; + // Ken loves to interpolate + setrollangle(oscreentilt + mulscale16(((screentilt-oscreentilt+1024)&2047)-1024,smoothratio)); + } + + if ((gotpic[FLOORMIRROR>>3]&(1<<(FLOORMIRROR&7))) > 0) + { + dist = 0x7fffffff; i = 0; + for(k=floormirrorcnt-1;k>=0;k--) + { + j = klabs(wall[sector[floormirrorsector[k]].wallptr].x-cposx); + j += klabs(wall[sector[floormirrorsector[k]].wallptr].y-cposy); + if (j < dist) dist = j, i = k; + } + + //if (cposz > sector[floormirrorsector[i]].ceilingz) i = 1-i; //SOS + + j = floormirrorsector[i]; + + if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,(sector[j].floorz<<1)-cposz,cang,201-choriz,j); //SOS + //drawrooms(cposx,cposy,cposz,cang,choriz,j+MAXSECTORS); //SOS + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + drawmasks(); + + //Temp horizon + if (getrendermode() == 0) { + l = scale(choriz-100,windowx2-windowx1,320)+((windowy1+windowy2)>>1); + begindrawing(); //{{{ + for(y1=windowy1,y2=windowy2;y1>2,31)<<8); + ptr4 = palookup[18]; + ptr4 += (min(klabs(y2-l)>>2,31)<<8); + + j = sintable[((y2+totalclock)<<6)&2047]; + j += sintable[((y2-totalclock)<<7)&2047]; + j >>= 14; + + //ptr2 += j; + + //for(x1=windowx1;x1<=windowx2;x1++) + // { ch = ptr[x1]; ptr[x1] = ptr3[ptr2[x1]]; ptr2[x1] = ptr4[ch]; } + + ox1 = windowx1-min(j,0); + ox2 = windowx2-max(j,0); + + for(x1=windowx1;x1>3] &= ~(1<<(FLOORMIRROR&7)); + } + + if (gotpic[DAYSKY>>3]&(1<<(DAYSKY&7))) + { + gotpic[DAYSKY>>3] &= ~(1<<(DAYSKY&7)); + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + } + else if (gotpic[NIGHTSKY>>3]&(1<<(NIGHTSKY&7))) + { + gotpic[NIGHTSKY>>3] &= ~(1<<(NIGHTSKY&7)); + pskyoff[0] = 0; pskyoff[1] = 0; pskyoff[2] = 0; pskyoff[3] = 0; + pskyoff[4] = 0; pskyoff[5] = 0; pskyoff[6] = 0; pskyoff[7] = 0; + pskybits = 3; + } + + + //Over the shoulder mode + csect = cursectnum[snum]; + if (cameradist >= 0) + { + cang += cameraang; + view(playersprite[snum],&cposx,&cposy,&cposz,&csect,cang,choriz); + } + + //WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 + intptr = (long *)&gotpic[MIRRORLABEL>>3]; // CHECK! + if (intptr[0]|intptr[1]) + for(i=MAXMIRRORS-1;i>=0;i--) + if (gotpic[(i+MIRRORLABEL)>>3]&(1<<(i&7))) + { + gotpic[(i+MIRRORLABEL)>>3] &= ~(1<<(i&7)); + + //Prepare drawrooms for drawing mirror and calculate reflected + //position into tposx, tposy, and tang (tposz == cposz) + //Must call preparemirror before drawrooms and + // completemirror after drawrooms + preparemirror(cposx,cposy,cposz,cang,choriz, + mirrorwall[i],mirrorsector[i],&tposx,&tposy,&tang); + + ovisibility = visibility; + oparallaxvisibility = parallaxvisibility; + visibility <<= 1; + parallaxvisibility <<= 1; + ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; + + drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]|MAXSECTORS); + for(j=0,tspr=&tsprite[0];jcstat&48) == 0) tspr->cstat |= 4; + analyzesprites(tposx,tposy); + drawmasks(); + + ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; + visibility = ovisibility; + parallaxvisibility = oparallaxvisibility; + + completemirror(); //Reverse screen x-wise in this function + + break; + } + + if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,cposz,cang,choriz,csect); + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + drawmasks(); + + //Finish for screen rotation + if (getrendermode() == 0) { // JBF 20031220 + if ((tiltlock) || (detailmode)) + { + setviewback(); + i = (tiltlock&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + if (detailmode == 0) i >>= 1; + rotatesprite(320<<15,200<<15,i,tiltlock+512,MAXTILES-2,0,0,2+4+64,windowx1,windowy1,windowx2,windowy2); + walock[MAXTILES-2] = 1; + } + } + + if (((numgrabbers[screenpeek] > 0) || (nummissiles[screenpeek] > 0) || (numbombs[screenpeek] > 0)) && (cameradist < 0)) + { + //Reset startdmost to bottom of screen + if ((windowx1 == 0) && (windowx2 == 319) && (yxaspect == 65536) && (tiltlock == 0)) + { + x1 = 160L-(tilesizx[GUNONBOTTOM]>>1); y1 = windowy2+1; + for(i=0;i>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + else if (lockclock < 256) + rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); + else + rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + } + + if (health[screenpeek] <= 0) + rotatesprite(320<<15,200<<15,(-health[screenpeek])<<11,(-health[screenpeek])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); + } + } + + //Only animate lava if its picnum is on screen + //gotpic is a bit array where the tile number's bit is set + //whenever it is drawn (ceilings, walls, sprites, etc.) + if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0) + { + gotpic[SLIME>>3] &= ~(1<<(SLIME&7)); + if (waloff[SLIME] != 0) { + movelava((char *)waloff[SLIME]); + invalidatetile(SLIME,0,1); // JBF 20031228 + } + } + + if ((show2dsector[cursectnum[snum]>>3]&(1<<(cursectnum[snum]&7))) == 0) + searchmap(cursectnum[snum]); + + if (dimensionmode[snum] != 3) + { + //Move back pivot point + i = scale(czoom,screensize,320); + if (dimensionmode[snum] == 2) + { + clearview(0L); //Clear screen to specified color + drawmapview(cposx,cposy,i,cang); + } + drawoverheadmap(cposx,cposy,i,cang); + } + + if (typemode != 0) + { + charsperline = 40; + //if (dimensionmode[snum] == 2) charsperline = 80; + + for(i=0;i<=typemessageleng;i+=charsperline) + { + for(j=0;j 0) + { + charsperline = 40; + //if (dimensionmode[snum] == 2) charsperline = 80; + + for(i=0;i<=getmessageleng;i+=charsperline) + { + for(j=0;j getmessagetimeoff) + getmessageleng = 0; + } + if ((numplayers >= 2) && (screenpeek != myconnectindex)) + { + j = 1; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i == screenpeek) break; + j++; + } + Bsprintf(tempbuf,"(Player %ld's view)",j); + printext256((xdim>>1)-(Bstrlen(tempbuf)<<2),0,24,-1,tempbuf,0); + } + + if (syncstat != 0) printext256(68L,84L,31,0,"OUT OF SYNC!",0); + if (syncstate != 0) printext256(68L,92L,31,0,"Missed Network packet!",0); + +// //Uncomment this to test cache locks +//extern long cacnum; +//typedef struct { long *hand, leng; char *lock; } cactype; +//extern cactype cac[]; +// +// j = 0; +// for(i=0;i= 200) +// { +// Bsprintf(tempbuf,"Locked- %ld: Leng:%ld, Lock:%ld",i,cac[i].leng,*cac[i].lock); +// printext256(0L,j,31,-1,tempbuf,1); j += 6; +// } + + nextpage(); // send completed frame to display + + while (totalclock >= ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) + faketimerhandler(); + + if (keystatus[0x3f]) //F5 + { + keystatus[0x3f] = 0; + detailmode ^= 1; + //setrendermode(3); + } + if (keystatus[0x58]) //F12 + { + keystatus[0x58] = 0; + screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); + } + if (keystatus[0x3e]) //F4 - screen re-size + { + keystatus[0x3e] = 0; + + if (keystatus[0x2a]|keystatus[0x36]) { + setgamemode(!fullscreen, xdim, ydim, bpp); + } else { + + //cycle through all modes + j=-1; + + // work out a mask to select the mode + for (i=0; i 8) brightness = 0; + setbrightness(brightness,(char *)&palette[0],0); + } + + if (option[4] == 0) //Single player only keys + { + if (keystatus[0xd2]) //Insert - Insert player + { + keystatus[0xd2] = 0; + if (numplayers < MAXPLAYERS) + { + connectpoint2[numplayers-1] = numplayers; + connectpoint2[numplayers] = -1; + + movefifoend[numplayers] = movefifoend[0]; //HACK 01/05/2000 + + initplayersprite(numplayers); + + clearallviews(0L); //Clear screen to specified color + + numplayers++; + } + } + if (keystatus[0xd3]) //Delete - Delete player + { + keystatus[0xd3] = 0; + if (numplayers > 1) + { + numplayers--; + connectpoint2[numplayers-1] = -1; + + deletesprite(playersprite[numplayers]); + playersprite[numplayers] = -1; + + if (myconnectindex >= numplayers) myconnectindex = 0; + if (screenpeek >= numplayers) screenpeek = 0; + + if (numplayers < 2) + setup3dscreen(); + else + clearallviews(0L); //Clear screen to specified color + } + } + if (keystatus[0x46]) //Scroll Lock + { + keystatus[0x46] = 0; + + myconnectindex = connectpoint2[myconnectindex]; + if (myconnectindex < 0) myconnectindex = connecthead; + screenpeek = myconnectindex; + } + } + + restoreinterpolations(); +} + +void movethings(void) +{ + long i; + + gotlastpacketclock = totalclock; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + copybufbyte(&ffsync[i],&baksync[movefifoend[i]][i],sizeof(input)); + movefifoend[i] = ((movefifoend[i]+1)&(MOVEFIFOSIZ-1)); + } +} + +void fakedomovethings(void) +{ + input *syn; + long i, j, k, doubvel, xvect, yvect, goalz; + short bakcstat; + + syn = (input *)&baksync[fakemovefifoplc][myconnectindex]; + + omyx = myx; + omyy = myy; + omyz = myz; + omyang = myang; + omyhoriz = myhoriz; + + bakcstat = sprite[playersprite[myconnectindex]].cstat; + sprite[playersprite[myconnectindex]].cstat &= ~0x101; + + if ((syn->fvel|syn->svel) != 0) + { + doubvel = (TICSPERFRAME<<((syn->bits&256)>0)); + + xvect = 0, yvect = 0; + if (syn->fvel != 0) + { + xvect += ((((long)syn->fvel)*doubvel*(long)sintable[(myang+512)&2047])>>3); + yvect += ((((long)syn->fvel)*doubvel*(long)sintable[myang&2047])>>3); + } + if (syn->svel != 0) + { + xvect += ((((long)syn->svel)*doubvel*(long)sintable[myang&2047])>>3); + yvect += ((((long)syn->svel)*doubvel*(long)sintable[(myang+1536)&2047])>>3); + } + if (flytime[myconnectindex] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed + clipmove(&myx,&myy,&myz,&mycursectnum,xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); + } + + pushmove(&myx,&myy,&myz,&mycursectnum,128L,4<<8,4<<8,CLIPMASK0); + getzrange(myx,myy,myz,mycursectnum,&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); + + if (syn->avel != 0) //ang += avel * constant + { //ENGINE calculates avel for you + doubvel = TICSPERFRAME; + if ((syn->bits&256) > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (TICSPERFRAME>>1); + myang += ((((long)syn->avel)*doubvel)>>4); + myang &= 2047; + } + + if (((syn->bits&8) > 0) && (myhoriz > 100-(200>>1))) myhoriz -= 4; //- + if (((syn->bits&4) > 0) && (myhoriz < 100+(200>>1))) myhoriz += 4; //+ + + goalz = globloz-EYEHEIGHT; + if (sector[mycursectnum].lotag == 4) //slime sector + if ((globlohit&0xc000) != 49152) //You're not on a sprite + { + goalz = globloz-(8<<8); + if (myz >= goalz-(2<<8)) + clipmove(&myx,&myy,&myz,&mycursectnum,-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); + } + if (goalz < globhiz+(16<<8)) //ceiling&floor too close + goalz = ((globloz+globhiz)>>1); + + if (health[myconnectindex] >= 0) + { + if ((syn->bits&1) > 0) //A (stand high) + { + if (flytime[myconnectindex] <= lockclock) + { + if (myz >= globloz-(32<<8)) + { + goalz -= (16<<8); + if (syn->bits&256) goalz -= (24<<8); + } + } + else + { + myzvel -= 192; + if (syn->bits&256) myzvel -= 192; + } + } + if ((syn->bits&2) > 0) //Z (stand low) + { + if (flytime[myconnectindex] <= lockclock) + { + goalz += (12<<8); + if (syn->bits&256) goalz += (12<<8); + } + else + { + myzvel += 192; + if (syn->bits&256) myzvel += 192; + } + } + } + + if (flytime[myconnectindex] <= lockclock) + { + if (myz < goalz) + myzvel += (TICSPERFRAME<<4); + else + myzvel = (((goalz-myz)*TICSPERFRAME)>>5); + } + else + { + myzvel -= (myzvel>>2); + myzvel -= ksgn(myzvel); + } + + myz += myzvel; + if (myz > globloz-(4<<8)) myz = globloz-(4<<8), myzvel = 0; + if (myz < globhiz+(4<<8)) myz = globhiz+(4<<8), myzvel = 0; + + sprite[playersprite[myconnectindex]].cstat = bakcstat; + + myxbak[fakemovefifoplc] = myx; + myybak[fakemovefifoplc] = myy; + myzbak[fakemovefifoplc] = myz; + myangbak[fakemovefifoplc] = myang; + myhorizbak[fakemovefifoplc] = myhoriz; + fakemovefifoplc = (fakemovefifoplc+1)&(MOVEFIFOSIZ-1); +} + + //Prediction correction +void fakedomovethingscorrect(void) +{ + long i; + + if ((networkmode == 0) && (myconnectindex == connecthead)) return; + + i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); + + if ((posx[myconnectindex] == myxbak[i]) && + (posy[myconnectindex] == myybak[i]) && + (posz[myconnectindex] == myzbak[i]) && + (horiz[myconnectindex] == myhorizbak[i]) && + (ang[myconnectindex] == myangbak[i])) + return; + + //Re-start fakedomovethings back to place of error + myx = omyx = posx[myconnectindex]; + myy = omyy = posy[myconnectindex]; + myz = omyz = posz[myconnectindex]; myzvel = hvel[myconnectindex]; + myang = omyang = ang[myconnectindex]; + mycursectnum = mycursectnum; + myhoriz = omyhoriz = horiz[myconnectindex]; + + fakemovefifoplc = movefifoplc; + while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); +} + +void domovethings(void) +{ + short i, j, startwall, endwall; + spritetype *spr; + walltype *wal; + point3d *ospr; + + nummoves++; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + copybufbyte(&baksync[movefifoplc][i],&ssync[i],sizeof(input)); + movefifoplc = ((movefifoplc+1)&(MOVEFIFOSIZ-1)); + + if (option[4] != 0) + { + syncval[syncvalhead] = (char)(randomseed&255); + syncvalhead = ((syncvalhead+1)&(MOVEFIFOSIZ-1)); + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + oposx[i] = posx[i]; + oposy[i] = posy[i]; + oposz[i] = posz[i]; + ohoriz[i] = horiz[i]; + ozoom[i] = zoom[i]; + oang[i] = ang[i]; + } + + for(i=NUMSTATS-1;i>=0;i--) + if (statrate[i] >= 0) + for(j=headspritestat[i];j>=0;j=nextspritestat[j]) + if (((nummoves-j)&statrate[i]) == 0) + copybuf(&sprite[j].x,&osprite[j].x,3); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + ocursectnum[i] = cursectnum[i]; + + updateinterpolations(); + + if ((numplayers <= 2) && (recstat == 1)) + { + j = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + copybufbyte(&ssync[i],&recsync[reccnt][j],sizeof(input)); + j++; + } + reccnt++; if (reccnt > 16383) reccnt = 16383; + } + + lockclock += TICSPERFRAME; + drawstatusflytime(screenpeek); // Andy did this + + if (cameradist >= 0) + { + cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536); + if (keystatus[0x52]) //0 + cameraang -= ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); + if (keystatus[0x53]) //. + cameraang += ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); + cameraclock = totalclock; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + processinput(i); //Move player + + checktouchsprite(i,cursectnum[i]); //Pick up coins + startwall = sector[cursectnum[i]].wallptr; + endwall = startwall + sector[cursectnum[i]].wallnum; + for(j=startwall,wal=&wall[j];jnextsector >= 0) checktouchsprite(i,wal->nextsector); + } + + doanimations(); + tagcode(); //Door code, moving sector code, other stuff + statuslistcode(); //Monster / bullet code / explosions + + fakedomovethingscorrect(); + + checkmasterslaveswitch(); +} + +void getinput(void) +{ + char ch, keystate, *ptr; + long i, j, k; + long mousx, mousy, bstatus; + + if (typemode == 0) //if normal game keys active + { + if (keystatus[keys[15]]) + { + keystatus[keys[15]] = 0; + + screenpeek = connectpoint2[screenpeek]; + if (screenpeek < 0) screenpeek = connecthead; + drawstatusbar(screenpeek); // Andy did this + } + + for(i=7;i>=0;i--) + if (keystatus[i+2]) + { keystatus[i+2] = 0; locselectedgun = i; break; } + } + + + //KEYTIMERSTUFF + if (!keystatus[keys[5]]) + { + if (keystatus[keys[2]]) avel = max(avel-16*TICSPERFRAME,-128); + if (keystatus[keys[3]]) avel = min(avel+16*TICSPERFRAME,127); + } + else + { + if (keystatus[keys[2]]) svel = min(svel+8*TICSPERFRAME,127); + if (keystatus[keys[3]]) svel = max(svel-8*TICSPERFRAME,-128); + } + if (keystatus[keys[0]]) fvel = min(fvel+8*TICSPERFRAME,127); + if (keystatus[keys[1]]) fvel = max(fvel-8*TICSPERFRAME,-128); + if (keystatus[keys[12]]) svel = min(svel+8*TICSPERFRAME,127); + if (keystatus[keys[13]]) svel = max(svel-8*TICSPERFRAME,-128); + + if (avel < 0) avel = min(avel+12*TICSPERFRAME,0); + if (avel > 0) avel = max(avel-12*TICSPERFRAME,0); + if (svel < 0) svel = min(svel+2*TICSPERFRAME,0); + if (svel > 0) svel = max(svel-2*TICSPERFRAME,0); + if (fvel < 0) fvel = min(fvel+2*TICSPERFRAME,0); + if (fvel > 0) fvel = max(fvel-2*TICSPERFRAME,0); + + if ((option[4] == 0) && (numplayers >= 2)) + { + if (!keystatus[0x4f]) + { + if (keystatus[0x4b]) avel2 = max(avel2-16*TICSPERFRAME,-128); + if (keystatus[0x4d]) avel2 = min(avel2+16*TICSPERFRAME,127); + } + else + { + if (keystatus[0x4b]) svel2 = min(svel2+8*TICSPERFRAME,127); + if (keystatus[0x4d]) svel2 = max(svel2-8*TICSPERFRAME,-128); + } + if (keystatus[0x48]) fvel2 = min(fvel2+8*TICSPERFRAME,127); + if (keystatus[0x4c]) fvel2 = max(fvel2-8*TICSPERFRAME,-128); + + if (avel2 < 0) avel2 = min(avel2+12*TICSPERFRAME,0); + if (avel2 > 0) avel2 = max(avel2-12*TICSPERFRAME,0); + if (svel2 < 0) svel2 = min(svel2+2*TICSPERFRAME,0); + if (svel2 > 0) svel2 = max(svel2-2*TICSPERFRAME,0); + if (fvel2 < 0) fvel2 = min(fvel2+2*TICSPERFRAME,0); + if (fvel2 > 0) fvel2 = max(fvel2-2*TICSPERFRAME,0); + } + + oscreentilt = screentilt; + if (keystatus[0x1a]) screentilt += ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); + if (keystatus[0x1b]) screentilt -= ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); + + i = (TICSPERFRAME<<1); + while ((screentilt != 0) && (i > 0)) + { screentilt = ((screentilt+ksgn(screentilt-1024))&2047); i--; } + if (keystatus[0x28]) screentilt = 1536; + + + loc.fvel = min(max(fvel,-128+8),127-8); + loc.svel = min(max(svel,-128+8),127-8); + loc.avel = min(max(avel,-128+16),127-16); + + getmousevalues(&mousx,&mousy,&bstatus); + loc.avel = min(max(loc.avel+(mousx<<3),-128),127); + loc.fvel = min(max(loc.fvel-(mousy<<3),-128),127); + + loc.bits = (locselectedgun<<13); + if (typemode == 0) //if normal game keys active + { + loc.bits |= (keystatus[0x32]<<9); //M (be master) + loc.bits |= ((keystatus[keys[14]]==1)<<12); //Map mode + } + loc.bits |= keystatus[keys[8]]; //Stand high + loc.bits |= (keystatus[keys[9]]<<1); //Stand low + loc.bits |= (keystatus[keys[16]]<<4); //Zoom in + loc.bits |= (keystatus[keys[17]]<<5); //Zoom out + loc.bits |= (keystatus[keys[4]]<<8); //Run + loc.bits |= (keystatus[keys[10]]<<2); //Look up + loc.bits |= (keystatus[keys[11]]<<3); //Look down + loc.bits |= ((keystatus[keys[7]]==1)<<10); //Space + loc.bits |= ((keystatus[keys[6]]==1)<<11); //Shoot + loc.bits |= (((bstatus&6)>(oldmousebstatus&6))<<10); //Space + loc.bits |= (((bstatus&1)>(oldmousebstatus&1))<<11); //Shoot + + oldmousebstatus = bstatus; + if (((loc.bits&2048) > 0) && (locselectedgun == 0)) + oldmousebstatus &= ~1; //Allow continous fire with mouse for chain gun + + //PRIVATE KEYS: +/* if (keystatus[0xb7]) //Printscreen + { + keystatus[0xb7] = 0; + printscreeninterrupt(); + } +*/ + if (keystatus[0x2f]) //V + { + keystatus[0x2f] = 0; + if (cameradist < 0) cameradist = 0; else cameradist = -1; + cameraang = 0; + } + + if (typemode == 0) //if normal game keys active + { + if (keystatus[0x19]) //P + { + keystatus[0x19] = 0; + parallaxtype++; + if (parallaxtype > 2) parallaxtype = 0; + } + if (keystatus[0x38]|keystatus[0xb8]) //ALT + { + if (keystatus[0x4a]) // Keypad - + visibility = min(visibility+(visibility>>3),16384); + if (keystatus[0x4e]) // Keypad + + visibility = max(visibility-(visibility>>3),128); + } + + if (keystatus[keys[18]]) //Typing mode + { + keystatus[keys[18]] = 0; + typemode = 1; + bflushchars(); + keyfifoplc = keyfifoend; //Reset keyboard fifo + } + } + else + { + while ((ch = bgetchar())) + { + if (ch == 8) //Backspace + { + if (typemessageleng == 0) { typemode = 0; break; } + typemessageleng--; + } + else if (ch == 9) // tab + { + keystatus[0xf] = 0; + typemode = 0; + break; + } + else if (ch == 13) //Either ENTER + { + keystatus[0x1c] = 0; keystatus[0x9c] = 0; + if (typemessageleng > 0) + { + packbuf[0] = 2; //Sending text is message type 4 + for(j=typemessageleng-1;j>=0;j--) + packbuf[j+1] = typemessage[j]; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + sendpacket(i,packbuf,typemessageleng+1); + + typemessageleng = 0; + } + typemode = 0; + break; + } + else if ((typemessageleng < 159) && (ch >= 32) && (ch < 128)) + { + typemessage[typemessageleng++] = ch; + } + } + } +} + +void initplayersprite(short snum) +{ + long i; + + if (playersprite[snum] >= 0) return; + + spawnsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT, + 1+256,0,snum,32,64,64,0,0,PLAYER,ang[snum],0,0,0,snum+4096, + cursectnum[snum],8,0,0,0); + + switch(snum) + { + case 1: for(i=0;i<32;i++) tempbuf[i+192] = i+128; break; //green->red + case 2: for(i=0;i<32;i++) tempbuf[i+192] = i+32; break; //green->blue + case 3: for(i=0;i<32;i++) tempbuf[i+192] = i+224; break; //green->pink + case 4: for(i=0;i<32;i++) tempbuf[i+192] = i+64; break; //green->brown + case 5: for(i=0;i<32;i++) tempbuf[i+192] = i+96; break; + case 6: for(i=0;i<32;i++) tempbuf[i+192] = i+160; break; + case 7: for(i=0;i<32;i++) tempbuf[i+192] = i+192; break; + default: for(i=0;i<256;i++) tempbuf[i] = i; break; + } + makepalookup(snum,tempbuf,0,0,0,1); +} + +void playback(void) +{ + long i, j, k; + + ready2send = 0; + recstat = 0; i = reccnt; + while (!keystatus[1]) + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + refreshaudio(); + + while (totalclock >= lockclock+TICSPERFRAME) + { + sampletimer(); + if (i >= reccnt) + { + prepareboard(boardfilename); + for(i=connecthead;i>=0;i=connectpoint2[i]) + initplayersprite((short)i); + totalclock = 0; + i = 0; + } + + k = 0; + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + copybufbyte(&recsync[i][k],&ffsync[j],sizeof(input)); + k++; + } + movethings(); domovethings(); + i++; + } + drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND))); + + if (keystatus[keys[15]]) + { + keystatus[keys[15]] = 0; + screenpeek = connectpoint2[screenpeek]; + if (screenpeek < 0) screenpeek = connecthead; + drawstatusbar(screenpeek); // Andy did this + } + if (keystatus[keys[14]]) + { + keystatus[keys[14]] = 0; + dimensionmode[screenpeek]++; + if (dimensionmode[screenpeek] > 3) dimensionmode[screenpeek] = 1; + } + } + + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); +} + +void setup3dscreen(void) +{ + long i, dax, day, dax2, day2; + + i = setgamemode(fullscreen,xdimgame,ydimgame,bppgame); + if (i < 0) + { + printf("Error setting video mode.\n"); + sendlogoff(); + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + + //Make that ugly pink into black in case it ever shows up! + i = 0L; + setpalette(255,1,(char *)&i); + //outp(0x3c8,255); outp(0x3c9,0); outp(0x3c9,0); outp(0x3c9,0); + + screensize = xdim; + if (screensize > xdim) + { + dax = 0; day = 0; + dax2 = xdim-1; day2 = ydim-1; + } + else + { + dax = ((xdim-screensize)>>1); + dax2 = dax+screensize-1; + day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + day2 = day + scale(screensize,ydim-32,xdim)-1; + setview(dax,day,dax2,day2); + } + + flushperms(); + + if (screensize < xdim) + drawtilebackground(0L,0L,BACKGROUND,8,0L,0L,xdim-1L,ydim-1L,0); //Draw background + + if (screensize <= xdim) + { + rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1); + while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1)+320; + while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; + if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; + + drawstatusbar(screenpeek); // Andy did this + } +} + +void findrandomspot(long *x, long *y, short *sectnum) +{ + short startwall, endwall, s, dasector; + long dax, day, daz, minx, maxx, miny, maxy, cnt; + + for(cnt=256;cnt>=0;cnt--) + { + do + { + dasector = mulscale16(krand(),numsectors); + } while ((sector[dasector].ceilingz+(8<<8) >= sector[dasector].floorz) || ((sector[dasector].lotag|sector[dasector].hitag) != 0) || ((sector[dasector].floorstat&1) != 0)); + + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + if (endwall <= startwall) continue; + + dax = 0L; + day = 0L; + minx = 0x7fffffff; maxx = 0x80000000; + miny = 0x7fffffff; maxy = 0x80000000; + + for(s=startwall;s maxx) maxx = wall[s].x; + if (wall[s].y < miny) miny = wall[s].y; + if (wall[s].y > maxy) maxy = wall[s].y; + } + + if ((maxx-minx <= 256) || (maxy-miny <= 256)) continue; + + dax /= (endwall-startwall); + day /= (endwall-startwall); + + if (inside(dax,day,dasector) == 0) continue; + + daz = sector[dasector].floorz-(32<<8); + if (pushmove(&dax,&day,&daz,&dasector,128L,4<<8,4<<8,CLIPMASK0) < 0) continue; + + *x = dax; *y = day; *sectnum = dasector; + return; + } +} + +void warp(long *x, long *y, long *z, short *daang, short *dasector) +{ + short startwall, endwall, s; + long i, j, dax, day, ox, oy; + + ox = *x; oy = *y; + + for(i=0;i= warpsectorcnt) i = 0; + } while (sector[warpsectorlist[i]].hitag != j); + *dasector = warpsectorlist[i]; + break; + } + + //Find center of sector + startwall = sector[*dasector].wallptr; + endwall = startwall+sector[*dasector].wallnum; + dax = 0L, day = 0L; + for(s=startwall;s= 0) + i = s; + } + *x = dax / (endwall-startwall); + *y = day / (endwall-startwall); + *z = sector[*dasector].floorz-(32<<8); + updatesector(*x,*y,dasector); + dax = ((wall[i].x+wall[wall[i].point2].x)>>1); + day = ((wall[i].y+wall[wall[i].point2].y)>>1); + *daang = getangle(dax-*x,day-*y); + + wsayfollow("warp.wav",3072L+(krand()&127)-64,192L,&ox,&oy,0); + wsayfollow("warp.wav",4096L+(krand()&127)-64,256L,x,y,0); +} + +void warpsprite(short spritenum) +{ + short dasectnum; + + dasectnum = sprite[spritenum].sectnum; + warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z, + &sprite[spritenum].ang,&dasectnum); + + copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3); + changespritesect(spritenum,dasectnum); + + show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7)); + if (show2dsector[dasectnum>>3]&(1<<(dasectnum&7))) + show2dsprite[spritenum>>3] |= (1<<(spritenum&7)); +} + +void initlava(void) +{ + long x, y, z, r; + + for(z=0;z<32;z++) lavaradcnt[z] = 0; + for(x=-16;x<=16;x++) + for(y=-16;y<=16;y++) + { + r = ksqrt(x*x + y*y); + lavaradx[r][lavaradcnt[r]] = x; + lavarady[r][lavaradcnt[r]] = y; + lavaradcnt[r]++; + } + + for(z=0;z<16;z++) + lavadropsizlookup[z] = 8 / (ksqrt(z)+1); + + for(z=0;z>4)&7)-4)+12; + + lavanumdrops = 0; + lavanumframes = 0; +} + +#if defined(NOASM) +inline long addlava(long bx) +{ + char *b = (char *)bx; + return b[-133] + b[-132] + b[-131] + b[1] + b[-1] + b[131] + b[132]; +} +#elif defined(__WATCOMC__) +#pragma aux addlava =\ + "mov al, byte ptr [ebx-133]",\ + "mov dl, byte ptr [ebx-1]",\ + "add al, byte ptr [ebx-132]",\ + "add dl, byte ptr [ebx+131]",\ + "add al, byte ptr [ebx-131]",\ + "add dl, byte ptr [ebx+132]",\ + "add al, byte ptr [ebx+1]",\ + "add al, dl",\ + parm [ebx]\ + modify exact [eax edx] +long addlava(long); +#elif defined(_MSC_VER) +inline long addlava(long b) +{ + _asm { + mov ebx, b + mov al, byte ptr [ebx-133] + mov dl, byte ptr [ebx-1] + add al, byte ptr [ebx-132] + add dl, byte ptr [ebx+131] + add al, byte ptr [ebx-131] + add dl, byte ptr [ebx+132] + add al, byte ptr [ebx+1] + add al, dl + } +} +#elif defined(__GNUC__) && defined(__i386__) +inline long addlava(long b) +{ + long r; + __asm__ __volatile__ ( + "movb -133(%%ebx), %%al\n\t" + "movb -1(%%ebx), %%dl\n\t" + "addb -132(%%ebx), %%al\n\t" + "addb 131(%%ebx), %%dl\n\t" + "addb -131(%%ebx), %%al\n\t" + "addb 132(%%ebx), %%dl\n\t" + "addb 1(%%ebx), %%al\n\t" + "addb %%dl, %%al" + : "=a" (r) : "b" (b) + : "dx" + ); + return r; +} +#else +#error Unsupported compiler or architecture +#endif + +void movelava(char *dapic) +{ + long i, j, x, y, z, zz, dalavadropsiz, dadropsizlookup; + long dalavax, dalavay, *ptr, *ptr2; + + for(z=min(LAVAMAXDROPS-lavanumdrops-1,3);z>=0;z--) + { + lavadropx[lavanumdrops] = (Brand()&(LAVASIZ-1)); + lavadropy[lavanumdrops] = (Brand()&(LAVASIZ-1)); + lavadropsiz[lavanumdrops] = 1; + lavanumdrops++; + } + + for(z=lavanumdrops-1;z>=0;z--) + { + dadropsizlookup = lavadropsizlookup[lavadropsiz[z]]*(((z&1)<<1)-1); + dalavadropsiz = lavadropsiz[z]; + dalavax = lavadropx[z]; dalavay = lavadropy[z]; + for(zz=lavaradcnt[lavadropsiz[z]]-1;zz>=0;zz--) + { + i = (((lavaradx[dalavadropsiz][zz]+dalavax)&(LAVASIZ-1))< 10) + { + lavanumdrops--; + lavadropx[z] = lavadropx[lavanumdrops]; + lavadropy[z] = lavadropy[lavanumdrops]; + lavadropsiz[z] = lavadropsiz[lavanumdrops]; + } + } + + //Back up dapic with 1 pixel extra on each boundary + //(to prevent anding for wrap-around) + ptr = (long *)dapic; + ptr2 = (long *)((LAVASIZ+4)+1+((long)lavabakpic)); + for(x=0;x>2);y>0;y--) *ptr2++ = ((*ptr++)&0x1f1f1f1f); + ptr2++; + } + for(y=0;y>3)+ + ((addlava(y+1)&0xf8)<<5)+ + ((addlava(y+2)&0xf8)<<13)+ + ((addlava(y+3)&0xf8)<<21)+ + 0xc2c2c2c2; + } + } + + lavanumframes++; +} + +void doanimations(void) +{ + long i, j; + + for(i=animatecnt-1;i>=0;i--) + { + j = *animateptr[i]; + + if (j < animategoal[i]) + j = min(j+animatevel[i]*TICSPERFRAME,animategoal[i]); + else + j = max(j-animatevel[i]*TICSPERFRAME,animategoal[i]); + animatevel[i] += animateacc[i]; + + *animateptr[i] = j; + + if (j == animategoal[i]) + { + animatecnt--; + if (i != animatecnt) + { + stopinterpolation(animateptr[i]); + animateptr[i] = animateptr[animatecnt]; + animategoal[i] = animategoal[animatecnt]; + animatevel[i] = animatevel[animatecnt]; + animateacc[i] = animateacc[animatecnt]; + } + } + } +} + +long getanimationgoal(long animptr) +{ + long i; + + for(i=animatecnt-1;i>=0;i--) + if ((long *)animptr == animateptr[i]) return(i); + return(-1); +} + +long setanimation(long *animptr, long thegoal, long thevel, long theacc) +{ + long i, j; + + if (animatecnt >= MAXANIMATES) return(-1); + + j = animatecnt; + for(i=animatecnt-1;i>=0;i--) + if (animptr == animateptr[i]) + { j = i; break; } + + setinterpolation(animptr); + + animateptr[j] = animptr; + animategoal[j] = thegoal; + animatevel[j] = thevel; + animateacc[j] = theacc; + if (j == animatecnt) animatecnt++; + return(j); +} + +void checkmasterslaveswitch(void) +{ + long i, j; + + if (option[4] == 0) return; + + j = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (ssync[i].bits&512) j++; + if (j != 1) return; + + i = connecthead; + for(j=connectpoint2[i];j>=0;j=connectpoint2[j]) + { + if (ssync[j].bits&512) + { + connectpoint2[i] = connectpoint2[j]; + connectpoint2[j] = connecthead; + connecthead = (short)j; + + oloc.fvel = loc.fvel+1; + oloc.svel = loc.svel+1; + oloc.avel = loc.avel+1; + oloc.bits = loc.bits+1; + for(i=0;i=0;i=connectpoint2[i]) + { + if (myconnectindex == i) break; + j++; + } + if (j == 1) + Bstrcpy(getmessage,"Player 1 (Master)"); + else + Bsprintf(getmessage,"Player %ld (Slave)",j); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+120; + + return; + } + i = j; + } +} + + +long testneighborsectors(short sect1, short sect2) +{ + short i, startwall, num1, num2; + + num1 = sector[sect1].wallnum; + num2 = sector[sect2].wallnum; + if (num1 < num2) //Traverse walls of sector with fewest walls (for speed) + { + startwall = sector[sect1].wallptr; + for(i=num1-1;i>=0;i--) + if (wall[i+startwall].nextsector == sect2) + return(1); + } + else + { + startwall = sector[sect2].wallptr; + for(i=num2-1;i>=0;i--) + if (wall[i+startwall].nextsector == sect1) + return(1); + } + return(0); +} + +long loadgame(void) +{ + long i; + long fil; + + if ((fil = kopen4load("save0000.gam",0)) == -1) return(-1); + + kdfread(&numplayers,4,1,fil); + kdfread(&myconnectindex,4,1,fil); + kdfread(&connecthead,4,1,fil); + kdfread(connectpoint2,4,MAXPLAYERS,fil); + + //Make sure palookups get set, sprites will get overwritten later + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + kdfread(posx,4,MAXPLAYERS,fil); + kdfread(posy,4,MAXPLAYERS,fil); + kdfread(posz,4,MAXPLAYERS,fil); + kdfread(horiz,4,MAXPLAYERS,fil); + kdfread(zoom,4,MAXPLAYERS,fil); + kdfread(hvel,4,MAXPLAYERS,fil); + kdfread(ang,2,MAXPLAYERS,fil); + kdfread(cursectnum,2,MAXPLAYERS,fil); + kdfread(ocursectnum,2,MAXPLAYERS,fil); + kdfread(playersprite,2,MAXPLAYERS,fil); + kdfread(deaths,2,MAXPLAYERS,fil); + kdfread(lastchaingun,4,MAXPLAYERS,fil); + kdfread(health,4,MAXPLAYERS,fil); + kdfread(numgrabbers,2,MAXPLAYERS,fil); + kdfread(nummissiles,2,MAXPLAYERS,fil); + kdfread(numbombs,2,MAXPLAYERS,fil); + kdfread(flytime,4,MAXPLAYERS,fil); + kdfread(oflags,2,MAXPLAYERS,fil); + kdfread(dimensionmode,1,MAXPLAYERS,fil); + kdfread(revolvedoorstat,1,MAXPLAYERS,fil); + kdfread(revolvedoorang,2,MAXPLAYERS,fil); + kdfread(revolvedoorrotang,2,MAXPLAYERS,fil); + kdfread(revolvedoorx,4,MAXPLAYERS,fil); + kdfread(revolvedoory,4,MAXPLAYERS,fil); + + kdfread(&numsectors,2,1,fil); + kdfread(sector,sizeof(sectortype),numsectors,fil); + kdfread(&numwalls,2,1,fil); + kdfread(wall,sizeof(walltype),numwalls,fil); + //Store all sprites (even holes) to preserve indeces + kdfread(sprite,sizeof(spritetype),MAXSPRITES,fil); + kdfread(headspritesect,2,MAXSECTORS+1,fil); + kdfread(prevspritesect,2,MAXSPRITES,fil); + kdfread(nextspritesect,2,MAXSPRITES,fil); + kdfread(headspritestat,2,MAXSTATUS+1,fil); + kdfread(prevspritestat,2,MAXSPRITES,fil); + kdfread(nextspritestat,2,MAXSPRITES,fil); + + kdfread(&fvel,4,1,fil); + kdfread(&svel,4,1,fil); + kdfread(&avel,4,1,fil); + + kdfread(&locselectedgun,4,1,fil); + kdfread(&loc.fvel,1,1,fil); + kdfread(&oloc.fvel,1,1,fil); + kdfread(&loc.svel,1,1,fil); + kdfread(&oloc.svel,1,1,fil); + kdfread(&loc.avel,1,1,fil); + kdfread(&oloc.avel,1,1,fil); + kdfread(&loc.bits,2,1,fil); + kdfread(&oloc.bits,2,1,fil); + + kdfread(&locselectedgun2,4,1,fil); + kdfread(&loc2.fvel,sizeof(input),1,fil); + + kdfread(ssync,sizeof(input),MAXPLAYERS,fil); + kdfread(osync,sizeof(input),MAXPLAYERS,fil); + + kdfread(boardfilename,1,80,fil); + kdfread(&screenpeek,2,1,fil); + kdfread(&oldmousebstatus,2,1,fil); + kdfread(&brightness,2,1,fil); + kdfread(&neartagsector,2,1,fil); + kdfread(&neartagwall,2,1,fil); + kdfread(&neartagsprite,2,1,fil); + kdfread(&lockclock,4,1,fil); + kdfread(&neartagdist,4,1,fil); + kdfread(&neartaghitdist,4,1,fil); + + kdfread(turnspritelist,2,16,fil); + kdfread(&turnspritecnt,2,1,fil); + kdfread(warpsectorlist,2,16,fil); + kdfread(&warpsectorcnt,2,1,fil); + kdfread(xpanningsectorlist,2,16,fil); + kdfread(&xpanningsectorcnt,2,1,fil); + kdfread(ypanningwalllist,2,64,fil); + kdfread(&ypanningwallcnt,2,1,fil); + kdfread(floorpanninglist,2,64,fil); + kdfread(&floorpanningcnt,2,1,fil); + kdfread(dragsectorlist,2,16,fil); + kdfread(dragxdir,2,16,fil); + kdfread(dragydir,2,16,fil); + kdfread(&dragsectorcnt,2,1,fil); + kdfread(dragx1,4,16,fil); + kdfread(dragy1,4,16,fil); + kdfread(dragx2,4,16,fil); + kdfread(dragy2,4,16,fil); + kdfread(dragfloorz,4,16,fil); + kdfread(&swingcnt,2,1,fil); + kdfread(swingwall,2,32*5,fil); + kdfread(swingsector,2,32,fil); + kdfread(swingangopen,2,32,fil); + kdfread(swingangclosed,2,32,fil); + kdfread(swingangopendir,2,32,fil); + kdfread(swingang,2,32,fil); + kdfread(swinganginc,2,32,fil); + kdfread(swingx,4,32*8,fil); + kdfread(swingy,4,32*8,fil); + kdfread(revolvesector,2,4,fil); + kdfread(revolveang,2,4,fil); + kdfread(&revolvecnt,2,1,fil); + kdfread(revolvex,4,4*16,fil); + kdfread(revolvey,4,4*16,fil); + kdfread(revolvepivotx,4,4,fil); + kdfread(revolvepivoty,4,4,fil); + kdfread(subwaytracksector,2,4*128,fil); + kdfread(subwaynumsectors,2,4,fil); + kdfread(&subwaytrackcnt,2,1,fil); + kdfread(subwaystop,4,4*8,fil); + kdfread(subwaystopcnt,4,4,fil); + kdfread(subwaytrackx1,4,4,fil); + kdfread(subwaytracky1,4,4,fil); + kdfread(subwaytrackx2,4,4,fil); + kdfread(subwaytracky2,4,4,fil); + kdfread(subwayx,4,4,fil); + kdfread(subwaygoalstop,4,4,fil); + kdfread(subwayvel,4,4,fil); + kdfread(subwaypausetime,4,4,fil); + kdfread(waterfountainwall,2,MAXPLAYERS,fil); + kdfread(waterfountaincnt,2,MAXPLAYERS,fil); + kdfread(slimesoundcnt,2,MAXPLAYERS,fil); + + //Warning: only works if all pointers are in sector structures! + kdfread(animateptr,4,MAXANIMATES,fil); + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]+((long)sector)); + + kdfread(animategoal,4,MAXANIMATES,fil); + kdfread(animatevel,4,MAXANIMATES,fil); + kdfread(animateacc,4,MAXANIMATES,fil); + kdfread(&animatecnt,4,1,fil); + + kdfread(&totalclock,4,1,fil); + kdfread(&numframes,4,1,fil); + kdfread(&randomseed,4,1,fil); + kdfread(&numpalookups,2,1,fil); + + kdfread(&visibility,4,1,fil); + kdfread(¶llaxvisibility,4,1,fil); + kdfread(¶llaxtype,1,1,fil); + kdfread(¶llaxyoffs,4,1,fil); + kdfread(pskyoff,2,MAXPSKYTILES,fil); + kdfread(&pskybits,2,1,fil); + + kdfread(&mirrorcnt,2,1,fil); + kdfread(mirrorwall,2,mirrorcnt,fil); + kdfread(mirrorsector,2,mirrorcnt,fil); + + //I should save off interpolation list, but they're pointers :( + numinterpolations = 0; + startofdynamicinterpolations = 0; + + kclose(fil); + + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + totalclock = lockclock; + ototalclock = lockclock; + + Bstrcpy(getmessage,"Game loaded."); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + return(0); +} + +long savegame(void) +{ + long i; + BFILE *fil; + + if ((fil = Bfopen("save0000.gam","wb")) == 0) return(-1); + + dfwrite(&numplayers,4,1,fil); + dfwrite(&myconnectindex,4,1,fil); + dfwrite(&connecthead,4,1,fil); + dfwrite(connectpoint2,4,MAXPLAYERS,fil); + + dfwrite(posx,4,MAXPLAYERS,fil); + dfwrite(posy,4,MAXPLAYERS,fil); + dfwrite(posz,4,MAXPLAYERS,fil); + dfwrite(horiz,4,MAXPLAYERS,fil); + dfwrite(zoom,4,MAXPLAYERS,fil); + dfwrite(hvel,4,MAXPLAYERS,fil); + dfwrite(ang,2,MAXPLAYERS,fil); + dfwrite(cursectnum,2,MAXPLAYERS,fil); + dfwrite(ocursectnum,2,MAXPLAYERS,fil); + dfwrite(playersprite,2,MAXPLAYERS,fil); + dfwrite(deaths,2,MAXPLAYERS,fil); + dfwrite(lastchaingun,4,MAXPLAYERS,fil); + dfwrite(health,4,MAXPLAYERS,fil); + dfwrite(numgrabbers,2,MAXPLAYERS,fil); + dfwrite(nummissiles,2,MAXPLAYERS,fil); + dfwrite(numbombs,2,MAXPLAYERS,fil); + dfwrite(flytime,4,MAXPLAYERS,fil); + dfwrite(oflags,2,MAXPLAYERS,fil); + dfwrite(dimensionmode,1,MAXPLAYERS,fil); + dfwrite(revolvedoorstat,1,MAXPLAYERS,fil); + dfwrite(revolvedoorang,2,MAXPLAYERS,fil); + dfwrite(revolvedoorrotang,2,MAXPLAYERS,fil); + dfwrite(revolvedoorx,4,MAXPLAYERS,fil); + dfwrite(revolvedoory,4,MAXPLAYERS,fil); + + dfwrite(&numsectors,2,1,fil); + dfwrite(sector,sizeof(sectortype),numsectors,fil); + dfwrite(&numwalls,2,1,fil); + dfwrite(wall,sizeof(walltype),numwalls,fil); + //Store all sprites (even holes) to preserve indeces + dfwrite(sprite,sizeof(spritetype),MAXSPRITES,fil); + dfwrite(headspritesect,2,MAXSECTORS+1,fil); + dfwrite(prevspritesect,2,MAXSPRITES,fil); + dfwrite(nextspritesect,2,MAXSPRITES,fil); + dfwrite(headspritestat,2,MAXSTATUS+1,fil); + dfwrite(prevspritestat,2,MAXSPRITES,fil); + dfwrite(nextspritestat,2,MAXSPRITES,fil); + + dfwrite(&fvel,4,1,fil); + dfwrite(&svel,4,1,fil); + dfwrite(&avel,4,1,fil); + + dfwrite(&locselectedgun,4,1,fil); + dfwrite(&loc.fvel,1,1,fil); + dfwrite(&oloc.fvel,1,1,fil); + dfwrite(&loc.svel,1,1,fil); + dfwrite(&oloc.svel,1,1,fil); + dfwrite(&loc.avel,1,1,fil); + dfwrite(&oloc.avel,1,1,fil); + dfwrite(&loc.bits,2,1,fil); + dfwrite(&oloc.bits,2,1,fil); + + dfwrite(&locselectedgun2,4,1,fil); + dfwrite(&loc2.fvel,sizeof(input),1,fil); + + dfwrite(ssync,sizeof(input),MAXPLAYERS,fil); + dfwrite(osync,sizeof(input),MAXPLAYERS,fil); + + dfwrite(boardfilename,1,80,fil); + dfwrite(&screenpeek,2,1,fil); + dfwrite(&oldmousebstatus,2,1,fil); + dfwrite(&brightness,2,1,fil); + dfwrite(&neartagsector,2,1,fil); + dfwrite(&neartagwall,2,1,fil); + dfwrite(&neartagsprite,2,1,fil); + dfwrite(&lockclock,4,1,fil); + dfwrite(&neartagdist,4,1,fil); + dfwrite(&neartaghitdist,4,1,fil); + + dfwrite(turnspritelist,2,16,fil); + dfwrite(&turnspritecnt,2,1,fil); + dfwrite(warpsectorlist,2,16,fil); + dfwrite(&warpsectorcnt,2,1,fil); + dfwrite(xpanningsectorlist,2,16,fil); + dfwrite(&xpanningsectorcnt,2,1,fil); + dfwrite(ypanningwalllist,2,64,fil); + dfwrite(&ypanningwallcnt,2,1,fil); + dfwrite(floorpanninglist,2,64,fil); + dfwrite(&floorpanningcnt,2,1,fil); + dfwrite(dragsectorlist,2,16,fil); + dfwrite(dragxdir,2,16,fil); + dfwrite(dragydir,2,16,fil); + dfwrite(&dragsectorcnt,2,1,fil); + dfwrite(dragx1,4,16,fil); + dfwrite(dragy1,4,16,fil); + dfwrite(dragx2,4,16,fil); + dfwrite(dragy2,4,16,fil); + dfwrite(dragfloorz,4,16,fil); + dfwrite(&swingcnt,2,1,fil); + dfwrite(swingwall,2,32*5,fil); + dfwrite(swingsector,2,32,fil); + dfwrite(swingangopen,2,32,fil); + dfwrite(swingangclosed,2,32,fil); + dfwrite(swingangopendir,2,32,fil); + dfwrite(swingang,2,32,fil); + dfwrite(swinganginc,2,32,fil); + dfwrite(swingx,4,32*8,fil); + dfwrite(swingy,4,32*8,fil); + dfwrite(revolvesector,2,4,fil); + dfwrite(revolveang,2,4,fil); + dfwrite(&revolvecnt,2,1,fil); + dfwrite(revolvex,4,4*16,fil); + dfwrite(revolvey,4,4*16,fil); + dfwrite(revolvepivotx,4,4,fil); + dfwrite(revolvepivoty,4,4,fil); + dfwrite(subwaytracksector,2,4*128,fil); + dfwrite(subwaynumsectors,2,4,fil); + dfwrite(&subwaytrackcnt,2,1,fil); + dfwrite(subwaystop,4,4*8,fil); + dfwrite(subwaystopcnt,4,4,fil); + dfwrite(subwaytrackx1,4,4,fil); + dfwrite(subwaytracky1,4,4,fil); + dfwrite(subwaytrackx2,4,4,fil); + dfwrite(subwaytracky2,4,4,fil); + dfwrite(subwayx,4,4,fil); + dfwrite(subwaygoalstop,4,4,fil); + dfwrite(subwayvel,4,4,fil); + dfwrite(subwaypausetime,4,4,fil); + dfwrite(waterfountainwall,2,MAXPLAYERS,fil); + dfwrite(waterfountaincnt,2,MAXPLAYERS,fil); + dfwrite(slimesoundcnt,2,MAXPLAYERS,fil); + + //Warning: only works if all pointers are in sector structures! + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]-((long)sector)); + dfwrite(animateptr,4,MAXANIMATES,fil); + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]+((long)sector)); + + dfwrite(animategoal,4,MAXANIMATES,fil); + dfwrite(animatevel,4,MAXANIMATES,fil); + dfwrite(animateacc,4,MAXANIMATES,fil); + dfwrite(&animatecnt,4,1,fil); + + dfwrite(&totalclock,4,1,fil); + dfwrite(&numframes,4,1,fil); + dfwrite(&randomseed,4,1,fil); + dfwrite(&numpalookups,2,1,fil); + + dfwrite(&visibility,4,1,fil); + dfwrite(¶llaxvisibility,4,1,fil); + dfwrite(¶llaxtype,1,1,fil); + dfwrite(¶llaxyoffs,4,1,fil); + dfwrite(pskyoff,2,MAXPSKYTILES,fil); + dfwrite(&pskybits,2,1,fil); + + dfwrite(&mirrorcnt,2,1,fil); + dfwrite(mirrorwall,2,mirrorcnt,fil); + dfwrite(mirrorsector,2,mirrorcnt,fil); + + Bfclose(fil); + + Bstrcpy(getmessage,"Game saved."); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + return(0); +} + +void faketimerhandler(void) +{ + short other, packbufleng; + long i, j, k, l; + + sampletimer(); + if ((totalclock < ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) || (ready2send == 0)) return; + ototalclock += (TIMERINTSPERSECOND/MOVESPERSECOND); + + getpackets(); + if (getoutputcirclesize() >= 16) return; + getinput(); + + /* + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + { + k = (movefifoend[myconnectindex]-1)-movefifoend[i]; + myminlag[i] = min(myminlag[i],k); + mymaxlag = max(mymaxlag,k); + } + + if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) + { + i = mymaxlag-bufferjitter; mymaxlag = 0; + if (i > 0) bufferjitter += ((2+i)>>2); + else if (i < 0) bufferjitter -= ((2-i)>>2); + } + */ + + if (networkmode == 1) + { + packbuf[2] = 0; j = 3; + if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[2] |= 1; + if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[2] |= 2; + if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[2] |= 4; + if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[2] |= 8; + if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[2] |= 16; + copybufbyte(&loc,&oloc,sizeof(input)); + + copybufbyte(&loc,&baksync[movefifoend[myconnectindex]][myconnectindex],sizeof(input)); + movefifoend[myconnectindex] = ((movefifoend[myconnectindex]+1)&(MOVEFIFOSIZ-1)); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + { + packbuf[0] = 17; + packbuf[1] = (char)((movefifoend[myconnectindex]-movefifoend[i])&(MOVEFIFOSIZ-1)); + + k = j; + if ((myconnectindex == connecthead) || ((i == connecthead) && (myconnectindex == connectpoint2[connecthead]))) + { + while (syncvalhead != syncvaltail) + { + packbuf[j++] = syncval[syncvaltail]; + syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); + } + } + sendpacket(i,packbuf,j); + j = k; + } + + gotlastpacketclock = totalclock; + return; + } + + //MASTER (or 1 player game) + if ((myconnectindex == connecthead) || (option[4] == 0)) + { + copybufbyte(&loc,&ffsync[myconnectindex],sizeof(input)); + + if (option[4] != 0) + { + packbuf[0] = 0; + j = ((numplayers+1)>>1)+1; + for(k=1;k=0;i=connectpoint2[i]) + { + l = 0; + if (ffsync[i].fvel != osync[i].fvel) packbuf[j++] = ffsync[i].fvel, l |= 1; + if (ffsync[i].svel != osync[i].svel) packbuf[j++] = ffsync[i].svel, l |= 2; + if (ffsync[i].avel != osync[i].avel) packbuf[j++] = ffsync[i].avel, l |= 4; + if (ffsync[i].bits != osync[i].bits) + { + packbuf[j++] = (ffsync[i].bits&255); + packbuf[j++] = ((ffsync[i].bits>>8)&255); + l |= 8; + } + packbuf[k>>3] |= (l<<(k&7)); + k += 4; + + copybufbyte(&ffsync[i],&osync[i],sizeof(input)); + } + + while (syncvalhead != syncvaltail) + { + packbuf[j++] = syncval[syncvaltail]; + syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); + } + + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + sendpacket(i,packbuf,j); + } + else if (numplayers >= 2) + { + if (keystatus[0xb5]) + { + keystatus[0xb5] = 0; + locselectedgun2++; if (locselectedgun2 >= 3) locselectedgun2 = 0; + } + + //Second player on 1 computer mode + loc2.fvel = min(max(fvel2,-128+8),127-8); + loc2.svel = min(max(svel2,-128+8),127-8); + loc2.avel = min(max(avel2,-128+16),127-16); + loc2.bits = (locselectedgun2<<13); + loc2.bits |= keystatus[0x45]; //Stand high + loc2.bits |= (keystatus[0x47]<<1); //Stand low + loc2.bits |= (1<<8); //Run + loc2.bits |= (keystatus[0x49]<<2); //Look up + loc2.bits |= (keystatus[0x37]<<3); //Look down + loc2.bits |= (keystatus[0x50]<<10); //Space + loc2.bits |= (keystatus[0x52]<<11); //Shoot + + other = connectpoint2[myconnectindex]; + if (other < 0) other = connecthead; + + copybufbyte(&loc2,&ffsync[other],sizeof(input)); + } + movethings(); //Move EVERYTHING (you too!) + } + else //I am a SLAVE + { + packbuf[0] = 1; packbuf[1] = 0; j = 2; + if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[1] |= 1; + if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[1] |= 2; + if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[1] |= 4; + if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[1] |= 8; + if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[1] |= 16; + copybufbyte(&loc,&oloc,sizeof(input)); + sendpacket(connecthead,packbuf,j); + } +} + +void getpackets(void) +{ + long i, j, k, l; + long other, packbufleng, movecnt; + + if (option[4] == 0) return; + + movecnt = 0; + while ((packbufleng = getpacket(&other,packbuf)) > 0) + { + switch(packbuf[0]) + { + case 0: //[0] (receive master sync buffer) + j = ((numplayers+1)>>1)+1; k = (1<<3); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + l = (packbuf[k>>3]>>(k&7)); + if (l&1) ffsync[i].fvel = packbuf[j++]; + if (l&2) ffsync[i].svel = packbuf[j++]; + if (l&4) ffsync[i].avel = packbuf[j++]; + if (l&8) + { + ffsync[i].bits = ((short)packbuf[j])+(((short)packbuf[j+1])<<8); + j += 2; + } + k += 4; + } + + while (j != packbufleng) + { + othersyncval[othersyncvalhead] = packbuf[j++]; + othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); + } + if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) + { + syncstat = 0; + do + { + syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); + syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); + } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); + } + + movethings(); //Move all players and sprites + movecnt++; + break; + case 1: //[1] (receive slave sync buffer) + j = 2; k = packbuf[1]; + if (k&1) ffsync[other].fvel = packbuf[j++]; + if (k&2) ffsync[other].svel = packbuf[j++]; + if (k&4) ffsync[other].avel = packbuf[j++]; + if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); + if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); + break; + case 2: + getmessageleng = packbufleng-1; + for(j=getmessageleng-1;j>=0;j--) getmessage[j] = packbuf[j+1]; + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + wsay("getstuff.wav",8192L,63L,63L); //Added 12/2004 + break; + case 3: + wsay("getstuff.wav",4096L,63L,63L); + break; + /* + case 5: + playerreadyflag[other] = packbuf[1]; + if ((other == connecthead) && (packbuf[1] == 2)) + sendpacket(connecthead,packbuf,2); + break; + */ + case 250: + playerreadyflag[other]++; + break; + case 17: + j = 3; k = packbuf[2]; + if (k&1) ffsync[other].fvel = packbuf[j++]; + if (k&2) ffsync[other].svel = packbuf[j++]; + if (k&4) ffsync[other].avel = packbuf[j++]; + if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); + if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); + otherlag[other] = packbuf[1]; + + copybufbyte(&ffsync[other],&baksync[movefifoend[other]][other],sizeof(input)); + movefifoend[other] = ((movefifoend[other]+1)&(MOVEFIFOSIZ-1)); + + while (j != packbufleng) + { + othersyncval[othersyncvalhead] = packbuf[j++]; + othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); + } + if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) + { + syncstat = 0; + do + { + syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); + syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); + } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); + } + + break; + case 255: //[255] (logout) + keystatus[1] = 1; + break; + } + } + if ((networkmode == 0) && (myconnectindex != connecthead) && ((movecnt&1) == 0)) + { + if (rand()&1) ototalclock += (TICSPERFRAME>>1); + else ototalclock -= (TICSPERFRAME>>1); + } +} + +void drawoverheadmap(long cposx, long cposy, long czoom, short cang) +{ + long i, j, k, l=0, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; + long dax, day, cosang, sinang, xspan, yspan, sprx, spry; + long xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; + long xvect, yvect, xvect2, yvect2; + char col; + walltype *wal, *wal2; + spritetype *spr; + + xvect = sintable[(-cang)&2047] * czoom; + yvect = sintable[(1536-cang)&2047] * czoom; + xvect2 = mulscale16(xvect,yxaspect); + yvect2 = mulscale16(yvect,yxaspect); + + //Draw red lines + for(i=0;inextwall; if (k < 0) continue; + + if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue; + + if (sector[wal->nextsector].ceilingz == z1) + if (sector[wal->nextsector].floorz == z2) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; + + col = 152; + + if (dimensionmode[screenpeek] == 2) + { + if (sector[i].floorz != sector[i].ceilingz) + if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) + if (sector[i].floorz == sector[wal->nextsector].floorz) continue; + if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue; + if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue; + col = 12; + } + + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + wal2 = &wall[wal->point2]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,col); + } + } + + //Draw sprites + k = playersprite[screenpeek]; + for(i=0;i=0;j=nextspritesect[j]) + if ((show2dsprite[j>>3]&(1<<(j&7))) > 0) + { + spr = &sprite[j]; if (spr->cstat&0x8000) continue; + col = 56; + if (spr->cstat&1) col = 248; + if (j == k) col = 31; + + k = statrate[spr->statnum]; + sprx = spr->x; + spry = spr->y; + if (k >= 0) + { + switch(k) + { + case 0: l = smoothratio; break; + case 1: l = (smoothratio>>1)+(((nummoves-j)&1)<<15); break; + case 3: l = (smoothratio>>2)+(((nummoves-j)&3)<<14); break; + case 7: l = (smoothratio>>3)+(((nummoves-j)&7)<<13); break; + case 15: l = (smoothratio>>4)+(((nummoves-j)&15)<<12); break; + } + sprx = osprite[j].x+mulscale16(sprx-osprite[j].x,l); + spry = osprite[j].y+mulscale16(spry-osprite[j].y,l); + } + + switch (spr->cstat&48) + { + case 0: + ox = sprx-cposx; oy = spry-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + if (dimensionmode[screenpeek] == 1) + { + ox = (sintable[(spr->ang+512)&2047]>>7); + oy = (sintable[(spr->ang)&2047]>>7); + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect,ox,yvect); + + if (j == playersprite[screenpeek]) + { + x2 = 0L; + y2 = -(czoom<<5); + } + + x3 = mulscale16(x2,yxaspect); + y3 = mulscale16(y2,yxaspect); + + drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + } + else + { + if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 96)) + { + daang = (spr->ang-cang)&2047; + if (j == playersprite[screenpeek]) { x1 = 0; y1 = 0; daang = 0; } + rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale16(czoom*spr->yrepeat,yxaspect),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1,windowx1,windowy1,windowx2,windowy2); + } + } + break; + case 16: + x1 = sprx; y1 = spry; + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + + break; + case 32: + if (dimensionmode[screenpeek] == 1) + { + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + if ((spr->cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; sinang = sintable[k]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + x1 = sprx + dmulscale16(sinang,dax,cosang,day); + y1 = spry + dmulscale16(sinang,day,-cosang,dax); + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang,l); + y2 = y1 + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; + k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x3-cposx; oy = y3-cposy; + x3 = dmulscale16(ox,xvect,-oy,yvect); + y3 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x4-cposx; oy = y4-cposy; + x4 = dmulscale16(ox,xvect,-oy,yvect); + y4 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + + drawline256(x2+(xdim<<11),y2+(ydim<<11), + x3+(xdim<<11),y3+(ydim<<11),col); + + drawline256(x3+(xdim<<11),y3+(ydim<<11), + x4+(xdim<<11),y4+(ydim<<11),col); + + drawline256(x4+(xdim<<11),y4+(ydim<<11), + x1+(xdim<<11),y1+(ydim<<11),col); + + } + break; + } + } + + //Draw white lines + for(i=0;inextwall >= 0) continue; + + if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + + if (tilesizx[wal->picnum] == 0) continue; + if (tilesizy[wal->picnum] == 0) continue; + + if (j == k) + { x1 = x2; y1 = y2; } + else + { + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + } + + k = wal->point2; wal2 = &wall[k]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,24); + } + } +} + + //New movesprite using getzrange. Note that I made the getzrange + //parameters global (&globhiz,&globhihit,&globloz,&globlohit) so they + //don't need to be passed everywhere. Also this should make this + //movesprite function compatible with the older movesprite functions. +long movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, long clipmask) +{ + long daz, zoffs, tempint; + short retval, dasectnum, datempshort; + spritetype *spr; + + spr = &sprite[spritenum]; + + if ((spr->cstat&128) == 0) + zoffs = -((tilesizy[spr->picnum]*spr->yrepeat)<<1); + else + zoffs = 0; + + dasectnum = spr->sectnum; //Can't modify sprite sectors directly becuase of linked lists + daz = spr->z+zoffs; //Must do this if not using the new centered centering (of course) + retval = clipmove(&spr->x,&spr->y,&daz,&dasectnum,dx,dy, + ((long)spr->clipdist)<<2,ceildist,flordist,clipmask); + + if (dasectnum < 0) retval = -1; + + if ((dasectnum != spr->sectnum) && (dasectnum >= 0)) + changespritesect(spritenum,dasectnum); + + //Set the blocking bit to 0 temporarly so getzrange doesn't pick up + //its own sprite + datempshort = spr->cstat; spr->cstat &= ~1; + getzrange(spr->x,spr->y,spr->z-1,spr->sectnum, + &globhiz,&globhihit,&globloz,&globlohit, + ((long)spr->clipdist)<<2,clipmask); + spr->cstat = datempshort; + + daz = spr->z+zoffs + dz; + if ((daz <= globhiz) || (daz > globloz)) + { + if (retval != 0) return(retval); + return(16384+dasectnum); + } + spr->z = daz-zoffs; + return(retval); +} + + +void waitforeverybody () +{ + long i; + if (numplayers < 2) return; + packbuf[0] = 250; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) sendpacket(i,packbuf,1); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + playerreadyflag[myconnectindex]++; + while (1) + { + handleevents(); + refreshaudio(); + + drawrooms(posx[myconnectindex],posy[myconnectindex],posz[myconnectindex],ang[myconnectindex],horiz[myconnectindex],cursectnum[myconnectindex]); + if (!networkmode) Bsprintf(tempbuf,"Master/slave mode"); + else Bsprintf(tempbuf,"Peer-peer mode"); + printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-24,31,0,tempbuf,0); + Bsprintf(tempbuf,"Waiting for players"); + printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-16,31,0,tempbuf,0); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerreadyflag[i] < playerreadyflag[myconnectindex]) + { + //slaves in M/S mode only wait for master + if ((!networkmode) && (myconnectindex != connecthead) && (i != connecthead)) + { + Bsprintf(tempbuf,"Player %ld",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,15,0,tempbuf,0); + } + else + { + Bsprintf(tempbuf,"Player %ld NOT ready",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,127,0,tempbuf,0); + } + } + else + { + Bsprintf(tempbuf,"Player %ld ready",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,31,0,tempbuf,0); + } + if (i == myconnectindex) + { + Bsprintf(tempbuf,"You->"); + printext256((xdim>>1)-(26<<2),(ydim>>1)+i*8,95,0,tempbuf,0); + } + } + nextpage(); + + + if (quitevent || keystatus[1]) { + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + + getpackets(); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerreadyflag[i] < playerreadyflag[myconnectindex]) break; + if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master + } + if (i < 0) return; + } +} + + +void searchmap(short startsector) +{ + long i, j, dasect, splc, send, startwall, endwall; + short dapic; + walltype *wal; + + if ((startsector < 0) || (startsector >= numsectors)) return; + for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0; + for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0; + for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0; + + automapping = 0; + + //Search your area recursively & set all show2dsector/show2dwalls + tempshort[0] = startsector; + show2dsector[startsector>>3] |= (1<<(startsector&7)); + dapic = sector[startsector].ceilingpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = sector[startsector].floorpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + for(splc=0,send=1;splc>3] |= (1<<(i&7)); + dapic = wall[i].picnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = wall[i].overpicnum; + if (((dapic&0xfffff000) == 0) && (waloff[dapic] == 0)) loadtile(dapic); + + j = wal->nextsector; + if ((j >= 0) && ((show2dsector[j>>3]&(1<<(j&7))) == 0)) + { + show2dsector[j>>3] |= (1<<(j&7)); + + dapic = sector[j].ceilingpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = sector[j].floorpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + + tempshort[send++] = (short)j; + } + } + + for(i=headspritesect[dasect];i>=0;i=nextspritesect[i]) + { + show2dsprite[i>>3] |= (1<<(i&7)); + dapic = sprite[i].picnum; + if (waloff[dapic] == 0) loadtile(dapic); + } + } +} + +void setinterpolation(long *posptr) +{ + long i; + + if (numinterpolations >= MAXINTERPOLATIONS) return; + for(i=numinterpolations-1;i>=0;i--) + if (curipos[i] == posptr) return; + curipos[numinterpolations] = posptr; + oldipos[numinterpolations] = *posptr; + numinterpolations++; +} + +void stopinterpolation(long *posptr) +{ + long i; + + for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--) + if (curipos[i] == posptr) + { + numinterpolations--; + oldipos[i] = oldipos[numinterpolations]; + bakipos[i] = bakipos[numinterpolations]; + curipos[i] = curipos[numinterpolations]; + } +} + +void updateinterpolations(void) //Stick at beginning of domovethings +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i]; +} + +void dointerpolations(void) //Stick at beginning of drawscreen +{ + long i, j, odelta, ndelta; + + ndelta = 0; j = 0; + for(i=numinterpolations-1;i>=0;i--) + { + bakipos[i] = *curipos[i]; + odelta = ndelta; ndelta = (*curipos[i])-oldipos[i]; + if (odelta != ndelta) j = mulscale16(ndelta,smoothratio); + *curipos[i] = oldipos[i]+j; + } +} + +void restoreinterpolations(void) //Stick at end of drawscreen +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i]; +} + +void printext(long x, long y, char *buffer, short tilenum, char invisiblecol) +{ + long i; + char ch; + + for(i=0;buffer[i]!=0;i++) + { + ch = buffer[i]; + rotatesprite((x-((8&15)<<3))<<16,(y-((8>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+64+128,x,y,x+7,y+7); + rotatesprite((x-((ch&15)<<3))<<16,(y-((ch>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+128,x,y,x+7,y+7); + x += 8; + } +} + +void drawtilebackground (long thex, long they, short tilenum, + signed char shade, long cx1, long cy1, + long cx2, long cy2, char dapalnum) +{ + long x, y, xsiz, ysiz, tx1, ty1, tx2, ty2; + + xsiz = tilesizx[tilenum]; tx1 = cx1/xsiz; tx2 = cx2/xsiz; + ysiz = tilesizy[tilenum]; ty1 = cy1/ysiz; ty2 = cy2/ysiz; + + for(x=tx1;x<=tx2;x++) + for(y=ty1;y<=ty2;y++) + rotatesprite(x*xsiz<<16,y*ysiz<<16,65536L,0,tilenum,shade,dapalnum,8+16+64+128,cx1,cy1,cx2,cy2); +} + + +/* + * vim:ts=4:sw=4: + */ diff --git a/polymer/build/src/gamestartwin.c b/polymer/build/src/gamestartwin.c new file mode 100644 index 000000000..f210933fd --- /dev/null +++ b/polymer/build/src/gamestartwin.c @@ -0,0 +1,144 @@ +#ifndef RENDERTYPEWIN +#error Only for Windows +#endif + +#include "build.h" +#include "editor.h" +#include "winlayer.h" +#include "compat.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + + +#define IDCFULLSCREEN 100 +#define IDCVMODE 101 + +static void PopulateVideoModeLists(int fs, HWND list3d) +{ + int i,j; + char buf[64]; + + ComboBox_ResetContent(list3d); + for (i=0; i 0) { + if (!IsWindow(hwndLaunch) || quitevent) break; + if (IsDialogMessage(hwndStart, &msg) /*|| IsDialogMessage(hwndLaunch, &msg)*/) continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + EnableWindow(GetDlgItem(hwndStart,WIN_STARTWIN_ITEMLIST),TRUE); + } + if (quitevent) return 1; + return 0; +} + diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c new file mode 100644 index 000000000..060c9ace3 --- /dev/null +++ b/polymer/build/src/glbuild.c @@ -0,0 +1,359 @@ +#include "glbuild.h" +#include "baselayer.h" +#include +#include +#include + +#if defined DYNAMIC_OPENGL && defined USE_OPENGL + +#ifdef RENDERTYPESDL +#include "SDL.h" +#endif + +void (APIENTRY * bglClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +void (APIENTRY * bglClear)( GLbitfield mask ); +void (APIENTRY * bglColorMask)( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); +void (APIENTRY * bglAlphaFunc)( GLenum func, GLclampf ref ); +void (APIENTRY * bglBlendFunc)( GLenum sfactor, GLenum dfactor ); +void (APIENTRY * bglCullFace)( GLenum mode ); +void (APIENTRY * bglFrontFace)( GLenum mode ); +void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); +void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); +void (APIENTRY * bglEnable)( GLenum cap ); +void (APIENTRY * bglDisable)( GLenum cap ); +void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); +void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); +void (APIENTRY * bglPushAttrib)( GLbitfield mask ); +void (APIENTRY * bglPopAttrib)( void ); +GLenum (APIENTRY * bglGetError)( void ); +const GLubyte* (APIENTRY * bglGetString)( GLenum name ); +void (APIENTRY * bglHint)( GLenum target, GLenum mode ); + +// Depth +void (APIENTRY * bglDepthFunc)( GLenum func ); +void (APIENTRY * bglDepthMask)( GLboolean flag ); +void (APIENTRY * bglDepthRange)( GLclampd near_val, GLclampd far_val ); + +// Matrix +void (APIENTRY * bglMatrixMode)( GLenum mode ); +void (APIENTRY * bglOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +void (APIENTRY * bglFrustum)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +void (APIENTRY * bglViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); +void (APIENTRY * bglPushMatrix)( void ); +void (APIENTRY * bglPopMatrix)( void ); +void (APIENTRY * bglLoadIdentity)( void ); +void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); + +// Drawing +void (APIENTRY * bglBegin)( GLenum mode ); +void (APIENTRY * bglEnd)( void ); +void (APIENTRY * bglVertex2f)( GLfloat x, GLfloat y ); +void (APIENTRY * bglVertex2i)( GLint x, GLint y ); +void (APIENTRY * bglVertex3d)( GLdouble x, GLdouble y, GLdouble z ); +void (APIENTRY * bglVertex3fv)( const GLfloat *v ); +void (APIENTRY * bglColor4f)( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); +void (APIENTRY * bglColor4ub)( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); +void (APIENTRY * bglTexCoord2d)( GLdouble s, GLdouble t ); +void (APIENTRY * bglTexCoord2f)( GLfloat s, GLfloat t ); + +// Lighting +void (APIENTRY * bglShadeModel)( GLenum mode ); + +// Raster funcs +void (APIENTRY * bglReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); + +// Texture mapping +void (APIENTRY * bglTexEnvf)( GLenum target, GLenum pname, GLfloat param ); +void (APIENTRY * bglGenTextures)( GLsizei n, GLuint *textures ); // 1.1 +void (APIENTRY * bglDeleteTextures)( GLsizei n, const GLuint *textures); // 1.1 +void (APIENTRY * bglBindTexture)( GLenum target, GLuint texture ); // 1.1 +void (APIENTRY * bglTexImage2D)( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); +void (APIENTRY * bglTexSubImage2D)( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); // 1.1 +void (APIENTRY * bglTexParameterf)( GLenum target, GLenum pname, GLfloat param ); +void (APIENTRY * bglTexParameteri)( GLenum target, GLenum pname, GLint param ); +void (APIENTRY * bglGetTexLevelParameteriv)( GLenum target, GLint level, GLenum pname, GLint *params ); +void (APIENTRY * bglCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +void (APIENTRY * bglGetCompressedTexImageARB)(GLenum, GLint, GLvoid *); + +// Fog +void (APIENTRY * bglFogf)( GLenum pname, GLfloat param ); +void (APIENTRY * bglFogi)( GLenum pname, GLint param ); +void (APIENTRY * bglFogfv)( GLenum pname, const GLfloat *params ); + +#ifdef RENDERTYPEWIN +// Windows +HGLRC (WINAPI * bwglCreateContext)(HDC); +BOOL (WINAPI * bwglDeleteContext)(HGLRC); +PROC (WINAPI * bwglGetProcAddress)(LPCSTR); +BOOL (WINAPI * bwglMakeCurrent)(HDC,HGLRC); + +BOOL (WINAPI * bwglSwapBuffers)(HDC); +int (WINAPI * bwglChoosePixelFormat)(HDC,CONST PIXELFORMATDESCRIPTOR*); +int (WINAPI * bwglDescribePixelFormat)(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); +int (WINAPI * bwglGetPixelFormat)(HDC); +BOOL (WINAPI * bwglSetPixelFormat)(HDC,int,const PIXELFORMATDESCRIPTOR*); + +static HANDLE hGLDLL; +#endif + + +char *gldriver = NULL; + +static void * getproc_(const char *s, int *err, int fatal, int extension) +{ + void *t; +#if defined RENDERTYPESDL + t = (void*)SDL_GL_GetProcAddress(s); +#elif defined _WIN32 + if (extension) t = (void*)bwglGetProcAddress(s); + else t = (void*)GetProcAddress(hGLDLL,s); +#else +#error Need a dynamic loader for this platform... +#endif + if (!t && fatal) { + initprintf("Failed to find %s in %s\n", s, gldriver); + *err = 1; + } + return t; +} +#define GETPROC(s) getproc_(s,&err,1,0) +#define GETPROCSOFT(s) getproc_(s,&err,0,0) +#define GETPROCEXT(s) getproc_(s,&err,1,1) +#define GETPROCEXTSOFT(s) getproc_(s,&err,0,1) + +int loadgldriver(const char *driver) +{ + void *t; + int err=0; + +#ifdef RENDERTYPEWIN + if (hGLDLL) return 0; +#endif + + if (!driver) { +#ifdef _WIN32 + driver = "OPENGL32.DLL"; +#else + driver = "libGL.so"; +#endif + } + + initprintf("Loading %s\n",driver); + +#if defined RENDERTYPESDL + if (SDL_GL_LoadLibrary(driver)) return -1; +#elif defined _WIN32 + hGLDLL = LoadLibrary(driver); + if (!hGLDLL) return -1; +#endif + gldriver = strdup(driver); + +#ifdef RENDERTYPEWIN + bwglCreateContext = GETPROC("wglCreateContext"); + bwglDeleteContext = GETPROC("wglDeleteContext"); + bwglGetProcAddress = GETPROC("wglGetProcAddress"); + bwglMakeCurrent = GETPROC("wglMakeCurrent"); + + bwglSwapBuffers = GETPROC("wglSwapBuffers"); + bwglChoosePixelFormat = GETPROC("wglChoosePixelFormat"); + bwglDescribePixelFormat = GETPROC("wglDescribePixelFormat"); + bwglGetPixelFormat = GETPROC("wglGetPixelFormat"); + bwglSetPixelFormat = GETPROC("wglSetPixelFormat"); +#endif + + bglClearColor = GETPROC("glClearColor"); + bglClear = GETPROC("glClear"); + bglColorMask = GETPROC("glColorMask"); + bglAlphaFunc = GETPROC("glAlphaFunc"); + bglBlendFunc = GETPROC("glBlendFunc"); + bglCullFace = GETPROC("glCullFace"); + bglFrontFace = GETPROC("glFrontFace"); + bglPolygonOffset = GETPROC("glPolygonOffset"); + bglPolygonMode = GETPROC("glPolygonMode"); + bglEnable = GETPROC("glEnable"); + bglDisable = GETPROC("glDisable"); + bglGetFloatv = GETPROC("glGetFloatv"); + bglGetIntegerv = GETPROC("glGetIntegerv"); + bglPushAttrib = GETPROC("glPushAttrib"); + bglPopAttrib = GETPROC("glPopAttrib"); + bglGetError = GETPROC("glGetError"); + bglGetString = GETPROC("glGetString"); + bglHint = GETPROC("glHint"); + + // Depth + bglDepthFunc = GETPROC("glDepthFunc"); + bglDepthMask = GETPROC("glDepthMask"); + bglDepthRange = GETPROC("glDepthRange"); + + // Matrix + bglMatrixMode = GETPROC("glMatrixMode"); + bglOrtho = GETPROC("glOrtho"); + bglFrustum = GETPROC("glFrustum"); + bglViewport = GETPROC("glViewport"); + bglPushMatrix = GETPROC("glPushMatrix"); + bglPopMatrix = GETPROC("glPopMatrix"); + bglLoadIdentity = GETPROC("glLoadIdentity"); + bglLoadMatrixf = GETPROC("glLoadMatrixf"); + + // Drawing + bglBegin = GETPROC("glBegin"); + bglEnd = GETPROC("glEnd"); + bglVertex2f = GETPROC("glVertex2f"); + bglVertex2i = GETPROC("glVertex2i"); + bglVertex3d = GETPROC("glVertex3d"); + bglVertex3fv = GETPROC("glVertex3fv"); + bglColor4f = GETPROC("glColor4f"); + bglColor4ub = GETPROC("glColor4ub"); + bglTexCoord2d = GETPROC("glTexCoord2d"); + bglTexCoord2f = GETPROC("glTexCoord2f"); + + // Lighting + bglShadeModel = GETPROC("glShadeModel"); + + // Raster funcs + bglReadPixels = GETPROC("glReadPixels"); + + // Texture mapping + bglTexEnvf = GETPROC("glTexEnvf"); + bglGenTextures = GETPROC("glGenTextures"); + bglDeleteTextures = GETPROC("glDeleteTextures"); + bglBindTexture = GETPROC("glBindTexture"); + bglTexImage2D = GETPROC("glTexImage2D"); + bglTexSubImage2D = GETPROC("glTexSubImage2D"); + bglTexParameterf = GETPROC("glTexParameterf"); + bglTexParameteri = GETPROC("glTexParameteri"); + bglGetTexLevelParameteriv = GETPROC("glGetTexLevelParameteriv"); + + // Fog + bglFogf = GETPROC("glFogf"); + bglFogi = GETPROC("glFogi"); + bglFogfv = GETPROC("glFogfv"); + + loadglextensions(); + + if (err) unloadgldriver(); + return err; +} + +int loadglextensions(void) +{ + int err = 0; +#ifdef RENDERTYPEWIN + if (!hGLDLL) return 0; +#endif + + bglCompressedTexImage2DARB = GETPROCEXTSOFT("glCompressedTexImage2DARB"); + bglGetCompressedTexImageARB = GETPROCEXTSOFT("glGetCompressedTexImageARB"); + + return err; +} + +int unloadgldriver(void) +{ +#ifdef RENDERTYPEWIN + if (!hGLDLL) return 0; +#endif + + free(gldriver); + gldriver = NULL; + +#ifdef RENDERTYPEWIN + FreeLibrary(hGLDLL); + hGLDLL = NULL; +#endif + + bglClearColor = NULL; + bglClear = NULL; + bglColorMask = NULL; + bglAlphaFunc = NULL; + bglBlendFunc = NULL; + bglCullFace = NULL; + bglFrontFace = NULL; + bglPolygonOffset = NULL; + bglPolygonMode = NULL; + bglEnable = NULL; + bglDisable = NULL; + bglGetFloatv = NULL; + bglGetIntegerv = NULL; + bglPushAttrib = NULL; + bglPopAttrib = NULL; + bglGetError = NULL; + bglGetString = NULL; + bglHint = NULL; + + // Depth + bglDepthFunc = NULL; + bglDepthMask = NULL; + bglDepthRange = NULL; + + // Matrix + bglMatrixMode = NULL; + bglOrtho = NULL; + bglFrustum = NULL; + bglViewport = NULL; + bglPushMatrix = NULL; + bglPopMatrix = NULL; + bglLoadIdentity = NULL; + bglLoadMatrixf = NULL; + + // Drawing + bglBegin = NULL; + bglEnd = NULL; + bglVertex2f = NULL; + bglVertex2i = NULL; + bglVertex3d = NULL; + bglVertex3fv = NULL; + bglColor4f = NULL; + bglColor4ub = NULL; + bglTexCoord2d = NULL; + bglTexCoord2f = NULL; + + // Lighting + bglShadeModel = NULL; + + // Raster funcs + bglReadPixels = NULL; + + // Texture mapping + bglTexEnvf = NULL; + bglGenTextures = NULL; + bglDeleteTextures = NULL; + bglBindTexture = NULL; + bglTexImage2D = NULL; + bglTexSubImage2D = NULL; + bglTexParameterf = NULL; + bglTexParameteri = NULL; + bglGetTexLevelParameteriv = NULL; + bglCompressedTexImage2DARB = NULL; + bglGetCompressedTexImageARB = NULL; + + // Fog + bglFogf = NULL; + bglFogi = NULL; + bglFogfv = NULL; + +#ifdef RENDERTYPEWIN + bwglCreateContext = NULL; + bwglDeleteContext = NULL; + bwglGetProcAddress = NULL; + bwglMakeCurrent = NULL; + + bwglSwapBuffers = NULL; + bwglChoosePixelFormat = NULL; + bwglDescribePixelFormat = NULL; + bwglGetPixelFormat = NULL; + bwglSetPixelFormat = NULL; +#endif + + return 0; +} + +#else + +char *gldriver = ""; + +int loadgldriver(const char *a) { return 0; } +int unloadgldriver(void) { return 0; } + +#endif + diff --git a/polymer/build/src/gtkbits.c b/polymer/build/src/gtkbits.c new file mode 100644 index 000000000..8c359ecad --- /dev/null +++ b/polymer/build/src/gtkbits.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "baselayer.h" +#include "build.h" + +static int gtkenabled = 0; + +extern const GdkPixdata startbanner_pixdata; +static GtkWidget *startwin = NULL; +static GdkPixbuf *appicon = NULL; + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +#define lookup_widget(x,w) \ + (GtkWidget*) g_object_get_data(G_OBJECT(x), w) + +static gboolean on_startwin_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + quitevent++; + return TRUE; // FALSE would let the event go through. we want the game to decide when to close +} + +void gtkbuild_create_startwin(void) +{ + GtkWidget *banner, *label, *content, *scroll; + GtkWidget *hbox1, *fixed1; + GdkPixbuf *startbanner_pixbuf; + + if (!gtkenabled) return; + + startwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (startwin), apptitle); + gtk_window_set_position (GTK_WINDOW (startwin), GTK_WIN_POS_CENTER); + gtk_window_set_resizable (GTK_WINDOW (startwin), FALSE); + gtk_window_set_type_hint (GTK_WINDOW (startwin), GDK_WINDOW_TYPE_HINT_DIALOG); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox1); + gtk_container_add (GTK_CONTAINER (startwin), hbox1); + + startbanner_pixbuf = gdk_pixbuf_from_pixdata(&startbanner_pixdata, FALSE, NULL); + banner = gtk_image_new_from_pixbuf(startbanner_pixbuf); + g_object_unref((gpointer)startbanner_pixbuf); + gtk_widget_show (banner); + gtk_box_pack_start (GTK_BOX (hbox1), banner, FALSE, FALSE, 0); + + fixed1 = gtk_fixed_new (); + gtk_widget_show (fixed1); + gtk_box_pack_start (GTK_BOX (hbox1), fixed1, TRUE, TRUE, 0); + gtk_widget_set_size_request (fixed1, 390, -1); + + label = gtk_label_new (startwin_labeltext); + gtk_widget_show (label); + gtk_fixed_put (GTK_FIXED (fixed1), label, 6, 6); + gtk_widget_set_size_request (label, 378, 16); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scroll); + gtk_fixed_put (GTK_FIXED (fixed1), scroll, 6, 28); + gtk_widget_set_size_request (scroll, 378, 248); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + + content = gtk_text_view_new (); + gtk_widget_show (content); + gtk_container_add (GTK_CONTAINER(scroll), content); + //gtk_fixed_put (GTK_FIXED (fixed1), content, 6, 28); + gtk_widget_set_size_request (content, 378, 248); + gtk_text_view_set_editable (GTK_TEXT_VIEW (content), FALSE); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (content), GTK_WRAP_WORD); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (content), FALSE); + + g_signal_connect ((gpointer) startwin, "delete_event", + G_CALLBACK (on_startwin_delete_event), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (startwin, startwin, "startwin"); + GLADE_HOOKUP_OBJECT (startwin, banner, "banner"); + GLADE_HOOKUP_OBJECT (startwin, label, "label"); + GLADE_HOOKUP_OBJECT (startwin, scroll, "scroll"); + GLADE_HOOKUP_OBJECT (startwin, content, "content"); + + g_signal_connect((gpointer)startwin, "destroy", G_CALLBACK(gtk_widget_destroyed), (gpointer)&startwin); + gtk_widget_show (startwin); + gtk_main_iteration_do (FALSE); +} + +void gtkbuild_settitle_startwin(const char *title) +{ + if (!gtkenabled || !startwin) return; + gtk_window_set_title (GTK_WINDOW (startwin), title); +} + +void gtkbuild_puts_startwin(const char *str) +{ + GtkWidget *textview; + GtkTextBuffer *textbuffer; + GtkTextIter enditer; + GtkTextMark *mark; + const char *aptr, *bptr; + + if (!gtkenabled || !startwin || !str) return; + if (!(textview = lookup_widget(startwin, "content"))) return; + textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); + + gtk_text_buffer_get_end_iter(textbuffer, &enditer); + for (aptr = bptr = str; *aptr != 0; ) { + switch (*bptr) { + case '\b': + if (bptr > aptr) + gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1); +#if GTK_CHECK_VERSION(2,6,0) + gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE); +#else + { + GtkTextIter iter2 = enditer; + gtk_text_iter_backward_cursor_position(&iter2); + //FIXME: this seems be deleting one too many chars somewhere! + if (!gtk_text_iter_equal(&iter2, &enditer)) + gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE); + } +#endif + aptr = ++bptr; + break; + case 0: + if (bptr > aptr) + gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)); + aptr = bptr; + break; + case '\r': // FIXME + default: + bptr++; + break; + } + } + + mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1); + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0); + gtk_text_buffer_delete_mark(textbuffer, mark); +} + +void gtkbuild_close_startwin(void) +{ + if (!gtkenabled) return; + if (startwin) { + gtk_widget_destroy (startwin); + startwin = NULL; + } +} + +void gtkbuild_update_startwin(void) +{ + if (!gtkenabled) return; + gtk_main_iteration_do (FALSE); +} + + +int gtkbuild_msgbox(char *name, char *msg) +{ + GtkWidget *dialog; + + if (!gtkenabled) return -1; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + msg); + gtk_window_set_title(GTK_WINDOW(dialog), name); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + return 1; +} + +int gtkbuild_ynbox(char *name, char *msg) +{ + int r; + GtkWidget *dialog; + + if (!gtkenabled) return -1; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_YES_NO, + msg); + gtk_window_set_title(GTK_WINDOW(dialog), name); + r = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + if (r == GTK_RESPONSE_YES) return 1; + return 0; +} + +#ifdef RENDERTYPESDL +#include "sdlayer.h" +extern struct sdlappicon sdlappicon; +#endif +void gtkbuild_init(int argc, char **argv) +{ + gtkenabled = gtk_init_check(argc, argv); + if (!gtkenabled) return; +#ifdef RENDERTYPESDL + appicon = gdk_pixbuf_new_from_data((const guchar *)sdlappicon.pixels, + GDK_COLORSPACE_RGB, TRUE, 8, sdlappicon.width, sdlappicon.height, + sdlappicon.width*4, NULL, NULL); +#endif + if (appicon) gtk_window_set_default_icon(appicon); +} + +void gtkbuild_exit(int r) +{ + if (!gtkenabled) return; + if (appicon) g_object_unref((gpointer)appicon); + //gtk_exit(r); +} + +void *gtkbuild_get_app_icon(void) +{ + return appicon; +} diff --git a/polymer/build/src/hightile.c b/polymer/build/src/hightile.c new file mode 100644 index 000000000..182216af7 --- /dev/null +++ b/polymer/build/src/hightile.c @@ -0,0 +1,254 @@ +/* + * High-colour textures support for Polymost + * by Jonathon Fowler + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "kplib.h" + +#define HICEFFECTMASK (1|2) +static palette_t hictinting[MAXPALOOKUPS]; + +struct hicskybox_t { + long ignore; + char *face[6]; +}; +typedef struct hicreplc_t { + struct hicreplc_t *next; + char palnum, ignore, flags, filler; + char *filename; + float alphacut; + struct hicskybox_t *skybox; +} hicreplctyp; +static hicreplctyp *hicreplc[MAXTILES]; +static char hicfirstinit = 0; + +// +// find the index into hicreplc[] which contains the replacement tile particulars +// +static hicreplctyp * hicfindsubst(long picnum, long palnum, long skybox) +{ + hicreplctyp *hr; + + if (!hicfirstinit) return NULL; + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return NULL; + + do { + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) { + if (skybox) { + if (hr->skybox && !hr->skybox->ignore) return hr; + } else { + if (!hr->ignore) return hr; + } + } + } + + if (!palnum) break; + palnum = 0; + } while (1); + + return NULL; // no replacement found +} + + +// +// hicinit() +// Initialise the high-colour stuff to default. +// +void hicinit(void) +{ + long i,j; + hicreplctyp *hr, *next; + + for (i=0;i=0;i--) { + for (hr=hicreplc[i]; hr; ) { + next = hr->next; + + if (hr->skybox) { + for (j=5;j>=0;j--) { + if (hr->skybox->face[j]) { + free(hr->skybox->face[j]); + } + } + free(hr->skybox); + } + if (hr->filename) free(hr->filename); + free(hr); + + hr = next; + } + } + memset(hicreplc,0,sizeof(hicreplc)); + + hicfirstinit = 1; +} + + +// +// hicsetpalettetint(pal,r,g,b,effect) +// The tinting values represent a mechanism for emulating the effect of global sector +// palette shifts on true-colour textures and only true-colour textures. +// effect bitset: 1 = greyscale, 2 = invert +// +void hicsetpalettetint(long palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect) +{ + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return; + if (!hicfirstinit) hicinit(); + + hictinting[palnum].r = r; + hictinting[palnum].g = g; + hictinting[palnum].b = b; + hictinting[palnum].f = effect & HICEFFECTMASK; +} + + +// +// hicsetsubsttex(picnum,pal,filen,alphacut) +// Specifies a replacement graphic file for an ART tile. +// +int hicsetsubsttex(long picnum, long palnum, char *filen, float alphacut, char flags) +{ + hicreplctyp *hr, *hrn; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + if (!hicfirstinit) hicinit(); + + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) { + // no replacement yet defined + hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); + if (!hrn) return -1; + hrn->palnum = palnum; + } else hrn = hr; + + // store into hicreplc the details for this replacement + if (hrn->filename) free(hrn->filename); + + hrn->filename = strdup(filen); + if (!hrn->filename) { + if (hrn->skybox) return -1; // don't free the base structure if there's a skybox defined + if (hr == NULL) free(hrn); // not yet a link in the chain + return -1; + } + hrn->ignore = 0; + hrn->alphacut = min(alphacut,1.0); + hrn->flags = flags; + if (hr == NULL) { + hrn->next = hicreplc[picnum]; + hicreplc[picnum] = hrn; + } + + //printf("Replacement [%d,%d]: %s\n", picnum, palnum, hicreplc[i]->filename); + + return 0; +} + + +// +// hicsetskybox(picnum,pal,faces[6]) +// Specifies a graphic files making up a skybox. +// +int hicsetskybox(long picnum, long palnum, char *faces[6]) +{ + hicreplctyp *hr, *hrn; + long j; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + for (j=5;j>=0;j--) if (!faces[j]) return -1; + if (!hicfirstinit) hicinit(); + + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) { + // no replacement yet defined + hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); + if (!hrn) return -1; + + hrn->palnum = palnum; + } else hrn = hr; + + if (!hrn->skybox) { + hrn->skybox = (struct hicskybox_t *)calloc(1,sizeof(struct hicskybox_t)); + if (!hrn->skybox) { + if (hr == NULL) free(hrn); // not yet a link in the chain + return -1; + } + } else { + for (j=5;j>=0;j--) { + if (hrn->skybox->face[j]) + free(hrn->skybox->face[j]); + } + } + + // store each face's filename + for (j=0;j<6;j++) { + hrn->skybox->face[j] = strdup(faces[j]); + if (!hrn->skybox->face[j]) { + for (--j; j>=0; --j) // free any previous faces + free(hrn->skybox->face[j]); + free(hrn->skybox); + hrn->skybox = NULL; + if (hr == NULL) free(hrn); + return -1; + } + } + hrn->skybox->ignore = 0; + if (hr == NULL) { + hrn->next = hicreplc[picnum]; + hicreplc[picnum] = hrn; + } + + return 0; +} + + +// +// hicclearsubst(picnum,pal) +// Clears a replacement for an ART tile, including skybox faces. +// +int hicclearsubst(long picnum, long palnum) +{ + hicreplctyp *hr, *hrn = NULL; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + if (!hicfirstinit) return 0; + + for (hr = hicreplc[picnum]; hr; hrn = hr, hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) return 0; + + if (hr->filename) free(hr->filename); + if (hr->skybox) { + int i; + for (i=5;i>=0;i--) + if (hr->skybox->face[i]) + free(hr->skybox->face[i]); + free(hr->skybox); + } + + if (hrn) hrn->next = hr->next; + else hicreplc[picnum] = hr->next; + free(hr); + + return 0; +} diff --git a/polymer/build/src/jfaud_sound.cpp b/polymer/build/src/jfaud_sound.cpp new file mode 100644 index 000000000..9bc8bfabb --- /dev/null +++ b/polymer/build/src/jfaud_sound.cpp @@ -0,0 +1,378 @@ +#ifdef __APPLE__ +# include +#else +# include "jfaud.hpp" +#endif + +#include + +#include "compat.h" +#include "baselayer.h" +#include "cache1d.h" + +extern "C" { +void initsb(char,char,long,char,char,char,char); +void uninitsb(void); +void setears(long,long,long,long); +void wsayfollow(char *,long,long,long *,long *,char); +void wsay(char *,long,long,long); +void loadwaves(void); +void loadsong(char *); +void musicon(void); +void musicoff(void); +void refreshaudio(void); +} + +#define NUMCHANNELS 16 +#define UNITSPERMTR 640.0 +#define WAVESFILE "WAVES.KWV" + +static char musistat = 0; +static char songname[BMAX_PATH] = ""; +static JFAud *jfaud = NULL; + +static int kwvnumwaves = 0; +static struct _kwvitem { + char instname[16]; + long wavleng; + long repstart; + long repleng; + long finetune; + long datastart; +} *kwvitems = NULL; + +static struct { + long *posx, *posy; + JFAudMixerChannel *handle; +} sfxchans[NUMCHANNELS]; + +class KenFile : public JFAudFile { +private: + int fh; +public: + KenFile(const char *filename, const char *subfilename) + : JFAudFile(filename, subfilename) + { + fh = kopen4load(const_cast(filename), 0); + } + + virtual ~KenFile() + { + if (fh >= 0) kclose(fh); + } + + virtual bool IsOpen(void) const { return fh >= 0; } + + virtual long Read(long nbytes, void *buf) + { + if (fh < 0) return -1; + return kread(fh, buf, nbytes); + } + virtual long Seek(long pos, SeekFrom where) + { + int when; + if (fh < 0) return -1; + switch (where) { + case JFAudFile::Set: when = SEEK_SET; break; + case JFAudFile::Cur: when = SEEK_CUR; break; + case JFAudFile::End: when = SEEK_END; break; + default: return -1; + } + return klseek(fh, pos, when); + } + virtual long Tell(void) const + { + if (fh < 0) return -1; + return klseek(fh, 0, SEEK_CUR); + } + virtual long Length(void) const + { + if (fh < 0) return -1; + return kfilelength(fh); + } +}; + +class KWVFile : public JFAudFile { +private: + int fh; + long datastart, datalen, datapos; +public: + KWVFile(const char *filename, const char *subfilename = NULL) + : JFAudFile(filename, NULL), + datastart(-1), datalen(-1), datapos(-1) + { + long i,j; + bool found = false; + + if (!subfilename) return; + + for (i=0;i(filename), 0); + if (fh < 0) return; + + datastart = kwvitems[i].datastart; + datalen = kwvitems[i].wavleng; + datapos = 0; + klseek(fh, datastart, SEEK_SET); + return; + } + } + } + + virtual ~KWVFile() + { + if (fh >= 0) kclose(fh); + } + virtual bool IsOpen(void) const + { + return datalen > 0 && fh >= 0; + } + + virtual long Read(long nbytes, void *buf) + { + if (!IsOpen()) return -1; + if (datalen - datapos < nbytes) nbytes = datalen - datapos; + if (nbytes <= 0) return 0; + nbytes = kread(fh, buf, nbytes); + if (nbytes > 0) datapos += nbytes; + return nbytes; + } + virtual long Seek(long pos, SeekFrom where) + { + long newpos; + if (!IsOpen()) return -1; + switch (where) { + case JFAudFile::Set: newpos = pos; break; + case JFAudFile::Cur: newpos = datapos + pos; break; + case JFAudFile::End: newpos = datalen + pos; break; + default: return -1; + } + if (newpos < 0) newpos = 0; + else if (newpos > datalen) newpos = datalen; + return klseek(fh, datastart + newpos, SEEK_SET); + } + virtual long Tell(void) const + { + if (!IsOpen()) return -1; + return datapos; + } + virtual long Length(void) const + { + if (!IsOpen()) return -1; + return datalen; + } +}; + +static JFAudFile *openfile(const char *fn, const char *subfn) +{ + char *ext; + bool loadkwv = false; + + ext = Bstrrchr(fn,'.'); + if (!ext || Bstrcasecmp(ext, ".kwv")) + return static_cast(new KenFile(fn,subfn)); + if (!subfn) return NULL; // KWV files need a sub name + + return static_cast(new KWVFile(fn, subfn)); +} + +static void logfunc(const char *s) { initprintf("%s", s); } + +void loadwaves(void) +{ + long fh, i, datastart; + + fh = kopen4load(WAVESFILE, 0); + if (fh < 0) return; + + if (kread(fh, &i, 4) != 4 || i != 0) return; + if (kread(fh, &kwvnumwaves, 4) != 4) return; kwvnumwaves = B_LITTLE32(kwvnumwaves); + + kwvitems = new struct _kwvitem [kwvnumwaves]; + if (!kwvitems) { + kclose(fh); + return; + } + + datastart = (4+4) + kwvnumwaves * (16+4*4); + for (i=0;iSetUserOpenFunc(openfile); + + musistat = 0; + if (!jfaud->InitWave(NULL, NUMCHANNELS, dasamplerate)) { + delete jfaud; + jfaud = NULL; + return; + } + + musistat = damusistat; + + for (i=NUMCHANNELS-1;i>=0;i--) sfxchans[i].handle = NULL; + + loadwaves(); +} + +void uninitsb(void) +{ + if (!jfaud) return; + + delete jfaud; + jfaud = NULL; + + if (kwvitems) delete [] kwvitems; +} + +void setears(long daposx, long daposy, long daxvect, long dayvect) +{ + JFAudMixer *mixer; + + if (!jfaud) return; + mixer = jfaud->GetWave(); + if (!mixer) return; + + mixer->SetListenerPosition((float)daposx/UNITSPERMTR, 0.0, (float)-daposy/UNITSPERMTR); + mixer->SetListenerOrientation((float)daxvect/UNITSPERMTR, 0.0, (float)-dayvect/UNITSPERMTR, + 0.0, 1.0, 0.0); +} + +static int storehandle(JFAudMixerChannel *handle, long *daxplc, long *dayplc) +{ + int i,empty = -1; + + for (i=NUMCHANNELS-1;i>=0;i--) { + if (!sfxchans[i].handle && empty<0) empty = i; + if (sfxchans[i].handle == handle) { + empty = i; + break; + } + } + + if (empty < 0) return -1; + + sfxchans[empty].handle = handle; + sfxchans[empty].posx = daxplc; + sfxchans[empty].posy = dayplc; + + return empty; +} + +static void stopcb(int r) +{ + jfaud->FreeSound(sfxchans[r].handle); + sfxchans[r].handle = NULL; +} + +void wsayfollow(char *dafilename, long dafreq, long davol, long *daxplc, long *dayplc, char followstat) +{ + JFAudMixerChannel *handl; + int r; + + if (!jfaud) return; + + handl = jfaud->PlayRawSound(WAVESFILE, dafilename, 1, 11025, 1, 1, false); + if (!handl) return; + + if (followstat) r = storehandle(handl, daxplc, dayplc); + else r = storehandle(handl, NULL, NULL); + + if (r >= 0) handl->SetStopCallback(stopcb, r); + + handl->SetPitch((float)dafreq / 4096.0); + handl->SetGain((float)davol / 256.0); + handl->SetPosition((float)(*daxplc) / UNITSPERMTR, 0.0, (float)(-*dayplc) / UNITSPERMTR); + handl->SetFollowListener(false); + handl->SetRolloff(1.0); + + handl->Play(); +} + +void wsay(char *dafilename, long dafreq, long volume1, long volume2) +{ + JFAudMixerChannel *handl; + int r; + + if (!jfaud) return; + + handl = jfaud->PlayRawSound(WAVESFILE, dafilename, 1, 11025, 1, 1, false); + if (!handl) return; + + r = storehandle(handl, NULL, NULL); + + if (r >= 0) handl->SetStopCallback(stopcb, r); + + handl->SetPitch((float)dafreq / 4096.0); + handl->SetGain((float)volume1 / 256.0); + handl->SetPosition(0.0, 0.0, 0.0); + handl->SetFollowListener(true); + handl->SetRolloff(0.0); + + handl->Play(); +} + +void loadsong(char *filename) +{ + if (!jfaud) return; + strcpy(songname,filename); +} + +void musicon(void) +{ + if (!jfaud || !musistat || !songname[0]) return; + + jfaud->PlayMusic(songname); +} + +void musicoff(void) +{ + if (!jfaud || !musistat) return; + + jfaud->StopMusic(); +} + +void refreshaudio(void) +{ + int i; + + if (!jfaud) return; + for (i=NUMCHANNELS-1;i>=0;i--) { + if (!sfxchans[i].handle || !jfaud->IsValidSound(sfxchans[i].handle)) continue; + if (!sfxchans[i].posx || !sfxchans[i].posy) continue; + + sfxchans[i].handle->SetPosition( + (float)(*sfxchans[i].posx)/UNITSPERMTR, + 0.0, + (float)(-*sfxchans[i].posy)/UNITSPERMTR); + } + jfaud->Update(); +} diff --git a/polymer/build/src/kplib.c b/polymer/build/src/kplib.c new file mode 100644 index 000000000..f3db7dd75 --- /dev/null +++ b/polymer/build/src/kplib.c @@ -0,0 +1,3117 @@ +/************************************************************************************************** +KPLIB.C: Ken's Picture LIBrary written by Ken Silverman +Copyright (c) 1998-2005 Ken Silverman +Ken Silverman's official web site: http://advsys.net/ken + +Features of KPLIB.C: + * Routines for decoding JPG, PNG, GIF, PCX, TGA, BMP, CEL. + See kpgetdim(), kprender(), and optional helper function: kpzload(). + * Routines for ZIP decompression. All ZIP functions start with the letters "kz". + * Multi-platform support: Dos/Windows/Linux/Mac/etc.. + * Compact code, all in a single source file. Yeah, bad design on my part... but makes life + easier for everyone else - you simply add a single C file to your project, throw a few + externs in there, add the function calls, and you're done! + +Brief history: +1998?: Wrote KPEG, a JPEG viewer for DOS +2000: Wrote KPNG, a PNG viewer for DOS +2001: Combined KPEG & KPNG, ported to Visual C, and made it into a library called KPLIB.C +2002: Added support for TGA, GIF, CEL, ZIP +2003: Added support for BMP +05/18/2004: Added support for 8&24 bit PCX +12/09/2005: Added support for progressive JPEG + +I offer this code to the community for free use - all I ask is that my name be included in the +credits. + +-Ken S. +**************************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#if defined(__POWERPC__) +#define BIGENDIAN 1 +#endif + +#ifdef BIGENDIAN +static unsigned long LSWAPIB (unsigned long a) { return(((a>>8)&0xff00)+((a&0xff00)<<8)+(a<<24)+(a>>24)); } +static unsigned short SSWAPIB (unsigned short a) { return((a>>8)+(a<<8)); } +#define LSWAPIL(a) (a) +#define SSWAPIL(a) (a) +#else +#define LSWAPIB(a) (a) +#define SSWAPIB(a) (a) +static unsigned long LSWAPIL (unsigned long a) { return(((a>>8)&0xff00)+((a&0xff00)<<8)+(a<<24)+(a>>24)); } +static unsigned short SSWAPIL (unsigned short a) { return((a>>8)+(a<<8)); } +#endif + +#if !defined(_WIN32) && !defined(__DOS__) +#include +#include +typedef long long __int64; +static __inline long _lrotl (long i, int sh) + { return((i>>(-sh))|(i< +#endif + +#if defined(__DOS__) +#include +#elif defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#if !defined(max) +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#if !defined(min) +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#if defined(__GNUC__) +#define _inline inline +#endif + + //use GCC-specific extension to force symbol name to be something in particular to override underscoring. +#if defined(__GNUC__) && defined(__i386__) && !defined(NOASM) +#define ASMNAME(x) asm(x) +#else +#define ASMNAME(x) +#endif + +static long frameplace, bytesperline, xres, yres, globxoffs, globyoffs; + +static const long pow2mask[32] = +{ + 0x00000000,0x00000001,0x00000003,0x00000007, + 0x0000000f,0x0000001f,0x0000003f,0x0000007f, + 0x000000ff,0x000001ff,0x000003ff,0x000007ff, + 0x00000fff,0x00001fff,0x00003fff,0x00007fff, + 0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, + 0x000fffff,0x001fffff,0x003fffff,0x007fffff, + 0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff, + 0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff, +}; +static const long pow2long[32] = +{ + 0x00000001,0x00000002,0x00000004,0x00000008, + 0x00000010,0x00000020,0x00000040,0x00000080, + 0x00000100,0x00000200,0x00000400,0x00000800, + 0x00001000,0x00002000,0x00004000,0x00008000, + 0x00010000,0x00020000,0x00040000,0x00080000, + 0x00100000,0x00200000,0x00400000,0x00800000, + 0x01000000,0x02000000,0x04000000,0x08000000, + 0x10000000,0x20000000,0x40000000,0x80000000, +}; + + //Hack for peekbits,getbits,suckbits (to prevent lots of duplicate code) + // 0: PNG: do 12-byte chunk_header removal hack + // !=0: ZIP: use 64K buffer (olinbuf) +static long zipfilmode; +typedef struct +{ + FILE *fil; //0:no file open, !=0:open file (either stand-alone or zip) + long comptyp; //0:raw data (can be ZIP or stand-alone), 8:PKZIP LZ77 *flate + long seek0; //0:stand-alone file, !=0: start of zip compressed stream data + long compleng;//Global variable for compression FIFO + long comptell;//Global variable for compression FIFO + long leng; //Uncompressed file size (bytes) + long pos; //Current uncompressed relative file position (0<=pos<=leng) + long endpos; //Temp global variable for kzread + long jmpplc; //Store place where decompression paused + long i; //For stand-alone/ZIP comptyp#0, this is like "uncomptell" + //For ZIP comptyp#8&btype==0 "<64K store", this saves i state + long bfinal; //LZ77 decompression state (for later calls) +} kzfilestate; +static kzfilestate kzfs; + +//Initialized tables (can't be in union) +//jpg: png: +// crmul 16384 abstab10 4096 +// cbmul 16384 hxbit 472 +// dct 4608 pow2mask 128* +// colclip 4096 +// colclipup8 4096 +// colclipup16 4096 +// unzig 256 +// pow2mask 128* +// dcflagor 64 + +long palcol[256] ASMNAME("palcol"), paleng; +unsigned char coltype, bitdepth; + +//============================ KPNGILIB begins =============================== + +#define PROCESSALPHAHERE 0 //Set to 1 for KPNG, 0 in all other cases + +//07/31/2000: KPNG.C first ported to C from READPNG.BAS +//10/11/2000: KPNG.C split into 2 files: KPNG.C and PNGINLIB.C +//11/24/2000: Finished adding support for coltypes 4&6 +//03/31/2001: Added support for Adam7-type interlaced images +//Currently, there is no support for: +// * 16-bit color depth +// * Some useless ancillary chunks, like: gAMA(gamma) & pHYs(aspect ratio) + + //.PNG specific variables: +static long bakcol = 0xff808080, bakr = 0x80, bakg = 0x80, bakb = 0x80; //this used to be public... +static long gslidew = 0, gslider = 0, xm, xmn[4], xr0, xr1, xplc, yplc, nfplace; +static long clen[320], cclen[19], bitpos, filt, xsiz, ysiz; +static long xsizbpl, ixsiz, ixoff, iyoff, ixstp, iystp, intlac, nbpl, trnsrgb ASMNAME("trnsrgb"); +static long ccind[19] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +static long hxbit[59][2], ibuf0[288], nbuf0[32], ibuf1[32], nbuf1[32]; +static const unsigned char *filptr; +static unsigned char slidebuf[32768], opixbuf0[4], opixbuf1[4]; +static unsigned char pnginited = 0, olinbuf[65536] ASMNAME("olinbuf"); //WARNING:max xres is: 65536/bpp-1 +static long gotcmov = -2, abstab10[1024] ASMNAME("abstab10"); + + //Variables to speed up dynamic Huffman decoding: +#define LOGQHUFSIZ0 9 +#define LOGQHUFSIZ1 6 +static long qhufval0[1<>8) + ((a&0xff00)<<8) + (a<<24) + (a>>24)); +} + +static inline long bitrev (long b, long c) +{ + long i, j; + for(i=1,j=0,c=(1< 0x8000000) + { + cpuid(0x80000001,cpb); + i |= (cpb[3]&(1<<31)); + if (!((cpid[1]^0x68747541)|(cpid[3]^0x69746e65)|(cpid[2]^0x444d4163))) //AuthenticAMD + i |= (cpb[3]&((1<<22)|(1<<30))); + } + if (i&(1<<25)) i |= (1<<22); //SSE implies MMX+ support + return(i); +} + +static unsigned char fakebuf[8], *nfilptr; +static long nbitpos; +static void suckbitsnextblock () +{ + long n; + + if (!zipfilmode) + { + if (!nfilptr) + { //|===|===|crc|lng|typ|===|===| + // \ fakebuf: / + // |===|===| + //----x O---x O-------- + nbitpos = LSWAPIL(*(long *)&filptr[8]); + nfilptr = (unsigned char *)&filptr[nbitpos+12]; + *(long *)&fakebuf[0] = *(long *)&filptr[0]; //Copy last dword of IDAT chunk + if (*(long *)&filptr[12] == LSWAPIB(0x54414449)) //Copy 1st dword of next IDAT chunk + *(long *)&fakebuf[4] = *(long *)&filptr[16]; + filptr = &fakebuf[4]; bitpos -= 32; + } + else + { + filptr = nfilptr; nfilptr = 0; + bitpos -= ((nbitpos-4)<<3); + } + //if (n_from_suckbits < 4) will it crash? + } + else + { + //NOTE: should only read bytes inside compsize, not 64K!!! :/ + *(long *)&olinbuf[0] = *(long *)&olinbuf[sizeof(olinbuf)-4]; + n = min((unsigned)(kzfs.compleng-kzfs.comptell),sizeof(olinbuf)-4); + fread(&olinbuf[4],n,1,kzfs.fil); + kzfs.comptell += n; + bitpos -= ((sizeof(olinbuf)-4)<<3); + } +} + +static _inline long peekbits (long n) { return((LSWAPIB(*(long *)&filptr[bitpos>>3])>>(bitpos&7))&pow2mask[n]); } +static _inline void suckbits (long n) { bitpos += n; if (bitpos >= 0) suckbitsnextblock(); } +static _inline long getbits (long n) { long i = peekbits(n); suckbits(n); return(i); } + +static long hufgetsym (long *hitab, long *hbmax) +{ + long v, n; + + v = n = 0; + do { v = (v<<1)+getbits(1)+hbmax[n]-hbmax[n+1]; n++; } while (v >= 0); + return(hitab[hbmax[n]+v]); +} + + //This did not result in a speed-up on P4-3.6Ghz (02/22/2005) +//static long hufgetsym_skipb (long *hitab, long *hbmax, long n, long addit) +//{ +// long v; +// +// v = bitrev(getbits(n),n)+addit; +// do { v = (v<<1)+getbits(1)+hbmax[n]-hbmax[n+1]; n++; } while (v >= 0); +// return(hitab[hbmax[n]+v]); +//} + +static void qhufgencode (long *hitab, long *hbmax, long *qhval, unsigned char *qhbit, long numbits) +{ + long i, j, k, n, r; + + //r is the bit reverse of i. Ex: if: i = 1011100111, r = 1110011101 + i = r = 0; + for(n=1;n<=numbits;n++) + for(k=hbmax[n-1];k>n)&1) + hbmax[n]-hbmax[n+1]; + // + //n = numbits; + //k = hbmax[n]-r; + // + //j = peekbits(LOGQHUFSIZ); i = qhufval[j]; j = qhufbit[j]; + // + //i = j = 0; + //do + //{ + // i = (i<<1)+getbits(1)+nbuf0[j]-nbuf0[j+1]; j++; + //} while (i >= 0); + //i = ibuf0[nbuf0[j]+i]; + //qhval[r] = k; + + qhbit[r] = 0; //n-32; + } + + // //hufgetsym_skipb related code: + //for(k=n=0;n=0;i--) tbuf[inbuf[i]]++; + tbuf[0] = hbmax[0] = 0; //Hack to remove symbols of length 0? + for(i=0;i<31;i++) hbmax[i+1] = hbmax[i]+tbuf[i]; + for(i=0;i>i)&15); + iyoff = ((0x00402010>>i)&15); + if (((ixoff >= xsiz) || (iyoff >= ysiz)) && (intlac >= 2)) { i = -1; intlac--; } + } while (i < 0); + j = ((0x33221100>>i)&15); ixstp = (1<>i)&15); iystp = (1<>3) = 2 + //j=3,ixoff=4 2 ((12+(1<<3)-1 - 4)>>3) = 1 + //j=2,ixoff=2 3 4 5 ((12+(1<<2)-1 - 2)>>2) = 3 + //j=1,ixoff=1 6 7 8 9 a b ((12+(1<<1)-1 - 1)>>1) = 6 + ixsiz = ((xsiz+ixstp-1-ixoff)>>j); //It's confusing! See the above example. + nbpl = (bytesperline<>(coltype<<2))&15)*ixsiz; + switch (bitdepth) + { + case 1: xsizbpl = ((xsizbpl+7)>>3); break; + case 2: xsizbpl = ((xsizbpl+3)>>2); break; + case 4: xsizbpl = ((xsizbpl+1)>>1); break; + } + + memset(olinbuf,0,(xsizbpl+1)*sizeof(olinbuf[0])); + *(long *)&opixbuf0[0] = *(long *)&opixbuf1[0] = 0; + xplc = xsizbpl; yplc = globyoffs+iyoff; xm = 0; filt = -1; + + i = globxoffs+ixoff; i = (((-(i>=0))|(ixstp-1))&i); + k = (((-(yplc>=0))|(iystp-1))&yplc); + nfplace = k*bytesperline + (i<<2) + frameplace; + + //Precalculate x-clipping to screen borders (speeds up putbuf) + //Equation: (0 <= xr <= ixsiz) && (0 <= xr*ixstp+globxoffs+ixoff <= xres) + xr0 = max((-globxoffs-ixoff+(1<>j,0); + xr1 = min((xres-globxoffs-ixoff+(1<>j,ixsiz); + xr0 = ixsiz-xr0; + xr1 = ixsiz-xr1; + + if (coltype == 4) { xr0 = xr0*2; xr1 = xr1*2; } + else if (coltype == 2) { xr0 = xr0*3-2; xr1 = xr1*3-2; } + else if (coltype == 6) { xr0 = xr0*4-2; xr1 = xr1*4-2; } + else + { + switch(bitdepth) + { + case 1: xr0 += ((-ixsiz)&7)+7; + xr1 += ((-ixsiz)&7)+7; break; + case 2: xr0 = ((xr0+((-ixsiz)&3)+3)<<1); + xr1 = ((xr1+((-ixsiz)&3)+3)<<1); break; + case 4: xr0 = ((xr0+((-ixsiz)&1)+1)<<2); + xr1 = ((xr1+((-ixsiz)&1)+1)<<2); break; + } + } + ixstp <<= 2; + return(0); +} + +static long Paeth (long a, long b, long c) +{ + long pa, pb, pc; + + pa = b-c; pb = a-c; pc = labs(pa+pb); pa = labs(pa); pb = labs(pb); + if ((pa <= pb) && (pa <= pc)) return(a); + if (pb <= pc) return(b); else return(c); +} + +#if defined(NOASM) + +static inline long Paeth686 (long a, long b, long c) +{ + return(Paeth(a,b,c)); +} + +static inline void rgbhlineasm (long x, long xr1, long p, long ixstp) +{ + long i; + if (!trnsrgb) + { + for(;x>xr1;p+=ixstp,x-=3) *(long *)p = (*(long *)&olinbuf[x])|LSWAPIB(0xff000000); + return; + } + for(;x>xr1;p+=ixstp,x-=3) + { + i = (*(long *)&olinbuf[x])|LSWAPIB(0xff000000); + if (i == trnsrgb) i &= LSWAPIB(0xffffff); + *(long *)p = i; + } +} + +static inline void pal8hlineasm (long x, long xr1, long p, long ixstp) +{ + for(;x>xr1;p+=ixstp,x--) *(long *)p = palcol[olinbuf[x]]; +} + +#elif defined(__WATCOMC__) + + //NOTE: cmov now has correctly ordered registers (thx to bug fix in 11.0c!) +long Paeth686 (long, long, long); +#pragma aux Paeth686 =\ + ".686"\ + "mov edx, ecx"\ + "sub edx, eax"\ + "sub edx, ebx"\ + "lea edx, abstab10[edx*4+2048]"\ + "mov esi, [ebx*4+edx]"\ + "mov edi, [ecx*4+edx]"\ + "cmp edi, esi"\ + "cmovge edi, esi"\ + "cmovge ecx, ebx"\ + "cmp edi, [eax*4+edx]"\ + "cmovge ecx, eax"\ + parm nomemory [eax][ebx][ecx]\ + modify exact [ecx edx esi edi]\ + value [ecx] + + //Note: "cmove eax,?" may be faster than "jne ?:and eax,?" but who cares +void rgbhlineasm (long, long, long, long); +#pragma aux rgbhlineasm =\ + "sub ecx, edx"\ + "jle short endit"\ + "add edx, offset olinbuf"\ + "cmp dword ptr trnsrgb, 0"\ + "jz short begit2"\ + "begit: mov eax, dword ptr [ecx+edx]"\ + "or eax, 0xff000000"\ + "cmp eax, dword ptr trnsrgb"\ + "jne short skipit"\ + "and eax, 0xffffff"\ + "skipit: sub ecx, 3"\ + "mov [edi], eax"\ + "lea edi, [edi+ebx]"\ + "jnz short begit"\ + "jmp short endit"\ + "begit2: mov eax, dword ptr [ecx+edx]"\ + "or eax, 0xff000000"\ + "sub ecx, 3"\ + "mov [edi], eax"\ + "lea edi, [edi+ebx]"\ + "jnz short begit2"\ + "endit:"\ + parm [ecx][edx][edi][ebx]\ + modify exact [eax ecx edi]\ + value + +void pal8hlineasm (long, long, long, long); +#pragma aux pal8hlineasm =\ + "sub ecx, edx"\ + "jle short endit"\ + "add edx, offset olinbuf"\ + "begit: movzx eax, byte ptr [ecx+edx]"\ + "mov eax, dword ptr palcol[eax*4]"\ + "dec ecx"\ + "mov [edi], eax"\ + "lea edi, [edi+ebx]"\ + "jnz short begit"\ + "endit:"\ + parm [ecx][edx][edi][ebx]\ + modify exact [eax ecx edi]\ + value + +#elif defined(_MSC_VER) + +static _inline long Paeth686 (long a, long b, long c) +{ + _asm + { + mov eax, a + mov ebx, b + mov ecx, c + mov edx, ecx + sub edx, eax + sub edx, ebx + lea edx, abstab10[edx*4+2048] + mov esi, [ebx*4+edx] + mov edi, [ecx*4+edx] + cmp edi, esi + cmovge edi, esi + cmovge ecx, ebx + cmp edi, [eax*4+edx] + cmovl eax, ecx + } +} + +static _inline void rgbhlineasm (long c, long d, long t, long b) +{ + _asm + { + mov ecx, c + mov edx, d + mov edi, t + mov ebx, b + sub ecx, edx + jle short endit + add edx, offset olinbuf + cmp dword ptr trnsrgb, 0 + jz short begit2 + begit: mov eax, dword ptr [ecx+edx] + or eax, 0xff000000 + cmp eax, dword ptr trnsrgb + jne short skipit + and eax, 0xffffff + skipit: sub ecx, 3 + mov [edi], eax + lea edi, [edi+ebx] + jnz short begit + jmp short endit + begit2: mov eax, dword ptr [ecx+edx] + or eax, 0xff000000 + sub ecx, 3 + mov [edi], eax + lea edi, [edi+ebx] + jnz short begit2 + endit: + } +} + +static _inline void pal8hlineasm (long c, long d, long t, long b) +{ + _asm + { + mov ecx, c + mov edx, d + mov edi, t + mov ebx, b + sub ecx, edx + jle short endit + add edx, offset olinbuf + begit: movzx eax, byte ptr [ecx+edx] + mov eax, dword ptr palcol[eax*4] + sub ecx, 1 + mov [edi], eax + lea edi, [edi+ebx] + jnz short begit + endit: + } +} + +#elif defined(__GNUC__) && defined(__i386__) + +static inline long Paeth686 (long a, long b, long c) +{ + __asm__ __volatile__ ( + "movl %%ecx, %%edx\n\tsubl %%eax, %%edx\n\tsubl %%ebx, %%edx\n\t" + "leal (abstab10+2048)(,%%edx,4), %%edx\n\t" + "movl (%%edx,%%ebx,4), %%esi\n\tmovl (%%edx,%%ecx,4), %%edi\n\t" + "cmpl %%esi, %%edi\n\tcmovgel %%esi, %%edi\n\tcmovgel %%ebx, %%ecx\n\t" + "cmpl (%%edx,%%eax,4), %%edi\n\tcmovgel %%eax, %%ecx" + : "+c" (c) : "a" (a), "b" (b) : "esi","edi","memory","cc" + ); + return c; +} + + //Note: "cmove eax,?" may be faster than "jne ?:and eax,?" but who cares +static inline void rgbhlineasm (long c, long d, long t, long b) +{ + __asm__ __volatile__ ( + "subl %%edx, %%ecx\n\tjle 3f\n\taddl $olinbuf, %%edx\n\t" + "cmpl $0, trnsrgb(,1)\n\tjz 2f\n\t" + "0: movl (%%ecx,%%edx,1), %%eax\n\torl $0xff000000, %%eax\n\tcmpl trnsrgb(,1), %%eax\n\t" + "jne 1f\n\tandl $0xffffff, %%eax\n\t" + "1: subl $3, %%ecx\n\tmovl %%eax, (%%edi)\n\tleal (%%edi,%%ebx,1), %%edi\n\t" + "jnz 0b\n\tjmp 3f\n\t" + "2: movl (%%ecx,%%edx,1), %%eax\n\torl $0xff000000, %%eax\n\tsubl $3, %%ecx\n\t" + "movl %%eax, (%%edi)\n\tleal (%%edi,%%ebx,1), %%edi\n\tjnz 2b\n\t" + "3:" + : "+c" (c), "+D" (t) : "d" (d), "b" (b) : "eax","memory","cc" + ); +} + +static inline void pal8hlineasm (long c, long d, long t, long b) +{ + __asm__ __volatile__ ( + "subl %%edx, %%ecx\n\tjle 1f\n\taddl $olinbuf, %%edx\n\t" + "0: movzbl (%%ecx,%%edx,1), %%eax\n\tmovl palcol(,%%eax,4), %%eax\n\t" + "subl $1, %%ecx\n\tmovl %%eax, (%%edi)\n\tleal (%%edi,%%ebx,1), %%edi\n\tjnz 0b\n\t" + "1:" + : "+c" (c), "+D" (t) : "d" (d), "b" (b) : "eax","memory","cc" + ); +} + +#else + +#error Unsupported compiler or architecture. + +#endif + +static void putbuf (const unsigned char *buf, long leng) +{ + long i, x, p; + + if (filt < 0) + { + if (leng <= 0) return; + filt = buf[0]; if (filt == gotcmov) filt = 5; + i = 1; + } else i = 0; + + while (i < leng) + { + x = i+xplc; if (x > leng) x = leng; + switch (filt) + { + case 0: + while (i < x) { olinbuf[xplc] = buf[i]; xplc--; i++; } + break; + case 1: + while (i < x) + { + olinbuf[xplc] = (opixbuf1[xm] += buf[i]); + xm = xmn[xm]; xplc--; i++; + } + break; + case 2: + while (i < x) { olinbuf[xplc] += buf[i]; xplc--; i++; } + break; + case 3: + while (i < x) + { + opixbuf1[xm] = olinbuf[xplc] = ((opixbuf1[xm]+olinbuf[xplc])>>1)+buf[i]; + xm = xmn[xm]; xplc--; i++; + } + break; + case 4: + while (i < x) + { + opixbuf1[xm] = (char)(Paeth(opixbuf1[xm],olinbuf[xplc],opixbuf0[xm])+buf[i]); + opixbuf0[xm] = olinbuf[xplc]; + olinbuf[xplc] = opixbuf1[xm]; + xm = xmn[xm]; xplc--; i++; + } + break; + case 5: //Special hack for Paeth686 (Doesn't have to be case 5) + while (i < x) + { + opixbuf1[xm] = (char)(Paeth686(opixbuf1[xm],olinbuf[xplc],opixbuf0[xm])+buf[i]); + opixbuf0[xm] = olinbuf[xplc]; + olinbuf[xplc] = opixbuf1[xm]; + xm = xmn[xm]; xplc--; i++; + } + break; + } + + if (xplc > 0) return; + + //Draw line! + if ((unsigned long)yplc < (unsigned long)yres) + { + x = xr0; p = nfplace; + switch (coltype) + { + case 2: + rgbhlineasm(x,xr1,p,ixstp); + break; + case 4: + for(;x>xr1;p+=ixstp,x-=2) + { +#if (PROCESSALPHAHERE == 1) + //Enable this code to process alpha right here! + if (olinbuf[x-1] == 255) { *(long *)p = palcol[olinbuf[x]]; continue; } + if (!olinbuf[x-1]) { *(long *)p = bakcol; continue; } + //I do >>8, but theoretically should be: /255 + *(char *)(p) = *(char *)(p+1) = *(char *)(p+2) = *(char *)(p+3) = + (((((long)olinbuf[x])-bakr)*(long)olinbuf[x-1])>>8) + bakr; +#else + *(long *)p = (palcol[olinbuf[x]]&LSWAPIB(0xffffff))|LSWAPIL((long)olinbuf[x-1]); +#endif + } + break; + case 6: + for(;x>xr1;p+=ixstp,x-=4) + { +#if (PROCESSALPHAHERE == 1) + //Enable this code to process alpha right here! + if (olinbuf[x-1] == 255) { *(long *)p = *(long *)&olinbuf[x]; continue; } + if (!olinbuf[x-1]) { *(long *)p = bakcol; continue; } + //I do >>8, but theoretically should be: /255 + *(char *)(p ) = (((((long)olinbuf[x ])-bakr)*(long)olinbuf[x-1])>>8) + bakr; + *(char *)(p+1) = (((((long)olinbuf[x+1])-bakg)*(long)olinbuf[x-1])>>8) + bakg; + *(char *)(p+2) = (((((long)olinbuf[x+2])-bakb)*(long)olinbuf[x-1])>>8) + bakb; +#else + *(char *)(p ) = olinbuf[x ]; //R + *(char *)(p+1) = olinbuf[x+1]; //G + *(char *)(p+2) = olinbuf[x+2]; //B + *(char *)(p+3) = olinbuf[x-1]; //A +#endif + } + break; + default: + switch(bitdepth) + { + case 1: for(;x>xr1;p+=ixstp,x-- ) *(long *)p = palcol[olinbuf[x>>3]>>(x&7)]; break; + case 2: for(;x>xr1;p+=ixstp,x-=2) *(long *)p = palcol[olinbuf[x>>3]>>(x&6)]; break; + case 4: for(;x>xr1;p+=ixstp,x-=4) *(long *)p = palcol[olinbuf[x>>3]>>(x&4)]; break; + case 8: pal8hlineasm(x,xr1,p,ixstp); break; //for(;x>xr1;p+=ixstp,x--) *(long *)p = palcol[olinbuf[x]]; break; + } + break; + } + nfplace += nbpl; + } + + *(long *)&opixbuf0[0] = *(long *)&opixbuf1[0] = 0; + xplc = xsizbpl; yplc += iystp; + if ((intlac) && (yplc >= globyoffs+ysiz)) { intlac--; initpass(); } + if (i < leng) { filt = buf[i++]; if (filt == gotcmov) filt = 5; } else filt = -1; + } +} + +static void initpngtables() +{ + long i, j, k; + + //hxbit[0-58][0-1] is a combination of 4 different tables: + // 1st parameter: [0-29] are distances, [30-58] are lengths + // 2nd parameter: [0]: extra bits, [1]: base number + + j = 1; k = 0; + for(i=0;i<30;i++) + { + hxbit[i][1] = j; j += (1<= 2)); + } + j = 3; k = 0; + for(i=257;i<285;i++) + { + hxbit[i+30-257][1] = j; j += (1<= 264)); + } + hxbit[285+30-257][1] = 258; hxbit[285+30-257][0] = 0; + + k = getcputype(); + if (k&(1<<15)) + { + gotcmov = 4; + for(i=0;i<512;i++) abstab10[512+i] = abstab10[512-i] = i; + } +} + +static long kpngrend (const char *kfilebuf, long kfilength, + long daframeplace, long dabytesperline, long daxres, long dayres, + long daglobxoffs, long daglobyoffs) +{ + long i, j, k, bfinal, btype, hlit, hdist, leng; + long slidew, slider; + //long qhuf0v, qhuf1v; + + if (!pnginited) { pnginited = 1; initpngtables(); } + + if ((*(long *)&kfilebuf[0] != LSWAPIB(0x474e5089)) || (*(long *)&kfilebuf[4] != LSWAPIB(0x0a1a0a0d))) + return(-1); //"Invalid PNG file signature" + filptr = (unsigned char *)&kfilebuf[8]; + + trnsrgb = 0; + + while (1) + { + leng = LSWAPIL(*(long *)&filptr[0]); i = *(long *)&filptr[4]; + filptr = &filptr[8]; + + if (i == LSWAPIB(0x52444849)) //IHDR (must be first) + { + xsiz = LSWAPIL(*(long *)&filptr[0]); if (xsiz <= 0) return(-1); + ysiz = LSWAPIL(*(long *)&filptr[4]); if (ysiz <= 0) return(-1); + bitdepth = filptr[8]; if (!((1<= 2) return(-1); //"Unsupported interlace type" + intlac = filptr[12]*7; //0=no interlace/1=Adam7 interlace + + //Save code by making grayscale look like a palette color scheme + if ((!coltype) || (coltype == 4)) + { + j = 0xff000000; k = (255 / ((1<=0;i--) palcol[i] = LSWAPIB((LSWAPIL(*(long *)&filptr[i*3])>>8)|0xff000000); + } + else if (i == LSWAPIB(0x44474b62)) //bKGD (must be after PLTE and before IDAT) + { + switch(coltype) + { + case 0: case 4: + bakcol = (((long)filptr[0]<<8)+(long)filptr[1])*255/((1<>16)&255); + bakg = ((bakcol>>8)&255); + bakb = (bakcol&255); + bakcol = LSWAPIB(bakcol); + } + else if (i == LSWAPIB(0x534e5274)) //tRNS (must be after PLTE and before IDAT) + { + switch(coltype) + { + case 0: + if (bitdepth <= 8) + palcol[(long)filptr[1]] &= LSWAPIB(0xffffff); + //else {} // /c0 /d16 not yet supported + break; + case 2: + if (bitdepth == 8) + { trnsrgb = LSWAPIB((((long)filptr[1])<<16)+(((long)filptr[3])<<8)+((long)filptr[5])+0xff000000); } + //else {} //WARNING: PNG docs say: MUST compare all 48 bits :( + break; + case 3: + for(i=min(leng,paleng)-1;i>=0;i--) + palcol[i] &= LSWAPIB((((long)filptr[i])<<24)|0xffffff); + break; + default:; + } + } + else if (i == LSWAPIB(0x54414449)) { break; } //IDAT + + filptr = &filptr[leng+4]; //crc = LSWAPIL(*(long *)&filptr[-4]); + } + + //Initialize this for the getbits() function + zipfilmode = 0; + filptr = &filptr[leng-4]; bitpos = -((leng-4)<<3); nfilptr = 0; + //if (leng < 4) will it crash? + + frameplace = daframeplace; + bytesperline = dabytesperline; + xres = daxres; + yres = dayres; + globxoffs = daglobxoffs; + globyoffs = daglobyoffs; + + switch (coltype) + { + case 4: xmn[0] = 1; xmn[1] = 0; break; + case 2: xmn[0] = 1; xmn[1] = 2; xmn[2] = 0; break; + case 6: xmn[0] = 1; xmn[1] = 2; xmn[2] = 3; xmn[3] = 0; break; + default: xmn[0] = 0; break; + } + switch (bitdepth) + { + case 1: for(i=2;i<256;i++) palcol[i] = palcol[i&1]; break; + case 2: for(i=4;i<256;i++) palcol[i] = palcol[i&3]; break; + case 4: for(i=16;i<256;i++) palcol[i] = palcol[i&15]; break; + } + + //coltype: bitdepth: format: + // 0 1,2,4,8,16 I + // 2 8,16 RGB + // 3 1,2,4,8 P + // 4 8,16 IA + // 6 8,16 RGBA + xsizbpl = ((0x04021301>>(coltype<<2))&15)*xsiz; + switch (bitdepth) + { + case 1: xsizbpl = ((xsizbpl+7)>>3); break; + case 2: xsizbpl = ((xsizbpl+3)>>2); break; + case 4: xsizbpl = ((xsizbpl+1)>>1); break; + } + //Tests to see if xsiz > allocated space in olinbuf + //Note: xsizbpl gets re-written inside initpass() + if ((xsizbpl+1)*sizeof(olinbuf[0]) > sizeof(olinbuf)) return(-1); + + initpass(); + + slidew = 0; slider = 16384; + suckbits(16); //Actually 2 fields: 8:compmethflags, 8:addflagscheck + do + { + bfinal = getbits(1); btype = getbits(2); + if (btype == 0) + { + //Raw (uncompressed) + suckbits((-bitpos)&7); //Synchronize to start of next byte + i = getbits(16); if ((getbits(16)^i) != 0xffff) return(-1); + for(;i;i--) + { + if (slidew >= slider) + { + putbuf(&slidebuf[(slider-16384)&32767],16384); slider += 16384; + if ((yplc >= yres) && (intlac < 2)) return(0); + } + slidebuf[(slidew++)&32767] = (char)getbits(8); + } + continue; + } + if (btype == 3) continue; + + if (btype == 1) //Fixed Huffman + { + hlit = 288; hdist = 32; i = 0; + for(;i<144;i++) clen[i] = 8; //Fixed bit sizes (literals) + for(;i<256;i++) clen[i] = 9; //Fixed bit sizes (literals) + for(;i<280;i++) clen[i] = 7; //Fixed bit sizes (EOI,lengths) + for(;i<288;i++) clen[i] = 8; //Fixed bit sizes (lengths) + for(;i<320;i++) clen[i] = 5; //Fixed bit sizes (distances) + } + else //Dynamic Huffman + { + hlit = getbits(5)+257; hdist = getbits(5)+1; j = getbits(4)+4; + for(i=0;i= slider) + { + putbuf(&slidebuf[(slider-16384)&32767],16384); slider += 16384; + if ((yplc >= yres) && (intlac < 2)) return(0); + } + + k = peekbits(LOGQHUFSIZ0); + if (qhufbit0[k]) { i = qhufval0[k]; suckbits((long)qhufbit0[k]); } else i = hufgetsym(ibuf0,nbuf0); + //else i = hufgetsym_skipb(ibuf0,nbuf0,LOGQHUFSIZ0,qhuf0v); //hufgetsym_skipb related code + + if (i < 256) { slidebuf[(slidew++)&32767] = (char)i; continue; } + if (i == 256) break; + i = getbits(hxbit[i+30-257][0]) + hxbit[i+30-257][1]; + + k = peekbits(LOGQHUFSIZ1); + if (qhufbit1[k]) { j = qhufval1[k]; suckbits((long)qhufbit1[k]); } else j = hufgetsym(ibuf1,nbuf1); + //else j = hufgetsym_skipb(ibuf1,nbuf1,LOGQHUFSIZ1,qhuf1v); //hufgetsym_skipb related code + + j = getbits(hxbit[j][0]) + hxbit[j][1]; + i += slidew; do { slidebuf[slidew&32767] = slidebuf[(slidew-j)&32767]; slidew++; } while (slidew < i); + } + } while (!bfinal); + + slider -= 16384; + if (!((slider^slidew)&32768)) + putbuf(&slidebuf[slider&32767],slidew-slider); + else + { + putbuf(&slidebuf[slider&32767],(-slider)&32767); + putbuf(slidebuf,slidew&32767); + } + return(0); +} + +//============================= KPNGILIB ends ================================ +//============================ KPEGILIB begins =============================== + + //11/01/2000: This code was originally from KPEG.C + // All non 32-bit color drawing was removed + // "Motion" JPG code was removed + // A lot of parameters were added to kpeg() for library usage +static long kpeginited = 0; +static long clipxdim, clipydim; + +static long hufmaxatbit[8][20], hufvalatbit[8][20], hufcnt[8]; +static unsigned char hufnumatbit[8][20], huftable[8][256]; +static long hufquickval[8][1024], hufquickbits[8][1024], hufquickcnt[8]; +static long quantab[4][64], dct[12][64], lastdc[4], unzig[64], zigit[64]; //dct:10=MAX (says spec);+2 for hacks +static unsigned char gnumcomponents, dcflagor[64]; +static long gcompid[4], gcomphsamp[4], gcompvsamp[4], gcompquantab[4], gcomphsampshift[4], gcompvsampshift[4]; +static long lnumcomponents, lcompid[4], lcompdc[4], lcompac[4], lcomphsamp[4], lcompvsamp[4], lcompquantab[4]; +static long lcomphvsamp0, lcomphsampshift0, lcompvsampshift0; +static long colclip[1024], colclipup8[1024], colclipup16[1024]; +static unsigned char pow2char[8] = {1,2,4,8,16,32,64,128}; + +#if defined(NOASM) + +static inline long mulshr24 (long a, long b) +{ + return((long)((((__int64)a)*((__int64)b))>>24)); +} + +static inline long mulshr32 (long a, long b) +{ + return((long)((((__int64)a)*((__int64)b))>>32)); +} + +#elif defined(__WATCOMC__) + +long mulshr24 (long, long); +#pragma aux mulshr24 =\ + "imul edx"\ + "shrd eax, edx, 24"\ + parm nomemory [eax][edx]\ + modify exact [eax edx] + +long mulshr32 (long, long); +#pragma aux mulshr32 =\ + "imul edx"\ + parm nomemory [eax][edx]\ + modify exact [eax edx]\ + value [edx] + +#elif defined(_MSC_VER) + +static _inline long mulshr24 (long a, long d) +{ + _asm + { + mov eax, a + imul d + shrd eax, edx, 24 + } +} + +static _inline long mulshr32 (long a, long d) +{ + _asm + { + mov eax, a + imul d + mov eax, edx + } +} + +#elif defined(__GNUC__) && defined(__i386__) + +#define mulshr24(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx; shrdl $24, %%edx, %%eax" \ + : "+a" (__a), "+d" (__d) : : "cc"); \ + __a; }) + +#define mulshr32(a,d) \ + ({ long __a=(a), __d=(d); \ + __asm__ __volatile__ ("imull %%edx" \ + : "+a" (__a), "+d" (__d) : : "cc"); \ + __d; }) + +#else + +#error Unsupported compiler or architecture. + +#endif + +static long cosqr16[8] = //cosqr16[i] = ((cos(PI*i/16)*sqrt(2))<<24); + {23726566,23270667,21920489,19727919,16777216,13181774,9079764,4628823}; +static long crmul[4096], cbmul[4096]; + +static void initkpeg () +{ + long i, x, y; + + x = 0; //Back & forth diagonal pattern (aligning bytes for best compression) + for(i=0;i<16;i+=2) + { + for(y=8-1;y>=0;y--) + if ((unsigned)(i-y) < (unsigned)8) unzig[x++] = (y<<3)+i-y; + for(y=0;y<8;y++) + if ((unsigned)(i+1-y) < (unsigned)8) unzig[x++] = (y<<3)+i+1-y; + } + for(i=64-1;i>=0;i--) zigit[unzig[i]] = i; + for(i=64-1;i>=0;i--) dcflagor[i] = (unsigned char)(1<<(unzig[i]>>3)); + + for(i=0;i<128;i++) colclip[i] = i+128; + for(i=128;i<512;i++) colclip[i] = 255; + for(i=512;i<896;i++) colclip[i] = 0; + for(i=896;i<1024;i++) colclip[i] = i-896; + for(i=0;i<1024;i++) + { + colclipup8[i] = (colclip[i]<<8); + colclipup16[i] = (colclip[i]<<16)+0xff000000; //Hack: set alphas to 255 + } +#if defined(BIGENDIAN) + for(i=0;i<1024;i++) + { + colclip[i] = bswap(colclip[i]); + colclipup8[i] = bswap(colclipup8[i]); + colclipup16[i] = bswap(colclipup16[i]); + } +#endif + + for(i=0;i<2048;i++) + { + crmul[(i<<1)+0] = (i-1024)*1470104; //1.402*1048576 + crmul[(i<<1)+1] = (i-1024)*-748830; //-0.71414*1048576 + cbmul[(i<<1)+0] = (i-1024)*-360857; //-0.34414*1048576 + cbmul[(i<<1)+1] = (i-1024)*1858077; //1.772*1048576 + } + + memset((void *)&dct[10][0],0,64*2*sizeof(dct[0][0])); +} + +static void huffgetval (long index, long curbits, long num, long *daval, long *dabits) +{ + long b, v, pow2, *hmax; + + hmax = &hufmaxatbit[index][0]; + pow2 = pow2long[curbits-1]; + if (num&pow2) v = 1; else v = 0; + for(b=1;b<=16;b++) + { + if (v < hmax[b]) + { + *dabits = b; + *daval = huftable[index][hufvalatbit[index][b]+v]; + return; + } + pow2 >>= 1; v <<= 1; + if (num&pow2) v++; + } + *dabits = 16; *daval = 0; +} + +static void invdct8x8 (long *dc, unsigned char dcflag) +{ + #define SQRT2 23726566 //(sqrt(2))<<24 + #define C182 31000253 //(cos(PI/8)*2)<<24 + #define C18S22 43840978 //(cos(PI/8)*sqrt(2)*2)<<24 + #define C38S22 18159528 //(cos(PI*3/8)*sqrt(2)*2)<<24 + long *edc, t0, t1, t2, t3, t4, t5, t6, t7; + + edc = dc+64; + do + { + if (dcflag&1) //pow2char[z]) + { + t3 = dc[2] + dc[6]; + t2 = (mulshr32(dc[2]-dc[6],SQRT2<<6)<<2) - t3; + t4 = dc[0] + dc[4]; t5 = dc[0] - dc[4]; + t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2; + t4 = (mulshr32(dc[5]-dc[3]+dc[1]-dc[7],C182<<6)<<2); + t7 = dc[1] + dc[7] + dc[5] + dc[3]; + t6 = (mulshr32(dc[3]-dc[5],C18S22<<5)<<3) + t4 - t7; + t5 = (mulshr32(dc[1]+dc[7]-dc[5]-dc[3],SQRT2<<6)<<2) - t6; + t4 = (mulshr32(dc[1]-dc[7],C38S22<<6)<<2) - t4 + t5; + dc[0] = t0+t7; dc[7] = t0-t7; dc[1] = t1+t6; dc[6] = t1-t6; + dc[2] = t2+t5; dc[5] = t2-t5; dc[4] = t3+t4; dc[3] = t3-t4; + } + dc += 8; dcflag >>= 1; + } while (dc < edc); + dc -= 32; edc -= 24; + do + { + t3 = dc[2*8-32] + dc[6*8-32]; + t2 = (mulshr32(dc[2*8-32]-dc[6*8-32],SQRT2<<6)<<2) - t3; + t4 = dc[0*8-32] + dc[4*8-32]; t5 = dc[0*8-32] - dc[4*8-32]; + t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2; + t4 = (mulshr32(dc[5*8-32]-dc[3*8-32]+dc[1*8-32]-dc[7*8-32],C182<<6)<<2); + t7 = dc[1*8-32] + dc[7*8-32] + dc[5*8-32] + dc[3*8-32]; + t6 = (mulshr32(dc[3*8-32]-dc[5*8-32],C18S22<<5)<<3) + t4 - t7; + t5 = (mulshr32(dc[1*8-32]+dc[7*8-32]-dc[5*8-32]-dc[3*8-32],SQRT2<<6)<<2) - t6; + t4 = (mulshr32(dc[1*8-32]-dc[7*8-32],C38S22<<6)<<2) - t4 + t5; + dc[0*8-32] = t0+t7; dc[7*8-32] = t0-t7; dc[1*8-32] = t1+t6; dc[6*8-32] = t1-t6; + dc[2*8-32] = t2+t5; dc[5*8-32] = t2-t5; dc[4*8-32] = t3+t4; dc[3*8-32] = t3-t4; + dc++; + } while (dc < edc); +} + +static void yrbrend (long x, long y) +{ + long i, j, ox, oy, xx, yy, xxx, yyy, xxxend, yyyend, yv, cr, cb, p, pp, *odc, *dc, *dc2; + + odc = dct[0]; dc2 = dct[10]; + for(yy=0;yy<(lcompvsamp[0]<<3);yy+=8) + { + oy = y+yy+globyoffs; if ((unsigned)oy >= (unsigned)clipydim) { odc += (lcomphsamp[0]<<6); continue; } + pp = oy*bytesperline + ((x+globxoffs)<<2) + frameplace; + for(xx=0;xx<(lcomphsamp[0]<<3);xx+=8,odc+=64) + { + ox = x+xx+globxoffs; if ((unsigned)ox >= (unsigned)clipxdim) continue; + p = pp+(xx<<2); + dc = odc; + if (lnumcomponents > 1) dc2 = &dct[lcomphvsamp0][((yy>>lcompvsampshift0)<<3)+(xx>>lcomphsampshift0)]; + xxxend = min(clipxdim-ox,8); + yyyend = min(clipydim-oy,8); + if ((lcomphsamp[0] == 1) && (xxxend == 8)) + { + for(yyy=0;yyy>13)&~1; + cb = (dc2[xxx ]>>13)&~1; + ((long *)p)[xxx] = colclipup16[(unsigned)(yv+crmul[cr+2048] )>>22]+ + colclipup8[(unsigned)(yv+crmul[cr+2049]+cbmul[cb+2048])>>22]+ + colclip[(unsigned)(yv+cbmul[cb+2049] )>>22]; + } + p += bytesperline; + dc += 8; + if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8; + } + } + else if ((lcomphsamp[0] == 2) && (xxxend == 8)) + { + for(yyy=0;yyy>1)+64]>>13)&~1; + cb = (dc2[(xxx>>1) ]>>13)&~1; + i = crmul[cr+2049]+cbmul[cb+2048]; + cr = crmul[cr+2048]; + cb = cbmul[cb+2049]; + ((long *)p)[xxx] = colclipup16[(unsigned)(yv+cr)>>22]+ + colclipup8[(unsigned)(yv+ i)>>22]+ + colclip[(unsigned)(yv+cb)>>22]; + yv = dc[xxx+1]; + ((long *)p)[xxx+1] = colclipup16[(unsigned)(yv+cr)>>22]+ + colclipup8[(unsigned)(yv+ i)>>22]+ + colclip[(unsigned)(yv+cb)>>22]; + } + p += bytesperline; + dc += 8; + if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8; + } + } + else + { + for(yyy=0;yyy>13)&~1; + cb = (dc2[i ]>>13)&~1; + i++; + } + ((long *)p)[xxx] = colclipup16[(unsigned)(yv+crmul[cr+2048] )>>22]+ + colclipup8[(unsigned)(yv+crmul[cr+2049]+cbmul[cb+2048])>>22]+ + colclip[(unsigned)(yv+cbmul[cb+2049] )>>22]; + } + p += bytesperline; + dc += 8; + if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8; + } + } + } + } +} + +static long kpegrend (const char *kfilebuf, long kfilength, + long daframeplace, long dabytesperline, long daxres, long dayres, + long daglobxoffs, long daglobyoffs) +{ + long i, j, p, v, leng, xdim, ydim, index, prec, restartcnt, restartinterval; + long x, y, z, xx, yy, zz, *dc, *dc2, num, curbits, c, daval, dabits, *hqval, *hqbits, hqcnt, *quanptr; + long passcnt = 0, ghsampmax, gvsampmax, glhsampmax, glvsampmax, glhstep, glvstep; + long eobrun, Ss, Se, Ah, Al, Alut[2], dctx[12], dcty[12], ldctx[12], ldcty[12], lshx[4], lshy[4]; + short *dctbuf = 0, *dctptr[12], *ldctptr[12], *dcs; + unsigned char ch, marker, dcflag; + const unsigned char *kfileptr; + + if (!kpeginited) { kpeginited = 1; initkpeg(); } + + kfileptr = (unsigned char *)kfilebuf; + + if (*(unsigned short *)kfileptr == SSWAPIB(0xd8ff)) kfileptr += 2; + else return(-1); //"%s is not a JPEG file\n",filename + + restartinterval = 0; + for(i=0;i<4;i++) lastdc[i] = 0; + for(i=0;i<8;i++) hufcnt[i] = 0; + + coltype = 0; bitdepth = 8; //For PNGOUT + do + { + ch = *kfileptr++; if (ch != 255) continue; + do { marker = *kfileptr++; } while (marker == 255); + if (marker != 0xd9) //Don't read past end of buffer + { + leng = ((long)kfileptr[0]<<8)+(long)kfileptr[1]-2; + kfileptr += 2; + } + //printf("fileoffs=%08x, marker=%02x,leng=%d",((long)kfileptr)-((long)kfilebuf)-2,marker,leng); + switch(marker) + { + case 0xc0: case 0xc1: case 0xc2: + //processit! + kfileptr++; //numbits = *kfileptr++; + + ydim = SSWAPIL(*(unsigned short *)&kfileptr[0]); + xdim = SSWAPIL(*(unsigned short *)&kfileptr[2]); + //printf("%s: %ld / %ld = %ld\n",filename,xdim*ydim*3,kfilength,(xdim*ydim*3)/kfilength); + + frameplace = daframeplace; + bytesperline = dabytesperline; + xres = daxres; + yres = dayres; + globxoffs = daglobxoffs; + globyoffs = daglobyoffs; + + gnumcomponents = kfileptr[4]; + kfileptr += 5; + ghsampmax = gvsampmax = glhsampmax = glvsampmax = 0; + for(z=0;z>4); + gcompvsamp[z] = (kfileptr[1]&15); + gcompquantab[z] = kfileptr[2]; + for(i=0;i<8;i++) if (gcomphsamp[z] == pow2long[i]) { gcomphsampshift[z] = i; break; } + for(i=0;i<8;i++) if (gcompvsamp[z] == pow2long[i]) { gcompvsampshift[z] = i; break; } + if (gcomphsamp[z] > ghsampmax) { ghsampmax = gcomphsamp[z]; glhsampmax = gcomphsampshift[z]; } + if (gcompvsamp[z] > gvsampmax) { gvsampmax = gcompvsamp[z]; glvsampmax = gcompvsampshift[z]; } + kfileptr += 3; + } + + break; + case 0xc4: //Huffman table + do + { + ch = *kfileptr++; leng--; + if (ch >= 16) { index = ch-12; } + else { index = ch; } + memcpy((void *)&hufnumatbit[index][1],(void *)kfileptr,16); kfileptr += 16; + leng -= 16; + + v = 0; hufcnt[index] = 0; + hufquickcnt[index] = 0; + for(i=1;i<=16;i++) + { + hufmaxatbit[index][i] = v+hufnumatbit[index][i]; + hufvalatbit[index][i] = hufcnt[index]-v; + memcpy((void *)&huftable[index][hufcnt[index]],(void *)kfileptr,(long)hufnumatbit[index][i]); + if (i <= 10) + for(c=0;c0;j--) + { + hufquickval[index][hufquickcnt[index]] = huftable[index][hufcnt[index]+c]; + hufquickbits[index][hufquickcnt[index]] = i; + hufquickcnt[index]++; + } + kfileptr += hufnumatbit[index][i]; + leng -= hufnumatbit[index][i]; + hufcnt[index] += hufnumatbit[index][i]; + v = ((v+hufnumatbit[index][i])<<1); + } + + } while (leng > 0); + break; + case 0xdb: + do + { + ch = *kfileptr++; leng--; + index = (ch&15); + prec = (ch>>4); + for(z=0;z<64;z++) + { + v = (long)(*kfileptr++); + if (prec) v = (v<<8)+((long)(*kfileptr++)); + v <<= 19; + if (unzig[z]&7 ) v = mulshr24(v,cosqr16[unzig[z]&7 ]); + if (unzig[z]>>3) v = mulshr24(v,cosqr16[unzig[z]>>3]); + if (index) v >>= 6; + quantab[index][unzig[z]] = v; + } + leng -= 64; + if (prec) leng -= 64; + } while (leng > 0); + break; + case 0xdd: + restartinterval = SSWAPIL(*(unsigned short *)&kfileptr[0]); + kfileptr += leng; + break; + case 0xda: + if ((xdim <= 0) || (ydim <= 0)) { if (dctbuf) free(dctbuf); return(-1); } + + lnumcomponents = (long)(*kfileptr++); if (!lnumcomponents) { if (dctbuf) free(dctbuf); return(-1); } + if (lnumcomponents > 1) coltype = 2; + for(z=0;z>4); + lcompac[z] = (kfileptr[1]&15); + kfileptr += 2; + } + + Ss = kfileptr[0]; + Se = kfileptr[1]; + Ah = (kfileptr[2]>>4); + Al = (kfileptr[2]&15); + kfileptr += 3; + //printf("passcnt=%d, Ss=%d, Se=%d, Ah=%d, Al=%d\n",passcnt,Ss,Se,Ah,Al); + + if ((!passcnt) && ((Ss) || (Se != 63) || (Ah) || (Al))) + { + for(z=zz=0;z>(glhsampmax+3)) << gcomphsampshift[z]; + dcty[z] = ((ydim+(gvsampmax<<3)-1)>>(glvsampmax+3)) << gcompvsampshift[z]; + zz += dctx[z]*dcty[z]; + } + z = zz*64*sizeof(short); + dctbuf = (short *)malloc(z); if (!dctbuf) return(-1); + memset(dctbuf,0,z); + for(z=zz=0;z>glhstep); lcomphsamp[0] = min(lcomphsamp[0],glhstep); glhstep <<= 3; + glvstep = (gvsampmax>>glvstep); lcompvsamp[0] = min(lcompvsamp[0],glvstep); glvstep <<= 3; + lcomphvsamp0 = lcomphsamp[0]*lcompvsamp[0]; + + clipxdim = min(xdim+globxoffs,xres); + clipydim = min(ydim+globyoffs,yres); + + if ((max(globxoffs,0) >= xres) || (min(globxoffs+xdim,xres) <= 0) || + (max(globyoffs,0) >= yres) || (min(globyoffs+ydim,yres) <= 0)) + { if (dctbuf) free(dctbuf); return(0); } + + Alut[0] = (1<= kfilength) goto kpegrend_break2; //rest of file is missing! + + if (!dctbuf) dc = dct[0]; + for(c=0;c>lshy[c])*ldctx[c] + ((x+xx)>>lshx[c]))<<6]; + + //Get DC + if (!Ss) + { + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + + if (!Ah) + { + i = ((num>>(curbits-10))&1023); + if (i < hufquickcnt[lcompdc[c]]) + { daval = hufquickval[lcompdc[c]][i]; curbits -= hufquickbits[lcompdc[c]][i]; } + else { huffgetval(lcompdc[c],curbits,num,&daval,&dabits); curbits -= dabits; } + + if (daval) + { + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + + curbits -= daval; v = ((unsigned)num >> curbits) & pow2mask[daval]; + if (v <= pow2mask[daval-1]) v -= pow2mask[daval]; + lastdc[c] += v; + } + if (!dctbuf) dc[0] = lastdc[c]; else dcs[0] = (short)(lastdc[c]<>(curbits-10))&1023); + if (i < hqcnt) + { daval = hqval[i]; curbits -= hqbits[i]; } + else { huffgetval(lcompac[c]+4,curbits,num,&daval,&dabits); curbits -= dabits; } + + zz = (daval>>4); daval &= 15; + if (daval) + { + if (Ah) + { + //NOTE: Getbits not needed here - buffer should have enough bits + if (num&(pow2long[--curbits])) daval = Alut[0]; else daval = Alut[1]; + } + } + else if (zz < 15) + { + eobrun = pow2long[zz]; + if (zz) + { + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + curbits -= zz; eobrun += ((unsigned)num >> curbits) & pow2mask[zz]; + } + if (!Ah) eobrun--; + break; + } + if (Ah) + { + do + { + if (dcs[z]) + { + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + if (num&(pow2long[--curbits])) dcs[z] += ((short)Alut[dcs[z] < 0]); + } else if (--zz < 0) break; + z++; + } while (z <= Se); + if (daval) dcs[z] = daval; + } + else + { + z += zz; if (z > Se) break; + + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + curbits -= daval; v = ((unsigned)num >> curbits) & pow2mask[daval]; + if (v <= pow2mask[daval-1]) v -= pow2mask[daval]; + dcflag |= dcflagor[z]; + if (!dctbuf) dc[unzig[z]] = v; else dcs[z] = (short)(v< 0)) + { + eobrun--; + for(;z<=Se;z++) + { + if (!dcs[z]) continue; + while (curbits < 24) //Getbits + { + ch = *kfileptr++; if (ch == 255) kfileptr++; + num = (num<<8)+((long)ch); curbits += 8; + } + if (num&(pow2long[--curbits])) dcs[z] += ((short)Alut[dcs[z] < 0]); + } + } + + if (!dctbuf) + { + for(z=64-1;z>=0;z--) dc[z] *= quanptr[z]; + invdct8x8(dc,dcflag); dc += 64; + } + } + } + + if (!dctbuf) yrbrend(x,y); + + restartcnt--; + if (!restartcnt) + { + kfileptr += 1-(curbits>>3); curbits = 0; + if ((kfileptr[-2] != 255) || (kfileptr[-1] != marker)) kfileptr--; + marker++; if (marker >= 0xd8) marker = 0xd0; + restartcnt = restartinterval; + for(i=0;i<4;i++) lastdc[i] = 0; + eobrun = 0; + } + } +kpegrend_break2:; + if (!dctbuf) return(0); + passcnt++; kfileptr -= ((curbits>>3)+1); break; + case 0xd9: break; + default: kfileptr += leng; break; + } + } while (kfileptr-(unsigned char *)kfilebuf < kfilength); + + if (!dctbuf) return(0); + + lnumcomponents = gnumcomponents; + for(i=0;i>lshy[c])*dctx[c] + ((x+xx)>>lshx[c]))<<6]; + quanptr = &quantab[gcompquantab[c]][0]; + for(z=0;z<64;z++) dc[z] = ((long)dcs[zigit[z]])*quanptr[z]; + invdct8x8(dc,-1); + } + yrbrend(x,y); + } + + free(dctbuf); return(0); +} + +//============================== KPEGILIB ends ============================== +//================================ GIF begins ================================ + +static unsigned char suffix[4100], filbuffer[768], tempstack[4096]; +static long prefix[4100]; + +static long kgifrend (const char *kfilebuf, long kfilelength, + long daframeplace, long dabytesperline, long daxres, long dayres, + long daglobxoffs, long daglobyoffs) +{ + long i, x, y, xsiz, ysiz, yinc, xend, xspan, yspan, currstr, numbitgoal; + long lzcols, dat, blocklen, bitcnt, xoff, yoff, transcol, backcol, *lptr; + char numbits, startnumbits, chunkind, ilacefirst; + const unsigned char *ptr, *cptr; + + coltype = 3; bitdepth = 8; //For PNGOUT + + if ((kfilebuf[0] != 'G') || (kfilebuf[1] != 'I') || + (kfilebuf[2] != 'F') || (kfilebuf[12])) return(-1); + paleng = (1<<((kfilebuf[10]&7)+1)); + ptr = (unsigned char *)&kfilebuf[13]; + if (kfilebuf[10]&128) { cptr = ptr; ptr += paleng*3; } + transcol = -1; + while ((chunkind = *ptr++) == '!') + { //! 0xf9 leng flags ?? ?? transcol + if (ptr[0] == 0xf9) { if (ptr[2]&1) transcol = (long)(((unsigned char)ptr[5])); } + ptr++; + do { i = *ptr++; ptr += i; } while (i); + } + if (chunkind != ',') return(-1); + + xoff = SSWAPIB(*(unsigned short *)&ptr[0]); + yoff = SSWAPIB(*(unsigned short *)&ptr[2]); + xspan = SSWAPIB(*(unsigned short *)&ptr[4]); + yspan = SSWAPIB(*(unsigned short *)&ptr[6]); ptr += 9; + if (ptr[-1]&64) { yinc = 8; ilacefirst = 1; } + else { yinc = 1; ilacefirst = 0; } + if (ptr[-1]&128) + { + paleng = (1<<((ptr[-1]&7)+1)); + cptr = ptr; ptr += paleng*3; + } + + for(i=0;i= 0) palcol[transcol] &= LSWAPIB(~0xff000000); + + //Handle GIF files with different logical&image sizes or non-0 offsets (added 05/15/2004) + xsiz = SSWAPIB(*(unsigned short *)&kfilebuf[6]); + ysiz = SSWAPIB(*(unsigned short *)&kfilebuf[8]); + if ((xoff != 0) || (yoff != 0) || (xsiz != xspan) || (ysiz != yspan)) + { + long xx[4], yy[4]; + if (kfilebuf[10]&128) backcol = palcol[(unsigned char)kfilebuf[11]]; else backcol = 0; + + //Fill border to backcol + xx[0] = max(daglobxoffs , 0); yy[0] = max(daglobyoffs , 0); + xx[1] = min(daglobxoffs+xoff ,daxres); yy[1] = min(daglobyoffs+yoff ,dayres); + xx[2] = max(daglobxoffs+xoff+xspan, 0); yy[2] = min(daglobyoffs+yoff+yspan,dayres); + xx[3] = min(daglobxoffs+xsiz ,daxres); yy[3] = min(daglobyoffs+ysiz ,dayres); + + lptr = (long *)(yy[0]*dabytesperline+daframeplace); + for(y=yy[0];y=0;i--) { suffix[i] = (char)(prefix[i] = i); } + currstr = lzcols+2; numbits = startnumbits; numbitgoal = (lzcols<<1); + blocklen = *ptr++; + memcpy(filbuffer,ptr,blocklen); ptr += blocklen; + bitcnt = 0; + while (1) + { + dat = (LSWAPIB(*(long *)&filbuffer[bitcnt>>3])>>(bitcnt&7)) & (numbitgoal-1); + bitcnt += numbits; + if ((bitcnt>>3) > blocklen-3) + { + *(short *)filbuffer = *(short *)&filbuffer[bitcnt>>3]; + i = blocklen-(bitcnt>>3); + blocklen = (long)*ptr++; + memcpy(&filbuffer[i],ptr,blocklen); ptr += blocklen; + bitcnt &= 7; blocklen += i; + } + if (dat == lzcols) + { + currstr = lzcols+2; numbits = startnumbits; numbitgoal = (lzcols<<1); + continue; + } + if ((currstr == numbitgoal) && (numbits < 12)) + { numbits++; numbitgoal <<= 1; } + + prefix[currstr] = dat; + for(i=0;dat>=lzcols;dat=prefix[dat]) tempstack[i++] = suffix[dat]; + tempstack[i] = (char)prefix[dat]; + suffix[currstr-1] = suffix[currstr] = (char)dat; + + for(;i>=0;i--) + { + if ((unsigned long)x < (unsigned long)daxres) + *(long *)(yoff+(x<<2)) = palcol[(long)tempstack[i]]; + x++; + if (x == xend) + { + y += yinc; + if (y >= yspan) + switch(yinc) + { + case 8: if (!ilacefirst) { y = daglobyoffs+2; yinc = 4; break; } + ilacefirst = 0; y = daglobyoffs+4; yinc = 8; break; + case 4: y = daglobyoffs+1; yinc = 2; break; + case 2: case 1: return(0); + } + if ((unsigned long)y < (unsigned long)dayres) + { yoff = y*dabytesperline+daframeplace; x = daglobxoffs; xend = xspan; } + else + { x = daglobxoffs+0x80000000; xend = xspan+0x80000000; } + } + } + currstr++; + } +} + +//=============================== GIF ends ================================== +//============================== CEL begins ================================= + + // //old .CEL format: + //short id = 0x9119, xdim, ydim, xoff, yoff, id = 0x0008; + //long imagebytes, filler[4]; + //char pal6bit[256][3], image[ydim][xdim]; +static long kcelrend (const char *buf, long fleng, + long daframeplace, long dabytesperline, long daxres, long dayres, + long daglobxoffs, long daglobyoffs) +{ + long i, x, y, x0, x1, y0, y1, xsiz, ysiz; + const char *cptr; + + if ((buf[0] != 0x19) || (buf[1] != 0x91) || + (buf[10] != 8) || (buf[11] != 0)) return(-1); + + coltype = 3; bitdepth = 8; paleng = 256; //For PNGOUT + + xsiz = (long)SSWAPIB(*(unsigned short *)&buf[2]); if (xsiz <= 0) return(-1); + ysiz = (long)SSWAPIB(*(unsigned short *)&buf[4]); if (ysiz <= 0) return(-1); + + cptr = &buf[32]; + for(i=0;i<256;i++) + { + palcol[i] = (((long)cptr[0])<<18) + + (((long)cptr[1])<<10) + + (((long)cptr[2])<< 2) + LSWAPIB(0xff000000); + cptr += 3; + } + + x0 = daglobyoffs; x1 = xsiz+daglobyoffs; + y0 = daglobyoffs; y1 = ysiz+daglobyoffs; + for(y=y0;y= 12) || (!((1< 32)) return(-1); + if (header[17]&0xc0) return(-1); + + fptr = (unsigned char *)&header[header[0]+18]; + xsiz = (long)SSWAPIB(*(unsigned short *)&header[12]); if (xsiz <= 0) return(-1); + ysiz = (long)SSWAPIB(*(unsigned short *)&header[14]); if (ysiz <= 0) return(-1); + colbyte = ((((long)header[16])+7)>>3); + + if (header[1] == 1) + { + pixbyte = ((((long)header[7])+7)>>3); + cptr = &fptr[-SSWAPIB(*(unsigned short *)&header[3])*pixbyte]; + fptr += SSWAPIB(*(unsigned short *)&header[5])*pixbyte; + } else pixbyte = colbyte; + + switch(pixbyte) //For PNGOUT + { + case 1: coltype = 0; bitdepth = 8; palcol[0] = LSWAPIB(0xff000000); + for(i=1;i<256;i++) palcol[i] = palcol[i-1]+LSWAPIB(0x10101); break; + case 2: case 3: coltype = 2; break; + case 4: coltype = 6; break; + } + + if (!(header[17]&16)) { x0 = 0; x1 = xsiz; xi = 1; } + else { x0 = xsiz-1; x1 = -1; xi =-1; } + if (header[17]&32) { y0 = 0; y1 = ysiz; yi = 1; pi = dabytesperline; } + else { y0 = ysiz-1; y1 = -1; yi =-1; pi =-dabytesperline; } + x0 += daglobxoffs; y0 += daglobyoffs; + x1 += daglobxoffs; y1 += daglobyoffs; + if (header[2] < 8) rlestat = -2; else rlestat = -1; + + p = y0*dabytesperline+daframeplace; + for(y=y0;y!=y1;y+=yi,p+=pi) + for(x=x0;x!=x1;x+=xi) + { + if (rlestat < 128) + { + if ((rlestat&127) == 127) { rlestat = (long)fptr[0]; fptr++; } + if (header[1] == 1) + { + if (colbyte == 1) i = fptr[0]; + else i = (long)SSWAPIB(*(unsigned short *)&fptr[0]); + nptr = &cptr[i*pixbyte]; + } else nptr = fptr; + + switch(pixbyte) + { + case 1: i = palcol[(long)nptr[0]]; break; + case 2: i = (long)SSWAPIB(*(unsigned short *)&nptr[0]); + i = LSWAPIB(((i&0x7c00)<<9) + ((i&0x03e0)<<6) + ((i&0x001f)<<3) + 0xff000000); + break; + case 3: i = (*(long *)&nptr[0]) | LSWAPIB(0xff000000); break; + case 4: i = (*(long *)&nptr[0]); break; + } + fptr += colbyte; + } + if (rlestat >= 0) rlestat--; + + if (((unsigned long)x < (unsigned long)daxres) && ((unsigned long)y < (unsigned long)dayres)) + *(long *)(x*4+p) = i; + } + return(0); +} + +//============================== TARGA ends ================================= +//============================== BMP begins ================================= + //TODO: handle BI_RLE8 and BI_RLE4 (compression types 1&2 respectively) + // ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + // ³ 0(2): "BM" ³ + // ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿³ 10(4): rastoff³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + // ³headsiz=12 (OS/2 1.x)³³ 14(4): headsiz³ ³ All new formats: ³ + //ÚÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÁÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + //³ 18(2): xsiz ³ 18(4): xsiz ³ + //³ 20(2): ysiz ³ 22(4): ysiz ³ + //³ 22(2): planes (always 1) ³ 26(2): planes (always 1) ³ + //³ 24(2): cdim (1,4,8,24) ³ 28(2): cdim (1,4,8,16,24,32) ³ + //³ if (cdim < 16) ³ 30(4): compression (0,1,2,3!?,4) ³ + //³ 26(rastoff-14-headsiz): pal(bgr) ³ 34(4): (bitmap data size+3)&3 ³ + //³ ³ 46(4): N colors (0=2^cdim) ³ + //³ ³ if (cdim < 16) ³ + //³ ³ 14+headsiz(rastoff-14-headsiz): pal(bgr0) ³ + //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + // ³ rastoff(?): bitmap data ³ + // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +static long kbmprend (const char *buf, long fleng, + long daframeplace, long dabytesperline, long daxres, long dayres, + long daglobxoffs, long daglobyoffs) +{ + long i, j, x, y, x0, x1, y0, y1, rastoff, headsiz, xsiz, ysiz, cdim, comp, cptrinc, *lptr; + const char *cptr; + + headsiz = *(long *)&buf[14]; + if (headsiz == LSWAPIB(12)) //OS/2 1.x (old format) + { + if (*(short *)(&buf[22]) != SSWAPIB(1)) return(-1); + xsiz = (long)SSWAPIB(*(unsigned short *)&buf[18]); + ysiz = (long)SSWAPIB(*(unsigned short *)&buf[20]); + cdim = (long)SSWAPIB(*(unsigned short *)&buf[24]); + comp = 0; + } + else //All newer formats... + { + if (*(short *)(&buf[26]) != SSWAPIB(1)) return(-1); + xsiz = LSWAPIB(*(long *)&buf[18]); + ysiz = LSWAPIB(*(long *)&buf[22]); + cdim = (long)SSWAPIB(*(unsigned short *)&buf[28]); + comp = LSWAPIB(*(long *)&buf[30]); + } + if ((xsiz <= 0) || (!ysiz)) return(-1); + //cdim must be: (1,4,8,16,24,32) + if (((unsigned long)(cdim-1) >= (unsigned long)32) || (!((1<>1); + } + for(palcol[i+3]=0;palcol[i+3]<32;palcol[i+3]++) + { + if (!(j&1)) break; + j = (((unsigned long)j)>>1); + } + } + } + palcol[0] = 24-(palcol[0]+palcol[3]); + palcol[1] = 16-(palcol[1]+palcol[4]); + palcol[2] = 8-(palcol[2]+palcol[5]); + palcol[3] = ((-1<<(24-palcol[3]))&0x00ff0000); + palcol[4] = ((-1<<(16-palcol[4]))&0x0000ff00); + palcol[5] = ((-1<<( 8-palcol[5]))&0x000000ff); + } + + cptrinc = (((xsiz*cdim+31)>>3)&~3); cptr = &buf[rastoff]; + if (ysiz < 0) { ysiz = -ysiz; } else { cptr = &cptr[(ysiz-1)*cptrinc]; cptrinc = -cptrinc; } + + x0 = daglobxoffs; x1 = xsiz+daglobxoffs; + y0 = daglobyoffs; y1 = ysiz+daglobyoffs; + if ((x0 >= daxres) || (x1 <= 0) || (y0 >= dayres) || (y1 <= 0)) return(0); + if (x0 < 0) x0 = 0; + if (x1 > daxres) x1 = daxres; + for(y=y0;y= (unsigned long)dayres) continue; + lptr = (long *)(y*dabytesperline-(daglobyoffs<<2)+daframeplace); + switch(cdim) + { + case 1: for(x=x0;x>3]>>((x&7)^7))&1)]; break; + case 4: for(x=x0;x>1]>>(((x&1)^1)<<2))&15)]; break; + case 8: for(x=x0;x= x1) { x = x0; y++; p += dabytesperline; } + } + } while (y < y1); + } + else if (nplanes == 3) //24-bit PCX + { + do + { + c = *cptr++; if (c < 192) i = 1; else { i = (c&63); c = *cptr++; } + for(;i;i--) + { + if ((unsigned long)y < (unsigned long)dayres) + if ((unsigned long)x < (unsigned long)daxres) *(char *)(x+p) = c; + x += 4; if (x >= x1) { j--; if (j < 0) { j = 3-1; y++; p += dabytesperline; } x = x0+j; } + } + } while (y < y1); + } + + return(0); +} + +//=============================== BMP ends ================================== +//=================== External picture interface begins ====================== + +void kpgetdim (const char *buf, long leng, long *xsiz, long *ysiz) +{ + long *lptr; + const unsigned char *cptr; + unsigned char *ubuf = (unsigned char *)buf; + + (*xsiz) = (*ysiz) = 0; if (leng < 16) return; + if ((ubuf[0] == 0x89) && (ubuf[1] == 0x50)) //.PNG + { + lptr = (long *)buf; + if ((lptr[0] != LSWAPIB(0x474e5089)) || (lptr[1] != LSWAPIB(0x0a1a0a0d))) return; + lptr = &lptr[2]; + while (((unsigned long)lptr-(unsigned long)buf) < (unsigned long)(leng-16)) + { + if (lptr[1] == LSWAPIB(0x52444849)) //IHDR + { (*xsiz) = LSWAPIL(lptr[2]); (*ysiz) = LSWAPIL(lptr[3]); break; } + lptr = (long *)((long)lptr + LSWAPIL(lptr[0]) + 12); + } + } + else if ((ubuf[0] == 0xff) && (ubuf[1] == 0xd8)) //.JPG + { + cptr = (unsigned char *)&buf[2]; + while (((unsigned long)cptr-(unsigned long)buf) < (unsigned long)(leng-8)) + { + if (cptr[0] != 255) { cptr = &cptr[1]; continue; } + if ((unsigned long)(cptr[1]-0xc0) < 3) + { + (*ysiz) = SSWAPIL(*(unsigned short *)&cptr[5]); + (*xsiz) = SSWAPIL(*(unsigned short *)&cptr[7]); + break; + } + cptr = &cptr[SSWAPIL(*(unsigned short *)&cptr[2])+2]; + } + } + else if ((ubuf[0] == 'G') && (ubuf[1] == 'I') && (ubuf[2] == 'F') && (ubuf[12] == 0)) //.GIF + { + (*xsiz) = (long)SSWAPIB(*(unsigned short *)&buf[6]); + (*ysiz) = (long)SSWAPIB(*(unsigned short *)&buf[8]); + } + else if ((ubuf[0] == 0x19) && (ubuf[1] == 0x91) && (ubuf[10] == 8) && (ubuf[11] == 0)) //old .CEL/.PIC + { + (*xsiz) = (long)SSWAPIB(*(unsigned short *)&buf[2]); + (*ysiz) = (long)SSWAPIB(*(unsigned short *)&buf[4]); + } + else if ((ubuf[0] == 'B') && (ubuf[1] == 'M')) //.BMP + { + if (*(long *)(&buf[14]) == LSWAPIB(12)) //OS/2 1.x (old format) + { + if (*(short *)(&buf[22]) != SSWAPIB(1)) return; + (*xsiz) = (long)SSWAPIB(*(unsigned short *)&buf[18]); + (*ysiz) = (long)SSWAPIB(*(unsigned short *)&buf[20]); + } + else //All newer formats... + { + if (*(short *)(&buf[26]) != SSWAPIB(1)) return; + (*xsiz) = LSWAPIB(*(long *)&buf[18]); + (*ysiz) = LSWAPIB(*(long *)&buf[22]); + } + } + else if (*(long *)ubuf == LSWAPIB(0x0801050a)) //.PCX + { + (*xsiz) = SSWAPIB(*(short *)&buf[ 8])-SSWAPIB(*(short *)&buf[4])+1; + (*ysiz) = SSWAPIB(*(short *)&buf[10])-SSWAPIB(*(short *)&buf[6])+1; + } + else + { //Unreliable .TGA identification - this MUST be final case! + if ((leng >= 20) && (!(ubuf[1]&0xfe))) + if ((ubuf[2] < 12) && ((1<= 20) && (!(ubuf[1]&0xfe))) + if ((ubuf[2] < 12) && ((1<= 'a') && (c0 <= 'z')) c0 -= 32; + c1 = *j; if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32; + if (c0 == '/') c0 = '\\'; + if (c1 == '/') c1 = '\\'; + if (c0 != c1) return(0); + i++; j++; + } while (*j); + return(!*i); +} + + //Same as: stricmp(st0,st1) except: '/' == '\' +static long filnamcmp (const char *st0, const char *st1) +{ + long i; + char ch0, ch1; + + for(i=0;st0[i];i++) + { + ch0 = st0[i]; if ((ch0 >= 'a') && (ch0 <= 'z')) ch0 -= 32; + ch1 = st1[i]; if ((ch1 >= 'a') && (ch1 <= 'z')) ch1 -= 32; + if (ch0 == '/') ch0 = '\\'; + if (ch1 == '/') ch1 = '\\'; + if (ch0 != ch1) return(-1); + } + if (!st1[i]) return(0); + return(-1); +} + +//===================== ZIP decompression code begins ======================== + + //format: (used by kzaddstack/kzopen to cache file name&start info) + //[char zipnam[?]\0] + //[next hashindex/-1][next index/-1][zipnam index][zipseek][char filnam[?]\0] + //[next hashindex/-1][next index/-1][zipnam index][zipseek][char filnam[?]\0] + //... + //[char zipnam[?]\0] + //[next hashindex/-1][next index/-1][zipnam index][zipseek][char filnam[?]\0] + //[next hashindex/-1][next index/-1][zipnam index][zipseek][char filnam[?]\0] + //... +#define KZHASHINITSIZE 8192 +static char *kzhashbuf = 0; +static long kzhashead[256], kzhashpos, kzlastfnam, kzhashsiz; + +static long kzcheckhashsiz (long siz) +{ + long i; + + if (!kzhashbuf) //Initialize hash table on first call + { + memset(kzhashead,-1,sizeof(kzhashead)); + kzhashbuf = (char *)malloc(KZHASHINITSIZE); if (!kzhashbuf) return(0); + kzhashpos = 0; kzlastfnam = -1; kzhashsiz = KZHASHINITSIZE; + } + if (kzhashpos+siz > kzhashsiz) //Make sure string fits in kzhashbuf + { + i = kzhashsiz; do { i <<= 1; } while (kzhashpos+siz > i); + kzhashbuf = (char *)realloc(kzhashbuf,i); if (!kzhashbuf) return(0); + kzhashsiz = i; + } + return(1); +} + +static long kzcalchash (const char *st) +{ + long i, hashind; + char ch; + + for(i=0,hashind=0;st[i];i++) + { + ch = st[i]; + if ((ch >= 'a') && (ch <= 'z')) ch -= 32; + if (ch == '/') ch = '\\'; + hashind = (ch - hashind*3); + } + return(hashind%(sizeof(kzhashead)/sizeof(kzhashead[0]))); +} + +static long kzcheckhash (const char *filnam, char **zipnam, long *zipseek) +{ + long i; + + if (!kzhashbuf) return(0); + if (filnam[0] == '|') filnam++; + for(i=kzhashead[kzcalchash(filnam)];i>=0;i=(*(long *)&kzhashbuf[i])) + if (!filnamcmp(filnam,&kzhashbuf[i+16])) + { + (*zipnam) = &kzhashbuf[*(long *)&kzhashbuf[i+8]]; + (*zipseek) = *(long *)&kzhashbuf[i+12]; + return(1); + } + return(0); +} + +void kzuninit () +{ + if (kzhashbuf) { free(kzhashbuf); kzhashbuf = 0; } + kzhashpos = kzhashsiz = 0; +} + + //Load ZIP directory into memory (hash) to allow fast access later +long kzaddstack (const char *zipnam) +{ + FILE *fil; + long i, j, hashind, zipnamoffs, numfiles; + char tempbuf[260+46]; + + fil = fopen(zipnam,"rb"); if (!fil) return(-1); + + //Write ZIP filename to hash + i = strlen(zipnam)+1; if (!kzcheckhashsiz(i)) { fclose(fil); return(-1); } + strcpy(&kzhashbuf[kzhashpos],zipnam); + zipnamoffs = kzhashpos; kzhashpos += i; + + fseek(fil,-22,SEEK_END); + fread(tempbuf,22,1,fil); + if (*(long *)&tempbuf[0] == LSWAPIB(0x06054b50)) //Fast way of finding dir info + { + numfiles = SSWAPIB(*(short *)&tempbuf[10]); + fseek(fil,LSWAPIB(*(long *)&tempbuf[16]),SEEK_SET); + } + else //Slow way of finding dir info (used when ZIP has junk at end) + { + fseek(fil,0,SEEK_SET); numfiles = 0; + while (1) + { + if (!fread(&j,4,1,fil)) { numfiles = -1; break; } + if (j == LSWAPIB(0x02014b50)) break; //Found central file header :) + if (j != LSWAPIB(0x04034b50)) { numfiles = -1; break; } + fread(tempbuf,26,1,fil); + fseek(fil,LSWAPIB(*(long *)&tempbuf[14]) + SSWAPIB(*(short *)&tempbuf[24]) + SSWAPIB(*(short *)&tempbuf[22]),SEEK_CUR); + numfiles++; + } + if (numfiles < 0) { fclose(fil); return(-1); } + fseek(fil,-4,SEEK_CUR); + } + for(i=0;i 2GB-32K bytes + gslidew = 0x7fffffff; //Force reload at beginning + + return((long)kzfs.fil); + default: fclose(kzfs.fil); kzfs.fil = 0; return(0); + } + } + return(0); +} + +// -------------------------------------------------------------------------- + +static long srchstat = -1, wildstpathleng; + +#if defined(__DOS__) +static char wildst[260] = ""; +static struct find_t findata; +#elif defined(_WIN32) +static char wildst[MAX_PATH] = ""; +static HANDLE hfind = INVALID_HANDLE_VALUE; +static WIN32_FIND_DATA findata; +#else +static char wildst[260] = ""; +static DIR *hfind = NULL; +static struct dirent *findata = NULL; +#endif + +void kzfindfilestart (const char *st) +{ +#ifdef _WIN32 + if (hfind != INVALID_HANDLE_VALUE) + { FindClose(hfind); hfind = INVALID_HANDLE_VALUE; } +#else + if (hfind) { closedir(hfind); hfind = NULL; } +#endif + strcpy(wildst,st); + srchstat = -3; +} + +long kzfindfile (char *filnam) +{ + long i; + + filnam[0] = 0; + if (srchstat == -3) + { + if (!wildst[0]) { srchstat = -1; return(0); } + do + { + srchstat = -2; + + //Extract directory from wildcard string for pre-pending + wildstpathleng = 0; + for(i=0;wildst[i];i++) + if ((wildst[i] == '/') || (wildst[i] == '\\')) + wildstpathleng = i+1; + + memcpy(filnam,wildst,wildstpathleng); + +#if defined(__DOS__) + if (_dos_findfirst(wildst,_A_SUBDIR,&findata)) + { if (!kzhashbuf) return(0); srchstat = kzlastfnam; continue; } + i = wildstpathleng; + if (findata.attrib&16) + if ((findata.name[0] == '.') && (!findata.name[1])) continue; + strcpy(&filnam[i],findata.name); + if (findata.attrib&16) strcat(&filnam[i],"\\"); +#elif defined(_WIN32) + hfind = FindFirstFile(wildst,&findata); + if (hfind == INVALID_HANDLE_VALUE) + { if (!kzhashbuf) return(0); srchstat = kzlastfnam; continue; } + if (findata.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) continue; + i = wildstpathleng; + if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + if ((findata.cFileName[0] == '.') && (!findata.cFileName[1])) continue; + strcpy(&filnam[i],findata.cFileName); + if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) strcat(&filnam[i],"\\"); +#else + if (!hfind) + { + char *s = "."; + if (wildstpathleng > 0) { + filnam[wildstpathleng] = 0; + s = filnam; + } + hfind = opendir(s); + if (!hfind) { if (!kzhashbuf) return 0; srchstat = kzlastfnam; continue; } + } + break; // process srchstat == -2 +#endif + return(1); + } while (0); + } + if (srchstat == -2) + while (1) + { + memcpy(filnam,wildst,wildstpathleng); +#if defined(__DOS__) + if (_dos_findnext(&findata)) + { if (!kzhashbuf) return(0); srchstat = kzlastfnam; break; } + i = wildstpathleng; + if (findata.attrib&16) + if ((findata.name[0] == '.') && (!findata.name[1])) continue; + strcpy(&filnam[i],findata.name); + if (findata.attrib&16) strcat(&filnam[i],"\\"); +#elif defined(_WIN32) + if (!FindNextFile(hfind,&findata)) + { FindClose(hfind); if (!kzhashbuf) return(0); srchstat = kzlastfnam; break; } + if (findata.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) continue; + i = wildstpathleng; + if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + if ((findata.cFileName[0] == '.') && (!findata.cFileName[1])) continue; + strcpy(&filnam[i],findata.cFileName); + if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) strcat(&filnam[i],"\\"); +#else + { + struct stat st; + if ((findata = readdir(hfind)) == NULL) + { closedir(hfind); hfind = NULL; if (!kzhashbuf) return 0; srchstat = kzlastfnam; break; } + i = wildstpathleng; + strcpy(&filnam[i],findata->d_name); + if (stat(filnam,&st) < 0) continue; + if (st.st_mode & S_IFDIR) + { if (findata->d_name[0] == '.' && !findata->d_name[1]) continue; } //skip . + else if ((st.st_mode & S_IFREG) || (st.st_mode & S_IFLNK)) + { if (findata->d_name[0] == '.') continue; } //skip hidden (dot) files + else continue; //skip devices and fifos and such + if (!wildmatch(findata->d_name,&wildst[wildstpathleng])) continue; + if (st.st_mode & S_IFDIR) strcat(&filnam[i],"/"); + } +#endif + return(1); + } + while (srchstat >= 0) + { + if (wildmatch(&kzhashbuf[srchstat+16],wildst)) + { + //strcpy(filnam,&kzhashbuf[srchstat+16]); + filnam[0] = '|'; strcpy(&filnam[1],&kzhashbuf[srchstat+16]); + srchstat = *(long *)&kzhashbuf[srchstat+4]; + return(1); + } + srchstat = *(long *)&kzhashbuf[srchstat+4]; + } + return(0); +} + +//File searching code (supports inside ZIP files!) How to use this code: +// char filnam[MAX_PATH]; +// kzfindfilestart("vxl/*.vxl"); +// while (kzfindfile(filnam)) puts(filnam); +//NOTES: +// * Directory names end with '\' or '/' (depending on system) +// * Files inside zip begin with '|' + +// -------------------------------------------------------------------------- + +static char *gzbufptr; +static void putbuf4zip (const unsigned char *buf, long uncomp0, long uncomp1) +{ + long i0, i1; + // uncomp0 ... uncomp1 + // &gzbufptr[kzfs.pos] ... &gzbufptr[kzfs.endpos]; + i0 = max(uncomp0,kzfs.pos); + i1 = min(uncomp1,kzfs.endpos); + if (i0 < i1) memcpy(&gzbufptr[i0],&buf[i0-uncomp0],i1-i0); +} + + //returns number of bytes copied +long kzread (void *buffer, long leng) +{ + long i, j, k, bfinal, btype, hlit, hdist; + + if ((!kzfs.fil) || (leng <= 0)) return(0); + + if (kzfs.comptyp == 0) + { + if (kzfs.pos != kzfs.i) //Seek only when position changes + fseek(kzfs.fil,kzfs.seek0+kzfs.pos,SEEK_SET); + i = min(kzfs.leng-kzfs.pos,leng); + fread(buffer,i,1,kzfs.fil); + kzfs.i += i; //kzfs.i is a local copy of ftell(kzfs.fil); + } + else if (kzfs.comptyp == 8) + { + zipfilmode = 1; + + //Initialize for putbuf4zip + gzbufptr = (char *)buffer; gzbufptr = &gzbufptr[-kzfs.pos]; + kzfs.endpos = min(kzfs.pos+leng,kzfs.leng); + if (kzfs.endpos == kzfs.pos) return(0); //Guard against reading 0 length + + if (kzfs.pos < gslidew-32768) // Must go back to start :( + { + if (kzfs.comptell) fseek(kzfs.fil,kzfs.seek0,SEEK_SET); + + gslidew = 0; gslider = 16384; + kzfs.jmpplc = 0; + + //Initialize for suckbits/peekbits/getbits + kzfs.comptell = min((unsigned)kzfs.compleng,sizeof(olinbuf)); + fread(&olinbuf[0],kzfs.comptell,1,kzfs.fil); + //Make it re-load when there are < 32 bits left in FIFO + bitpos = -(((long)sizeof(olinbuf)-4)<<3); + //Identity: filptr + (bitpos>>3) = &olinbuf[0] + filptr = &olinbuf[-(bitpos>>3)]; + } + else + { + i = max(gslidew-32768,0); j = gslider-16384; + + //HACK: Don't unzip anything until you have to... + // (keeps file pointer as low as possible) + if (kzfs.endpos <= gslidew) j = kzfs.endpos; + + //write uncompoffs on slidebuf from: i to j + if (!((i^j)&32768)) + putbuf4zip(&slidebuf[i&32767],i,j); + else + { + putbuf4zip(&slidebuf[i&32767],i,j&~32767); + putbuf4zip(slidebuf,j&~32767,j); + } + + //HACK: Don't unzip anything until you have to... + // (keeps file pointer as low as possible) + if (kzfs.endpos <= gslidew) goto retkzread; + } + + switch (kzfs.jmpplc) + { + case 0: goto kzreadplc0; + case 1: goto kzreadplc1; + case 2: goto kzreadplc2; + case 3: goto kzreadplc3; + } +kzreadplc0:; + do + { + bfinal = getbits(1); btype = getbits(2); + +#if 0 + //Display Huffman block offsets&lengths of input file - for debugging only! + { + static long ouncomppos = 0, ocomppos = 0; + if (kzfs.comptell == sizeof(olinbuf)) i = 0; + else if (kzfs.comptell < kzfs.compleng) i = kzfs.comptell-(sizeof(olinbuf)-4); + else i = kzfs.comptell-(kzfs.comptell%(sizeof(olinbuf)-4)); + i += ((long)&filptr[bitpos>>3])-((long)(&olinbuf[0])); + i = (i<<3)+(bitpos&7)-3; + if (gslidew) printf(" ULng:0x%08x CLng:0x%08x.%x",gslidew-ouncomppos,(i-ocomppos)>>3,((i-ocomppos)&7)<<1); + printf("\ntype:%d, Uoff:0x%08x Coff:0x%08x.%x",btype,gslidew,i>>3,(i&7)<<1); + if (bfinal) + { + printf(" ULng:0x%08x CLng:0x%08x.%x",kzfs.leng-gslidew,((kzfs.compleng<<3)-i)>>3,(((kzfs.compleng<<3)-i)&7)<<1); + printf("\n Uoff:0x%08x Coff:0x%08x.0",kzfs.leng,kzfs.compleng); + ouncomppos = ocomppos = 0; + } + else { ouncomppos = gslidew; ocomppos = i; } + } +#endif + + if (btype == 0) + { + //Raw (uncompressed) + suckbits((-bitpos)&7); //Synchronize to start of next byte + i = getbits(16); if ((getbits(16)^i) != 0xffff) return(-1); + for(;i;i--) + { + if (gslidew >= gslider) + { + putbuf4zip(&slidebuf[(gslider-16384)&32767],gslider-16384,gslider); gslider += 16384; + if (gslider-16384 >= kzfs.endpos) + { + kzfs.jmpplc = 1; kzfs.i = i; kzfs.bfinal = bfinal; + goto retkzread; +kzreadplc1:; i = kzfs.i; bfinal = kzfs.bfinal; + } + } + slidebuf[(gslidew++)&32767] = (char)getbits(8); + } + continue; + } + if (btype == 3) continue; + + if (btype == 1) //Fixed Huffman + { + hlit = 288; hdist = 32; i = 0; + for(;i<144;i++) clen[i] = 8; //Fixed bit sizes (literals) + for(;i<256;i++) clen[i] = 9; //Fixed bit sizes (literals) + for(;i<280;i++) clen[i] = 7; //Fixed bit sizes (EOI,lengths) + for(;i<288;i++) clen[i] = 8; //Fixed bit sizes (lengths) + for(;i<320;i++) clen[i] = 5; //Fixed bit sizes (distances) + } + else //Dynamic Huffman + { + hlit = getbits(5)+257; hdist = getbits(5)+1; j = getbits(4)+4; + for(i=0;i= gslider) + { + putbuf4zip(&slidebuf[(gslider-16384)&32767],gslider-16384,gslider); gslider += 16384; + if (gslider-16384 >= kzfs.endpos) + { + kzfs.jmpplc = 2; kzfs.bfinal = bfinal; goto retkzread; +kzreadplc2:; bfinal = kzfs.bfinal; + } + } + + k = peekbits(LOGQHUFSIZ0); + if (qhufbit0[k]) { i = qhufval0[k]; suckbits((long)qhufbit0[k]); } + else i = hufgetsym(ibuf0,nbuf0); + + if (i < 256) { slidebuf[(gslidew++)&32767] = (char)i; continue; } + if (i == 256) break; + i = getbits(hxbit[i+30-257][0]) + hxbit[i+30-257][1]; + + k = peekbits(LOGQHUFSIZ1); + if (qhufbit1[k]) { j = qhufval1[k]; suckbits((long)qhufbit1[k]); } + else j = hufgetsym(ibuf1,nbuf1); + + j = getbits(hxbit[j][0]) + hxbit[j][1]; + for(;i;i--,gslidew++) slidebuf[gslidew&32767] = slidebuf[(gslidew-j)&32767]; + } + } while (!bfinal); + + gslider -= 16384; + if (!((gslider^gslidew)&32768)) + putbuf4zip(&slidebuf[gslider&32767],gslider,gslidew); + else + { + putbuf4zip(&slidebuf[gslider&32767],gslider,gslidew&~32767); + putbuf4zip(slidebuf,gslidew&~32767,gslidew); + } +kzreadplc3:; kzfs.jmpplc = 3; + } + +retkzread:; + i = kzfs.pos; + kzfs.pos += leng; if (kzfs.pos > kzfs.leng) kzfs.pos = kzfs.leng; + return(kzfs.pos-i); +} + +long kzfilelength () +{ + if (!kzfs.fil) return(0); + return(kzfs.leng); +} + + //WARNING: kzseek(<-32768,SEEK_CUR); or: + // kzseek(0,SEEK_END); can make next kzread very slow!!! +long kzseek (long offset, long whence) +{ + if (!kzfs.fil) return(-1); + switch (whence) + { + case SEEK_CUR: kzfs.pos += offset; break; + case SEEK_END: kzfs.pos = kzfs.leng+offset; break; + case SEEK_SET: default: kzfs.pos = offset; + } + if (kzfs.pos < 0) kzfs.pos = 0; + if (kzfs.pos > kzfs.leng) kzfs.pos = kzfs.leng; + return(kzfs.pos); +} + +long kztell () +{ + if (!kzfs.fil) return(-1); + return(kzfs.pos); +} + +long kzgetc () +{ + char ch; + if (!kzread(&ch,1)) return(-1); + return((long)ch); +} + +long kzeof () +{ + if (!kzfs.fil) return(-1); + return(kzfs.pos >= kzfs.leng); +} + +void kzclose () +{ + if (kzfs.fil) { fclose(kzfs.fil); kzfs.fil = 0; } +} + +//====================== ZIP decompression code ends ========================= +//===================== HANDY PICTURE function begins ======================== + +void kpzload (const char *filnam, long *pic, long *bpl, long *xsiz, long *ysiz) +{ + char *buf; + long leng; + + (*pic) = 0; + if (!kzopen(filnam)) return; + leng = kzfilelength(); + buf = (char *)malloc(leng); if (!buf) return; + kzread(buf,leng); + kzclose(); + + kpgetdim(buf,leng,xsiz,ysiz); + (*bpl) = ((*xsiz)<<2); + (*pic) = (long)malloc((*ysiz)*(*bpl)); if (!(*pic)) { free(buf); return; } + if (kprender(buf,leng,*pic,*bpl,*xsiz,*ysiz,0,0) < 0) { free(buf); free((void *)*pic); (*pic) = 0; return; } + free(buf); +} +//====================== HANDY PICTURE function ends ========================= diff --git a/polymer/build/src/lzfP.h b/polymer/build/src/lzfP.h new file mode 100644 index 000000000..48963b2bc --- /dev/null +++ b/polymer/build/src/lzfP.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2000-2005 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License version 2 (the "GPL"), in which case the + * provisions of the GPL are applicable instead of the above. If you wish to + * allow the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under the + * BSD license, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. If + * you do not delete the provisions above, a recipient may use your version + * of this file under either the BSD or the GPL. + */ + +#ifndef LZFP_h +#define LZFP_h + +#define STANDALONE 1 /* at the moment, this is ok. */ + +#ifndef STANDALONE +# include "lzf.h" +#endif + +/* + * size of hashtable is (1 << HLOG) * sizeof (char *) + * decompression is independent of the hash table size + * the difference between 15 and 14 is very small + * for small blocks (and 14 is usually a but faster). + * For a low-memory/faster configuration, use HLOG == 13; + * For best compression, use 15 or 16 (or more). + */ +#ifndef HLOG +# define HLOG 14 +#endif + +/* + * sacrifice very little compression quality in favour of compression speed. + * This gives almost the same compression as the default code, and is + * (very roughly) 15% faster. This is the preferable mode of operation. + */ + +#ifndef VERY_FAST +# define VERY_FAST 1 +#endif + +/* + * sacrifice some more compression quality in favour of compression speed. + * (roughly 1-2% worse compression for large blocks and + * 9-10% for small, redundant, blocks and >>20% better speed in both cases) + * In short: when in need for speed, enable this for binary data, + * possibly disable this for text data. + */ +#ifndef ULTRA_FAST +# define ULTRA_FAST 0 +#endif + +/* + * unconditionally aligning does not cost very much, so do it if unsure + */ +#ifndef STRICT_ALIGN +# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) +#endif + +/* + * use string functions to copy memory. + * this is usually a loss, even with glibc's optimized memcpy + */ +#ifndef USE_MEMCPY +# define USE_MEMCPY 0 +#endif + +/* + * you may choose to pre-set the hash table (might be faster on some + * modern cpus and large (>>64k) blocks) + */ +#ifndef INIT_HTAB +# define INIT_HTAB 0 +#endif + +/* + * avoid assigning values to errno variable? for some embedding purposes + * (linux kernel for example), this is neccessary. NOTE: this breaks + * the documentation in lzf.h. + */ +#ifndef AVOID_ERRNO +# define AVOID_ERRNO 0 +#endif + +/* + * Wether to pass the LZF_STATE variable as argument, or allocate it + * on the stack. For small-stack environments, define this to 1. + * NOTE: this breaks the prototype in lzf.h. + */ +#ifndef LZF_STATE_ARG +# define LZF_STATE_ARG 0 +#endif + +/*****************************************************************************/ +/* nothing should be changed below */ + +typedef unsigned char u8; + +typedef const u8 *LZF_STATE[1 << (HLOG)]; + +#if !STRICT_ALIGN +/* for unaligned accesses we need a 16 bit datatype. */ +# include +# if USHRT_MAX == 65535 + typedef unsigned short u16; +# elif UINT_MAX == 65535 + typedef unsigned int u16; +# else +# undef STRICT_ALIGN +# define STRICT_ALIGN 1 +# endif +#endif + +#if ULTRA_FAST +# if defined(VERY_FAST) +# undef VERY_FAST +# endif +#endif + +#if USE_MEMCPY || INIT_HTAB +# ifdef __cplusplus +# include +# else +# include +# endif +#endif + +#endif + diff --git a/polymer/build/src/lzf_c.c b/polymer/build/src/lzf_c.c new file mode 100644 index 000000000..b9b9ef991 --- /dev/null +++ b/polymer/build/src/lzf_c.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2000-2005 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License version 2 (the "GPL"), in which case the + * provisions of the GPL are applicable instead of the above. If you wish to + * allow the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under the + * BSD license, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. If + * you do not delete the provisions above, a recipient may use your version + * of this file under either the BSD or the GPL. + */ + +#include "lzfP.h" + +#define HSIZE (1 << (HLOG)) + +/* + * don't play with this unless you benchmark! + * decompression is not dependent on the hash function + * the hashing function might seem strange, just believe me + * it works ;) + */ +#ifndef FRST +# define FRST(p) (((p[0]) << 8) | p[1]) +# define NEXT(v,p) (((v) << 8) | p[2]) +# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) +#endif +/* + * IDX works because it is very similar to a multiplicative hash, e.g. + * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) + * the latter is also quite fast on newer CPUs, and sligthly better + * + * the next one is also quite good, albeit slow ;) + * (int)(cos(h & 0xffffff) * 1e6) + */ + +#if 0 +/* original lzv-like hash function, much worse and thus slower */ +# define FRST(p) (p[0] << 5) ^ p[1] +# define NEXT(v,p) ((v) << 5) ^ p[2] +# define IDX(h) ((h) & (HSIZE - 1)) +#endif + +#define MAX_LIT (1 << 5) +#define MAX_OFF (1 << 13) +#define MAX_REF ((1 << 8) + (1 << 3)) + +/* + * compressed format + * + * 000LLLLL ; literal + * LLLooooo oooooooo ; backref L + * 111ooooo LLLLLLLL oooooooo ; backref L+7 + * + */ + +unsigned int +lzf_compress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len +#if LZF_STATE_ARG + , LZF_STATE *htab +#endif + ) +{ +#if !LZF_STATE_ARG + LZF_STATE htab; +#endif + const u8 **hslot; + const u8 *ip = (const u8 *)in_data; + u8 *op = (u8 *)out_data; + const u8 *in_end = ip + in_len; + u8 *out_end = op + out_len; + const u8 *ref; + + unsigned int hval = FRST (ip); + unsigned long off; + int lit = 0; + +#if INIT_HTAB +# if USE_MEMCPY + memset (htab, 0, sizeof (htab)); +# else + for (hslot = htab; hslot < htab + HSIZE; hslot++) + *hslot++ = ip; +# endif +#endif + + for (;;) + { + if (ip < in_end - 2) + { + hval = NEXT (hval, ip); + hslot = htab + IDX (hval); + ref = *hslot; *hslot = ip; + + if (1 +#if INIT_HTAB && !USE_MEMCPY + && ref < ip /* the next test will actually take care of this, but this is faster */ +#endif + && (off = ip - ref - 1) < MAX_OFF + && ip + 4 < in_end + && ref > (u8 *)in_data +#if STRICT_ALIGN + && ref[0] == ip[0] + && ref[1] == ip[1] + && ref[2] == ip[2] +#else + && *(u16 *)ref == *(u16 *)ip + && ref[2] == ip[2] +#endif + ) + { + /* match found at *ref++ */ + unsigned int len = 2; + unsigned int maxlen = in_end - ip - len; + maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; + + if (op + lit + 1 + 3 >= out_end) + return 0; + + do + len++; + while (len < maxlen && ref[len] == ip[len]); + + if (lit) + { + *op++ = lit - 1; + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); + } + + len -= 2; + ip++; + + if (len < 7) + { + *op++ = (off >> 8) + (len << 5); + } + else + { + *op++ = (off >> 8) + ( 7 << 5); + *op++ = len - 7; + } + + *op++ = off; + +#if ULTRA_FAST || VERY_FAST + ip += len; +#if VERY_FAST && !ULTRA_FAST + --ip; +#endif + hval = FRST (ip); + + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; + +#if VERY_FAST && !ULTRA_FAST + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; +#endif +#else + do + { + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; + } + while (len--); +#endif + continue; + } + } + else if (ip == in_end) + break; + + /* one more literal byte we must copy */ + lit++; + ip++; + + if (lit == MAX_LIT) + { + if (op + 1 + MAX_LIT >= out_end) + return 0; + + *op++ = MAX_LIT - 1; +#if USE_MEMCPY + memcpy (op, ip - MAX_LIT, MAX_LIT); + op += MAX_LIT; + lit = 0; +#else + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); +#endif + } + } + + if (lit) + { + if (op + lit + 1 >= out_end) + return 0; + + *op++ = lit - 1; + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); + } + + return op - (u8 *) out_data; +} diff --git a/polymer/build/src/lzf_d.c b/polymer/build/src/lzf_d.c new file mode 100644 index 000000000..d0229d7dc --- /dev/null +++ b/polymer/build/src/lzf_d.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000-2005 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License version 2 (the "GPL"), in which case the + * provisions of the GPL are applicable instead of the above. If you wish to + * allow the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under the + * BSD license, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. If + * you do not delete the provisions above, a recipient may use your version + * of this file under either the BSD or the GPL. + */ + +#include "lzfP.h" + +#if AVOID_ERRNO +# define SET_ERRNO(n) +#else +# include +# define SET_ERRNO(n) errno = (n) +#endif + +unsigned int +lzf_decompress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len) +{ + u8 const *ip = (const u8 *)in_data; + u8 *op = (u8 *)out_data; + u8 const *const in_end = ip + in_len; + u8 *const out_end = op + out_len; + + do + { + unsigned int ctrl = *ip++; + + if (ctrl < (1 << 5)) /* literal run */ + { + ctrl++; + + if (op + ctrl > out_end) + { + SET_ERRNO (E2BIG); + return 0; + } + +#if USE_MEMCPY + memcpy (op, ip, ctrl); + op += ctrl; + ip += ctrl; +#else + do + *op++ = *ip++; + while (--ctrl); +#endif + } + else /* back reference */ + { + unsigned int len = ctrl >> 5; + + u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; + + if (len == 7) + len += *ip++; + + ref -= *ip++; + + if (op + len + 2 > out_end) + { + SET_ERRNO (E2BIG); + return 0; + } + + if (ref < (u8 *)out_data) + { + SET_ERRNO (EINVAL); + return 0; + } + + *op++ = *ref++; + *op++ = *ref++; + + do + *op++ = *ref++; + while (--len); + } + } + while (op < out_end && ip < in_end); + + return op - (u8 *)out_data; +} + diff --git a/polymer/build/src/lzwnew.c b/polymer/build/src/lzwnew.c new file mode 100644 index 000000000..dad07a960 --- /dev/null +++ b/polymer/build/src/lzwnew.c @@ -0,0 +1,116 @@ +//-------------------------------------------------------------------------------------------------- +#if defined(__POWERPC__) +static unsigned long LSWAPIB (unsigned long a) { return(((a>>8)&0xff00)+((a&0xff00)<<8)+(a<<24)+(a>>24)); } +static unsigned short SSWAPIB (unsigned short a) { return((a>>8)+(a<<8)); } +#else +#define LSWAPIB(a) (a) +#define SSWAPIB(a) (a) +#endif + +#define USENEW 1 +long lzwcompress (unsigned char *ucompbuf, long ucompleng, unsigned char *compbuf) +{ + long i, j, numnodes, *lptr, bitcnt, nbits, oneupnbits, hmask, *child; + long *sibly; +#if USENEW + long *sibry; +#endif + unsigned char *nodev, *cptr, *eptr; + + nodev = (unsigned char *)malloc((ucompleng+256)*sizeof(char)); if (!nodev) return(0); + child = (long *)malloc((ucompleng+256)*sizeof(long)); if (!child) { free(nodev); return(0); } + sibly = (long *)malloc((ucompleng+256)*sizeof(long)); if (!sibly) { free(child); free(nodev); return(0); } +#if USENEW + sibry = (long *)malloc((ucompleng+256)*sizeof(long)); if (!sibry) { free(sibly); free(child); free(nodev); return(0); } +#endif + + for(i=255;i>=0;i--) { nodev[i] = i; child[i] = -1; } + memset(compbuf,0,ucompleng+15); + + cptr = ucompbuf; eptr = &ucompbuf[ucompleng]; + + numnodes = 256; bitcnt = (4<<3); nbits = 8; oneupnbits = (1<<8); hmask = ((oneupnbits>>1)-1); + do + { + for(i=cptr[0];i>=0;i=j) + { + cptr++; if (cptr >= eptr) goto lzwcompbreak2b; + j = child[i]; if (j < 0) { child[i] = numnodes; break; } +#if USENEW + //This is about 2x faster when ucompbuf is more random, 5% slower when very compressible + while (cptr[0] != nodev[j]) + { + if (cptr[0] < nodev[j]) + { if (sibly[j] < 0) { sibly[j] = numnodes; goto lzwcompbreak2a; } j = sibly[j]; } + else { if (sibry[j] < 0) { sibry[j] = numnodes; goto lzwcompbreak2a; } j = sibry[j]; } + } +#else + for(;nodev[j]!=cptr[0];j=sibly[j]) + if (sibly[j] < 0) { sibly[j] = numnodes; goto lzwcompbreak2a; } +#endif + } +lzwcompbreak2a: nodev[numnodes] = cptr[0]; +lzwcompbreak2b: child[numnodes] = sibly[numnodes] = -1; +#if USENEW + sibry[numnodes] = -1; +#endif + + lptr = (long *)&compbuf[bitcnt>>3]; lptr[0] |= LSWAPIB(i<<(bitcnt&7)); + bitcnt += nbits; if ((i&hmask) > ((numnodes-1)&hmask)) bitcnt--; + + numnodes++; if (numnodes > oneupnbits) { nbits++; oneupnbits <<= 1; hmask = ((oneupnbits>>1)-1); } + } while ((cptr < eptr) && (bitcnt < (ucompleng<<3))); + +#if USENEW + free(sibry); +#endif + free(sibly); + free(child); free(nodev); + + lptr = (long *)compbuf; + if (((bitcnt+7)>>3) < ucompleng) { lptr[0] = LSWAPIB(numnodes); return((bitcnt+7)>>3); } + memcpy(compbuf,ucompbuf,ucompleng); return(ucompleng); +} + +long lzwuncompress (unsigned char *compbuf, long compleng, unsigned char *ucompbuf, long ucompleng) +{ + long i, dat, leng, bitcnt, *lptr, numnodes, totnodes, nbits, oneupnbits, hmask, *prefix; + unsigned char ch, *ucptr, *suffix; + long ucomp = (long)ucompbuf; + + if (compleng >= ucompleng) { memcpy(ucompbuf,compbuf,ucompleng); return ucompleng; } + + totnodes = LSWAPIB(((long *)compbuf)[0]); if (totnodes <= 0 || totnodes >= ucompleng+256) return 0; + + prefix = (long *)malloc(totnodes*sizeof(long)); if (!prefix) return 0; + suffix = (unsigned char *)malloc(totnodes*sizeof(char)); if (!suffix) { free(prefix); return 0; } + + numnodes = 256; bitcnt = (4<<3); nbits = 8; oneupnbits = (1<<8); hmask = ((oneupnbits>>1)-1); + do + { + lptr = (long *)&compbuf[bitcnt>>3]; dat = ((LSWAPIB(lptr[0])>>(bitcnt&7))&(oneupnbits-1)); + bitcnt += nbits; if ((dat&hmask) > ((numnodes-1)&hmask)) { dat &= hmask; bitcnt--; } + + prefix[numnodes] = dat; + + ucompbuf++; + for(leng=0;dat>=256;dat=prefix[dat]) { + if ((long)ucompbuf+leng-ucomp > ucompleng) goto bail; + ucompbuf[leng++] = suffix[dat]; + } + + ucptr = &ucompbuf[leng-1]; + for(i=(leng>>1)-1;i>=0;i--) { ch = ucompbuf[i]; ucompbuf[i] = ucptr[-i]; ucptr[-i] = ch; } + ucompbuf[-1] = dat; ucompbuf += leng; + + suffix[numnodes-1] = suffix[numnodes] = dat; + + numnodes++; if (numnodes > oneupnbits) { nbits++; oneupnbits <<= 1; hmask = ((oneupnbits>>1)-1); } + } while (numnodes < totnodes); + +bail: + free(suffix); free(prefix); + + return (long)ucompbuf-ucomp; +} +//-------------------------------------------------------------------------------------------------- diff --git a/polymer/build/src/md4.c b/polymer/build/src/md4.c new file mode 100644 index 000000000..7de5776a0 --- /dev/null +++ b/polymer/build/src/md4.c @@ -0,0 +1,272 @@ +/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm + Modified from original version published in RFC1320 by + Jonathon Fowler (jonof@edgenetwork.org) + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD4 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD4 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +typedef unsigned char * POINTER; +typedef unsigned short UINT2; +typedef unsigned long UINT4; + +#include "md4.h" +#include "compat.h" + +/* Constants for MD4Transform routine. + */ +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +static void MD4Transform (UINT4 [4], unsigned char [64]); +static void Encode (unsigned char *, UINT4 *, unsigned int); +static void Decode (UINT4 *, unsigned char *, unsigned int); +#define MD4_memcpy memcpy +#define MD4_memset memset + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G and H are basic MD4 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +void md4once(unsigned char *block, unsigned int len, unsigned char digest[16]) +{ + MD4_CTX ctx; + + md4init(&ctx); + md4block(&ctx, block, len); + md4finish(digest, &ctx); +} + +/* MD4 initialization. Begins an MD4 operation, writing a new context. + */ +void md4init (MD4_CTX *context) +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. + */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD4 block update operation. Continues an MD4 message-digest + operation, processing another message block, and updating the + context. + */ +void md4block (MD4_CTX *context, unsigned char *input, unsigned int inputLen) +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + MD4_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD4Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD4Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD4_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD4 finalization. Ends an MD4 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void md4finish (unsigned char digest[16], MD4_CTX *context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. + */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + md4block (context, PADDING, padLen); + + /* Append length (before padding) */ + md4block (context, bits, 8); + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. + */ + MD4_memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD4 basic transformation. Transforms state based on block. + */ +static void MD4Transform (UINT4 state[4], unsigned char block[64]) +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + MD4_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (unsigned char *output, UINT4 *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (UINT4 *output, unsigned char *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} diff --git a/polymer/build/src/mdsprite.c b/polymer/build/src/mdsprite.c new file mode 100644 index 000000000..83c19b5a9 --- /dev/null +++ b/polymer/build/src/mdsprite.c @@ -0,0 +1,2561 @@ +//------------------------------------- MD2/MD3 LIBRARY BEGINS ------------------------------------- + +#ifdef __POWERPC__ +#define SHIFTMOD32(a) ((a)&31) +#else +#define SHIFTMOD32(a) (a) +#endif + +typedef struct +{ + long mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! + long shadeoff; + float scale, bscale, zadd; + GLuint *texid; // skins +} mdmodel; + +typedef struct _mdanim_t +{ + int startframe, endframe; + int fpssc, flags; + struct _mdanim_t *next; +} mdanim_t; +#define MDANIM_LOOP 0 +#define MDANIM_ONESHOT 1 + +typedef struct _mdskinmap_t +{ + unsigned char palette, filler[3]; // Build palette number + int skinnum, surfnum; // Skin identifier, surface number + char *fn; // Skin filename + GLuint texid[HICEFFECTMASK+1]; // OpenGL texture numbers for effect variations + struct _mdskinmap_t *next; +} mdskinmap_t; + + + //This MD2 code is based on the source code from David Henry (tfc_duke(at)hotmail.com) + // Was at http://tfc.duke.free.fr/us/tutorials/models/md2.htm + // Available from http://web.archive.org/web/20030816010242/http://tfc.duke.free.fr/us/tutorials/models/md2.htm + // Now at http://tfc.duke.free.fr/coding/md2.html (in French) + //He probably wouldn't recognize it if he looked at it though :) +typedef struct { float x, y, z; } point3d; + +typedef struct +{ + long id, vers, skinxsiz, skinysiz, framebytes; //id:"IPD2", vers:8 + long numskins, numverts, numuv, numtris, numglcmds, numframes; + long ofsskins, ofsuv, ofstris, ofsframes, ofsglcmds, ofseof; //ofsskins: skin names (64 bytes each) +} md2head_t; + +typedef struct { unsigned char v[3], ni; } md2vert_t; //compressed vertex coords (x,y,z) +typedef struct +{ + point3d mul, add; //scale&translation vector + char name[16]; //frame name + md2vert_t verts[1]; //first vertex of this frame +} md2frame_t; + +typedef struct +{ + //WARNING: This top block is a union between md2model&md3model: Make sure it matches! + long mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! + long shadeoff; + float scale, bscale, zadd; + GLuint *texid; // texture ids for base skin if no mappings defined + + long numframes, cframe, nframe, fpssc, usesalpha; + float oldtime, curtime, interpol; + mdanim_t *animations; + mdskinmap_t *skinmap; + long numskins, skinloaded; // set to 1+numofskin when a skin is loaded and the tex coords are modified, + + //MD2 specific stuff: + long numverts, numglcmds, framebytes, *glcmds; + char *frames; + char *basepath; // pointer to string of base path + char *skinfn; // pointer to first of numskins 64-char strings +} md2model; + + +typedef struct { char nam[64]; long i; } md3shader_t; //ascz path of shader, shader index +typedef struct { long i[3]; } md3tri_t; //indices of tri +typedef struct { float u, v; } md3uv_t; +typedef struct { signed short x, y, z; unsigned char nlat, nlng; } md3xyzn_t; //xyz are [10:6] ints + +typedef struct +{ + point3d min, max, cen; //bounding box&origin + float r; //radius of bounding sphere + char nam[16]; //ascz frame name +} md3frame_t; + +typedef struct +{ + char nam[64]; //ascz tag name + point3d p, x, y, z; //tag object pos&orient +} md3tag_t; + +typedef struct +{ + long id; //IDP3(0x33806873) + char nam[64]; //ascz surface name + long flags; //? + long numframes, numshaders, numverts, numtris; //numframes same as md3head,max shade=~256,vert=~4096,tri=~8192 + md3tri_t *tris; //file format: rel offs from md3surf + md3shader_t *shaders; //file format: rel offs from md3surf + md3uv_t *uv; //file format: rel offs from md3surf + md3xyzn_t *xyzn; //file format: rel offs from md3surf + long ofsend; +} md3surf_t; + +typedef struct +{ + long id, vers; //id=IDP3(0x33806873), vers=15 + char nam[64]; //ascz path in PK3 + long flags; //? + long numframes, numtags, numsurfs, numskins; //max=~1024,~16,~32,numskins=artifact of MD2; use shader field instead + md3frame_t *frames; //file format: abs offs + md3tag_t *tags; //file format: abs offs + md3surf_t *surfs; //file format: abs offs + long eof; //file format: abs offs +} md3head_t; + +typedef struct +{ + //WARNING: This top block is a union between md2model&md3model: Make sure it matches! + long mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! + long shadeoff; + float scale, bscale, zadd; + unsigned int *texid; // texture ids for base skin if no mappings defined + + long numframes, cframe, nframe, fpssc, usesalpha; + float oldtime, curtime, interpol; + mdanim_t *animations; + mdskinmap_t *skinmap; + long numskins, skinloaded; // set to 1+numofskin when a skin is loaded and the tex coords are modified, + + //MD3 specific + md3head_t head; +} md3model; + +#define VOXBORDWIDTH 1 //use 0 to save memory, but has texture artifacts; 1 looks better... +#define VOXUSECHAR 0 +#if (VOXUSECHAR != 0) +typedef struct { unsigned char x, y, z, u, v; } vert_t; +#else +typedef struct { unsigned short x, y, z, u, v; } vert_t; +#endif +typedef struct { vert_t v[4]; } voxrect_t; +typedef struct +{ + //WARNING: This top block is a union of md2model,md3model,voxmodel: Make sure it matches! + long mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! + long shadeoff; + float scale, bscale, zadd; + unsigned int *texid; // skins for palettes + + //VOX specific stuff: + voxrect_t *quad; long qcnt, qfacind[7]; + long *mytex, mytexx, mytexy; + long xsiz, ysiz, zsiz; + float xpiv, ypiv, zpiv; + long is8bit; +} voxmodel; +static voxmodel *voxmodels[MAXVOXELS]; + +typedef struct +{ // maps build tiles to particular animation frames of a model + int modelid; + int skinnum; + int framenum; // calculate the number from the name when declaring +} tile2model_t; +static tile2model_t tile2model[MAXTILES]; + + //Move this to appropriate place! +typedef struct { float xadd, yadd, zadd; short angadd, flags; } hudtyp; +hudtyp hudmem[2][MAXTILES]; //~320KB ... ok for now ... could replace with dynamic alloc + +static char mdinited=0; + +#define MODELALLOCGROUP 256 +static long nummodelsalloced = 0, nextmodelid = 0; +static mdmodel **models = NULL; + +static long maxmodelverts = 0, allocmodelverts = 0; +static point3d *vertlist = NULL; //temp array to store interpolated vertices for drawing + +mdmodel *mdload (const char *); +int mddraw (spritetype *); +void mdfree (mdmodel *); + +static void freeallmodels () +{ + int i; + + if (models) + { + for(i=0;imdnum == 1) { + voxmodel *v = (voxmodel*)m; + for(j=0;jtexid[j]) bglDeleteTextures(1,(GLuint*)&v->texid[j]); + v->texid[j] = 0; + } + } else if (m->mdnum == 2 || m->mdnum == 3) { + md2model *m2 = (md2model*)m; + mdskinmap_t *sk; + for(j=0;jnumskins*(HICEFFECTMASK+1);j++) + { + if (m2->texid[j]) bglDeleteTextures(1,(GLuint*)&m2->texid[j]); + m2->texid[j] = 0; + } + + for(sk=m2->skinmap;sk;sk=sk->next) + for(j=0;j<(HICEFFECTMASK+1);j++) + { + if (sk->texid[j]) bglDeleteTextures(1,(GLuint*)&sk->texid[j]); + sk->texid[j] = 0; + } + } + } + + for(i=0;itexid[j]) bglDeleteTextures(1,(GLuint*)&v->texid[j]); + v->texid[j] = 0; + } + } +} + +static void mdinit () +{ + memset(hudmem,0,sizeof(hudmem)); + freeallmodels(); + mdinited = 1; +} + +int md_loadmodel (const char *fn) +{ + mdmodel *vm, **ml; + + if (!mdinited) mdinit(); + + if (nextmodelid >= nummodelsalloced) + { + ml = (mdmodel **)realloc(models,(nummodelsalloced+MODELALLOCGROUP)*4); if (!ml) return(-1); + models = ml; nummodelsalloced += MODELALLOCGROUP; + } + + vm = mdload(fn); if (!vm) return(-1); + models[nextmodelid++] = vm; + return(nextmodelid-1); +} + +int md_setmisc (int modelid, float scale, int shadeoff, float zadd) +{ + mdmodel *m; + + if (!mdinited) mdinit(); + + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return -1; + m = models[modelid]; + m->bscale = scale; + m->shadeoff = shadeoff; + m->zadd = zadd; + + return 0; +} + +int md_tilehasmodel (int tilenume) +{ + if (!mdinited) return -1; + return tile2model[tilenume].modelid; +} + +static long framename2index (mdmodel *vm, const char *nam) +{ + int i = 0; + + switch(vm->mdnum) + { + case 2: + { + md2model *m = (md2model *)vm; + md2frame_t *fr; + for(i=0;inumframes;i++) + { + fr = (md2frame_t *)&m->frames[i*m->framebytes]; + if (!Bstrcmp(fr->name, nam)) break; + } + } + break; + case 3: + { + md3model *m = (md3model *)vm; + for(i=0;inumframes;i++) + if (!Bstrcmp(m->head.frames[i].nam,nam)) break; + } + break; + } + return(i); +} + +int md_defineframe (int modelid, const char *framename, int tilenume, int skinnum) +{ + void *vm; + md2model *m; + int i; + + if (!mdinited) mdinit(); + + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return(-1); + if ((unsigned long)tilenume >= (unsigned long)MAXTILES) return(-2); + if (!framename) return(-3); + + m = (md2model *)models[modelid]; + if (m->mdnum == 1) { + tile2model[tilenume].modelid = modelid; + tile2model[tilenume].framenum = tile2model[tilenume].skinnum = 0; + return 0; + } + + i = framename2index((mdmodel*)m,framename); + if (i == m->numframes) return(-3); // frame name invalid + + tile2model[tilenume].modelid = modelid; + tile2model[tilenume].framenum = i; + tile2model[tilenume].skinnum = skinnum; + + return 0; +} + +int md_defineanimation (int modelid, const char *framestart, const char *frameend, int fpssc, int flags) +{ + md2model *m; + mdanim_t ma, *map; + int i; + + if (!mdinited) mdinit(); + + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return(-1); + + memset(&ma, 0, sizeof(ma)); + m = (md2model *)models[modelid]; + if (m->mdnum < 2) return 0; + + //find index of start frame + i = framename2index((mdmodel*)m,framestart); + if (i == m->numframes) return -2; + ma.startframe = i; + + //find index of finish frame which must trail start frame + i = framename2index((mdmodel*)m,frameend); + if (i == m->numframes) return -3; + ma.endframe = i; + + ma.fpssc = fpssc; + ma.flags = flags; + + map = (mdanim_t*)calloc(1,sizeof(mdanim_t)); + if (!map) return(-4); + memcpy(map, &ma, sizeof(ma)); + + map->next = m->animations; + m->animations = map; + + return(0); +} + +int md_defineskin (int modelid, const char *skinfn, int palnum, int skinnum, int surfnum) +{ + mdskinmap_t *sk, *skl; + md2model *m; + + if (!mdinited) mdinit(); + + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return -1; + if (!skinfn) return -2; + if ((unsigned)palnum >= (unsigned)MAXPALOOKUPS) return -3; + + m = (md2model *)models[modelid]; + if (m->mdnum < 2) return 0; + if (m->mdnum == 2) surfnum = 0; + + skl = NULL; + for (sk = m->skinmap; sk; skl = sk, sk = sk->next) + if (sk->palette == (unsigned char)palnum && skinnum == sk->skinnum && surfnum == sk->surfnum) break; + if (!sk) { + sk = (mdskinmap_t *)calloc(1,sizeof(mdskinmap_t)); + if (!sk) return -4; + + if (!skl) m->skinmap = sk; + else skl->next = sk; + } else if (sk->fn) free(sk->fn); + + sk->palette = (unsigned char)palnum; + sk->skinnum = skinnum; + sk->surfnum = surfnum; + sk->fn = (char *)malloc(strlen(skinfn)+1); + if (!sk->fn) return(-4); + strcpy(sk->fn, skinfn); + + return 0; +} + +int md_definehud (int modelid, int tilex, double xadd, double yadd, double zadd, double angadd, int flags) +{ + if (!mdinited) mdinit(); + + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return -1; + if ((unsigned long)tilex >= (unsigned long)MAXTILES) return -2; + + hudmem[(flags>>2)&1][tilex].xadd = xadd; + hudmem[(flags>>2)&1][tilex].yadd = yadd; + hudmem[(flags>>2)&1][tilex].zadd = zadd; + hudmem[(flags>>2)&1][tilex].angadd = ((short)angadd)|2048; + hudmem[(flags>>2)&1][tilex].flags = (short)flags; + + return 0; +} + +int md_undefinetile(int tile) +{ + if (!mdinited) return 0; + if ((unsigned)tile >= (unsigned)MAXTILES) return -1; + + tile2model[tile].modelid = -1; + return 0; +} + +int md_undefinemodel(int modelid) +{ + int i; + if (!mdinited) return 0; + if ((unsigned long)modelid >= (unsigned long)nextmodelid) return -1; + + for (i=MAXTILES-1; i>=0; i--) + if (tile2model[i].modelid == modelid) + tile2model[i].modelid = -1; + + if (models) { + mdfree(models[modelid]); + models[modelid] = NULL; + } + + return 0; +} + +static int daskinloader (long filh, long *fptr, long *bpl, long *sizx, long *sizy, long *osizx, long *osizy, char *hasalpha, char effect) +{ + long picfillen, j,y,x; + char *picfil,*cptr,al=255; + coltype *pic; + long xsiz, ysiz, tsizx, tsizy; + + picfillen = kfilelength(filh); + picfil = (char *)malloc(picfillen); if (!picfil) { return -1; } + kread(filh, picfil, picfillen); + + // tsizx/y = replacement texture's natural size + // xsiz/y = 2^x size of replacement + + kpgetdim(picfil,picfillen,&tsizx,&tsizy); + if (tsizx == 0 || tsizy == 0) { free(picfil); return -1; } + + if (!glinfo.texnpot) { + for(xsiz=1;xsiz=0;j--) { + swapchar(&pic[j].r, &pic[j].b); + } + } + + *sizx = xsiz; + *sizy = ysiz; + *bpl = xsiz; + *fptr = (long)pic; + *hasalpha = (al != 255); + return 0; +} + +// JONOF'S COMPRESSED TEXTURE CACHE STUFF --------------------------------------------------- +long mdloadskin_trytexcache(char *fn, long len, char effect, texcacheheader *head) +{ + long fil, fp; + char cachefn[BMAX_PATH], *cp; + unsigned char mdsum[16]; + + if (!glinfo.texcompr || !glusetexcompr || !glusetexcache) return -1; + if (!bglCompressedTexImage2DARB || !bglGetCompressedTexImageARB) { + // lacking the necessary extensions to do this + initprintf("Warning: the GL driver lacks necessary functions to use caching\n"); + glusetexcache = 0; + return -1; + } + + md4once(fn, strlen(fn), mdsum); + for (cp = cachefn, fp = 0; (*cp = TEXCACHEDIR[fp]); cp++,fp++); + *(cp++) = '/'; + for (fp = 0; fp < 16; phex(mdsum[fp++], cp), cp+=2); + sprintf(cp, "-%lx-0%x", len, effect); + + fil = kopen4load(cachefn, 0); + if (fil < 0) return -1; + + initprintf("Loading cached skin: %s\n", cachefn); + + if (kread(fil, head, sizeof(texcacheheader)) < (int)sizeof(texcacheheader)) goto failure; + if (memcmp(head->magic, "Polymost", 8)) goto failure; + + head->xdim = B_LITTLE32(head->xdim); + head->ydim = B_LITTLE32(head->ydim); + head->flags = B_LITTLE32(head->flags); + + if (!glinfo.texnpot && (head->flags & 1)) goto failure; + + return fil; +failure: + kclose(fil); + return -1; +} + +static long mdloadskin_cached(long fil, texcacheheader *head, long *doalloc, GLuint *glpic, long *xsiz, long *ysiz) +{ + int level, r; + texcachepicture pict; + void *pic = NULL, *packbuf = NULL; + void *midbuf = NULL; + long alloclen=0; + + if (*doalloc&1) { + bglGenTextures(1,glpic); //# of textures (make OpenGL allocate structure) + *doalloc |= 2; // prevents bglGenTextures being called again if we fail in here + } + bglBindTexture(GL_TEXTURE_2D,*glpic); + + bglGetError(); + + // load the mipmaps + for (level = 0; level==0 || (pict.xdim > 1 || pict.ydim > 1); level++) { + r = kread(fil, &pict, sizeof(texcachepicture)); + if (r < (int)sizeof(texcachepicture)) goto failure; + + pict.size = B_LITTLE32(pict.size); + pict.format = B_LITTLE32(pict.format); + pict.xdim = B_LITTLE32(pict.xdim); + pict.ydim = B_LITTLE32(pict.ydim); + pict.border = B_LITTLE32(pict.border); + pict.depth = B_LITTLE32(pict.depth); + + if (level == 0) { *xsiz = pict.xdim; *ysiz = pict.ydim; } + + if (alloclen < pict.size) { + void *picc = realloc(pic, pict.size); + if (!picc) goto failure; else pic = picc; + alloclen = pict.size; + + picc = realloc(packbuf, alloclen+16); + if (!picc) goto failure; else packbuf = picc; + + picc = realloc(midbuf, pict.size); + if (!picc) goto failure; else midbuf = picc; + } + + if (dedxtfilter(fil, &pict, pic, midbuf, packbuf, (head->flags&4)==4)) goto failure; + + bglCompressedTexImage2DARB(GL_TEXTURE_2D,level,pict.format,pict.xdim,pict.ydim,pict.border, + pict.size,pic); + if (bglGetError() != GL_NO_ERROR) goto failure; + } + + if (midbuf) free(midbuf); + if (pic) free(pic); + if (packbuf) free(packbuf); + return 0; +failure: + if (midbuf) free(midbuf); + if (pic) free(pic); + if (packbuf) free(packbuf); + return -1; +} +// --------------------------------------------------- JONOF'S COMPRESSED TEXTURE CACHE STUFF + + //Note: even though it says md2model, it works for both md2model&md3model +static long mdloadskin (md2model *m, int number, int pal, int surf) +{ + long i,j, fptr=0, bpl, xsiz, ysiz, osizx, osizy, texfmt = GL_RGBA, intexfmt = GL_RGBA; + char *skinfile, hasalpha, fn[BMAX_PATH+65]; + GLuint *texidx = NULL; + mdskinmap_t *sk, *skzero = NULL; + long doalloc = 1, filh; + + long cachefil = -1, picfillen; + texcacheheader cachead; + + if (m->mdnum == 2) surf = 0; + + if ((unsigned)pal >= (unsigned)MAXPALOOKUPS) return 0; + i = -1; + for (sk = m->skinmap; sk; sk = sk->next) + { + if ((int)sk->palette == pal && sk->skinnum == number && sk->surfnum == surf) + { + skinfile = sk->fn; + texidx = &sk->texid[ hictinting[pal].f ]; + strcpy(fn,skinfile); + //OSD_Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile); + break; + } + //If no match, give highest priority to number, then pal.. (Parkar's request, 02/27/2005) + else if (((int)sk->palette == 0) && (sk->skinnum == number) && (sk->surfnum == surf) && (i < 5)) { i = 5; skzero = sk; } + else if (((int)sk->palette == pal) && (sk->skinnum == 0) && (sk->surfnum == surf) && (i < 4)) { i = 4; skzero = sk; } + else if (((int)sk->palette == 0) && (sk->skinnum == 0) && (sk->surfnum == surf) && (i < 3)) { i = 3; skzero = sk; } + else if (((int)sk->palette == 0) && (sk->skinnum == number) && (i < 2)) { i = 2; skzero = sk; } + else if (((int)sk->palette == pal) && (sk->skinnum == 0) && (i < 1)) { i = 1; skzero = sk; } + else if (((int)sk->palette == 0) && (sk->skinnum == 0) && (i < 0)) { i = 0; skzero = sk; } + } + if (!sk) + { + if (skzero) + { + skinfile = skzero->fn; + texidx = &skzero->texid[ hictinting[pal].f ]; + strcpy(fn,skinfile); + //OSD_Printf("Using def skin 0,0 as fallback, pal=%d\n", pal); + } + else + { + if ((unsigned)number >= (unsigned)m->numskins) number = 0; + skinfile = m->skinfn + number*64; + texidx = &m->texid[ number * (HICEFFECTMASK+1) + hictinting[pal].f ]; + strcpy(fn,m->basepath); strcat(fn,skinfile); + //OSD_Printf("Using MD2/MD3 skin (%d) %s, pal=%d\n",number,skinfile,pal); + } + } + if (!skinfile[0]) return 0; + + if (*texidx) return *texidx; + *texidx = 0; + + if ((filh = kopen4load(fn, 0)) < 0) { + initprintf("Skin %s not found.\n",fn); + skinfile[0] = 0; + return 0; + } + + picfillen = kfilelength(filh); + kclose(filh); // FIXME: shouldn't have to do this. bug in cache1d.c + + cachefil = mdloadskin_trytexcache(fn, picfillen, hictinting[pal].f, &cachead); + if (cachefil >= 0 && !mdloadskin_cached(cachefil, &cachead, &doalloc, texidx, &xsiz, &ysiz)) { + osizx = cachead.xdim; + osizy = cachead.ydim; + m->usesalpha = hasalpha = (cachead.flags & 2) ? 1 : 0; + kclose(cachefil); + //kclose(filh); // FIXME: uncomment when cache1d.c is fixed + // cachefil >= 0, so it won't be rewritten + } else { + if (cachefil >= 0) kclose(cachefil); + cachefil = -1; // the compressed version will be saved to disk + + if ((filh = kopen4load(fn, 0)) < 0) return -1; + if (daskinloader(filh,&fptr,&bpl,&xsiz,&ysiz,&osizx,&osizy,&hasalpha,hictinting[pal].f)) + { + kclose(filh); + initprintf("Failed loading skin file \"%s\"\n", fn); + skinfile[0] = 0; + return(0); + } else kclose(filh); + m->usesalpha = hasalpha; + + if ((doalloc&3)==1) bglGenTextures(1,(GLuint*)texidx); + bglBindTexture(GL_TEXTURE_2D,*texidx); + + //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr); + if (glinfo.texcompr && glusetexcompr) intexfmt = hasalpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB; + else if (!hasalpha) intexfmt = GL_RGB; + if (glinfo.bgra) texfmt = GL_BGRA; + uploadtexture((doalloc&1), xsiz, ysiz, intexfmt, texfmt, (coltype*)fptr, xsiz, ysiz, 0); + free((void*)fptr); + } + + if (!m->skinloaded) + { + if (xsiz != osizx || ysiz != osizy) + { + float fx, fy; + fx = ((float)osizx)/((float)xsiz); + fy = ((float)osizy)/((float)ysiz); + if (m->mdnum == 2) + { + long *lptr; + for(lptr=m->glcmds;(i=*lptr++);) + for(i=labs(i);i>0;i--,lptr+=3) + { + ((float *)lptr)[0] *= fx; + ((float *)lptr)[1] *= fy; + } + } + else if (m->mdnum == 3) + { + md3model *m3 = (md3model *)m; + md3surf_t *s; + long surfi; + for (surfi=0;surfihead.numsurfs;surfi++) + { + s = &m3->head.surfs[surfi]; + for(i=s->numverts-1;i>=0;i--) + { + s->uv[i].u *= fx; + s->uv[i].v *= fy; + } + } + } + } + m->skinloaded = 1+number; + } + + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + if (glinfo.maxanisotropy > 1.0) + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + if (cachefil < 0) { + // save off the compressed version + cachead.xdim = osizx; + cachead.ydim = osizy; + i = 0; + for (j=0;j<31;j++) { + if (xsiz == pow2long[j]) { i |= 1; } + if (ysiz == pow2long[j]) { i |= 2; } + } + cachead.flags = (i!=3) | (hasalpha ? 2 : 0); + writexcache(fn, picfillen, 0, hictinting[pal].f, &cachead); + } + + return(*texidx); +} + + //Note: even though it says md2model, it works for both md2model&md3model +static void updateanimation (md2model *m, spritetype *tspr) +{ + mdanim_t *anim; + long i, j; + + m->cframe = m->nframe = tile2model[tspr->picnum].framenum; + + for (anim = m->animations; + anim && anim->startframe != m->cframe; + anim = anim->next) ; + if (!anim) { m->interpol = 0; return; } + + if (((long)spriteext[tspr->owner].mdanimcur) != anim->startframe || + (spriteext[tspr->owner].flags & SPREXT_NOMDANIM)) + { + spriteext[tspr->owner].mdanimcur = (short)anim->startframe; + spriteext[tspr->owner].mdanimtims = mdtims; + m->cframe = m->nframe = anim->startframe; + m->interpol = 0; + return; + } + + i = (mdtims-spriteext[tspr->owner].mdanimtims)*anim->fpssc; + j = ((anim->endframe+1-anim->startframe)<<16); + + //Just in case you play the game for a VERY long time... + if (i < 0) { i = 0; spriteext[tspr->owner].mdanimtims = mdtims; } + //compare with j*2 instead of j to ensure i stays > j-65536 for MDANIM_ONESHOT + if ((i >= j+j) && (anim->fpssc)) //Keep mdanimtims close to mdtims to avoid the use of MOD + spriteext[tspr->owner].mdanimtims += j/anim->fpssc; + + if (anim->flags&MDANIM_ONESHOT) + { if (i > j-65536) i = j-65536; } + else { if (i >= j) { i -= j; if (i >= j) i %= j; } } + + m->cframe = (i>>16)+anim->startframe; + m->nframe = m->cframe+1; if (m->nframe > anim->endframe) m->nframe = anim->startframe; + m->interpol = ((float)(i&65535))/65536.f; +} + +//--------------------------------------- MD2 LIBRARY BEGINS --------------------------------------- + +static void md2free (md2model *m) +{ + mdanim_t *anim, *nanim = NULL; + mdskinmap_t *sk, *nsk = NULL; + + if (!m) return; + + for(anim=m->animations; anim; anim=nanim) + { + nanim = anim->next; + free(anim); + } + for(sk=m->skinmap; sk; sk=nsk) + { + nsk = sk->next; + free(sk->fn); + free(sk); + } + + if (m->frames) free(m->frames); + if (m->glcmds) free(m->glcmds); + if (m->basepath) free(m->basepath); + if (m->skinfn) free(m->skinfn); + + if (m->texid) free(m->texid); +} + +static md2model *md2load (int fil, const char *filnam) +{ + md2model *m; + md2head_t head; + char *buf, st[BMAX_PATH]; + long i; + + m = (md2model *)calloc(1,sizeof(md2model)); if (!m) return(0); + m->mdnum = 2; m->scale = .01; + + kread(fil,(char *)&head,sizeof(md2head_t)); + head.id = B_LITTLE32(head.id); head.vers = B_LITTLE32(head.vers); + head.skinxsiz = B_LITTLE32(head.skinxsiz); head.skinysiz = B_LITTLE32(head.skinysiz); + head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins); + head.numverts = B_LITTLE32(head.numverts); head.numuv = B_LITTLE32(head.numuv); + head.numtris = B_LITTLE32(head.numtris); head.numglcmds = B_LITTLE32(head.numglcmds); + head.numframes = B_LITTLE32(head.numframes); head.ofsskins = B_LITTLE32(head.ofsskins); + head.ofsuv = B_LITTLE32(head.ofsuv); head.ofstris = B_LITTLE32(head.ofstris); + head.ofsframes = B_LITTLE32(head.ofsframes); head.ofsglcmds = B_LITTLE32(head.ofsglcmds); + head.ofseof = B_LITTLE32(head.ofseof); + + if ((head.id != 0x32504449) || (head.vers != 8)) { free(m); return(0); } //"IDP2" + + m->numskins = head.numskins; + m->numframes = head.numframes; + m->numverts = head.numverts; + m->numglcmds = head.numglcmds; + m->framebytes = head.framebytes; + m->frames = (char *)calloc(m->numframes,m->framebytes); if (!m->frames) { free(m); return(0); } + m->glcmds = (long *)calloc(m->numglcmds,sizeof(long)); if (!m->glcmds) { free(m->frames); free(m); return(0); } + klseek(fil,head.ofsframes,SEEK_SET); + if (kread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes) + { free(m->glcmds); free(m->frames); free(m); return(0); } + klseek(fil,head.ofsglcmds,SEEK_SET); + if (kread(fil,(char *)m->glcmds,m->numglcmds*sizeof(long)) != (long)(m->numglcmds*sizeof(long))) + { free(m->glcmds); free(m->frames); free(m); return(0); } + +#if B_BIG_ENDIAN != 0 + { + char *f = (char *)m->frames; + long *l,j; + md2frame_t *fr; + + for (i = m->numframes-1; i>=0; i--) { + fr = (md2frame_t *)f; + l = (long *)&fr->mul; + for (j=5;j>=0;j--) l[j] = B_LITTLE32(l[j]); + f += m->framebytes; + } + + for (i = m->numglcmds-1; i>=0; i--) { + m->glcmds[i] = B_LITTLE32(m->glcmds[i]); + } + } +#endif + + strcpy(st,filnam); + for(i=strlen(st)-1;i>0;i--) + if ((st[i] == '/') || (st[i] == '\\')) { i++; break; } + if (i<0) i=0; + st[i] = 0; + m->basepath = (char *)malloc(i+1); if (!m->basepath) { free(m->glcmds); free(m->frames); free(m); return(0); } + strcpy(m->basepath, st); + + m->skinfn = (char *)calloc(m->numskins,64); if (!m->skinfn) { free(m->basepath); free(m->glcmds); free(m->frames); free(m); return(0); } + klseek(fil,head.ofsskins,SEEK_SET); + if (kread(fil,m->skinfn,64*m->numskins) != 64*m->numskins) + { free(m->glcmds); free(m->frames); free(m); return(0); } + + m->texid = (GLuint *)calloc(m->numskins, sizeof(GLuint) * (HICEFFECTMASK+1)); + if (!m->texid) { free(m->skinfn); free(m->basepath); free(m->glcmds); free(m->frames); free(m); return(0); } + + maxmodelverts = max(maxmodelverts, m->numverts); + + return(m); +} + +static int md2draw (md2model *m, spritetype *tspr) +{ + point3d fp, fp1, fp2, m0, m1, a0, a1; + md2frame_t *f0, *f1; + unsigned char *c0, *c1; + long i, *lptr; + float f, g, k0, k1, k2, k3, k4, k5, k6, k7, mat[16], pc[4]; + +// if ((tspr->cstat&48) == 32) return 0; + + updateanimation(m,tspr); + +// -------- Unnecessarily clean (lol) code to generate translation/rotation matrix for MD2 --------- + + //create current&next frame's vertex list from whole list + f0 = (md2frame_t *)&m->frames[m->cframe*m->framebytes]; + f1 = (md2frame_t *)&m->frames[m->nframe*m->framebytes]; + f = m->interpol; g = 1-f; + m0.x = f0->mul.x*m->scale*g; m1.x = f1->mul.x*m->scale*f; + m0.y = f0->mul.y*m->scale*g; m1.y = f1->mul.y*m->scale*f; + m0.z = f0->mul.z*m->scale*g; m1.z = f1->mul.z*m->scale*f; + a0.x = f0->add.x*m->scale; a0.x = (f1->add.x*m->scale-a0.x)*f+a0.x; + a0.y = f0->add.y*m->scale; a0.y = (f1->add.y*m->scale-a0.y)*f+a0.y; + a0.z = f0->add.z*m->scale; a0.z = (f1->add.z*m->scale-a0.z)*f+a0.z + m->zadd*m->scale; + c0 = &f0->verts[0].v[0]; c1 = &f1->verts[0].v[0]; + + // Parkar: Moved up to be able to use k0 for the y-flipping code + k0 = tspr->z; + if ((globalorientation&128) && !((globalorientation&48)==32)) k0 += (float)((tilesizy[tspr->picnum]*tspr->yrepeat)<<1); + + // Parkar: Changed to use the same method as centeroriented sprites + if (globalorientation&8) //y-flipping + { + m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; + k0 -= (float)((tilesizy[tspr->picnum]*tspr->yrepeat)<<2); + } + if (globalorientation&4) { m0.y = -m0.y; m1.y = -m1.y; a0.y = -a0.y; } //x-flipping + + f = ((float)tspr->xrepeat)/64*m->bscale; + m0.x *= f; m1.x *= f; a0.x *= f; f = -f; // 20040610: backwards models aren't cool + m0.y *= f; m1.y *= f; a0.y *= f; + f = ((float)tspr->yrepeat)/64*m->bscale; + m0.z *= f; m1.z *= f; a0.z *= f; + + // floor aligned + k1 = tspr->y; + if((globalorientation&48)==32) + { + m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; + m0.y = -m0.y; m1.y = -m1.y; a0.y = -a0.y; + f = a0.x; a0.x = a0.z; a0.z = f; + k1 += (float)((tilesizy[tspr->picnum]*tspr->yrepeat)>>3); + } + + f = (65536.0*512.0)/((float)xdimen*viewingrange); + g = 32.0/((float)xdimen*gxyaspect); + m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x-globalposx))/ 1024.0 + a0.y)*f; + m0.x *=-f; m1.x *=-f; a0.x = (((float)(k1 -globalposy))/ -1024.0 + a0.x)*-f; + m0.z *= g; m1.z *= g; a0.z = (((float)(k0 -globalposz))/-16384.0 + a0.z)*g; + + k0 = ((float)(tspr->x-globalposx))*f/1024.0; + k1 = ((float)(tspr->y-globalposy))*f/1024.0; + f = gcosang2*gshang; + g = gsinang2*gshang; + k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] / 16384.0; + k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] / 16384.0; + k2 = k0*(1-k4)+k1*k5; + k3 = k1*(1-k4)-k0*k5; + k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang; + mat[0] = k4*k6 + k5*k7; mat[4] = gchang*gstang; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7; + k6 = f*gctang + gsinang*gstang; k7 = g*gctang - gcosang*gstang; + mat[1] = k4*k6 + k5*k7; mat[5] = gchang*gctang; mat[ 9] = k4*k7 - k5*k6; mat[13] = k2*k6 + k3*k7; + k6 = gcosang2*gchang; k7 = gsinang2*gchang; + mat[2] = k4*k6 + k5*k7; mat[6] =-gshang; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7; + + mat[12] += a0.y*mat[0] + a0.z*mat[4] + a0.x*mat[ 8]; + mat[13] += a0.y*mat[1] + a0.z*mat[5] + a0.x*mat[ 9]; + mat[14] += a0.y*mat[2] + a0.z*mat[6] + a0.x*mat[10]; + + // floor aligned + if((globalorientation&48)==32) + { + f = mat[4]; mat[4] = mat[8]*16.0; mat[8] = -f*(1.0/16.0); + f = mat[5]; mat[5] = mat[9]*16.0; mat[9] = -f*(1.0/16.0); + f = mat[6]; mat[6] = mat[10]*16.0; mat[10] = -f*(1.0/16.0); + } + + //Mirrors + if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } + +// ------ Unnecessarily clean (lol) code to generate translation/rotation matrix for MD2 ends ------ + +// PLAG: Cleaner model rotation code + if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll) + { + if (spriteext[tspr->owner].xoff) + a0.x = (int)(spriteext[tspr->owner].xoff / (2048 * (m0.x+m1.x))); + else + a0.x = 0; + if (spriteext[tspr->owner].yoff) + a0.y = (int)(spriteext[tspr->owner].yoff / (2048 * (m0.y+m1.y))); + else + a0.y = 0; + if ((spriteext[tspr->owner].zoff) && !(tspr->cstat&1024)) + a0.z = (int)(spriteext[tspr->owner].zoff / (524288 * (m0.z+m1.z))); + else + a0.z = 0; + k0 = (float)sintable[(spriteext[tspr->owner].pitch+512)&2047] / 16384.0; + k1 = (float)sintable[spriteext[tspr->owner].pitch&2047] / 16384.0; + k2 = (float)sintable[(spriteext[tspr->owner].roll+512)&2047] / 16384.0; + k3 = (float)sintable[spriteext[tspr->owner].roll&2047] / 16384.0; + } + for(i=m->numverts-1;i>=0;i--) + { + if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll) + { + fp.z = c0[(i<<2)+0] + a0.x; + fp.x = c0[(i<<2)+1] + a0.y; + fp.y = c0[(i<<2)+2] + a0.z; + fp1.x = fp.x*k2 + fp.y*k3; + fp1.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp1.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + fp.z = c1[(i<<2)+0] + a0.x; + fp.x = c1[(i<<2)+1] + a0.y; + fp2.y = c1[(i<<2)+2] + a0.z; + fp2.x = fp.x*k2 + fp.y*k3; + fp2.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp2.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + fp.z = (fp1.z - a0.x)*m0.x + (fp2.z - a0.x)*m1.x; + fp.x = (fp1.x - a0.y)*m0.y + (fp2.x - a0.y)*m1.y; + fp.y = (fp1.y - a0.z)*m0.z + (fp2.y - a0.z)*m1.z; + } + else + { + fp.z = c0[(i<<2)+0]*m0.x + c1[(i<<2)+0]*m1.x; + fp.y = c0[(i<<2)+2]*m0.z + c1[(i<<2)+2]*m1.z; + fp.x = c0[(i<<2)+1]*m0.y + c1[(i<<2)+1]*m1.y; + } + vertlist[i].x = fp.x; + vertlist[i].y = fp.y; + vertlist[i].z = fp.z; + } + bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation + mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; bglLoadMatrixf(mat); +// PLAG: End + + i = mdloadskin(m,tile2model[tspr->picnum].skinnum,globalpal,0); if (!i) return 0; + + //bit 10 is an ugly hack in game.c\animatesprites telling MD2SPRITE + //to use Z-buffer hacks to hide overdraw problems with the shadows + if (tspr->cstat&1024) + { + bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.9999); + } + bglPushAttrib(GL_POLYGON_BIT); + if ((grhalfxdown10x >= 0) ^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)) bglFrontFace(GL_CW); else bglFrontFace(GL_CCW); + bglEnable(GL_CULL_FACE); + bglCullFace(GL_BACK); + + bglEnable(GL_TEXTURE_2D); + bglBindTexture(GL_TEXTURE_2D, i); + + pc[0] = pc[1] = pc[2] = ((float)(numpalookups-min(max(globalshade+m->shadeoff,0),numpalookups)))/((float)numpalookups); + pc[0] *= (float)hictinting[globalpal].r / 255.0; + pc[1] *= (float)hictinting[globalpal].g / 255.0; + pc[2] *= (float)hictinting[globalpal].b / 255.0; + if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; } else pc[3] = 1.0; + if (m->usesalpha) //Sprites with alpha in texture + { +// bglEnable(GL_BLEND);// bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +// bglEnable(GL_ALPHA_TEST); bglAlphaFunc(GL_GREATER,0.32); + float al = 0.32; + if (alphahackarray[globalpicnum] != 0) + al=alphahackarray[globalpicnum]; + bglEnable(GL_BLEND); + bglEnable(GL_ALPHA_TEST); + bglAlphaFunc(GL_GREATER,al); + } + else + { + if (tspr->cstat&2) bglEnable(GL_BLEND); else bglDisable(GL_BLEND); + } + bglColor4f(pc[0],pc[1],pc[2],pc[3]); + + for(lptr=m->glcmds;(i=*lptr++);) + { + if (i < 0) { bglBegin(GL_TRIANGLE_FAN); i = -i; } + else { bglBegin(GL_TRIANGLE_STRIP); } + for(;i>0;i--,lptr+=3) + { + bglTexCoord2f(((float *)lptr)[0],((float *)lptr)[1]); + bglVertex3fv((float *)&vertlist[lptr[2]]); + } + bglEnd(); + } + + if (m->usesalpha) bglDisable(GL_ALPHA_TEST); + bglDisable(GL_CULL_FACE); + bglPopAttrib(); + if (tspr->cstat&1024) + { + bglDepthFunc(GL_LEQUAL); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.99999); + } + bglLoadIdentity(); + + return 1; +} + +//---------------------------------------- MD2 LIBRARY ENDS ---------------------------------------- + +// DICHOTOMIC RECURSIVE SORTING - USED BY MD3DRAW - MAY PUT IT IN ITS OWN SOURCE FILE LATER +int partition(unsigned short *indexes, float *depths, int f, int l) { + int up,down,temp; + float tempf; + unsigned short tempus; + float piv = depths[f]; + unsigned short piv2 = indexes[f]; + up = f; + down = l; + do { + while ((depths[up] <= piv) && (up < l)) + up++; + while ((depths[down] > piv) && (down > f)) + down--; + if (up < down ) + { + tempf = depths[up]; + depths[up] = depths[down]; + depths[down] = tempf; + tempus = indexes[up]; + indexes[up] = indexes[down]; + indexes[down] = tempus; + } + } while (down > up); + depths[f] = depths[down]; + depths[down] = piv; + indexes[f] = indexes[down]; + indexes[down] = piv2; + return down; +} + +void quicksort(unsigned short *indexes, float *depths, int first, int last) { + int pivIndex = 0; + if(first < last) { + pivIndex = partition(indexes,depths,first, last); + quicksort(indexes,depths,first,(pivIndex-1)); + quicksort(indexes,depths,(pivIndex+1),last); + } +} +// END OF QUICKSORT LIB + +//--------------------------------------- MD3 LIBRARY BEGINS --------------------------------------- + +static md3model *md3load (int fil) +{ + char *buf, st[BMAX_PATH+2], bst[BMAX_PATH+2]; + long i, j, surfi, ofsurf, bsc, offs[4], leng[4]; + md3model *m; + md3surf_t *s; + + m = (md3model *)calloc(1,sizeof(md3model)); if (!m) return(0); + m->mdnum = 3; m->texid = 0; m->scale = .01; + + kread(fil,&m->head,sizeof(md3head_t)); + m->head.id = B_LITTLE32(m->head.id); m->head.vers = B_LITTLE32(m->head.vers); + m->head.flags = B_LITTLE32(m->head.flags); m->head.numframes = B_LITTLE32(m->head.numframes); + m->head.numtags = B_LITTLE32(m->head.numtags); m->head.numsurfs = B_LITTLE32(m->head.numsurfs); + m->head.numskins = B_LITTLE32(m->head.numskins); m->head.frames = (md3frame_t*)B_LITTLE32((long)m->head.frames); + m->head.tags = (md3tag_t*)B_LITTLE32((long)m->head.tags); m->head.surfs = (md3surf_t*)B_LITTLE32((long)m->head.surfs); + m->head.eof = B_LITTLE32(m->head.eof); + + if ((m->head.id != 0x33504449) && (m->head.vers != 15)) { free(m); return(0); } //"IDP3" + + m->numskins = m->head.numskins; //<- dead code? + m->numframes = m->head.numframes; + + ofsurf = (long)m->head.surfs; + + klseek(fil,(long)m->head.frames,SEEK_SET); i = m->head.numframes*sizeof(md3frame_t); + m->head.frames = (md3frame_t *)malloc(i); if (!m->head.frames) { free(m); return(0); } + kread(fil,m->head.frames,i); + + if (m->head.numtags == 0) m->head.tags = NULL; + else { + klseek(fil,(long)m->head.tags,SEEK_SET); i = m->head.numtags*sizeof(md3tag_t); + m->head.tags = (md3tag_t *)malloc(i); if (!m->head.tags) { free(m->head.frames); free(m); return(0); } + kread(fil,m->head.tags,i); + } + + klseek(fil,(long)m->head.surfs,SEEK_SET); i = m->head.numsurfs*sizeof(md3surf_t); + m->head.surfs = (md3surf_t *)malloc(i); if (!m->head.surfs) { if (m->head.tags) free(m->head.tags); free(m->head.frames); free(m); return(0); } + +#if B_BIG_ENDIAN != 0 + { + long *l; + + for (i = m->head.numframes-1; i>=0; i--) { + l = (long *)&m->head.frames[i].min; + for (j=3+3+3+1-1;j>=0;j--) l[j] = B_LITTLE32(l[j]); + } + + for (i = m->head.numtags-1; i>=0; i--) { + l = (long *)&m->head.tags[i].p; + for (j=3+3+3+3-1;j>=0;j--) l[j] = B_LITTLE32(l[j]); + } + } +#endif + + for(surfi=0;surfihead.numsurfs;surfi++) + { + s = &m->head.surfs[surfi]; + klseek(fil,ofsurf,SEEK_SET); kread(fil,s,sizeof(md3surf_t)); + +#if B_BIG_ENDIAN != 0 + { + long *l; + s->id = B_LITTLE32(s->id); + l = (long *)&s->flags; + for (j=1+1+1+1+1+1+1+1+1+1-1;j>=0;j--) l[j] = B_LITTLE32(l[j]); + } +#endif + + offs[0] = ofsurf+((long)(s->tris )); leng[0] = s->numtris*sizeof(md3tri_t); + offs[1] = ofsurf+((long)(s->shaders)); leng[1] = s->numshaders*sizeof(md3shader_t); + offs[2] = ofsurf+((long)(s->uv )); leng[2] = s->numverts*sizeof(md3uv_t); + offs[3] = ofsurf+((long)(s->xyzn )); leng[3] = s->numframes*s->numverts*sizeof(md3xyzn_t); + + s->tris = (md3tri_t *)malloc(leng[0]+leng[1]+leng[2]+leng[3]); + if (!s->tris) + { + for(surfi--;surfi>=0;surfi--) free(m->head.surfs[surfi].tris); + if (m->head.tags) free(m->head.tags); free(m->head.frames); free(m); return(0); + } + s->shaders = (md3shader_t *)(((long)s->tris )+leng[0]); + s->uv = (md3uv_t *)(((long)s->shaders)+leng[1]); + s->xyzn = (md3xyzn_t *)(((long)s->uv )+leng[2]); + + klseek(fil,offs[0],SEEK_SET); kread(fil,s->tris ,leng[0]); + klseek(fil,offs[1],SEEK_SET); kread(fil,s->shaders,leng[1]); + klseek(fil,offs[2],SEEK_SET); kread(fil,s->uv ,leng[2]); + klseek(fil,offs[3],SEEK_SET); kread(fil,s->xyzn ,leng[3]); + +#if B_BIG_ENDIAN != 0 + { + long *l; + + for (i=s->numtris-1;i>=0;i--) { + for (j=2;j>=0;j--) s->tris[i].i[j] = B_LITTLE32(s->tris[i].i[j]); + } + for (i=s->numshaders-1;i>=0;i--) { + s->shaders[i].i = B_LITTLE32(s->shaders[i].i); + } + for (i=s->numverts-1;i>=0;i--) { + l = (long*)&s->uv[i].u; + l[0] = B_LITTLE32(l[0]); + l[1] = B_LITTLE32(l[1]); + } + for (i=s->numframes*s->numverts-1;i>=0;i--) { + s->xyzn[i].x = (signed short)B_LITTLE16((unsigned short)s->xyzn[i].x); + s->xyzn[i].y = (signed short)B_LITTLE16((unsigned short)s->xyzn[i].y); + s->xyzn[i].z = (signed short)B_LITTLE16((unsigned short)s->xyzn[i].z); + } + } +#endif + maxmodelverts = max(maxmodelverts, s->numverts); + ofsurf += s->ofsend; + } + +#if 0 + strcpy(st,filnam); + for(i=0,j=0;st[i];i++) if ((st[i] == '/') || (st[i] == '\\')) j = i+1; + st[j] = '*'; st[j+1] = 0; + kzfindfilestart(st); bsc = -1; + while (kzfindfile(st)) + { + if (st[0] == '\\') continue; + + for(i=0,j=0;st[i];i++) if (st[i] == '.') j = i+1; + if ((!stricmp(&st[j],"JPG")) || (!stricmp(&st[j],"PNG")) || (!stricmp(&st[j],"GIF")) || + (!stricmp(&st[j],"PCX")) || (!stricmp(&st[j],"TGA")) || (!stricmp(&st[j],"BMP")) || + (!stricmp(&st[j],"CEL"))) + { + for(i=0;st[i];i++) if (st[i] != filnam[i]) break; + if (i > bsc) { bsc = i; strcpy(bst,st); } + } + } + if (!mdloadskin(&m->texid,&m->usesalpha,bst)) ;//bad! +#endif + + return(m); +} + +static int md3draw (md3model *m, spritetype *tspr) +{ + point3d fp, fp1, fp2, m0, m1, a0, a1; + md3xyzn_t *v0, *v1; + long i, j, k, surfi, *lptr; + float f, g, k0, k1, k2, k3, k4, k5, k6, k7, mat[16], pc[4]; + md3surf_t *s; + //PLAG : sorting stuff + unsigned short *indexes; + float *maxdepths; + unsigned short tempus; + + +// if ((tspr->cstat&48) == 32) return 0; + + updateanimation((md2model *)m,tspr); + + //create current&next frame's vertex list from whole list + + f = m->interpol; g = 1-f; + m0.x = (1.0/64.0)*m->scale*g; m1.x = (1.0/64.0)*m->scale*f; + m0.y = (1.0/64.0)*m->scale*g; m1.y = (1.0/64.0)*m->scale*f; + m0.z = (1.0/64.0)*m->scale*g; m1.z = (1.0/64.0)*m->scale*f; + a0.x = a0.y = 0; a0.z = m->zadd*m->scale; + + // Parkar: Moved up to be able to use k0 for the y-flipping code + k0 = tspr->z; + if ((globalorientation&128) && !((globalorientation&48)==32)) k0 += (float)((tilesizy[tspr->picnum]*tspr->yrepeat)<<1); + + // Parkar: Changed to use the same method as centeroriented sprites + if (globalorientation&8) //y-flipping + { + m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; + k0 -= (float)((tilesizy[tspr->picnum]*tspr->yrepeat)<<2); + } + if (globalorientation&4) { m0.y = -m0.y; m1.y = -m1.y; a0.y = -a0.y; } //x-flipping + + f = ((float)tspr->xrepeat)/64*m->bscale; + m0.x *= f; m1.x *= f; a0.x *= f; f = -f; // 20040610: backwards models aren't cool + m0.y *= f; m1.y *= f; a0.y *= f; + f = ((float)tspr->yrepeat)/64*m->bscale; + m0.z *= f; m1.z *= f; a0.z *= f; + + // floor aligned + k1 = tspr->y; + if((globalorientation&48)==32) + { + m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; + m0.y = -m0.y; m1.y = -m1.y; a0.y = -a0.y; + f = a0.x; a0.x = a0.z; a0.z = f; + k1 += (float)((tilesizy[tspr->picnum]*tspr->yrepeat)>>3); + } + + f = (65536.0*512.0)/((float)xdimen*viewingrange); + g = 32.0/((float)xdimen*gxyaspect); + m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x-globalposx))/ 1024.0 + a0.y)*f; + m0.x *=-f; m1.x *=-f; a0.x = (((float)(k1 -globalposy))/ -1024.0 + a0.x)*-f; + m0.z *= g; m1.z *= g; a0.z = (((float)(k0 -globalposz))/-16384.0 + a0.z)*g; + + k0 = ((float)(tspr->x-globalposx))*f/1024.0; + k1 = ((float)(tspr->y-globalposy))*f/1024.0; + f = gcosang2*gshang; + g = gsinang2*gshang; + k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] / 16384.0; + k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] / 16384.0; + k2 = k0*(1-k4)+k1*k5; + k3 = k1*(1-k4)-k0*k5; + k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang; + mat[0] = k4*k6 + k5*k7; mat[4] = gchang*gstang; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7; + k6 = f*gctang + gsinang*gstang; k7 = g*gctang - gcosang*gstang; + mat[1] = k4*k6 + k5*k7; mat[5] = gchang*gctang; mat[ 9] = k4*k7 - k5*k6; mat[13] = k2*k6 + k3*k7; + k6 = gcosang2*gchang; k7 = gsinang2*gchang; + mat[2] = k4*k6 + k5*k7; mat[6] =-gshang; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7; + + mat[12] += a0.y*mat[0] + a0.z*mat[4] + a0.x*mat[ 8]; + mat[13] += a0.y*mat[1] + a0.z*mat[5] + a0.x*mat[ 9]; + mat[14] += a0.y*mat[2] + a0.z*mat[6] + a0.x*mat[10]; + + // floor aligned + if((globalorientation&48)==32) + { + f = mat[4]; mat[4] = mat[8]*16.0; mat[8] = -f*(1.0/16.0); + f = mat[5]; mat[5] = mat[9]*16.0; mat[9] = -f*(1.0/16.0); + f = mat[6]; mat[6] = mat[10]*16.0; mat[10] = -f*(1.0/16.0); + } + + //Mirrors + if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } + +//------------ + //bit 10 is an ugly hack in game.c\animatesprites telling MD2SPRITE + //to use Z-buffer hacks to hide overdraw problems with the shadows + if (tspr->cstat&1024) + { + bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.9999); + } + bglPushAttrib(GL_POLYGON_BIT); + if ((grhalfxdown10x >= 0) ^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)) bglFrontFace(GL_CW); else bglFrontFace(GL_CCW); + bglEnable(GL_CULL_FACE); + bglCullFace(GL_BACK); + + bglEnable(GL_TEXTURE_2D); + + pc[0] = pc[1] = pc[2] = ((float)(numpalookups-min(max(globalshade+m->shadeoff,0),numpalookups)))/((float)numpalookups); + pc[0] *= (float)hictinting[globalpal].r / 255.0; + pc[1] *= (float)hictinting[globalpal].g / 255.0; + pc[2] *= (float)hictinting[globalpal].b / 255.0; + if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; } else pc[3] = 1.0; + if (m->usesalpha) //Sprites with alpha in texture + { +// bglEnable(GL_BLEND);// bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +// bglEnable(GL_ALPHA_TEST); bglAlphaFunc(GL_GREATER,0.32); +// float al = 0.32; + // PLAG : default cutoff removed + float al = 0.0; + if (alphahackarray[globalpicnum] != 0) + al=alphahackarray[globalpicnum]; + bglEnable(GL_BLEND); + bglEnable(GL_ALPHA_TEST); + bglAlphaFunc(GL_GREATER,al); + } + else + { + if (tspr->cstat&2) bglEnable(GL_BLEND); else bglDisable(GL_BLEND); + } + bglColor4f(pc[0],pc[1],pc[2],pc[3]); +//------------ + +// PLAG: Cleaner model rotation code + if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll) + { + if (spriteext[tspr->owner].xoff) + a0.x = (int)(spriteext[tspr->owner].xoff / (2048 * (m0.x+m1.x))); + else + a0.x = 0; + if (spriteext[tspr->owner].yoff) + a0.y = (int)(spriteext[tspr->owner].yoff / (2048 * (m0.x+m1.x))); + else + a0.y = 0; + if ((spriteext[tspr->owner].zoff) && !(tspr->cstat&1024)) + a0.z = (int)(spriteext[tspr->owner].zoff / (524288 * (m0.z+m1.z))); + else + a0.z = 0; + k0 = (float)sintable[(spriteext[tspr->owner].pitch+512)&2047] / 16384.0; + k1 = (float)sintable[spriteext[tspr->owner].pitch&2047] / 16384.0; + k2 = (float)sintable[(spriteext[tspr->owner].roll+512)&2047] / 16384.0; + k3 = (float)sintable[spriteext[tspr->owner].roll&2047] / 16384.0; + } + for(surfi=0;surfihead.numsurfs;surfi++) + { + s = &m->head.surfs[surfi]; + v0 = &s->xyzn[m->cframe*s->numverts]; + v1 = &s->xyzn[m->nframe*s->numverts]; + + for(i=s->numverts-1;i>=0;i--) + { + if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll) + { + fp.z = v0[i].x + a0.x; + fp.x = v0[i].y + a0.y; + fp.y = v0[i].z + a0.z; + fp1.x = fp.x*k2 + fp.y*k3; + fp1.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp1.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + fp.z = v1[i].x + a0.x; + fp.x = v1[i].y + a0.y; + fp.y = v1[i].z + a0.z; + fp2.x = fp.x*k2 + fp.y*k3; + fp2.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp2.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + fp.z = (fp1.z - a0.x)*m0.x + (fp2.z - a0.x)*m1.x; + fp.x = (fp1.x - a0.y)*m0.y + (fp2.x - a0.y)*m1.y; + fp.y = (fp1.y - a0.z)*m0.z + (fp2.y - a0.z)*m1.z; + } + else + { + fp.z = v0[i].x*m0.x + v1[i].x*m1.x; + fp.y = v0[i].z*m0.z + v1[i].z*m1.z; + fp.x = v0[i].y*m0.y + v1[i].y*m1.y; + } + vertlist[i].x = fp.x; + vertlist[i].y = fp.y; + vertlist[i].z = fp.z; + } + bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation + mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; bglLoadMatrixf(mat); +// PLAG: End + + i = mdloadskin((md2model *)m,tile2model[tspr->picnum].skinnum,globalpal,surfi); if (!i) continue; + //i = mdloadskin((md2model *)m,tile2model[tspr->picnum].skinnum,surfi); //hack for testing multiple surfaces per MD3 + bglBindTexture(GL_TEXTURE_2D, i); + +//PLAG: delayed polygon-level sorted rendering + if (m->usesalpha && !(tspr->cstat & 1024)) + { + indexes = malloc(sizeof(unsigned short) * s->numtris); + maxdepths = malloc(sizeof(float) * s->numtris); + + // old sorting methods - dead code + /*for(i=s->numtris-1;i>=0;i--) + { + tempf = (vertlist[s->tris[i].i[0]].x * mat[2]) + (vertlist[s->tris[i].i[0]].y * mat[6]) + (vertlist[s->tris[i].i[0]].z * mat[10]) + mat[14]; + if (tempf < ((vertlist[s->tris[i].i[1]].x * mat[2]) + (vertlist[s->tris[i].i[1]].y * mat[6]) + (vertlist[s->tris[i].i[1]].z * mat[10]) + mat[14])) + tempf = (vertlist[s->tris[i].i[1]].x * mat[2]) + (vertlist[s->tris[i].i[1]].y * mat[6]) + (vertlist[s->tris[i].i[1]].z * mat[10]) + mat[14]; + if (tempf < ((vertlist[s->tris[i].i[2]].x * mat[2]) + (vertlist[s->tris[i].i[2]].y * mat[6]) + (vertlist[s->tris[i].i[2]].z * mat[10]) + mat[14])) + tempf = (vertlist[s->tris[i].i[2]].x * mat[2]) + (vertlist[s->tris[i].i[2]].y * mat[6]) + (vertlist[s->tris[i].i[2]].z * mat[10]) + mat[14]; + maxdepths[i] = tempf; + indexes[i] = i; + } + + for(i=s->numtris-1;i>=0;i--) + { + tempf = (vertlist[s->tris[i].i[0]].x * mat[2]) + (vertlist[s->tris[i].i[0]].y * mat[6]) + (vertlist[s->tris[i].i[0]].z * mat[10]) + mat[14]; + tempf += (vertlist[s->tris[i].i[1]].x * mat[2]) + (vertlist[s->tris[i].i[1]].y * mat[6]) + (vertlist[s->tris[i].i[1]].z * mat[10]) + mat[14]; + tempf += (vertlist[s->tris[i].i[2]].x * mat[2]) + (vertlist[s->tris[i].i[2]].y * mat[6]) + (vertlist[s->tris[i].i[2]].z * mat[10]) + mat[14]; + tempf /= 3.0f; + maxdepths[i] = tempf; + indexes[i] = i; + } + + for(i=s->numtris-1;i>=0;i--) + { + tempvec[0].x = (vertlist[s->tris[i].i[0]].x * mat[0]) + (vertlist[s->tris[i].i[0]].y * mat[4]) + (vertlist[s->tris[i].i[0]].z * mat[8]) + mat[12]; + tempvec[0].y = (vertlist[s->tris[i].i[0]].x * mat[1]) + (vertlist[s->tris[i].i[0]].y * mat[5]) + (vertlist[s->tris[i].i[0]].z * mat[9]) + mat[13]; + tempvec[0].z = (vertlist[s->tris[i].i[0]].x * mat[2]) + (vertlist[s->tris[i].i[0]].y * mat[6]) + (vertlist[s->tris[i].i[0]].z * mat[10]) + mat[14]; + + tempvec[1].x = (vertlist[s->tris[i].i[1]].x * mat[0]) + (vertlist[s->tris[i].i[1]].y * mat[4]) + (vertlist[s->tris[i].i[1]].z * mat[8]) + mat[12]; + tempvec[1].y = (vertlist[s->tris[i].i[1]].x * mat[1]) + (vertlist[s->tris[i].i[1]].y * mat[5]) + (vertlist[s->tris[i].i[1]].z * mat[9]) + mat[13]; + tempvec[1].z = (vertlist[s->tris[i].i[1]].x * mat[2]) + (vertlist[s->tris[i].i[1]].y * mat[6]) + (vertlist[s->tris[i].i[1]].z * mat[10]) + mat[14]; + + tempvec[2].x = (vertlist[s->tris[i].i[2]].x * mat[0]) + (vertlist[s->tris[i].i[2]].y * mat[4]) + (vertlist[s->tris[i].i[2]].z * mat[8]) + mat[12]; + tempvec[2].y = (vertlist[s->tris[i].i[2]].x * mat[1]) + (vertlist[s->tris[i].i[2]].y * mat[5]) + (vertlist[s->tris[i].i[2]].z * mat[9]) + mat[13]; + tempvec[2].z = (vertlist[s->tris[i].i[2]].x * mat[2]) + (vertlist[s->tris[i].i[2]].y * mat[6]) + (vertlist[s->tris[i].i[2]].z * mat[10]) + mat[14]; + + tempf = (tempvec[0].x * tempvec[0].x) + (tempvec[0].y * tempvec[0].y) + (tempvec[0].z * tempvec[0].z); + tempf += (tempvec[1].x * tempvec[1].x) + (tempvec[1].y * tempvec[1].y) + (tempvec[1].z * tempvec[1].z); + tempf += (tempvec[2].x * tempvec[2].x) + (tempvec[2].y * tempvec[2].y) + (tempvec[2].z * tempvec[2].z); + + maxdepths[i] = tempf; + indexes[i] = i; + }*/ + + for(i=s->numtris-1;i>=0;i--) + { + // Matrix multiplication - ugly but clear + fp.x = (vertlist[s->tris[i].i[0]].x * mat[0]) + (vertlist[s->tris[i].i[0]].y * mat[4]) + (vertlist[s->tris[i].i[0]].z * mat[8]) + mat[12]; + fp.y = (vertlist[s->tris[i].i[0]].x * mat[1]) + (vertlist[s->tris[i].i[0]].y * mat[5]) + (vertlist[s->tris[i].i[0]].z * mat[9]) + mat[13]; + fp.z = (vertlist[s->tris[i].i[0]].x * mat[2]) + (vertlist[s->tris[i].i[0]].y * mat[6]) + (vertlist[s->tris[i].i[0]].z * mat[10]) + mat[14]; + + fp1.x = (vertlist[s->tris[i].i[1]].x * mat[0]) + (vertlist[s->tris[i].i[1]].y * mat[4]) + (vertlist[s->tris[i].i[1]].z * mat[8]) + mat[12]; + fp1.y = (vertlist[s->tris[i].i[1]].x * mat[1]) + (vertlist[s->tris[i].i[1]].y * mat[5]) + (vertlist[s->tris[i].i[1]].z * mat[9]) + mat[13]; + fp1.z = (vertlist[s->tris[i].i[1]].x * mat[2]) + (vertlist[s->tris[i].i[1]].y * mat[6]) + (vertlist[s->tris[i].i[1]].z * mat[10]) + mat[14]; + + fp2.x = (vertlist[s->tris[i].i[2]].x * mat[0]) + (vertlist[s->tris[i].i[2]].y * mat[4]) + (vertlist[s->tris[i].i[2]].z * mat[8]) + mat[12]; + fp2.y = (vertlist[s->tris[i].i[2]].x * mat[1]) + (vertlist[s->tris[i].i[2]].y * mat[5]) + (vertlist[s->tris[i].i[2]].z * mat[9]) + mat[13]; + fp2.z = (vertlist[s->tris[i].i[2]].x * mat[2]) + (vertlist[s->tris[i].i[2]].y * mat[6]) + (vertlist[s->tris[i].i[2]].z * mat[10]) + mat[14]; + + f = (fp.x * fp.x) + (fp.y * fp.y) + (fp.z * fp.z); + + g = (fp1.x * fp1.x) + (fp1.y * fp1.y) + (fp1.z * fp1.z); + if (f > g) + f = g; + g = (fp2.x * fp2.x) + (fp2.y * fp2.y) + (fp2.z * fp2.z); + if (f > g) + f = g; + + maxdepths[i] = f; + indexes[i] = i; + } + + //bubble sort - dead code + /*test = 0; + j = 0; + while (j == 0) + { + j = 1; + for(i=s->numtris-1;i>0;i--) + if (maxdepths[i] < maxdepths[i-1]) + { + f = maxdepths[i]; + maxdepths[i] = maxdepths[i-1]; + maxdepths[i-1] = f; + k = indexes[i]; + indexes[i] = indexes[i-1]; + indexes[i-1] = k; + test++; + j = 0; + } + }*/ + + // dichotomic recursive sorting - about 100x less iterations than bubblesort + quicksort(indexes, maxdepths, 0, s->numtris - 1); + + bglBegin(GL_TRIANGLES); + for(i=s->numtris-1;i>=0;i--) + for(j=0;j<3;j++) + { + k = s->tris[indexes[i]].i[j]; + bglTexCoord2f(s->uv[k].u,s->uv[k].v); + bglVertex3fv((float *)&vertlist[k]); + } + bglEnd(); + + free(indexes); + free(maxdepths); + } + else + { + bglBegin(GL_TRIANGLES); + for(i=s->numtris-1;i>=0;i--) + for(j=0;j<3;j++) + { + k = s->tris[i].i[j]; + bglTexCoord2f(s->uv[k].u,s->uv[k].v); + bglVertex3fv((float *)&vertlist[k]); + } + bglEnd(); + } + } +//------------ + + if (m->usesalpha) bglDisable(GL_ALPHA_TEST); + bglDisable(GL_CULL_FACE); + bglPopAttrib(); + if (tspr->cstat&1024) + { + bglDepthFunc(GL_LEQUAL); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.99999); + } + bglLoadIdentity(); + + return 1; +} + +static void md3free (md3model *m) +{ + mdanim_t *anim, *nanim = NULL; + mdskinmap_t *sk, *nsk = NULL; + md3surf_t *s; + long surfi; + + if (!m) return; + + for(anim=m->animations; anim; anim=nanim) + { + nanim = anim->next; + free(anim); + } + for(sk=m->skinmap; sk; sk=nsk) + { + nsk = sk->next; + free(sk->fn); + free(sk); + } + + if (m->head.surfs) + { + for(surfi=m->head.numsurfs-1;surfi>=0;surfi--) + { + s = &m->head.surfs[surfi]; + if (s->tris) free(s->tris); + } + free(m->head.surfs); + } + if (m->head.tags) free(m->head.tags); + if (m->head.frames) free(m->head.frames); + + if (m->texid) free(m->texid); + + free(m); +} + +//---------------------------------------- MD3 LIBRARY ENDS ---------------------------------------- +//--------------------------------------- VOX LIBRARY BEGINS --------------------------------------- + + //For loading/conversion only +static long xsiz, ysiz, zsiz, yzsiz, *vbit = 0; //vbit: 1 bit per voxel: 0=air,1=solid +static float xpiv, ypiv, zpiv; //Might want to use more complex/unique names! +static long *vcolhashead = 0, vcolhashsizm1; +typedef struct { long p, c, n; } voxcol_t; +static voxcol_t *vcol = 0; long vnum = 0, vmax = 0; +typedef struct { short x, y; } spoint2d; +static spoint2d *shp; +static long *shcntmal, *shcnt = 0, shcntp; +static long mytexo5, *zbit, gmaxx, gmaxy, garea, pow2m1[33]; +static voxmodel *gvox; + + //pitch must equal xsiz*4 +unsigned gloadtex (long *picbuf, long xsiz, long ysiz, long is8bit, long dapal) +{ + unsigned rtexid; + coltype *pic, *pic2; + unsigned char *cptr; + long i; + + pic = (coltype *)picbuf; //Correct for GL's RGB order; also apply gamma here.. + pic2 = (coltype *)malloc(xsiz*ysiz*sizeof(long)); if (!pic2) return((unsigned)-1); + cptr = (unsigned char*)&britable[gammabrightness ? 0 : curbrightness][0]; + if (!is8bit) + { + for(i=xsiz*ysiz-1;i>=0;i--) + { + pic2[i].b = cptr[pic[i].r]; + pic2[i].g = cptr[pic[i].g]; + pic2[i].r = cptr[pic[i].b]; + pic2[i].a = 255; + } + } + else + { + if (palookup[dapal] == 0) dapal = 0; + for(i=xsiz*ysiz-1;i>=0;i--) + { + pic2[i].b = cptr[palette[(long)palookup[dapal][pic[i].a]*3+2]*4]; + pic2[i].g = cptr[palette[(long)palookup[dapal][pic[i].a]*3+1]*4]; + pic2[i].r = cptr[palette[(long)palookup[dapal][pic[i].a]*3+0]*4]; + pic2[i].a = 255; + } + } + + bglGenTextures(1,(GLuint*)&rtexid); + bglBindTexture(GL_TEXTURE_2D,rtexid); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + bglTexImage2D(GL_TEXTURE_2D,0,4,xsiz,ysiz,0,GL_RGBA,GL_UNSIGNED_BYTE,(unsigned char *)pic2); + free(pic2); + return(rtexid); +} + +static long getvox (long x, long y, long z) +{ + z += x*yzsiz + y*zsiz; + for(x=vcolhashead[(z*214013)&vcolhashsizm1];x>=0;x=vcol[x].n) + if (vcol[x].p == z) return(vcol[x].c); + return(0x808080); +} + +static void putvox (long x, long y, long z, long col) +{ + if (vnum >= vmax) { vmax = max(vmax<<1,4096); vcol = (voxcol_t *)realloc(vcol,vmax*sizeof(voxcol_t)); } + + z += x*yzsiz + y*zsiz; + vcol[vnum].p = z; z = ((z*214013)&vcolhashsizm1); + vcol[vnum].c = col; + vcol[vnum].n = vcolhashead[z]; vcolhashead[z] = vnum++; +} + + //Set all bits in vbit from (x,y,z0) to (x,y,z1-1) to 0's +static void setzrange0 (long *lptr, long z0, long z1) +{ + long z, ze; + if (!((z0^z1)&~31)) { lptr[z0>>5] &= ((~(-1<>5); ze = (z1>>5); + lptr[z] &=~(-1<>5] |= ((~(-1<>5); ze = (z1>>5); + lptr[z] |= (-1<mytexx + x0; + for(dy=0;dy;dy--,i+=gvox->mytexx) + for(x=0;x>5]&(1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); + m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; + if (!c) { for(m&=m1;dy;dy--,i+=mytexo5) if (zbit[i]&m) return(0); } + else + { for(;dy;dy--,i+=mytexo5) + { + if (zbit[i]&m) return(0); + for(x=1;xmytexx + x0; + for(y=0;ymytexx) + for(x=0;x>5] |= (1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); + m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; + if (!c) { for(m&=m1;dy;dy--,i+=mytexo5) zbit[i] |= m; } + else + { for(;dy;dy--,i+=mytexo5) + { + zbit[i] |= m; + for(x=1;x gmaxx) gmaxx = x; + if (y > gmaxy) gmaxy = y; + garea += (x+(VOXBORDWIDTH<<1))*(y+(VOXBORDWIDTH<<1)); + gvox->qcnt++; +} + +static void addquad (long x0, long y0, long z0, long x1, long y1, long z1, long x2, long y2, long z2, long face) +{ + long i, j, x, y, z, xx, yy, nx = 0, ny = 0, nz = 0, *lptr; + voxrect_t *qptr; + + x = labs(x2-x0); y = labs(y2-y0); z = labs(z2-z0); + if (!x) { x = y; y = z; i = 0; } else if (!y) { y = z; i = 1; } else i = 2; + if (x < y) { z = x; x = y; y = z; i += 3; } + z = shcnt[y*shcntp+x]++; + lptr = &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx+(shp[z].x+VOXBORDWIDTH)]; + switch(face) + { + case 0: ny = y1; x2 = x0; x0 = x1; x1 = x2; break; + case 1: ny = y0; y0++; y1++; y2++; break; + case 2: nz = z1; y0 = y2; y2 = y1; y1 = y0; z0++; z1++; z2++; break; + case 3: nz = z0; break; + case 4: nx = x1; y2 = y0; y0 = y1; y1 = y2; x0++; x1++; x2++; break; + case 5: nx = x0; break; + } + for(yy=0;yymytexx) + for(xx=0;xxmytex[(shp[z].y+yy)*gvox->mytexx+shp[z].x]; + lptr[xx] = lptr[VOXBORDWIDTH]; lptr[xx+x+VOXBORDWIDTH] = lptr[x-1+VOXBORDWIDTH]; + } + //Extend borders vertically + for(yy=0;yymytex[(shp[z].y+yy)*gvox->mytexx+shp[z].x], + &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx+shp[z].x], + (x+(VOXBORDWIDTH<<1))<<2); + memcpy(&gvox->mytex[(shp[z].y+y+yy+VOXBORDWIDTH)*gvox->mytexx+shp[z].x], + &gvox->mytex[(shp[z].y+y-1+VOXBORDWIDTH)*gvox->mytexx+shp[z].x], + (x+(VOXBORDWIDTH<<1))<<2); + } + + qptr = &gvox->quad[gvox->qcnt]; + qptr->v[0].x = x0; qptr->v[0].y = y0; qptr->v[0].z = z0; + qptr->v[1].x = x1; qptr->v[1].y = y1; qptr->v[1].z = z1; + qptr->v[2].x = x2; qptr->v[2].y = y2; qptr->v[2].z = z2; + for(j=0;j<3;j++) { qptr->v[j].u = shp[z].x+VOXBORDWIDTH; qptr->v[j].v = shp[z].y+VOXBORDWIDTH; } + if (i < 3) qptr->v[1].u += x; else qptr->v[1].v += y; + qptr->v[2].u += x; qptr->v[2].v += y; + + qptr->v[3].u = qptr->v[0].u - qptr->v[1].u + qptr->v[2].u; + qptr->v[3].v = qptr->v[0].v - qptr->v[1].v + qptr->v[2].v; + qptr->v[3].x = qptr->v[0].x - qptr->v[1].x + qptr->v[2].x; + qptr->v[3].y = qptr->v[0].y - qptr->v[1].y + qptr->v[2].y; + qptr->v[3].z = qptr->v[0].z - qptr->v[1].z + qptr->v[2].z; + if (gvox->qfacind[face] < 0) gvox->qfacind[face] = gvox->qcnt; + gvox->qcnt++; + +} + +static long isolid (long x, long y, long z) +{ + if ((unsigned long)x >= (unsigned long)xsiz) return(0); + if ((unsigned long)y >= (unsigned long)ysiz) return(0); + if ((unsigned long)z >= (unsigned long)zsiz) return(0); + z += x*yzsiz + y*zsiz; return(vbit[z>>5]&(1<qfacind[i] = -1; + + i = ((max(ysiz,zsiz)+1)<<2); + bx0 = (long *)malloc(i<<1); if (!bx0) { free(gvox); return(0); } + by0 = (long *)(((long)bx0)+i); + + for(cnt=0;cnt<2;cnt++) + { + if (!cnt) daquad = cntquad; + else daquad = addquad; + gvox->qcnt = 0; + + memset(by0,-1,(max(ysiz,zsiz)+1)<<2); v = 0; + + for(i=-1;i<=1;i+=2) + for(y=0;y= 0) && ((by0[z] != oz) || (v >= ov))) + { daquad(bx0[z],y,by0[z],x,y,by0[z],x,y,z,i>=0); by0[z] = -1; } + if (v > ov) oz = z; else if ((v < ov) && (by0[z] != oz)) { bx0[z] = x; by0[z] = oz; } + } + + for(i=-1;i<=1;i+=2) + for(z=0;z= 0) && ((by0[y] != oz) || (v >= ov))) + { daquad(bx0[y],by0[y],z,x,by0[y],z,x,y,z,(i>=0)+2); by0[y] = -1; } + if (v > ov) oz = y; else if ((v < ov) && (by0[y] != oz)) { bx0[y] = x; by0[y] = oz; } + } + + for(i=-1;i<=1;i+=2) + for(x=0;x= 0) && ((by0[z] != oz) || (v >= ov))) + { daquad(x,bx0[z],by0[z],x,y,by0[z],x,y,z,(i>=0)+4); by0[z] = -1; } + if (v > ov) oz = z; else if ((v < ov) && (by0[z] != oz)) { bx0[z] = y; by0[z] = oz; } + } + + if (!cnt) + { + shp = (spoint2d *)malloc(gvox->qcnt*sizeof(spoint2d)); + if (!shp) { free(bx0); free(gvox); return(0); } + + sc = 0; + for(y=gmaxy;y;y--) + for(x=gmaxx;x>=y;x--) + { + i = shcnt[y*shcntp+x]; shcnt[y*shcntp+x] = sc; //shcnt changes from counter to head index + for(;i>0;i--) { shp[sc].x = x; shp[sc].y = y; sc++; } + } + + for(gvox->mytexx=32;gvox->mytexx<(gmaxx+(VOXBORDWIDTH<<1));gvox->mytexx<<=1); + for(gvox->mytexy=32;gvox->mytexy<(gmaxy+(VOXBORDWIDTH<<1));gvox->mytexy<<=1); + while (gvox->mytexx*gvox->mytexy*8 < garea*9) //This should be sufficient to fit most skins... + { +skindidntfit:; + if (gvox->mytexx <= gvox->mytexy) gvox->mytexx <<= 1; else gvox->mytexy <<= 1; + } + mytexo5 = (gvox->mytexx>>5); + + i = (((gvox->mytexx*gvox->mytexy+31)>>5)<<2); + zbit = (long *)malloc(i); if (!zbit) { free(bx0); free(gvox); free(shp); return(0); } + memset(zbit,0,i); + + v = gvox->mytexx*gvox->mytexy; + for(z=0;zmytexx,255)-dx))>>15); + y0 = (((rand()&32767)*(min(gvox->mytexy,255)-dy))>>15); +#else + x0 = (((rand()&32767)*(gvox->mytexx+1-dx))>>15); + y0 = (((rand()&32767)*(gvox->mytexy+1-dy))>>15); +#endif + i--; + if (i < 0) //Time-out! Very slow if this happens... but at least it still works :P + { + free(zbit); + + //Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/ + j = 0; + for(y=gmaxy;y;y--) + for(x=gmaxx;x>=y;x--) + { + i = shcnt[y*shcntp+x]; + for(;jquad = (voxrect_t *)malloc(gvox->qcnt*sizeof(voxrect_t)); + if (!gvox->quad) { free(zbit); free(shp); free(bx0); free(gvox); return(0); } + + gvox->mytex = (long *)malloc(gvox->mytexx*gvox->mytexy*sizeof(long)); + if (!gvox->mytex) { free(gvox->quad); free(zbit); free(shp); free(bx0); free(gvox); return(0); } + } + } + free(shp); free(zbit); free(bx0); + return(gvox); +} + +static long loadvox (const char *filnam) +{ + long i, j, k, x, y, z, pal[256], fil; + unsigned char c[3], *tbuf; + + fil = kopen4load((char *)filnam,0); if (fil < 0) return(-1); + kread(fil,&xsiz,4); xsiz = B_LITTLE32(xsiz); + kread(fil,&ysiz,4); ysiz = B_LITTLE32(ysiz); + kread(fil,&zsiz,4); zsiz = B_LITTLE32(zsiz); + xpiv = ((float)xsiz)*.5; + ypiv = ((float)ysiz)*.5; + zpiv = ((float)zsiz)*.5; + + klseek(fil,-768,SEEK_END); + for(i=0;i<256;i++) + { kread(fil,c,3); pal[i] = (((long)c[0])<<18)+(((long)c[1])<<10)+(((long)c[2])<<2)+(i<<24); } + pal[255] = -1; + + vcolhashsizm1 = 8192-1; + vcolhashead = (long *)malloc((vcolhashsizm1+1)*sizeof(long)); if (!vcolhashead) { kclose(fil); return(-1); } + memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(long)); + + yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3); + vbit = (long *)malloc(i); if (!vbit) { kclose(fil); return(-1); } + memset(vbit,0,i); + + tbuf = (unsigned char *)malloc(zsiz*sizeof(char)); if (!tbuf) { kclose(fil); return(-1); } + + klseek(fil,12,SEEK_SET); + for(x=0;x=0;z--) + { if (tbuf[z] != 255) { i = j+z; vbit[i>>5] |= (1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<=0; i--) xyoffs[i] = B_LITTLE16(xyoffs[i]); + + klseek(fil,-768,SEEK_END); + for(i=0;i<256;i++) + { kread(fil,c,3); pal[i] = B_LITTLE32((((long)c[0])<<18)+(((long)c[1])<<10)+(((long)c[2])<<2)+(i<<24)); } + + yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3); + vbit = (long *)malloc(i); if (!vbit) { free(xyoffs); kclose(fil); return(-1); } + memset(vbit,0,i); + + for(vcolhashsizm1=4096;vcolhashsizm1<(mip1leng>>1);vcolhashsizm1<<=1); vcolhashsizm1--; //approx to numvoxs! + vcolhashead = (long *)malloc((vcolhashsizm1+1)*sizeof(long)); if (!vcolhashead) { free(xyoffs); kclose(fil); return(-1); } + memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(long)); + + klseek(fil,28+((xsiz+1)<<2)+((ysizp1*xsiz)<<1),SEEK_SET); + + i = kfilelength(fil)-ktell(fil); + tbuf = (unsigned char *)malloc(i); if (!tbuf) { free(xyoffs); kclose(fil); return(-1); } + kread(fil,tbuf,i); kclose(fil); + + cptr = tbuf; + for(x=0;x=0; i--) ylen[i] = B_LITTLE16(ylen[i]); + klseek(fil,32,SEEK_SET); + + yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3); + vbit = (long *)malloc(i); if (!vbit) { free(ylen); kclose(fil); return(-1); } + memset(vbit,0,i); + + for(vcolhashsizm1=4096;vcolhashsizm10;i--) + { + kread(fil,c,8); //b,g,r,a,z_lo,z_hi,vis,dir + z0 = B_LITTLE16(*(unsigned short *)&c[4]); + if (!(c[6]&16)) setzrange1(vbit,j+z1,j+z0); + vbit[(j+z0)>>5] |= (1<>3); + vbit = (long *)malloc(i); if (!vbit) { kclose(fil); return(-1); } + memset(vbit,-1,i); + + vcolhashsizm1 = 1048576-1; + vcolhashead = (long *)malloc((vcolhashsizm1+1)*sizeof(long)); if (!vcolhashead) { kclose(fil); return(-1); } + memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(long)); + + //Allocate huge buffer and load rest of file into it... + i = kfilelength(fil)-ktell(fil); + vbuf = (unsigned char *)malloc(i); if (!vbuf) { kclose(fil); return(-1); } + kread(fil,vbuf,i); + kclose(fil); + + v = vbuf; + for(y=0;ymytex) free(m->mytex); + if (m->quad) free(m->quad); + if (m->texid) free(m->texid); + free(m); +} + +static voxmodel *voxload (const char *filnam) +{ + long i, is8bit, ret; + voxmodel *vm; + + i = strlen(filnam)-4; if (i < 0) return(0); + if (!Bstrcasecmp(&filnam[i],".vox")) { ret = loadvox(filnam); is8bit = 1; } + else if (!Bstrcasecmp(&filnam[i],".kvx")) { ret = loadkvx(filnam); is8bit = 1; } + else if (!Bstrcasecmp(&filnam[i],".kv6")) { ret = loadkv6(filnam); is8bit = 0; } + //else if (!Bstrcasecmp(&filnam[i],".vxl")) { ret = loadvxl(filnam); is8bit = 0; } + else return(0); + if (ret >= 0) vm = vox2poly(); else vm = 0; + if (vm) + { + vm->mdnum = 1; //VOXel model id + vm->scale = vm->bscale = 1.0; + vm->xsiz = xsiz; vm->ysiz = ysiz; vm->zsiz = zsiz; + vm->xpiv = xpiv; vm->ypiv = ypiv; vm->zpiv = zpiv; + vm->is8bit = is8bit; + + vm->texid = (unsigned int *)calloc(MAXPALOOKUPS,sizeof(unsigned int)); + if (!vm->texid) { voxfree(vm); vm = 0; } + } + if (shcntmal) { free(shcntmal); shcntmal = 0; } + if (vbit) { free(vbit); vbit = 0; } + if (vcol) { free(vcol); vcol = 0; vnum = 0; vmax = 0; } + if (vcolhashead) { free(vcolhashead); vcolhashead = 0; } + return(vm); +} + + //Draw voxel model as perfect cubes +static int voxdraw (voxmodel *m, spritetype *tspr) +{ + point3d fp, m0, a0; + long i, j, k, fi, *lptr, xx, yy, zz; + float ru, rv, uhack[2], vhack[2], phack[2], clut[6] = {1,1,1,1,1,1}; //1.02,1.02,0.94,1.06,0.98,0.98}; + float f, g, k0, k1, k2, k3, k4, k5, k6, k7, mat[16], omat[16], pc[4]; + vert_t *vptr; + + if ((int)m == (int)0xffffffff) // hackhackhack + return 0; + if ((tspr->cstat&48)==32) return 0; + + //updateanimation((md2model *)m,tspr); + + m0.x = m->scale; + m0.y = m->scale; + m0.z = m->scale; + a0.x = a0.y = 0; a0.z = m->zadd*m->scale; + + //if (globalorientation&8) //y-flipping + //{ + // m0.z = -m0.z; a0.z = -a0.z; + // //Add height of 1st frame (use same frame to prevent animation bounce) + // a0.z += m->zsiz*m->scale; + //} + //if (globalorientation&4) { m0.y = -m0.y; a0.y = -a0.y; } //x-flipping + + f = ((float)tspr->xrepeat)*(256.0/320.0)/64.0*m->bscale; + m0.x *= f; a0.x *= f; f = -f; + m0.y *= f; a0.y *= f; + f = ((float)tspr->yrepeat)/64.0*m->bscale; + m0.z *= f; a0.z *= f; + + k0 = tspr->z; + if (globalorientation&128) k0 += (float)((tilesizy[tspr->picnum]*tspr->yrepeat)<<1); + + f = (65536.0*512.0)/((float)xdimen*viewingrange); + g = 32.0/((float)xdimen*gxyaspect); + m0.y *= f; a0.y = (((float)(tspr->x-globalposx))/ 1024.0 + a0.y)*f; + m0.x *=-f; a0.x = (((float)(tspr->y-globalposy))/ -1024.0 + a0.x)*-f; + m0.z *= g; a0.z = (((float)(k0 -globalposz))/-16384.0 + a0.z)*g; + + k0 = ((float)(tspr->x-globalposx))*f/1024.0; + k1 = ((float)(tspr->y-globalposy))*f/1024.0; + f = gcosang2*gshang; + g = gsinang2*gshang; + k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] / 16384.0; + k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] / 16384.0; + k2 = k0*(1-k4)+k1*k5; + k3 = k1*(1-k4)-k0*k5; + k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang; + mat[0] = k4*k6 + k5*k7; mat[4] = gchang*gstang; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7; + k6 = f*gctang + gsinang*gstang; k7 = g*gctang - gcosang*gstang; + mat[1] = k4*k6 + k5*k7; mat[5] = gchang*gctang; mat[ 9] = k4*k7 - k5*k6; mat[13] = k2*k6 + k3*k7; + k6 = gcosang2*gchang; k7 = gsinang2*gchang; + mat[2] = k4*k6 + k5*k7; mat[6] =-gshang; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7; + + mat[12] += a0.y*mat[0] + a0.z*mat[4] + a0.x*mat[ 8]; + mat[13] += a0.y*mat[1] + a0.z*mat[5] + a0.x*mat[ 9]; + mat[14] += a0.y*mat[2] + a0.z*mat[6] + a0.x*mat[10]; + + //Mirrors + if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } + +//------------ + //bit 10 is an ugly hack in game.c\animatesprites telling MD2SPRITE + //to use Z-buffer hacks to hide overdraw problems with the shadows + if (tspr->cstat&1024) + { + bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.9999); + } + bglPushAttrib(GL_POLYGON_BIT); + if ((grhalfxdown10x >= 0) /*^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)*/) bglFrontFace(GL_CW); else bglFrontFace(GL_CCW); + bglEnable(GL_CULL_FACE); + bglCullFace(GL_BACK); + + bglEnable(GL_TEXTURE_2D); + + pc[0] = pc[1] = pc[2] = ((float)(numpalookups-min(max(globalshade+m->shadeoff,0),numpalookups)))/((float)numpalookups); + pc[0] *= (float)hictinting[globalpal].r / 255.0; + pc[1] *= (float)hictinting[globalpal].g / 255.0; + pc[2] *= (float)hictinting[globalpal].b / 255.0; + if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; } else pc[3] = 1.0; + if (tspr->cstat&2) bglEnable(GL_BLEND); else bglDisable(GL_BLEND); +//------------ + + //transform to Build coords + memcpy(omat,mat,sizeof(omat)); + f = 1.f/64.f; + g = m0.x*f; mat[0] *= g; mat[1] *= g; mat[2] *= g; + g = m0.y*f; mat[4] = omat[8]*g; mat[5] = omat[9]*g; mat[6] = omat[10]*g; + g =-m0.z*f; mat[8] = omat[4]*g; mat[9] = omat[5]*g; mat[10] = omat[6]*g; + mat[12] -= (m->xpiv*mat[0] + m->ypiv*mat[4] + (m->zpiv+m->zsiz*.5)*mat[ 8]); + mat[13] -= (m->xpiv*mat[1] + m->ypiv*mat[5] + (m->zpiv+m->zsiz*.5)*mat[ 9]); + mat[14] -= (m->xpiv*mat[2] + m->ypiv*mat[6] + (m->zpiv+m->zsiz*.5)*mat[10]); + bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation + mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; + + bglLoadMatrixf(mat); + + ru = 1.f/((float)m->mytexx); + rv = 1.f/((float)m->mytexy); +#if (VOXBORDWIDTH == 0) + uhack[0] = ru*.125; uhack[1] = -uhack[0]; + vhack[0] = rv*.125; vhack[1] = -vhack[0]; +#endif + phack[0] = 0; phack[1] = 1.f/256.f; + + if (!m->texid[globalpal]) m->texid[globalpal] = gloadtex(m->mytex,m->mytexx,m->mytexy,m->is8bit,globalpal); + else bglBindTexture(GL_TEXTURE_2D,m->texid[globalpal]); + bglBegin(GL_QUADS); + for(i=0,fi=0;iqcnt;i++) + { + if (i == m->qfacind[fi]) { f = clut[fi++]; bglColor4f(pc[0]*f,pc[1]*f,pc[2]*f,pc[3]*f); } + vptr = &m->quad[i].v[0]; + + xx = vptr[0].x+vptr[2].x; + yy = vptr[0].y+vptr[2].y; + zz = vptr[0].z+vptr[2].z; + + for(j=0;j<4;j++) + { +#if (VOXBORDWIDTH == 0) + bglTexCoord2f(((float)vptr[j].u)*ru+uhack[vptr[j].u!=vptr[0].u], + ((float)vptr[j].v)*rv+vhack[vptr[j].v!=vptr[0].v]); +#else + bglTexCoord2f(((float)vptr[j].u)*ru,((float)vptr[j].v)*rv); +#endif + fp.x = ((float)vptr[j].x) - phack[xx>vptr[j].x*2] + phack[xxvptr[j].y*2] + phack[yyvptr[j].z*2] + phack[zzcstat&1024) + { + bglDepthFunc(GL_LEQUAL); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0,0.99999); + } + bglLoadIdentity(); + return 1; +} + +//---------------------------------------- VOX LIBRARY ENDS ---------------------------------------- +//--------------------------------------- MD LIBRARY BEGINS --------------------------------------- + +mdmodel *mdload (const char *filnam) +{ + mdmodel *vm; + int fil; + long i; + + vm = (mdmodel*)voxload(filnam); if (vm) return(vm); + + fil = kopen4load((char *)filnam,0); if (fil < 0) return(0); + kread(fil,&i,4); klseek(fil,0,SEEK_SET); + switch(B_LITTLE32(i)) + { + case 0x32504449: vm = (mdmodel*)md2load(fil,filnam); break; //IDP2 + case 0x33504449: vm = (mdmodel*)md3load(fil); break; //IDP3 + default: vm = (mdmodel*)0; break; + } + kclose(fil); + return(vm); +} + +int mddraw (spritetype *tspr) +{ + mdanim_t *anim; + mdmodel *vm; + + if (maxmodelverts > allocmodelverts) + { + point3d *vl = (point3d *)realloc(vertlist,sizeof(point3d)*maxmodelverts); + if (!vl) { OSD_Printf("ERROR: Not enough memory to allocate %d vertices!\n",maxmodelverts); return 0; } + vertlist = vl; allocmodelverts = maxmodelverts; + } + + vm = models[tile2model[tspr->picnum].modelid]; + if (vm->mdnum == 1) { return voxdraw((voxmodel *)vm,tspr); } + if (vm->mdnum == 2) { return md2draw((md2model *)vm,tspr); } + if (vm->mdnum == 3) { return md3draw((md3model *)vm,tspr); } + return 0; +} + +void mdfree (mdmodel *vm) +{ + if (vm->mdnum == 1) { voxfree((voxmodel *)vm); return; } + if (vm->mdnum == 2) { md2free((md2model *)vm); return; } + if (vm->mdnum == 3) { md3free((md3model *)vm); return; } +} + +//---------------------------------------- MD LIBRARY ENDS ---------------------------------------- diff --git a/polymer/build/src/misc/buildres.rc b/polymer/build/src/misc/buildres.rc new file mode 100644 index 000000000..0a5c4b6be --- /dev/null +++ b/polymer/build/src/misc/buildres.rc @@ -0,0 +1,31 @@ +#include + +100 ICON "rsrc/build_icon.ico" +200 BITMAP "rsrc/build.bmp" + +1000 DIALOGEX DISCARDABLE 20, 40, 265, 233 +STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +CAPTION "Startup" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", 100, "STATIC", SS_BITMAP | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 5, 5, 255, 255 + CONTROL "Starting Build Editor...", 101, "STATIC", SS_CENTER | WS_CHILD | WS_VISIBLE, 5, 79, 255, 8 + //CONTROL "", 102, "LISTBOX", LBS_HASSTRINGS | LBS_NOSEL | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_DISABLENOSCROLL, 5, 92, 255, 138 + CONTROL "", 102, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 5, 92, 255, 138 +END + +2000 DIALOGEX DISCARDABLE 20, 40, 279, 168 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | DS_CONTROL +CAPTION "Dialog" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Video mode", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 5, 3, 128, 64 + CONTROL "&Fullscreen", 100, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 45, 15, 49, 10 + CONTROL "&2D mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 30, 37, 8 + CONTROL "", 101, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 50, 28, 75, 56 + CONTROL "&3D mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 47, 37, 8 + CONTROL "", 102, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 50, 46, 75, 56 + CONTROL "&Continue", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 140, 145, 64, 17 + CONTROL "E&xit", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 208, 145, 64, 17 +END + diff --git a/polymer/build/src/misc/enumdisplay.c b/polymer/build/src/misc/enumdisplay.c new file mode 100644 index 000000000..313839b9f --- /dev/null +++ b/polymer/build/src/misc/enumdisplay.c @@ -0,0 +1,156 @@ +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define DEFAULT_OUTPUT_FILE "enumdisplay.txt" +char *outputfile = DEFAULT_OUTPUT_FILE; + +HMODULE hDDrawDLL = NULL; +LPDIRECTDRAW lpDD = NULL; +FILE *output = NULL; + +void usage(void) +{ + printf( + "enumdisplay by Jonathon Fowler (jonof@edgenetwork.org)\n" + "Options:\n" + " -h, -?, --help This message\n" + " -o Use different output file (default: " + DEFAULT_OUTPUT_FILE ", use - for stdout)\n" + ); +} + +void dumpdevmode(DEVMODE *devmode) +{ + fprintf(output, "\tdmFields has"); + if (devmode->dmFields & DM_PELSWIDTH) fprintf(output, " DM_PELSWIDTH"); + if (devmode->dmFields & DM_PELSHEIGHT) fprintf(output, " DM_PELSHEIGHT"); + if (devmode->dmFields & DM_BITSPERPEL) fprintf(output, " DM_BITSPERPEL"); + fprintf(output, "\n\tdmPelsWidth = %d\n", devmode->dmPelsWidth); + fprintf(output, "\tdmPelsHeight = %d\n", devmode->dmPelsHeight); + fprintf(output, "\tdmBitsPerPel = %d\n", devmode->dmBitsPerPel); +} + +HRESULT WINAPI ddenum(DDSURFACEDESC *ddsd, VOID *udata) +{ + fprintf(output, "\tdwFlags has"); + if (ddsd->dwFlags & DDSD_WIDTH) fprintf(output, " DDSD_WIDTH"); + if (ddsd->dwFlags & DDSD_HEIGHT) fprintf(output, " DDSD_HEIGHT"); + if (ddsd->dwFlags & DDSD_PIXELFORMAT) fprintf(output, " DDSD_PIXELFORMAT"); + fprintf(output, "\n\tdwWidth = %d\n", ddsd->dwWidth); + fprintf(output, "\tdwHeight = %d\n", ddsd->dwHeight); + fprintf(output, "\tddpfPixelFormat.dwFlags has"); + if (ddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1) fprintf(output, " DDPF_PALETTEINDEXED1"); + if (ddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2) fprintf(output, " DDPF_PALETTEINDEXED2"); + if (ddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) fprintf(output, " DDPF_PALETTEINDEXED4"); + if (ddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) fprintf(output, " DDPF_PALETTEINDEXED8"); + if (ddsd->ddpfPixelFormat.dwFlags & DDPF_RGB) fprintf(output, " DDPF_RGB"); + fprintf(output, "\n\tddpfPixelFormat.dwRGBBitCount = %d\n", ddsd->ddpfPixelFormat.dwRGBBitCount); + fprintf(output, "\n"); + + return(DDENUMRET_OK); +} + +int InitDirectDraw(void) +{ + HRESULT result; + HRESULT (WINAPI *aDirectDrawCreate)(GUID *, LPDIRECTDRAW *, IUnknown *); + HRESULT (WINAPI *aDirectDrawEnumerate)(LPDDENUMCALLBACK, LPVOID); + DDCAPS ddcaps; + + hDDrawDLL = LoadLibrary("DDRAW.DLL"); + if (!hDDrawDLL) { fprintf(output, "Failed loading DDRAW.DLL\n"); return -1; } + + aDirectDrawEnumerate = (void *)GetProcAddress(hDDrawDLL, "DirectDrawEnumerateA"); + if (!aDirectDrawEnumerate) { fprintf(output, "Error fetching DirectDrawEnumerate\n"); return -1; } + + aDirectDrawCreate = (void *)GetProcAddress(hDDrawDLL, "DirectDrawCreate"); + if (!aDirectDrawCreate) { fprintf(output, "Error fetching DirectDrawCreate\n"); return -1; } + + result = aDirectDrawCreate(NULL, &lpDD, NULL); + if (result != DD_OK) { fprintf(output, "DirectDrawCreate() failed (%d)\n", result); return -1; } + + return 0; +} + +void UninitDirectDraw(void) +{ + if (lpDD) IDirectDraw_Release(lpDD); + lpDD = NULL; + if (hDDrawDLL) FreeLibrary(hDDrawDLL); + hDDrawDLL = NULL; +} + +int main(int argc, char **argv) +{ + int i; + + DEVMODE devmode; + HRESULT hresult; + + for (i=1; i + +100 ICON "rsrc/game_icon.ico" +200 BITMAP "rsrc/game.bmp" + +1000 DIALOGEX DISCARDABLE 20, 40, 265, 233 +STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +CAPTION "Startup" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", 100, "STATIC", SS_BITMAP | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 5, 5, 255, 255 + CONTROL "Starting KenBuild...", 101, "STATIC", SS_CENTER | WS_CHILD | WS_VISIBLE, 5, 79, 255, 8 + //CONTROL "", 102, "LISTBOX", LBS_HASSTRINGS | LBS_NOSEL | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_DISABLENOSCROLL, 5, 92, 255, 138 + CONTROL "", 102, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 5, 92, 255, 138 +END + +2000 DIALOGEX DISCARDABLE 20, 40, 279, 168 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | DS_CONTROL +CAPTION "Dialog" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Video mode", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 5, 3, 128, 46 + CONTROL "&Fullscreen", 100, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 45, 15, 49, 10 + CONTROL "&Mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 30, 37, 8 + CONTROL "", 101, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 50, 28, 75, 56 + CONTROL "&Continue", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 140, 145, 64, 17 + CONTROL "E&xit", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 208, 145, 64, 17 +END + diff --git a/polymer/build/src/misc/getdxdidf.c b/polymer/build/src/misc/getdxdidf.c new file mode 100644 index 000000000..f0c7675c6 --- /dev/null +++ b/polymer/build/src/misc/getdxdidf.c @@ -0,0 +1,129 @@ +// compile with: +// gcc -o getdxdidf.exe src\getdxdidf.c -Ic:\mingw32\dx6\include -Lc:\mingw32\dx6\lib -ldxguid -ldinput -mwindows + +#define WIN32_LEAN_AND_MEAN +#define INITGUID +#include +#include +#include + + +char *WhatGUID(const GUID *guid) +{ + if (guid == &GUID_XAxis) return "&GUID_XAxis"; + if (guid == &GUID_YAxis) return "&GUID_YAxis"; + if (guid == &GUID_ZAxis) return "&GUID_ZAxis"; + if (guid == &GUID_RxAxis) return "&GUID_RxAxis"; + if (guid == &GUID_RyAxis) return "&GUID_RyAxis"; + if (guid == &GUID_RzAxis) return "&GUID_RzAxis"; + if (guid == &GUID_Slider) return "&GUID_Slider"; + + if (guid == &GUID_Button) return "&GUID_Button"; + if (guid == &GUID_Key) return "&GUID_Key"; + + if (guid == &GUID_POV) return "&GUID_POV"; + + if (guid == &GUID_Unknown) return "&GUID_Unknown"; + + return "NULL"; +} + + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + FILE *fp; + DWORD i; + + fp = fopen("didf.txt", "w"); + if (!fp) return -1; + setvbuf(fp, NULL, _IONBF, 0); + + + fprintf(fp, + "// Keyboard\n" + "\n" + "static DIOBJECTDATAFORMAT c_dfDIKeyboard_odf[] = {\n" + ); + + for (i=0; i +#include "SDL/SDL.h" + +int keytranslation[SDLK_LAST]; +char *keysyms[SDLK_LAST]; + +static int buildkeytranslationtable(void) +{ + memset(keytranslation,0,sizeof(keytranslation)); + memset(keysyms,0,sizeof(keysyms)); + +#define MAP(x,y) { \ + keytranslation[x] = y; \ + keysyms[x] = #x ; \ +} + MAP(SDLK_BACKSPACE, 0xe); + MAP(SDLK_TAB, 0xf); + MAP(SDLK_RETURN, 0x1c); + MAP(SDLK_PAUSE, 0x59); // 0x1d + 0x45 + 0x9d + 0xc5 + MAP(SDLK_ESCAPE, 0x1); + MAP(SDLK_SPACE, 0x39); + MAP(SDLK_EXCLAIM, 0x2); // '1' + MAP(SDLK_QUOTEDBL, 0x28); // ''' + MAP(SDLK_HASH, 0x4); // '3' + MAP(SDLK_DOLLAR, 0x5); // '4' + MAP(37, 0x6); // '5' <-- where's the keysym SDL guys? + MAP(SDLK_AMPERSAND, 0x8); // '7' + MAP(SDLK_QUOTE, 0x28); // ''' + MAP(SDLK_LEFTPAREN, 0xa); // '9' + MAP(SDLK_RIGHTPAREN, 0xb); // '0' + MAP(SDLK_ASTERISK, 0x9); // '8' + MAP(SDLK_PLUS, 0xd); // '=' + MAP(SDLK_COMMA, 0x33); + MAP(SDLK_MINUS, 0xc); + MAP(SDLK_PERIOD, 0x34); + MAP(SDLK_SLASH, 0x35); + MAP(SDLK_0, 0xb); + MAP(SDLK_1, 0x2); + MAP(SDLK_2, 0x3); + MAP(SDLK_3, 0x4); + MAP(SDLK_4, 0x5); + MAP(SDLK_5, 0x6); + MAP(SDLK_6, 0x7); + MAP(SDLK_7, 0x8); + MAP(SDLK_8, 0x9); + MAP(SDLK_9, 0xa); + MAP(SDLK_COLON, 0x27); + MAP(SDLK_SEMICOLON, 0x27); + MAP(SDLK_LESS, 0x33); + MAP(SDLK_EQUALS, 0xd); + MAP(SDLK_GREATER, 0x34); + MAP(SDLK_QUESTION, 0x35); + MAP(SDLK_AT, 0x3); // '2' + MAP(SDLK_LEFTBRACKET, 0x1a); + MAP(SDLK_BACKSLASH, 0x2b); + MAP(SDLK_RIGHTBRACKET, 0x1b); + MAP(SDLK_CARET, 0x7); // '7' + MAP(SDLK_UNDERSCORE, 0xc); + MAP(SDLK_BACKQUOTE, 0x29); + MAP(SDLK_a, 0x1e); + MAP(SDLK_b, 0x30); + MAP(SDLK_c, 0x2e); + MAP(SDLK_d, 0x20); + MAP(SDLK_e, 0x12); + MAP(SDLK_f, 0x21); + MAP(SDLK_g, 0x22); + MAP(SDLK_h, 0x23); + MAP(SDLK_i, 0x17); + MAP(SDLK_j, 0x24); + MAP(SDLK_k, 0x25); + MAP(SDLK_l, 0x26); + MAP(SDLK_m, 0x32); + MAP(SDLK_n, 0x31); + MAP(SDLK_o, 0x18); + MAP(SDLK_p, 0x19); + MAP(SDLK_q, 0x10); + MAP(SDLK_r, 0x13); + MAP(SDLK_s, 0x1f); + MAP(SDLK_t, 0x14); + MAP(SDLK_u, 0x16); + MAP(SDLK_v, 0x2f); + MAP(SDLK_w, 0x11); + MAP(SDLK_x, 0x2d); + MAP(SDLK_y, 0x15); + MAP(SDLK_z, 0x2c); + MAP(SDLK_DELETE, 0xd3); + MAP(SDLK_KP0, 0x52); + MAP(SDLK_KP1, 0x4f); + MAP(SDLK_KP2, 0x50); + MAP(SDLK_KP3, 0x51); + MAP(SDLK_KP4, 0x4b); + MAP(SDLK_KP5, 0x4c); + MAP(SDLK_KP6, 0x4d); + MAP(SDLK_KP7, 0x47); + MAP(SDLK_KP8, 0x48); + MAP(SDLK_KP9, 0x49); + MAP(SDLK_KP_PERIOD, 0x53); + MAP(SDLK_KP_DIVIDE, 0xb5); + MAP(SDLK_KP_MULTIPLY, 0x37); + MAP(SDLK_KP_MINUS, 0x4a); + MAP(SDLK_KP_PLUS, 0x4e); + MAP(SDLK_KP_ENTER, 0x9c); + //MAP(SDLK_KP_EQUALS, ); + MAP(SDLK_UP, 0xc8); + MAP(SDLK_DOWN, 0xd0); + MAP(SDLK_RIGHT, 0xcd); + MAP(SDLK_LEFT, 0xcb); + MAP(SDLK_INSERT, 0xd2); + MAP(SDLK_HOME, 0xc7); + MAP(SDLK_END, 0xcf); + MAP(SDLK_PAGEUP, 0xc9); + MAP(SDLK_PAGEDOWN, 0xd1); + MAP(SDLK_F1, 0x3b); + MAP(SDLK_F2, 0x3c); + MAP(SDLK_F3, 0x3d); + MAP(SDLK_F4, 0x3e); + MAP(SDLK_F5, 0x3f); + MAP(SDLK_F6, 0x40); + MAP(SDLK_F7, 0x41); + MAP(SDLK_F8, 0x42); + MAP(SDLK_F9, 0x43); + MAP(SDLK_F10, 0x44); + MAP(SDLK_F11, 0x57); + MAP(SDLK_F12, 0x58); + MAP(SDLK_NUMLOCK, 0x45); + MAP(SDLK_CAPSLOCK, 0x3a); + MAP(SDLK_SCROLLOCK, 0x46); + MAP(SDLK_RSHIFT, 0x36); + MAP(SDLK_LSHIFT, 0x2a); + MAP(SDLK_RCTRL, 0x9d); + MAP(SDLK_LCTRL, 0x1d); + MAP(SDLK_RALT, 0xb8); + MAP(SDLK_LALT, 0x38); + MAP(SDLK_LSUPER, 0xdb); // win l + MAP(SDLK_RSUPER, 0xdc); // win r + MAP(SDLK_PRINT, -2); // 0xaa + 0xb7 + MAP(SDLK_SYSREQ, 0x54); // alt+printscr + MAP(SDLK_BREAK, 0xb7); // ctrl+pause + MAP(SDLK_MENU, 0xdd); // win menu? +#undef MAP + + return 0; +} + +#undef main + +int main(int argc, char **argv) +{ + int i; + + buildkeytranslationtable(); + + for (i=0;i0) printf(", "); + if (i%8 == 7) printf("\n"); + printf("%d",keytranslation[i]); + } + + return 0; +} + diff --git a/polymer/build/src/mmulti.c b/polymer/build/src/mmulti.c new file mode 100644 index 000000000..88e0b63bc --- /dev/null +++ b/polymer/build/src/mmulti.c @@ -0,0 +1,641 @@ +#include +#include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#include +#ifndef __BEOS__ +#include +#endif +#ifdef __sun +#include +#endif +#include +#include +#include +#define SOCKET int +#define INVALID_HANDLE_VALUE (-1) +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) +#define closesocket close +#define ioctlsocket ioctl +#define LPHOSTENT struct hostent * + +#include +static long GetTickCount(void) +{ + struct timeval tv; + long ti; + if (gettimeofday(&tv,NULL) < 0) return 0; + // tv is sec.usec, GTC gives msec + ti = tv.tv_sec * 1000; + ti += tv.tv_usec / 1000; + return ti; +} +#endif + +#ifdef KSFORBUILD +# include "baselayer.h" +# define printf initprintf +#endif + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#define MAXPLAYERS 16 +#define MAXPAKSIZ 256 //576 + + +#define PAKRATE 40 //Packet rate/sec limit ... necessary? +#define SIMMIS 0 //Release:0 Test:100 Packets per 256 missed. +#define SIMLAG 0 //Release:0 Test: 10 Packets to delay receipt +static long simlagcnt[MAXPLAYERS]; +static char simlagfif[MAXPLAYERS][SIMLAG+1][MAXPAKSIZ+2]; +#if ((SIMMIS != 0) || (SIMLAG != 0)) +#pragma message("\n\nWARNING! INTENTIONAL PACKET LOSS SIMULATION IS ENABLED!\nREMEMBER TO CHANGE SIMMIS&SIMLAG to 0 before RELEASE!\n\n") +#endif + +long myconnectindex, numplayers; +long connecthead, connectpoint2[MAXPLAYERS]; + +static long tims, lastsendtims[MAXPLAYERS]; +static char pakbuf[MAXPAKSIZ]; + +#define FIFSIZ 512 //16384/40 = 6min:49sec +static long ipak[MAXPLAYERS][FIFSIZ], icnt0[MAXPLAYERS]; +static long opak[MAXPLAYERS][FIFSIZ], ocnt0[MAXPLAYERS], ocnt1[MAXPLAYERS]; +static char pakmem[4194304]; static long pakmemi = 1; + +#define NETPORT 0x5bd9 +static SOCKET mysock; +static long myip, myport = NETPORT, otherip[MAXPLAYERS], otherport[MAXPLAYERS]; +static long snatchip = 0, snatchport = 0, danetmode = 255, netready = 0; + +void netuninit () +{ + if (mysock != (SOCKET)INVALID_HANDLE_VALUE) closesocket(mysock); +#ifdef _WIN32 + WSACleanup(); +#endif +} + +long netinit (long portnum) +{ + LPHOSTENT lpHostEnt; + char hostnam[256]; + struct sockaddr_in ip; + long i; + +#ifdef _WIN32 + WSADATA ws; + + if (WSAStartup(0x101,&ws) == SOCKET_ERROR) return(0); +#endif + + mysock = socket(AF_INET,SOCK_DGRAM,0); if (mysock == INVALID_SOCKET) return(0); +#ifdef __BEOS__ + i = 1; if (setsockopt(mysock,SOL_SOCKET,SO_NONBLOCK,&i,sizeof(i)) < 0) return(0); +#else + i = 1; if (ioctlsocket(mysock,FIONBIO,(unsigned long *)&i) == SOCKET_ERROR) return(0); +#endif + + ip.sin_family = AF_INET; + ip.sin_addr.s_addr = INADDR_ANY; + ip.sin_port = htons(portnum); + if (bind(mysock,(struct sockaddr *)&ip,sizeof(ip)) != SOCKET_ERROR) + { + myport = portnum; + if (gethostname(hostnam,sizeof(hostnam)) != SOCKET_ERROR) + if ((lpHostEnt = gethostbyname(hostnam))) + { + myip = ip.sin_addr.s_addr = *(long *)lpHostEnt->h_addr; + printf("mmulti: This machine's IP is %s\n", inet_ntoa(ip.sin_addr)); + } + return(1); + } + return(0); +} + +long netsend (long other, char *dabuf, long bufsiz) //0:buffer full... can't send +{ + struct sockaddr_in ip; + + if (!otherip[other]) return(0); + ip.sin_family = AF_INET; + ip.sin_addr.s_addr = otherip[other]; + ip.sin_port = otherport[other]; + return(sendto(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,sizeof(struct sockaddr_in)) != SOCKET_ERROR); +} + +long netread (long *other, char *dabuf, long bufsiz) //0:no packets in buffer +{ + struct sockaddr_in ip; + long i; + + i = sizeof(ip); + if (recvfrom(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,(int *)&i) == -1) return(0); +#if (SIMMIS > 0) + if ((rand()&255) < SIMMIS) return(0); +#endif + + snatchip = (long)ip.sin_addr.s_addr; snatchport = (long)ip.sin_port; + + (*other) = myconnectindex; + for(i=0;i 1) + i = simlagcnt[*other]%(SIMLAG+1); + *(short *)&simlagfif[*other][i][0] = bufsiz; memcpy(&simlagfif[*other][i][2],dabuf,bufsiz); + simlagcnt[*other]++; if (simlagcnt[*other] < SIMLAG+1) return(0); + i = simlagcnt[*other]%(SIMLAG+1); + bufsiz = *(short *)&simlagfif[*other][i][0]; memcpy(dabuf,&simlagfif[*other][i][2],bufsiz); +#endif + + return(1); +} + +long isvalidipaddress (char *st) +{ + long i, bcnt, num; + + bcnt = 0; num = 0; + for(i=0;st[i];i++) + { + if (st[i] == '.') { bcnt++; num = 0; continue; } + if (st[i] == ':') + { + if (bcnt != 3) return(0); + num = 0; + for(i++;st[i];i++) + { + if ((st[i] >= '0') && (st[i] <= '9')) + { num = num*10+st[i]-'0'; if (num >= 65536) return(0); } + else return(0); + } + return(1); + } + if ((st[i] >= '0') && (st[i] <= '9')) + { num = num*10+st[i]-'0'; if (num >= 256) return(0); } + + } + return(bcnt == 3); +} + +//---------------------------------- Obsolete variables&functions ---------------------------------- +char syncstate = 0; +void setpackettimeout (long datimeoutcount, long daresendagaincount) {} +void genericmultifunction (long other, char *bufptr, long messleng, long command) {} +long getoutputcirclesize () { return(0); } +void setsocket (long newsocket) { } +void flushpackets () {} +void sendlogon () {} +void sendlogoff () {} +//-------------------------------------------------------------------------------------------------- + +static long crctab16[256]; +static void initcrc16 () +{ + long i, j, k, a; + for(j=0;j<256;j++) + { + for(i=7,k=(j<<8),a=0;i>=0;i--,k=((k<<1)&65535)) + { + if ((k^a)&0x8000) a = ((a<<1)&65535)^0x1021; + else a = ((a<<1)&65535); + } + crctab16[j] = (a&65535); + } +} +#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctab16[((((unsigned short)crc)>>8)&65535)^dat]) +static unsigned short getcrc16 (char *buffer, long bufleng) +{ + long i, j; + + j = 0; + for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]); + return((unsigned short)(j&65535)); +} + +void uninitmultiplayers () { netuninit(); } + +long getpacket(long *, char *); +static void initmultiplayers_reset(void) +{ + long i; + + initcrc16(); + memset(icnt0,0,sizeof(icnt0)); + memset(ocnt0,0,sizeof(ocnt0)); + memset(ocnt1,0,sizeof(ocnt1)); + memset(ipak,0,sizeof(ipak)); + //memset(opak,0,sizeof(opak)); //Don't need to init opak + //memset(pakmem,0,sizeof(pakmem)); //Don't need to init pakmem +#if (SIMLAG > 1) + memset(simlagcnt,0,sizeof(simlagcnt)); +#endif + + lastsendtims[0] = GetTickCount(); + for(i=1;i 0 && j<65535) portnum = j; + + printf("mmulti: Using port %ld\n", portnum); + } + } + + netinit(portnum); + + for(i=0;i= '0') && (argv[i][4] <= '9')) + { + numplayers = (argv[i][4]-'0'); + if ((argv[i][5] >= '0') && (argv[i][5] <= '9')) numplayers = numplayers*10+(argv[i][5]-'0'); + printf("mmulti: %ld-player game\n", numplayers); + } + printf("mmulti: Master-slave mode\n"); + } + else if (argv[i][2] == '1') + { + danetmode = 1; + myconnectindex = daindex; daindex++; + printf("mmulti: Peer-to-peer mode\n"); + } + continue; + } + else if ((argv[i][1] == 'P') || (argv[i][1] == 'p')) continue; + } + + st = strdup(argv[i]); if (!st) break; + if (isvalidipaddress(st)) + { + if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; + for(j=0;st[j];j++) { + if (st[j] == ':') + { otherport[daindex] = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } + } + otherip[daindex] = inet_addr(st); + printf("mmulti: Player %ld at %s:%d\n",daindex,st,ntohs(otherport[daindex])); + daindex++; + } + else + { + LPHOSTENT lph; + unsigned short pt = htons(NETPORT); + + for(j=0;st[j];j++) + if (st[j] == ':') + { pt = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } + if ((lph = gethostbyname(st))) + { + if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; + otherip[daindex] = *(long *)lph->h_addr; + otherport[daindex] = pt; + printf("mmulti: Player %ld at %s:%d (%s)\n",daindex, + inet_ntoa(*(struct in_addr *)lph->h_addr),ntohs(pt),argv[i]); + daindex++; + } else printf("mmulti: Failed resolving %s\n",argv[i]); + } + free(st); + } + if ((danetmode == 255) && (daindex)) { numplayers = 2; danetmode = 0; } //an IP w/o /n# defaults to /n0 + if ((numplayers >= 2) && (daindex) && (!danetmode)) myconnectindex = 1; + if (daindex > numplayers) numplayers = daindex; + + //for(i=0;i>8)&255,(otherip[i]>>16)&255,((unsigned long)otherip[i])>>24,ntohs(otherport[i])); + + connecthead = 0; + for(i=0;i= 2)) || (numplayers == 2)); +} + +long initmultiplayerscycle(void) +{ + long i, k; + + getpacket(&i,0); + + tims = GetTickCount(); + if (myconnectindex == connecthead) + { + for(i=numplayers-1;i>0;i--) + if (!otherip[i]) break; + if (!i) { + netready = 1; + return 0; + } + } + else + { + if (netready) return 0; + if (tims < lastsendtims[connecthead]) lastsendtims[connecthead] = tims; + if (tims >= lastsendtims[connecthead]+250) //1000/PAKRATE) + { + lastsendtims[connecthead] = tims; + + // short crc16ofs; //offset of crc16 + // long icnt0; //-1 (special packet for MMULTI.C's player collection) + // ... + // unsigned short crc16; //CRC16 of everything except crc16 + k = 2; + *(long *)&pakbuf[k] = -1; k += 4; + pakbuf[k++] = 0xaa; + *(unsigned short *)&pakbuf[0] = (unsigned short)k; + *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; + netsend(connecthead,pakbuf,k); + } + } + + return 1; +} + +void initmultiplayers (long argc, char **argv, char damultioption, char dacomrateoption, char dapriority) +{ + long i, j, k, otims; + + if (initmultiplayersparms(argc,argv)) + { +#if 0 + //Console code seems to crash Win98 upon quitting game + //it's not necessary and it's not portable anyway + char tbuf[1024]; + unsigned long u; + HANDLE hconsout; + AllocConsole(); + SetConsoleTitle("Multiplayer status..."); + hconsout = GetStdHandle(STD_OUTPUT_HANDLE); + otims = 0; +#endif + while (initmultiplayerscycle()) + { +#if 0 + if ((tims < otims) || (tims > otims+100)) + { + otims = tims; + sprintf(tbuf,"\rWait for players (%d/%d): ",myconnectindex,numplayers); + for(i=0;i "); continue; } + if (!otherip[i]) { strcat(tbuf,"?.?.?.?:? "); continue; } + sprintf(&tbuf[strlen(tbuf)],"%d.%d.%d.%d:%04x ",otherip[i]&255,(otherip[i]>>8)&255,(otherip[i]>>16)&255,(((unsigned long)otherip[i])>>24),otherport[i]); + } + WriteConsole(hconsout,tbuf,strlen(tbuf),&u,0); + } + } + FreeConsole(); +#else + } +#endif + } + netready = 1; +} + +void dosendpackets (long other) +{ + long i, j, k; + + if (!otherip[other]) return; + + //Packet format: + // short crc16ofs; //offset of crc16 + // long icnt0; //earliest unacked packet + // char ibits[32]; //ack status of packets icnt0<=i>3)+k] |= (1<<((i-icnt0[other])&7)); + k += 32; + + while ((ocnt0[other] < ocnt1[other]) && (!opak[other][ocnt0[other]&(FIFSIZ-1)])) ocnt0[other]++; + for(i=ocnt0[other];i (long)sizeof(pakbuf)) break; + + *(unsigned short *)&pakbuf[k] = (unsigned short)j; k += 2; + *(long *)&pakbuf[k] = i; k += 4; + memcpy(&pakbuf[k],&pakmem[opak[other][i&(FIFSIZ-1)]+2],j); k += j; + } + *(unsigned short *)&pakbuf[k] = 0; k += 2; + *(unsigned short *)&pakbuf[0] = (unsigned short)k; + *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; + + //printf("Send: "); for(i=0;i (long)sizeof(pakmem)) pakmemi = 1; + opak[other][ocnt1[other]&(FIFSIZ-1)] = pakmemi; + *(short *)&pakmem[pakmemi] = messleng; + memcpy(&pakmem[pakmemi+2],bufptr,messleng); pakmemi += messleng+2; + ocnt1[other]++; + + //printf("Send: "); for(i=0;i=0;i=connectpoint2[i]) + { + if (i != myconnectindex) dosendpackets(i); + if ((!danetmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + } + + while (netread(&other,pakbuf,sizeof(pakbuf))) + { + //Packet format: + // short crc16ofs; //offset of crc16 + // long icnt0; //earliest unacked packet + // char ibits[32]; //ack status of packets icnt0<=i>3)+k]&(1<<((i-ic0)&7))) + opak[other][i&(FIFSIZ-1)] = 0; + k += 32; + + messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; + while (messleng) + { + j = *(long *)&pakbuf[k]; k += 4; + if ((j >= icnt0[other]) && (!ipak[other][j&(FIFSIZ-1)])) + { + if (pakmemi+messleng+2 > (long)sizeof(pakmem)) pakmemi = 1; + ipak[other][j&(FIFSIZ-1)] = pakmemi; + *(short *)&pakmem[pakmemi] = messleng; + memcpy(&pakmem[pakmemi+2],&pakbuf[k],messleng); pakmemi += messleng+2; + } + k += messleng; + messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; + } + } + } + } + + //Return next valid packet from any player + if (!bufptr) return(0); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) + { + j = ipak[i][icnt0[i]&(FIFSIZ-1)]; + if (j) + { + messleng = *(short *)&pakmem[j]; memcpy(bufptr,&pakmem[j+2],messleng); + *retother = i; ipak[i][icnt0[i]&(FIFSIZ-1)] = 0; icnt0[i]++; + //printf("Recv: "); for(i=0;i k) { k = j; white = i; } + } + } + + printext256(4+(x<<3),4+(y<<3), white, -1, st, 0); +} + +static void _internal_drawosdstr(int x, int y, char *ch, int len, int shade, int pal) +{ + int i,j,k; + char st[1024]; + + if (len>1023) len=1023; + memcpy(st,ch,len); + st[len]=0; + + if (white<0) { + // find the palette index closest to white + k=0; + for(i=0;i<256;i++) + { + j = ((int)curpalette[i].r)+((int)curpalette[i].g)+((int)curpalette[i].b); + if (j > k) { k = j; white = i; } + } + } + + printext256(4+(x<<3),4+(y<<3), white, -1, st, 0); +} + +static void _internal_drawosdcursor(int x, int y, int type, int lastkeypress) +{ + int i,j,k; + char st[2] = { '_',0 }; + + if (type) st[0] = '#'; + + if (white<0) { + // find the palette index closest to white + k=0; + for(i=0;i<256;i++) + { + j = ((int)palette[i*3])+((int)palette[i*3+1])+((int)palette[i*3+2]); + if (j > k) { k = j; white = i; } + } + } + + printext256(4+(x<<3),4+(y<<3)+2, white, -1, st, 0); +} + +static int _internal_getcolumnwidth(int w) +{ + return w/8 - 1; +} + +static int _internal_getrowheight(int w) +{ + return w/8; +} + +static void _internal_clearbackground(int cols, int rows) +{ +} + +static int _internal_gettime(void) +{ + return 0; +} + +static void _internal_onshowosd(int a) +{ +} + +//////////////////////////// + +static int _internal_osdfunc_vars(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms < 1); + + if (!Bstrcasecmp(parm->name, "osdrows")) { + if (showval) { OSD_Printf("osdrows is %d\n", osdrows); return OSDCMD_OK; } + else { + osdrows = atoi(parm->parms[0]); + if (osdrows < 1) osdrows = 1; + else if (osdrows > osdmaxrows) osdrows = osdmaxrows; + return OSDCMD_OK; + } + } + return OSDCMD_SHOWHELP; +} + +static int _internal_osdfunc_listsymbols(const osdfuncparm_t *parm) +{ + symbol_t *i; + + OSD_Printf("Symbol listing:\n"); + for (i=symbols; i!=NULL; i=i->next) + OSD_Printf(" %s\n", i->name); + + return OSDCMD_OK; +} + +static int _internal_osdfunc_help(const osdfuncparm_t *parm) +{ + symbol_t *symb; + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + symb = findexactsymbol(parm->parms[0]); + if (!symb) { + OSD_Printf("Help Error: \"%s\" is not a defined variable or function\n", parm->parms[0]); + } else { + OSD_Printf("%s\n", symb->help); + } + + return OSDCMD_OK; +} + + + +//////////////////////////// + + +// +// OSD_Cleanup() -- Cleans up the on-screen display +// +void OSD_Cleanup(void) +{ + symbol_t *s; + + for (; symbols; symbols=s) { + s=symbols->next; + Bfree(symbols); + } + + osdinited=0; +} + + +// +// OSD_Init() -- Initialises the on-screen display +// +void OSD_Init(void) +{ + Bmemset(osdtext, 32, TEXTSIZE); + osdlines=1; + + osdinited=1; + + OSD_RegisterFunction("listsymbols","listsymbols: lists all the recognized symbols",_internal_osdfunc_listsymbols); + OSD_RegisterFunction("help","help: displays help on the named symbol",_internal_osdfunc_help); + OSD_RegisterFunction("osdrows","osdrows: sets the number of visible lines of the OSD",_internal_osdfunc_vars); + + atexit(OSD_Cleanup); +} + + +// +// OSD_SetLogFile() -- Sets the text file where printed text should be echoed +// +void OSD_SetLogFile(char *fn) +{ + if (osdlog) Bfclose(osdlog); + osdlog = NULL; + if (fn) osdlog = Bfopen(fn,"w"); + if (osdlog) setvbuf(osdlog, (char*)NULL, _IONBF, 0); +} + + +// +// OSD_SetFunctions() -- Sets some callbacks which the OSD uses to understand its world +// +void OSD_SetFunctions( + void (*drawchar)(int,int,char,int,int), + void (*drawstr)(int,int,char*,int,int,int), + void (*drawcursor)(int,int,int,int), + int (*colwidth)(int), + int (*rowheight)(int), + void (*clearbg)(int,int), + int (*gtime)(void), + void (*showosd)(int) + ) +{ + drawosdchar = drawchar; + drawosdstr = drawstr; + drawosdcursor = drawcursor; + getcolumnwidth = colwidth; + getrowheight = rowheight; + clearbackground = clearbg; + gettime = gtime; + onshowosd = showosd; + + if (!drawosdchar) drawosdchar = _internal_drawosdchar; + if (!drawosdstr) drawosdstr = _internal_drawosdstr; + if (!drawosdcursor) drawosdcursor = _internal_drawosdcursor; + if (!getcolumnwidth) getcolumnwidth = _internal_getcolumnwidth; + if (!getrowheight) getrowheight = _internal_getrowheight; + if (!clearbackground) clearbackground = _internal_clearbackground; + if (!gettime) gettime = _internal_gettime; + if (!onshowosd) onshowosd = _internal_onshowosd; +} + + +// +// OSD_SetParameters() -- Sets the parameters for presenting the text +// +void OSD_SetParameters( + int promptshade, int promptpal, + int editshade, int editpal, + int textshade, int textpal + ) +{ + osdpromptshade = promptshade; + osdpromptpal = promptpal; + osdeditshade = editshade; + osdeditpal = editpal; + osdtextshade = textshade; + osdtextpal = textpal; +} + + +// +// OSD_CaptureKey() -- Sets the scancode for the key which activates the onscreen display +// +void OSD_CaptureKey(int sc) +{ + osdkey = sc; +} + + +// +// OSD_HandleKey() -- Handles keyboard input when capturing input. +// Returns 0 if the key was handled internally, or the scancode if it should +// be passed on to the game. +// +int OSD_HandleKey(int sc, int press) +{ + char ch; + int i,j; + symbol_t *tabc = NULL; + static symbol_t *lastmatch = NULL; + + if (!osdinited) return sc; + + if (sc == osdkey) { + if (press) { + OSD_ShowDisplay(osdvisible ^ 1); + bflushchars(); + } + return 0;//sc; + } else if (!osdvisible) { + return sc; + } + + if (!press) { + if (sc == 42 || sc == 54) // shift + osdeditshift = 0; + if (sc == 29 || sc == 157) // control + osdeditcontrol = 0; + return 0;//sc; + } + + keytime = gettime(); + + if (sc != 15) lastmatch = NULL; // tab + + while ( (ch = bgetchar()) ) { + if (ch == 1) { // control a. jump to beginning of line + } else if (ch == 2) { // control b, move one character left + } else if (ch == 5) { // control e, jump to end of line + } else if (ch == 6) { // control f, move one character right + } else if (ch == 8 || ch == 127) { // control h, backspace + if (!osdeditcursor || !osdeditlen) return 0; + if (!osdovertype) { + if (osdeditcursor < osdeditlen) + Bmemmove(osdeditbuf+osdeditcursor-1, osdeditbuf+osdeditcursor, osdeditlen-osdeditcursor); + osdeditlen--; + } + osdeditcursor--; + if (osdeditcursor0;i--) if (osdeditbuf[i-1] == ' ') break; + for (j=0;osdeditbuf[i] != ' ' && i < osdeditlen;j++,i++) + osdedittmp[j] = osdeditbuf[i]; + osdedittmp[j] = 0; + + if (j > 0) + tabc = findsymbol(osdedittmp, NULL); + } else { + tabc = findsymbol(osdedittmp, lastmatch->next); + if (!tabc && lastmatch) + tabc = findsymbol(osdedittmp, NULL); // wrap + } + + if (tabc) { + for (i=osdeditcursor;i>0;i--) if (osdeditbuf[i-1] == ' ') break; + osdeditlen = i; + for (j=0;tabc->name[j] && osdeditlen <= EDITLENGTH;i++,j++,osdeditlen++) + osdeditbuf[i] = tabc->name[j]; + osdeditcursor = osdeditlen; + osdeditwinend = osdeditcursor; + osdeditwinstart = osdeditwinend-editlinewidth; + if (osdeditwinstart<0) { + osdeditwinstart=0; + osdeditwinend = editlinewidth; + } + + lastmatch = tabc; + } + } else if (ch == 11) { // control k, delete all to end of line + } else if (ch == 12) { // control l, clear screen + } else if (ch == 13) { // control m, enter + if (osdeditlen>0) { + osdeditbuf[osdeditlen] = 0; + Bmemmove(osdhistorybuf[1], osdhistorybuf[0], HISTORYDEPTH*(EDITLENGTH+1)); + Bmemmove(osdhistorybuf[0], osdeditbuf, EDITLENGTH+1); + if (osdhistorysize < HISTORYDEPTH) osdhistorysize++; + if (osdexeccount == HISTORYDEPTH) + OSD_Printf("Command Buffer Warning: Failed queueing command " + "for execution. Buffer full.\n"); + else + osdexeccount++; + osdhistorypos=-1; + } + + osdeditlen=0; + osdeditcursor=0; + osdeditwinstart=0; + osdeditwinend=editlinewidth; + } else if (ch == 16) { // control p, previous (ie. up arrow) + } else if (ch == 20) { // control t, swap previous two chars + } else if (ch == 21) { // control u, delete all to beginning + if (osdeditcursor>0 && osdeditlen) { + if (osdeditcursor0 && osdeditlen>0) { + i=osdeditcursor; + while (i>0 && osdeditbuf[i-1]==32) i--; + while (i>0 && osdeditbuf[i-1]!=32) i--; + if (osdeditcursor= 32) { // text char + if (!osdovertype && osdeditlen == EDITLENGTH) // buffer full, can't insert another char + return 0; + + if (!osdovertype) { + if (osdeditcursor < osdeditlen) + Bmemmove(osdeditbuf+osdeditcursor+1, osdeditbuf+osdeditcursor, osdeditlen-osdeditcursor); + osdeditlen++; + } else { + if (osdeditcursor == osdeditlen) + osdeditlen++; + } + osdeditbuf[osdeditcursor] = ch; + osdeditcursor++; + if (osdeditcursor>osdeditwinend) osdeditwinstart++,osdeditwinend++; + } + } + + if (sc == 15) { // tab + } else if (sc == 1) { // escape + OSD_ShowDisplay(0); + } else if (sc == 201) { // page up + if (osdhead < osdlines-1) + osdhead++; + } else if (sc == 209) { // page down + if (osdhead > 0) + osdhead--; + } else if (sc == 199) { // home + if (osdeditcontrol) { + osdhead = osdlines-1; + } else { + osdeditcursor = 0; + osdeditwinstart = osdeditcursor; + osdeditwinend = osdeditwinstart+editlinewidth; + } + } else if (sc == 207) { // end + if (osdeditcontrol) { + osdhead = 0; + } else { + osdeditcursor = osdeditlen; + osdeditwinend = osdeditcursor; + osdeditwinstart = osdeditwinend-editlinewidth; + if (osdeditwinstart<0) { + osdeditwinstart=0; + osdeditwinend = editlinewidth; + } + } + } else if (sc == 210) { // insert + osdovertype ^= 1; + } else if (sc == 203) { // left + if (osdeditcursor>0) { + if (osdeditcontrol) { + while (osdeditcursor>0) { + if (osdeditbuf[osdeditcursor-1] != 32) break; + osdeditcursor--; + } + while (osdeditcursor>0) { + if (osdeditbuf[osdeditcursor-1] == 32) break; + osdeditcursor--; + } + } else osdeditcursor--; + } + if (osdeditcursor=osdeditwinend) + osdeditwinstart+=(osdeditcursor-osdeditwinend), + osdeditwinend+=(osdeditcursor-osdeditwinend); + } else if (sc == 200) { // up + if (osdhistorypos < osdhistorysize-1) { + osdhistorypos++; + memcpy(osdeditbuf, osdhistorybuf[osdhistorypos], EDITLENGTH+1); + osdeditlen = osdeditcursor = 0; + while (osdeditbuf[osdeditcursor]) osdeditlen++, osdeditcursor++; + if (osdeditcursor=osdeditwinend) + osdeditwinstart+=(osdeditcursor-osdeditwinend), + osdeditwinend+=(osdeditcursor-osdeditwinend); + } + } else if (sc == 208) { // down + if (osdhistorypos >= 0) { + if (osdhistorypos == 0) { + osdeditlen=0; + osdeditcursor=0; + osdeditwinstart=0; + osdeditwinend=editlinewidth; + osdhistorypos = -1; + } else { + osdhistorypos--; + memcpy(osdeditbuf, osdhistorybuf[osdhistorypos], EDITLENGTH+1); + osdeditlen = osdeditcursor = 0; + while (osdeditbuf[osdeditcursor]) osdeditlen++, osdeditcursor++; + if (osdeditcursor=osdeditwinend) + osdeditwinstart+=(osdeditcursor-osdeditwinend), + osdeditwinend+=(osdeditcursor-osdeditwinend); + } + } + } else if (sc == 42 || sc == 54) { // shift + osdeditshift = 1; + } else if (sc == 29 || sc == 157) { // control + osdeditcontrol = 1; + } else if (sc == 58) { // capslock + osdeditcaps ^= 1; + } else if (sc == 28 || sc == 156) { // enter + } else if (sc == 14) { // backspace + } else if (sc == 211) { // delete + if (osdeditcursor == osdeditlen || !osdeditlen) return 0; + if (osdeditcursor <= osdeditlen-1) Bmemmove(osdeditbuf+osdeditcursor, osdeditbuf+osdeditcursor+1, osdeditlen-osdeditcursor-1); + osdeditlen--; + } + + return 0; +} + + +// +// OSD_ResizeDisplay() -- Handles readjustment of the display when the screen resolution +// changes on us. +// +void OSD_ResizeDisplay(int w, int h) +{ + int newcols; + int newmaxlines; + char newtext[TEXTSIZE]; + int i,j,k; + + newcols = getcolumnwidth(w); + newmaxlines = TEXTSIZE / newcols; + + j = min(newmaxlines, osdmaxlines); + k = min(newcols, osdcols); + + memset(newtext, 32, TEXTSIZE); + for (i=0;i osdmaxrows) osdrows = osdmaxrows; + + osdpos = 0; + osdhead = 0; + osdeditwinstart = 0; + osdeditwinend = editlinewidth; + white = -1; +} + + +// +// OSD_ShowDisplay() -- Shows or hides the onscreen display +// +void OSD_ShowDisplay(int onf) +{ + osdvisible = (onf != 0); + osdeditcontrol = 0; + osdeditshift = 0; + + grabmouse(osdvisible == 0); + onshowosd(osdvisible); + if (osdvisible) releaseallbuttons(); +} + + +// +// OSD_Draw() -- Draw the onscreen display +// +void OSD_Draw(void) +{ + unsigned topoffs; + int row, lines, x, len; + + if (!osdvisible || !osdinited) return; + + topoffs = osdhead * osdcols; + row = osdrows-1; + lines = min( osdlines-osdhead, osdrows ); + + begindrawing(); + + clearbackground(osdcols,osdrows+1); + + for (; lines>0; lines--, row--) { + drawosdstr(0,row,osdtext+topoffs,osdcols,osdtextshade,osdtextpal); + topoffs+=osdcols; + } + + drawosdchar(2,osdrows,'>',osdpromptshade,osdpromptpal); + if (osdeditcaps) drawosdchar(0,osdrows,'C',osdpromptshade,osdpromptpal); + if (osdeditshift) drawosdchar(1,osdrows,'H',osdpromptshade,osdpromptpal); + + len = min(osdcols-1-3, osdeditlen-osdeditwinstart); + for (x=0; x=0; cmd--) { + OSD_Dispatch((const char *)osdhistorybuf[cmd]); + } +} + + +// +// OSD_Dispatch() -- Executes a command string +// + +static char *strtoken(char *s, char **ptrptr, int *restart) +{ + char *p, *p2, *start; + + *restart = 0; + if (!ptrptr) return NULL; + + // if s != NULL, we process from the start of s, otherwise + // we just continue with where ptrptr points to + if (s) p = s; + else p = *ptrptr; + + if (!p) return NULL; + + // eat up any leading whitespace + while (*p != 0 && *p != ';' && *p == ' ') p++; + + // a semicolon is an end of statement delimiter like a \0 is, so we signal + // the caller to 'restart' for the rest of the string pointed at by *ptrptr + if (*p == ';') { + *restart = 1; + *ptrptr = p+1; + return NULL; + } + // or if we hit the end of the input, signal all done by nulling *ptrptr + else if (*p == 0) { + *ptrptr = NULL; + return NULL; + } + + if (*p == '\"') { + // quoted string + start = ++p; + p2 = p; + while (*p != 0) { + if (*p == '\"') { + p++; + break; + } else if (*p == '\\') { + switch (*(++p)) { + case 'n': *p2 = '\n'; break; + case 'r': *p2 = '\r'; break; + default: *p2 = *p; break; + } + } else { + *p2 = *p; + } + p2++, p++; + } + *p2 = 0; + } else { + start = p; + while (*p != 0 && *p != ';' && *p != ' ') p++; + } + + // if we hit the end of input, signal all done by nulling *ptrptr + if (*p == 0) { + *ptrptr = NULL; + } + // or if we came upon a semicolon, signal caller to restart with the + // string at *ptrptr + else if (*p == ';') { + *p = 0; + *ptrptr = p+1; + *restart = 1; + } + // otherwise, clip off the token and carry on + else { + *(p++) = 0; + *ptrptr = p; + } + + return start; +} + +#define MAXPARMS 512 +int OSD_Dispatch(const char *cmd) +{ + char *workbuf, *wp, *wtp, *state; + char *parms[MAXPARMS]; + int numparms, restart = 0; + osdfuncparm_t ofp; + symbol_t *symb; + //int i; + + workbuf = state = Bstrdup(cmd); + if (!workbuf) return -1; + + do { + numparms = 0; + Bmemset(parms, 0, sizeof(parms)); + wp = strtoken(state, &wtp, &restart); + if (!wp) { + state = wtp; + continue; + } + + symb = findexactsymbol(wp); + if (!symb) { + OSD_Printf("Error: \"%s\" is not defined\n", wp); + free(workbuf); + return -1; + } + + ofp.name = wp; + while (wtp && !restart) { + wp = strtoken(NULL, &wtp, &restart); + if (wp && numparms < MAXPARMS) parms[numparms++] = wp; + } + ofp.numparms = numparms; + ofp.parms = (const char **)parms; + ofp.raw = cmd; + switch (symb->func(&ofp)) { + case OSDCMD_OK: break; + case OSDCMD_SHOWHELP: OSD_Printf("%s\n", symb->help); break; + } + + state = wtp; + } while (wtp && restart); + + free(workbuf); + + return 0; +} + + +// +// OSD_RegisterFunction() -- Registers a new function +// +int OSD_RegisterFunction(const char *name, const char *help, int (*func)(const osdfuncparm_t*)) +{ + symbol_t *symb; + const char *cp; + + if (!osdinited) OSD_Init(); + + if (!name) { + Bprintf("OSD_RegisterFunction(): may not register a function with a null name\n"); + return -1; + } + if (!name[0]) { + Bprintf("OSD_RegisterFunction(): may not register a function with no name\n"); + return -1; + } + + // check for illegal characters in name + for (cp = name; *cp; cp++) { + if ((cp == name) && (*cp >= '0') && (*cp <= '9')) { + Bprintf("OSD_RegisterFunction(): first character of function name \"%s\" must not be a numeral\n", name); + return -1; + } + if ((*cp < '0') || + (*cp > '9' && *cp < 'A') || + (*cp > 'Z' && *cp < 'a' && *cp != '_') || + (*cp > 'z')) { + Bprintf("OSD_RegisterFunction(): illegal character in function name \"%s\"\n", name); + return -1; + } + } + + if (!help) help = "(no description for this function)"; + if (!func) { + Bprintf("OSD_RegisterFunction(): may not register a null function\n"); + return -1; + } + + symb = findexactsymbol(name); + if (symb) { + Bprintf("OSD_RegisterFunction(): \"%s\" is already defined\n", name); + return -1; + } + + symb = addnewsymbol(name); + if (!symb) { + Bprintf("OSD_RegisterFunction(): Failed registering function \"%s\"\n", name); + return -1; + } + + symb->name = name; + symb->help = help; + symb->func = func; + + return 0; +} + + +// +// addnewsymbol() -- Allocates space for a new symbol and attaches it +// appropriately to the lists, sorted. +// +static symbol_t *addnewsymbol(const char *name) +{ + symbol_t *newsymb, *s, *t; + + newsymb = (symbol_t *)Bmalloc(sizeof(symbol_t)); + if (!newsymb) { return NULL; } + Bmemset(newsymb, 0, sizeof(symbol_t)); + + // link it to the main chain + if (!symbols) { + symbols = newsymb; + } else { + if (Bstrcasecmp(name, symbols->name) <= 0) { + t = symbols; + symbols = newsymb; + symbols->next = t; + } else { + s = symbols; + while (s->next) { + if (Bstrcasecmp(s->next->name, name) > 0) break; + s=s->next; + } + t = s->next; + s->next = newsymb; + newsymb->next = t; + } + } + + return newsymb; +} + + +// +// findsymbol() -- Finds a symbol, possibly partially named +// +static symbol_t *findsymbol(const char *name, symbol_t *startingat) +{ + if (!startingat) startingat = symbols; + if (!startingat) return NULL; + + for (; startingat; startingat=startingat->next) + if (!Bstrncasecmp(name, startingat->name, Bstrlen(name))) return startingat; + + return NULL; +} + + +// +// findexactsymbol() -- Finds a symbol, complete named +// +static symbol_t *findexactsymbol(const char *name) +{ + symbol_t *startingat; + if (!symbols) return NULL; + + startingat = symbols; + + for (; startingat; startingat=startingat->next) + if (!Bstrcasecmp(name, startingat->name)) return startingat; + + return NULL; +} + diff --git a/polymer/build/src/osxbits.m b/polymer/build/src/osxbits.m new file mode 100644 index 000000000..781dc4b1f --- /dev/null +++ b/polymer/build/src/osxbits.m @@ -0,0 +1,37 @@ +#include "osxbits.h" +#include + +int osx_msgbox(char *name, char *msg) +{ + NSAlert *alert = [[NSAlert alloc] init]; + NSString *mmsg = [[NSString alloc] initWithCString: msg]; + [alert addButtonWithTitle: @"OK"]; + [alert setMessageText: mmsg]; + [alert setAlertStyle: NSInformationalAlertStyle]; + + [alert runModal]; + + [alert release]; + [mmsg release]; + + return 0; +} + +int osx_ynbox(char *name, char *msg) +{ + NSAlert *alert = [[NSAlert alloc] init]; + NSString *mmsg = [[NSString alloc] initWithCString: msg]; + int r; + + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + [alert setMessageText: mmsg]; + [alert setAlertStyle: NSInformationalAlertStyle]; + + r = ([alert runModal] == NSAlertFirstButtonReturn); + + [alert release]; + [mmsg release]; + + return r; +} diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c new file mode 100644 index 000000000..3ea5db812 --- /dev/null +++ b/polymer/build/src/polymost.c @@ -0,0 +1,5103 @@ +/************************************************************************************************** +"POLYMOST" code written by Ken Silverman +Ken Silverman's official web site: http://www.advsys.net/ken + +Motivation: +When 3D Realms released the Duke Nukem 3D source code, I thought somebody would do a OpenGL or +Direct3D port. Well, after a few months passed, I saw no sign of somebody working on a true +hardware-accelerated port of Build, just people saying it wasn't possible. Eventually, I realized +the only way this was going to happen was for me to do it myself. First, I needed to port Build to +Windows. I could have done it myself, but instead I thought I'd ask my Australian buddy, Jonathon +Fowler, if he would upgrade his Windows port to my favorite compiler (MSVC) - which he did. Once +that was done, I was ready to start the "POLYMOST" project. + +About: +This source file is basically a complete rewrite of the entire rendering part of the Build engine. +There are small pieces in ENGINE.C to activate this code, and other minor hacks in other source +files, but most of it is in here. If you're looking for polymost-related code in the other source +files, you should find most of them by searching for either "polymost" or "rendmode". Speaking of +rendmode, there are now 4 rendering modes in Build: + + rendmode 0: The original code I wrote from 1993-1997 + rendmode 1: Solid-color rendering: my debug code before I did texture mapping + rendmode 2: Software rendering before I started the OpenGL code (Note: this is just a quick + hack to make testing easier - it's not optimized to my usual standards!) + rendmode 3: The OpenGL code + +The original Build engine did hidden surface removal by using a vertical span buffer on the tops +and bottoms of walls. This worked nice back in the day, but it it's not suitable for a polygon +engine. So I decided to write a brand new hidden surface removal algorithm - using the same idea +as the original Build - but one that worked with vectors instead of already rasterized data. + +Brief history: +06/20/2000: I release Build Source code +04/01/2003: 3D Realms releases Duke Nukem 3D source code +10/04/2003: Jonathon Fowler gets his Windows port working in Visual C +10/04/2003: I start writing POLYMOST.BAS, a new hidden surface removal algorithm for Build that + works on a polygon level instead of spans. +10/16/2003: Ported POLYMOST.BAS to C inside JonoF KenBuild's ENGINE.C; later this code was split + out of ENGINE.C and put in this file, POLYMOST.C. +12/10/2003: Started OpenGL code for POLYMOST (rendmode 3) +12/23/2003: 1st public release +01/01/2004: 2nd public release: fixed stray lines, status bar, mirrors, sky, and lots of other bugs. + +---------------------------------------------------------------------------------------------------- + +Todo list (in approximate chronological order): + +High priority: + * BOTH: Do accurate software sorting/chopping for sprites: drawing in wrong order is bad :/ + * BOTH: Fix hall of mirrors near "zenith". Call polymost_drawrooms twice? + * OPENGL: drawmapview() + +Low priority: + * SOFT6D: Do back-face culling of sprites during up/down/tilt transformation (top of drawpoly) + * SOFT6D: Fix depth shading: use saturation&LUT + * SOFT6D: Optimize using hyperbolic mapping (similar to KUBE algo) + * SOFT6D: Slab6-style voxel sprites. How to accelerate? :/ + * OPENGL: KENBUILD: Write flipping code for floor mirrors + * BOTH: KENBUILD: Parallaxing sky modes 1&2 + * BOTH: Masked/1-way walls don't clip correctly to sectors of intersecting ceiling/floor slopes + * BOTH: Editart x-center is not working correctly with Duke's camera/turret sprites + * BOTH: Get rid of horizontal line above Duke full-screen status bar + * BOTH: Combine ceilings/floors into a single triangle strip (should lower poly count by 2x) + * BOTH: Optimize/clean up texture-map setup equations + +**************************************************************************************************/ + +static long animateoffs(short tilenum, short fakevar); +long rendmode = 0; +long usemodels=1, usehightile=1; + + +#include //<-important! +typedef struct { float x, cy[2], fy[2]; long n, p, tag, ctag, ftag; } vsptyp; +#define VSPMAX 4096 //<- careful! +static vsptyp vsp[VSPMAX]; +static long vcnt, gtag; + +static double dxb1[MAXWALLSB], dxb2[MAXWALLSB]; + +#define SCISDIST 1.0 //1.0: Close plane clipping distance +#define USEZBUFFER 1 //1:use zbuffer (slow, nice sprite rendering), 0:no zbuffer (fast, bad sprite rendering) +#define LINTERPSIZ 4 //log2 of interpolation size. 4:pretty fast&acceptable quality, 0:best quality/slow! +#define DEPTHDEBUG 0 //1:render distance instead of texture, for debugging only!, 0:default +#define FOGSCALE 0.0000384 +#define PI 3.14159265358979323 + +static double gyxscale, gxyaspect, gviewxrange, ghalfx, grhalfxdown10, grhalfxdown10x, ghoriz; +static double gcosang, gsinang, gcosang2, gsinang2; +static double gchang, gshang, gctang, gstang, gvisibility; +static float gtang = 0.0; +double guo, gux, guy; //Screen-based texture mapping parameters +double gvo, gvx, gvy; +double gdo, gdx, gdy; + +#if (USEZBUFFER != 0) +long zbufmem = 0, zbufysiz = 0, zbufbpl = 0, *zbufoff = 0; +#endif + +#ifdef USE_OPENGL +long glredbluemode = 0; +static long lastglredbluemode = 0, redblueclearcnt = 0; + +static struct glfiltermodes { + char *name; + long min,mag; +} glfiltermodes[] = { + {"GL_NEAREST",GL_NEAREST,GL_NEAREST}, + {"GL_LINEAR",GL_LINEAR,GL_LINEAR}, + {"GL_NEAREST_MIPMAP_NEAREST",GL_NEAREST_MIPMAP_NEAREST,GL_NEAREST}, + {"GL_LINEAR_MIPMAP_NEAREST",GL_LINEAR_MIPMAP_NEAREST,GL_LINEAR}, + {"GL_NEAREST_MIPMAP_LINEAR",GL_NEAREST_MIPMAP_LINEAR,GL_NEAREST}, + {"GL_LINEAR_MIPMAP_LINEAR",GL_LINEAR_MIPMAP_LINEAR,GL_LINEAR} +}; +#define numglfiltermodes (sizeof(glfiltermodes)/sizeof(glfiltermodes[0])) + +long glanisotropy = 1; // 0 = maximum supported by card +long glusetexcompr = 1; +long gltexfiltermode = 3; // GL_LINEAR_MIPMAP_NEAREST +long glusetexcache = 0; +long glusetexcachecompression = 1; +long glmultisample = 0, glnvmultisamplehint = 0; +long gltexmaxsize = 0; // 0 means autodetection on first run +long gltexmiplevel = 0; // discards this many mipmap levels +static long lastglpolygonmode = 0; //FUK +long glpolygonmode = 0; // 0:GL_FILL,1:GL_LINE,2:GL_POINT //FUK +static GLuint polymosttext = 0; +extern char nofog; +#endif + +#if defined(USE_MSC_PRAGMAS) +static inline void ftol (float f, long *a) +{ + _asm + { + mov eax, a + fld f + fistp dword ptr [eax] + } +} + +static inline void dtol (double d, long *a) +{ + _asm + { + mov eax, a + fld d + fistp dword ptr [eax] + } +} +#elif defined(USE_WATCOM_PRAGMAS) + +#pragma aux ftol =\ + "fistp dword ptr [eax]",\ + parm [eax 8087] +#pragma aux dtol =\ + "fistp dword ptr [eax]",\ + parm [eax 8087] + +#elif defined(USE_GCC_PRAGMAS) + +static inline void ftol (float f, long *a) +{ + __asm__ __volatile__ ( +#if 0 //(__GNUC__ >= 3) + "flds %1; fistpl %0;" +#else + "flds %1; fistpl (%0);" +#endif + : "=r" (a) : "m" (f) : "memory","cc"); +} + +static inline void dtol (double d, long *a) +{ + __asm__ __volatile__ ( +#if 0 //(__GNUC__ >= 3) + "fldl %1; fistpl %0;" +#else + "fldl %1; fistpl (%0);" +#endif + : "=r" (a) : "m" (d) : "memory","cc"); +} + +#else +static inline void ftol (float f, long *a) +{ + *a = (long)f; +} + +static inline void dtol (double d, long *a) +{ + *a = (long)d; +} +#endif + +static inline long imod (long a, long b) +{ + if (a >= 0) return(a%b); + return(((a+1)%b)+b-1); +} + +void drawline2d (float x0, float y0, float x1, float y1, char col) +{ + float f, dx, dy, fxres, fyres; + long e, inc, x, y; + unsigned long up16; + + dx = x1-x0; dy = y1-y0; if ((dx == 0) && (dy == 0)) return; + fxres = (float)xdimen; fyres = (float)ydimen; + if (x0 >= fxres) { if (x1 >= fxres) return; y0 += (fxres-x0)*dy/dx; x0 = fxres; } + else if (x0 < 0) { if (x1 < 0) return; y0 += ( 0-x0)*dy/dx; x0 = 0; } + if (x1 >= fxres) { y1 += (fxres-x1)*dy/dx; x1 = fxres; } + else if (x1 < 0) { y1 += ( 0-x1)*dy/dx; x1 = 0; } + if (y0 >= fyres) { if (y1 >= fyres) return; x0 += (fyres-y0)*dx/dy; y0 = fyres; } + else if (y0 < 0) { if (y1 < 0) return; x0 += ( 0-y0)*dx/dy; y0 = 0; } + if (y1 >= fyres) { x1 += (fyres-y1)*dx/dy; y1 = fyres; } + else if (y1 < 0) { x1 += ( 0-y1)*dx/dy; y1 = 0; } + + if (fabs(dx) > fabs(dy)) + { + if (x0 > x1) { f = x0; x0 = x1; x1 = f; f = y0; y0 = y1; y1 = f; } + y = (long)(y0*65536.f)+32768; + inc = (long)(dy/dx*65536.f+.5f); + x = (long)(x0+.5); if (x < 0) { y -= inc*x; x = 0; } //if for safety + e = (long)(x1+.5); if (e > xdimen) e = xdimen; //if for safety + up16 = (ydimen<<16); + for(;x>16]+x+frameoffset) = col; + } + else + { + if (y0 > y1) { f = x0; x0 = x1; x1 = f; f = y0; y0 = y1; y1 = f; } + x = (long)(x0*65536.f)+32768; + inc = (long)(dx/dy*65536.f+.5f); + y = (long)(y0+.5); if (y < 0) { x -= inc*y; y = 0; } //if for safety + e = (long)(y1+.5); if (e > ydimen) e = ydimen; //if for safety + up16 = (xdimen<<16); + for(;y>16)+frameoffset) = col; + } +} + +#ifdef USE_OPENGL +typedef struct { unsigned char r, g, b, a; } coltype; + +static void uploadtexture(long doalloc, long xsiz, long ysiz, long intexfmt, long texfmt, coltype *pic, long tsizx, long tsizy, long dameth); + +#include "md4.h" + +#define USELZF +#define USEKENFILTER 1 + +#ifdef USELZF +# include "lzf.h" +#else +# include "lzwnew.h" +#endif + +static char TEXCACHEDIR[] = "texcache"; +typedef struct { + char magic[8]; // 'Polymost' + long xdim, ydim; // of image, unpadded + long flags; // 1 = !2^x, 2 = has alpha, 4 = lzw compressed +} texcacheheader; +typedef struct { + long size; + long format; + long xdim, ydim; // of mipmap (possibly padded) + long border, depth; +} texcachepicture; + +int dxtfilter(int fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, unsigned long miplen); +int dedxtfilter(int fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, int ispacked); + +static inline void phex(unsigned char v, char *s); +void writexcache(char *fn, long len, long dameth, char effect, texcacheheader *head); + +static long mdtims, omdtims; +float alphahackarray[MAXTILES]; +#include "mdsprite.c" + +//-------------------------------------------------------------------------------------------------- +//TEXTURE MANAGEMENT: treats same texture with different .PAL as a separate texture. This makes the +// max number of virtual textures very large (MAXTILES*256). Instead of allocating a handle for +// every virtual texture, I use a cache where indexing is managed through a hash table. +// + +typedef struct pthtyp_t +{ + struct pthtyp_t *next; + GLuint glpic; + short picnum; + char palnum; + char effects; + char flags; // 1 = clamped (dameth&4), 2 = hightile, 4 = skybox face, 8 = hasalpha, 128 = invalidated + char skyface; + hicreplctyp *hicr; + + unsigned short sizx, sizy; + float scalex, scaley; +} pthtyp; + +#define GLTEXCACHEADSIZ 8192 +static pthtyp *gltexcachead[GLTEXCACHEADSIZ]; + +static long drawingskybox = 0; + +int gloadtile_art(long,long,long,pthtyp*,long); +int gloadtile_hi(long,long,hicreplctyp*,long,pthtyp*,long,char); +static int hicprecaching = 0; +static pthtyp * gltexcache (long dapicnum, long dapalnum, long dameth) +{ + long i, j; + hicreplctyp *si; + pthtyp *pth; + + j = (dapicnum&(GLTEXCACHEADSIZ-1)); + + if (usehightile) si = hicfindsubst(dapicnum,dapalnum,drawingskybox); + else si = NULL; + if (!si) { + if (drawingskybox) return NULL; + goto tryart; + } + + /* if palette > 0 && replacement found + * no effects are applied to the texture + * else if palette > 0 && no replacement found + * effects are applied to the palette 0 texture if it exists + */ + + // load a replacement + for(pth=gltexcachead[j]; pth; pth=pth->next) { + if (pth->picnum == dapicnum && + pth->palnum == si->palnum && + (si->palnum>0 ? 1 : (pth->effects == hictinting[dapalnum].f)) && + (pth->flags & (1+2+4)) == (((dameth&4)>>2)+2+((drawingskybox>0)<<2)) && + (drawingskybox>0 ? (pth->skyface == drawingskybox) : 1) + ) + { + if (pth->flags & 128) + { + pth->flags &= ~128; + if (gloadtile_hi(dapicnum,drawingskybox,si,dameth,pth,0, + (si->palnum>0) ? 0 : hictinting[dapalnum].f)) { // reload tile + if (drawingskybox) return NULL; + goto tryart; // failed, so try for ART + } + } + return(pth); + } + } + + pth = (pthtyp *)calloc(1,sizeof(pthtyp)); + if (!pth) return NULL; + + if (gloadtile_hi(dapicnum,drawingskybox,si,dameth,pth,1, (si->palnum>0) ? 0 : hictinting[dapalnum].f)) { + free(pth); + if (drawingskybox) return NULL; + goto tryart; // failed, so try for ART + } + pth->palnum = si->palnum; + pth->next = gltexcachead[j]; + gltexcachead[j] = pth; + return(pth); + +tryart: + if (hicprecaching) return NULL; + + // load from art + for(pth=gltexcachead[j]; pth; pth=pth->next) + if (pth->picnum == dapicnum && + pth->palnum == dapalnum && + (pth->flags & (1+2)) == ((dameth&4)>>2) + ) + { + if (pth->flags & 128) + { + pth->flags &= ~128; + if (gloadtile_art(dapicnum,dapalnum,dameth,pth,0)) return NULL; //reload tile (for animations) + } + return(pth); + } + + pth = (pthtyp *)calloc(1,sizeof(pthtyp)); + if (!pth) return NULL; + + if (gloadtile_art(dapicnum,dapalnum,dameth,pth,1)) { + free(pth); + return NULL; + } + pth->next = gltexcachead[j]; + gltexcachead[j] = pth; + return(pth); +} + +long gltexmayhavealpha (long dapicnum, long dapalnum) +{ + long j = (dapicnum&(GLTEXCACHEADSIZ-1)); + pthtyp *pth; + + for(pth=gltexcachead[j]; pth; pth=pth->next) + if ((pth->picnum == dapicnum) && (pth->palnum == dapalnum)) + return((pth->flags&8) != 0); + return(1); +} + +void gltexinvalidate (long dapicnum, long dapalnum, long dameth) +{ + long i, j; + pthtyp *pth; + + j = (dapicnum&(GLTEXCACHEADSIZ-1)); + for(pth=gltexcachead[j]; pth; pth=pth->next) + if (pth->picnum == dapicnum && pth->palnum == dapalnum && (pth->flags & 1) == ((dameth&4)>>2) ) + { pth->flags |= 128; } +} + + //Make all textures "dirty" so they reload, but not re-allocate + //This should be much faster than polymost_glreset() + //Use this for palette effects ... but not ones that change every frame! +void gltexinvalidateall () +{ + long j; + pthtyp *pth; + + for(j=GLTEXCACHEADSIZ-1;j>=0;j--) + for(pth=gltexcachead[j];pth;pth=pth->next) + pth->flags |= 128; + clearskins(); +#ifdef DEBUGGINGAIDS + OSD_Printf("gltexinvalidateall()\n"); +#endif +} + + +void gltexapplyprops (void) +{ + long i; + pthtyp *pth; + + if (glinfo.maxanisotropy > 1.0) + { + if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy) glanisotropy = (long)glinfo.maxanisotropy; + } + + if (gltexfiltermode < 0) gltexfiltermode = 0; + else if (gltexfiltermode >= (long)numglfiltermodes) gltexfiltermode = numglfiltermodes-1; + for(i=GLTEXCACHEADSIZ-1;i>=0;i--) { + for(pth=gltexcachead[i];pth;pth=pth->next) { + bglBindTexture(GL_TEXTURE_2D,pth->glpic); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + if (glinfo.maxanisotropy > 1.0) + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + } + } + + { + int j; + mdskinmap_t *sk; + md2model *m; + + for (i=0;imdnum < 2) continue; + for (j=0;jnumskins*(HICEFFECTMASK+1);j++) + { + if (!m->texid[j]) continue; + bglBindTexture(GL_TEXTURE_2D,m->texid[j]); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + if (glinfo.maxanisotropy > 1.0) + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + } + + for (sk=m->skinmap;sk;sk=sk->next) + for (j=0;j<(HICEFFECTMASK+1);j++) + { + if (!sk->texid[j]) continue; + bglBindTexture(GL_TEXTURE_2D,sk->texid[j]); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + if (glinfo.maxanisotropy > 1.0) + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- + +static float glox1, gloy1, glox2, gloy2; + + //Use this for both initialization and uninitialization of OpenGL. +static int gltexcacnum = -1; +void polymost_glreset () +{ + long i; + pthtyp *pth, *next; + //Reset if this is -1 (meaning 1st texture call ever), or > 0 (textures in memory) + if (gltexcacnum < 0) + { + gltexcacnum = 0; + + //Hack for polymost_dorotatesprite calls before 1st polymost_drawrooms() + gcosang = gcosang2 = ((double)16384)/262144.0; + gsinang = gsinang2 = ((double) 0)/262144.0; + } + else + { + for (i=GLTEXCACHEADSIZ-1; i>=0; i--) { + for (pth=gltexcachead[i]; pth;) { + next = pth->next; + bglDeleteTextures(1,&pth->glpic); + free(pth); + pth = next; + } + gltexcachead[i] = NULL; + } + clearskins(); + } + + if (polymosttext) bglDeleteTextures(1,&polymosttext); + polymosttext=0; + + memset(gltexcachead,0,sizeof(gltexcachead)); + glox1 = -1; +} + +// one-time initialisation of OpenGL for polymost +void polymost_glinit() +{ + GLfloat col[4]; + + bglFogi(GL_FOG_MODE,GL_EXP); //GL_EXP(default),GL_EXP2,GL_LINEAR + //bglHint(GL_FOG_HINT,GL_NICEST); + bglFogf(GL_FOG_DENSITY,1.0); //must be > 0, default is 1 + bglFogf(GL_FOG_START,0.0); //default is 0 + bglFogf(GL_FOG_END,1.0); //default is 1 + col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; //range:0 to 1 + bglFogfv(GL_FOG_COLOR,col); //default is 0,0,0,0 + + bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + if (glmultisample > 0 && glinfo.multisample) { + if (glinfo.nvmultisamplehint) + bglHint(GL_MULTISAMPLE_FILTER_HINT_NV, glnvmultisamplehint ? GL_NICEST:GL_FASTEST); + bglEnable(GL_MULTISAMPLE_ARB); + } +} + +void resizeglcheck () +{ + float m[4][4]; + + if (glredbluemode < lastglredbluemode) { + glox1 = -1; + bglColorMask(1,1,1,1); + } else if (glredbluemode != lastglredbluemode) { + redblueclearcnt = 0; + } + lastglredbluemode = glredbluemode; + + //FUK + if (lastglpolygonmode != glpolygonmode) + { + lastglpolygonmode = glpolygonmode; + switch(glpolygonmode) + { + default: + case 0: bglPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break; + case 1: bglPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break; + case 2: bglPolygonMode(GL_FRONT_AND_BACK,GL_POINT); break; + } + } + if (glpolygonmode) //FUK + { + bglClearColor(1.0,1.0,1.0,0.0); + bglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + bglDisable(GL_TEXTURE_2D); + } + + if ((glox1 != windowx1) || (gloy1 != windowy1) || (glox2 != windowx2) || (gloy2 != windowy2)) + { + glox1 = windowx1; gloy1 = windowy1; + glox2 = windowx2; gloy2 = windowy2; + + bglViewport(windowx1,yres-(windowy2+1),windowx2-windowx1+1,windowy2-windowy1+1); + + bglMatrixMode(GL_PROJECTION); + memset(m,0,sizeof(m)); + m[0][0] = (float)ydimen; m[0][2] = 1.0; + m[1][1] = (float)xdimen; m[1][2] = 1.0; + m[2][2] = 1.0; m[2][3] = (float)ydimen; + m[3][2] =-1.0; + bglLoadMatrixf(&m[0][0]); + + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); + + if (!nofog) bglEnable(GL_FOG); + + //bglEnable(GL_TEXTURE_2D); + } +} + +void fixtransparency (coltype *dapic, long daxsiz, long daysiz, long daxsiz2, long daysiz2, long dameth) +{ + coltype *wpptr; + long j, x, y, r, g, b, dox, doy, naxsiz2; + + dox = daxsiz2-1; doy = daysiz2-1; + if (dameth&4) { dox = min(dox,daxsiz); doy = min(doy,daysiz); } + else { daxsiz = daxsiz2; daysiz = daysiz2; } //Make repeating textures duplicate top/left parts + + daxsiz--; daysiz--; naxsiz2 = -daxsiz2; //Hacks for optimization inside loop + + //Set transparent pixels to average color of neighboring opaque pixels + //Doing this makes bilinear filtering look much better for masked textures (I.E. sprites) + for(y=doy;y>=0;y--) + { + wpptr = &dapic[y*daxsiz2+dox]; + for(x=dox;x>=0;x--,wpptr--) + { + if (wpptr->a) continue; + r = g = b = j = 0; + if ((x> 0) && (wpptr[ -1].a)) { r += (long)wpptr[ -1].r; g += (long)wpptr[ -1].g; b += (long)wpptr[ -1].b; j++; } + if ((x 0) && (wpptr[naxsiz2].a)) { r += (long)wpptr[naxsiz2].r; g += (long)wpptr[naxsiz2].g; b += (long)wpptr[naxsiz2].b; j++; } + if ((yr = r ; wpptr->g = g ; wpptr->b = b ; break; + case 2: wpptr->r = ((r + 1)>>1); wpptr->g = ((g + 1)>>1); wpptr->b = ((b + 1)>>1); break; + case 3: wpptr->r = ((r*85+128)>>8); wpptr->g = ((g*85+128)>>8); wpptr->b = ((b*85+128)>>8); break; + case 4: wpptr->r = ((r + 2)>>2); wpptr->g = ((g + 2)>>2); wpptr->b = ((b + 2)>>2); break; + default: break; + } + } + } +} + +static void uploadtexture(long doalloc, long xsiz, long ysiz, long intexfmt, long texfmt, coltype *pic, long tsizx, long tsizy, long dameth) +{ + coltype *wpptr, *rpptr; + long x2, y2, j, js=0, x3, y3, y, x, r, g, b, a, k; + + if (gltexmaxsize <= 0) { + GLint i = 0; + bglGetIntegerv(GL_MAX_TEXTURE_SIZE, &i); + if (!i) gltexmaxsize = 6; // 2^6 = 64 == default GL max texture size + else { + gltexmaxsize = 0; + for (; i>1; i>>=1) gltexmaxsize++; + } + } + + js = max(0,min(gltexmaxsize-1,gltexmiplevel)); + gltexmiplevel = js; + while ((xsiz>>js) > (1<>js) > (1< 1) || (y2 > 1);j++) + { + //x3 = ((x2+1)>>1); y3 = ((y2+1)>>1); + x3 = max(1, x2 >> 1); y3 = max(1, y2 >> 1); // this came from the GL_ARB_texture_non_power_of_two spec + for(y=0;yr = r; wpptr->g = g; wpptr->b = b; wpptr->a = a; break; + case 2: wpptr->r = ((r+1)>>1); wpptr->g = ((g+1)>>1); wpptr->b = ((b+1)>>1); wpptr->a = ((a+1)>>1); break; + case 3: wpptr->r = ((r*85+128)>>8); wpptr->g = ((g*85+128)>>8); wpptr->b = ((b*85+128)>>8); wpptr->a = ((a*85+128)>>8); break; + case 4: wpptr->r = ((r+2)>>2); wpptr->g = ((g+2)>>2); wpptr->b = ((b+2)>>2); wpptr->a = ((a+2)>>2); break; + default: break; + } + //if (wpptr->a) wpptr->a = 255; + } + } + if (tsizx >= 0) fixtransparency(pic,(tsizx+(1<>j,(tsizy+(1<>j,x3,y3,dameth); + if (j >= js) { + if (doalloc&1) + bglTexImage2D(GL_TEXTURE_2D,j-js,intexfmt,x3,y3,0,texfmt,GL_UNSIGNED_BYTE,pic); //loading 1st time + else + bglTexSubImage2D(GL_TEXTURE_2D,j-js,0,0,x3,y3,texfmt,GL_UNSIGNED_BYTE,pic); //overwrite old texture + } + x2 = x3; y2 = y3; + } +#endif +} + +int gloadtile_art (long dapic, long dapal, long dameth, pthtyp *pth, long doalloc) +{ + coltype *pic, *wpptr; + long j, x, y, x2, y2, xsiz, ysiz, dacol, tsizx, tsizy; + char hasalpha = 0; + + tsizx = tilesizx[dapic]; + tsizy = tilesizy[dapic]; + if (!glinfo.texnpot) { + for(xsiz=1;xsiz= tsizx) || (y >= tsizy))) //Clamp texture + { wpptr->r = wpptr->g = wpptr->b = wpptr->a = 0; continue; } + if (x < tsizx) x2 = x; else x2 = x-tsizx; + dacol = (long)(*(unsigned char *)(waloff[dapic]+x2*tsizy+y2)); + if (dacol == 255) { + wpptr->a = 0; hasalpha = 1; + } else { + wpptr->a = 255; + dacol = (long)((unsigned char)palookup[dapal][dacol]); + } + if (gammabrightness) { + wpptr->r = curpalette[dacol].r; + wpptr->g = curpalette[dacol].g; + wpptr->b = curpalette[dacol].b; + } else { + wpptr->r = britable[curbrightness][ curpalette[dacol].r ]; + wpptr->g = britable[curbrightness][ curpalette[dacol].g ]; + wpptr->b = britable[curbrightness][ curpalette[dacol].b ]; + } + } + } + } + + if (doalloc) bglGenTextures(1,(GLuint*)&pth->glpic); //# of textures (make OpenGL allocate structure) + bglBindTexture(GL_TEXTURE_2D,pth->glpic); + + fixtransparency(pic,tsizx,tsizy,xsiz,ysiz,dameth); + uploadtexture(doalloc,xsiz,ysiz,hasalpha?GL_RGBA:GL_RGB,GL_RGBA,pic,tsizx,tsizy,dameth); + + if (gltexfiltermode < 0) gltexfiltermode = 0; + else if (gltexfiltermode >= (long)numglfiltermodes) gltexfiltermode = numglfiltermodes-1; + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + + if (glinfo.maxanisotropy > 1.0) + { + if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy) glanisotropy = (long)glinfo.maxanisotropy; + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + } + + if (!(dameth&4)) + { + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + } + else + { //For sprite textures, clamping looks better than wrapping + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); + } + + if (pic) free(pic); + + pth->picnum = dapic; + pth->palnum = dapal; + pth->effects = 0; + pth->flags = ((dameth&4)>>2) | (hasalpha<<3); + pth->hicr = NULL; + + return 0; +} + +// JONOF'S COMPRESSED TEXTURE CACHE STUFF --------------------------------------------------- +static inline void phex(unsigned char v, char *s) +{ + int x; + x = v>>4; + s[0] = x<10 ? (x+'0') : (x-10+'a'); + x = v&15; + s[1] = x<10 ? (x+'0') : (x-10+'a'); +} + +long trytexcache(char *fn, long len, long dameth, char effect, texcacheheader *head) +{ + long fil, fp; + char cachefn[BMAX_PATH], *cp; + unsigned char mdsum[16]; + + if (!glinfo.texcompr || !glusetexcompr || !glusetexcache) return -1; + if (!bglCompressedTexImage2DARB || !bglGetCompressedTexImageARB) { + // lacking the necessary extensions to do this + initprintf("Warning: the GL driver lacks necessary functions to use caching\n"); + glusetexcache = 0; + return -1; + } + + md4once(fn, strlen(fn), mdsum); + for (cp = cachefn, fp = 0; (*cp = TEXCACHEDIR[fp]); cp++,fp++); + *(cp++) = '/'; + for (fp = 0; fp < 16; phex(mdsum[fp++], cp), cp+=2); + sprintf(cp, "-%lx-%lx%x", len, dameth, effect); + + fil = kopen4load(cachefn, 0); + if (fil < 0) return -1; + + initprintf("Loading cached tex: %s\n", cachefn); + + if (kread(fil, head, sizeof(texcacheheader)) < (int)sizeof(texcacheheader)) goto failure; + if (memcmp(head->magic, "Polymost", 8)) goto failure; + + head->xdim = B_LITTLE32(head->xdim); + head->ydim = B_LITTLE32(head->ydim); + head->flags = B_LITTLE32(head->flags); + + if (!glinfo.texnpot && (head->flags & 1)) goto failure; + + return fil; +failure: + kclose(fil); + return -1; +} + +void writexcache(char *fn, long len, long dameth, char effect, texcacheheader *head) +{ + long fil=-1, fp; + char cachefn[BMAX_PATH], *cp; + unsigned char mdsum[16]; + texcachepicture pict; + char *pic = NULL, *packbuf = NULL; + void *midbuf = NULL; + unsigned long alloclen=0, level, miplen; + unsigned long padx, pady; + GLuint gi; + long j, k; + + if (!glinfo.texcompr || !glusetexcompr || !glusetexcache) return; + if (!bglCompressedTexImage2DARB || !bglGetCompressedTexImageARB) { + // lacking the necessary extensions to do this + initprintf("Warning: the GL driver lacks necessary functions to use caching\n"); + glusetexcache = 0; + return; + } + + { + struct stat st; + if (stat(TEXCACHEDIR, &st) < 0) { + if (errno == ENOENT) { // path doesn't exist + // try to create the cache directory + if (Bmkdir(TEXCACHEDIR, S_IRWXU) < 0) { + initprintf("Failed to create texture cache directory %s\n", TEXCACHEDIR); + glusetexcache = 0; + return; + } else initprintf("Created texture cache directory %s\n", TEXCACHEDIR); + } else { + // another type of failure + glusetexcache = 0; + return; + } + } else if ((st.st_mode & S_IFDIR) != S_IFDIR) { + // cache directory isn't a directory + glusetexcache = 0; + return; + } + } + + gi = GL_FALSE; + bglGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &gi); + if (gi != GL_TRUE) return; + + md4once(fn, strlen(fn), mdsum); + for (cp = cachefn, fp = 0; (*cp = TEXCACHEDIR[fp]); cp++,fp++); + *(cp++) = '/'; + for (fp = 0; fp < 16; phex(mdsum[fp++], cp), cp+=2); + sprintf(cp, "-%lx-%lx%x", len, dameth, effect); + + initprintf("Writing cached tex: %s\n", cachefn); + + fil = Bopen(cachefn,BO_BINARY|BO_CREAT|BO_TRUNC|BO_RDWR,BS_IREAD|BS_IWRITE); + if (fil < 0) return; + + memcpy(head->magic, "Polymost", 8); // sizes are set by caller + + if (glusetexcachecompression) head->flags |= 4; + + head->xdim = B_LITTLE32(head->xdim); + head->ydim = B_LITTLE32(head->ydim); + head->flags = B_LITTLE32(head->flags); + + if (Bwrite(fil, head, sizeof(texcacheheader)) != sizeof(texcacheheader)) goto failure; + + bglGetError(); + for (level = 0; level==0 || (padx > 1 || pady > 1); level++) { + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_COMPRESSED_ARB, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + if (gi != GL_TRUE) goto failure; // an uncompressed mipmap + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_INTERNAL_FORMAT, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + pict.format = B_LITTLE32(gi); + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + padx = gi; pict.xdim = B_LITTLE32(gi); + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + pady = gi; pict.ydim = B_LITTLE32(gi); + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_BORDER, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + pict.border = B_LITTLE32(gi); + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_DEPTH, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + pict.depth = B_LITTLE32(gi); + bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &gi); + if (bglGetError() != GL_NO_ERROR) goto failure; + miplen = (long)gi; pict.size = B_LITTLE32(gi); + + if (alloclen < miplen) { + void *picc = realloc(pic, miplen); + if (!picc) goto failure; else pic = picc; + alloclen = miplen; + + picc = realloc(packbuf, alloclen+16); + if (!picc) goto failure; else packbuf = picc; + + picc = realloc(midbuf, miplen); + if (!picc) goto failure; else midbuf = picc; + } + + bglGetCompressedTexImageARB(GL_TEXTURE_2D, level, pic); + if (bglGetError() != GL_NO_ERROR) goto failure; + + if (Bwrite(fil, &pict, sizeof(texcachepicture)) != sizeof(texcachepicture)) goto failure; + if (dxtfilter(fil, &pict, pic, midbuf, packbuf, miplen)) goto failure; + } + +failure: + if (fil>=0) Bclose(fil); + if (midbuf) free(midbuf); + if (pic) free(pic); + if (packbuf) free(packbuf); +} + +int gloadtile_cached(long fil, texcacheheader *head, long *doalloc, pthtyp *pth) +{ + int level, r; + texcachepicture pict; + char *pic = NULL, *packbuf = NULL; + void *midbuf = NULL; + long alloclen=0; + + if (*doalloc&1) { + bglGenTextures(1,(GLuint*)&pth->glpic); //# of textures (make OpenGL allocate structure) + *doalloc |= 2; // prevents bglGenTextures being called again if we fail in here + } + bglBindTexture(GL_TEXTURE_2D,pth->glpic); + + pth->sizx = head->xdim; + pth->sizy = head->ydim; + + bglGetError(); + + // load the mipmaps + for (level = 0; level==0 || (pict.xdim > 1 || pict.ydim > 1); level++) { + r = kread(fil, &pict, sizeof(texcachepicture)); + if (r < (int)sizeof(texcachepicture)) goto failure; + + pict.size = B_LITTLE32(pict.size); + pict.format = B_LITTLE32(pict.format); + pict.xdim = B_LITTLE32(pict.xdim); + pict.ydim = B_LITTLE32(pict.ydim); + pict.border = B_LITTLE32(pict.border); + pict.depth = B_LITTLE32(pict.depth); + + if (alloclen < pict.size) { + void *picc = realloc(pic, pict.size); + if (!picc) goto failure; else pic = picc; + alloclen = pict.size; + + picc = realloc(packbuf, alloclen+16); + if (!picc) goto failure; else packbuf = picc; + + picc = realloc(midbuf, pict.size); + if (!picc) goto failure; else midbuf = picc; + } + + if (dedxtfilter(fil, &pict, pic, midbuf, packbuf, (head->flags&4)==4)) goto failure; + + bglCompressedTexImage2DARB(GL_TEXTURE_2D,level,pict.format,pict.xdim,pict.ydim,pict.border, + pict.size,pic); + if (bglGetError() != GL_NO_ERROR) goto failure; + } + + if (midbuf) free(midbuf); + if (pic) free(pic); + if (packbuf) free(packbuf); + return 0; +failure: + if (midbuf) free(midbuf); + if (pic) free(pic); + if (packbuf) free(packbuf); + return -1; +} +// --------------------------------------------------- JONOF'S COMPRESSED TEXTURE CACHE STUFF + +int gloadtile_hi(long dapic, long facen, hicreplctyp *hicr, long dameth, pthtyp *pth, long doalloc, char effect) +{ + coltype *pic = NULL, *rpptr; + long j, x, y, x2, y2, xsiz, ysiz, tsizx, tsizy; + + char *picfil = NULL, *fn, hasalpha = 255; + long picfillen, texfmt = GL_RGBA, intexfmt = GL_RGBA, filh; + + long cachefil = -1; + texcacheheader cachead; + + if (!hicr) return -1; + if (facen > 0) { + if (!hicr->skybox) return -1; + if (facen > 6) return -1; + if (!hicr->skybox->face[facen-1]) return -1; + fn = hicr->skybox->face[facen-1]; + } else { + if (!hicr->filename) return -1; + fn = hicr->filename; + } + + if ((filh = kopen4load(fn, 0)) < 0) { + initprintf("hightile: %s (pic %d) not found\n", fn, dapic); + if (facen > 0) + hicr->skybox->ignore = 1; + else + hicr->ignore = 1; + return -1; + } + picfillen = kfilelength(filh); + + kclose(filh); // FIXME: shouldn't have to do this. bug in cache1d.c + + cachefil = trytexcache(fn, picfillen, dameth, effect, &cachead); + if (cachefil >= 0 && !gloadtile_cached(cachefil, &cachead, &doalloc, pth)) { + tsizx = cachead.xdim; + tsizy = cachead.ydim; + hasalpha = (cachead.flags & 2) ? 0 : 255; + kclose(cachefil); + //kclose(filh); // FIXME: uncomment when cache1d.c is fixed + // cachefil >= 0, so it won't be rewritten + } else { + if (cachefil >= 0) kclose(cachefil); + cachefil = -1; // the compressed version will be saved to disk + + if ((filh = kopen4load(fn, 0)) < 0) return -1; + + picfil = (char *)malloc(picfillen); if (!picfil) { kclose(filh); return 1; } + kread(filh, picfil, picfillen); + kclose(filh); + + // tsizx/y = replacement texture's natural size + // xsiz/y = 2^x size of replacement + + kpgetdim(picfil,picfillen,&tsizx,&tsizy); + if (tsizx == 0 || tsizy == 0) { free(picfil); return -1; } + pth->sizx = tsizx; + pth->sizy = tsizy; + + if (!glinfo.texnpot) { + for(xsiz=1;xsiz tsizx) //Copy left to right + { + long *lptr = (long *)pic; + for(y=0;y tsizy) //Copy top to bottom + memcpy(&pic[xsiz*tsizy],pic,(ysiz-tsizy)*xsiz<<2); + } + if (!glinfo.bgra) { + for(j=xsiz*ysiz-1;j>=0;j--) { + swapchar(&pic[j].r, &pic[j].b); + } + } else texfmt = GL_BGRA; + free(picfil); picfil = 0; + + if (glinfo.texcompr && glusetexcompr && !(hicr->flags & 1)) + intexfmt = (hasalpha == 255) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB; + else if (hasalpha == 255) intexfmt = GL_RGB; + + if ((doalloc&3)==1) bglGenTextures(1,(GLuint*)&pth->glpic); //# of textures (make OpenGL allocate structure) + bglBindTexture(GL_TEXTURE_2D,pth->glpic); + + fixtransparency(pic,tsizx,tsizy,xsiz,ysiz,dameth); + uploadtexture(doalloc,xsiz,ysiz,intexfmt,texfmt,pic,-1,tsizy,dameth); + } + + // precalculate scaling parameters for replacement + if (facen > 0) { + pth->scalex = ((float)tsizx) / 64.0; + pth->scaley = ((float)tsizy) / 64.0; + } else { + pth->scalex = ((float)tsizx) / ((float)tilesizx[dapic]); + pth->scaley = ((float)tsizy) / ((float)tilesizy[dapic]); + } + + if (gltexfiltermode < 0) gltexfiltermode = 0; + else if (gltexfiltermode >= (long)numglfiltermodes) gltexfiltermode = numglfiltermodes-1; + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min); + + if (glinfo.maxanisotropy > 1.0) + { + if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy) glanisotropy = (long)glinfo.maxanisotropy; + bglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy); + } + + if (!(dameth&4)) + { + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + } + else + { //For sprite textures, clamping looks better than wrapping + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); + } + + if (pic) free(pic); + + pth->picnum = dapic; + pth->effects = effect; + pth->flags = ((dameth&4)>>2) + 2 + ((facen>0)<<2); if (hasalpha != 255) pth->flags |= 8; + pth->skyface = facen; + pth->hicr = hicr; + + if (cachefil < 0) { + // save off the compressed version + cachead.xdim = tsizx; + cachead.ydim = tsizy; + x = 0; + for (j=0;j<31;j++) { + if (xsiz == pow2long[j]) { x |= 1; } + if (ysiz == pow2long[j]) { x |= 2; } + } + cachead.flags = (x!=3) | (hasalpha != 255 ? 2 : 0); + writexcache(fn, picfillen, dameth, effect, &cachead); + } + + return 0; +} + +#endif + + //(dpx,dpy) specifies an n-sided polygon. The polygon must be a convex clockwise loop. + // n must be <= 8 (assume clipping can double number of vertices) + //method: 0:solid, 1:masked(255 is transparent), 2:transluscent #1, 3:transluscent #2 + // +4 means it's a sprite, so wraparound isn't needed +static long pow2xsplit = 0, skyclamphack = 0; + +void drawpoly (double *dpx, double *dpy, long n, long method) +{ + #define PI 3.14159265358979323 + double ngdx = 0.0, ngdy = 0.0, ngdo = 0.0, ngux = 0.0, nguy = 0.0, nguo = 0.0; + double ngvx = 0.0, ngvy = 0.0, ngvo = 0.0, dp, up, vp, rdp, du0 = 0.0, du1 = 0.0, dui, duj; + double ngdx2, ngux2, ngvx2; + double f, r, ox, oy, oz, ox2, oy2, oz2, dd[16], uu[16], vv[16], px[16], py[16], uoffs; + long i, j, k, x, y, z, nn, ix0, ix1, mini, maxi, tsizx, tsizy, tsizxm1 = 0, tsizym1 = 0, ltsizy = 0; + long xx, yy, xi, d0, u0, v0, d1, u1, v1, xmodnice = 0, ymulnice = 0, dorot; + char dacol = 0, *walptr, *palptr = NULL, *vidp, *vide; +#ifdef USE_OPENGL + pthtyp *pth; +#endif + + if (method == -1) return; + + if (n == 3) + { + if ((dpx[0]-dpx[1])*(dpy[2]-dpy[1]) >= (dpx[2]-dpx[1])*(dpy[0]-dpy[1])) return; //for triangle + } + else + { + f = 0; //f is area of polygon / 2 + for(i=n-2,j=n-1,k=0;k= MAXTILES) globalpicnum = 0; + setgotpic(globalpicnum); + tsizx = tilesizx[globalpicnum]; + tsizy = tilesizy[globalpicnum]; + if (!palookup[globalpal]) globalpal = 0; + if (!waloff[globalpicnum]) + { + loadtile(globalpicnum); + if (!waloff[globalpicnum]) + { + if (rendmode != 3) return; + tsizx = tsizy = 1; method = 1; //Hack to update Z-buffer for invalid mirror textures + } + } + walptr = (char *)waloff[globalpicnum]; + + j = 0; dorot = ((gchang != 1.0) || (gctang != 1.0)); + if (dorot) + { + for(i=0;i= 3) && (px[j-1] == px[0]) && (py[j-1] == py[0])) j--; + if (j < 3) return; + n = j; + +#ifdef USE_OPENGL + if (rendmode == 3) + { + float hackscx, hackscy; + + if (skyclamphack) method |= 4; + pth = gltexcache(globalpicnum,globalpal,method&(~3)); + bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0); + + if (pth && (pth->flags & 2)) + { + hackscx = pth->scalex; + hackscy = pth->scaley; + tsizx = pth->sizx; + tsizy = pth->sizy; + } + else { hackscx = 1.0; hackscy = 1.0; } + + if (!glinfo.texnpot) { + for(xx=1;xxhicr && pth->hicr->alphacut >= 0.0) al = pth->hicr->alphacut; + if (alphahackarray[globalpicnum]) + al=alphahackarray[globalpicnum]; + if (!waloff[globalpicnum]) al = 0.0; // invalid textures ignore the alpha cutoff settings + bglEnable(GL_BLEND); + bglEnable(GL_ALPHA_TEST); + bglAlphaFunc(GL_GREATER,al); + } + + if (!dorot) + { + for(i=n-1;i>=0;i--) + { + dd[i] = px[i]*gdx + py[i]*gdy + gdo; + uu[i] = px[i]*gux + py[i]*guy + guo; + vv[i] = px[i]*gvx + py[i]*gvy + gvo; + } + } + + { + float pc[4]; + f = ((float)(numpalookups-min(max(globalshade,0),numpalookups)))/((float)numpalookups); + pc[0] = pc[1] = pc[2] = f; + switch(method&3) + { + case 0: pc[3] = 1.0; break; + case 1: pc[3] = 1.0; break; + case 2: pc[3] = 0.66; break; + case 3: pc[3] = 0.33; break; + } + // tinting happens only to hightile textures, and only if the texture we're + // rendering isn't for the same palette as what we asked for + if (pth && (pth->flags & 2) && (pth->palnum != globalpal)) { + // apply tinting for replaced textures + pc[0] *= (float)hictinting[globalpal].r / 255.0; + pc[1] *= (float)hictinting[globalpal].g / 255.0; + pc[2] *= (float)hictinting[globalpal].b / 255.0; + } + bglColor4f(pc[0],pc[1],pc[2],pc[3]); + } + + //Hack for walls&masked walls which use textures that are not a power of 2 + if ((pow2xsplit) && (tsizx != xx)) + { + if (!dorot) + { + ngdx = gdx; ngdy = gdy; ngdo = gdo+(ngdx+ngdy)*.5; + ngux = gux; nguy = guy; nguo = guo+(ngux+nguy)*.5; + ngvx = gvx; ngvy = gvy; ngvo = gvo+(ngvx+ngvy)*.5; + } + else + { + ox = py[1]-py[2]; oy = py[2]-py[0]; oz = py[0]-py[1]; + r = 1.0 / (ox*px[0] + oy*px[1] + oz*px[2]); + ngdx = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + ngux = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + ngvx = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + ox = px[2]-px[1]; oy = px[0]-px[2]; oz = px[1]-px[0]; + ngdy = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + nguy = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + ngvy = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + ox = px[0]-.5; oy = py[0]-.5; //.5 centers texture nicely + ngdo = dd[0] - ox*ngdx - oy*ngdy; + nguo = uu[0] - ox*ngux - oy*nguy; + ngvo = vv[0] - ox*ngvx - oy*ngvy; + } + + ngux *= hackscx; nguy *= hackscx; nguo *= hackscx; + ngvx *= hackscy; ngvy *= hackscy; ngvo *= hackscy; + uoffs = ((double)(xx-tsizx)*.5); + ngux -= ngdx*uoffs; + nguy -= ngdy*uoffs; + nguo -= ngdo*uoffs; + + //Find min&max u coordinates (du0...du1) + for(i=0;i du1) du1 = f; + } + + f = 1.0/(double)tsizx; + ix0 = (long)floor(du0*f); + ix1 = (long)floor(du1*f); + for(;ix0<=ix1;ix0++) + { + du0 = (double)((ix0 )*tsizx); // + uoffs; + du1 = (double)((ix0+1)*tsizx); // + uoffs; + + i = 0; nn = 0; + duj = (px[i]*ngux + py[i]*nguy + nguo) / (px[i]*ngdx + py[i]*ngdy + ngdo); + do + { + j = i+1; if (j == n) j = 0; + + dui = duj; duj = (px[j]*ngux + py[j]*nguy + nguo) / (px[j]*ngdx + py[j]*ngdy + ngdo); + + if ((du0 <= dui) && (dui <= du1)) { uu[nn] = px[i]; vv[nn] = py[i]; nn++; } + if (duj <= dui) + { + if ((du1 < duj) != (du1 < dui)) + { + //ox*(ngux-ngdx*du1) + oy*(nguy-ngdy*du1) + (nguo-ngdo*du1) = 0 + //(px[j]-px[i])*f + px[i] = ox + //(py[j]-py[i])*f + py[i] = oy + + ///Solve for f + //((px[j]-px[i])*f + px[i])*(ngux-ngdx*du1) + + //((py[j]-py[i])*f + py[i])*(nguy-ngdy*du1) + (nguo-ngdo*du1) = 0 + + f = -( px[i] *(ngux-ngdx*du1) + py[i] *(nguy-ngdy*du1) + (nguo-ngdo*du1)) / + ((px[j]-px[i])*(ngux-ngdx*du1) + (py[j]-py[i])*(nguy-ngdy*du1)); + uu[nn] = (px[j]-px[i])*f + px[i]; + vv[nn] = (py[j]-py[i])*f + py[i]; nn++; + } + if ((du0 < duj) != (du0 < dui)) + { + f = -( px[i] *(ngux-ngdx*du0) + py[i] *(nguy-ngdy*du0) + (nguo-ngdo*du0)) / + ((px[j]-px[i])*(ngux-ngdx*du0) + (py[j]-py[i])*(nguy-ngdy*du0)); + uu[nn] = (px[j]-px[i])*f + px[i]; + vv[nn] = (py[j]-py[i])*f + py[i]; nn++; + } + } + else + { + if ((du0 < duj) != (du0 < dui)) + { + f = -( px[i] *(ngux-ngdx*du0) + py[i] *(nguy-ngdy*du0) + (nguo-ngdo*du0)) / + ((px[j]-px[i])*(ngux-ngdx*du0) + (py[j]-py[i])*(nguy-ngdy*du0)); + uu[nn] = (px[j]-px[i])*f + px[i]; + vv[nn] = (py[j]-py[i])*f + py[i]; nn++; + } + if ((du1 < duj) != (du1 < dui)) + { + f = -( px[i] *(ngux-ngdx*du1) + py[i] *(nguy-ngdy*du1) + (nguo-ngdo*du1)) / + ((px[j]-px[i])*(ngux-ngdx*du1) + (py[j]-py[i])*(nguy-ngdy*du1)); + uu[nn] = (px[j]-px[i])*f + px[i]; + vv[nn] = (py[j]-py[i])*f + py[i]; nn++; + } + } + i = j; + } while (i); + if (nn < 3) continue; + + bglBegin(GL_TRIANGLE_FAN); + for(i=0;i>4); + } + else + { + dacol = palookup[0][(long)(*(char *)(waloff[globalpicnum]))+(min(max(globalshade,0),numpalookups-1)<<8)]; + } + + if (grhalfxdown10x < 0) //Hack for mirrors + { + for(i=((n-1)>>1);i>=0;i--) + { + r = px[i]; px[i] = ((double)xdimen)-px[n-1-i]; px[n-1-i] = ((double)xdimen)-r; + r = py[i]; py[i] = py[n-1-i]; py[n-1-i] = r; + } + ngdo += ((double)xdimen)*ngdx; ngdx = -ngdx; + nguo += ((double)xdimen)*ngux; ngux = -ngux; + ngvo += ((double)xdimen)*ngvx; ngvx = -ngvx; + } + + ngdx2 = ngdx*(1<= py[1]); maxi = 1-mini; + for(z=2;z py[maxi]) maxi = z; + } + + i = maxi; dtol(py[i],&yy); if (yy > ydimen) yy = ydimen; + do + { + j = i+1; if (j == n) j = 0; + dtol(py[j],&y); if (y < 0) y = 0; + if (y < yy) + { + f = (px[j]-px[i])/(py[j]-py[i]); dtol(f*16384.0,&xi); + dtol((((double)yy-.5-py[j])*f + px[j])*16384.0+8192.0,&x); + for(;yy>y;yy--,x-=xi) lastx[yy-1] = (x>>14); + } + i = j; + } while (i != mini); + do + { + j = i+1; if (j == n) j = 0; + dtol(py[j],&yy); if (yy > ydimen) yy = ydimen; + if (y < yy) + { + f = (px[j]-px[i])/(py[j]-py[i]); dtol(f*16384.0,&xi); + dtol((((double)y+.5-py[j])*f + px[j])*16384.0+8192.0,&x); + for(;y>14); if (ix1 > xdimen) ix1 = xdimen; + if (ix0 < ix1) + { + if (rendmode == 1) + memset((void *)(ylookup[y]+ix0+frameoffset),dacol,ix1-ix0); + else + { + vidp = (char *)(ylookup[y]+frameoffset+ix0); + dp = ngdx*(double)ix0 + ngdy*(double)y + ngdo; + up = ngux*(double)ix0 + nguy*(double)y + nguo; + vp = ngvx*(double)ix0 + ngvy*(double)y + ngvo; + rdp = 65536.0/dp; dp += ngdx2; + dtol( rdp,&d0); + dtol(up*rdp,&u0); up += ngux2; + dtol(vp*rdp,&v0); vp += ngvx2; + rdp = 65536.0/dp; + + switch (method&3) + { + case 0: + if (xmodnice&ymulnice) //both u&v texture sizes are powers of 2 :) + { + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16)&tsizxm1)<>16)&tsizym1)]]; //+((d0>>13)&0x3f00)]; +#else + vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + } + else + { + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16,tsizx)*tsizy + ((v0>>16)&tsizym1)]]; //+((d0>>13)&0x3f00)]; +#else + vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + } + break; + case 1: + if (xmodnice) //both u&v texture sizes are powers of 2 :) + { + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16)&tsizxm1)*tsizy) + ((v0>>16)&tsizym1)]; +#if (DEPTHDEBUG == 0) +#if (USEZBUFFER != 0) + if ((dacol != 255) && (d0 <= zbufoff[(long)vidp])) + { + zbufoff[(long)vidp] = d0; + vidp[0] = palptr[((long)dacol)]; //+((d0>>13)&0x3f00)]; + } +#else + if (dacol != 255) vidp[0] = palptr[((long)dacol)]; //+((d0>>13)&0x3f00)]; +#endif +#else + if ((dacol != 255) && (vidp[0] > (d0>>16))) vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + } + else + { + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16,tsizx)*tsizy + ((v0>>16)&tsizym1)]; +#if (DEPTHDEBUG == 0) +#if (USEZBUFFER != 0) + if ((dacol != 255) && (d0 <= zbufoff[(long)vidp])) + { + zbufoff[(long)vidp] = d0; + vidp[0] = palptr[((long)dacol)]; //+((d0>>13)&0x3f00)]; + } +#else + if (dacol != 255) vidp[0] = palptr[((long)dacol)]; //+((d0>>13)&0x3f00)]; +#endif +#else + if ((dacol != 255) && (vidp[0] > (d0>>16))) vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + } + break; + case 2: //Transluscence #1 + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16,tsizx)*tsizy + ((v0>>16)&tsizym1)]; + //dacol = walptr[(((u0>>16)&tsizxm1)<>16)&tsizym1)]; +#if (DEPTHDEBUG == 0) +#if (USEZBUFFER != 0) + if ((dacol != 255) && (d0 <= zbufoff[(long)vidp])) + { + zbufoff[(long)vidp] = d0; + vidp[0] = transluc[(((long)vidp[0])<<8)+((long)palptr[((long)dacol)])]; //+((d0>>13)&0x3f00)])]; + } +#else + if (dacol != 255) + vidp[0] = transluc[(((long)vidp[0])<<8)+((long)palptr[((long)dacol)])]; //+((d0>>13)&0x3f00)])]; +#endif +#else + if ((dacol != 255) && (vidp[0] > (d0>>16))) vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + break; + case 3: //Transluscence #2 + for(xx=ix0;xx>LINTERPSIZ); + dtol(up*rdp,&u1); up += ngux2; u1 = ((u1-u0)>>LINTERPSIZ); + dtol(vp*rdp,&v1); vp += ngvx2; v1 = ((v1-v0)>>LINTERPSIZ); + rdp = 65536.0/dp; vide = &vidp[min(ix1-xx,1<>16,tsizx)*tsizy + ((v0>>16)&tsizym1)]; + //dacol = walptr[(((u0>>16)&tsizxm1)<>16)&tsizym1)]; +#if (DEPTHDEBUG == 0) +#if (USEZBUFFER != 0) + if ((dacol != 255) && (d0 <= zbufoff[(long)vidp])) + { + zbufoff[(long)vidp] = d0; + vidp[0] = transluc[((long)vidp[0])+(((long)palptr[((long)dacol)/*+((d0>>13)&0x3f00)*/])<<8)]; + } +#else + if (dacol != 255) + vidp[0] = transluc[((long)vidp[0])+(((long)palptr[((long)dacol)/*+((d0>>13)&0x3f00)*/])<<8)]; +#endif +#else + if ((dacol != 255) && (vidp[0] > (d0>>16))) vidp[0] = ((d0>>16)&255); +#endif + d0 += d1; u0 += u1; v0 += v1; vidp++; + } + } + break; + } + } + } + } + } + i = j; + } while (i != maxi); + + if (rendmode == 1) + { + if (method&3) //Only draw border around sprites/maskwalls + { + for(i=0,j=n-1;i=2;i--) if (px[i] < px[imin]) imin = i; + + + vsp[vcnt].x = px[imin]; + vsp[vcnt].cy[0] = vsp[vcnt].fy[0] = py[imin]; + vcnt++; + i = imin+1; if (i >= n) i = 0; + j = imin-1; if (j < 0) j = n-1; + do + { + if (px[i] < px[j]) + { + if ((vcnt > 1) && (px[i] <= vsp[vcnt-1].x)) vcnt--; + vsp[vcnt].x = px[i]; + vsp[vcnt].cy[0] = py[i]; + k = j+1; if (k >= n) k = 0; + //(px[k],py[k]) + //(px[i],?) + //(px[j],py[j]) + vsp[vcnt].fy[0] = (px[i]-px[k])*(py[j]-py[k])/(px[j]-px[k]) + py[k]; + vcnt++; + i++; if (i >= n) i = 0; + } + else if (px[j] < px[i]) + { + if ((vcnt > 1) && (px[j] <= vsp[vcnt-1].x)) vcnt--; + vsp[vcnt].x = px[j]; + vsp[vcnt].fy[0] = py[j]; + k = i-1; if (k < 0) k = n-1; + //(px[k],py[k]) + //(px[j],?) + //(px[i],py[i]) + vsp[vcnt].cy[0] = (px[j]-px[k])*(py[i]-py[k])/(px[i]-px[k]) + py[k]; + vcnt++; + j--; if (j < 0) j = n-1; + } + else + { + if ((vcnt > 1) && (px[i] <= vsp[vcnt-1].x)) vcnt--; + vsp[vcnt].x = px[i]; + vsp[vcnt].cy[0] = py[i]; + vsp[vcnt].fy[0] = py[j]; + vcnt++; + i++; if (i >= n) i = 0; if (i == j) break; + j--; if (j < 0) j = n-1; + } + } while (i != j); + if (px[i] > vsp[vcnt-1].x) + { + vsp[vcnt].x = px[i]; + vsp[vcnt].cy[0] = vsp[vcnt].fy[0] = py[i]; + vcnt++; + } + + + for(i=0;i= 0)) return(1); + } + return(0); +} + +static long domostpolymethod = 0; + +void domost (float x0, float y0, float x1, float y1) +{ + double dpx[4], dpy[4]; + float d, f, n, t, slop, dx, dx0, dx1, nx, nx0, ny0, nx1, ny1; + float spx[4], spy[4], cy[2], cv[2]; + long i, j, k, z, ni, vcnt = 0, scnt, newi, dir, spt[4]; + + if (x0 < x1) + { + dir = 1; //clip dmost (floor) + y0 -= .01; y1 -= .01; + } + else + { + if (x0 == x1) return; + f = x0; x0 = x1; x1 = f; + f = y0; y0 = y1; y1 = f; + dir = 0; //clip umost (ceiling) + //y0 += .01; y1 += .01; //necessary? + } + + slop = (y1-y0)/(x1-x0); + for(i=vsp[0].n;i;i=newi) + { + newi = vsp[i].n; nx0 = vsp[i].x; nx1 = vsp[newi].x; + if ((x0 >= nx1) || (nx0 >= x1) || (vsp[i].ctag <= 0)) continue; + dx = nx1-nx0; + cy[0] = vsp[i].cy[0]; cv[0] = vsp[i].cy[1]-cy[0]; + cy[1] = vsp[i].fy[0]; cv[1] = vsp[i].fy[1]-cy[1]; + + scnt = 0; + + //Test if left edge requires split (x0,y0) (nx0,cy(0)), + if ((x0 > nx0) && (x0 < nx1)) + { + t = (x0-nx0)*cv[dir] - (y0-cy[dir])*dx; + if (((!dir) && (t < 0)) || ((dir) && (t > 0))) + { spx[scnt] = x0; spy[scnt] = y0; spt[scnt] = -1; scnt++; } + } + + //Test for intersection on umost (j == 0) and dmost (j == 1) + for(j=0;j<2;j++) + { + d = (y0-y1)*dx - (x0-x1)*cv[j]; + n = (y0-cy[j])*dx - (x0-nx0)*cv[j]; + if ((fabs(n) <= fabs(d)) && (d*n >= 0) && (d != 0)) + { + t = n/d; nx = (x1-x0)*t + x0; + if ((nx > nx0) && (nx < nx1)) + { + spx[scnt] = nx; spy[scnt] = (y1-y0)*t + y0; + spt[scnt] = j; scnt++; + } + } + } + + //Nice hack to avoid full sort later :) + if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2])) + { + f = spx[scnt-1]; spx[scnt-1] = spx[scnt-2]; spx[scnt-2] = f; + f = spy[scnt-1]; spy[scnt-1] = spy[scnt-2]; spy[scnt-2] = f; + j = spt[scnt-1]; spt[scnt-1] = spt[scnt-2]; spt[scnt-2] = j; + } + + //Test if right edge requires split + if ((x1 > nx0) && (x1 < nx1)) + { + t = (x1-nx0)*cv[dir] - (y1-cy[dir])*dx; + if (((!dir) && (t < 0)) || ((dir) && (t > 0))) + { spx[scnt] = x1; spy[scnt] = y1; spt[scnt] = -1; scnt++; } + } + + vsp[i].tag = vsp[newi].tag = -1; + for(z=0;z<=scnt;z++,i=vcnt) + { + if (z < scnt) + { + vcnt = vsinsaft(i); + t = (spx[z]-nx0)/dx; + vsp[i].cy[1] = t*cv[0] + cy[0]; + vsp[i].fy[1] = t*cv[1] + cy[1]; + vsp[vcnt].x = spx[z]; + vsp[vcnt].cy[0] = vsp[i].cy[1]; + vsp[vcnt].fy[0] = vsp[i].fy[1]; + vsp[vcnt].tag = spt[z]; + } + + ni = vsp[i].n; if (!ni) continue; //this 'if' fixes many bugs! + dx0 = vsp[i].x; if (x0 > dx0) continue; + dx1 = vsp[ni].x; if (x1 < dx1) continue; + ny0 = (dx0-x0)*slop + y0; + ny1 = (dx1-x0)*slop + y0; + + // dx0 dx1 + // ~ ~ + //---------------------------- + // t0+=0 t1+=0 + // vsp[i].cy[0] vsp[i].cy[1] + //============================ + // t0+=1 t1+=3 + //============================ + // vsp[i].fy[0] vsp[i].fy[1] + // t0+=2 t1+=6 + // + // ny0 ? ny1 ? + + k = 1+3; + if ((vsp[i].tag == 0) || (ny0 <= vsp[i].cy[0]+.01)) k--; + if ((vsp[i].tag == 1) || (ny0 >= vsp[i].fy[0]-.01)) k++; + if ((vsp[ni].tag == 0) || (ny1 <= vsp[i].cy[1]+.01)) k -= 3; + if ((vsp[ni].tag == 1) || (ny1 >= vsp[i].fy[1]-.01)) k += 3; + + if (!dir) + { + switch(k) + { + case 1: case 2: + dpx[0] = dx0; dpy[0] = vsp[i].cy[0]; + dpx[1] = dx1; dpy[1] = vsp[i].cy[1]; + dpx[2] = dx0; dpy[2] = ny0; drawpoly(dpx,dpy,3,domostpolymethod); + vsp[i].cy[0] = ny0; vsp[i].ctag = gtag; break; + case 3: case 6: + dpx[0] = dx0; dpy[0] = vsp[i].cy[0]; + dpx[1] = dx1; dpy[1] = vsp[i].cy[1]; + dpx[2] = dx1; dpy[2] = ny1; drawpoly(dpx,dpy,3,domostpolymethod); + vsp[i].cy[1] = ny1; vsp[i].ctag = gtag; break; + case 4: case 5: case 7: + dpx[0] = dx0; dpy[0] = vsp[i].cy[0]; + dpx[1] = dx1; dpy[1] = vsp[i].cy[1]; + dpx[2] = dx1; dpy[2] = ny1; + dpx[3] = dx0; dpy[3] = ny0; drawpoly(dpx,dpy,4,domostpolymethod); + vsp[i].cy[0] = ny0; vsp[i].cy[1] = ny1; vsp[i].ctag = gtag; break; + case 8: + dpx[0] = dx0; dpy[0] = vsp[i].cy[0]; + dpx[1] = dx1; dpy[1] = vsp[i].cy[1]; + dpx[2] = dx1; dpy[2] = vsp[i].fy[1]; + dpx[3] = dx0; dpy[3] = vsp[i].fy[0]; drawpoly(dpx,dpy,4,domostpolymethod); + vsp[i].ctag = vsp[i].ftag = -1; break; + default: break; + } + } + else + { + switch(k) + { + case 7: case 6: + dpx[0] = dx0; dpy[0] = ny0; + dpx[1] = dx1; dpy[1] = vsp[i].fy[1]; + dpx[2] = dx0; dpy[2] = vsp[i].fy[0]; drawpoly(dpx,dpy,3,domostpolymethod); + vsp[i].fy[0] = ny0; vsp[i].ftag = gtag; break; + case 5: case 2: + dpx[0] = dx0; dpy[0] = vsp[i].fy[0]; + dpx[1] = dx1; dpy[1] = ny1; + dpx[2] = dx1; dpy[2] = vsp[i].fy[1]; drawpoly(dpx,dpy,3,domostpolymethod); + vsp[i].fy[1] = ny1; vsp[i].ftag = gtag; break; + case 4: case 3: case 1: + dpx[0] = dx0; dpy[0] = ny0; + dpx[1] = dx1; dpy[1] = ny1; + dpx[2] = dx1; dpy[2] = vsp[i].fy[1]; + dpx[3] = dx0; dpy[3] = vsp[i].fy[0]; drawpoly(dpx,dpy,4,domostpolymethod); + vsp[i].fy[0] = ny0; vsp[i].fy[1] = ny1; vsp[i].ftag = gtag; break; + case 0: + dpx[0] = dx0; dpy[0] = vsp[i].cy[0]; + dpx[1] = dx1; dpy[1] = vsp[i].cy[1]; + dpx[2] = dx1; dpy[2] = vsp[i].fy[1]; + dpx[3] = dx0; dpy[3] = vsp[i].fy[0]; drawpoly(dpx,dpy,4,domostpolymethod); + vsp[i].ctag = vsp[i].ftag = -1; break; + default: break; + } + } + } + } + + gtag++; + + //Combine neighboring vertical strips with matching collinear top&bottom edges + //This prevents x-splits from propagating through the entire scan + i = vsp[0].n; + while (i) + { + ni = vsp[i].n; + if ((vsp[i].cy[0] >= vsp[i].fy[0]) && (vsp[i].cy[1] >= vsp[i].fy[1])) { vsp[i].ctag = vsp[i].ftag = -1; } + if ((vsp[i].ctag == vsp[ni].ctag) && (vsp[i].ftag == vsp[ni].ftag)) + { vsp[i].cy[1] = vsp[ni].cy[1]; vsp[i].fy[1] = vsp[ni].fy[1]; vsdel(ni); } + else i = ni; + } +} + +static void polymost_scansector (long sectnum); + +static void polymost_drawalls (long bunch) +{ + sectortype *sec, *nextsec; + walltype *wal, *wal2, *nwal; + double ox, oy, oz, ox2, oy2, px[3], py[3], dd[3], uu[3], vv[3]; + double fx, fy, x0, x1, y0, y1, cy0, cy1, fy0, fy1, xp0, yp0, xp1, yp1, ryp0, ryp1, nx0, ny0, nx1, ny1; + double t, r, t0, t1, ocy0, ocy1, ofy0, ofy1, oxp0, oyp0, ft[4]; + double oguo, ogux, oguy; + long i, x, y, z, cz, fz, wallnum, sectnum, nextsectnum; + + sectnum = thesector[bunchfirst[bunch]]; sec = §or[sectnum]; + +#ifdef USE_OPENGL + if (!nofog) { + if (rendmode == 3) { + float col[4]; + col[0] = (float)palookupfog[sec->floorpal].r / 63.f; + col[1] = (float)palookupfog[sec->floorpal].g / 63.f; + col[2] = (float)palookupfog[sec->floorpal].b / 63.f; + col[3] = 0; + bglFogfv(GL_FOG_COLOR,col); + bglFogf(GL_FOG_DENSITY,gvisibility*((float)((unsigned char)(sec->visibility+16)))); + } + } +#endif + + //DRAW WALLS SECTION! + for(z=bunchfirst[bunch];z>=0;z=p2[z]) + { + wallnum = thewall[z]; wal = &wall[wallnum]; wal2 = &wall[wal->point2]; + nextsectnum = wal->nextsector; nextsec = §or[nextsectnum]; + + //Offset&Rotate 3D coordinates to screen 3D space + x = wal->x-globalposx; y = wal->y-globalposy; + xp0 = (double)y*gcosang - (double)x*gsinang; + yp0 = (double)x*gcosang2 + (double)y*gsinang2; + x = wal2->x-globalposx; y = wal2->y-globalposy; + xp1 = (double)y*gcosang - (double)x*gsinang; + yp1 = (double)x*gcosang2 + (double)y*gsinang2; + + oxp0 = xp0; oyp0 = yp0; + + //Clip to close parallel-screen plane + if (yp0 < SCISDIST) + { + if (yp1 < SCISDIST) continue; + t0 = (SCISDIST-yp0)/(yp1-yp0); xp0 = (xp1-xp0)*t0+xp0; yp0 = SCISDIST; + nx0 = (wal2->x-wal->x)*t0+wal->x; + ny0 = (wal2->y-wal->y)*t0+wal->y; + } + else { t0 = 0.f; nx0 = wal->x; ny0 = wal->y; } + if (yp1 < SCISDIST) + { + t1 = (SCISDIST-oyp0)/(yp1-oyp0); xp1 = (xp1-oxp0)*t1+oxp0; yp1 = SCISDIST; + nx1 = (wal2->x-wal->x)*t1+wal->x; + ny1 = (wal2->y-wal->y)*t1+wal->y; + } + else { t1 = 1.f; nx1 = wal2->x; ny1 = wal2->y; } + + ryp0 = 1.f/yp0; ryp1 = 1.f/yp1; + + //Generate screen coordinates for front side of wall + x0 = ghalfx*xp0*ryp0 + ghalfx; + x1 = ghalfx*xp1*ryp1 + ghalfx; + if (x1 <= x0) continue; + + ryp0 *= gyxscale; ryp1 *= gyxscale; + + getzsofslope(sectnum,(long)nx0,(long)ny0,&cz,&fz); + cy0 = ((float)(cz-globalposz))*ryp0 + ghoriz; + fy0 = ((float)(fz-globalposz))*ryp0 + ghoriz; + getzsofslope(sectnum,(long)nx1,(long)ny1,&cz,&fz); + cy1 = ((float)(cz-globalposz))*ryp1 + ghoriz; + fy1 = ((float)(fz-globalposz))*ryp1 + ghoriz; + + + globalpicnum = sec->floorpicnum; globalshade = sec->floorshade; globalpal = (long)((unsigned char)sec->floorpal); + globalorientation = sec->floorstat; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,sectnum); + if (!(globalorientation&1)) + { + //(singlobalang/-16384*(sx-ghalfx) + 0*(sy-ghoriz) + (cosviewingrangeglobalang/16384)*ghalfx)*d + globalposx = u*16 + //(cosglobalang/ 16384*(sx-ghalfx) + 0*(sy-ghoriz) + (sinviewingrangeglobalang/16384)*ghalfx)*d + globalposy = v*16 + //( 0*(sx-ghalfx) + 1*(sy-ghoriz) + ( 0)*ghalfx)*d + globalposz/16 = (sec->floorz/16) + if (!(globalorientation&64)) + { ft[0] = globalposx; ft[1] = globalposy; ft[2] = cosglobalang; ft[3] = singlobalang; } + else + { + //relative alignment + fx = (double)(wall[wall[sec->wallptr].point2].x-wall[sec->wallptr].x); + fy = (double)(wall[wall[sec->wallptr].point2].y-wall[sec->wallptr].y); + r = 1.0/sqrt(fx*fx+fy*fy); fx *= r; fy *= r; + ft[2] = cosglobalang*fx + singlobalang*fy; + ft[3] = singlobalang*fx - cosglobalang*fy; + ft[0] = ((double)(globalposx-wall[sec->wallptr].x))*fx + ((double)(globalposy-wall[sec->wallptr].y))*fy; + ft[1] = ((double)(globalposy-wall[sec->wallptr].y))*fx - ((double)(globalposx-wall[sec->wallptr].x))*fy; + if (!(globalorientation&4)) globalorientation ^= 32; else globalorientation ^= 16; + } + gdx = 0; + gdy = gxyaspect; if (!(globalorientation&2)) gdy /= (double)(sec->floorz-globalposz); + gdo = -ghoriz*gdy; + if (globalorientation&8) { ft[0] /= 8; ft[1] /= -8; ft[2] /= 2097152; ft[3] /= 2097152; } + else { ft[0] /= 16; ft[1] /= -16; ft[2] /= 4194304; ft[3] /= 4194304; } + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + + //Texture flipping + if (globalorientation&4) + { + r = gux; gux = gvx; gvx = r; + r = guy; guy = gvy; gvy = r; + r = guo; guo = gvo; gvo = r; + } + if (globalorientation&16) { gux = -gux; guy = -guy; guo = -guo; } + if (globalorientation&32) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } + + //Texture panning + fx = (float)sec->floorxpanning*((float)(1<<(picsiz[globalpicnum]&15)))/256.0; + fy = (float)sec->floorypanning*((float)(1<<(picsiz[globalpicnum]>>4)))/256.0; + if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment + { + r = (float)sec->floorheinum / 4096.0; r = 1.0/sqrt(r*r+1); + if (!(globalorientation&4)) fy *= r; else fx *= r; + } + guy += gdy*fx; guo += gdo*fx; + gvy += gdy*fy; gvo += gdo*fy; + + if (globalorientation&2) //slopes + { + px[0] = x0; py[0] = ryp0 + ghoriz; + px[1] = x1; py[1] = ryp1 + ghoriz; + + //Pick some point guaranteed to be not collinear to the 1st two points + ox = nx0 + (ny1-ny0); + oy = ny0 + (nx0-nx1); + ox2 = (double)(oy-globalposy)*gcosang - (double)(ox-globalposx)*gsinang; + oy2 = (double)(ox-globalposx)*gcosang2 + (double)(oy-globalposy)*gsinang2; + oy2 = 1.0/oy2; + px[2] = ghalfx*ox2*oy2 + ghalfx; oy2 *= gyxscale; + py[2] = oy2 + ghoriz; + + for(i=0;i<3;i++) + { + dd[i] = px[i]*gdx + py[i]*gdy + gdo; + uu[i] = px[i]*gux + py[i]*guy + guo; + vv[i] = px[i]*gvx + py[i]*gvy + gvo; + } + + py[0] = fy0; + py[1] = fy1; + py[2] = (getflorzofslope(sectnum,(long)ox,(long)oy)-globalposz)*oy2 + ghoriz; + + ox = py[1]-py[2]; oy = py[2]-py[0]; oz = py[0]-py[1]; + r = 1.0 / (ox*px[0] + oy*px[1] + oz*px[2]); + gdx = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + gux = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + gvx = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + ox = px[2]-px[1]; oy = px[0]-px[2]; oz = px[1]-px[0]; + gdy = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + guy = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + gvy = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + gdo = dd[0] - px[0]*gdx - py[0]*gdy; + guo = uu[0] - px[0]*gux - py[0]*guy; + gvo = vv[0] - px[0]*gvx - py[0]*gvy; + + if (globalorientation&64) //Hack for relative alignment on slopes + { + r = (float)sec->floorheinum / 4096.0; + r = sqrt(r*r+1); + if (!(globalorientation&4)) { gvx *= r; gvy *= r; gvo *= r; } + else { gux *= r; guy *= r; guo *= r; } + } + } + domostpolymethod = (globalorientation>>7)&3; + if (globalposz >= getflorzofslope(sectnum,globalposx,globalposy)) domostpolymethod = -1; //Back-face culling + pow2xsplit = 0; domost(x0,fy0,x1,fy1); //flor + domostpolymethod = 0; + } + else if ((nextsectnum < 0) || (!(sector[nextsectnum].floorstat&1))) + { + //Parallaxing sky... hacked for Ken's mountain texture; paper-sky only :/ +#ifdef USE_OPENGL + if (rendmode == 3) + { + if (!nofog) { + bglDisable(GL_FOG); + //r = ((float)globalpisibility)*((float)((unsigned char)(sec->visibility+16)))*FOGSCALE; + //r *= ((double)xdimscale*(double)viewingrange*gdo) / (65536.0*65536.0); + //bglFogf(GL_FOG_DENSITY,r); + } + + //Use clamping for tiled sky textures + for(i=(1<0;i--) + if (pskyoff[i] != pskyoff[i-1]) + { skyclamphack = 1; break; } + } +#endif + if (bpp == 8 || !usehightile || !hicfindsubst(globalpicnum,globalpal,1)) + { + dd[0] = (float)xdimen*.0000001; //Adjust sky depth based on screen size! + t = (double)((1<<(picsiz[globalpicnum]&15))<>1)+parallaxyoffs)) - vv[1]*ghoriz; + i = (1<<(picsiz[globalpicnum]>>4)); if (i != tilesizy[globalpicnum]) i += i; + vv[0] += dd[0]*((double)sec->floorypanning)*((double)i)/256.0; + + + //Hack to draw black rectangle below sky when looking down... + gdx = 0; gdy = gxyaspect / 262144.0; gdo = -ghoriz*gdy; + gux = 0; guy = 0; guo = 0; + gvx = 0; gvy = (double)(tilesizy[globalpicnum]-1)*gdy; gvo = (double)(tilesizy[globalpicnum-1])*gdo; + oy = (((double)tilesizy[globalpicnum])*dd[0]-vv[0])/vv[1]; + if ((oy > fy0) && (oy > fy1)) domost(x0,oy,x1,oy); + else if ((oy > fy0) != (oy > fy1)) + { // fy0 fy1 + // \ / + //oy---------- oy---------- + // \ / + // fy1 fy0 + ox = (oy-fy0)*(x1-x0)/(fy1-fy0) + x0; + if (oy > fy0) { domost(x0,oy,ox,oy); domost(ox,oy,x1,fy1); } + else { domost(x0,fy0,ox,oy); domost(ox,oy,x1,oy); } + } else domost(x0,fy0,x1,fy1); + + + gdx = 0; gdy = 0; gdo = dd[0]; + gux = gdo*(t*((double)xdimscale)*((double)yxaspect)*((double)viewingrange))/(16384.0*65536.0*65536.0*5.0*1024.0); + guy = 0; //guo calculated later + gvx = 0; gvy = vv[1]; gvo = vv[0]; + + i = globalpicnum; r = (fy1-fy0)/(x1-x0); //slope of line + oy = ((double)viewingrange)/(ghalfx*256.0); oz = 1/oy; + + y = ((((long)((x0-ghalfx)*oy))+globalang)>>(11-pskybits)); + fx = x0; + do + { + globalpicnum = pskyoff[y&((1<floorxpanning) - gux*ghalfx; + y++; + ox = fx; fx = ((double)((y<<(11-pskybits))-globalang))*oz+ghalfx; + if (fx > x1) { fx = x1; i = -1; } + + pow2xsplit = 0; domost(ox,(ox-x0)*r+fy0,fx,(fx-x0)*r+fy0); //flor + } while (i >= 0); + + } + else //NOTE: code copied from ceiling code... lots of duplicated stuff :/ + { //Skybox code for parallax ceiling! + double _xp0, _yp0, _xp1, _yp1, _oxp0, _oyp0, _t0, _t1, _nx0, _ny0, _nx1, _ny1; + double _ryp0, _ryp1, _x0, _x1, _cy0, _fy0, _cy1, _fy1, _ox0, _ox1; + double nfy0, nfy1; + long skywalx[4] = {-512,512,512,-512}, skywaly[4] = {-512,-512,512,512}; + + pow2xsplit = 0; + skyclamphack = 1; + + for(i=0;i<4;i++) + { + x = skywalx[i&3]; y = skywaly[i&3]; + _xp0 = (double)y*gcosang - (double)x*gsinang; + _yp0 = (double)x*gcosang2 + (double)y*gsinang2; + x = skywalx[(i+1)&3]; y = skywaly[(i+1)&3]; + _xp1 = (double)y*gcosang - (double)x*gsinang; + _yp1 = (double)x*gcosang2 + (double)y*gsinang2; + + _oxp0 = _xp0; _oyp0 = _yp0; + + //Clip to close parallel-screen plane + if (_yp0 < SCISDIST) + { + if (_yp1 < SCISDIST) continue; + _t0 = (SCISDIST-_yp0)/(_yp1-_yp0); _xp0 = (_xp1-_xp0)*_t0+_xp0; _yp0 = SCISDIST; + _nx0 = (skywalx[(i+1)&3]-skywalx[i&3])*_t0+skywalx[i&3]; + _ny0 = (skywaly[(i+1)&3]-skywaly[i&3])*_t0+skywaly[i&3]; + } + else { _t0 = 0.f; _nx0 = skywalx[i&3]; _ny0 = skywaly[i&3]; } + if (_yp1 < SCISDIST) + { + _t1 = (SCISDIST-_oyp0)/(_yp1-_oyp0); _xp1 = (_xp1-_oxp0)*_t1+_oxp0; _yp1 = SCISDIST; + _nx1 = (skywalx[(i+1)&3]-skywalx[i&3])*_t1+skywalx[i&3]; + _ny1 = (skywaly[(i+1)&3]-skywaly[i&3])*_t1+skywaly[i&3]; + } + else { _t1 = 1.f; _nx1 = skywalx[(i+1)&3]; _ny1 = skywaly[(i+1)&3]; } + + _ryp0 = 1.f/_yp0; _ryp1 = 1.f/_yp1; + + //Generate screen coordinates for front side of wall + _x0 = ghalfx*_xp0*_ryp0 + ghalfx; + _x1 = ghalfx*_xp1*_ryp1 + ghalfx; + if (_x1 <= _x0) continue; + if ((_x0 >= x1) || (x0 >= _x1)) continue; + + _ryp0 *= gyxscale; _ryp1 *= gyxscale; + + _cy0 = -8192.f*_ryp0 + ghoriz; + _fy0 = 8192.f*_ryp0 + ghoriz; + _cy1 = -8192.f*_ryp1 + ghoriz; + _fy1 = 8192.f*_ryp1 + ghoriz; + + _ox0 = _x0; _ox1 = _x1; + + //Make sure: x0<=_x0<_x1<=_x1 + nfy0 = fy0; nfy1 = fy1; + if (_x0 < x0) + { + t = (x0-_x0)/(_x1-_x0); + _cy0 += (_cy1-_cy0)*t; + _fy0 += (_fy1-_fy0)*t; + _x0 = x0; + } + else if (_x0 > x0) nfy0 += (_x0-x0)*(fy1-fy0)/(x1-x0); + if (_x1 > x1) + { + t = (x1-_x1)/(_x1-_x0); + _cy1 += (_cy1-_cy0)*t; + _fy1 += (_fy1-_fy0)*t; + _x1 = x1; + } + else if (_x1 < x1) nfy1 += (_x1-x1)*(fy1-fy0)/(x1-x0); + + // (skybox floor) + //(_x0,_fy0)-(_x1,_fy1) + // (skybox wall) + //(_x0,_cy0)-(_x1,_cy1) + // (skybox ceiling) + //(_x0,nfy0)-(_x1,nfy1) + + //ceiling of skybox + ft[0] = 512/16; ft[1] = 512/-16; + ft[2] = ((float)cosglobalang)*(1.f/2147483648.f); + ft[3] = ((float)singlobalang)*(1.f/2147483648.f); + gdx = 0; + gdy = gxyaspect*(1.f/4194304.f); + gdo = -ghoriz*gdy; + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + gvx = -gvx; gvy = -gvy; gvo = -gvo; //y-flip skybox floor +#ifdef USE_OPENGL + drawingskybox = 6; //ceiling/5th texture/index 4 of skybox +#endif + if ((_fy0 > nfy0) && (_fy1 > nfy1)) domost(_x0,_fy0,_x1,_fy1); + else if ((_fy0 > nfy0) != (_fy1 > nfy1)) + { + //(ox,oy) is intersection of: (_x0,_cy0)-(_x1,_cy1) + // (_x0,nfy0)-(_x1,nfy1) + //ox = _x0 + (_x1-_x0)*t + //oy = _cy0 + (_cy1-_cy0)*t + //oy = nfy0 + (nfy1-nfy0)*t + t = (_fy0-nfy0)/(nfy1-nfy0-_fy1+_fy0); + ox = _x0 + (_x1-_x0)*t; + oy = _fy0 + (_fy1-_fy0)*t; + if (nfy0 > _fy0) { domost(_x0,nfy0,ox,oy); domost(ox,oy,_x1,_fy1); } + else { domost(_x0,_fy0,ox,oy); domost(ox,oy,_x1,nfy1); } + } else domost(_x0,nfy0,_x1,nfy1); + + //wall of skybox +#ifdef USE_OPENGL + drawingskybox = i+1; //i+1th texture/index i of skybox +#endif + gdx = (_ryp0-_ryp1)*gxyaspect*(1.f/512.f) / (_ox0-_ox1); + gdy = 0; + gdo = _ryp0*gxyaspect*(1.f/512.f) - gdx*_ox0; + gux = (_t0*_ryp0 - _t1*_ryp1)*gxyaspect*(64.f/512.f) / (_ox0-_ox1); + guo = _t0*_ryp0*gxyaspect*(64.f/512.f) - gux*_ox0; + guy = 0; + _t0 = -8192.0*_ryp0 + ghoriz; + _t1 = -8192.0*_ryp1 + ghoriz; + t = ((gdx*_ox0 + gdo)*8.f) / ((_ox1-_ox0) * _ryp0 * 2048.f); + gvx = (_t0-_t1)*t; + gvy = (_ox1-_ox0)*t; + gvo = -gvx*_ox0 - gvy*_t0; + if ((_cy0 > nfy0) && (_cy1 > nfy1)) domost(_x0,_cy0,_x1,_cy1); + else if ((_cy0 > nfy0) != (_cy1 > nfy1)) + { + //(ox,oy) is intersection of: (_x0,_fy0)-(_x1,_fy1) + // (_x0,nfy0)-(_x1,nfy1) + //ox = _x0 + (_x1-_x0)*t + //oy = _fy0 + (_fy1-_fy0)*t + //oy = nfy0 + (nfy1-nfy0)*t + t = (_cy0-nfy0)/(nfy1-nfy0-_cy1+_cy0); + ox = _x0 + (_x1-_x0)*t; + oy = _cy0 + (_cy1-_cy0)*t; + if (nfy0 > _cy0) { domost(_x0,nfy0,ox,oy); domost(ox,oy,_x1,_cy1); } + else { domost(_x0,_cy0,ox,oy); domost(ox,oy,_x1,nfy1); } + } else domost(_x0,nfy0,_x1,nfy1); + } + + //Floor of skybox +#ifdef USE_OPENGL + drawingskybox = 5; //floor/6th texture/index 5 of skybox +#endif + ft[0] = 512/16; ft[1] = -512/-16; + ft[2] = ((float)cosglobalang)*(1.f/2147483648.f); + ft[3] = ((float)singlobalang)*(1.f/2147483648.f); + gdx = 0; + gdy = gxyaspect*(-1.f/4194304.f); + gdo = -ghoriz*gdy; + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + domost(x0,fy0,x1,fy1); + + skyclamphack = 0; +#ifdef USE_OPENGL + drawingskybox = 0; +#endif + } +#ifdef USE_OPENGL + if (rendmode == 3) + { + skyclamphack = 0; + if (!nofog) { + bglEnable(GL_FOG); + //bglFogf(GL_FOG_DENSITY,gvisibility*((float)((unsigned char)(sec->visibility+16)))); + } + } +#endif + } + + globalpicnum = sec->ceilingpicnum; globalshade = sec->ceilingshade; globalpal = (long)((unsigned char)sec->ceilingpal); + globalorientation = sec->ceilingstat; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,sectnum); + if (!(globalorientation&1)) + { + if (!(globalorientation&64)) + { ft[0] = globalposx; ft[1] = globalposy; ft[2] = cosglobalang; ft[3] = singlobalang; } + else + { + //relative alignment + fx = (double)(wall[wall[sec->wallptr].point2].x-wall[sec->wallptr].x); + fy = (double)(wall[wall[sec->wallptr].point2].y-wall[sec->wallptr].y); + r = 1.0/sqrt(fx*fx+fy*fy); fx *= r; fy *= r; + ft[2] = cosglobalang*fx + singlobalang*fy; + ft[3] = singlobalang*fx - cosglobalang*fy; + ft[0] = ((double)(globalposx-wall[sec->wallptr].x))*fx + ((double)(globalposy-wall[sec->wallptr].y))*fy; + ft[1] = ((double)(globalposy-wall[sec->wallptr].y))*fx - ((double)(globalposx-wall[sec->wallptr].x))*fy; + if (!(globalorientation&4)) globalorientation ^= 32; else globalorientation ^= 16; + } + gdx = 0; + gdy = gxyaspect; + if (!(globalorientation&2)) gdy /= (double)(sec->ceilingz-globalposz); + gdo = -ghoriz*gdy; + if (globalorientation&8) { ft[0] /= 8; ft[1] /= -8; ft[2] /= 2097152; ft[3] /= 2097152; } + else { ft[0] /= 16; ft[1] /= -16; ft[2] /= 4194304; ft[3] /= 4194304; } + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + + //Texture flipping + if (globalorientation&4) + { + r = gux; gux = gvx; gvx = r; + r = guy; guy = gvy; gvy = r; + r = guo; guo = gvo; gvo = r; + } + if (globalorientation&16) { gux = -gux; guy = -guy; guo = -guo; } + if (globalorientation&32) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } + + //Texture panning + fx = (float)sec->ceilingxpanning*((float)(1<<(picsiz[globalpicnum]&15)))/256.0; + fy = (float)sec->ceilingypanning*((float)(1<<(picsiz[globalpicnum]>>4)))/256.0; + if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment + { + r = (float)sec->ceilingheinum / 4096.0; r = 1.0/sqrt(r*r+1); + if (!(globalorientation&4)) fy *= r; else fx *= r; + } + guy += gdy*fx; guo += gdo*fx; + gvy += gdy*fy; gvo += gdo*fy; + + if (globalorientation&2) //slopes + { + px[0] = x0; py[0] = ryp0 + ghoriz; + px[1] = x1; py[1] = ryp1 + ghoriz; + + //Pick some point guaranteed to be not collinear to the 1st two points + ox = nx0 + (ny1-ny0); + oy = ny0 + (nx0-nx1); + ox2 = (double)(oy-globalposy)*gcosang - (double)(ox-globalposx)*gsinang ; + oy2 = (double)(ox-globalposx)*gcosang2 + (double)(oy-globalposy)*gsinang2; + oy2 = 1.0/oy2; + px[2] = ghalfx*ox2*oy2 + ghalfx; oy2 *= gyxscale; + py[2] = oy2 + ghoriz; + + for(i=0;i<3;i++) + { + dd[i] = px[i]*gdx + py[i]*gdy + gdo; + uu[i] = px[i]*gux + py[i]*guy + guo; + vv[i] = px[i]*gvx + py[i]*gvy + gvo; + } + + py[0] = cy0; + py[1] = cy1; + py[2] = (getceilzofslope(sectnum,(long)ox,(long)oy)-globalposz)*oy2 + ghoriz; + + ox = py[1]-py[2]; oy = py[2]-py[0]; oz = py[0]-py[1]; + r = 1.0 / (ox*px[0] + oy*px[1] + oz*px[2]); + gdx = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + gux = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + gvx = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + ox = px[2]-px[1]; oy = px[0]-px[2]; oz = px[1]-px[0]; + gdy = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; + guy = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; + gvy = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; + gdo = dd[0] - px[0]*gdx - py[0]*gdy; + guo = uu[0] - px[0]*gux - py[0]*guy; + gvo = vv[0] - px[0]*gvx - py[0]*gvy; + + if (globalorientation&64) //Hack for relative alignment on slopes + { + r = (float)sec->ceilingheinum / 4096.0; + r = sqrt(r*r+1); + if (!(globalorientation&4)) { gvx *= r; gvy *= r; gvo *= r; } + else { gux *= r; guy *= r; guo *= r; } + } + } + domostpolymethod = (globalorientation>>7)&3; + if (globalposz <= getceilzofslope(sectnum,globalposx,globalposy)) domostpolymethod = -1; //Back-face culling + pow2xsplit = 0; domost(x1,cy1,x0,cy0); //ceil + domostpolymethod = 0; + } + else if ((nextsectnum < 0) || (!(sector[nextsectnum].ceilingstat&1))) + { +#ifdef USE_OPENGL + if (rendmode == 3) + { + if (!nofog) { + bglDisable(GL_FOG); + //r = ((float)globalpisibility)*((float)((unsigned char)(sec->visibility+16)))*FOGSCALE; + //r *= ((double)xdimscale*(double)viewingrange*gdo) / (65536.0*65536.0); + //bglFogf(GL_FOG_DENSITY,r); + } + + //Use clamping for tiled sky textures + for(i=(1<0;i--) + if (pskyoff[i] != pskyoff[i-1]) + { skyclamphack = 1; break; } + } +#endif + //Parallaxing sky... + if (bpp == 8 || !usehightile || !hicfindsubst(globalpicnum,globalpal,1)) + { + //Render for parallaxtype == 0 / paper-sky + dd[0] = (float)xdimen*.0000001; //Adjust sky depth based on screen size! + t = (double)((1<<(picsiz[globalpicnum]&15))<>1)+parallaxyoffs)) - vv[1]*ghoriz; + i = (1<<(picsiz[globalpicnum]>>4)); if (i != tilesizy[globalpicnum]) i += i; + vv[0] += dd[0]*((double)sec->ceilingypanning)*((double)i)/256.0; + + //Hack to draw black rectangle below sky when looking down... + gdx = 0; gdy = gxyaspect / -262144.0; gdo = -ghoriz*gdy; + gux = 0; guy = 0; guo = 0; + gvx = 0; gvy = 0; gvo = 0; + oy = -vv[0]/vv[1]; + if ((oy < cy0) && (oy < cy1)) domost(x1,oy,x0,oy); + else if ((oy < cy0) != (oy < cy1)) + { /* cy1 cy0 + // / \ + //oy---------- oy--------- + // / \ + // cy0 cy1 + */ + ox = (oy-cy0)*(x1-x0)/(cy1-cy0) + x0; + if (oy < cy0) { domost(ox,oy,x0,oy); domost(x1,cy1,ox,oy); } + else { domost(ox,oy,x0,cy0); domost(x1,oy,ox,oy); } + } else domost(x1,cy1,x0,cy0); + + gdx = 0; gdy = 0; gdo = dd[0]; + gux = gdo*(t*((double)xdimscale)*((double)yxaspect)*((double)viewingrange))/(16384.0*65536.0*65536.0*5.0*1024.0); + guy = 0; //guo calculated later + gvx = 0; gvy = vv[1]; gvo = vv[0]; + + i = globalpicnum; r = (cy1-cy0)/(x1-x0); //slope of line + oy = ((double)viewingrange)/(ghalfx*256.0); oz = 1/oy; + + y = ((((long)((x0-ghalfx)*oy))+globalang)>>(11-pskybits)); + fx = x0; + do + { + globalpicnum = pskyoff[y&((1<ceilingxpanning) - gux*ghalfx; + y++; + ox = fx; fx = ((double)((y<<(11-pskybits))-globalang))*oz+ghalfx; + if (fx > x1) { fx = x1; i = -1; } + pow2xsplit = 0; domost(fx,(fx-x0)*r+cy0,ox,(ox-x0)*r+cy0); //ceil + } while (i >= 0); + } + else + { //Skybox code for parallax ceiling! + double _xp0, _yp0, _xp1, _yp1, _oxp0, _oyp0, _t0, _t1, _nx0, _ny0, _nx1, _ny1; + double _ryp0, _ryp1, _x0, _x1, _cy0, _fy0, _cy1, _fy1, _ox0, _ox1; + double ncy0, ncy1; + long skywalx[4] = {-512,512,512,-512}, skywaly[4] = {-512,-512,512,512}; + + pow2xsplit = 0; + skyclamphack = 1; + + for(i=0;i<4;i++) + { + x = skywalx[i&3]; y = skywaly[i&3]; + _xp0 = (double)y*gcosang - (double)x*gsinang; + _yp0 = (double)x*gcosang2 + (double)y*gsinang2; + x = skywalx[(i+1)&3]; y = skywaly[(i+1)&3]; + _xp1 = (double)y*gcosang - (double)x*gsinang; + _yp1 = (double)x*gcosang2 + (double)y*gsinang2; + + _oxp0 = _xp0; _oyp0 = _yp0; + + //Clip to close parallel-screen plane + if (_yp0 < SCISDIST) + { + if (_yp1 < SCISDIST) continue; + _t0 = (SCISDIST-_yp0)/(_yp1-_yp0); _xp0 = (_xp1-_xp0)*_t0+_xp0; _yp0 = SCISDIST; + _nx0 = (skywalx[(i+1)&3]-skywalx[i&3])*_t0+skywalx[i&3]; + _ny0 = (skywaly[(i+1)&3]-skywaly[i&3])*_t0+skywaly[i&3]; + } + else { _t0 = 0.f; _nx0 = skywalx[i&3]; _ny0 = skywaly[i&3]; } + if (_yp1 < SCISDIST) + { + _t1 = (SCISDIST-_oyp0)/(_yp1-_oyp0); _xp1 = (_xp1-_oxp0)*_t1+_oxp0; _yp1 = SCISDIST; + _nx1 = (skywalx[(i+1)&3]-skywalx[i&3])*_t1+skywalx[i&3]; + _ny1 = (skywaly[(i+1)&3]-skywaly[i&3])*_t1+skywaly[i&3]; + } + else { _t1 = 1.f; _nx1 = skywalx[(i+1)&3]; _ny1 = skywaly[(i+1)&3]; } + + _ryp0 = 1.f/_yp0; _ryp1 = 1.f/_yp1; + + //Generate screen coordinates for front side of wall + _x0 = ghalfx*_xp0*_ryp0 + ghalfx; + _x1 = ghalfx*_xp1*_ryp1 + ghalfx; + if (_x1 <= _x0) continue; + if ((_x0 >= x1) || (x0 >= _x1)) continue; + + _ryp0 *= gyxscale; _ryp1 *= gyxscale; + + _cy0 = -8192.f*_ryp0 + ghoriz; + _fy0 = 8192.f*_ryp0 + ghoriz; + _cy1 = -8192.f*_ryp1 + ghoriz; + _fy1 = 8192.f*_ryp1 + ghoriz; + + _ox0 = _x0; _ox1 = _x1; + + //Make sure: x0<=_x0<_x1<=_x1 + ncy0 = cy0; ncy1 = cy1; + if (_x0 < x0) + { + t = (x0-_x0)/(_x1-_x0); + _cy0 += (_cy1-_cy0)*t; + _fy0 += (_fy1-_fy0)*t; + _x0 = x0; + } + else if (_x0 > x0) ncy0 += (_x0-x0)*(cy1-cy0)/(x1-x0); + if (_x1 > x1) + { + t = (x1-_x1)/(_x1-_x0); + _cy1 += (_cy1-_cy0)*t; + _fy1 += (_fy1-_fy0)*t; + _x1 = x1; + } + else if (_x1 < x1) ncy1 += (_x1-x1)*(cy1-cy0)/(x1-x0); + + // (skybox ceiling) + //(_x0,_cy0)-(_x1,_cy1) + // (skybox wall) + //(_x0,_fy0)-(_x1,_fy1) + // (skybox floor) + //(_x0,ncy0)-(_x1,ncy1) + + //ceiling of skybox +#ifdef USE_OPENGL + drawingskybox = 5; //ceiling/5th texture/index 4 of skybox +#endif + ft[0] = 512/16; ft[1] = -512/-16; + ft[2] = ((float)cosglobalang)*(1.f/2147483648.f); + ft[3] = ((float)singlobalang)*(1.f/2147483648.f); + gdx = 0; + gdy = gxyaspect*-(1.f/4194304.f); + gdo = -ghoriz*gdy; + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + if ((_cy0 < ncy0) && (_cy1 < ncy1)) domost(_x1,_cy1,_x0,_cy0); + else if ((_cy0 < ncy0) != (_cy1 < ncy1)) + { + //(ox,oy) is intersection of: (_x0,_cy0)-(_x1,_cy1) + // (_x0,ncy0)-(_x1,ncy1) + //ox = _x0 + (_x1-_x0)*t + //oy = _cy0 + (_cy1-_cy0)*t + //oy = ncy0 + (ncy1-ncy0)*t + t = (_cy0-ncy0)/(ncy1-ncy0-_cy1+_cy0); + ox = _x0 + (_x1-_x0)*t; + oy = _cy0 + (_cy1-_cy0)*t; + if (ncy0 < _cy0) { domost(ox,oy,_x0,ncy0); domost(_x1,_cy1,ox,oy); } + else { domost(ox,oy,_x0,_cy0); domost(_x1,ncy1,ox,oy); } + } else domost(_x1,ncy1,_x0,ncy0); + + //wall of skybox +#ifdef USE_OPENGL + drawingskybox = i+1; //i+1th texture/index i of skybox +#endif + gdx = (_ryp0-_ryp1)*gxyaspect*(1.f/512.f) / (_ox0-_ox1); + gdy = 0; + gdo = _ryp0*gxyaspect*(1.f/512.f) - gdx*_ox0; + gux = (_t0*_ryp0 - _t1*_ryp1)*gxyaspect*(64.f/512.f) / (_ox0-_ox1); + guo = _t0*_ryp0*gxyaspect*(64.f/512.f) - gux*_ox0; + guy = 0; + _t0 = -8192.0*_ryp0 + ghoriz; + _t1 = -8192.0*_ryp1 + ghoriz; + t = ((gdx*_ox0 + gdo)*8.f) / ((_ox1-_ox0) * _ryp0 * 2048.f); + gvx = (_t0-_t1)*t; + gvy = (_ox1-_ox0)*t; + gvo = -gvx*_ox0 - gvy*_t0; + if ((_fy0 < ncy0) && (_fy1 < ncy1)) domost(_x1,_fy1,_x0,_fy0); + else if ((_fy0 < ncy0) != (_fy1 < ncy1)) + { + //(ox,oy) is intersection of: (_x0,_fy0)-(_x1,_fy1) + // (_x0,ncy0)-(_x1,ncy1) + //ox = _x0 + (_x1-_x0)*t + //oy = _fy0 + (_fy1-_fy0)*t + //oy = ncy0 + (ncy1-ncy0)*t + t = (_fy0-ncy0)/(ncy1-ncy0-_fy1+_fy0); + ox = _x0 + (_x1-_x0)*t; + oy = _fy0 + (_fy1-_fy0)*t; + if (ncy0 < _fy0) { domost(ox,oy,_x0,ncy0); domost(_x1,_fy1,ox,oy); } + else { domost(ox,oy,_x0,_fy0); domost(_x1,ncy1,ox,oy); } + } else domost(_x1,ncy1,_x0,ncy0); + } + + //Floor of skybox +#ifdef USE_OPENGL + drawingskybox = 6; //floor/6th texture/index 5 of skybox +#endif + ft[0] = 512/16; ft[1] = 512/-16; + ft[2] = ((float)cosglobalang)*(1.f/2147483648.f); + ft[3] = ((float)singlobalang)*(1.f/2147483648.f); + gdx = 0; + gdy = gxyaspect*(1.f/4194304.f); + gdo = -ghoriz*gdy; + gux = (double)ft[3]*((double)viewingrange)/-65536.0; + gvx = (double)ft[2]*((double)viewingrange)/-65536.0; + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]-gux)*ghalfx; + gvo -= (double)(ft[3]+gvx)*ghalfx; + gvx = -gvx; gvy = -gvy; gvo = -gvo; //y-flip skybox floor + domost(x1,cy1,x0,cy0); + + skyclamphack = 0; +#ifdef USE_OPENGL + drawingskybox = 0; +#endif + } +#ifdef USE_OPENGL + if (rendmode == 3) + { + skyclamphack = 0; + if (!nofog) { + bglEnable(GL_FOG); + //bglFogf(GL_FOG_DENSITY,gvisibility*((float)((unsigned char)(sec->visibility+16)))); + } + } +#endif + } + + //(x0,cy0) == (u= 0,v=0,d=) + //(x1,cy0) == (u=wal->xrepeat*8,v=0) + //(x0,fy0) == (u= 0,v=v) + // u = (gux*sx + guy*sy + guo) / (gdx*sx + gdy*sy + gdo) + // v = (gvx*sx + gvy*sy + gvo) / (gdx*sx + gdy*sy + gdo) + // 0 = (gux*x0 + guy*cy0 + guo) / (gdx*x0 + gdy*cy0 + gdo) + //wal->xrepeat*8 = (gux*x1 + guy*cy0 + guo) / (gdx*x1 + gdy*cy0 + gdo) + // 0 = (gvx*x0 + gvy*cy0 + gvo) / (gdx*x0 + gdy*cy0 + gdo) + // v = (gvx*x0 + gvy*fy0 + gvo) / (gdx*x0 + gdy*fy0 + gdo) + //sx = x0, u = t0*wal->xrepeat*8, d = yp0; + //sx = x1, u = t1*wal->xrepeat*8, d = yp1; + //d = gdx*sx + gdo + //u = (gux*sx + guo) / (gdx*sx + gdo) + //yp0 = gdx*x0 + gdo + //yp1 = gdx*x1 + gdo + //t0*wal->xrepeat*8 = (gux*x0 + guo) / (gdx*x0 + gdo) + //t1*wal->xrepeat*8 = (gux*x1 + guo) / (gdx*x1 + gdo) + //gdx*x0 + gdo = yp0 + //gdx*x1 + gdo = yp1 + gdx = (ryp0-ryp1)*gxyaspect / (x0-x1); + gdy = 0; + gdo = ryp0*gxyaspect - gdx*x0; + + //gux*x0 + guo = t0*wal->xrepeat*8*yp0 + //gux*x1 + guo = t1*wal->xrepeat*8*yp1 + gux = (t0*ryp0 - t1*ryp1)*gxyaspect*(float)wal->xrepeat*8.f / (x0-x1); + guo = t0*ryp0*gxyaspect*(float)wal->xrepeat*8.f - gux*x0; + guo += (float)wal->xpanning*gdo; + gux += (float)wal->xpanning*gdx; + guy = 0; + //Derivation for u: + // (gvx*x0 + gvy*cy0 + gvo) / (gdx*x0 + gdy*cy0 + gdo) = 0 + // (gvx*x1 + gvy*cy1 + gvo) / (gdx*x1 + gdy*cy1 + gdo) = 0 + // (gvx*x0 + gvy*fy0 + gvo) / (gdx*x0 + gdy*fy0 + gdo) = v + // (gvx*x1 + gvy*fy1 + gvo) / (gdx*x1 + gdy*fy1 + gdo) = v + // (gvx*x0 + gvy*cy0 + gvo*1) = 0 + // (gvx*x1 + gvy*cy1 + gvo*1) = 0 + // (gvx*x0 + gvy*fy0 + gvo*1) = t + ogux = gux; oguy = guy; oguo = guo; + + if (nextsectnum >= 0) + { + getzsofslope(nextsectnum,(long)nx0,(long)ny0,&cz,&fz); + ocy0 = ((float)(cz-globalposz))*ryp0 + ghoriz; + ofy0 = ((float)(fz-globalposz))*ryp0 + ghoriz; + getzsofslope(nextsectnum,(long)nx1,(long)ny1,&cz,&fz); + ocy1 = ((float)(cz-globalposz))*ryp1 + ghoriz; + ofy1 = ((float)(fz-globalposz))*ryp1 + ghoriz; + + if ((wal->cstat&48) == 16) maskwall[maskwallcnt++] = z; + + if (((cy0 < ocy0) || (cy1 < ocy1)) && (!((sec->ceilingstat§or[nextsectnum].ceilingstat)&1))) + { + globalpicnum = wal->picnum; globalshade = wal->shade; globalpal = (long)((unsigned char)wal->pal); + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,wallnum+16384); + + if (!(wal->cstat&4)) i = sector[nextsectnum].ceilingz; else i = sec->ceilingz; + t0 = ((float)(i-globalposz))*ryp0 + ghoriz; + t1 = ((float)(i-globalposz))*ryp1 + ghoriz; + t = ((gdx*x0 + gdo) * (float)wal->yrepeat) / ((x1-x0) * ryp0 * 2048.f); + i = (1<<(picsiz[globalpicnum]>>4)); if (i < tilesizy[globalpicnum]) i <<= 1; + fy = (float)wal->ypanning * ((float)i) / 256.0; + gvx = (t0-t1)*t; + gvy = (x1-x0)*t; + gvo = -gvx*x0 - gvy*t0 + fy*gdo; gvx += fy*gdx; gvy += fy*gdy; + + if (wal->cstat&8) //xflip + { + t = (float)(wal->xrepeat*8 + wal->xpanning*2); + gux = gdx*t - gux; + guy = gdy*t - guy; + guo = gdo*t - guo; + } + if (wal->cstat&256) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } //yflip + + pow2xsplit = 1; domost(x1,ocy1,x0,ocy0); + + if (wal->cstat&8) { gux = ogux; guy = oguy; guo = oguo; } + } + if (((ofy0 < fy0) || (ofy1 < fy1)) && (!((sec->floorstat§or[nextsectnum].floorstat)&1))) + { + if (!(wal->cstat&2)) nwal = wal; + else + { + nwal = &wall[wal->nextwall]; + guo += (float)(nwal->xpanning-wal->xpanning)*gdo; + gux += (float)(nwal->xpanning-wal->xpanning)*gdx; + guy += (float)(nwal->xpanning-wal->xpanning)*gdy; + } + globalpicnum = nwal->picnum; globalshade = nwal->shade; globalpal = (long)((unsigned char)nwal->pal); + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,wallnum+16384); + + if (!(nwal->cstat&4)) i = sector[nextsectnum].floorz; else i = sec->ceilingz; + t0 = ((float)(i-globalposz))*ryp0 + ghoriz; + t1 = ((float)(i-globalposz))*ryp1 + ghoriz; + t = ((gdx*x0 + gdo) * (float)wal->yrepeat) / ((x1-x0) * ryp0 * 2048.f); + i = (1<<(picsiz[globalpicnum]>>4)); if (i < tilesizy[globalpicnum]) i <<= 1; + fy = (float)nwal->ypanning * ((float)i) / 256.0; + gvx = (t0-t1)*t; + gvy = (x1-x0)*t; + gvo = -gvx*x0 - gvy*t0 + fy*gdo; gvx += fy*gdx; gvy += fy*gdy; + + if (wal->cstat&8) //xflip + { + t = (float)(wal->xrepeat*8 + nwal->xpanning*2); + gux = gdx*t - gux; + guy = gdy*t - guy; + guo = gdo*t - guo; + } + if (nwal->cstat&256) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } //yflip + + pow2xsplit = 1; domost(x0,ofy0,x1,ofy1); + + if (wal->cstat&(2+8)) { guo = oguo; gux = ogux; guy = oguy; } + } + } + + if ((nextsectnum < 0) || (wal->cstat&32)) //White/1-way wall + { + if (nextsectnum < 0) globalpicnum = wal->picnum; else globalpicnum = wal->overpicnum; + globalshade = wal->shade; globalpal = (long)((unsigned char)wal->pal); + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,wallnum+16384); + + if (nextsectnum >= 0) { if (!(wal->cstat&4)) i = nextsec->ceilingz; else i = sec->ceilingz; } + else { if (!(wal->cstat&4)) i = sec->ceilingz; else i = sec->floorz; } + t0 = ((float)(i-globalposz))*ryp0 + ghoriz; + t1 = ((float)(i-globalposz))*ryp1 + ghoriz; + t = ((gdx*x0 + gdo) * (float)wal->yrepeat) / ((x1-x0) * ryp0 * 2048.f); + i = (1<<(picsiz[globalpicnum]>>4)); if (i < tilesizy[globalpicnum]) i <<= 1; + fy = (float)wal->ypanning * ((float)i) / 256.0; + gvx = (t0-t1)*t; + gvy = (x1-x0)*t; + gvo = -gvx*x0 - gvy*t0 + fy*gdo; gvx += fy*gdx; gvy += fy*gdy; + + if (wal->cstat&8) //xflip + { + t = (float)(wal->xrepeat*8 + wal->xpanning*2); + gux = gdx*t - gux; + guy = gdy*t - guy; + guo = gdo*t - guo; + } + if (wal->cstat&256) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } //yflip + pow2xsplit = 1; domost(x0,-10000,x1,-10000); + } + + if (nextsectnum >= 0) + if ((!(gotsector[nextsectnum>>3]&pow2char[nextsectnum&7])) && (testvisiblemost(x0,x1))) + polymost_scansector(nextsectnum); + } +} + +static long wallfront(long, long); +static long polymost_bunchfront (long b1, long b2) +{ + double x1b1, x1b2, x2b1, x2b2; + long b1f, b2f, i; + + b1f = bunchfirst[b1]; x1b1 = dxb1[b1f]; x2b2 = dxb2[bunchlast[b2]]; if (x1b1 >= x2b2) return(-1); + b2f = bunchfirst[b2]; x1b2 = dxb1[b2f]; x2b1 = dxb2[bunchlast[b1]]; if (x1b2 >= x2b1) return(-1); + + if (x1b1 >= x1b2) + { + for(i=b2f;dxb2[i]<=x1b1;i=p2[i]); + return(wallfront(b1f,i)); + } + for(i=b1f;dxb2[i]<=x1b2;i=p2[i]); + return(wallfront(i,b2f)); +} + +static void polymost_scansector (long sectnum) +{ + double d, xp1, yp1, xp2, yp2; + walltype *wal, *wal2; + spritetype *spr; + long z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst, nextsectnum; + long xs, ys, x1, y1, x2, y2; + + if (sectnum < 0) return; + if (automapping) show2dsector[sectnum>>3] |= pow2char[sectnum&7]; + + sectorborder[0] = sectnum, sectorbordercnt = 1; + do + { + sectnum = sectorborder[--sectorbordercnt]; + + for(z=headspritesect[sectnum];z>=0;z=nextspritesect[z]) + { + spr = &sprite[z]; + if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) && + (spr->xrepeat > 0) && (spr->yrepeat > 0) && + (spritesortcnt < MAXSPRITESONSCREEN)) + { + xs = spr->x-globalposx; ys = spr->y-globalposy; + if ((spr->cstat&48) || (xs*gcosang+ys*gsinang > 0)) + { + copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); + tsprite[spritesortcnt++].owner = z; + } + } + } + + gotsector[sectnum>>3] |= pow2char[sectnum&7]; + + bunchfrst = numbunches; + numscansbefore = numscans; + + startwall = sector[sectnum].wallptr; endwall = sector[sectnum].wallnum+startwall; + scanfirst = numscans; + xp2 = 0; yp2 = 0; + for(z=startwall,wal=&wall[z];zpoint2]; + x1 = wal->x-globalposx; y1 = wal->y-globalposy; + x2 = wal2->x-globalposx; y2 = wal2->y-globalposy; + + nextsectnum = wal->nextsector; //Scan close sectors + if ((nextsectnum >= 0) && (!(wal->cstat&32)) && (!(gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]))) + { + d = (double)x1*(double)y2 - (double)x2*(double)y1; xp1 = (double)(x2-x1); yp1 = (double)(y2-y1); + if (d*d <= (xp1*xp1 + yp1*yp1)*(SCISDIST*SCISDIST*260.0)) + sectorborder[sectorbordercnt++] = nextsectnum; + } + + if ((z == startwall) || (wall[z-1].point2 != z)) + { + xp1 = ((double)y1*(double)cosglobalang - (double)x1*(double)singlobalang )/64.0; + yp1 = ((double)x1*(double)cosviewingrangeglobalang + (double)y1*(double)sinviewingrangeglobalang)/64.0; + } + else { xp1 = xp2; yp1 = yp2; } + xp2 = ((double)y2*(double)cosglobalang - (double)x2*(double)singlobalang )/64.0; + yp2 = ((double)x2*(double)cosviewingrangeglobalang + (double)y2*(double)sinviewingrangeglobalang)/64.0; + if ((yp1 >= SCISDIST) || (yp2 >= SCISDIST)) + if ((double)xp1*(double)yp2 < (double)xp2*(double)yp1) //if wall is facing you... + { + if (yp1 >= SCISDIST) + dxb1[numscans] = (double)xp1*ghalfx/(double)yp1 + ghalfx; + else dxb1[numscans] = -1e32; + + if (yp2 >= SCISDIST) + dxb2[numscans] = (double)xp2*ghalfx/(double)yp2 + ghalfx; + else dxb2[numscans] = 1e32; + + if (dxb1[numscans] < dxb2[numscans]) + { thesector[numscans] = sectnum; thewall[numscans] = z; p2[numscans] = numscans+1; numscans++; } + } + + if ((wall[z].point2 < z) && (scanfirst < numscans)) + { p2[numscans-1] = scanfirst; scanfirst = numscans; } + } + + for(z=numscansbefore;z dxb1[p2[z]])) + { bunchfirst[numbunches++] = p2[z]; p2[z] = -1; } + + for(z=bunchfrst;z=0;zz=p2[zz]); + bunchlast[z] = zz; + } + } while (sectorbordercnt > 0); +} + +void polymost_drawrooms () +{ + long i, j, k, n, n2, closest; + double ox, oy, oz, ox2, oy2, oz2, r, px[6], py[6], pz[6], px2[6], py2[6], pz2[6], sx[6], sy[6]; + + if (!rendmode) return; + + begindrawing(); + frameoffset = frameplace + windowy1*bytesperline + windowx1; + +#ifdef USE_OPENGL + if (rendmode == 3) + { + resizeglcheck(); + + //bglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + bglEnable(GL_TEXTURE_2D); + //bglTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); //default anyway + bglEnable(GL_DEPTH_TEST); + bglDepthFunc(GL_ALWAYS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + + //bglPolygonOffset(1,1); //Supposed to make sprites pasted on walls or floors not disappear + bglDepthRange(0.00001,1.0); //<- this is more widely supported than glPolygonOffset + + //Enable this for OpenGL red-blue glasses mode :) + if (glredbluemode) + { + float m[4][4]; + static int grbfcnt = 0; grbfcnt++; + if (redblueclearcnt < numpages) { redblueclearcnt++; bglColorMask(1,1,1,1); bglClear(GL_COLOR_BUFFER_BIT); } + if (grbfcnt&1) + { + bglViewport(windowx1-16,yres-(windowy2+1),windowx2-(windowx1-16)+1,windowy2-windowy1+1); + bglColorMask(1,0,0,1); + globalposx += singlobalang/1024; + globalposy -= cosglobalang/1024; + } + else + { + bglViewport(windowx1,yres-(windowy2+1),windowx2+16-windowx1+1,windowy2-windowy1+1); + bglColorMask(0,1,1,1); + globalposx -= singlobalang/1024; + globalposy += cosglobalang/1024; + } + } + } +#endif + + //Polymost supports true look up/down :) Here, we convert horizon to angle. + //gchang&gshang are cos&sin of this angle (respectively) + gyxscale = ((double)xdimenscale)/131072.0; + gxyaspect = ((double)xyaspect*(double)viewingrange)*(5.0/(65536.0*262144.0)); + gviewxrange = ((double)viewingrange)*((double)xdimen)/(32768.0*1024.0); + gcosang = ((double)cosglobalang)/262144.0; + gsinang = ((double)singlobalang)/262144.0; + gcosang2 = gcosang*((double)viewingrange)/65536.0; + gsinang2 = gsinang*((double)viewingrange)/65536.0; + ghalfx = (double)halfxdimen; grhalfxdown10 = 1.0/(((double)ghalfx)*1024); + ghoriz = (double)globalhoriz; + + gvisibility = ((float)globalvisibility)*gxyaspect*FOGSCALE; + + //global cos/sin height angle + r = (double)((ydimen>>1)-ghoriz); + gshang = r/sqrt(r*r+ghalfx*ghalfx); + gchang = sqrt(1.0-gshang*gshang); + ghoriz = (double)(ydimen>>1); + + //global cos/sin tilt angle + gctang = cos(gtang); + gstang = sin(gtang); + if (fabs(gstang) < .001) //This hack avoids nasty precision bugs in domost() + { gstang = 0; if (gctang > 0) gctang = 1.0; else gctang = -1.0; } + + if (inpreparemirror) + gstang = -gstang; + + //Generate viewport trapezoid (for handling screen up/down) + px[0] = px[3] = 0-1; px[1] = px[2] = windowx2+1-windowx1+2; + py[0] = py[1] = 0-1; py[2] = py[3] = windowy2+1-windowy1+2; n = 4; + for(i=0;i= n) j = 0; + if (pz[i] >= SCISDIST) { px2[n2] = px[i]; py2[n2] = py[i]; pz2[n2] = pz[i]; n2++; } + if ((pz[i] >= SCISDIST) != (pz[j] >= SCISDIST)) + { + r = (SCISDIST-pz[i])/(pz[j]-pz[i]); + px2[n2] = (px[j]-px[i])*r + px[i]; + py2[n2] = (py[j]-py[i])*r + py[i]; + pz2[n2] = SCISDIST; n2++; + } + } + if (n2 < 3) { enddrawing(); return; } + for(i=0;i>12,vy>>12,vz>>8,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,0xffff0030); + hitallsprites = 0; + + searchsector = hitsect; + if (hitwall >= 0) + { + searchwall = hitwall; searchstat = 0; + if (wall[hitwall].nextwall >= 0) + { + long cz, fz; + getzsofslope(wall[hitwall].nextsector,hitx,hity,&cz,&fz); + if (hitz > fz) + { + if (wall[hitwall].cstat&2) //'2' bottoms of walls + searchwall = wall[hitwall].nextwall; + } + else if ((hitz > cz) && (wall[hitwall].cstat&(16+32))) //masking or 1-way + searchstat = 4; + } + } + else if (hitsprite >= 0) { searchwall = hitsprite; searchstat = 3; } + else + { + long cz, fz; + getzsofslope(hitsect,hitx,hity,&cz,&fz); + if ((hitz<<1) < cz+fz) searchstat = 1; else searchstat = 2; + //if (vz < 0) searchstat = 1; else searchstat = 2; //Won't work for slopes :/ + } + searchit = 0; + } + + numscans = numbunches = 0; + + if (globalcursectnum >= MAXSECTORS) + globalcursectnum -= MAXSECTORS; + else + { + i = globalcursectnum; + updatesector(globalposx,globalposy,&globalcursectnum); + if (globalcursectnum < 0) globalcursectnum = i; + } + + polymost_scansector(globalcursectnum); + + if (inpreparemirror) + { + grhalfxdown10x = -grhalfxdown10; + inpreparemirror = 0; + polymost_drawalls(0); + numbunches--; + bunchfirst[0] = bunchfirst[numbunches]; + bunchlast[0] = bunchlast[numbunches]; + } + else + grhalfxdown10x = grhalfxdown10; + + while (numbunches > 0) + { + memset(tempbuf,0,numbunches+3); tempbuf[0] = 1; + + closest = 0; //Almost works, but not quite :( + for(i=1;ipoint2]; + sectnum = thesector[z]; sec = §or[sectnum]; + nsec = §or[wal->nextsector]; + z1 = max(nsec->ceilingz,sec->ceilingz); + z2 = min(nsec->floorz,sec->floorz); + + globalpicnum = wal->overpicnum; if ((unsigned long)globalpicnum >= MAXTILES) globalpicnum = 0; + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,(short)thewall[z]+16384); + globalshade = (long)wal->shade; + globalpal = (long)((unsigned char)wal->pal); + globalorientation = (long)wal->cstat; + + sx0 = (float)(wal->x-globalposx); sx1 = (float)(wal2->x-globalposx); + sy0 = (float)(wal->y-globalposy); sy1 = (float)(wal2->y-globalposy); + yp0 = sx0*gcosang2 + sy0*gsinang2; + yp1 = sx1*gcosang2 + sy1*gsinang2; + if ((yp0 < SCISDIST) && (yp1 < SCISDIST)) return; + xp0 = sy0*gcosang - sx0*gsinang; + xp1 = sy1*gcosang - sx1*gsinang; + + //Clip to close parallel-screen plane + oxp0 = xp0; oyp0 = yp0; + if (yp0 < SCISDIST) { t0 = (SCISDIST-yp0)/(yp1-yp0); xp0 = (xp1-xp0)*t0+xp0; yp0 = SCISDIST; } + else t0 = 0.f; + if (yp1 < SCISDIST) { t1 = (SCISDIST-oyp0)/(yp1-oyp0); xp1 = (xp1-oxp0)*t1+oxp0; yp1 = SCISDIST; } + else { t1 = 1.f; } + + getzsofslope(sectnum,(long)((wal2->x-wal->x)*t0+wal->x),(long)((wal2->y-wal->y)*t0+wal->y),&cz[0],&fz[0]); + getzsofslope(wal->nextsector,(long)((wal2->x-wal->x)*t0+wal->x),(long)((wal2->y-wal->y)*t0+wal->y),&cz[1],&fz[1]); + getzsofslope(sectnum,(long)((wal2->x-wal->x)*t1+wal->x),(long)((wal2->y-wal->y)*t1+wal->y),&cz[2],&fz[2]); + getzsofslope(wal->nextsector,(long)((wal2->x-wal->x)*t1+wal->x),(long)((wal2->y-wal->y)*t1+wal->y),&cz[3],&fz[3]); + + ryp0 = 1.f/yp0; ryp1 = 1.f/yp1; + + //Generate screen coordinates for front side of wall + x0 = ghalfx*xp0*ryp0 + ghalfx; + x1 = ghalfx*xp1*ryp1 + ghalfx; + if (x1 <= x0) return; + + ryp0 *= gyxscale; ryp1 *= gyxscale; + + gdx = (ryp0-ryp1)*gxyaspect / (x0-x1); + gdy = 0; + gdo = ryp0*gxyaspect - gdx*x0; + + //gux*x0 + guo = t0*wal->xrepeat*8*yp0 + //gux*x1 + guo = t1*wal->xrepeat*8*yp1 + gux = (t0*ryp0 - t1*ryp1)*gxyaspect*(float)wal->xrepeat*8.f / (x0-x1); + guo = t0*ryp0*gxyaspect*(float)wal->xrepeat*8.f - gux*x0; + guo += (float)wal->xpanning*gdo; + gux += (float)wal->xpanning*gdx; + guy = 0; + + if (!(wal->cstat&4)) i = z1; else i = z2; + i -= globalposz; + t0 = ((float)i)*ryp0 + ghoriz; + t1 = ((float)i)*ryp1 + ghoriz; + t = ((gdx*x0 + gdo) * (float)wal->yrepeat) / ((x1-x0) * ryp0 * 2048.f); + i = (1<<(picsiz[globalpicnum]>>4)); if (i < tilesizy[globalpicnum]) i <<= 1; + fy = (float)wal->ypanning * ((float)i) / 256.0; + gvx = (t0-t1)*t; + gvy = (x1-x0)*t; + gvo = -gvx*x0 - gvy*t0 + fy*gdo; gvx += fy*gdx; gvy += fy*gdy; + + if (wal->cstat&8) //xflip + { + t = (float)(wal->xrepeat*8 + wal->xpanning*2); + gux = gdx*t - gux; + guy = gdy*t - guy; + guo = gdo*t - guo; + } + if (wal->cstat&256) { gvx = -gvx; gvy = -gvy; gvo = -gvo; } //yflip + + method = 1; pow2xsplit = 1; + if (wal->cstat&128) { if (!(wal->cstat&512)) method = 2; else method = 3; } + +#ifdef USE_OPENGL + if (!nofog) { + if (rendmode == 3) { + float col[4]; + col[0] = (float)palookupfog[sec->floorpal].r / 63.f; + col[1] = (float)palookupfog[sec->floorpal].g / 63.f; + col[2] = (float)palookupfog[sec->floorpal].b / 63.f; + col[3] = 0; + bglFogfv(GL_FOG_COLOR,col); + bglFogf(GL_FOG_DENSITY,gvisibility*((float)((unsigned char)(sec->visibility+16)))); + } + } +#endif + + for(i=0;i<2;i++) + { + csy[i] = ((float)(cz[i]-globalposz))*ryp0 + ghoriz; + fsy[i] = ((float)(fz[i]-globalposz))*ryp0 + ghoriz; + csy[i+2] = ((float)(cz[i+2]-globalposz))*ryp1 + ghoriz; + fsy[i+2] = ((float)(fz[i+2]-globalposz))*ryp1 + ghoriz; + } + + //Clip 2 quadrilaterals + // /csy3 + // / | + // csy0------/----csy2 + // | /xxxxxxx| + // | /xxxxxxxxx| + // csy1/xxxxxxxxxxx| + // |xxxxxxxxxxx/fsy3 + // |xxxxxxxxx/ | + // |xxxxxxx/ | + // fsy0----/------fsy2 + // | / + // fsy1/ + + dpx[0] = x0; dpy[0] = csy[1]; + dpx[1] = x1; dpy[1] = csy[3]; + dpx[2] = x1; dpy[2] = fsy[3]; + dpx[3] = x0; dpy[3] = fsy[1]; + n = 4; + + //Clip to (x0,csy[0])-(x1,csy[2]) + n2 = 0; t1 = -((dpx[0]-x0)*(csy[2]-csy[0]) - (dpy[0]-csy[0])*(x1-x0)); + for(i=0;i= n) j = 0; + + t0 = t1; t1 = -((dpx[j]-x0)*(csy[2]-csy[0]) - (dpy[j]-csy[0])*(x1-x0)); + if (t0 >= 0) { dpx2[n2] = dpx[i]; dpy2[n2] = dpy[i]; n2++; } + if ((t0 >= 0) != (t1 >= 0)) + { + r = t0/(t0-t1); + dpx2[n2] = (dpx[j]-dpx[i])*r + dpx[i]; + dpy2[n2] = (dpy[j]-dpy[i])*r + dpy[i]; + n2++; + } + } + if (n2 < 3) return; + + //Clip to (x1,fsy[2])-(x0,fsy[0]) + n = 0; t1 = -((dpx2[0]-x1)*(fsy[0]-fsy[2]) - (dpy2[0]-fsy[2])*(x0-x1)); + for(i=0;i= n2) j = 0; + + t0 = t1; t1 = -((dpx2[j]-x1)*(fsy[0]-fsy[2]) - (dpy2[j]-fsy[2])*(x0-x1)); + if (t0 >= 0) { dpx[n] = dpx2[i]; dpy[n] = dpy2[i]; n++; } + if ((t0 >= 0) != (t1 >= 0)) + { + r = t0/(t0-t1); + dpx[n] = (dpx2[j]-dpx2[i])*r + dpx2[i]; + dpy[n] = (dpy2[j]-dpy2[i])*r + dpy2[i]; + n++; + } + } + if (n < 3) return; + + drawpoly(dpx,dpy,n,method); +} + +void polymost_drawsprite (long snum) +{ + double px[6], py[6]; + float f, r, c, s, fx, fy, sx0, sy0, sx1, sy1, xp0, yp0, xp1, yp1, oxp0, oyp0, ryp0, ryp1, ft[4]; + float x0, y0, x1, y1, sc0, sf0, sc1, sf1, px2[6], py2[6], xv, yv, t0, t1; + long i, j, spritenum, xoff, yoff, method, npoints; + spritetype *tspr; + + tspr = tspriteptr[snum]; + if (tspr->owner < 0 || tspr->picnum < 0) return; + + globalpicnum = tspr->picnum; + globalshade = tspr->shade; + globalpal = tspr->pal; + globalorientation = tspr->cstat; + spritenum = tspr->owner; + + if ((globalorientation&48) != 48) { // only non-voxel sprites should do this + if (picanm[globalpicnum]&192) globalpicnum += animateoffs(globalpicnum,spritenum+32768); + + xoff = (long)((signed char)((picanm[globalpicnum]>>8)&255))+((long)tspr->xoffset); + yoff = (long)((signed char)((picanm[globalpicnum]>>16)&255))+((long)tspr->yoffset); + } + + method = 1+4; + if (tspr->cstat&2) { if (!(tspr->cstat&512)) method = 2+4; else method = 3+4; } + +#ifdef USE_OPENGL + if (!nofog && rendmode == 3) { + float col[4]; + col[0] = (float)palookupfog[sector[tspr->sectnum].floorpal].r / 63.f; + col[1] = (float)palookupfog[sector[tspr->sectnum].floorpal].g / 63.f; + col[2] = (float)palookupfog[sector[tspr->sectnum].floorpal].b / 63.f; + col[3] = 0; + bglFogfv(GL_FOG_COLOR,col); //default is 0,0,0,0 + bglFogf(GL_FOG_DENSITY,gvisibility*((float)((unsigned char)(sector[tspr->sectnum].visibility+16)))); + } + + while (rendmode == 3 && !(spriteext[tspr->owner].flags&SPREXT_NOTMD)) { + if (usemodels && tile2model[tspr->picnum].modelid >= 0 && tile2model[tspr->picnum].framenum >= 0) { + if (mddraw(tspr)) return; + break; // else, render as flat sprite + } + if (usevoxels && (tspr->cstat&48)!=48 && tiletovox[tspr->picnum] >= 0 && voxmodels[ tiletovox[tspr->picnum] ]) { + if (voxdraw(voxmodels[ tiletovox[tspr->picnum] ], tspr)) return; + break; // else, render as flat sprite + } + if ((tspr->cstat&48)==48 && voxmodels[ tspr->picnum ]) { + voxdraw(voxmodels[ tspr->picnum ], tspr); + return; + } + break; + } +#endif + + switch((globalorientation>>4)&3) + { + case 0: //Face sprite + + //Project 3D to 2D + sx0 = (float)(tspr->x-globalposx); + sy0 = (float)(tspr->y-globalposy); + xp0 = sy0*gcosang - sx0*gsinang; + yp0 = sx0*gcosang2 + sy0*gsinang2; + if (yp0 <= SCISDIST) return; + ryp0 = 1/yp0; + sx0 = ghalfx*xp0*ryp0 + ghalfx; + sy0 = ((float)(tspr->z-globalposz))*gyxscale*ryp0 + ghoriz; + + f = ryp0*(float)xdimen/160.0; + fx = ((float)tspr->xrepeat)*f; + fy = ((float)tspr->yrepeat)*f*((float)yxaspect/65536.0); + sx0 -= fx*(float)xoff; if (tilesizx[globalpicnum]&1) sx0 += fx*.5; + sy0 -= fy*(float)yoff; + fx *= ((float)tilesizx[globalpicnum]); + fy *= ((float)tilesizy[globalpicnum]); + + px[0] = px[3] = sx0-fx*.5; px[1] = px[2] = sx0+fx*.5; + if (!(globalorientation&128)) { py[0] = py[1] = sy0-fy; py[2] = py[3] = sy0; } + else { py[0] = py[1] = sy0-fy*.5; py[2] = py[3] = sy0+fy*.5; } + + gdx = gdy = guy = gvx = 0; gdo = ryp0*gviewxrange; + if (!(globalorientation&4)) + { gux = (float)tilesizx[globalpicnum]*gdo/(px[1]-px[0]+.002); guo = -gux*(px[0]-.001); } + else { gux = (float)tilesizx[globalpicnum]*gdo/(px[0]-px[1]-.002); guo = -gux*(px[1]+.001); } + if (!(globalorientation&8)) + { gvy = (float)tilesizy[globalpicnum]*gdo/(py[3]-py[0]+.002); gvo = -gvy*(py[0]-.001); } + else { gvy = (float)tilesizy[globalpicnum]*gdo/(py[0]-py[3]-.002); gvo = -gvy*(py[3]+.001); } + + //Clip sprites to ceilings/floors when no parallaxing and not sloped + if (!(sector[tspr->sectnum].ceilingstat&3)) + { + sy0 = ((float)(sector[tspr->sectnum].ceilingz-globalposz))*gyxscale*ryp0 + ghoriz; + if (py[0] < sy0) py[0] = py[1] = sy0; + } + if (!(sector[tspr->sectnum].floorstat&3)) + { + sy0 = ((float)(sector[tspr->sectnum].floorz-globalposz))*gyxscale*ryp0 + ghoriz; + if (py[2] > sy0) py[2] = py[3] = sy0; + } + + pow2xsplit = 0; drawpoly(px,py,4,method); + break; + case 1: //Wall sprite + + //Project 3D to 2D + if (globalorientation&4) xoff = -xoff; + if (globalorientation&8) yoff = -yoff; + + xv = (float)tspr->xrepeat * (float)sintable[(tspr->ang )&2047] / 65536.0; + yv = (float)tspr->xrepeat * (float)sintable[(tspr->ang+1536)&2047] / 65536.0; + f = (float)(tilesizx[globalpicnum]>>1) + (float)xoff; + x0 = (float)(tspr->x-globalposx) - xv*f; x1 = xv*(float)tilesizx[globalpicnum] + x0; + y0 = (float)(tspr->y-globalposy) - yv*f; y1 = yv*(float)tilesizx[globalpicnum] + y0; + + yp0 = x0*gcosang2 + y0*gsinang2; + yp1 = x1*gcosang2 + y1*gsinang2; + if ((yp0 <= SCISDIST) && (yp1 <= SCISDIST)) return; + xp0 = y0*gcosang - x0*gsinang; + xp1 = y1*gcosang - x1*gsinang; + + //Clip to close parallel-screen plane + oxp0 = xp0; oyp0 = yp0; + if (yp0 < SCISDIST) { t0 = (SCISDIST-yp0)/(yp1-yp0); xp0 = (xp1-xp0)*t0+xp0; yp0 = SCISDIST; } + else { t0 = 0.f; } + if (yp1 < SCISDIST) { t1 = (SCISDIST-oyp0)/(yp1-oyp0); xp1 = (xp1-oxp0)*t1+oxp0; yp1 = SCISDIST; } + else { t1 = 1.f; } + + f = ((float)tspr->yrepeat) * (float)tilesizy[globalpicnum] * 4; + + ryp0 = 1.0/yp0; + ryp1 = 1.0/yp1; + sx0 = ghalfx*xp0*ryp0 + ghalfx; + sx1 = ghalfx*xp1*ryp1 + ghalfx; + ryp0 *= gyxscale; + ryp1 *= gyxscale; + + tspr->z -= ((yoff*tspr->yrepeat)<<2); + if (globalorientation&128) + { + tspr->z += ((tilesizy[globalpicnum]*tspr->yrepeat)<<1); + if (tilesizy[globalpicnum]&1) tspr->z += (tspr->yrepeat<<1); //Odd yspans + } + + sc0 = ((float)(tspr->z-globalposz-f))*ryp0 + ghoriz; + sc1 = ((float)(tspr->z-globalposz-f))*ryp1 + ghoriz; + sf0 = ((float)(tspr->z-globalposz))*ryp0 + ghoriz; + sf1 = ((float)(tspr->z-globalposz))*ryp1 + ghoriz; + + gdx = (ryp0-ryp1)*gxyaspect / (sx0-sx1); + gdy = 0; + gdo = ryp0*gxyaspect - gdx*sx0; + + //Original equations: + //(gux*sx0 + guo)/(gdx*sx1 + gdo) = tilesizx[globalpicnum]*t0 + //(gux*sx1 + guo)/(gdx*sx1 + gdo) = tilesizx[globalpicnum]*t1 + // + // gvx*sx0 + gvy*sc0 + gvo = 0 + // gvy*sx1 + gvy*sc1 + gvo = 0 + //(gvx*sx0 + gvy*sf0 + gvo)/(gdx*sx0 + gdo) = tilesizy[globalpicnum] + //(gvx*sx1 + gvy*sf1 + gvo)/(gdx*sx1 + gdo) = tilesizy[globalpicnum] + + //gux*sx0 + guo = t0*tilesizx[globalpicnum]*yp0 + //gux*sx1 + guo = t1*tilesizx[globalpicnum]*yp1 + if (globalorientation&4) { t0 = 1.f-t0; t1 = 1.f-t1; } + gux = (t0*ryp0 - t1*ryp1)*gxyaspect*(float)tilesizx[globalpicnum] / (sx0-sx1); + guy = 0; + guo = t0*ryp0*gxyaspect*(float)tilesizx[globalpicnum] - gux*sx0; + + //gvx*sx0 + gvy*sc0 + gvo = 0 + //gvx*sx1 + gvy*sc1 + gvo = 0 + //gvx*sx0 + gvy*sf0 + gvo = tilesizy[globalpicnum]*(gdx*sx0 + gdo) + f = ((float)tilesizy[globalpicnum])*(gdx*sx0 + gdo) / ((sx0-sx1)*(sc0-sf0)); + if (!(globalorientation&8)) + { + gvx = (sc0-sc1)*f; + gvy = (sx1-sx0)*f; + gvo = -gvx*sx0 - gvy*sc0; + } + else + { + gvx = (sf1-sf0)*f; + gvy = (sx0-sx1)*f; + gvo = -gvx*sx0 - gvy*sf0; + } + + //Clip sprites to ceilings/floors when no parallaxing + if (!(sector[tspr->sectnum].ceilingstat&1)) + { + f = ((float)tspr->yrepeat) * (float)tilesizy[globalpicnum] * 4; + if (sector[tspr->sectnum].ceilingz > tspr->z-f) + { + sc0 = ((float)(sector[tspr->sectnum].ceilingz-globalposz))*ryp0 + ghoriz; + sc1 = ((float)(sector[tspr->sectnum].ceilingz-globalposz))*ryp1 + ghoriz; + } + } + if (!(sector[tspr->sectnum].floorstat&1)) + { + if (sector[tspr->sectnum].floorz < tspr->z) + { + sf0 = ((float)(sector[tspr->sectnum].floorz-globalposz))*ryp0 + ghoriz; + sf1 = ((float)(sector[tspr->sectnum].floorz-globalposz))*ryp1 + ghoriz; + } + } + + if (sx0 > sx1) + { + if (globalorientation&64) return; //1-sided sprite + f = sx0; sx0 = sx1; sx1 = f; + f = sc0; sc0 = sc1; sc1 = f; + f = sf0; sf0 = sf1; sf1 = f; + } + + px[0] = sx0; py[0] = sc0; + px[1] = sx1; py[1] = sc1; + px[2] = sx1; py[2] = sf1; + px[3] = sx0; py[3] = sf0; + pow2xsplit = 0; drawpoly(px,py,4,method); + break; + case 2: //Floor sprite + + if ((globalorientation&64) != 0) + if ((globalposz > tspr->z) == (!(globalorientation&8))) + return; + if ((globalorientation&4) > 0) xoff = -xoff; + if ((globalorientation&8) > 0) yoff = -yoff; + + i = (tspr->ang&2047); + c = sintable[(i+512)&2047]/65536.0; + s = sintable[i]/65536.0; + x0 = ((tilesizx[globalpicnum]>>1)-xoff)*tspr->xrepeat; + y0 = ((tilesizy[globalpicnum]>>1)-yoff)*tspr->yrepeat; + x1 = ((tilesizx[globalpicnum]>>1)+xoff)*tspr->xrepeat; + y1 = ((tilesizy[globalpicnum]>>1)+yoff)*tspr->yrepeat; + + //Project 3D to 2D + for(j=0;j<4;j++) + { + sx0 = (float)(tspr->x-globalposx); + sy0 = (float)(tspr->y-globalposy); + if ((j+0)&2) { sy0 -= s*y0; sx0 -= c*y0; } else { sy0 += s*y1; sx0 += c*y1; } + if ((j+1)&2) { sx0 -= s*x0; sy0 += c*x0; } else { sx0 += s*x1; sy0 -= c*x1; } + px[j] = sy0*gcosang - sx0*gsinang; + py[j] = sx0*gcosang2 + sy0*gsinang2; + } + + if (tspr->z < globalposz) //if floor sprite is above you, reverse order of points + { + f = px[0]; px[0] = px[1]; px[1] = f; + f = py[0]; py[0] = py[1]; py[1] = f; + f = px[2]; px[2] = px[3]; px[3] = f; + f = py[2]; py[2] = py[3]; py[3] = f; + } + + //Clip to SCISDIST plane + npoints = 0; + for(i=0;i<4;i++) + { + j = ((i+1)&3); + if (py[i] >= SCISDIST) { px2[npoints] = px[i]; py2[npoints] = py[i]; npoints++; } + if ((py[i] >= SCISDIST) != (py[j] >= SCISDIST)) + { + f = (SCISDIST-py[i])/(py[j]-py[i]); + px2[npoints] = (px[j]-px[i])*f + px[i]; + py2[npoints] = (py[j]-py[i])*f + py[i]; npoints++; + } + } + if (npoints < 3) return; + + //Project rotated 3D points to screen + f = ((float)(tspr->z-globalposz))*gyxscale; + for(j=0;jz-globalposz); + gdo = -ghoriz*gdy; + //copied&modified from relative alignment + xv = (float)tspr->x + s*x1 + c*y1; fx = (double)-(x0+x1)*s; + yv = (float)tspr->y + s*y1 - c*x1; fy = (double)+(x0+x1)*c; + f = 1.0/sqrt(fx*fx+fy*fy); fx *= f; fy *= f; + ft[2] = singlobalang*fy + cosglobalang*fx; + ft[3] = singlobalang*fx - cosglobalang*fy; + ft[0] = ((double)(globalposy-yv))*fy + ((double)(globalposx-xv))*fx; + ft[1] = ((double)(globalposx-xv))*fy - ((double)(globalposy-yv))*fx; + gux = (double)ft[3]*((double)viewingrange)/(-65536.0*262144.0); + gvx = (double)ft[2]*((double)viewingrange)/(-65536.0*262144.0); + guy = (double)ft[0]*gdy; gvy = (double)ft[1]*gdy; + guo = (double)ft[0]*gdo; gvo = (double)ft[1]*gdo; + guo += (double)(ft[2]/262144.0-gux)*ghalfx; + gvo -= (double)(ft[3]/262144.0+gvx)*ghalfx; + f = 4.0/(float)tspr->xrepeat; gux *= f; guy *= f; guo *= f; + f =-4.0/(float)tspr->yrepeat; gvx *= f; gvy *= f; gvo *= f; + if (globalorientation&4) + { + gux = ((float)tilesizx[globalpicnum])*gdx - gux; + guy = ((float)tilesizx[globalpicnum])*gdy - guy; + guo = ((float)tilesizx[globalpicnum])*gdo - guo; + } + + pow2xsplit = 0; drawpoly(px,py,npoints,method); + break; + + case 3: //Voxel sprite + break; + } +} + + //sx,sy center of sprite; screen coods*65536 + //z zoom*65536. > is zoomed in + //a angle (0 is default) + //dastat&1 1:translucence + //dastat&2 1:auto-scale mode (use 320*200 coordinates) + //dastat&4 1:y-flip + //dastat&8 1:don't clip to startumost/startdmost + //dastat&16 1:force point passed to be top-left corner, 0:Editart center + //dastat&32 1:reverse translucence + //dastat&64 1:non-masked, 0:masked + //dastat&128 1:draw all pages (permanent) + //cx1,... clip window (actual screen coords) +void polymost_dorotatesprite (long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat, long cx1, long cy1, long cx2, long cy2, long uniqid) +{ + static long onumframes = 0; + long i, n, nn, x, zz, xoff, yoff, xsiz, ysiz, method; + long ogpicnum, ogshade, ogpal, ofoffset, oxdimen, oydimen, oldviewingrange; + double ogxyaspect; + double ogchang, ogshang, ogctang, ogstang, oghalfx, oghoriz, fx, fy, x1, y1, z1, x2, y2; + double ogrhalfxdown10, ogrhalfxdown10x; + double d, cosang, sinang, cosang2, sinang2, px[8], py[8], px2[8], py2[8]; + float m[4][4]; + +#ifdef USE_OPENGL + if (rendmode == 3 && usemodels && hudmem[(dastat&4)>>2][picnum].angadd) + { + if ((tile2model[picnum].modelid >= 0) && (tile2model[picnum].framenum >= 0)) + { + spritetype tspr; + memset(&tspr,0,sizeof(spritetype)); + + if (hudmem[(dastat&4)>>2][picnum].flags&1) return; //"HIDE" is specified in DEF + + ogchang = gchang; gchang = 1.0; + ogshang = gshang; gshang = 0.0; d = (double)z/(65536.0*16384.0); + ogctang = gctang; gctang = (double)sintable[(a+512)&2047]*d; + ogstang = gstang; gstang = (double)sintable[a&2047]*d; + ogshade = globalshade; globalshade = dashade; + ogpal = globalpal; globalpal = (long)((unsigned char)dapalnum); + ogxyaspect = gxyaspect; gxyaspect = 1.0; + oldviewingrange = viewingrange; viewingrange = 65536; + + x1 = hudmem[(dastat&4)>>2][picnum].xadd; + y1 = hudmem[(dastat&4)>>2][picnum].yadd; + z1 = hudmem[(dastat&4)>>2][picnum].zadd; + if (!(hudmem[(dastat&4)>>2][picnum].flags&2)) //"NOBOB" is specified in DEF + { + fx = ((double)sx)*(1.0/65536.0); + fy = ((double)sy)*(1.0/65536.0); + + if (dastat&16) + { + xsiz = tilesizx[picnum]; ysiz = tilesizy[picnum]; + xoff = (long)((signed char)((picanm[picnum]>>8)&255))+(xsiz>>1); + yoff = (long)((signed char)((picanm[picnum]>>16)&255))+(ysiz>>1); + + d = (double)z/(65536.0*16384.0); + cosang2 = cosang = (double)sintable[(a+512)&2047]*d; + sinang2 = sinang = (double)sintable[a&2047]*d; + if ((dastat&2) || (!(dastat&8))) //Don't aspect unscaled perms + { d = (double)xyaspect/65536.0; cosang2 *= d; sinang2 *= d; } + fx += -(double)xoff*cosang2+ (double)yoff*sinang2; + fy += -(double)xoff*sinang - (double)yoff*cosang; + } + + if (!(dastat&2)) + { + x1 += fx/((double)(xdim<<15))-1.0; //-1: left of screen, +1: right of screen + y1 += fy/((double)(ydim<<15))-1.0; //-1: top of screen, +1: bottom of screen + } + else + { + x1 += fx/160.0-1.0; //-1: left of screen, +1: right of screen + y1 += fy/100.0-1.0; //-1: top of screen, +1: bottom of screen + } + } + tspr.ang = hudmem[(dastat&4)>>2][picnum].angadd+globalang; + tspr.xrepeat = tspr.yrepeat = 32; + + if (dastat&4) { x1 = -x1; y1 = -y1; } + tspr.x = (long)(((double)gcosang*z1 - (double)gsinang*x1)*16384.0 + globalposx); + tspr.y = (long)(((double)gsinang*z1 + (double)gcosang*x1)*16384.0 + globalposy); + tspr.z = (long)(globalposz + y1*16384.0*0.8); + tspr.picnum = picnum; + tspr.shade = dashade; + tspr.pal = dapalnum; + tspr.owner = uniqid+MAXSPRITES; + globalorientation = (dastat&1)+((dastat&32)<<4)+((dastat&4)<<1); + + if ((dastat&10) == 2) bglViewport(windowx1,yres-(windowy2+1),windowx2-windowx1+1,windowy2-windowy1+1); + else { bglViewport(0,0,xdim,ydim); glox1 = -1; } //Force fullscreen (glox1=-1 forces it to restore) + + bglMatrixMode(GL_PROJECTION); + memset(m,0,sizeof(m)); + if ((dastat&10) == 2) + { + m[0][0] = (float)ydimen; m[0][2] = 1.0; + m[1][1] = (float)xdimen; m[1][2] = 1.0; + m[2][2] = 1.0; m[2][3] = (float)ydimen; + m[3][2] =-1.0; + } + else { m[0][0] = m[2][3] = 1.0; m[1][1] = ((float)xdim)/((float)ydim); m[2][2] = 1.0001; m[3][2] = 1-m[2][2]; } + bglLoadMatrixf(&m[0][0]); + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); + + if (hudmem[(dastat&4)>>2][picnum].flags&8) //NODEPTH flag + bglDisable(GL_DEPTH_TEST); + else + { + bglEnable(GL_DEPTH_TEST); + if (onumframes != numframes) + { + onumframes = numframes; + bglClear(GL_DEPTH_BUFFER_BIT); + } + } + + mddraw(&tspr); + + viewingrange = oldviewingrange; + gxyaspect = ogxyaspect; + globalshade = ogshade; + globalpal = ogpal; + gchang = ogchang; + gshang = ogshang; + gctang = ogctang; + gstang = ogstang; + return; + } + } +#endif + + ogpicnum = globalpicnum; globalpicnum = picnum; + ogshade = globalshade; globalshade = dashade; + ogpal = globalpal; globalpal = (long)((unsigned char)dapalnum); + oghalfx = ghalfx; ghalfx = (double)(xdim>>1); + ogrhalfxdown10 = grhalfxdown10; grhalfxdown10 = 1.0/(((double)ghalfx)*1024); + ogrhalfxdown10x = grhalfxdown10x; grhalfxdown10x = grhalfxdown10; + oghoriz = ghoriz; ghoriz = (double)(ydim>>1); + ofoffset = frameoffset; frameoffset = frameplace; + oxdimen = xdimen; xdimen = xdim; + oydimen = ydimen; ydimen = ydim; + ogchang = gchang; gchang = 1.0; + ogshang = gshang; gshang = 0.0; + ogctang = gctang; gctang = 1.0; + ogstang = gstang; gstang = 0.0; + +#ifdef USE_OPENGL + if (rendmode == 3) + { + bglViewport(0,0,xdim,ydim); glox1 = -1; //Force fullscreen (glox1=-1 forces it to restore) + bglMatrixMode(GL_PROJECTION); + memset(m,0,sizeof(m)); + m[0][0] = m[2][3] = 1.0; m[1][1] = ((float)xdim)/((float)ydim); m[2][2] = 1.0001; m[3][2] = 1-m[2][2]; + bglPushMatrix(); bglLoadMatrixf(&m[0][0]); + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); + + bglDisable(GL_DEPTH_TEST); + bglDisable(GL_ALPHA_TEST); + bglEnable(GL_TEXTURE_2D); + } +#endif + + method = 0; + if (!(dastat&64)) + { + method = 1; + if (dastat&1) { if (!(dastat&32)) method = 2; else method = 3; } + } + method |= 4; //Use OpenGL clamping - dorotatesprite never repeats + + xsiz = tilesizx[globalpicnum]; ysiz = tilesizy[globalpicnum]; + if (dastat&16) { xoff = 0; yoff = 0; } + else + { + xoff = (long)((signed char)((picanm[globalpicnum]>>8)&255))+(xsiz>>1); + yoff = (long)((signed char)((picanm[globalpicnum]>>16)&255))+(ysiz>>1); + } + if (dastat&4) yoff = ysiz-yoff; + + if (dastat&2) //Auto window size scaling + { + if (!(dastat&8)) + { + x = xdimenscale; //= scale(xdimen,yxaspect,320); + sx = ((cx1+cx2+2)<<15)+scale(sx-(320<<15),oxdimen,320); + sy = ((cy1+cy2+2)<<15)+mulscale16(sy-(200<<15),x); + } + else + { + //If not clipping to startmosts, & auto-scaling on, as a + //hard-coded bonus, scale to full screen instead + x = scale(xdim,yxaspect,320); + sx = (xdim<<15)+32768+scale(sx-(320<<15),xdim,320); + sy = (ydim<<15)+32768+mulscale16(sy-(200<<15),x); + } + z = mulscale16(z,x); + } + + d = (double)z/(65536.0*16384.0); + cosang2 = cosang = (double)sintable[(a+512)&2047]*d; + sinang2 = sinang = (double)sintable[a&2047]*d; + if ((dastat&2) || (!(dastat&8))) //Don't aspect unscaled perms + { d = (double)xyaspect/65536.0; cosang2 *= d; sinang2 *= d; } + px[0] = (double)sx/65536.0 - (double)xoff*cosang2+ (double)yoff*sinang2; + py[0] = (double)sy/65536.0 - (double)xoff*sinang - (double)yoff*cosang; + px[1] = px[0] + (double)xsiz*cosang2; + py[1] = py[0] + (double)xsiz*sinang; + px[3] = px[0] - (double)ysiz*sinang2; + py[3] = py[0] + (double)ysiz*cosang; + px[2] = px[1]+px[3]-px[0]; + py[2] = py[1]+py[3]-py[0]; + n = 4; + + gdx = 0; gdy = 0; gdo = 1.0; + //px[0]*gux + py[0]*guy + guo = 0 + //px[1]*gux + py[1]*guy + guo = xsiz-.0001 + //px[3]*gux + py[3]*guy + guo = 0 + d = 1.0/(px[0]*(py[1]-py[3]) + px[1]*(py[3]-py[0]) + px[3]*(py[0]-py[1])); + gux = (py[3]-py[0])*((double)xsiz-.0001)*d; + guy = (px[0]-px[3])*((double)xsiz-.0001)*d; + guo = 0 - px[0]*gux - py[0]*guy; + + if (!(dastat&4)) + { //px[0]*gvx + py[0]*gvy + gvo = 0 + //px[1]*gvx + py[1]*gvy + gvo = 0 + //px[3]*gvx + py[3]*gvy + gvo = ysiz-.0001 + gvx = (py[0]-py[1])*((double)ysiz-.0001)*d; + gvy = (px[1]-px[0])*((double)ysiz-.0001)*d; + gvo = 0 - px[0]*gvx - py[0]*gvy; + } + else + { //px[0]*gvx + py[0]*gvy + gvo = ysiz-.0001 + //px[1]*gvx + py[1]*gvy + gvo = ysiz-.0001 + //px[3]*gvx + py[3]*gvy + gvo = 0 + gvx = (py[1]-py[0])*((double)ysiz-.0001)*d; + gvy = (px[0]-px[1])*((double)ysiz-.0001)*d; + gvo = (double)ysiz-.0001 - px[0]*gvx - py[0]*gvy; + } + + cx2++; cy2++; + //Clippoly4 (converted from long to double) + nn = z = 0; + do + { + zz = z+1; if (zz == n) zz = 0; + x1 = px[z]; x2 = px[zz]-x1; if ((cx1 <= x1) && (x1 <= cx2)) { px2[nn] = x1; py2[nn] = py[z]; nn++; } + if (x2 <= 0) fx = cx2; else fx = cx1; d = fx-x1; + if ((d < x2) != (d < 0)) { px2[nn] = fx; py2[nn] = (py[zz]-py[z])*d/x2 + py[z]; nn++; } + if (x2 <= 0) fx = cx1; else fx = cx2; d = fx-x1; + if ((d < x2) != (d < 0)) { px2[nn] = fx; py2[nn] = (py[zz]-py[z])*d/x2 + py[z]; nn++; } + z = zz; + } while (z); + if (nn >= 3) + { + n = z = 0; + do + { + zz = z+1; if (zz == nn) zz = 0; + y1 = py2[z]; y2 = py2[zz]-y1; if ((cy1 <= y1) && (y1 <= cy2)) { py[n] = y1; px[n] = px2[z]; n++; } + if (y2 <= 0) fy = cy2; else fy = cy1; d = fy-y1; + if ((d < y2) != (d < 0)) { py[n] = fy; px[n] = (px2[zz]-px2[z])*d/y2 + px2[z]; n++; } + if (y2 <= 0) fy = cy1; else fy = cy2; d = fy-y1; + if ((d < y2) != (d < 0)) { py[n] = fy; px[n] = (px2[zz]-px2[z])*d/y2 + px2[z]; n++; } + z = zz; + } while (z); + pow2xsplit = 0; drawpoly(px,py,n,method); + } + +#ifdef USE_OPENGL + if (rendmode == 3) { + bglMatrixMode(GL_PROJECTION); bglPopMatrix(); + } +#endif + + globalpicnum = ogpicnum; + globalshade = ogshade; + globalpal = ogpal; + ghalfx = oghalfx; + grhalfxdown10 = ogrhalfxdown10; + grhalfxdown10x = ogrhalfxdown10x; + ghoriz = oghoriz; + frameoffset = ofoffset; + xdimen = oxdimen; + ydimen = oydimen; + gchang = ogchang; + gshang = ogshang; + gctang = ogctang; + gstang = ogstang; +} + +#ifdef USE_OPENGL +static float trapextx[2]; +static void drawtrap (float x0, float x1, float y0, float x2, float x3, float y1) +{ + float px[4], py[4]; + long i, n; + + if (y0 == y1) return; + px[0] = x0; py[0] = y0; py[2] = y1; + if (x0 == x1) { px[1] = x3; py[1] = y1; px[2] = x2; n = 3; } + else if (x2 == x3) { px[1] = x1; py[1] = y0; px[2] = x3; n = 3; } + else { px[1] = x1; py[1] = y0; px[2] = x3; px[3] = x2; py[3] = y1; n = 4; } + + bglBegin(GL_TRIANGLE_FAN); + for(i=0;i allocpoints) //16 for safety + { + allocpoints = numpoints+16; + rst = (raster*)realloc(rst,allocpoints*sizeof(raster)); + slist = (long*)realloc(slist,allocpoints*sizeof(long)); + npoint2 = (long*)realloc(npoint2,allocpoints*sizeof(long)); + } + + //Remove unnecessary collinear points: + for(i=0;i m1) { z |= 2; continue; } + npoint2[i] = k; npoint2[j] = -1; npoints--; i--; //collinear + } + if (!z) return; + trapextx[0] = trapextx[1] = px[0]; + for(i=j=0;i trapextx[1]) trapextx[1] = px[i]; + slist[j++] = i; + } + if (z != 3) //Simple polygon... early out + { + bglBegin(GL_TRIANGLE_FAN); + for(i=0;i>1);gap;gap>>=1) + for(i=0;i=0;j-=gap) + { + if (py[npoint2[slist[j]]] <= py[npoint2[slist[j+gap]]]) break; + k = slist[j]; slist[j] = slist[j+gap]; slist[j+gap] = k; + } + + numrst = 0; + for(z=0;z0;i--) + { + if (rst[i-1].xi*(py[i1]-rst[i-1].y) + rst[i-1].x < px[i1]) break; + rst[i+1] = rst[i-1]; + } + numrst += 2; + + if (i&1) //split inside area + { + j = i-1; + + x0 = (py[i1] - rst[j ].y)*rst[j ].xi + rst[j ].x; + x1 = (py[i1] - rst[j+1].y)*rst[j+1].xi + rst[j+1].x; + drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1]); + rst[j ].x = x0; rst[j ].y = py[i1]; + rst[j+3].x = x1; rst[j+3].y = py[i1]; + } + + m0 = (px[i0]-px[i1]) / (py[i0]-py[i1]); + m1 = (px[i3]-px[i2]) / (py[i3]-py[i2]); + j = ((px[i1] > px[i2]) || ((i1 == i2) && (m0 >= m1))) + i; + k = (i<<1)+1 - j; + rst[j].i = i0; rst[j].xi = m0; rst[j].x = px[i1]; rst[j].y = py[i1]; + rst[k].i = i3; rst[k].xi = m1; rst[k].x = px[i2]; rst[k].y = py[i2]; + } + else + { //NOTE:don't count backwards! + if (i1 == i2) { for(i=0;i py[i0]) && (py[i2] > py[i3])) //Delete raster + { + for(;j<=i+1;j+=2) + { + x0 = (py[i1] - rst[j ].y)*rst[j ].xi + rst[j ].x; + if ((i == j) && (i1 == i2)) x1 = x0; else x1 = (py[i1] - rst[j+1].y)*rst[j+1].xi + rst[j+1].x; + drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1]); + rst[j ].x = x0; rst[j ].y = py[i1]; + rst[j+1].x = x1; rst[j+1].y = py[i1]; + } + numrst -= 2; for(;i=0;i--) + { + ((float *)rx1)[i] = ((float)rx1[i])/4096.0; + ((float *)ry1)[i] = ((float)ry1[i])/4096.0; + } + + if (gloy1 != -1) setpolymost2dview(); //disables blending, texturing, and depth testing + bglEnable(GL_ALPHA_TEST); + bglEnable(GL_TEXTURE_2D); + pth = gltexcache(globalpicnum,globalpal,0); + bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0); + + f = ((float)(numpalookups-min(max(globalshade,0),numpalookups)))/((float)numpalookups); + switch ((globalorientation>>7)&3) { + case 0: + case 1: a = 1.0; bglDisable(GL_BLEND); break; + case 2: a = 0.66; bglEnable(GL_BLEND); break; + case 3: a = 0.33; bglEnable(GL_BLEND); break; + } + bglColor4f(f,f,f,a); + + tessectrap((float *)rx1,(float *)ry1,xb1,npoints); +} +#endif + +long polymost_drawtilescreen (long tilex, long tiley, long wallnum, long dimen) +{ +#ifdef USE_OPENGL + float xdime, ydime, xdimepad, ydimepad, scx, scy; + long i; + pthtyp *pth; + + if ((rendmode != 3) || (qsetmode != 200)) return(-1); + + if (!glinfo.texnpot) { + i = (1<<(picsiz[wallnum]&15)); if (i < tilesizx[wallnum]) i += i; xdimepad = (float)i; + i = (1<<(picsiz[wallnum]>>4)); if (i < tilesizy[wallnum]) i += i; ydimepad = (float)i; + } else { + xdimepad = (float)tilesizx[wallnum]; + ydimepad = (float)tilesizy[wallnum]; + } + xdime = (float)tilesizx[wallnum]; xdimepad = xdime/xdimepad; + ydime = (float)tilesizy[wallnum]; ydimepad = ydime/ydimepad; + + if ((xdime <= dimen) && (ydime <= dimen)) + { + scx = xdime; + scy = ydime; + } + else + { + scx = (float)dimen; + scy = (float)dimen; + if (xdime < ydime) scx *= xdime/ydime; else scy *= ydime/xdime; + } + + pth = gltexcache(wallnum,0,4); + bglBindTexture(GL_TEXTURE_2D,pth ? pth->glpic : 0); + + bglDisable(GL_ALPHA_TEST); + + if (!pth || (pth->flags & 8)) { + bglDisable(GL_TEXTURE_2D); + bglBegin(GL_TRIANGLE_FAN); + if (gammabrightness) + bglColor4f((float)curpalette[255].r/255.0, + (float)curpalette[255].g/255.0, + (float)curpalette[255].b/255.0, + 1); + else + bglColor4f((float)britable[curbrightness][ curpalette[255].r ] / 255.0, + (float)britable[curbrightness][ curpalette[255].g ] / 255.0, + (float)britable[curbrightness][ curpalette[255].b ] / 255.0, + 1); + bglVertex2f((float)tilex ,(float)tiley ); + bglVertex2f((float)tilex+scx,(float)tiley ); + bglVertex2f((float)tilex+scx,(float)tiley+scy); + bglVertex2f((float)tilex ,(float)tiley+scy); + bglEnd(); + } + + bglColor4f(1,1,1,1); + bglEnable(GL_TEXTURE_2D); + bglEnable(GL_BLEND); + bglBegin(GL_TRIANGLE_FAN); + bglTexCoord2f( 0, 0); bglVertex2f((float)tilex ,(float)tiley ); + bglTexCoord2f(xdimepad, 0); bglVertex2f((float)tilex+scx,(float)tiley ); + bglTexCoord2f(xdimepad,ydimepad); bglVertex2f((float)tilex+scx,(float)tiley+scy); + bglTexCoord2f( 0,ydimepad); bglVertex2f((float)tilex ,(float)tiley+scy); + bglEnd(); + + return(0); +#else + return -1; +#endif +} + +long polymost_printext256(long xpos, long ypos, short col, short backcol, char *name, char fontsize) +{ +#ifndef USE_OPENGL + return -1; +#else + GLfloat tx, ty, txc, tyc; + int c; + palette_t p,b; + + if (gammabrightness) { + p = curpalette[col]; + b = curpalette[backcol]; + } else { + p.r = britable[curbrightness][ curpalette[col].r ]; + p.g = britable[curbrightness][ curpalette[col].g ]; + p.b = britable[curbrightness][ curpalette[col].b ]; + b.r = britable[curbrightness][ curpalette[backcol].r ]; + b.g = britable[curbrightness][ curpalette[backcol].g ]; + b.b = britable[curbrightness][ curpalette[backcol].b ]; + } + + if ((rendmode != 3) || (qsetmode != 200)) return(-1); + + if (!polymosttext) { + // construct a 256x128 8-bit alpha-only texture for the font glyph matrix + unsigned char *tbuf, *cptr, *tptr; + int h,i,j,l; + + bglGenTextures(1,&polymosttext); + if (!polymosttext) return -1; + + tbuf = (unsigned char *)Bmalloc(256*128); + if (!tbuf) { + bglDeleteTextures(1,&polymosttext); + polymosttext = 0; + return -1; + } + Bmemset(tbuf, 0, 256*128); + + cptr = (unsigned char*)textfont; + for (h=0;h<256;h++) { + tptr = tbuf + (h%32)*8 + (h/32)*256*8; + for (i=0;i<8;i++) { + for (j=0;j<8;j++) { + if (cptr[h*8+i] & pow2char[7-j]) tptr[j] = 255; + } + tptr += 256; + } + } + + cptr = (unsigned char*)smalltextfont; + for (h=0;h<256;h++) { + tptr = tbuf + 256*64 + (h%32)*8 + (h/32)*256*8; + for (i=1;i<7;i++) { + for (j=2;j<6;j++) { + if (cptr[h*8+i] & pow2char[7-j]) tptr[j-2] = 255; + } + tptr += 256; + } + } + + bglBindTexture(GL_TEXTURE_2D, polymosttext); + bglTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,256,128,0,GL_ALPHA,GL_UNSIGNED_BYTE,(GLvoid*)tbuf); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + free(tbuf); + } + else bglBindTexture(GL_TEXTURE_2D, polymosttext); + + setpolymost2dview(); // disables blending, texturing, and depth testing + bglDisable(GL_ALPHA_TEST); + bglDepthMask(GL_FALSE); // disable writing to the z-buffer + + if (backcol >= 0) { + bglColor4ub(b.r,b.g,b.b,255); + c = Bstrlen(name); + + bglBegin(GL_QUADS); + bglVertex2i(xpos,ypos); + bglVertex2i(xpos,ypos+(fontsize?6:8)); + bglVertex2i(xpos+(c<<(3-fontsize)),ypos+(fontsize?6:8)); + bglVertex2i(xpos+(c<<(3-fontsize)),ypos); + bglEnd(); + } + + bglEnable(GL_TEXTURE_2D); + bglEnable(GL_BLEND); + bglColor4ub(p.r,p.g,p.b,255); + txc = fontsize ? (4.0/256.0) : (8.0/256.0); + tyc = fontsize ? (6.0/128.0) : (8.0/128.0); + bglBegin(GL_QUADS); + for (c=0; name[c]; c++) { + tx = (float)(name[c]%32)/32.0; + ty = (float)((name[c]/32) + (fontsize*8))/16.0; + + bglTexCoord2f(tx,ty); bglVertex2i(xpos,ypos); + bglTexCoord2f(tx+txc,ty); bglVertex2i(xpos+(8>>fontsize),ypos); + bglTexCoord2f(tx+txc,ty+tyc); bglVertex2i(xpos+(8>>fontsize),ypos+(fontsize?6:8)); + bglTexCoord2f(tx,ty+tyc); bglVertex2i(xpos,ypos+(fontsize?6:8)); + + xpos += (8>>fontsize); + } + bglEnd(); + + bglDepthMask(GL_TRUE); // re-enable writing to the z-buffer + + return 0; +#endif +} + +// Console commands by JBF +#ifdef USE_OPENGL +static int gltexturemode(const osdfuncparm_t *parm) +{ + int m; + const char *p; + + if (parm->numparms != 1) { + OSD_Printf("Current texturing mode is %s\n", glfiltermodes[gltexfiltermode].name); + OSD_Printf(" Vaild modes are:\n"); + for (m = 0; m < (int)numglfiltermodes; m++) + OSD_Printf(" %d - %s\n",m,glfiltermodes[m].name); + + return OSDCMD_OK; + } + + m = Bstrtoul(parm->parms[0], (char **)&p, 10); + if (p == parm->parms[0]) { + // string + for (m = 0; m < (int)numglfiltermodes; m++) { + if (!Bstrcasecmp(parm->parms[0], glfiltermodes[m].name)) break; + } + if (m == numglfiltermodes) m = gltexfiltermode; // no change + } else { + if (m < 0) m = 0; + else if (m >= (int)numglfiltermodes) m = numglfiltermodes - 1; + } + + if (m != gltexfiltermode) { + gltexfiltermode = m; + gltexapplyprops(); + } + + OSD_Printf("Texture filtering mode changed to %s\n", glfiltermodes[gltexfiltermode].name ); + + return OSDCMD_OK; +} + +static int gltextureanisotropy(const osdfuncparm_t *parm) +{ + long l; + const char *p; + + if (parm->numparms != 1) { + OSD_Printf("Current texture anisotropy is %d\n", glanisotropy); + OSD_Printf(" Maximum is %d\n", (long)glinfo.maxanisotropy); + + return OSDCMD_OK; + } + + l = Bstrtoul(parm->parms[0], (char **)&p, 10); + if (l < 0 || l > (long)glinfo.maxanisotropy) l = 0; + + if (l != gltexfiltermode) { + glanisotropy = l; + gltexapplyprops(); + } + + OSD_Printf("Texture anisotropy changed to %d\n", glanisotropy ); + + return OSDCMD_OK; +} +#endif + +static int osdcmd_polymostvars(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms < 1), val; + + if (!showval) val = atoi(parm->parms[0]); + if (!Bstrcasecmp(parm->name, "usemodels")) { + if (showval) { OSD_Printf("usemodels is %d\n", usemodels); } + else usemodels = (val != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "usehightile")) { + if (showval) { OSD_Printf("usehightile is %d\n", usehightile); } + else usehightile = (val != 0); + return OSDCMD_OK; + } +#ifdef USE_OPENGL + else if (!Bstrcasecmp(parm->name, "glusetexcompr")) { + if (showval) { OSD_Printf("glusetexcompr is %d\n", glusetexcompr); } + else glusetexcompr = (val != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glredbluemode")) { + if (showval) { OSD_Printf("glredbluemode is %d\n", glredbluemode); } + else glredbluemode = (val != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "gltexturemaxsize")) { + if (showval) { OSD_Printf("gltexturemaxsize is %d\n", gltexmaxsize); } + else gltexmaxsize = val; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "gltexturemiplevel")) { + if (showval) { OSD_Printf("gltexturemiplevel is %d\n", gltexmiplevel); } + else gltexmiplevel = val; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "usegoodalpha")) { + OSD_Printf("usegoodalpha is obsolete\n"); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glpolygonmode")) { + if (showval) { OSD_Printf("glpolygonmode is %d\n", glpolygonmode); } + else glpolygonmode = val; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glusetexcache")) { + if (showval) { OSD_Printf("glusetexcache is %d\n", glusetexcache); } + else glusetexcache = (val != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glusetexcachecompression")) { + if (showval) { OSD_Printf("glusetexcachecompression is %d\n", glusetexcachecompression); } + else glusetexcachecompression = (val != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glmultisample")) { + if (showval) { OSD_Printf("glmultisample is %d\n", glmultisample); } + else glmultisample = max(0,val); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glnvmultisamplehint")) { + if (showval) { OSD_Printf("glnvmultisamplehint is %d\n", glnvmultisamplehint); } + else glnvmultisamplehint = (val != 0); + return OSDCMD_OK; + } +#endif + return OSDCMD_SHOWHELP; +} + +#if 0 +// because I'm lazy +static int dumptexturedefs(const osdfuncparm_t *parm) +{ + hicreplctyp *hr; + int i; + + if (!hicfirstinit) return OSDCMD_OK; + + initprintf("// Begin Texture Dump\n"); + for (i=0;inext) { + if (!hr->filename) continue; + initprintf(" pal %d { name \"%s\" ", hr->palnum, hr->filename); + if (hr->alphacut >= 0.0) initprintf("alphacut %g ", hr->alphacut); + initprintf("}\n"); + } + initprintf("}\n"); + } + initprintf("// End Texture Dump\n"); + + return OSDCMD_OK; // no replacement found +} +#endif + +void polymost_initosdfuncs(void) +{ +#ifdef USE_OPENGL + OSD_RegisterFunction("glusetexcompr","glusetexcompr: enable/disable OpenGL texture compression",osdcmd_polymostvars); + OSD_RegisterFunction("glredbluemode","glredbluemode: enable/disable experimental OpenGL red-blue glasses mode",osdcmd_polymostvars); + OSD_RegisterFunction("gltexturemode", "gltexturemode: changes the texture filtering settings", gltexturemode); + OSD_RegisterFunction("gltextureanisotropy", "gltextureanisotropy: changes the OpenGL texture anisotropy setting", gltextureanisotropy); + OSD_RegisterFunction("gltexturemaxsize","gltexturemaxsize: changes the maximum OpenGL texture size limit",osdcmd_polymostvars); + OSD_RegisterFunction("gltexturemiplevel","gltexturemiplevel: changes the highest OpenGL mipmap level used",osdcmd_polymostvars); + OSD_RegisterFunction("usegoodalpha","usegoodalpha: [OBSOLETE] enable/disable better looking OpenGL alpha hack",osdcmd_polymostvars); + OSD_RegisterFunction("glpolygonmode","glpolygonmode: debugging feature",osdcmd_polymostvars); //FUK + OSD_RegisterFunction("glusetexcache","glusetexcache: enable/disable OpenGL compressed texture cache",osdcmd_polymostvars); + OSD_RegisterFunction("glusetexcachecompression","usetexcachecompression: enable/disable compression of files in the OpenGL compressed texture cache",osdcmd_polymostvars); + OSD_RegisterFunction("glmultisample","glmultisample: sets the number of samples used for antialiasing (0 = off)",osdcmd_polymostvars); + OSD_RegisterFunction("glnvmultisamplehint","glnvmultisamplehint: enable/disable Nvidia multisampling hinting",osdcmd_polymostvars); +#endif + OSD_RegisterFunction("usemodels","usemodels: enable/disable model rendering in >8-bit mode",osdcmd_polymostvars); + OSD_RegisterFunction("usehightile","usehightile: enable/disable hightile texture rendering in >8-bit mode",osdcmd_polymostvars); + //OSD_RegisterFunction("dumptexturedefs","dumptexturedefs: dumps all texture definitions in the new style",dumptexturedefs); +} + +void polymost_precache(long dapicnum, long dapalnum, long datype) +{ +#ifdef USE_OPENGL + // dapicnum and dapalnum are like you'd expect + // datype is 0 for a wall/floor/ceiling and 1 for a sprite + // basically this just means walls are repeating + // while sprites are clamped + int mid; + + if (rendmode < 3) return; + + if (!palookup[dapalnum]) return;//dapalnum = 0; + + //OSD_Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype); + hicprecaching = 1; + gltexcache(dapicnum, dapalnum, (datype & 1) << 2); + hicprecaching = 0; + + if (datype == 0) return; + + mid = md_tilehasmodel(dapicnum); + if (mid < 0 || models[mid]->mdnum < 2) return; + + { + int i,j=0; + + if (models[mid]->mdnum == 3) + j = ((md3model *)models[mid])->head.numsurfs; + + for (i=0;i<=j;i++) + mdloadskin((md2model*)models[mid], 0, dapalnum, i); + } +#endif +} + +static unsigned short hicosub (unsigned short c) +{ + long r, g, b; + g = ((c>> 5)&63); + r = ((c>>11)-(g>>1))&31; + b = ((c>> 0)-(g>>1))&31; + return((r<<11)+(g<<5)+b); +} + +static unsigned short hicoadd (unsigned short c) +{ + long r, g, b; + g = ((c>> 5)&63); + r = ((c>>11)+(g>>1))&31; + b = ((c>> 0)+(g>>1))&31; + return((r<<11)+(g<<5)+b); +} + +/* +Description of Ken's filter to improve LZW compression of DXT1 format by ~15%: (as tested with the HRP) + + To increase LZW patterns, I store each field of the DXT block structure separately. + Here are the 3 DXT fields: + 1. __int64 alpha_4x4; //DXT3 only (16 byte structure size when included) + 2. short rgb0, rgb1; + 3. long index_4x4; + + Each field is then stored with its own specialized algorithm. + 1. I haven't done much testing with this field - I just copy it raw without any transform for now. + + 2. For rgb0 and rgb1, I use a "green" filter like this: + g = g; + r = r-g; + b = b-g; + For grayscale, this makes the stream: x,0,0,x,0,0,x,0,0,... instead of x,x,x,x,x,x,x,x,... + Q:what was the significance of choosing green? A:largest/most dominant component + Believe it or not, this gave 1% better compression :P + I tried subtracting each componenet with the previous pixel, but strangely it hurt compression. + Oh, the joy of trial & error. :) + + 3. For index_4x4, I transform the ordering of 2-bit indices in the DXT blocks from this: + 0123 0123 0123 ---- ---- ---- + 4567 4567 4567 ---- ---- ---- + 89ab 89ab 89ab ---- ---- ---- + cdef cdef cdef ---- ---- ---- + To this: (I swap x & y axes) + 048c 048c 048c |||| |||| |||| + 159d 159d 159d |||| |||| |||| + 26ae 26ae 26ae |||| |||| |||| + 37bf 37bf 37bf |||| |||| |||| + The trick is: going from the bottom of the 4th line to the top of the 5th line + is the exact same jump (geometrically) as from 5th to 6th, etc.. This is not true in the top case. + These silly tricks will increase patterns and therefore make LZW compress better. + I think this improved compression by a few % :) + */ + +int dxtfilter(int fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, unsigned long miplen) +{ + void *writebuf; +#if (USEKENFILTER == 0) + unsigned long cleng,j; + if (glusetexcachecompression) { +#ifdef USELZF + cleng = lzf_compress(pic, miplen, packbuf, miplen-1); + if (cleng == 0) { + // failed to compress + cleng = miplen; + writebuf = pic; + } else writebuf = packbuf; +#else + cleng = lzwcompress(pic,miplen,packbuf); + writebuf = packbuf; +#endif + } else { + cleng = miplen; + writebuf = pic; + } + if (cleng < 0) return -1; j = B_LITTLE32(cleng); + if (Bwrite(fil, &j, sizeof(unsigned long)) != sizeof(unsigned long)) return -1; + if (Bwrite(fil, writebuf, cleng) != cleng) return -1; +#else + long j, k, offs, stride, cleng; + char *cptr; + + if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)) || + (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT))) { offs = 0; stride = 8; } + else if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)) || + (pict->format == B_LITTLE32(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))) { offs = 8; stride = 16; } + else { offs = 0; stride = 8; } + + if (stride == 16) //If DXT3... + { + //alpha_4x4 + cptr = midbuf; + for(k=0;k<8;k++) *cptr++ = pic[k]; + for(j=stride;j>0)&3) + (((c2[1]>>0)&3)<<2) + (((c2[2]>>0)&3)<<4) + (((c2[3]>>0)&3)<<6); + cptr[1] = ((c2[0]>>2)&3) + (((c2[1]>>2)&3)<<2) + (((c2[2]>>2)&3)<<4) + (((c2[3]>>2)&3)<<6); + cptr[2] = ((c2[0]>>4)&3) + (((c2[1]>>4)&3)<<2) + (((c2[2]>>4)&3)<<4) + (((c2[3]>>4)&3)<<6); + cptr[3] = ((c2[0]>>6)&3) + (((c2[1]>>6)&3)<<2) + (((c2[2]>>6)&3)<<4) + (((c2[3]>>6)&3)<<6); + cptr += 4; + } + if (glusetexcachecompression) { +#ifdef USELZF + j = (miplen/stride)*4; + cleng = lzf_compress(midbuf,j,packbuf,j-1); + if (cleng == 0) { + cleng = j; + writebuf = midbuf; + } else writebuf = packbuf; +#else + cleng = lzwcompress(midbuf,(miplen/stride)*4,packbuf); + writebuf = packbuf; +#endif + } else { + cleng = (miplen/stride)*4; + writebuf = midbuf; + } + j = B_LITTLE32(cleng); + Bwrite(fil,&j,4); + Bwrite(fil,writebuf,cleng); +#endif + return 0; +} + +int dedxtfilter(int fil, texcachepicture *pict, char *pic, void *midbuf, char *packbuf, int ispacked) +{ + void *inbuf; +#if (USEKENFILTER == 0) + unsigned long cleng; + if (kread(fil, &cleng, sizeof(unsigned long)) != sizeof(unsigned long)) return -1; cleng = B_LITTLE32(cleng); +#ifdef USELZF + if (ispacked && cleng < pict->size) inbuf = packbuf; else inbuf = pic; + if (kread(fil, inbuf, cleng) != cleng) return -1; + if (ispacked && cleng < pict->size) + if (lzf_decompress(packbuf, cleng, pic, pict->size) == 0) return -1; +#else + if (ispacked) inbuf = packbuf; else inbuf = pic; + if (kread(fil, inbuf, cleng) != cleng) return -1; + if (ispacked && lzwuncompress(packbuf, cleng, pic, pict->size) != pict->size) return -1; +#endif +#else + long j, k, offs, stride, cleng; + char *cptr; + + if (ispacked) inbuf = packbuf; else inbuf = midbuf; + + if ((pict->format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || + (pict->format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)) { offs = 0; stride = 8; } + else if ((pict->format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || + (pict->format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) { offs = 8; stride = 16; } + else { offs = 0; stride = 8; } + + if (stride == 16) //If DXT3... + { + //alpha_4x4 + if (kread(fil,&cleng,4) < 4) return -1; cleng = B_LITTLE32(cleng); + j = (pict->size/stride)*8; +#ifdef USELZF + if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf; + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && cleng < j) + if (lzf_decompress(packbuf,cleng,midbuf,j) == 0) return -1; +#else + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1; +#endif + cptr = midbuf; + for(k=0;k<8;k++) pic[k] = *cptr++; + for(j=stride;jsize;j+=stride) + for(k=0;k<8;k++) pic[j+k] = (*cptr++); + } + + //rgb0,rgb1 + if (kread(fil,&cleng,4) < 4) return -1; cleng = B_LITTLE32(cleng); + j = (pict->size/stride)*4; +#ifdef USELZF + if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf; + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && cleng < j) + if (lzf_decompress(packbuf,cleng,midbuf,j) == 0) return -1; +#else + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1; +#endif + cptr = midbuf; + for(k=0;k<=2;k+=2) + for(j=0;jsize;j+=stride) + { + *(short *)(&pic[offs+j+k]) = hicoadd(*(short *)cptr); + cptr += 2; + } + + //index_4x4: + if (kread(fil,&cleng,4) < 4) return -1; cleng = B_LITTLE32(cleng); + j = (pict->size/stride)*4; +#ifdef USELZF + if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf; + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && cleng < j) + if (lzf_decompress(packbuf,cleng,midbuf,j) == 0) return -1; +#else + if (kread(fil,inbuf,cleng) < cleng) return -1; + if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1; +#endif + cptr = midbuf; + for(j=0;jsize;j+=stride) + { + pic[j+offs+4] = ((cptr[0]>>0)&3) + (((cptr[1]>>0)&3)<<2) + (((cptr[2]>>0)&3)<<4) + (((cptr[3]>>0)&3)<<6); + pic[j+offs+5] = ((cptr[0]>>2)&3) + (((cptr[1]>>2)&3)<<2) + (((cptr[2]>>2)&3)<<4) + (((cptr[3]>>2)&3)<<6); + pic[j+offs+6] = ((cptr[0]>>4)&3) + (((cptr[1]>>4)&3)<<2) + (((cptr[2]>>4)&3)<<4) + (((cptr[3]>>4)&3)<<6); + pic[j+offs+7] = ((cptr[0]>>6)&3) + (((cptr[1]>>6)&3)<<2) + (((cptr[2]>>6)&3)<<4) + (((cptr[3]>>6)&3)<<6); + cptr += 4; + } +#endif + return 0; +} + +// vim:ts=4:sw=4: diff --git a/polymer/build/src/pragmas.c b/polymer/build/src/pragmas.c new file mode 100644 index 000000000..6b29640bb --- /dev/null +++ b/polymer/build/src/pragmas.c @@ -0,0 +1,250 @@ +// Function-wrapped Watcom pragmas +// by Jonathon Fowler (jonof@edgenetwk.com) +// +// These functions represent some of the more longer-winded pragmas +// from the original pragmas.h wrapped into functions for easier +// use since many jumps and whatnot make it harder to write macro- +// inline versions. I'll eventually convert these to macro-inline +// equivalents. --Jonathon + +//#include "pragmas.h" +#include "compat.h" + +long dmval; + +#if defined(NOASM) + +// +// Generic C version +// + +void qinterpolatedown16(long bufptr, long num, long val, long add) +{ // gee, I wonder who could have provided this... + long i, *lptr = (long *)bufptr; + for(i=0;i>16); val += add; } +} + +void qinterpolatedown16short(long bufptr, long num, long val, long add) +{ // ...maybe the same person who provided this too? + long i; short *sptr = (short *)bufptr; + for(i=0;i>16); val += add; } +} + +void clearbuf(void *d, long c, long a) +{ + long *p = (long*)d; + while ((c--) > 0) *(p++) = a; +} + +void copybuf(void *s, void *d, long c) +{ + long *p = (long*)s, *q = (long*)d; + while ((c--) > 0) *(q++) = *(p++); +} + +void swapbuf4(void *a, void *b, long c) +{ + long *p = (long*)a, *q = (long*)b; + long x, y; + while ((c--) > 0) { + x = *q; + y = *p; + *(q++) = y; + *(p++) = x; + } +} + +void clearbufbyte(void *D, long c, long a) +{ // Cringe City + char *p = (char*)D; + long m[4] = { 0xffl,0xff00l,0xff0000l,0xff000000l }; + long n[4] = { 0,8,16,24 }; + long z=0; + while ((c--) > 0) { + *(p++) = (char)((a & m[z])>>n[z]); + z=(z+1)&3; + } +} + +void copybufbyte(void *S, void *D, long c) +{ + char *p = (char*)S, *q = (char*)D; + while((c--) > 0) *(q++) = *(p++); +} + +void copybufreverse(void *S, void *D, long c) +{ + char *p = (char*)S, *q = (char*)D; + while((c--) > 0) *(q++) = *(p--); +} + +#elif defined(__GNUC__) && defined(__i386__) // NOASM + +// +// GCC Inline Assembler version +// + +#define ASM __asm__ __volatile__ + + +long boundmulscale(long a, long b, long c) +{ + ASM ( + "imull %%ebx\n\t" + "movl %%edx, %%ebx\n\t" // mov ebx, edx + "shrdl %%cl, %%edx, %%eax\n\t" // mov eax, edx, cl + "sarl %%cl, %%edx\n\t" // sar edx, cl + "xorl %%eax, %%edx\n\t" // xor edx, eax + "js 0f\n\t" // js checkit + "xorl %%eax, %%edx\n\t" // xor edx, eax + "jz 1f\n\t" // js skipboundit + "cmpl $0xffffffff, %%edx\n\t" // cmp edx, 0xffffffff + "je 1f\n\t" // je skipboundit + "0:\n\t" // checkit: + "movl %%ebx, %%eax\n\t" // mov eax, ebx + "sarl $31, %%eax\n\t" // sar eax, 31 + "xorl $0x7fffffff, %%eax\n\t" // xor eax, 0x7fffffff + "1:" // skipboundit: + : "+a" (a), "+b" (b), "+c" (c) // input eax ebx ecx + : + : "edx", "cc" + ); + return a; +} + + +void clearbufbyte(void *D, long c, long a) +{ + ASM ( + "cmpl $4, %%ecx\n\t" + "jae 1f\n\t" + "testb $1, %%cl\n\t" + "jz 0f\n\t" // jz preskip + "stosb\n\t" + "0:\n\t" // preskip: + "shrl $1, %%ecx\n\t" + "rep\n\t" + "stosw\n\t" + "jmp 5f\n\t" // jmp endit + "1:\n\t" // intcopy: + "testl $1, %%edi\n\t" + "jz 2f\n\t" // jz skip1 + "stosb\n\t" + "decl %%ecx\n\t" + "2:\n\t" // skip1: + "testl $2, %%edi\n\t" + "jz 3f\n\t" // jz skip2 + "stosw\n\t" + "subl $2, %%ecx\n\t" + "3:\n\t" // skip2: + "movl %%ecx, %%ebx\n\t" + "shrl $2, %%ecx\n\t" + "rep\n\t" + "stosl\n\t" + "testb $2, %%bl\n\t" + "jz 4f\n\t" // jz skip3 + "stosw\n\t" + "4:\n\t" // skip3: + "testb $1, %%bl\n\t" + "jz 5f\n\t" // jz endit + "stosb\n\t" + "5:" // endit + : "+D" (D), "+c" (c), "+a" (a) : + : "ebx", "memory", "cc" + ); +} + +void copybufbyte(void *S, void *D, long c) +{ + ASM ( + "cmpl $4, %%ecx\n\t" // cmp ecx, 4 + "jae 1f\n\t" + "testb $1, %%cl\n\t" // test cl, 1 + "jz 0f\n\t" + "movsb\n\t" + "0:\n\t" // preskip: + "shrl $1, %%ecx\n\t" // shr ecx, 1 + "rep\n\t" + "movsw\n\t" + "jmp 5f\n\t" + "1:\n\t" // intcopy: + "testl $1, %%edi\n\t" // test edi, 1 + "jz 2f\n\t" + "movsb\n\t" + "decl %%ecx\n\t" + "2:\n\t" // skip1: + "testl $2, %%edi\n\t" // test edi, 2 + "jz 3f\n\t" + "movsw\n\t" + "subl $2, %%ecx\n\t" // sub ecx, 2 + "3:\n\t" // skip2: + "movl %%ecx, %%ebx\n\t" // mov ebx, ecx + "shrl $2, %%ecx\n\t" // shr ecx ,2 + "rep\n\t" + "movsl\n\t" + "testb $2, %%bl\n\t" // test bl, 2 + "jz 4f\n\t" + "movsw\n\t" + "4:\n\t" // skip3: + "testb $1, %%bl\n\t" // test bl, 1 + "jz 5f\n\t" + "movsb\n\t" + "5:" // endit: + : "+c" (c), "+S" (S), "+D" (D) : + : "ebx", "memory", "cc" + ); +} + +void copybufreverse(void *S, void *D, long c) +{ + ASM ( + "shrl $1, %%ecx\n\t" + "jnc 0f\n\t" // jnc skipit1 + "movb (%%esi), %%al\n\t" + "decl %%esi\n\t" + "movb %%al, (%%edi)\n\t" + "incl %%edi\n\t" + "0:\n\t" // skipit1: + "shrl $1, %%ecx\n\t" + "jnc 1f\n\t" // jnc skipit2 + "movw -1(%%esi), %%ax\n\t" + "subl $2, %%esi\n\t" + "rorw $8, %%ax\n\t" + "movw %%ax, (%%edi)\n\t" + "addl $2, %%edi\n\t" + "1:\n\t" // skipit2 + "testl %%ecx, %%ecx\n\t" + "jz 3f\n\t" // jz endloop + "2:\n\t" // begloop + "movl -3(%%esi), %%eax\n\t" + "subl $4, %%esi\n\t" + "bswapl %%eax\n\t" + "movl %%eax, (%%edi)\n\t" + "addl $4, %%edi\n\t" + "decl %%ecx\n\t" + "jnz 2b\n\t" // jnz begloop + "3:" + : "+S" (S), "+D" (D), "+c" (c) : + : "eax", "memory", "cc" + ); +} + +#elif defined(__WATCOMC__) // __GNUC__ && __i386__ + +// +// Watcom C Inline Assembler version +// + +#elif defined(_MSC_VER) // __WATCOMC__ + +// +// Microsoft C Inline Assembler version +// + +#else // _MSC_VER + +#error Unsupported compiler or architecture. + +#endif + + diff --git a/polymer/build/src/scriptfile.c b/polymer/build/src/scriptfile.c new file mode 100644 index 000000000..514cfcb93 --- /dev/null +++ b/polymer/build/src/scriptfile.c @@ -0,0 +1,394 @@ +/* + * File Tokeniser/Parser/Whatever + * by Jonathon Fowler + * Remixed completely by Ken Silverman + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "scriptfile.h" +#include "baselayer.h" +#include "compat.h" +#include "cache1d.h" + + +#define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n')) +static void skipoverws(scriptfile *sf) { if ((sf->textptr < sf->eof) && (!sf->textptr[0])) sf->textptr++; } +static void skipovertoken(scriptfile *sf) { while ((sf->textptr < sf->eof) && (sf->textptr[0])) sf->textptr++; } + +char *scriptfile_gettoken(scriptfile *sf) +{ + char *start; + + skipoverws(sf); + if (sf->textptr >= sf->eof) return NULL; + + start = sf->ltextptr = sf->textptr; + skipovertoken(sf); + return start; +} + +int scriptfile_getstring(scriptfile *sf, char **retst) +{ + (*retst) = scriptfile_gettoken(sf); + if (*retst == NULL) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return(-2); + } + return(0); +} + +int scriptfile_getnumber(scriptfile *sf, int *num) +{ + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + while ((sf->textptr[0] == '0') && (sf->textptr[1] >= '0') && (sf->textptr[1] <= '9')) + sf->textptr++; //hack to treat octal numbers like decimal + + sf->ltextptr = sf->textptr; + (*num) = strtol((const char *)sf->textptr,&sf->textptr,0); + if (!ISWS(*sf->textptr) && *sf->textptr) { + char *p = sf->textptr; + skipovertoken(sf); + initprintf("Error on line %s:%d: expecting int, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); + return -2; + } + return 0; +} + +static double parsedouble(char *ptr, char **end) +{ + int beforedecimal = 1, negative = 0, dig; + int exposgn = 0, expo = 0; + double num = 0.0, decpl = 0.1; + char *p; + + p = ptr; + if (*p == '-') negative = 1, p++; + else if (*p == '+') p++; + for (;; p++) { + if (*p >= '0' && *p <= '9') { + dig = *p - '0'; + if (beforedecimal) num = num * 10.0 + dig; + else if (exposgn) expo = expo*10 + dig; + else { + num += (double)dig * decpl; + decpl /= 10.0; + } + } else if (*p == '.') { + if (beforedecimal) beforedecimal = 0; + else break; + } else if ((*p == 'E') || (*p == 'e')) { + exposgn = 1; + if (p[1] == '-') { exposgn = -1; p++; } + else if (p[1] == '+') p++; + } else break; + } + + if (end) *end = p; + if (exposgn) num *= pow(10.0,(double)(expo*exposgn)); + return negative ? -num : num; +} + +int scriptfile_getdouble(scriptfile *sf, double *num) +{ + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + sf->ltextptr = sf->textptr; + + // On Linux, locale settings interfere with interpreting x.y format numbers + //(*num) = strtod((const char *)sf->textptr,&sf->textptr); + (*num) = parsedouble(sf->textptr, &sf->textptr); + + if (!ISWS(*sf->textptr) && *sf->textptr) { + char *p = sf->textptr; + skipovertoken(sf); + initprintf("Error on line %s:%d: expecting float, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); + return -2; + } + return 0; +} + +int scriptfile_getsymbol(scriptfile *sf, int *num) +{ + char *t, *e; + int v; + + t = scriptfile_gettoken(sf); + if (!t) return -1; + + v = Bstrtol(t, &e, 10); + if (*e) { + // looks like a string, so find it in the symbol table + if (scriptfile_getsymbolvalue(t, num)) return 0; + initprintf("Error on line %s:%d: expecting symbol, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),t); + return -2; // not found + } + + *num = v; + return 0; +} + +int scriptfile_getbraces(scriptfile *sf, char **braceend) +{ + int bracecnt; + char *bracestart; + + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + if (sf->textptr[0] != '{') { + initprintf("Error on line %s:%d: expecting '{'\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + bracestart = ++sf->textptr; bracecnt = 1; + while (1) + { + if (sf->textptr >= sf->eof) return(0); + if (sf->textptr[0] == '{') bracecnt++; + if (sf->textptr[0] == '}') { bracecnt--; if (!bracecnt) break; } + sf->textptr++; + } + (*braceend) = sf->textptr; + sf->textptr = bracestart; + return 0; +} + + +int scriptfile_getlinum (scriptfile *sf, char *ptr) +{ + int i, stp, ind; + + //for(i=0;ilinenum;i++) if (sf->lineoffs[i] >= ind) return(i+1); //brute force algo + + ind = ((long)ptr) - ((long)sf->textbuf); + + for(stp=1;stp+stplinenum;stp+=stp); //stp = highest power of 2 less than sf->linenum + for(i=0;stp;stp>>=1) + if ((i+stp < sf->linenum) && (sf->lineoffs[i+stp] < ind)) i += stp; + return(i+1); //i = index to highest lineoffs which is less than ind; convert to 1-based line numbers +} + +void scriptfile_preparse (scriptfile *sf, char *tx, long flen) +{ + long i, cr, numcr, nflen, ws, cs, inquote; + + //Count number of lines + numcr = 1; + for(i=0;ilinenum = numcr; + sf->lineoffs = (long *)malloc(sf->linenum*sizeof(long)); + + //Preprocess file for comments (// and /*...*/, and convert all whitespace to single spaces) + nflen = 0; ws = 0; cs = 0; numcr = 0; inquote = 0; + for(i=0;ilineoffs[numcr++] = nflen; + if (cs == 1) cs = 0; + ws = 1; continue; //strip CR/LF + } + + if ((!inquote) && ((tx[i] == ' ') || (tx[i] == '\t'))) { ws = 1; continue; } //strip Space/Tab + if ((tx[i] == '/') && (tx[i+1] == '/') && (!cs)) cs = 1; + if ((tx[i] == '/') && (tx[i+1] == '*') && (!cs)) { ws = 1; cs = 2; } + if ((tx[i] == '*') && (tx[i+1] == '/') && (cs == 2)) { cs = 0; i++; continue; } + if (cs) continue; + + if (ws) { tx[nflen++] = 0; ws = 0; } + + //quotes inside strings: \" + if ((tx[i] == '\\') && (tx[i+1] == '\"')) { i++; tx[nflen++] = '\"'; continue; } + if (tx[i] == '\"') { inquote ^= 1; continue; } + tx[nflen++] = tx[i]; + } + tx[nflen++] = 0; sf->lineoffs[numcr] = nflen; + tx[nflen++] = 0; + +#if 0 + //for debugging only: + printf("pre-parsed file:flen=%d,nflen=%d\n",flen,nflen); + for(i=0;ilinenum); + for(i=0;ilinenum;i++) printf("line %d = byte %d\n",i,sf->lineoffs[i]); +#endif + flen = nflen; + + sf->textbuf = sf->textptr = tx; + sf->textlength = nflen; + sf->eof = &sf->textbuf[nflen-1]; +} + +scriptfile *scriptfile_fromfile(char *fn) +{ + int fp; + scriptfile *sf; + char *tx; + unsigned int flen; + + fp = kopen4load(fn,0); + if (fp<0) return NULL; + + flen = kfilelength(fp); + tx = (char *) malloc(flen + 2); + if (!tx) { + kclose(fp); + return NULL; + } + + sf = (scriptfile*) malloc(sizeof(scriptfile)); + if (!sf) { + kclose(fp); + free(tx); + return NULL; + } + + kread(fp, tx, flen); + tx[flen] = tx[flen+1] = 0; + + kclose(fp); + + scriptfile_preparse(sf,tx,flen); + sf->filename = strdup(fn); + + return sf; +} + +scriptfile *scriptfile_fromstring(char *string) +{ + scriptfile *sf; + char *tx; + unsigned int flen; + + if (!string) return NULL; + + flen = strlen(string); + + tx = (char *) malloc(flen + 2); + if (!tx) return NULL; + + sf = (scriptfile*) malloc(sizeof(scriptfile)); + if (!sf) { + free(tx); + return NULL; + } + + memcpy(tx, string, flen); + tx[flen] = tx[flen+1] = 0; + + scriptfile_preparse(sf,tx,flen); + sf->filename = NULL; + + return sf; +} + +void scriptfile_close(scriptfile *sf) +{ + if (!sf) return; + if (sf->lineoffs) free(sf->lineoffs); + if (sf->textbuf) free(sf->textbuf); + if (sf->filename) free(sf->filename); + sf->textbuf = NULL; + sf->filename = NULL; + free(sf); +} + + +#define SYMBTABSTARTSIZE 256 +static int symbtablength=0, symbtaballoclength=0; +static char *symbtab = NULL; + +static char * getsymbtabspace(int reqd) +{ + char *pos,*np; + int i; + + if (symbtablength + reqd > symbtaballoclength) + { + for(i=max(symbtaballoclength,SYMBTABSTARTSIZE);symbtablength+reqd>i;i<<=1); + np = (char *)realloc(symbtab, i); if (!np) return NULL; + symbtab = np; symbtaballoclength = i; + } + + pos = &symbtab[symbtablength]; + symbtablength += reqd; + return pos; +} + +int scriptfile_getsymbolvalue(char *name, int *val) +{ + char *scanner = symbtab; + + if (!symbtab) return 0; + while (scanner - symbtab < symbtablength) { + if (!Bstrcasecmp(name, scanner)) { + *val = *(int*)(scanner + strlen(scanner) + 1); + return 1; + } + + scanner += strlen(scanner) + 1 + sizeof(int); + } + + return 0; +} + +int scriptfile_addsymbolvalue(char *name, int val) +{ + int x; + char *sp; +// if (scriptfile_getsymbolvalue(name, &x)) return -1; // already exists + + if (symbtab) { + char *scanner = symbtab; + while (scanner - symbtab < symbtablength) { + if (!Bstrcasecmp(name, scanner)) { + *(int*)(scanner + strlen(scanner) + 1) = val; + return 1; + } + + scanner += strlen(scanner) + 1 + sizeof(int); + } + } + + sp = getsymbtabspace(strlen(name) + 1 + sizeof(int)); + if (!sp) return 0; + strcpy(sp, name); + sp += strlen(name)+1; + *(int*)sp = val; + return 1; // added +} + +void scriptfile_clearsymbols(void) +{ + if (symbtab) free(symbtab); + symbtab = NULL; + symbtablength = 0; + symbtaballoclength = 0; +} diff --git a/polymer/build/src/sdlayer.c b/polymer/build/src/sdlayer.c new file mode 100644 index 000000000..2ebb2e08c --- /dev/null +++ b/polymer/build/src/sdlayer.c @@ -0,0 +1,1510 @@ +// SDL interface layer +// for the Build Engine +// by Jonathon Fowler (jonof@edgenetwk.com) +// +// Use SDL1.2 from http://www.libsdl.org + +#include +#include +#ifndef __APPLE__ +# include "SDL.h" +#endif +#include "compat.h" +#include "sdlayer.h" +#include "cache1d.h" +#include "pragmas.h" +#include "a.h" +#include "build.h" +#include "osd.h" + +#ifdef USE_OPENGL +# include "glbuild.h" +#endif + +#if defined __APPLE__ +# include +# include "osxbits.h" +#elif defined HAVE_GTK2 +# include "gtkbits.h" +#endif + +#define SURFACE_FLAGS (SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWACCEL) + +// undefine to restrict windowed resolutions to conventional sizes +#define ANY_WINDOWED_SIZE + +int _buildargc = 1; +char **_buildargv = NULL; +extern long app_main(long argc, char *argv[]); + +char quitevent=0, appactive=1; + +// video +static SDL_Surface *sdl_surface; +long xres=-1, yres=-1, bpp=0, fullscreen=0, bytesperline, imageSize; +long frameplace=0, lockcount=0; +char modechange=1; +char offscreenrendering=0; +char videomodereset = 0; +char nofog=0; +static unsigned short sysgamma[3][256]; +extern long curbrightness, gammabrightness; + +#ifdef USE_OPENGL +// OpenGL stuff +static char nogl=0; +#endif + +// input +char inputdevices=0; +char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; +unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; +static unsigned char keynames[256][24]; +long mousex=0,mousey=0,mouseb=0; +long *joyaxis = NULL, joyb=0, *joyhat = NULL; +char joyisgamepad=0, joynumaxes=0, joynumbuttons=0, joynumhats=0; +long joyaxespresent=0; + + +void (*keypresscallback)(long,long) = 0; +void (*mousepresscallback)(long,long) = 0; +void (*joypresscallback)(long,long) = 0; + +static unsigned char keytranslation[SDLK_LAST]; +static int buildkeytranslationtable(void); + +//static SDL_Surface * loadtarga(const char *fn); // for loading the icon +static SDL_Surface * loadappicon(void); + +int wm_msgbox(char *name, char *fmt, ...) +{ + char buf[1000]; + va_list va; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + +#if defined(__APPLE__) + return osx_msgbox(name, buf); +#elif defined HAVE_GTK2 + if (gtkbuild_msgbox(name, buf) >= 0) return 1; +#endif + puts(buf); + puts(" (press Return or Enter to continue)"); + getchar(); + + return 0; +} + +int wm_ynbox(char *name, char *fmt, ...) +{ + char buf[1000]; + char c; + va_list va; + int r; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + +#if defined __APPLE__ + return osx_ynbox(name, buf); +#elif defined HAVE_GTK2 + if ((r = gtkbuild_ynbox(name, buf)) >= 0) return r; +#endif + puts(buf); + puts(" (type 'Y' or 'N', and press Return or Enter to continue)"); + do c = getchar(); while (c != 'Y' && c != 'y' && c != 'N' && c != 'n'); + if (c == 'Y' || c == 'y') return 1; + + return 0; +} + +void wm_setapptitle(char *name) +{ + if (name) { + Bstrncpy(apptitle, name, sizeof(apptitle)-1); + apptitle[ sizeof(apptitle)-1 ] = 0; + } + + SDL_WM_SetCaption(apptitle, NULL); + +#ifdef HAVE_GTK2 + gtkbuild_settitle_startwin(apptitle); +#endif +} + + +// +// +// --------------------------------------- +// +// System +// +// --------------------------------------- +// +// + +int main(int argc, char *argv[]) +{ + int r; + + buildkeytranslationtable(); + +#ifdef HAVE_GTK2 + gtkbuild_init(&argc, &argv); + gtkbuild_create_startwin(); +#endif + + _buildargc = argc; + _buildargv = (char**)argv; + //_buildargv = (char**)malloc(argc * sizeof(char*)); + //memcpy(_buildargv, argv, sizeof(char*)*argc); + + baselayer_init(); + r = app_main(argc, argv); + +#ifdef HAVE_GTK2 + gtkbuild_close_startwin(); + gtkbuild_exit(r); +#endif + return r; +} + + +// +// initsystem() -- init SDL systems +// +int initsystem(void) +{ + const SDL_VideoInfo *vid; + const SDL_version *linked = SDL_Linked_Version(); + SDL_version compiled; + char drvname[32]; + + SDL_VERSION(&compiled); + + initprintf("Initialising SDL system interface " + "(compiled with SDL version %d.%d.%d, DLL version %d.%d.%d)\n", + linked->major, linked->minor, linked->patch, + compiled.major, compiled.minor, compiled.patch); + + if (SDL_Init(SDL_INIT_VIDEO //| SDL_INIT_TIMER +#ifdef NOSDLPARACHUTE + | SDL_INIT_NOPARACHUTE +#endif + )) { + initprintf("Initialisation failed! (%s)\n", SDL_GetError()); + return -1; + } + + atexit(uninitsystem); + + frameplace = 0; + lockcount = 0; + +#ifdef USE_OPENGL + if (loadgldriver(getenv("BUILD_GLDRV"))) { + initprintf("Failed loading OpenGL driver. GL modes will be unavailable.\n"); + nogl = 1; + } +#endif + +#ifndef __APPLE__ + { + SDL_Surface *icon; + //icon = loadtarga("icon.tga"); + icon = loadappicon(); + if (icon) { + SDL_WM_SetIcon(icon, 0); + SDL_FreeSurface(icon); + } + } +#endif + + if (SDL_VideoDriverName(drvname, 32)) + initprintf("Using \"%s\" video driver\n", drvname); + + // dump a quick summary of the graphics hardware +#ifdef DEBUGGINGAIDS + vid = SDL_GetVideoInfo(); + initprintf("Video device information:\n"); + initprintf(" Can create hardware surfaces? %s\n", (vid->hw_available)?"Yes":"No"); + initprintf(" Window manager available? %s\n", (vid->wm_available)?"Yes":"No"); + initprintf(" Accelerated hardware blits? %s\n", (vid->blit_hw)?"Yes":"No"); + initprintf(" Accelerated hardware colourkey blits? %s\n", (vid->blit_hw_CC)?"Yes":"No"); + initprintf(" Accelerated hardware alpha blits? %s\n", (vid->blit_hw_A)?"Yes":"No"); + initprintf(" Accelerated software blits? %s\n", (vid->blit_sw)?"Yes":"No"); + initprintf(" Accelerated software colourkey blits? %s\n", (vid->blit_sw_CC)?"Yes":"No"); + initprintf(" Accelerated software alpha blits? %s\n", (vid->blit_sw_A)?"Yes":"No"); + initprintf(" Accelerated colour fills? %s\n", (vid->blit_fill)?"Yes":"No"); + initprintf(" Total video memory: %dKB\n", vid->video_mem); +#endif + + return 0; +} + + +// +// uninitsystem() -- uninit SDL systems +// +void uninitsystem(void) +{ + uninitinput(); + uninitmouse(); + uninittimer(); + + SDL_Quit(); + +#ifdef USE_OPENGL + unloadgldriver(); +#endif +} + + +// +// initprintf() -- prints a string to the intitialization window +// +void initprintf(const char *f, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, f); + vprintf(f,va); + va_end(va); + + va_start(va, f); + Bvsnprintf(buf, 1024, f, va); + va_end(va); + OSD_Printf(buf); + +#ifdef HAVE_GTK2 + gtkbuild_puts_startwin(buf); + gtkbuild_update_startwin(); +#endif +} + + +// +// debugprintf() -- prints a debug string to stderr +// +void debugprintf(const char *f, ...) +{ +#ifdef DEBUGGINGAIDS + va_list va; + + va_start(va,f); + Bvfprintf(stderr, f, va); + va_end(va); +#endif +} + + +// +// +// --------------------------------------- +// +// All things Input +// +// --------------------------------------- +// +// + +static char mouseacquired=0,moustat=0; +static long joyblast=0; +static SDL_Joystick *joydev = NULL; + +// +// initinput() -- init input system +// +int initinput(void) +{ + int i,j; + +#ifdef __APPLE__ + // force OS X to operate in >1 button mouse mode so that LMB isn't adulterated + if (!getenv("SDL_HAS3BUTTONMOUSE")) putenv("SDL_HAS3BUTTONMOUSE=1"); +#endif + + if (SDL_EnableKeyRepeat(250, 30)) initprintf("Error enabling keyboard repeat.\n"); + inputdevices = 1|2; // keyboard (1) and mouse (2) + mouseacquired = 0; + + SDL_EnableUNICODE(1); // let's hope this doesn't hit us too hard + + memset(keynames,0,sizeof(keynames)); + for (i=0; i= 256) return NULL; + return keynames[num]; +} + +const unsigned char *getjoyname(int what, int num) +{ + static char tmp[64]; + + switch (what) { + case 0: // axis + if ((unsigned)num > (unsigned)joynumaxes) return NULL; + sprintf(tmp,"Axis %d",num); + return tmp; + + case 1: // button + if ((unsigned)num > (unsigned)joynumbuttons) return NULL; + sprintf(tmp,"Button %d",num); + return tmp; + + case 2: // hat + if ((unsigned)num > (unsigned)joynumhats) return NULL; + sprintf(tmp,"Hat %d",num); + return tmp; + + default: + return NULL; + } +} + +// +// bgetchar, bkbhit, bflushchars -- character-based input functions +// +unsigned char bgetchar(void) +{ + unsigned char c; + if (keyasciififoplc == keyasciififoend) return 0; + c = keyasciififo[keyasciififoplc]; + keyasciififoplc = ((keyasciififoplc+1)&(KEYFIFOSIZ-1)); + return c; +} + +int bkbhit(void) +{ + return (keyasciififoplc != keyasciififoend); +} + +void bflushchars(void) +{ + keyasciififoplc = keyasciififoend = 0; +} + + +// +// set{key|mouse|joy}presscallback() -- sets a callback which gets notified when keys are pressed +// +void setkeypresscallback(void (*callback)(long, long)) { keypresscallback = callback; } +void setmousepresscallback(void (*callback)(long, long)) { mousepresscallback = callback; } +void setjoypresscallback(void (*callback)(long, long)) { joypresscallback = callback; } + +// +// initmouse() -- init mouse input +// +int initmouse(void) +{ + moustat=1; + grabmouse(1); + return 0; +} + +// +// uninitmouse() -- uninit mouse input +// +void uninitmouse(void) +{ + grabmouse(0); + moustat=0; +} + + +// +// grabmouse() -- show/hide mouse cursor +// +void grabmouse(char a) +{ + if (appactive && moustat) { + if (a != mouseacquired) { +#ifndef DEBUGGINGAIDS + SDL_GrabMode g; + + g = SDL_WM_GrabInput( a ? SDL_GRAB_ON : SDL_GRAB_OFF ); + mouseacquired = (g == SDL_GRAB_ON); + + SDL_ShowCursor(mouseacquired ? SDL_DISABLE : SDL_ENABLE); +#else + mouseacquired = a; +#endif + } + } else { + mouseacquired = a; + } + mousex = mousey = 0; +} + + +// +// readmousexy() -- return mouse motion information +// +void readmousexy(long *x, long *y) +{ + if (!mouseacquired || !appactive || !moustat) { *x = *y = 0; return; } + *x = mousex; + *y = mousey; + mousex = mousey = 0; +} + +// +// readmousebstatus() -- return mouse button information +// +void readmousebstatus(long *b) +{ + if (!mouseacquired || !appactive || !moustat) *b = 0; + else *b = mouseb; +} + +// +// setjoydeadzone() -- sets the dead and saturation zones for the joystick +// +void setjoydeadzone(int axis, unsigned short dead, unsigned short satur) +{ +} + + +// +// getjoydeadzone() -- gets the dead and saturation zones for the joystick +// +void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur) +{ + *dead = *satur = 0; +} + + +// +// releaseallbuttons() +// +void releaseallbuttons(void) +{ +} + + +// +// +// --------------------------------------- +// +// All things Timer +// Ken did this +// +// --------------------------------------- +// +// + +static Uint32 timerfreq=0; +static Uint32 timerlastsample=0; +static Uint32 timerticspersec=0; +static void (*usertimercallback)(void) = NULL; + +// +// inittimer() -- initialise timer +// +int inittimer(int tickspersecond) +{ + if (timerfreq) return 0; // already installed + + initprintf("Initialising timer\n"); + + timerfreq = 1000; + timerticspersec = tickspersecond; + timerlastsample = SDL_GetTicks() * timerticspersec / timerfreq; + + usertimercallback = NULL; + + return 0; +} + +// +// uninittimer() -- shut down timer +// +void uninittimer(void) +{ + if (!timerfreq) return; + + timerfreq=0; +} + +// +// sampletimer() -- update totalclock +// +void sampletimer(void) +{ + Uint32 i; + long n; + + if (!timerfreq) return; + + i = SDL_GetTicks(); + n = (long)(i * timerticspersec / timerfreq) - timerlastsample; + if (n>0) { + totalclock += n; + timerlastsample += n; + } + + if (usertimercallback) for (; n>0; n--) usertimercallback(); +} + +// +// getticks() -- returns the sdl ticks count +// +unsigned long getticks(void) +{ + return (unsigned long)SDL_GetTicks(); +} + + +// +// gettimerfreq() -- returns the number of ticks per second the timer is configured to generate +// +int gettimerfreq(void) +{ + return timerticspersec; +} + + +// +// installusertimercallback() -- set up a callback function to be called when the timer is fired +// +void (*installusertimercallback(void (*callback)(void)))(void) +{ + void (*oldtimercallback)(void); + + oldtimercallback = usertimercallback; + usertimercallback = callback; + + return oldtimercallback; +} + + + +// +// +// --------------------------------------- +// +// All things Video +// +// --------------------------------------- +// +// + + +// +// getvalidmodes() -- figure out what video modes are available +// +static int sortmodes(const struct validmode_t *a, const struct validmode_t *b) +{ + int x; + + if ((x = a->fs - b->fs) != 0) return x; + if ((x = a->bpp - b->bpp) != 0) return x; + if ((x = a->xdim - b->xdim) != 0) return x; + if ((x = a->ydim - b->ydim) != 0) return x; + + return 0; +} +static char modeschecked=0; +void getvalidmodes(void) +{ + static int cdepths[] = { + 8, +#ifdef USE_OPENGL + 16,24,32, +#endif + 0 }; + static int defaultres[][2] = { + {1280,1024},{1280,960},{1152,864},{1024,768},{800,600},{640,480}, + {640,400},{512,384},{480,360},{400,300},{320,240},{320,200},{0,0} + }; + SDL_Rect **modes; + SDL_PixelFormat pf = { NULL, 8, 1, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0 }; + int i, j, maxx=0, maxy=0; + + if (modeschecked) return; + + validmodecnt=0; + initprintf("Detecting video modes:\n"); + +#define ADDMODE(x,y,c,f) if (validmodecnt> 3; + + modes = SDL_ListModes(&pf, SURFACE_FLAGS | SDL_FULLSCREEN); + if (modes == (SDL_Rect **)0) { + if (cdepths[j] > 8) cdepths[j] = -1; + continue; + } + + if (modes == (SDL_Rect **)-1) { + for (i=0; defaultres[i][0]; i++) + ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],1) + } else { + for (i=0; modes[i]; i++) { + if ((modes[i]->w > MAXXDIM) || (modes[i]->h > MAXYDIM)) continue; + + ADDMODE(modes[i]->w, modes[i]->h, cdepths[j], 1) + + if ((modes[i]->w > maxx) && (modes[i]->h > maxy)) { + maxx = modes[i]->w; + maxy = modes[i]->h; + } + } + } + } + + if (maxx == 0 && maxy == 0) { + initprintf("No fullscreen modes available!\n"); + maxx = MAXXDIM; maxy = MAXYDIM; + } + + // add windowed modes next + for (j=0; cdepths[j]; j++) { + if (cdepths[j] < 0) continue; + for (i=0; defaultres[i][0]; i++) + CHECK(defaultres[i][0],defaultres[i][1]) + ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],0) + } + +#undef CHECK +#undef ADDMODE + + qsort((void*)validmode, validmodecnt, sizeof(struct validmode_t), (int(*)(const void*,const void*))sortmodes); + + modeschecked=1; +} + + +// +// checkvideomode() -- makes sure the video mode passed is legal +// +int checkvideomode(int *x, int *y, int c, int fs) +{ + int i, nearest=-1, dx, dy, odx=9999, ody=9999; + + getvalidmodes(); + + if (c>8 +#ifdef USE_OPENGL + && nogl +#endif + ) return -1; + + // fix up the passed resolution values to be multiples of 8 + // and at least 320x200 or at most MAXXDIMxMAXYDIM + if (*x < 320) *x = 320; + if (*y < 200) *y = 200; + if (*x > MAXXDIM) *x = MAXXDIM; + if (*y > MAXYDIM) *y = MAXYDIM; + *x &= 0xfffffff8l; + + for (i=0; i 8 && sdl_surface) polymost_glreset(); +#endif + + // restore gamma before we change video modes if it was changed + if (sdl_surface && gammabrightness) { + SDL_SetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]); + gammabrightness = 0; // redetect on next mode switch + } + +#if defined(USE_OPENGL) + if (c > 8) { + int i, j, multisamplecheck = (glmultisample > 0); + struct { + SDL_GLattr attr; + int value; + } attributes[] = { +#if 0 + { SDL_GL_RED_SIZE, 8 }, + { SDL_GL_GREEN_SIZE, 8 }, + { SDL_GL_BLUE_SIZE, 8 }, + { SDL_GL_ALPHA_SIZE, 8 }, + { SDL_GL_BUFFER_SIZE, c }, + { SDL_GL_STENCIL_SIZE, 0 }, + { SDL_GL_ACCUM_RED_SIZE, 0 }, + { SDL_GL_ACCUM_GREEN_SIZE, 0 }, + { SDL_GL_ACCUM_BLUE_SIZE, 0 }, + { SDL_GL_ACCUM_ALPHA_SIZE, 0 }, + { SDL_GL_DEPTH_SIZE, 24 }, +#endif + { SDL_GL_DOUBLEBUFFER, 1 }, + { SDL_GL_MULTISAMPLEBUFFERS, glmultisample > 0 }, + { SDL_GL_MULTISAMPLESAMPLES, glmultisample }, + }; + + if (nogl) return -1; + + initprintf("Setting video mode %dx%d (%d-bpp %s)\n", + x,y,c, ((fs&1) ? "fullscreen" : "windowed")); + do { + for (i=0; i < (int)(sizeof(attributes)/sizeof(attributes[0])); i++) { + j = attributes[i].value; + if (!multisamplecheck && + (attributes[i].attr == SDL_GL_MULTISAMPLEBUFFERS || + attributes[i].attr == SDL_GL_MULTISAMPLESAMPLES) + ) { + j = 0; + } + SDL_GL_SetAttribute(attributes[i].attr, j); + } + + sdl_surface = SDL_SetVideoMode(x, y, c, SDL_OPENGL | ((fs&1)?SDL_FULLSCREEN:0)); + if (!sdl_surface) { + if (multisamplecheck) { + initprintf("Multisample mode not possible. Retrying without multisampling.\n"); + glmultisample = 0; + continue; + } + initprintf("Unable to set video mode!\n"); + return -1; + } + } while (multisamplecheck--); + } else +#endif + { + initprintf("Setting video mode %dx%d (%d-bpp %s)\n", + x,y,c, ((fs&1) ? "fullscreen" : "windowed")); + sdl_surface = SDL_SetVideoMode(x, y, c, SURFACE_FLAGS | ((fs&1)?SDL_FULLSCREEN:0)); + if (!sdl_surface) { + initprintf("Unable to set video mode!\n"); + return -1; + } + } + +#if 0 + { + char flags[512] = ""; +#define FLAG(x,y) if ((sdl_surface->flags & x) == x) { strcat(flags, y); strcat(flags, " "); } + FLAG(SDL_HWSURFACE, "HWSURFACE") else + FLAG(SDL_SWSURFACE, "SWSURFACE") + FLAG(SDL_ASYNCBLIT, "ASYNCBLIT") + FLAG(SDL_ANYFORMAT, "ANYFORMAT") + FLAG(SDL_HWPALETTE, "HWPALETTE") + FLAG(SDL_DOUBLEBUF, "DOUBLEBUF") + FLAG(SDL_FULLSCREEN, "FULLSCREEN") + FLAG(SDL_OPENGL, "OPENGL") + FLAG(SDL_OPENGLBLIT, "OPENGLBLIT") + FLAG(SDL_RESIZABLE, "RESIZABLE") + FLAG(SDL_HWACCEL, "HWACCEL") + FLAG(SDL_SRCCOLORKEY, "SRCCOLORKEY") + FLAG(SDL_RLEACCEL, "RLEACCEL") + FLAG(SDL_SRCALPHA, "SRCALPHA") + FLAG(SDL_PREALLOC, "PREALLOC") +#undef FLAG + initprintf("SDL Surface flags: %s\n", flags); + } +#endif + + { + //static char t[384]; + //sprintf(t, "%s (%dx%d %s)", apptitle, x, y, ((fs) ? "fullscreen" : "windowed")); + SDL_WM_SetCaption(apptitle, 0); + } + +#ifdef USE_OPENGL + if (c > 8) { + GLubyte *p,*p2,*p3; + int i; + + polymost_glreset(); + + bglEnable(GL_TEXTURE_2D); + bglShadeModel(GL_SMOOTH); //GL_FLAT + bglClearColor(0,0,0,0.5); //Black Background + bglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho! + bglHint(GL_LINE_SMOOTH_HINT,GL_NICEST); + bglDisable(GL_DITHER); + + glinfo.vendor = bglGetString(GL_VENDOR); + glinfo.renderer = bglGetString(GL_RENDERER); + glinfo.version = bglGetString(GL_VERSION); + glinfo.extensions = bglGetString(GL_EXTENSIONS); + + glinfo.maxanisotropy = 1.0; + glinfo.bgra = 0; + glinfo.texcompr = 0; + + // process the extensions string and flag stuff we recognize + p = Bstrdup(glinfo.extensions); + p3 = p; + while ((p2 = Bstrtoken(p3==p?p:NULL, " ", (char**)&p3, 1)) != NULL) { + if (!Bstrcmp(p2, "GL_EXT_texture_filter_anisotropic")) { + // supports anisotropy. get the maximum anisotropy level + bglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy); + } else if (!Bstrcmp(p2, "GL_EXT_texture_edge_clamp") || + !Bstrcmp(p2, "GL_SGIS_texture_edge_clamp")) { + // supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS + glinfo.clamptoedge = 1; + } else if (!Bstrcmp(p2, "GL_EXT_bgra")) { + // support bgra textures + glinfo.bgra = 1; + } else if (!Bstrcmp(p2, "GL_ARB_texture_compression")) { + // support texture compression + glinfo.texcompr = 1; + } else if (!Bstrcmp(p2, "GL_ARB_texture_non_power_of_two")) { + // support non-power-of-two texture sizes + glinfo.texnpot = 1; + } else if (!Bstrcmp(p2, "WGL_3DFX_gamma_control")) { + // 3dfx cards have issues with fog + nofog = 1; + if (!(warnonce&1)) initprintf("3dfx card detected: OpenGL fog disabled\n"); + warnonce |= 1; + } else if (!Bstrcmp(p2, "GL_ARB_multisample")) { + // supports multisampling + glinfo.multisample = 1; + } else if (!Bstrcmp(p2, "GL_NV_multisample_filter_hint")) { + // supports nvidia's multisample hint extension + glinfo.nvmultisamplehint = 1; + } + } + Bfree(p); + } +#endif + + xres = x; + yres = y; + bpp = c; + fullscreen = fs; + //bytesperline = sdl_surface->pitch; + //imageSize = bytesperline*yres; + numpages = c>8?2:1; + frameplace = 0; + lockcount = 0; + modechange=1; + videomodereset = 0; + OSD_ResizeDisplay(xres,yres); + + // save the current system gamma to determine if gamma is available + if (!gammabrightness) { + float f = 1.0 + ((float)curbrightness / 10.0); + if (SDL_GetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]) >= 0) + gammabrightness = 1; + + // see if gamma really is working by trying to set the brightness + if (gammabrightness && SDL_SetGamma(f,f,f) < 0) + gammabrightness = 0; // nope + } + + // setpalettefade will set the palette according to whether gamma worked + setpalettefade(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + + //if (c==8) setpalette(0,256,0); + //baselayer_onvideomodechange(c>8); + + if (regrab) grabmouse(1); + + return 0; +} + + +// +// resetvideomode() -- resets the video system +// +void resetvideomode(void) +{ + videomodereset = 1; + modeschecked = 0; +} + + +// +// begindrawing() -- locks the framebuffer for drawing +// +void begindrawing(void) +{ + long i,j; + + if (bpp > 8) { + if (offscreenrendering) return; + frameplace = 0; + bytesperline = 0; + imageSize = 0; + modechange = 0; + return; + } + + // lock the frame + if (lockcount++ > 0) + return; + + if (offscreenrendering) return; + + if (SDL_MUSTLOCK(sdl_surface)) SDL_LockSurface(sdl_surface); + frameplace = (long)sdl_surface->pixels; + + if (sdl_surface->pitch != bytesperline || modechange) { + bytesperline = sdl_surface->pitch; + imageSize = bytesperline*yres; + setvlinebpl(bytesperline); + + j = 0; + for(i=0;i<=ydim;i++) ylookup[i] = j, j += bytesperline; + modechange=0; + } +} + + +// +// enddrawing() -- unlocks the framebuffer +// +void enddrawing(void) +{ + if (bpp > 8) { + if (!offscreenrendering) frameplace = 0; + return; + } + + if (!frameplace) return; + if (lockcount > 1) { lockcount--; return; } + if (!offscreenrendering) frameplace = 0; + if (lockcount == 0) return; + lockcount = 0; + + if (offscreenrendering) return; + + if (SDL_MUSTLOCK(sdl_surface)) SDL_UnlockSurface(sdl_surface); +} + + +// +// showframe() -- update the display +// +void showframe(int w) +{ + long i,j; + +#ifdef USE_OPENGL + if (bpp > 8) { + if (palfadedelta) { + bglMatrixMode(GL_PROJECTION); + bglPushMatrix(); + bglLoadIdentity(); + bglMatrixMode(GL_MODELVIEW); + bglPushMatrix(); + bglLoadIdentity(); + + bglDisable(GL_DEPTH_TEST); + bglDisable(GL_ALPHA_TEST); + bglDisable(GL_TEXTURE_2D); + + bglEnable(GL_BLEND); + bglColor4ub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + + bglBegin(GL_QUADS); + bglVertex2i(-1, -1); + bglVertex2i(1, -1); + bglVertex2i(1, 1); + bglVertex2i(-1, 1); + bglEnd(); + + bglMatrixMode(GL_MODELVIEW); + bglPopMatrix(); + bglMatrixMode(GL_PROJECTION); + bglPopMatrix(); + } + + SDL_GL_SwapBuffers(); + return; + } +#endif + + if (offscreenrendering) return; + + if (lockcount) { + printf("Frame still locked %ld times when showframe() called.\n", lockcount); + while (lockcount) enddrawing(); + } + + SDL_Flip(sdl_surface); +} + + +// +// setpalette() -- set palette values +// +int setpalette(int start, int num, char *dapal) +{ + SDL_Color pal[256]; + int i,n; + + if (bpp > 8) return 0; // no palette in opengl + + copybuf(curpalettefaded, pal, 256); + + for (i=start, n=num; n>0; i++, n--) { + /* + pal[i].b = dapal[0] << 2; + pal[i].g = dapal[1] << 2; + pal[i].r = dapal[2] << 2; + */ + curpalettefaded[i].f = pal[i].unused = 0; + dapal += 4; + } + + //return SDL_SetPalette(sdl_surface, SDL_LOGPAL|SDL_PHYSPAL, pal, 0, 256); + return SDL_SetColors(sdl_surface, pal, 0, 256); +} + +// +// getpalette() -- get palette values +// +/* +int getpalette(int start, int num, char *dapal) +{ + int i; + SDL_Palette *pal; + + // we shouldn't need to lock the surface to get the palette + pal = sdl_surface->format->palette; + + for (i=num; i>0; i--, start++) { + dapal[0] = pal->colors[start].b >> 2; + dapal[1] = pal->colors[start].g >> 2; + dapal[2] = pal->colors[start].r >> 2; + dapal += 4; + } + + return 1; +} +*/ + +// +// setgamma +// +int setgamma(float ro, float go, float bo) +{ + return SDL_SetGamma(ro,go,bo); +} + +#ifndef __APPLE__ +extern struct sdlappicon sdlappicon; +static SDL_Surface * loadappicon(void) +{ + SDL_Surface *surf; + + surf = SDL_CreateRGBSurfaceFrom((void*)sdlappicon.pixels, + sdlappicon.width, sdlappicon.height, 32, sdlappicon.width*4, + 0xffl,0xff00l,0xff0000l,0xff000000l); + + return surf; +} +#endif + +// +// +// --------------------------------------- +// +// Miscellany +// +// --------------------------------------- +// +// + + +// +// handleevents() -- process the SDL message queue +// returns !0 if there was an important event worth checking (like quitting) +// +int handleevents(void) +{ + int code, rv=0, j; + SDL_Event ev; + +#define SetKey(key,state) { \ + keystatus[key] = state; \ + if (state) { \ + keyfifo[keyfifoend] = key; \ + keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = state; \ + keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); \ + } \ +} + + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + code = keytranslation[ev.key.keysym.sym]; + + if (ev.key.keysym.unicode != 0 && ev.key.type == SDL_KEYDOWN && + (ev.key.keysym.unicode & 0xff80) == 0 && + ((keyasciififoend+1)&(KEYFIFOSIZ-1)) != keyasciififoplc) { + keyasciififo[keyasciififoend] = ev.key.keysym.unicode & 0x7f; + keyasciififoend = ((keyasciififoend+1)&(KEYFIFOSIZ-1)); + } + + // hook in the osd + if (OSD_HandleKey(code, (ev.key.type == SDL_KEYDOWN)) == 0) + break; + + if (ev.key.type == SDL_KEYDOWN) { + if (!keystatus[code]) { + SetKey(code, 1); + if (keypresscallback) + keypresscallback(code, 1); + } + } else { + SetKey(code, 0); + if (keypresscallback) + keypresscallback(code, 0); + } + break; + + case SDL_ACTIVEEVENT: + if (ev.active.state & SDL_APPINPUTFOCUS) { + appactive = ev.active.gain; + if (mouseacquired && moustat) { + if (appactive) { + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); + } else { + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); + } + } + rv=-1; + } + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + switch (ev.button.button) { + case SDL_BUTTON_LEFT: j = 0; break; + case SDL_BUTTON_RIGHT: j = 1; break; + case SDL_BUTTON_MIDDLE: j = 2; break; + default: j = -1; break; + } + if (j<0) break; + + if (ev.button.state == SDL_PRESSED) + mouseb |= (1< 48000) dasamplerate = 48000; + + musicstat = damusistat; + + printOSD("Initialising FMOD...\n"); + printOSD(" Linked version: %.02f\n", FMOD_VERSION); + printOSD(" DLL version: %.02f\n", FSOUND_GetVersion()); + + if (FSOUND_GetVersion() < FMOD_VERSION) { + printOSD(" ... Failure: FMOD DLL too old! Sound disabled.\n"); + return; + } + + printOSD(" Samplerate: %d hz\n", dasamplerate); + + //FSOUND_SetOutput(FSOUND_OUTPUT_ASIO); + + if (FSOUND_Init(dasamplerate, NUMCHANNELS, 0)) { + printOSD(" ... Success\n"); + fmod_inited = 1; + } else { + printOSD(" ... Failure: %s\n", FMOD_ErrorString(FSOUND_GetError())); + } + + switch (FSOUND_GetOutput()) { + case FSOUND_OUTPUT_NOSOUND: s = "No Sound"; break; + case FSOUND_OUTPUT_WINMM: s = "WINMM"; break; + case FSOUND_OUTPUT_DSOUND: s = "DirectSound"; break; + case FSOUND_OUTPUT_OSS: s = "OSS"; break; + case FSOUND_OUTPUT_ESD: s = "ESound"; break; + case FSOUND_OUTPUT_ALSA: s = "ALSA"; break; + case FSOUND_OUTPUT_ASIO: s = "ASIO"; break; + default: s = "Other"; break; + } + printOSD("Using FMOD \"%s\" output driver\n", s); + + FSOUND_File_SetCallbacks( + (FSOUND_OPENCALLBACK)f_open, + (FSOUND_CLOSECALLBACK)f_close, + (FSOUND_READCALLBACK)f_read, + (FSOUND_SEEKCALLBACK)f_seek, + (FSOUND_TELLCALLBACK)f_tell); + //FSOUND_SetMemorySystem(fmod_cache, fmod_cachelen, NULL, NULL, NULL); + + loadwaves(); + + for (i=0; i=0;wavnum--) { + bad = 0; + + i = 0; + while ((dafilename[i] > 0) && (i < 16)) + { + ch1 = dafilename[i]; if ((ch1 >= 97) && (ch1 <= 123)) ch1 -= 32; + ch2 = instname[wavnum][i]; if ((ch2 >= 97) && (ch2 <= 123)) ch2 -= 32; + if (ch1 != ch2) {bad = 1; break;} + i++; + } + if (bad != 0) continue; + + for (i=0; i oldestpos) { + oldest = i; + oldestpos = FSOUND_GetCurrentPosition(channels[i]); + } + } + + if (free < 0) { + FSOUND_StopSound(channels[oldest]); + free = oldest; + } + + chan = FSOUND_PlaySoundEx(FSOUND_FREE, samples[wavnum], NULL, 1); + if (chan == -1) return; + FSOUND_SetFrequency(chan, dafreq*11025/4096); + FSOUND_SetVolume(chan, davol); + + FSOUND_SetPaused(chan, 0); + + channels[free] = chan; + return; + } +} + + +void wsay(char *dafilename, long dafreq, long volume1, long volume2) +{ + unsigned char ch1, ch2; + long i, j, bad, free=-1, oldest=0; + unsigned int oldestpos=0; + int chan; + + if (fmod_inited == 0) return; + + i = numwaves-1; + do + { + bad = 0; + + j = 0; + while ((dafilename[j] > 0) && (j < 16)) + { + ch1 = dafilename[j]; if ((ch1 >= 97) && (ch1 <= 123)) ch1 -= 32; + ch2 = instname[i][j]; if ((ch2 >= 97) && (ch2 <= 123)) ch2 -= 32; + if (ch1 != ch2) {bad = 1; break;} + j++; + } + if (bad == 0) + { + for (j=0; j oldestpos) { + oldest = j; + oldestpos = FSOUND_GetCurrentPosition(channels[j]); + } + } + + if (free < 0) { + FSOUND_StopSound(channels[oldest]); + free = oldest; + } + + chan = FSOUND_PlaySoundEx(FSOUND_FREE, samples[i], NULL, 1); + if (chan == -1) return; + FSOUND_SetFrequency(chan, dafreq*11025/4096); + FSOUND_SetVolume(chan, (volume1*volume2)>>1); + // set pan + FSOUND_SetPaused(chan, 0); + + channels[free] = chan; + + return; + } + + i--; + } while (i >= 0); +} + + +void loadwaves(void) +{ + long fil, dawaversionum, i, tmp; + long wavleng[MAXWAVES], repstart[MAXWAVES], repleng[MAXWAVES], finetune[MAXWAVES]; + char *p; + + fil = kopen4load("WAVES.KWV", 0); + + if (fil != -1) { + kread(fil, &dawaversionum, 4); dawaversionum = B_LITTLE32(dawaversionum); + if (dawaversionum != 0) { kclose(fil); return; } + + kread(fil, &numwaves, 4); numwaves = B_LITTLE32(numwaves); + for (i=0; i +#include +#include +#include +#include +#include + + +char defsrcext[] = ".DAT"; +char defoutext[] = ".C"; + +char source[MAXPATH], output[MAXPATH], bytesize; + + +int PathAddExt(char *path, char *ext); + + +void main(int argc, char *argv[]) +{ + printf("BIN2C - Binary to C data converter\n" + "Copyright (c) 1999 Jonathon Fowler\n\n"); + + if (argc < 4) + { + printf("Usage:\n" + " BIN2C source<.DAT> output<.C> b|w\n\n" + " source<.DAT> Binary source file\n" + " output<.C> Output C code file\n" + " b|w Byte or word-sized data\n\n"); + exit(0); + } + + int arg; + FILE *in, *out; + char datab1, datab2; + int across=0, maxacross; + long length, written=0; + + + // get the source file + strcpy(source, argv[1]); + strupr(source); + PathAddExt(source, defsrcext); + printf("þ Source file: %s\n", source); + + // get the output file + strcpy(output, argv[2]); + strupr(output); + PathAddExt(output, defoutext); + printf("þ Output file: %s\n", output); + + // get byte/word data + switch (tolower(argv[3][0])) + { + case 'b': + printf("þ Byte data.\n"); + bytesize=1; + break; + + case 'w': + printf("þ Word data.\n"); + bytesize=0; + break; + + default: + printf("þ Unknown data size specified. Defaulting to byte.\n"); + bytesize=1; + break; + } + + // open the input file + in = fopen(source, "rb"); + if (!in) + { + printf("Error opening %s\n", source); + exit(1); + } + + // open the output file + out = fopen(output, "w+t"); + if (!out) + { + printf("Error creating %s\n", output); + exit(1); + } + + length = filelength(fileno(in)); + + // write a header out to the output file + fprintf(out, "// %s\n\n// Generated by BIN2C.EXE\n// By Jonathon Fowler\n\n", output); + + // start a data block + fprintf(out, "%s datablock[] = {\n // %ld bytes", (bytesize) ? "char" : "unsigned", length); + + if (bytesize) + maxacross = 12; + else + maxacross = 9; + across = maxacross; + + // convert the data + for (written=0; written1) ? ',' : '\n'); + } else { + datab1 = fgetc(in); + datab2 = fgetc(in); + fprintf(out, " 0x%02X%02X%c", datab2, datab1, ((length-written)>2) ? ',' : '\n'); + } + + across++; + + if (!bytesize) written++; + } + + + fprintf(out, " };"); + + fclose(out); + fclose(in); +} + + +// Add an extention to a path if one doesn't exist +int PathAddExt(char *path, char *ext) +{ + char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], extn[MAXEXT]; + int flags; + + flags = fnsplit(path, drive, dir, name, extn); + + if (!(flags & EXTENSION)) // tack on an extension + strcat(path, ext); + + return ((flags & EXTENSION) == 0); +} diff --git a/polymer/build/src/util/cacheinfo.c b/polymer/build/src/util/cacheinfo.c new file mode 100644 index 000000000..07b5f68ff --- /dev/null +++ b/polymer/build/src/util/cacheinfo.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include "compat.h" + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +typedef struct { + char magic[8]; // 'Polymost' + long xdim, ydim; // of image, unpadded + long flags; // 1 = !2^x, 2 = has alpha, 4 = lzw compressed +} texcacheheader; +typedef struct { + long size; + long format; + long xdim, ydim; // of mipmap (possibly padded) + long border, depth; +} texcachepicture; + +int main(int argc, char **argv) +{ + DIR *dir; + struct dirent *dirent; + struct stat st; + FILE *fp; + texcacheheader head; + texcachepicture mip; + + dir = opendir("."); + while ((dirent = readdir(dir))) { + if (stat(dirent->d_name, &st)) { + printf("%s: failed to stat\n", dirent->d_name); + continue; + } + if (!(st.st_mode&S_IFREG)) { + printf("%s: not a regular file\n", dirent->d_name); + continue; + } + + fp = fopen(dirent->d_name,"rb"); + if (!fp) { + printf("%s: failed to open\n", dirent->d_name); + continue; + } + + if (fread(&head, sizeof(head), 1, fp) != 1) { + fclose(fp); + printf("%s: failed to read header\n", dirent->d_name); + continue; + } + head.xdim = B_LITTLE32(head.xdim); + head.ydim = B_LITTLE32(head.ydim); + head.flags = B_LITTLE32(head.flags); + if (fread(&mip, sizeof(mip), 1, fp) != 1) { + fclose(fp); + printf("%s: failed to read mipmap header\n", dirent->d_name); + continue; + } + mip.format = B_LITTLE32(mip.format); + fclose(fp); + if (memcmp(head.magic, "Polymost", 8)) { + printf("%s: bad signature\n", dirent->d_name); + continue; + } + else { + char *format; + char flags[4] = "", flagsc = 0; + switch (mip.format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: format = "RGB DXT1"; break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: format = "RGBA DXT1"; break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: format = "RGBA DXT3"; break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: format = "RGBA DXT5"; break; + default: format = "Unknown"; break; + } + if (head.flags&1) flags[flagsc++] = '2'; + if (head.flags&2) flags[flagsc++] = 'A'; + if (head.flags&4) flags[flagsc++] = 'L'; + flags[flagsc++] = 0; + + printf("%s: flags=%s format=%s\n", dirent->d_name, flags, format); + } + } + closedir(dir); + + return 0; +} \ No newline at end of file diff --git a/polymer/build/src/util/generateicon.c b/polymer/build/src/util/generateicon.c new file mode 100644 index 000000000..c9d2341ea --- /dev/null +++ b/polymer/build/src/util/generateicon.c @@ -0,0 +1,110 @@ +#include "kplib.h" +#include "compat.h" + +struct icon { + int width,height; + unsigned int *pixels; + unsigned char *mask; +}; + +int writeicon(FILE *fp, struct icon *ico) +{ + int i; + + fprintf(fp, + "#include \"sdlayer.h\"\n" + "\n" + ); + fprintf(fp,"static unsigned int sdlappicon_pixels[] = {\n"); + for (i=0;iwidth*ico->height;i++) { + if ((i%6) == 0) fprintf(fp,"\t"); + else fprintf(fp," "); + fprintf(fp, "0x%08x,", B_LITTLE32(ico->pixels[i])); + if ((i%6) == 5) fprintf(fp,"\n"); + } + if ((i%16) > 0) fprintf(fp, "\n"); + fprintf(fp, "};\n\n"); + + fprintf(fp,"static unsigned char sdlappicon_mask[] = {\n"); + for (i=0;i<((ico->width+7)/8)*ico->height;i++) { + if ((i%14) == 0) fprintf(fp,"\t"); + else fprintf(fp," "); + fprintf(fp, "%3d,", ico->mask[i]); + if ((i%14) == 13) fprintf(fp,"\n"); + } + if ((i%16) > 0) fprintf(fp, "\n"); + fprintf(fp, "};\n\n"); + + fprintf(fp, + "struct sdlappicon sdlappicon = {\n" + " %d,%d, // width,height\n" + " sdlappicon_pixels,\n" + " sdlappicon_mask\n" + "};\n", + ico->width, ico->height + ); + + return 0; +} + +int main(int argc, char **argv) +{ + struct icon icon; + long bpl, xsiz, ysiz; + long i,j,k,c; + unsigned char *mask, *maskp, bm, *pp; + + if (argc<2) { + fprintf(stderr, "generateicon \n"); + return 1; + } + + memset(&icon, 0, sizeof(icon)); + + kpzload(argv[1], (long*)&icon.pixels, &bpl, (long*)&icon.width, (long*)&icon.height); + if (!icon.pixels) { + fprintf(stderr, "Failure loading %s\n", argv[1]); + return 1; + } + + if (bpl != icon.width * 4) { + fprintf(stderr, "bpl != icon.width * 4\n"); + free(icon.pixels); + return 1; + } + + icon.mask = (unsigned char *)calloc(icon.height, (icon.width+7)/8); + if (!icon.mask) { + fprintf(stderr, "Out of memory\n"); + free(icon.pixels); + return 1; + } + + maskp = icon.mask; + bm = 1; + pp = (unsigned char *)icon.pixels; + for (i=0; i 0) *maskp |= bm; + + bm <<= 1; + pp += 4; + } + + writeicon(stdout, &icon); + + free(icon.pixels); + free(icon.mask); + + return 0; +} + diff --git a/polymer/build/src/util/kextract.c b/polymer/build/src/util/kextract.c new file mode 100644 index 000000000..5558fd823 --- /dev/null +++ b/polymer/build/src/util/kextract.c @@ -0,0 +1,148 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" + +#define MAXFILES 4096 + +static char buf[65536]; + +static long numfiles, anyfiles4extraction; +static char marked4extraction[MAXFILES]; +static char filelist[MAXFILES][16]; +static long fileoffs[MAXFILES+1], fileleng[MAXFILES]; + +void findfiles(const char *dafilespec) +{ + char t[13]; + int i; + + for(i=numfiles-1;i>=0;i--) + { + memcpy(t,filelist[i],12); + t[12] = 0; + + if (Bwildmatch(t,dafilespec)) { + marked4extraction[i] = 1; + anyfiles4extraction = 1; + } + } +} + +int main(int argc, char **argv) +{ + long i, j, k, l, fil, fil2; + + if (argc < 3) + { + printf("KEXTRACT [grouped file][@file or filespec...] by Kenneth Silverman\n"); + printf(" This program extracts files from a previously grouped group file.\n"); + printf(" You can extract files using the ? and * wildcards.\n"); + printf(" Ex: kextract stuff.dat tiles000.art nukeland.map palette.dat\n"); + printf(" (stuff.dat is the group file, the rest are the files to extract)\n"); + return(0); + } + + if ((fil = Bopen(argv[1],BO_BINARY|BO_RDONLY,BS_IREAD)) == -1) + { + printf("Error: %s could not be opened\n",argv[1]); + return(0); + } + + Bread(fil,buf,16); + if ((buf[0] != 'K') || (buf[1] != 'e') || (buf[2] != 'n') || + (buf[3] != 'S') || (buf[4] != 'i') || (buf[5] != 'l') || + (buf[6] != 'v') || (buf[7] != 'e') || (buf[8] != 'r') || + (buf[9] != 'm') || (buf[10] != 'a') || (buf[11] != 'n')) + { + Bclose(fil); + printf("Error: %s not a valid group file\n",argv[1]); + return(0); + } + numfiles = *((long*)&buf[12]); numfiles = B_LITTLE32(numfiles); + + Bread(fil,filelist,numfiles<<4); + + j = 0; + for(i=0;i1;i--) + { + if (argv[i][0] == '@') + { + if ((fil2 = Bopen(&argv[i][1],BO_BINARY|BO_RDONLY,BS_IREAD)) != -1) + { + l = Bread(fil2,buf,65536); + j = 0; + while ((j < l) && (buf[j] <= 32)) j++; + while (j < l) + { + k = j; + while ((k < l) && (buf[k] > 32)) k++; + + buf[k] = 0; + findfiles(&buf[j]); + j = k+1; + + while ((j < l) && (buf[j] <= 32)) j++; + } + Bclose(fil2); + } + } + else + findfiles(argv[i]); + } + + if (anyfiles4extraction == 0) + { + Bclose(fil); + printf("No files found in group file with those names\n"); + return(0); + } + + for(i=0;imode & BS_IFDIR) return 0; // is a directory + if (a->namlen > 12) return 0; // name too long + return Bwildmatch(a->name, matchstr); +} + +long filesize(const char *path, const char *name) +{ + char p[BMAX_PATH]; + struct stat st; + + strcpy(p, path); + strcat(p, "/"); + strcat(p, name); + + if (!stat(p, &st)) return st.st_size; + return 0; +} + +void findfiles(const char *dafilespec) +{ + struct Bdirent *name; + long daspeclen; + char daspec[128], *dir; + BDIR *di; + + strcpy(daspec,dafilespec); + daspeclen=strlen(daspec); + while ((daspec[daspeclen] != '\\') && (daspec[daspeclen] != '/') && (daspeclen > 0)) daspeclen--; + if (daspeclen > 0) { + daspec[daspeclen]=0; + dir = daspec; + matchstr = &daspec[daspeclen+1]; + } else { + dir = "."; + matchstr = daspec; + } + + di = Bopendir(dir); + if (!di) return; + + while ((name = Breaddir(di))) { + if (!checkmatch(name)) continue; + + strcpy(&filelist[numfiles][0],name->name); + jstrupr(&filelist[numfiles][0]); + fileleng[numfiles] = name->size; + filelist[numfiles][12] = (char)(fileleng[numfiles]&255); + filelist[numfiles][13] = (char)((fileleng[numfiles]>>8)&255); + filelist[numfiles][14] = (char)((fileleng[numfiles]>>16)&255); + filelist[numfiles][15] = (char)((fileleng[numfiles]>>24)&255); + + strcpy(filespec[numfiles],dir); + strcat(filespec[numfiles], "/"); + strcat(filespec[numfiles],name->name); + + numfiles++; + if (numfiles > MAXFILES) + { + printf("FATAL ERROR: TOO MANY FILES SELECTED! (MAX is 4096)\n"); + exit(0); + } + } + + Bclosedir(di); +} + +int main(int argc, char **argv) +{ + long i, j, k, l, fil, fil2; + + if (argc < 3) + { + printf("KGROUP [grouped file][@file or filespec...] by Kenneth Silverman\n"); + printf(" This program collects many files into 1 big uncompressed file called a\n"); + printf(" group file\n"); + printf(" Ex: kgroup stuff.dat *.art *.map *.k?? palette.dat tables.dat\n"); + printf(" (stuff.dat is the group file, the rest are the files to add)\n"); + exit(0); + } + + numfiles = 0; + for(i=argc-1;i>1;i--) + { + if (argv[i][0] == '@') + { + if ((fil = Bopen(&argv[i][1],BO_BINARY|BO_RDONLY,BS_IREAD)) != -1) + { + l = Bread(fil,buf,65536); + j = 0; + while ((j < l) && (buf[j] <= 32)) j++; + while (j < l) + { + k = j; + while ((k < l) && (buf[k] > 32)) k++; + + buf[k] = 0; + findfiles(&buf[j]); + j = k+1; + + while ((j < l) && (buf[j] <= 32)) j++; + } + Bclose(fil); + } + } + else + findfiles(argv[i]); + } + + if ((fil = Bopen(argv[1],BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) + { + printf("Error: %s could not be opened\n",argv[1]); + exit(0); + } + Bwrite(fil,"KenSilverman",12); + Bwrite(fil,&numfiles,4); + Bwrite(fil,filelist,numfiles<<4); + + for(i=0;i +#include +#include + +typedef struct { float x, y, z; } point3d; + +typedef struct +{ long id, vers, skinxsiz, skinysiz, framebytes; //id:"IPD2", vers:8 + long numskins, numverts, numuv, numtris, numglcmds, numframes; + long ofsskins, ofsuv, ofstris, ofsframes, ofsglcmds, ofseof; //ofsskins: skin names (64 bytes each) +} md2typ; + +typedef struct { point3d mul, add; } frametyp; + +int main (int argc, char **argv) +{ + FILE *fil; + long i, leng; + char *fbuf; + md2typ *head; + frametyp *fptr; + + if (argc != 4) { puts("KMD2TOOL [MD2 in file] [MD2 out file] [z offset] by Ken Silverman"); return(0); } + if (!stricmp(argv[1],argv[2])) { puts("input&output filenames can't be same"); return(0); } + + fil = fopen(argv[1],"rb"); if (!fil) { puts("error"); return(0); } + leng = filelength(_fileno(fil)); + fbuf = (char *)malloc(leng); if (!fbuf) { puts("error"); return(0); } + fread(fbuf,leng,1,fil); + fclose(fil); + + head = (md2typ *)fbuf; + if ((head->id != 0x32504449) && (head->vers != 8)) { free(fbuf); puts("error"); return(0); } //"IDP2" + for(i=0;inumframes;i++) + { + fptr = (frametyp *)&fbuf[head->ofsframes+head->framebytes*i]; + printf("frame %2d scale:%f,%f,%f offs:%f,%f,%f\n",i,fptr->mul.x,fptr->mul.y,fptr->mul.z,fptr->add.x,fptr->add.y,fptr->add.z); + fptr->add.z += atof(argv[3]); + } + + fil = fopen(argv[2],"wb"); if (!fil) { puts("error"); return(0); } + fwrite(fbuf,leng,1,fil); + fclose(fil); + + free(fbuf); + + return(0); +} + +#if 0 +!endif +#endif diff --git a/polymer/build/src/util/transpal.c b/polymer/build/src/util/transpal.c new file mode 100644 index 000000000..f2e5218a6 --- /dev/null +++ b/polymer/build/src/util/transpal.c @@ -0,0 +1,270 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "pragmas.h" + +#define MAXPALOOKUPS 256 + +static long numpalookups, transratio; +static char palettefilename[13], origpalookup[MAXPALOOKUPS<<8]; +static char palette[768], palookup[MAXPALOOKUPS<<8], transluc[65536]; +static char closestcol[64][64][64]; + +#define FASTPALGRIDSIZ 8 +static long rdist[129], gdist[129], bdist[129]; +static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3]; +static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)]; +static long colnext[256]; +static char coldist[8] = {0,1,2,3,4,3,2,1}; +static long colscan[27]; + + + +char getclosestcol(long r, long g, long b) +{ + long i, j, k, dist, mindist, retcol; + long *rlookup, *glookup, *blookup; + char *ptr; + + if (closestcol[r][g][b] != 255) return(closestcol[r][g][b]); + + j = (r>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(g>>3)*FASTPALGRIDSIZ+(b>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1; + mindist = min(rdist[coldist[r&7]+64+8],gdist[coldist[g&7]+64+8]); + mindist = min(mindist,bdist[coldist[b&7]+64+8]); + mindist++; + + rlookup = (long *)&rdist[64-r]; + glookup = (long *)&gdist[64-g]; + blookup = (long *)&bdist[64-b]; + + retcol = -1; + for(k=26;k>=0;k--) + { + i = colscan[k]+j; if ((colhere[i>>3]&(1<<(i&7))) == 0) continue; + for(i=colhead[i];i>=0;i=colnext[i]) + { + ptr = (char *)&palette[i*3]; + dist = glookup[ptr[1]]; if (dist >= mindist) continue; + dist += rlookup[ptr[0]]; if (dist >= mindist) continue; + dist += blookup[ptr[2]]; if (dist >= mindist) continue; + mindist = dist; retcol = i; + } + } + if (retcol < 0) + { + mindist = 0x7fffffff; + ptr = (char *)&palette[768-3]; + for(i=255;i>=0;i--,ptr-=3) + { + dist = glookup[ptr[1]]; if (dist >= mindist) continue; + dist += rlookup[ptr[0]]; if (dist >= mindist) continue; + dist += blookup[ptr[2]]; if (dist >= mindist) continue; + mindist = dist; retcol = i; + } + } + ptr = (char *)&closestcol[r][g][b]; + *ptr = retcol; + if ((r >= 4) && (ptr[(-2)<<12] == retcol)) ptr[(-3)<<12] = retcol, ptr[(-2)<<12] = retcol, ptr[(-1)<<12] = retcol; + if ((g >= 4) && (ptr[(-2)<<6] == retcol)) ptr[(-3)<<6] = retcol, ptr[(-2)<<6] = retcol, ptr[(-1)<<6] = retcol; + if ((b >= 4) && (ptr[(-2)] == retcol)) ptr[(-3)] = retcol, ptr[(-2)] = retcol, ptr[(-1)] = retcol; + if ((r < 64-4) && (ptr[(2)<<12] == retcol)) ptr[(3)<<12] = retcol, ptr[(2)<<12] = retcol, ptr[(1)<<12] = retcol; + if ((g < 64-4) && (ptr[(2)<<6] == retcol)) ptr[(3)<<6] = retcol, ptr[(2)<<6] = retcol, ptr[(1)<<6] = retcol; + if ((b < 64-4) && (ptr[(2)] == retcol)) ptr[(3)] = retcol, ptr[(2)] = retcol, ptr[(1)] = retcol; + if ((r >= 2) && (ptr[(-1)<<12] == retcol)) ptr[(-1)<<12] = retcol; + if ((g >= 2) && (ptr[(-1)<<6] == retcol)) ptr[(-1)<<6] = retcol; + if ((b >= 2) && (ptr[(-1)] == retcol)) ptr[(-1)] = retcol; + if ((r < 64-2) && (ptr[(1)<<12] == retcol)) ptr[(1)<<12] = retcol; + if ((g < 64-2) && (ptr[(1)<<6] == retcol)) ptr[(1)<<6] = retcol; + if ((b < 64-2) && (ptr[(1)] == retcol)) ptr[(1)] = retcol; + return(retcol); +} + +char getpalookup(char dashade, char dacol) +{ + long r, g, b, t; + char *ptr; + + ptr = (char *)&palette[dacol*3]; + t = divscale16(numpalookups-dashade,numpalookups); + r = ((ptr[0]*t+32768)>>16); + g = ((ptr[1]*t+32768)>>16); + b = ((ptr[2]*t+32768)>>16); + return(getclosestcol(r,g,b)); +} + +char gettrans(char dat1, char dat2, long datransratio) +{ + long r, g, b; + char *ptr, *ptr2; + + ptr = (char *)&palette[dat1*3]; + ptr2 = (char *)&palette[dat2*3]; + r = ptr[0]; r += (((ptr2[0]-r)*datransratio+128)>>8); + g = ptr[1]; g += (((ptr2[1]-g)*datransratio+128)>>8); + b = ptr[2]; b += (((ptr2[2]-b)*datransratio+128)>>8); + return(getclosestcol(r,g,b)); +} + +void initfastcolorlookup(long rscale, long gscale, long bscale) +{ + long i, j, x, y, z; + char *ptr; + + j = 0; + for(i=64;i>=0;i--) + { + //j = (i-64)*(i-64); + rdist[i] = rdist[128-i] = j*rscale; + gdist[i] = gdist[128-i] = j*gscale; + bdist[i] = bdist[128-i] = j*bscale; + j += 129-(i<<1); + } + + clearbufbyte(FP_OFF(colhere),sizeof(colhere),0L); + clearbufbyte(FP_OFF(colhead),sizeof(colhead),0L); + + ptr = (char *)&palette[768-3]; + for(i=255;i>=0;i--,ptr-=3) + { + j = (ptr[0]>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ+(ptr[1]>>3)*FASTPALGRIDSIZ+(ptr[2]>>3)+FASTPALGRIDSIZ*FASTPALGRIDSIZ+FASTPALGRIDSIZ+1; + if (colhere[j>>3]&(1<<(j&7))) colnext[i] = colhead[j]; else colnext[i] = -1; + colhead[j] = i; + colhere[j>>3] |= (1<<(j&7)); + } + + i = 0; + for(x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ;x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ;x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ) + for(y=-FASTPALGRIDSIZ;y<=FASTPALGRIDSIZ;y+=FASTPALGRIDSIZ) + for(z=-1;z<=1;z++) + colscan[i++] = x+y+z; + i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i; +} + +int main(int argc, char **argv) +{ + char col, ch; + short orignumpalookups; + long fil, i, j, rscale, gscale, bscale; + char buf[65536]; + + ch = 13; + if (argc>1) { + if (argv[1][0] == '-') { + if (argv[1][1] == 't') { ch = 32; puts("Updating translucency table ONLY"); } + argc--; + argv++; + } + } + + if ((argc != 3) && (argc != 6)) + { + printf("TRANSPAL [-t] [numshades][trans#(0-inv,256-opa)][r][g][b] by Kenneth Silverman\n"); + printf(" Ex #1: transpal 32 170 30 59 11 (I use these values in my BUILD demo)\n"); + printf(" ÀÄÄÁÄÄÁÄÄÄ The RGB scales are optional\n"); + printf(" Ex #2: transpal 64 160\n\n"); + printf("Once tables are generated, the optional -t switch determines what to save:\n"); + printf(" Exclude -t to update both the shade table and transluscent table\n"); + printf(" Include -t to update the transluscent table ONLY\n"); + exit(0); + } + + strcpy(palettefilename,"palette.dat"); + numpalookups = atol(argv[1]); + transratio = atol(argv[2]); + + if (argc == 6) + { + rscale = atol(argv[3]); + gscale = atol(argv[4]); + bscale = atol(argv[5]); + } + else + { + rscale = 30; + gscale = 59; + bscale = 11; + } + + if ((numpalookups < 1) || (numpalookups > 256)) + { printf("Invalid number of shades\n"); exit(0); } + if ((transratio < 0) || (transratio > 256)) + { printf("Invalid transluscent ratio\n"); exit(0); } + + if ((fil = Bopen(palettefilename,BO_BINARY|BO_RDONLY,BS_IREAD)) == -1) + { + printf("%s not found",palettefilename); + return(0); + } + Bread(fil,palette,768); + Bread(fil,&orignumpalookups,2); orignumpalookups = B_LITTLE16(orignumpalookups); + orignumpalookups = min(max(orignumpalookups,1),256); + Bread(fil,origpalookup,(long)orignumpalookups<<8); + Bclose(fil); + + clearbuf(buf,65536>>2,0L); + + initfastcolorlookup(rscale,gscale,bscale); + clearbuf(closestcol,262144>>2,0xffffffff); + + for(i=0;i>2)+buf,(long)col); + drawpixel(((((i<<1)+1)*320+(j+8))>>2)+buf,(long)col); + } + + for(i=0;i<256;i++) + for(j=0;j<6;j++) + { + drawpixel((((j+132+0)*320+(i+8))>>2)+buf,i); + + drawpixel((((i+132+8)*320+(j+0))>>2)+buf,i); + } + + for(i=0;i<256;i++) + for(j=0;j<256;j++) + { + col = gettrans((char)i,(char)j,transratio); + transluc[(i<<8)+j] = col; + + drawpixel((((j+132+8)*320+(i+8))>>2)+buf,(long)col); + } + + if (ch == 13) + { + short s; + if ((fil = Bopen(palettefilename,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) + { printf("Couldn't save file %s",palettefilename); return(0); } + Bwrite(fil,palette,768); + s = B_LITTLE16(numpalookups); Bwrite(fil,&s,2); + Bwrite(fil,palookup,numpalookups<<8); + Bwrite(fil,transluc,65536); + Bclose(fil); + printf("Shade table AND transluscent table updated\n"); + } + else if (ch == 32) + { + short s; + if ((fil = Bopen(palettefilename,BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) + { printf("Couldn't save file %s",palettefilename); return(0); } + Bwrite(fil,palette,768); + s = B_LITTLE16(orignumpalookups); Bwrite(fil,&s,2); + Bwrite(fil,origpalookup,(long)orignumpalookups<<8); + Bwrite(fil,transluc,65536); + Bclose(fil); + printf("Transluscent table updated\n"); + } + else + printf("Palette file wasn't touched\n"); + + return 0; +} + diff --git a/polymer/build/src/util/vgafont.cpp b/polymer/build/src/util/vgafont.cpp new file mode 100644 index 000000000..7da2d093c --- /dev/null +++ b/polymer/build/src/util/vgafont.cpp @@ -0,0 +1,139 @@ +// VGA Font Grabber +// Copyright (c) 1997 Jonathon Fowler +// This is a DOS program originally written with Borland Turbo C++ for DOS 3.1 + + +#include +#include + +void main(void) +{ + int font, width, height, numchars; + struct REGPACK r; + FILE *fp; + + printf("VGA Font Grabber\n" + "Copyright (c) 1997 Jonathon Fowler\n"); + + do { + printf("\nSelect which font to grab:\n" + " 1. 8-by-8 ROM\n" + " 2. 8-by-14 ROM\n" + " 3. 8-by-16 ROM\n" + " 4. 9-by-16 ROM\n" + " 5. 9-by-14 ROM\n" + " 6. Quit\n" + " > "); + scanf("%d",&font); + + switch (font) { + case 1: + printf("Getting 8-by-8 ROM font..."); + + if ((fp = fopen("88vga.dat", "wb")) != NULL) { + width = 8; + height = 8; + numchars = 256; + + r.r_ax = 0x1130; // locate the font (1st half) + r.r_bx = 0x0300; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (8 * 128), fp); + + r.r_ax = 0x1130; // locate the font (2nd half) + r.r_bx = 0x0400; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (8 * 128), fp); + + fclose(fp); + } + + printf("Done\n"); + break; + case 2: + printf("Getting 8-by-14 ROM font..."); + + if ((fp = fopen("814vga.dat", "wb")) != NULL) { + width = 8; + height = 14; + numchars = 256; + + r.r_ax = 0x1130; // locate the font + r.r_bx = 0x0200; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (14 * 256), fp); + + fclose(fp); + } + + printf("Done\n"); + break; + case 3: + printf("Getting 8-by-16 ROM font..."); + + if ((fp = fopen("816vga.dat", "wb")) != NULL) { + width = 8; + height = 16; + numchars = 256; + + r.r_ax = 0x1130; // locate the font + r.r_bx = 0x0600; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (16 * 256), fp); + + fclose(fp); + } + + printf("Done\n"); + break; + case 4: + printf("Getting 9-by-16 ROM font..."); + + if ((fp = fopen("916vga.dat", "wb")) != NULL) { + width = 9; + height = 16; + numchars = 256; + + r.r_ax = 0x1130; // locate the font + r.r_bx = 0x0700; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (16 * 256) *2, fp); + + fclose(fp); + } + + printf("Done\n"); + break; + case 5: + printf("Getting 9-by-14 ROM font..."); + + if ((fp = fopen("914vga.dat", "wb")) != NULL) { + width = 9; + height = 16; + numchars = 256; + + r.r_ax = 0x1130; // locate the font + r.r_bx = 0x0500; + intr(0x10, &r); + + fwrite(MK_FP(r.r_es, r.r_bp), 1, (14 * 256)* 2, fp); + + fclose(fp); + } + + printf("Done\n"); + break; + case 6: + break; + default: + printf("Please try again\n"); + break; + } + } while (font != 6); + +} diff --git a/polymer/build/src/util/wad2art.c b/polymer/build/src/util/wad2art.c new file mode 100644 index 000000000..fd318011e --- /dev/null +++ b/polymer/build/src/util/wad2art.c @@ -0,0 +1,283 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "pragmas.h" + +#define MAXWADS 4096 + +static long artversion, localtilestart, localtileend; +static long fil1, fil2; +static char wadata[MAXWADS][8]; +static long wadplc[MAXWADS], wadlen[MAXWADS], numwads; +static long xoffses[1024], ylookup[256], picanm[MAXWADS]; +static short tilesizx[MAXWADS], tilesizy[MAXWADS]; +static char pal[768], palookup[8192]; +static char screen[65536], tempbuf[131072]; + + +void loadwadheader(void) +{ + long i, j; + + Bread(fil1,&tempbuf[0],12); + numwads = ((long)tempbuf[4])+(((long)tempbuf[5])<<8)+(((long)tempbuf[6])<<16)+(((long)tempbuf[7])<<24); + i = ((long)tempbuf[8])+(((long)tempbuf[9])<<8)+(((long)tempbuf[10])<<16)+(((long)tempbuf[11])<<24); + Blseek(fil1,i,BSEEK_SET); + Bread(fil1,&tempbuf[0],numwads*16); + j = 0; + for(i=0;i>= 2; + + i = 0; + while (Bstrncasecmp(wadata[i],"COLORMAP",8) != 0) i++; + Blseek(fil1,wadplc[i],BSEEK_SET); + Bread(fil1,palookup,8192); + + if ((fil3 = Bopen("palette.dat",BO_BINARY|BO_TRUNC|BO_CREAT|BO_WRONLY,BS_IREAD|BS_IWRITE)) == -1) + { printf("Cannot save palette.dat\n"); exit(0); } + Bwrite(fil3,pal,768); + danumshades = 32; + Bwrite(fil3,&danumshades,2); + Bwrite(fil3,palookup,8192); + Bclose(fil3); +} + +void saveart (short tilenum, short xlen, short ylen) +{ + long i, x, p, pend; + + pend = ylookup[ylen]; + + tilesizx[tilenum] = xlen; + tilesizy[tilenum] = ylen; + i = 0; + for(x=0;x= 10000) buffer[j++] = ((i/10000)%10)+48; + if (i >= 1000) buffer[j++] = ((i/1000)%10)+48; + if (i >= 100) buffer[j++] = ((i/100)%10)+48; + if (i >= 10) buffer[j++] = ((i/10)%10)+48; + buffer[j++] = (i%10)+48; + + buffer[j++] = 13; + buffer[j++] = 10; + Bwrite(fil3,&buffer[0],j); + } + + Bclose(fil3); +} + +void showart (char *part) +{ + char yoff, ylen; + short xsiz, ysiz; + long i, j, z, zx, zzx, x, y, p, pend, junk, curplc; + + curplc = -1; + if ((Bstrncasecmp(part,"L_START",7) == 0) || (Bstrncasecmp(part,"S_START",7) == 0) || (Bstrncasecmp(part,"P_START",7) == 0)) + { + if (Bstrncasecmp(part,"L_START",7) == 0) + z = 462; + else + { + z = 0; + while (Bstrncasecmp(wadata[z],part,7) != 0) z++; + z++; + } + + do + { + if (Bstrncasecmp(wadata[z],"P1_START",8) == 0) z++; + if (Bstrncasecmp(wadata[z],"P1_END",6) == 0) z++; + if (Bstrncasecmp(wadata[z],"P2_START",8) == 0) z++; + if (Bstrncasecmp(wadata[z],"S_START",7) == 0) break; + if (Bstrncasecmp(wadata[z],"S_END",5) == 0) break; + if (Bstrncasecmp(wadata[z],"P_END",5) == 0) break; + + if (curplc != wadplc[z]) Blseek(fil1,wadplc[z],BSEEK_SET); + read(fil1,&tempbuf[0],wadlen[z]); + curplc = wadplc[z]+wadlen[z]; + + xsiz = (long)tempbuf[0]+(((long)tempbuf[1])<<8); + ysiz = (long)tempbuf[2]+(((long)tempbuf[3])<<8); + if ((xsiz <= 0) || (ysiz <= 0) || (xsiz > 320) || (ysiz > 200)) goto skipit; + i = 8; + for(zx=0;zx>2,0xffffffff); + + for(x=0;x> 24) + 4096]; + else c = shlookup[a >> 12]; + a >>= c&0xff; + a = (a&0xffff0000)|(sqrtable[a]); + a >>= ((c&0xff00) >> 8); + + return a; +} + +static inline long msqrtasm(unsigned long c) +{ + unsigned long a,b; + + a = 0x40000000l; + b = 0x20000000l; + do { + if (c >= a) { + c -= a; + a += b*4; + } + a -= b; + a >>= 1; + b >>= 2; + } while (b); + if (c >= a) a++; + a >>= 1; + return a; +} + +static void initksqrt(void) +{ + long i, j, k; + + j = 1; k = 0; + for(i=0;i<4096;i++) + { + if (i >= j) { j <<= 2; k++; } + sqrtable[i] = (unsigned short)(msqrtasm((i<<18)+131072)<<1); + shlookup[i] = (k<<1)+((10-k)<<8); + if (i < 256) shlookup[i+4096] = ((k+6)<<1)+((10-(k+6))<<8); + } +} + + +long inside(long x, long y, short sectnum) +{ + walltype *wal; + long i, x1, y1, x2, y2; + char cnt; + + cnt = 0; + + wal = &wall[sector[sectnum].wallptr]; + for(i=sector[sectnum].wallnum;i>0;i--) + { + y1 = wal->y-y; y2 = wall[wal->point2].y-y; + if ((y1^y2) < 0) + { + x1 = wal->x-x; x2 = wall[wal->point2].x-x; + + if ((x1^x2) < 0) + cnt ^= (x1*y2= 0) + cnt ^= 1; + } + wal++; + } + return(cnt); +} + +long readbyte(void) +{ + if (filpos >= fileng) return(-1); + if ((filpos&16383) == 0) Bread(filhandle,filebuf,16384); + filpos++; + return((long)filebuf[(filpos-1)&16383]); +} + +long readline(void) +{ + long i, ch; + + do + { + do + { + ch = readbyte(); + if (ch < 0) return(0); + } while ((ch == 13) || (ch == 10)); + + i = 0; tempbuf[0] = 0; + while ((ch != 13) && (ch != 10)) + { + if (ch < 0) return(0); + if (ch == ';') + { + do + { + if (ch < 0) return(0); + ch = readbyte(); + } while ((ch != 13) && (ch != 10)); + break; + } + if ((ch == 32) || (ch == 9)) ch = ','; + if ((ch != ',') || (i == 0) || (tempbuf[i-1] != ',')) + { tempbuf[i++] = ch; tempbuf[i] = 0; } + ch = readbyte(); + } + if ((i > 0) && (tempbuf[i-1] == ',')) tempbuf[i-1] = 0; + } while (i <= 0); + return(i); +} + +void parsescript(void) +{ + long i, j, k, l, lasti, breakout, tstart, tend, textnum, frontbackstat; + long spritenumstat, slen; + char ch; + + clearbufbyte(FP_OFF(sectspri),MAXSECTS*8*sizeof(short),0xffffffff); + + if (scriptname[0] == 0) + { + for(i=0;i<4096;i++) texturelookup[i] = i; + return; + } + + if ((filhandle = Bopen(scriptname,BO_BINARY|BO_RDONLY,BS_IREAD)) == -1) + { + printf("Could not find %s\n",scriptname); + exit(0); + } + filpos = 0; fileng = Bfilelength(filhandle); + while (readline() != 0) + { + i = 0; j = 0; lasti = 0; + while (1) + { + if ((tempbuf[i] == ',') || (tempbuf[i] == 0)) + { + if (tempbuf[i] == 0) { breakout = 1; } + else { breakout = 0, tempbuf[i] = 0; } + + if (j == 0) + { + if (tempbuf[lasti] == '[') + { + definemode = 0; + thingtypemode = 0; + texturelookupmode = 0; + tagtypemode = 0; + sectypemode = 0; + } + + if (Bstrcasecmp(&tempbuf[lasti],"#define") == 0) + definemode = 1; + + if (thingtypemode == 1) + { + thingoff[numthings] = thingopnum; + + k = lasti; + while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; + + if (tempbuf[k] == '-') + { + tempbuf[k] = 0; + thingnum[numthings] = atol(&tempbuf[lasti]); + thingnum2[numthings] = atol(&tempbuf[k+1]); + } + else + { + thingnum[numthings] = atol(&tempbuf[lasti]); + thingnum2[numthings] = thingnum[numthings]; + } + + numthings++; + } + else if (Bstrcasecmp(&tempbuf[lasti],"[THINGTYPES]") == 0) + thingtypemode = 1; + + if (texturelookupmode == 1) + { + textnum = 0; + if ((tempbuf[lasti] >= 48) && (tempbuf[lasti] <= 57)) + { + k = lasti; + while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; + + if (tempbuf[k] == '-') + { + tempbuf[k] = 0; + tstart = atol(&tempbuf[lasti]); + tend = atol(&tempbuf[k+1]); + for(k=tstart;k<=tend;k++) + tempshort[textnum++] = k; + } + else + tempshort[textnum++] = atol(&tempbuf[lasti]); + } + else + { + slen = 0; + while (tempbuf[lasti+slen] != 0) + { + ch = tempbuf[lasti+slen]; + if ((ch >= 97) && (ch <= 122)) tempbuf[lasti+slen] -= 32; + slen++; + } + if (slen > 0) + for(k=inumwads-1;k>=0;k--) + if ((iwadata[k][slen] == 0) || (iwadata[k][slen] == 32)) + if ((iwadata[k][slen-1] != 0) && (iwadata[k][slen-1] != 32)) + { + for(l=slen-1;l>=0;l--) + if (tempbuf[lasti+l] != '?') + { + ch = iwadata[k][l]; + if ((ch >= 97) && (ch <= 122)) ch -= 32; + if (tempbuf[lasti+l] != ch) break; + } + if (l < 0) tempshort[textnum++] = k; + } + } + } + else if (Bstrcasecmp(&tempbuf[lasti],"[TEXTURELOOKUPS]") == 0) + texturelookupmode = 1; + + if (tagtypemode == 1) + { + tagoff[numtags] = tagopnum; + + k = lasti; + while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; + + if (tempbuf[k] == '-') + { + tempbuf[k] = 0; + tagnum[numtags] = atol(&tempbuf[lasti]); + tagnum2[numtags] = atol(&tempbuf[k+1]); + } + else + { + tagnum[numtags] = atol(&tempbuf[lasti]); + tagnum2[numtags] = tagnum[numtags]; + } + + numtags++; + } + else if (Bstrcasecmp(&tempbuf[lasti],"[TAGCONVERSIONS]") == 0) + tagtypemode = 1; + + if (sectypemode == 1) + { + secoff[numsecs] = secopnum; + + k = lasti; + while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; + + if (tempbuf[k] == '-') + { + tempbuf[k] = 0; + secnum[numsecs] = atol(&tempbuf[lasti]); + secnum2[numsecs] = atol(&tempbuf[k+1]); + } + else + { + secnum[numsecs] = atol(&tempbuf[lasti]); + secnum2[numsecs] = secnum[numsecs]; + } + numsecs++; + } + else if (Bstrcasecmp(&tempbuf[lasti],"[SECTORCONVERSIONS]") == 0) + sectypemode = 1; + + } + else if (j > 0) + { + if (definemode == 1) + { + defineptr[numdefines] = (char *)(&define[definecnt]); + for(k=lasti;k= 48) && (tempbuf[k+1] <= 57)) + thingval[thingopnum] = atol(&tempbuf[k+1]); + else + { + for(l=0;l= 48) && (tempbuf[lasti] <= 57)) + l = atol(&tempbuf[lasti]); + else + { + for(l=0;l=0;k--) texturelookup[tempshort[k]] = l; + } + + if (tagtypemode == 1) + { + for(k=lasti;k= 48) && (tempbuf[lasti] <= 57)) //1 DIGIT ONLY! + { + spritenumstat = tempbuf[lasti]-48; + lasti++; + } + + if (Bstrcasecmp(&tempbuf[lasti],"sprite.x") == 0) tagfield[tagopnum] = 0; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.y") == 0) tagfield[tagopnum] = 1; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.z") == 0) tagfield[tagopnum] = 2; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.cstat") == 0) tagfield[tagopnum] = 3; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.shade") == 0) tagfield[tagopnum] = 4; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.pal") == 0) tagfield[tagopnum] = 5; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.clipdist") == 0) tagfield[tagopnum] = 6; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xrepeat") == 0) tagfield[tagopnum] = 7; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yrepeat") == 0) tagfield[tagopnum] = 8; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xoffset") == 0) tagfield[tagopnum] = 9; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yoffset") == 0) tagfield[tagopnum] = 10; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.picnum") == 0) tagfield[tagopnum] = 11; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.ang") == 0) tagfield[tagopnum] = 12; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xvel") == 0) tagfield[tagopnum] = 13; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yvel") == 0) tagfield[tagopnum] = 14; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.zvel") == 0) tagfield[tagopnum] = 15; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.owner") == 0) tagfield[tagopnum] = 16; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.sectnum") == 0) tagfield[tagopnum] = 17; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.statnum") == 0) tagfield[tagopnum] = 18; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.lotag") == 0) tagfield[tagopnum] = 19; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.hitag") == 0) tagfield[tagopnum] = 20; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.extra") == 0) tagfield[tagopnum] = 21; + + if (Bstrcasecmp(&tempbuf[lasti],"sector.wallptr") == 0) tagfield[tagopnum] = 32; + if (Bstrcasecmp(&tempbuf[lasti],"sector.wallnum") == 0) tagfield[tagopnum] = 33; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpicnum") == 0) tagfield[tagopnum] = 34; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpicnum") == 0) tagfield[tagopnum] = 35; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingheinum") == 0) tagfield[tagopnum] = 36; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorheinum") == 0) tagfield[tagopnum] = 37; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingz") == 0) tagfield[tagopnum] = 38; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorz") == 0) tagfield[tagopnum] = 39; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingshade") == 0) tagfield[tagopnum] = 40; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorshade") == 0) tagfield[tagopnum] = 41; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingxpanning") == 0) tagfield[tagopnum] = 42; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorxpanning") == 0) tagfield[tagopnum] = 43; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingypanning") == 0) tagfield[tagopnum] = 44; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorypanning") == 0) tagfield[tagopnum] = 45; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingstat") == 0) tagfield[tagopnum] = 46; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorstat") == 0) tagfield[tagopnum] = 47; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpal") == 0) tagfield[tagopnum] = 48; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpal") == 0) tagfield[tagopnum] = 49; + if (Bstrcasecmp(&tempbuf[lasti],"sector.visibility") == 0) tagfield[tagopnum] = 50; + if (Bstrcasecmp(&tempbuf[lasti],"sector.lotag") == 0) tagfield[tagopnum] = 51; + if (Bstrcasecmp(&tempbuf[lasti],"sector.hitag") == 0) tagfield[tagopnum] = 52; + if (Bstrcasecmp(&tempbuf[lasti],"sector.extra") == 0) tagfield[tagopnum] = 53; + + if (Bstrcasecmp(&tempbuf[lasti],"wall.x") == 0) tagfield[tagopnum] = 64; + if (Bstrcasecmp(&tempbuf[lasti],"wall.y") == 0) tagfield[tagopnum] = 65; + if (Bstrcasecmp(&tempbuf[lasti],"wall.point2") == 0) tagfield[tagopnum] = 66; + if (Bstrcasecmp(&tempbuf[lasti],"wall.nextsector") == 0) tagfield[tagopnum] = 67; + if (Bstrcasecmp(&tempbuf[lasti],"wall.nextwall") == 0) tagfield[tagopnum] = 68; + if (Bstrcasecmp(&tempbuf[lasti],"wall.picnum") == 0) tagfield[tagopnum] = 69; + if (Bstrcasecmp(&tempbuf[lasti],"wall.overpicnum") == 0) tagfield[tagopnum] = 70; + if (Bstrcasecmp(&tempbuf[lasti],"wall.shade") == 0) tagfield[tagopnum] = 71; + if (Bstrcasecmp(&tempbuf[lasti],"wall.pal") == 0) tagfield[tagopnum] = 72; + if (Bstrcasecmp(&tempbuf[lasti],"wall.cstat") == 0) tagfield[tagopnum] = 73; + if (Bstrcasecmp(&tempbuf[lasti],"wall.xrepeat") == 0) tagfield[tagopnum] = 74; + if (Bstrcasecmp(&tempbuf[lasti],"wall.yrepeat") == 0) tagfield[tagopnum] = 75; + if (Bstrcasecmp(&tempbuf[lasti],"wall.xpanning") == 0) tagfield[tagopnum] = 76; + if (Bstrcasecmp(&tempbuf[lasti],"wall.ypanning") == 0) tagfield[tagopnum] = 77; + if (Bstrcasecmp(&tempbuf[lasti],"wall.lotag") == 0) tagfield[tagopnum] = 78; + if (Bstrcasecmp(&tempbuf[lasti],"wall.hitag") == 0) tagfield[tagopnum] = 79; + if (Bstrcasecmp(&tempbuf[lasti],"wall.extra") == 0) tagfield[tagopnum] = 80; + + tagfield[tagopnum] += (frontbackstat<<7) + (spritenumstat<<8); + + if ((tempbuf[k+1] >= 48) && (tempbuf[k+1] <= 57)) + tagval[tagopnum] = atol(&tempbuf[k+1]); + else if (Bstrcasecmp("tag",&tempbuf[k+1]) == 0) + tagval[tagopnum] = 0x80000000; + else + { + for(l=0;l= 48) && (tempbuf[lasti] <= 57)) //1 DIGIT ONLY! + { + spritenumstat = tempbuf[lasti]-48; + lasti++; + } + + if (Bstrcasecmp(&tempbuf[lasti],"sprite.x") == 0) secfield[secopnum] = 0; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.y") == 0) secfield[secopnum] = 1; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.z") == 0) secfield[secopnum] = 2; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.cstat") == 0) secfield[secopnum] = 3; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.shade") == 0) secfield[secopnum] = 4; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.pal") == 0) secfield[secopnum] = 5; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.clipdist") == 0) secfield[secopnum] = 6; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xrepeat") == 0) secfield[secopnum] = 7; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yrepeat") == 0) secfield[secopnum] = 8; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xoffset") == 0) secfield[secopnum] = 9; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yoffset") == 0) secfield[secopnum] = 10; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.picnum") == 0) secfield[secopnum] = 11; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.ang") == 0) secfield[secopnum] = 12; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.xvel") == 0) secfield[secopnum] = 13; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.yvel") == 0) secfield[secopnum] = 14; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.zvel") == 0) secfield[secopnum] = 15; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.owner") == 0) secfield[secopnum] = 16; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.sectnum") == 0) secfield[secopnum] = 17; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.statnum") == 0) secfield[secopnum] = 18; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.lotag") == 0) secfield[secopnum] = 19; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.hitag") == 0) secfield[secopnum] = 20; + if (Bstrcasecmp(&tempbuf[lasti],"sprite.extra") == 0) secfield[secopnum] = 21; + + if (Bstrcasecmp(&tempbuf[lasti],"sector.wallptr") == 0) secfield[secopnum] = 32; + if (Bstrcasecmp(&tempbuf[lasti],"sector.wallnum") == 0) secfield[secopnum] = 33; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpicnum") == 0) secfield[secopnum] = 34; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpicnum") == 0) secfield[secopnum] = 35; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingheinum") == 0) secfield[secopnum] = 36; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorheinum") == 0) secfield[secopnum] = 37; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingz") == 0) secfield[secopnum] = 38; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorz") == 0) secfield[secopnum] = 39; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingshade") == 0) secfield[secopnum] = 40; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorshade") == 0) secfield[secopnum] = 41; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingxpanning") == 0) secfield[secopnum] = 42; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorxpanning") == 0) secfield[secopnum] = 43; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingypanning") == 0) secfield[secopnum] = 44; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorypanning") == 0) secfield[secopnum] = 45; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingstat") == 0) secfield[secopnum] = 46; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorstat") == 0) secfield[secopnum] = 47; + if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpal") == 0) secfield[secopnum] = 48; + if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpal") == 0) secfield[secopnum] = 49; + if (Bstrcasecmp(&tempbuf[lasti],"sector.visibility") == 0) secfield[secopnum] = 50; + if (Bstrcasecmp(&tempbuf[lasti],"sector.lotag") == 0) secfield[secopnum] = 51; + if (Bstrcasecmp(&tempbuf[lasti],"sector.hitag") == 0) secfield[secopnum] = 52; + if (Bstrcasecmp(&tempbuf[lasti],"sector.extra") == 0) secfield[secopnum] = 53; + + secfield[secopnum] += (spritenumstat<<8); + + if ((tempbuf[k+1] >= 48) && (tempbuf[k+1] <= 57)) + secval[secopnum] = atol(&tempbuf[k+1]); + else if (Bstrcasecmp("tag",&tempbuf[k+1]) == 0) + secval[secopnum] = 0x80000000; + else + { + for(l=0;l0;j>>=1) + if (i+j < inumwads) + if (Bstrcasecmp(iwadata[slist[i+j]],nam) <= 0) i += j; + if (Bstrcasecmp(iwadata[slist[i]],nam) == 0) return(slist[i]); + return(-1); +} + +int main(int argc, char **argv) +{ + char argstring[5][80]; + char iwadfil[80], pwadfil[80], doommap[16], buildmap[16], picstr[16]; + long w, numwads, numtexts, startnumtexts, danumtexts, numpnames; + long x, y, z, zz, zzz, zzx, zx, cx, cy, gap, p, pp, i, j, k, l, offs; + long dnumpoints, dnumlines, dnumsides, dnumsectors, dnumthings, good; + long minx, maxx, miny, maxy, numsectors, numwalls, wadtype; + long startnumwalls, l1, l2, startpoint2, dapoint2, area; + long fil, ifil, pfil, x1, y1, x2, y2, startwall, endwall; + long mapversion, posx, posy, posz, templong, cnt, boardwadindex; + short ang, cursectnum; + + printf("Wad2Map! Copyright 1995 by Ken Silverman\n"); + + if ((argc < 3) || (argc > 5)) + { + printf("Command line parameters: Wad2Map (PWADName) IWADName MapName (ScriptName)\n"); + printf(" Ex #1: wad2map c:\\doom\\doom.wad e1m1\n"); + printf(" Ex #2: wad2map c:\\doom\\doom.wad e1m1 kenbuild.txt\n"); + printf(" Ex #3: wad2map c:\\doom\\mypwad.wad c:\\doom\\doom.wad e1m1\n"); + printf(" Ex #4: wad2map c:\\doom\\mypwad.wad c:\\doom\\doom.wad e1m1 kenbuild.txt\n"); + exit(0); + } + + for(i=1;i>1);gap>0;gap>>=1) + for(z=0;z=0;zz-=gap) + { + if (Bstrcasecmp(iwadata[slist[zz]],iwadata[slist[zz+gap]]) <= 0) break; + i = slist[zz]; slist[zz] = slist[zz+gap]; slist[zz+gap] = i; + } + + if (ifil != pfil) + { + Bread(pfil,&pnumwads,4); + Bread(pfil,&pwadstart,4); + Blseek(pfil,pwadstart,SEEK_SET); + for(z=0;z= 0) + { + Blseek(ifil,iwadplc[w],BSEEK_SET); + startnumtexts = numtexts; + Bread(ifil,&danumtexts,4); numtexts += danumtexts; + Bread(ifil,&textoffs[startnumtexts],(numtexts-startnumtexts)*sizeof(long)); + for(z=startnumtexts;z=boardwadindex;w--) + { + Blseek(pfil,pwadplc[w],BSEEK_SET); + + if (Bstrcasecmp(pwadata[w],"VERTEXES") == 0) + { + dnumpoints = (pwadlen[w]>>2); + Bread(pfil,tempbuf,pwadlen[w]); + offs = 0; + for(z=0;z maxx) maxx = x; + if (y < miny) miny = y; + if (y > maxy) maxy = y; + } + cx = (((minx+maxx)>>1)&0xffffffc0); + cy = (((miny+maxy)>>1)&0xffffffc0); + + numwalls = 0; + + for(z=0;z= 0) && (z == side[line[zz].side2].sect)) + { + wx[numwalls] = px[line[zz].p2]; wy[numwalls] = py[line[zz].p2]; + wx2[numwalls] = px[line[zz].p1]; wy2[numwalls] = py[line[zz].p1]; + picindex[numwalls] = line[zz].side2; linindex[numwalls++] = zz; + } + } + + startpoint2 = startnumwalls; + for(zz=startnumwalls;zz 0)) j = 2; + else if ((wx2[zz+1]-x)*(wy2[zzz]-y) > (wy2[zz+1]-y)*(wx2[zzz]-x)) j = 2; + + if (j == 2) + { + i = wx[zz+1]; wx[zz+1] = wx[zzz]; wx[zzz] = i; + i = wy[zz+1]; wy[zz+1] = wy[zzz]; wy[zzz] = i; + i = wx2[zz+1]; wx2[zz+1] = wx2[zzz]; wx2[zzz] = i; + i = wy2[zz+1]; wy2[zz+1] = wy2[zzz]; wy2[zzz] = i; + i = picindex[zz+1]; picindex[zz+1] = picindex[zzz]; picindex[zzz] = i; + i = linindex[zz+1]; linindex[zz+1] = linindex[zzz]; linindex[zzz] = i; + } + } + point2[zz] = zz+1; + } + if (j == 0) point2[zz] = startpoint2, startpoint2 = zz+1; + } + + sector[z].wallptr = startnumwalls; + sector[z].wallnum = numwalls-startnumwalls; + } + + //Collect sectors + for(z=0;z>3); + if ((sector[z].ceilingstat&1) == 0) sector[z].ceilingshade = j; + if ((sector[z].floorstat&1) == 0) sector[z].floorshade = j; + for(i=startwall;i>1);gap>0;gap>>=1) + for(z=0;z=0;zz-=gap) + { + if (wx[slist[zz]] <= wx[slist[zz+gap]]) break; + i = slist[zz]; slist[zz] = slist[zz+gap]; slist[zz+gap] = i; + } + + for(z=0;z>= 1; + if ((zz+zzz < numwalls) && (wx[slist[zz+zzz]] < x2)) zz += zzz; + zzz >>= 1; + } while (zzz > 0); + + do + { + zzx = slist[zz]; + if (wx[zzx] > x2) break; + if (wy[zzx] == y2) + if ((wx[point2[zzx]] == x1) && (wy[point2[zzx]] == y1)) + { + wall[z].nextwall = zzx; + wall[z].nextsector = sectorofwall[zzx]; + break; + } + zz++; + } while (zz < numwalls); + + if (wall[z].nextwall < 0) + { + wall[z].picnum = sidemidpic[picindex[z]]; + wall[z].overpicnum = 0; + } + else + { + wall[z].picnum = sidetoppic[picindex[z]]; + if (wall[z].picnum <= 0) wall[z].picnum = sidebotpic[picindex[z]]; + if ((wall[z].picnum <= 0) && (wall[z].nextwall >= 0)) + { + zx = picindex[wall[z].nextwall]; + wall[z].picnum = sidetoppic[zx]; + if (wall[z].picnum <= 0) wall[z].picnum = sidebotpic[zx]; + } + wall[z].overpicnum = sidemidpic[picindex[z]]; + if (wall[z].overpicnum >= 0) wall[z].cstat |= (1+4+16); + } + wall[z].xrepeat = 8; + wall[z].yrepeat = 8; + wall[z].xpanning = (char)((-side[picindex[z]].xoffset)&255); + wall[z].ypanning = (char)(((side[picindex[z]].yoffset<<1))&255); + + if (line[linindex[z]].flags&1) wall[z].cstat |= 1; + //if (wall[z].nextwall >= 0) wall[z].cstat |= 4; + //if ((line[linindex[z]].flags&24) && (wall[z].nextwall >= 0)) + // wall[z].cstat |= 4; + } + + for(z=0;z= thingnum[i]) && (thing[z].type <= thingnum2[i])) + for(j=thingoff[i];j tagnum2[i])) continue; + + for(j=tagoff[i];j= 0) + if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) + l = wall[zx].nextsector; + + zzz = sectspri[l][(tagfield[j]>>8)&7]; + if (zzz < 0) + { + zzz = dnumthings++; + sectspri[l][(tagfield[j]>>8)&7] = zzz; + zzx = sector[l].wallptr; x1 = wall[zzx].x; y1 = wall[zzx].y; + zzx = wall[zzx].point2; x2 = wall[zzx].x; y2 = wall[zzx].y; + sprite[zzz].x = ((x1+x2)>>1) + ksgn(y1-y2); + sprite[zzz].y = ((y1+y2)>>1) + ksgn(x2-x1); + sprite[zzz].sectnum = l; + sprite[zzz].z = sector[l].floorz; + sprite[zzz].clipdist = 32; + sprite[zzz].xrepeat = 64; + sprite[zzz].yrepeat = 64; + } + + switch(tagop[j]) + { + case 0: setspritefield(zzz,k,zz); break; + case 1: setspritefield(zzz,k,getspritefield(zzz,k)+zz); break; + case 2: setspritefield(zzz,k,getspritefield(zzz,k)-zz); break; + case 3: setspritefield(zzz,k,getspritefield(zzz,k)|zz); break; + case 4: setspritefield(zzz,k,getspritefield(zzz,k)&zz); break; + case 5: setspritefield(zzz,k,getspritefield(zzz,k)^zz); break; + } + } + else if (k < 64) + { + l = sectorofwall[zx]; + if (wall[zx].nextsector >= 0) + if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) + l = wall[zx].nextsector; + + switch(tagop[j]) + { + case 0: setsectorfield(l,k,zz); break; + case 1: setsectorfield(l,k,getsectorfield(l,k)+zz); break; + case 2: setsectorfield(l,k,getsectorfield(l,k)-zz); break; + case 3: setsectorfield(l,k,getsectorfield(l,k)|zz); break; + case 4: setsectorfield(l,k,getsectorfield(l,k)&zz); break; + case 5: setsectorfield(l,k,getsectorfield(l,k)^zz); break; + } + } + else if (k < 96) + { + l = zx; + if (wall[zx].nextwall >= 0) + if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) + l = wall[zx].nextwall; + + switch(tagop[j]) + { + case 0: setwallfield(l,k,zz); break; + case 1: setwallfield(l,k,getwallfield(l,k)+zz); break; + case 2: setwallfield(l,k,getwallfield(l,k)-zz); break; + case 3: setwallfield(l,k,getwallfield(l,k)|zz); break; + case 4: setwallfield(l,k,getwallfield(l,k)&zz); break; + case 5: setwallfield(l,k,getwallfield(l,k)^zz); break; + } + } + } + } + } + + for(l=0;l= secnum[i]) && (sect[l].type <= secnum2[i])) + { + for(j=secoff[i];j>8)&7]; + if (zzz < 0) + { + zzz = dnumthings++; + sectspri[l][(secfield[j]>>8)&7] = zzz; + zzx = sector[l].wallptr; x1 = wall[zzx].x; y1 = wall[zzx].y; + zzx = wall[zzx].point2; x2 = wall[zzx].x; y2 = wall[zzx].y; + sprite[zzz].x = ((x1+x2)>>1) + ksgn(y1-y2); + sprite[zzz].y = ((y1+y2)>>1) + ksgn(x2-x1); + sprite[zzz].sectnum = l; + sprite[zzz].z = sector[l].floorz; + sprite[zzz].clipdist = 32; + sprite[zzz].xrepeat = 64; + sprite[zzz].yrepeat = 64; + } + + switch(secop[j]) + { + case 0: setspritefield(zzz,k,zz); break; + case 1: setspritefield(zzz,k,getspritefield(zzz,k)+zz); break; + case 2: setspritefield(zzz,k,getspritefield(zzz,k)-zz); break; + case 3: setspritefield(zzz,k,getspritefield(zzz,k)|zz); break; + case 4: setspritefield(zzz,k,getspritefield(zzz,k)&zz); break; + case 5: setspritefield(zzz,k,getspritefield(zzz,k)^zz); break; + } + } + else if (k < 64) + { + switch(secop[j]) + { + case 0: setsectorfield(l,k,zz); break; + case 1: setsectorfield(l,k,getsectorfield(l,k)+zz); break; + case 2: setsectorfield(l,k,getsectorfield(l,k)-zz); break; + case 3: setsectorfield(l,k,getsectorfield(l,k)|zz); break; + case 4: setsectorfield(l,k,getsectorfield(l,k)&zz); break; + case 5: setsectorfield(l,k,getsectorfield(l,k)^zz); break; + } + } + } + } + + for(z=0;z= 32768) || (klabs(y) >= 32768)) + wall[z].xrepeat = 255; + else + { + zx = mulscale10(ksqrtasm(x*x+y*y),wall[z].yrepeat); + wall[z].xrepeat = (char)min(max(zx,1),255); + } + + wall[z].picnum = texturelookup[wall[z].picnum]; + wall[z].overpicnum = texturelookup[wall[z].overpicnum]; + } + + mapversion = 7; posx = 0; posy = 0; posz = 0; ang = 1536; cursectnum = 0; + + //WATCH OUT THAT FOR DNUMTHINGS BEING HIGHER THAN NUMBER ON DOOM MAP! + for(i=0;i +#include +#include +#ifndef DIK_PAUSE +# define DIK_PAUSE 0xC5 +#endif +#include + +#include "dxdidf.h" // comment this out if c_dfDI* is being reported as multiply defined +#include +#include +#include +#include + +#if defined(USE_OPENGL) && defined(POLYMOST) +#include "glbuild.h" +#endif + +#include "compat.h" +#include "winlayer.h" +#include "pragmas.h" +#include "build.h" +#include "a.h" +#include "osd.h" + + +// undefine to restrict windowed resolutions to conventional sizes +#define ANY_WINDOWED_SIZE + +int _buildargc = 0; +char **_buildargv = NULL; +static char *argvbuf = NULL; +extern long app_main(long argc, char *argv[]); + +// Windows crud +static HINSTANCE hInstance = 0; +static HWND hWindow = 0; +#define WINDOW_STYLE (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX) +#define WindowClass "buildapp" +static BOOL window_class_registered = FALSE; +static HANDLE instanceflag = NULL; + +static HWND startupdlg = NULL; +static long startupdlgsaferect[4] = { -1,-1,-1,-1 }; +static int startupdlgcommand = 0; +static void (*startupdlgonclose)(void) = NULL; +int backgroundidle = 1; + +static WORD sysgamma[3][256]; +extern long curbrightness, gammabrightness; + +#if defined(USE_OPENGL) && defined(POLYMOST) +// OpenGL stuff +static HGLRC hGLRC = 0; +char nofog=0; +static char nogl=0; +#endif + +static LPTSTR GetWindowsErrorMsg(DWORD code); +static const char * GetDDrawError(HRESULT code); +static const char * GetDInputError(HRESULT code); +static void ShowErrorBox(const char *m); +static void ShowDDrawErrorBox(const char *m, HRESULT r); +static void ShowDInputErrorBox(const char *m, HRESULT r); +static BOOL CheckWinVersion(void); +static LRESULT CALLBACK WndProcCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static BOOL InitDirectDraw(void); +static void UninitDirectDraw(void); +static int RestoreDirectDrawMode(void); +static void ReleaseDirectDrawSurfaces(void); +static BOOL InitDirectInput(void); +static void UninitDirectInput(void); +static void GetKeyNames(void); +static void AcquireInputDevices(char acquire, signed char device); +static void ProcessInputDevices(void); +static int SetupDirectDraw(int width, int height); +static void UninitDIB(void); +static int SetupDIB(int width, int height); +static void ReleaseOpenGL(void); +static void UninitOpenGL(void); +static int SetupOpenGL(int width, int height, int bitspp); +static BOOL RegisterWindowClass(void); +static BOOL CreateAppWindow(int modenum, char *wtitle); +static void DestroyAppWindow(void); +static void SaveSystemColours(void); +static void SetBWSystemColours(void); +static void RestoreSystemColours(void); + + +// video +static long desktopxdim=0,desktopydim=0,desktopbpp=0,modesetusing=-1; +long xres=-1, yres=-1, fullscreen=0, bpp=0, bytesperline=0, imageSize=0; +long frameplace=0, lockcount=0; +static int windowposx, windowposy, curvidmode = -1; +static int customxdim = 640, customydim = 480, custombpp = 8, customfs = 0; +static unsigned modeschecked=0; +unsigned maxrefreshfreq=60; +char modechange=1, repaintneeded=0; +char offscreenrendering=0; +long glcolourdepth=32; +char videomodereset = 0; + +// input and events +char inputdevices=0; +char quitevent=0, appactive=1; +long mousex=0, mousey=0, mouseb=0; +static unsigned long mousewheel[2] = { 0,0 }; +#define MouseWheelFakePressTime (100) // getticks() is a 1000Hz timer, and the button press is faked for 100ms +long *joyaxis = NULL, joyb=0, *joyhat = NULL; +char joyisgamepad=0, joynumaxes=0, joynumbuttons=0, joynumhats=0; + +static char taskswitching=1; + +char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; +unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; +static unsigned char keynames[256][24]; +static unsigned long lastKeyDown = 0; +static unsigned long lastKeyTime = 0; + +void (*keypresscallback)(long,long) = 0; +void (*mousepresscallback)(long,long) = 0; +void (*joypresscallback)(long,long) = 0; + + + + +//------------------------------------------------------------------------------------------------- +// MAIN CRAP +//================================================================================================= + + +// +// win_gethwnd() -- gets the window handle +// +long win_gethwnd(void) +{ + return (long)hWindow; +} + + +// +// win_gethinstance() -- gets the application instance +// +long win_gethinstance(void) +{ + return (long)hInstance; +} + + +// +// win_allowtaskswitching() -- captures/releases alt+tab hotkeys +// +void win_allowtaskswitching(int onf) +{ + if (onf == taskswitching) return; + + if (onf) { + UnregisterHotKey(0,0); + UnregisterHotKey(0,1); + } else { + RegisterHotKey(0,0,MOD_ALT,VK_TAB); + RegisterHotKey(0,1,MOD_ALT|MOD_SHIFT,VK_TAB); + } + + taskswitching = onf; +} + + +// +// win_checkinstance() -- looks for another instance of a Build app +// +int win_checkinstance(void) +{ + if (!instanceflag) return 0; + return (WaitForSingleObject(instanceflag,0) == WAIT_TIMEOUT); +} + + +// +// wm_msgbox/wm_ynbox() -- window-manager-provided message boxes +// +int wm_msgbox(char *name, char *fmt, ...) +{ + char buf[1000]; + va_list va; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + + MessageBox(hWindow,buf,name,MB_OK|MB_TASKMODAL); + return 0; +} +int wm_ynbox(char *name, char *fmt, ...) +{ + char buf[1000]; + va_list va; + int r; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + + r = MessageBox((HWND)win_gethwnd(),buf,name,MB_YESNO|MB_TASKMODAL); + if (r==IDYES) return 1; + return 0; +} + +// +// wm_setapptitle() -- changes the window title +// +void wm_setapptitle(char *name) +{ + if (name) { + Bstrncpy(apptitle, name, sizeof(apptitle)-1); + apptitle[ sizeof(apptitle)-1 ] = 0; + } + + if (hWindow) SetWindowText(hWindow, apptitle); + if (startupdlg) { + char buf[1000]; + Bsnprintf(buf, 1000, "%s Startup", apptitle); + SetWindowText(startupdlg, buf); + } +} + +// +// SignalHandler() -- called when we've sprung a leak +// +static void SignalHandler(int signum) +{ + switch (signum) { + case SIGSEGV: + printOSD("Fatal Signal caught: SIGSEGV. Bailing out.\n"); + uninitsystem(); + if (stdout) fclose(stdout); + break; + default: + break; + } +} + + +// +// startup_dlgproc() -- dialog procedure for the initialisation dialog +// +#define FIELDSWIDE 366 +#define PADWIDE 5 // 5 units of padding +// An overlayed child dialog should have the DS_CONTROL style + +static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static HBITMAP hbmp = NULL; + RECT rdlg, rbmp, rtxt; + HDC hdc; + int height=5; + + switch (uMsg) { + case WM_INITDIALOG: + // set the bitmap + hbmp = LoadBitmap(hInstance, MAKEINTRESOURCE(WIN_STARTWINBMP)); + SendDlgItemMessage(hwndDlg, WIN_STARTWIN_ITEMBITMAP, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp); + + // fetch the adjusted size + GetClientRect(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMBITMAP), &rbmp); + rbmp.right++; rbmp.bottom++; + + GetClientRect(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMTEXT), &rtxt); + rtxt.bottom++; + + // move the bitmap to the top of the client area + MoveWindow(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMBITMAP), + 0,0, rbmp.right,rbmp.bottom, + FALSE); + + // move the label + MoveWindow(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMTEXT), + rbmp.right+PADWIDE,PADWIDE, FIELDSWIDE,rtxt.bottom, + FALSE); + + // move the list box + MoveWindow(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMLIST), + rbmp.right+PADWIDE,PADWIDE+rtxt.bottom+PADWIDE, + FIELDSWIDE,rbmp.bottom-(PADWIDE+rtxt.bottom+PADWIDE+PADWIDE), + FALSE); + + SendDlgItemMessage(hwndDlg,WIN_STARTWIN_ITEMLIST, EM_LIMITTEXT, 0,0); + { + RECT rg; + GetWindowRect(GetDlgItem(hwndDlg,WIN_STARTWIN_ITEMLIST),&rg); + rg.right -= rg.left + GetSystemMetrics(SM_CXVSCROLL)+4; + rg.bottom -= rg.top; + rg.left = rg.top = 0; + SendDlgItemMessage(hwndDlg,WIN_STARTWIN_ITEMLIST, EM_SETRECTNP,0,(LPARAM)&rg); + } + + rdlg.left = 0; + rdlg.top = 0; + rdlg.right = rbmp.right+PADWIDE+FIELDSWIDE+PADWIDE; + rdlg.bottom = rbmp.bottom; + + AdjustWindowRect(&rdlg, + GetWindowLong(hwndDlg, GWL_STYLE), + FALSE); + + rdlg.right -= rdlg.left; + rdlg.bottom -= rdlg.top; + + hdc = GetDC(NULL); + rdlg.left = (GetDeviceCaps(hdc, HORZRES) - rdlg.right) / 2; + rdlg.top = (GetDeviceCaps(hdc, VERTRES) - rdlg.bottom) / 2; + ReleaseDC(NULL, hdc); + + SetWindowPos(hwndDlg,NULL, + rdlg.left,rdlg.top, + rdlg.right,rdlg.bottom, + SWP_NOREPOSITION); + + // save the safe region of the window + startupdlgsaferect[0] = rbmp.right; // left + startupdlgsaferect[1] = 0; // top + startupdlgsaferect[2] = PADWIDE+FIELDSWIDE+PADWIDE; // width + startupdlgsaferect[3] = rbmp.bottom; // height + + return TRUE; + + case WM_CLOSE: + quitevent = 1; + return TRUE; + + case WM_DESTROY: + if (hbmp) { + DeleteObject(hbmp); + hbmp = NULL; + } + + if (startupdlgonclose) startupdlgonclose(); + + startupdlg = NULL; + return TRUE; + + case WM_COMMAND: + startupdlgcommand = LOWORD(wParam); + return FALSE; + + case WM_CTLCOLORSTATIC: + switch (GetDlgCtrlID((HWND)lParam)) { + case WIN_STARTWIN_ITEMLIST: + return (BOOL)GetSysColorBrush(COLOR_WINDOW); + default: break; + } + break; + + default: break; + } + + return FALSE; +} + + +int win_getstartupwin(long *hwnd, long saferect[4], void (*onclose)(void)) +{ + if (!startupdlg) return 1; + + *hwnd = (long)startupdlg; + memcpy(saferect, startupdlgsaferect, sizeof(long)*4); + startupdlgonclose = onclose; + + return 0; +} + +int win_getstartupcommand(void) +{ + int t = startupdlgcommand; + startupdlgcommand = 0; + return t; +} + + +// +// WinMain() -- main Windows entry point +// +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) +{ + int r; + char *argp; + FILE *fp; + HDC hdc; + + hInstance = hInst; + + if (CheckWinVersion() || hPrevInst) { + MessageBox(0, "This application must be run under Windows 95/98/Me or Windows 2000/XP or better.", + apptitle, MB_OK|MB_ICONSTOP); + return -1; + } + + hdc = GetDC(NULL); + r = GetDeviceCaps(hdc, BITSPIXEL); + ReleaseDC(NULL, hdc); + if (r < 8) { + MessageBox(0, "This application requires a desktop colour depth of 256-colours or more.", + apptitle, MB_OK|MB_ICONSTOP); + return -1; + } + + // carve up the commandline into more recognizable pieces + argvbuf = strdup(GetCommandLine()); + _buildargc = 0; + if (argvbuf) { + char quoted = 0, instring = 0, swallownext = 0; + char *p,*wp; int i; + for (p=wp=argvbuf; *p; p++) { + if (*p == ' ') { + if (instring && !quoted) { + // end of a string + *(wp++) = 0; + instring = 0; + } else if (instring) { + *(wp++) = *p; + } + } else if (*p == '"' && !swallownext) { + if (instring && quoted) { + // end of a string + if (p[1] == ' ') { + *(wp++) = 0; + instring = 0; + quoted = 0; + } else { + quoted = 0; + } + } else if (instring && !quoted) { + quoted = 1; + } else if (!instring) { + instring = 1; + quoted = 1; + _buildargc++; + } + } else if (*p == '\\' && p[1] == '"' && !swallownext) { + swallownext = 1; + } else { + if (!instring) _buildargc++; + instring = 1; + *(wp++) = *p; + swallownext = 0; + } + } + *wp = 0; + + _buildargv = (char**)malloc(sizeof(char*)*_buildargc); + wp = argvbuf; + for (i=0; i<_buildargc; i++,wp++) { + _buildargv[i] = wp; + while (*wp) wp++; + } + } + + // pipe standard outputs to files + if ((argp = Bgetenv("BUILD_LOGSTDOUT")) != NULL) + if (!Bstrcasecmp(argp, "TRUE")) { + fp = freopen("stdout.txt", "w", stdout); + if (!fp) { + fp = fopen("stdout.txt", "w"); + } + if (fp) setvbuf(fp, 0, _IONBF, 0); + *stdout = *fp; + *stderr = *fp; + } + +#if defined(USE_OPENGL) && defined(POLYMOST) + if ((argp = Bgetenv("BUILD_NOFOG")) != NULL) + nofog = Batol(argp); +#endif + + // install signal handlers + signal(SIGSEGV, SignalHandler); + + if (RegisterWindowClass()) return -1; + +#ifdef DISCLAIMER + MessageBox(0, + DISCLAIMER, + "Notice", + MB_OK|MB_ICONINFORMATION); +#endif + + atexit(uninitsystem); + + baselayer_init(); + + instanceflag = CreateSemaphore(NULL, 1,1, WindowClass); + + startupdlg = CreateDialog(hInstance, MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc); + + r = app_main(_buildargc, _buildargv); + + fclose(stdout); + + if (instanceflag) CloseHandle(instanceflag); + + if (argvbuf) free(argvbuf); + + return r; +} + + +static int set_maxrefreshfreq(const osdfuncparm_t *parm) +{ + int freq; + if (parm->numparms == 0) { + if (maxrefreshfreq == 0) + OSD_Printf("maxrefreshfreq = No maximum\n"); + else + OSD_Printf("maxrefreshfreq = %d Hz\n",maxrefreshfreq); + return OSDCMD_OK; + } + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + + freq = Batol(parm->parms[0]); + if (freq < 0) return OSDCMD_SHOWHELP; + + maxrefreshfreq = (unsigned)freq; + modeschecked = 0; + + return OSDCMD_OK; +} + +// +// initsystem() -- init systems +// +int initsystem(void) +{ + DEVMODE desktopmode; + + initprintf("Initialising Windows DirectX/GDI system interface\n"); + + // get the desktop dimensions before anything changes them + ZeroMemory(&desktopmode, sizeof(DEVMODE)); + desktopmode.dmSize = sizeof(DEVMODE); + EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&desktopmode); + + desktopxdim = desktopmode.dmPelsWidth; + desktopydim = desktopmode.dmPelsHeight; + desktopbpp = desktopmode.dmBitsPerPel; + + if (desktopbpp <= 8) + // save the system colours + SaveSystemColours(); + + memset(curpalette, 0, sizeof(palette_t) * 256); + + atexit(uninitsystem); + + frameplace=0; + lockcount=0; + +#if defined(USE_OPENGL) && defined(POLYMOST) + if (loadgldriver(getenv("BUILD_GLDRV"))) { + initprintf("Failed loading OpenGL driver. GL modes will be unavailable.\n"); + nogl = 1; + } +#endif + + // try and start DirectDraw + if (InitDirectDraw()) + initprintf("DirectDraw initialisation failed. Fullscreen modes will be unavailable.\n"); + + OSD_RegisterFunction("maxrefreshfreq", "maxrefreshfreq: maximum display frequency to set for OpenGL Polymost modes (0=no maximum)", set_maxrefreshfreq); + return 0; +} + + +// +// uninitsystem() -- uninit systems +// +void uninitsystem(void) +{ + DestroyAppWindow(); + + if (startupdlg) { + DestroyWindow(startupdlg); + } + + uninitinput(); + uninittimer(); + + win_allowtaskswitching(1); + +#if defined(USE_OPENGL) && defined(POLYMOST) + unloadgldriver(); +#endif +} + + +// +// initprintf() -- prints a string to the intitialization window +// +void initprintf(const char *f, ...) +{ + va_list va; + char buf[1024],*p=NULL,*q=NULL,workbuf[1024]; + //int i = 0; + + static int newline = 0;//1; +// int overwriteline = -1; + + va_start(va, f); + Bvsnprintf(buf, 1024, f, va); + va_end(va); + OSD_Printf(buf); + if (!startupdlg) return; + + { + int curlen, linesbefore, linesafter; + HWND edctl; + + edctl = GetDlgItem(startupdlg,102); + if (!edctl) return; + + SendMessage(edctl, WM_SETREDRAW, FALSE,0); + curlen = SendMessage(edctl, WM_GETTEXTLENGTH, 0,0); + SendMessage(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen); + linesbefore = SendMessage(edctl, EM_GETLINECOUNT, 0,0); + p = buf; + while (*p) { + if (newline) { + SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n"); + newline = 0; + } + q = p; + while (*q && *q != '\n') q++; + memcpy(workbuf, p, q-p); + if (*q == '\n') { + if (!q[1]) { + newline = 1; + workbuf[q-p] = 0; + } else { + workbuf[q-p] = '\r'; + workbuf[q-p+1] = '\n'; + workbuf[q-p+2] = 0; + } + p = q+1; + } else { + workbuf[q-p] = 0; + p = q; + } + SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)workbuf); + } + linesafter = SendMessage(edctl, EM_GETLINECOUNT, 0,0); + SendMessage(edctl, EM_LINESCROLL, 0, linesafter-linesbefore); + SendMessage(edctl, WM_SETREDRAW, TRUE,0); + } + handleevents(); +} + + +// +// debugprintf() -- sends a debug string to the debugger +// +void debugprintf(const char *f, ...) +{ +#ifdef DEBUGGINGAIDS + va_list va; + char buf[1024]; + + if (!IsDebuggerPresent()) return; + + va_start(va,f); + Bvsnprintf(buf, 1024, f, va); + va_end(va); + + OutputDebugString(buf); +#endif +} + + +// +// handleevents() -- process the Windows message queue +// returns !0 if there was an important event worth checking (like quitting) +// +int handleevents(void) +{ + int rv=0; + MSG msg; + + //if (frameplace && fullscreen) printf("Offscreen buffer is locked!\n"); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) + quitevent = 1; + + if (IsWindow(startupdlg) && IsDialogMessage(startupdlg, &msg)) continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + ProcessInputDevices(); + +#ifdef DEBUGGINGAIDS + // break to the debugger if KP- is pressed + if (IsDebuggerPresent() && keystatus[0x4a]) { + keystatus[0x4a] = 0; + DebugBreak(); + } +#endif + + if (!appactive || quitevent) rv = -1; + + sampletimer(); + + return rv; +} + + + + + + + +//------------------------------------------------------------------------------------------------- +// INPUT (MOUSE/KEYBOARD/JOYSTICK?) +//================================================================================================= + +#define KEYBOARD 0 +#define MOUSE 1 +#define JOYSTICK 2 +#define NUM_INPUTS 3 + +static HMODULE hDInputDLL = NULL; +static LPDIRECTINPUTA lpDI = NULL; +static LPDIRECTINPUTDEVICE2A lpDID[NUM_INPUTS] = { NULL, NULL, NULL }; +static BOOL bDInputInited = FALSE; +#define INPUT_BUFFER_SIZE 32 +static GUID guidDevs[NUM_INPUTS]; + +static char devacquired[NUM_INPUTS] = { 0,0,0 }; +static HANDLE inputevt[NUM_INPUTS] = {0,0,0}; +static long joyblast=0; +static char moustat = 0, mousegrab = 0; + +static struct { + char *name; + LPDIRECTINPUTDEVICE2A *did; + const DIDATAFORMAT *df; +} devicedef[NUM_INPUTS] = { + { "keyboard", &lpDID[KEYBOARD], &c_dfDIKeyboard }, + { "mouse", &lpDID[MOUSE], &c_dfDIMouse }, + { "joystick", &lpDID[JOYSTICK], &c_dfDIJoystick } +}; +static struct _joydef { + const char *name; + unsigned ofs; // directinput 'dwOfs' value +} *axisdefs = NULL, *buttondefs = NULL, *hatdefs = NULL; + +struct _joydevicefeature { + unsigned int ofs; + const char *name; +}; +struct _joydevicedefn { + unsigned long devid; // is the value of DIDEVICEINSTANCE.guidProduct.Data1 + int nfeatures; + struct _joydevicefeature *features; +}; + +// This is to give more realistic names to the buttons, axes, etc on a controller than +// those the driver reports. Curse inconsistency. +struct _joydevicefeature joyfeatures_C20A046D[] = { // Logitech WingMan RumblePad USB + { 0, "Left Stick X" }, { 4, "Left Stick Y" }, { 8, "Right Stick X" }, + { 20, "Right Stick Y" }, { 24, "Throttle" }, +}; +struct _joydevicefeature joyfeatures_C218046D[] = { // Logitech RumblePad 2 USB + { 0, "Left Stick X" }, { 4, "Left Stick Y" }, { 8, "Right Stick X" }, + { 20, "Right Stick Y" }, { 32, "D-Pad" }, { 48, "Button 1" }, + { 49, "Button 2" }, { 50, "Button 3" }, { 51, "Button 4" }, + { 52, "Button 5" }, { 53, "Button 6" }, { 54, "Button 7" }, + { 55, "Button 8" }, { 56, "Button 9" }, { 57, "Button 10" }, + { 58, "Left Stick Press" }, { 59, "Right Stick Press" }, +}; +#define featurecount(x) (sizeof(x)/sizeof(struct _joydevicefeature)) +static struct _joydevicedefn *thisjoydef = NULL, joyfeatures[] = { + { 0xC20A046D, featurecount(joyfeatures_C20A046D), joyfeatures_C20A046D }, // Logitech WingMan RumblePad USB + { 0xC218046D, featurecount(joyfeatures_C218046D), joyfeatures_C218046D }, // Logitech RumblePad 2 USB +}; +#undef featurecount + +// I don't see any pressing need to store the key-up events yet +#define SetKey(key,state) { \ + keystatus[key] = state; \ + if (state) { \ + keyfifo[keyfifoend] = key; \ + keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = state; \ + keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); \ + } \ +} + + +// +// initinput() -- init input system +// +int initinput(void) +{ + moustat=0; + memset(keystatus, 0, sizeof(keystatus)); + keyfifoplc = keyfifoend = 0; + keyasciififoplc = keyasciififoend = 0; + + inputdevices = 0; + joyisgamepad=0, joynumaxes=0, joynumbuttons=0, joynumhats=0; + + if (InitDirectInput()) + return -1; + + return 0; +} + + +// +// uninitinput() -- uninit input system +// +void uninitinput(void) +{ + uninitmouse(); + UninitDirectInput(); +} + + +// +// bgetchar, bkbhit, bflushchars -- character-based input functions +// +unsigned char bgetchar(void) +{ + unsigned char c; + if (keyasciififoplc == keyasciififoend) return 0; + c = keyasciififo[keyasciififoplc]; + keyasciififoplc = ((keyasciififoplc+1)&(KEYFIFOSIZ-1)); + return c; +} + +int bkbhit(void) +{ + return (keyasciififoplc != keyasciififoend); +} + +void bflushchars(void) +{ + keyasciififoplc = keyasciififoend = 0; +} + + +// +// set{key|mouse|joy}presscallback() -- sets a callback which gets notified when keys are pressed +// +void setkeypresscallback(void (*callback)(long, long)) { keypresscallback = callback; } +void setmousepresscallback(void (*callback)(long, long)) { mousepresscallback = callback; } +void setjoypresscallback(void (*callback)(long, long)) { joypresscallback = callback; } + + +// +// initmouse() -- init mouse input +// +int initmouse(void) +{ + if (moustat) return 0; + + initprintf("Initialising mouse\n"); + + // grab input + moustat=1; + grabmouse(1); + + return 0; +} + + +// +// uninitmouse() -- uninit mouse input +// +void uninitmouse(void) +{ + if (!moustat) return; + + grabmouse(0); + moustat=mousegrab=0; +} + + +// +// grabmouse() -- show/hide mouse cursor +// +void grabmouse(char a) +{ + if (!moustat) return; + + mousegrab = a; + AcquireInputDevices(a,MOUSE); // only release or grab the mouse + + mousex = 0; + mousey = 0; + mouseb = 0; +} + + +// +// readmousexy() -- return mouse motion information +// +void readmousexy(long *x, long *y) +{ + if (!moustat || !devacquired[MOUSE] || !mousegrab) { *x = *y = 0; return; } + *x = mousex; + *y = mousey; + mousex = 0; + mousey = 0; +} + + +// +// readmousebstatus() -- return mouse button information +// +void readmousebstatus(long *b) +{ + if (!moustat || !devacquired[MOUSE] || !mousegrab) *b = 0; + else *b = mouseb; +} + + +// +// setjoydeadzone() -- sets the dead and saturation zones for the joystick +// +void setjoydeadzone(int axis, unsigned short dead, unsigned short satur) +{ + DIPROPDWORD dipdw; + HRESULT result; + + if (!lpDID[JOYSTICK]) return; + + if (dead > 10000) dead = 10000; + if (satur > 10000) satur = 10000; + if (dead >= satur) dead = satur-100; + if (axis >= joynumaxes) return; + + memset(&dipdw, 0, sizeof(dipdw)); + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + if (axis < 0) { + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + } else { + dipdw.diph.dwObj = axisdefs[axis].ofs; + dipdw.diph.dwHow = DIPH_BYOFFSET; + } + dipdw.dwData = dead; + + result = IDirectInputDevice2_SetProperty(lpDID[JOYSTICK], DIPROP_DEADZONE, &dipdw.diph); + if FAILED(result) { + //ShowDInputErrorBox("Failed setting joystick dead zone", result); + initprintf("Failed setting joystick dead zone: %s\n", GetDInputError(result)); + return; + } + + dipdw.dwData = satur; + + result = IDirectInputDevice2_SetProperty(lpDID[JOYSTICK], DIPROP_SATURATION, &dipdw.diph); + if FAILED(result) { + //ShowDInputErrorBox("Failed setting joystick saturation point", result); + initprintf("Failed setting joystick saturation point: %s\n", GetDInputError(result)); + return; + } +} + + +// +// getjoydeadzone() -- gets the dead and saturation zones for the joystick +// +void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur) +{ + DIPROPDWORD dipdw; + HRESULT result; + + if (!dead || !satur) return; + if (!lpDID[JOYSTICK]) { *dead = *satur = 0; return; } + if (axis >= joynumaxes) { *dead = *satur = 0; return; } + + memset(&dipdw, 0, sizeof(dipdw)); + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + if (axis < 0) { + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + } else { + dipdw.diph.dwObj = axisdefs[axis].ofs; + dipdw.diph.dwHow = DIPH_BYOFFSET; + } + + result = IDirectInputDevice2_GetProperty(lpDID[JOYSTICK], DIPROP_DEADZONE, &dipdw.diph); + if FAILED(result) { + //ShowDInputErrorBox("Failed getting joystick dead zone", result); + initprintf("Failed getting joystick dead zone: %s\n", GetDInputError(result)); + return; + } + + *dead = dipdw.dwData; + + result = IDirectInputDevice2_GetProperty(lpDID[JOYSTICK], DIPROP_SATURATION, &dipdw.diph); + if FAILED(result) { + //ShowDInputErrorBox("Failed getting joystick saturation point", result); + initprintf("Failed getting joystick saturation point: %s\n", GetDInputError(result)); + return; + } + + *satur = dipdw.dwData; +} + + +void releaseallbuttons(void) +{ + int i; + + if (mousepresscallback) { + if (mouseb & 1) mousepresscallback(1, 0); + if (mouseb & 2) mousepresscallback(2, 0); + if (mouseb & 4) mousepresscallback(3, 0); + if (mouseb & 8) mousepresscallback(4, 0); + if (mousewheel[0]>0) mousepresscallback(5,0); + if (mousewheel[1]>0) mousepresscallback(6,0); + } + mousewheel[0]=mousewheel[1]=0; + mouseb = 0; + + if (joypresscallback) { + for (i=0;i<32;i++) + if (joyb & (1<dwDevType&0xff) { + case DIDEVTYPE_KEYBOARD: + inputdevices |= (1<guidInstance); + break; + case DIDEVTYPE_MOUSE: + inputdevices |= (1<guidInstance); + break; + case DIDEVTYPE_JOYSTICK: + inputdevices |= (1<dwDevType & (DIDEVTYPEJOYSTICK_GAMEPAD<<8)) != 0); + d = joyisgamepad ? "GAMEPAD" : "JOYSTICK"; + COPYGUID(guidDevs[JOYSTICK],lpddi->guidInstance); + + thisjoydef = NULL; + for (i=0; i<(int)(sizeof(joyfeatures)/sizeof(joyfeatures[0])); i++) { + if (lpddi->guidProduct.Data1 == joyfeatures[i].devid) { + thisjoydef = &joyfeatures[i]; + break; + } + } + + // Outputs the GUID of the joystick to the console + /* + initprintf("GUID = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n", + lpddi->guidProduct.Data1, + lpddi->guidProduct.Data2, lpddi->guidProduct.Data3, + lpddi->guidProduct.Data4[0], lpddi->guidProduct.Data4[1], + lpddi->guidProduct.Data4[2], lpddi->guidProduct.Data4[3], + lpddi->guidProduct.Data4[4], lpddi->guidProduct.Data4[5], + lpddi->guidProduct.Data4[6], lpddi->guidProduct.Data4[7] + ); + */ + break; + default: d = "OTHER"; break; + } + + initprintf(" * %s: %s\n", d, lpddi->tszProductName); + + return DIENUM_CONTINUE; +} + +static const char *joyfindnameforofs(int ofs) +{ + int i; + if (!thisjoydef) return NULL; + for (i=0;infeatures;i++) { + if (ofs == (int)thisjoydef->features[i].ofs) + return Bstrdup(thisjoydef->features[i].name); + } + return NULL; +} + +static BOOL CALLBACK InitDirectInput_enumobjects(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) +{ + unsigned i; + long *typecounts = (long*)pvRef; + + if (lpddoi->dwType & DIDFT_AXIS) { + //initprintf(" Axis: %s (dwOfs=%d)\n", lpddoi->tszName, lpddoi->dwOfs); + + axisdefs[ typecounts[0] ].name = joyfindnameforofs(lpddoi->dwOfs); + if (!axisdefs[ typecounts[0] ].name) + axisdefs[ typecounts[0] ].name = Bstrdup(lpddoi->tszName); + axisdefs[ typecounts[0] ].ofs = lpddoi->dwOfs; + + typecounts[0]++; + } else if (lpddoi->dwType & DIDFT_BUTTON) { + //initprintf(" Button: %s (dwOfs=%d)\n", lpddoi->tszName, lpddoi->dwOfs); + + buttondefs[ typecounts[1] ].name = joyfindnameforofs(lpddoi->dwOfs); + if (!buttondefs[ typecounts[1] ].name) + buttondefs[ typecounts[1] ].name = Bstrdup(lpddoi->tszName); + buttondefs[ typecounts[1] ].ofs = lpddoi->dwOfs; + + typecounts[1]++; + } else if (lpddoi->dwType & DIDFT_POV) { + //initprintf(" POV: %s (dwOfs=%d)\n", lpddoi->tszName, lpddoi->dwOfs); + + hatdefs[ typecounts[2] ].name = joyfindnameforofs(lpddoi->dwOfs); + if (!hatdefs[ typecounts[2] ].name) + hatdefs[ typecounts[2] ].name = Bstrdup(lpddoi->tszName); + hatdefs[ typecounts[2] ].ofs = lpddoi->dwOfs; + + typecounts[2]++; + } + + return DIENUM_CONTINUE; +} + +#define HorribleDInputDeath( x, y ) \ + ShowDInputErrorBox(x,y); \ + UninitDirectInput(); \ + return TRUE + +static BOOL InitDirectInput(void) +{ + HRESULT result; + HRESULT (WINAPI *aDirectInputCreateA)(HINSTANCE, DWORD, LPDIRECTINPUTA *, LPUNKNOWN); + DIPROPDWORD dipdw; + LPDIRECTINPUTDEVICEA dev; + LPDIRECTINPUTDEVICE2A dev2; + DIDEVCAPS didc; + + int devn,i; + + if (bDInputInited) return FALSE; + + initprintf("Initialising DirectInput...\n"); + + // load up the DirectInput DLL + if (!hDInputDLL) { + initprintf(" - Loading DINPUT.DLL\n"); + hDInputDLL = LoadLibrary("DINPUT.DLL"); + if (!hDInputDLL) { + ShowErrorBox("Error loading DINPUT.DLL"); + return TRUE; + } + } + + // get the pointer to DirectInputCreate + aDirectInputCreateA = (void *)GetProcAddress(hDInputDLL, "DirectInputCreateA"); + if (!aDirectInputCreateA) ShowErrorBox("Error fetching DirectInputCreateA()"); + + // create a new DirectInput object + initprintf(" - Creating DirectInput object\n"); + result = aDirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &lpDI, NULL); + if FAILED(result) { HorribleDInputDeath("DirectInputCreateA() failed", result); } + else if (result != DI_OK) initprintf(" Created DirectInput object with warning: %s\n",GetDInputError(result)); + + // enumerate devices to make us look fancy + initprintf(" - Enumerating attached input devices\n"); + inputdevices = 0; + result = IDirectInput_EnumDevices(lpDI, 0, InitDirectInput_enum, NULL, DIEDFL_ATTACHEDONLY); + if FAILED(result) { HorribleDInputDeath("Failed enumerating attached input devices", result); } + else if (result != DI_OK) initprintf(" Enumerated input devices with warning: %s\n",GetDInputError(result)); + if (!(inputdevices & (1<=0; i--) if (axisdefs[i].name) free((void*)axisdefs[i].name); + free(axisdefs); axisdefs = NULL; + } + if (buttondefs) { + for (i=joynumbuttons-1; i>=0; i--) if (buttondefs[i].name) free((void*)buttondefs[i].name); + free(buttondefs); buttondefs = NULL; + } + if (hatdefs) { + for (i=joynumhats-1; i>=0; i--) if (hatdefs[i].name) free((void*)hatdefs[i].name); + free(hatdefs); hatdefs = NULL; + } + + for (devn = 0; devn < NUM_INPUTS; devn++) { + if (*devicedef[devn].did) { + initprintf(" - Releasing %s device\n", devicedef[devn].name); + + if (devn != JOYSTICK) IDirectInputDevice2_SetEventNotification(*devicedef[devn].did, NULL); + + IDirectInputDevice2_Release(*devicedef[devn].did); + *devicedef[devn].did = NULL; + } + if (inputevt[devn]) { + CloseHandle(inputevt[devn]); + inputevt[devn] = NULL; + } + } + + if (lpDI) { + initprintf(" - Releasing DirectInput object\n"); + IDirectInput_Release(lpDI); + lpDI = NULL; + } + + if (hDInputDLL) { + initprintf(" - Unloading DINPUT.DLL\n"); + FreeLibrary(hDInputDLL); + hDInputDLL = NULL; + } + + bDInputInited = FALSE; +} + + +// +// GetKeyNames() -- retrieves the names for all the keys on the keyboard +// +static void GetKeyNames(void) +{ + int i; + DIDEVICEOBJECTINSTANCE key; + HRESULT res; + char tbuf[MAX_PATH]; + + memset(keynames,0,sizeof(keynames)); + for (i=0;i<256;i++) { + ZeroMemory(&key,sizeof(key)); + key.dwSize = sizeof(DIDEVICEOBJECTINSTANCE); + + res = IDirectInputDevice_GetObjectInfo(*devicedef[KEYBOARD].did, &key, i, DIPH_BYOFFSET); + if (FAILED(res)) continue; + + CharToOem(key.tszName, tbuf); + strncpy(keynames[i], tbuf, sizeof(keynames[i])-1); + } +} + +const unsigned char *getkeyname(int num) +{ + if ((unsigned)num >= 256) return NULL; + return keynames[num]; +} + +const unsigned char *getjoyname(int what, int num) +{ + switch (what) { + case 0: // axis + if ((unsigned)num > (unsigned)joynumaxes) return NULL; + return axisdefs[num].name; + + case 1: // button + if ((unsigned)num > (unsigned)joynumbuttons) return NULL; + return buttondefs[num].name; + + case 2: // hat + if ((unsigned)num > (unsigned)joynumhats) return NULL; + return hatdefs[num].name; + + default: + return NULL; + } +} + +// +// AcquireInputDevices() -- (un)acquires the input devices +// +static void AcquireInputDevices(char acquire, signed char device) +{ + DWORD flags; + HRESULT result; + int i; + + if (!bDInputInited) return; + if (!hWindow) return; + + if (acquire) { + if (!appactive) return; // why acquire when inactive? + for (i=0; i 0 && t - mousewheel[0] > MouseWheelFakePressTime) { + if (mousepresscallback) mousepresscallback(5,0); + mousewheel[0] = 0; mouseb &= ~16; + } + if (mousewheel[1] > 0 && t - mousewheel[1] > MouseWheelFakePressTime) { + if (mousepresscallback) mousepresscallback(6,0); + mousewheel[1] = 0; mouseb &= ~32; + } + } + + if (numdevs == 0) return; // nothing to do + + // use event objects so that we can quickly get indication of when data is ready + // to be read and input events processed + ev = MsgWaitForMultipleObjects(numdevs, waithnds, FALSE, 0, 0); + if (/*(ev >= WAIT_OBJECT_0) &&*/ (ev < (WAIT_OBJECT_0+numdevs))) { + switch (idevnums[ev - WAIT_OBJECT_0]) { + case KEYBOARD: // keyboard + if (!lpDID[KEYBOARD]) break; + result = IDirectInputDevice2_GetDeviceData(lpDID[KEYBOARD], sizeof(DIDEVICEOBJECTDATA), + (LPDIDEVICEOBJECTDATA)&didod, &dwElements, 0); + if (result == DI_OK) { + DWORD k, numlockon = FALSE; + static DWORD shiftkey = 0, shiftkeycount = 0; + + numlockon = (GetKeyState(VK_NUMLOCK) & 1); + + // process the key events + for (i=0; i shiftkey=1, shiftkeycount=0\n"); + } + } else { + if ((thiskey == (SHIFT|UP)) && (nextkey == (NUMPAD|DOWN))) { + shiftkeycount--; + initprintf("shift is up and next key is numpad and down, shiftkeycount=%d\n", + shiftkeycount); + continue; + } else if (thiskey & SHIFT) { + if (thiskey & DOWN) { + shiftkeycount++; + initprintf("shift key down, shiftkeycount=%d\n", shiftkeycount); + continue; + } else { + if (shiftkeycount == 0) { + shiftkey = 0; + initprintf("shift key up and shiftkeycount == 0, shiftkey=0\n"); + } else { + shiftkeycount--; + initprintf("shift key up and shiftkeycount=%d\n",shiftkeycount); + continue; + } + } + } + } +#undef NUMPAD +#undef SHIFT +#undef UP +#undef DOWN + } +#endif + + if (k == DIK_PAUSE) continue; // fucking pause + + // hook in the osd + if (OSD_HandleKey(k, (didod[i].dwData & 0x80)) != 0) { + SetKey(k, (didod[i].dwData & 0x80) == 0x80); + + if (keypresscallback) + keypresscallback(k, (didod[i].dwData & 0x80) == 0x80); + } + + if (((lastKeyDown & 0x7fffffffl) == k) && !(didod[i].dwData & 0x80)) + lastKeyDown = 0; + else if (didod[i].dwData & 0x80) { + lastKeyDown = k; + lastKeyTime = t; + } + } + } + break; + + case MOUSE: // mouse + if (!lpDID[MOUSE]) break; + result = IDirectInputDevice2_GetDeviceData(lpDID[MOUSE], sizeof(DIDEVICEOBJECTDATA), + (LPDIDEVICEOBJECTDATA)&didod, &dwElements, 0); + + if (!mousegrab) break; + + if (result == DI_OK) { + // process the mouse events + mousex=0; + mousey=0; + for (i=0; i 0) { // wheel up + if (mousewheel[1] > 0 && mousepresscallback) mousepresscallback(6,0); + mousewheel[1] = t; + mouseb |= 32; if (mousepresscallback) mousepresscallback(6, 1); + } + else if ((int)didod[i].dwData < 0) { // wheel down + if (mousewheel[1] > 0 && mousepresscallback) mousepresscallback(6,0); + mousewheel[0] = t; + mouseb |= 16; if (mousepresscallback) mousepresscallback(5, 1); + } + break; + } + } + } + break; + case JOYSTICK: // joystick + if (!lpDID[JOYSTICK]) break; + result = IDirectInputDevice2_GetDeviceData(lpDID[JOYSTICK], sizeof(DIDEVICEOBJECTDATA), + (LPDIDEVICEOBJECTDATA)&didod, &dwElements, 0); + if (result == DI_OK) { + int j; + + for (i=0; i 0) { + u = (1000 + t - lastKeyTime)%1000; + if ((u >= 250) && !(lastKeyDown&0x80000000l)) { + if (OSD_HandleKey(lastKeyDown, 1) != 0) + SetKey(lastKeyDown, 1); + lastKeyDown |= 0x80000000l; + lastKeyTime = t; + } else if ((u >= 30) && (lastKeyDown&0x80000000l)) { + if (OSD_HandleKey(lastKeyDown&(0x7fffffffl), 1) != 0) + SetKey(lastKeyDown&(0x7fffffffl), 1); + lastKeyTime = t; + } + } +} + + +// +// ShowDInputErrorBox() -- shows an error message box for a DirectInput error +// +static void ShowDInputErrorBox(const char *m, HRESULT r) +{ + TCHAR msg[1024]; + + wsprintf(msg, "%s: %s", m, GetDInputError(r)); + MessageBox(0, msg, apptitle, MB_OK|MB_ICONSTOP); +} + + +// +// GetDInputError() -- stinking huge list of error messages since MS didn't want to include +// them in the DLL +// +static const char * GetDInputError(HRESULT code) +{ + switch (code) { + case DI_OK: return "DI_OK"; + case DI_BUFFEROVERFLOW: return "DI_BUFFEROVERFLOW"; + case DI_DOWNLOADSKIPPED: return "DI_DOWNLOADSKIPPED"; + case DI_EFFECTRESTARTED: return "DI_EFFECTRESTARTED"; + case DI_POLLEDDEVICE: return "DI_POLLEDDEVICE"; + case DI_TRUNCATED: return "DI_TRUNCATED"; + case DI_TRUNCATEDANDRESTARTED: return "DI_TRUNCATEDANDRESTARTED"; + case DIERR_ACQUIRED: return "DIERR_ACQUIRED"; + case DIERR_ALREADYINITIALIZED: return "DIERR_ALREADYINITIALIZED"; + case DIERR_BADDRIVERVER: return "DIERR_BADDRIVERVER"; + case DIERR_BETADIRECTINPUTVERSION: return "DIERR_BETADIRECTINPUTVERSION"; + case DIERR_DEVICEFULL: return "DIERR_DEVICEFULL"; + case DIERR_DEVICENOTREG: return "DIERR_DEVICENOTREG"; + case DIERR_EFFECTPLAYING: return "DIERR_EFFECTPLAYING"; + case DIERR_HASEFFECTS: return "DIERR_HASEFFECTS"; + case DIERR_GENERIC: return "DIERR_GENERIC"; + case DIERR_HANDLEEXISTS: return "DIERR_HANDLEEXISTS"; + case DIERR_INCOMPLETEEFFECT: return "DIERR_INCOMPLETEEFFECT"; + case DIERR_INPUTLOST: return "DIERR_INPUTLOST"; + case DIERR_INVALIDPARAM: return "DIERR_INVALIDPARAM"; + case DIERR_MOREDATA: return "DIERR_MOREDATA"; + case DIERR_NOAGGREGATION: return "DIERR_NOAGGREGATION"; + case DIERR_NOINTERFACE: return "DIERR_NOINTERFACE"; + case DIERR_NOTACQUIRED: return "DIERR_NOTACQUIRED"; + case DIERR_NOTBUFFERED: return "DIERR_NOTBUFFERED"; + case DIERR_NOTDOWNLOADED: return "DIERR_NOTDOWNLOADED"; + case DIERR_NOTEXCLUSIVEACQUIRED: return "DIERR_NOTEXCLUSIVEACQUIRED"; + case DIERR_NOTFOUND: return "DIERR_NOTFOUND"; + case DIERR_NOTINITIALIZED: return "DIERR_NOTINITIALIZED"; + case DIERR_OLDDIRECTINPUTVERSION: return "DIERR_OLDDIRECTINPUTVERSION"; + case DIERR_OUTOFMEMORY: return "DIERR_OUTOFMEMORY"; + case DIERR_UNSUPPORTED: return "DIERR_UNSUPPORTED"; + case E_PENDING: return "E_PENDING"; + default: break; + } + return "Unknown error"; +} + + + + +//------------------------------------------------------------------------------------------------- +// TIMER +//================================================================================================= + +static int64 timerfreq=0; +static long timerlastsample=0; +static int timerticspersec=0; +static void (*usertimercallback)(void) = NULL; + +// This timer stuff is all Ken's idea. + +// +// installusertimercallback() -- set up a callback function to be called when the timer is fired +// +void (*installusertimercallback(void (*callback)(void)))(void) +{ + void (*oldtimercallback)(void); + + oldtimercallback = usertimercallback; + usertimercallback = callback; + + return oldtimercallback; +} + + +// +// inittimer() -- initialise timer +// +int inittimer(int tickspersecond) +{ + int64 t; + + if (timerfreq) return 0; // already installed + + initprintf("Initialising timer\n"); + + // OpenWatcom seems to want us to query the value into a local variable + // instead of the global 'timerfreq' or else it gets pissed with an + // access violation + if (!QueryPerformanceFrequency((LARGE_INTEGER*)&t)) { + ShowErrorBox("Failed fetching timer frequency"); + return -1; + } + timerfreq = t; + timerticspersec = tickspersecond; + QueryPerformanceCounter((LARGE_INTEGER*)&t); + timerlastsample = (long)(t*timerticspersec / timerfreq); + + usertimercallback = NULL; + + return 0; +} + +// +// uninittimer() -- shut down timer +// +void uninittimer(void) +{ + if (!timerfreq) return; + + timerfreq=0; + timerticspersec = 0; +} + +// +// sampletimer() -- update totalclock +// +void sampletimer(void) +{ + int64 i; + long n; + + if (!timerfreq) return; + + QueryPerformanceCounter((LARGE_INTEGER*)&i); + n = (long)(i*timerticspersec / timerfreq) - timerlastsample; + if (n>0) { + totalclock += n; + timerlastsample += n; + } + + if (usertimercallback) for (; n>0; n--) usertimercallback(); +} + + +// +// getticks() -- returns the windows ticks count +// +unsigned long getticks(void) +{ + int64 i; + if (timerfreq == 0) return 0; + QueryPerformanceCounter((LARGE_INTEGER*)&i); + return (unsigned long)(i*longlong(1000)/timerfreq); +} + + +// +// gettimerfreq() -- returns the number of ticks per second the timer is configured to generate +// +int gettimerfreq(void) +{ + return timerticspersec; +} + + + + +//------------------------------------------------------------------------------------------------- +// VIDEO +//================================================================================================= + +// DirectDraw objects +static HMODULE hDDrawDLL = NULL; +static LPDIRECTDRAW lpDD = NULL; +static LPDIRECTDRAWSURFACE lpDDSPrimary = NULL; +static LPDIRECTDRAWSURFACE lpDDSBack = NULL; +static char * lpOffscreen = NULL; +static LPDIRECTDRAWPALETTE lpDDPalette = NULL; +static BOOL bDDrawInited = FALSE; +static DWORD DDdwCaps = 0, DDdwCaps2 = 0; + +// DIB stuff +static HDC hDC = NULL; // opengl shares this +static HDC hDCSection = NULL; +static HBITMAP hDIBSection = NULL; +static HPALETTE hPalette = NULL; +static VOID *lpPixels = NULL; + +#define NUM_SYS_COLOURS 25 +static int syscolouridx[NUM_SYS_COLOURS] = { + COLOR_SCROLLBAR, // 1 + COLOR_BACKGROUND, + COLOR_ACTIVECAPTION, + COLOR_INACTIVECAPTION, + COLOR_MENU, + COLOR_WINDOW, + COLOR_WINDOWFRAME, + COLOR_MENUTEXT, + COLOR_WINDOWTEXT, + COLOR_CAPTIONTEXT, // 10 + COLOR_ACTIVEBORDER, + COLOR_INACTIVEBORDER, + COLOR_APPWORKSPACE, + COLOR_HIGHLIGHT, + COLOR_HIGHLIGHTTEXT, + COLOR_BTNFACE, + COLOR_BTNSHADOW, + COLOR_GRAYTEXT, + COLOR_BTNTEXT, + COLOR_INACTIVECAPTIONTEXT, // 20 + COLOR_BTNHIGHLIGHT, + COLOR_3DDKSHADOW, + COLOR_3DLIGHT, + COLOR_INFOTEXT, + COLOR_INFOBK // 25 +}; +static DWORD syscolours[NUM_SYS_COLOURS]; +static char system_colours_saved = 0, bw_colours_set = 0; + +static int setgammaramp(WORD gt[3][256]); +static int getgammaramp(WORD gt[3][256]); + +// +// checkvideomode() -- makes sure the video mode passed is legal +// +int checkvideomode(int *x, int *y, int c, int fs) +{ + int i, nearest=-1, dx, dy, odx=9999, ody=9999; + + getvalidmodes(); + + // fix up the passed resolution values to be multiples of 8 + // and at least 320x200 or at most MAXXDIMxMAXYDIM + if (*x < 320) *x = 320; + if (*y < 200) *y = 200; + if (*x > MAXXDIM) *x = MAXXDIM; + if (*y > MAXYDIM) *y = MAXYDIM; + *x &= 0xfffffff8l; + + for (i=0; i= 0) gammabrightness = 1; + if (gammabrightness && setgamma(f,f,f) < 0) gammabrightness = 0; + } + + for (i=0;i8); + + return 0; +} + + +// +// getvalidmodes() -- figure out what video modes are available +// +#define ADDMODE(x,y,c,f,n) if (validmodecnt 8) { + for (i=0;i modes[i].freq && maxrefreshfreq > 0) || + (dm.dmDisplayFrequency > modes[i].freq && maxrefreshfreq == 0)) { + if (i==nmodes) nmodes++; + + modes[i].x = dm.dmPelsWidth; + modes[i].y = dm.dmPelsHeight; + modes[i].bpp = dm.dmBitsPerPel; + modes[i].freq = dm.dmDisplayFrequency; + } + } + + j++; + ZeroMemory(&dm,sizeof(DEVMODE)); + dm.dmSize = sizeof(DEVMODE); + } + + for (i=0;iddpfPixelFormat.dwRGBBitCount == 8) { + CHECK(ddsd->dwWidth, ddsd->dwHeight) + ADDMODE(ddsd->dwWidth, ddsd->dwHeight, ddsd->ddpfPixelFormat.dwRGBBitCount, 1,-1); + } + + return(DDENUMRET_OK); +} + +static int sortmodes(const struct validmode_t *a, const struct validmode_t *b) +{ + int x; + + if ((x = a->fs - b->fs) != 0) return x; + if ((x = a->bpp - b->bpp) != 0) return x; + if ((x = a->xdim - b->xdim) != 0) return x; + if ((x = a->ydim - b->ydim) != 0) return x; + + return 0; +} +void getvalidmodes(void) +{ + static int defaultres[][2] = { + {1280,1024},{1280,960},{1152,864},{1024,768},{800,600},{640,480}, + {640,400},{512,384},{480,360},{400,300},{320,240},{320,200},{0,0} + }; + int cdepths[2] = { 8, 0 }; + int i, j, maxx=0, maxy=0; + HRESULT result; + +#if defined(USE_OPENGL) && defined(POLYMOST) + if (desktopbpp > 8) cdepths[1] = desktopbpp; +#endif + + if (modeschecked) return; + + validmodecnt=0; + initprintf("Detecting video modes:\n"); + + if (bDDrawInited) { + // if DirectDraw initialisation didn't fail enumerate fullscreen modes + + result = IDirectDraw_EnumDisplayModes(lpDD, 0, NULL, 0, getvalidmodes_enum); + if (result != DD_OK) { + initprintf("Unable to enumerate fullscreen modes. Using default list.\n"); + for (j=0; j < 2; j++) { + if (cdepths[j] == 0) continue; + for (i=0; defaultres[i][0]; i++) + ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],1,-1) + } + } + } +#if defined(USE_OPENGL) && defined(POLYMOST) + cdsenummodes(); +#endif + + // windowed modes cant be bigger than the current desktop resolution + maxx = desktopxdim-1; + maxy = desktopydim-1; + + // add windowed modes next + for (j=0; j < 2; j++) { + if (cdepths[j] == 0) continue; + for (i=0; defaultres[i][0]; i++) + CHECK(defaultres[i][0],defaultres[i][1]) + ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],0,-1) + } + + qsort((void*)validmode, validmodecnt, sizeof(struct validmode_t), (int(*)(const void*,const void*))sortmodes); + + modeschecked=1; +} + +#undef CHECK +#undef ADDMODE + + +// +// resetvideomode() -- resets the video system +// +void resetvideomode(void) +{ + videomodereset = 1; + modeschecked = 0; +} + + +// +// begindrawing() -- locks the framebuffer for drawing +// +void begindrawing(void) +{ + long i,j; + + if (bpp > 8) { + if (offscreenrendering) return; + frameplace = 0; + bytesperline = 0; + imageSize = 0; + modechange = 0; + return; + } + + if (lockcount++ > 0) + return; // already locked + + if (offscreenrendering) return; + + if (!fullscreen) { + frameplace = (long)lpPixels; + } else { + frameplace = (long)lpOffscreen; + } + + if (!modechange) return; + + if (!fullscreen) { + bytesperline = xres|4; + } else { + bytesperline = xres|1; + } + + imageSize = bytesperline*yres; + setvlinebpl(bytesperline); + + j = 0; + for(i=0;i<=ydim;i++) ylookup[i] = j, j += bytesperline; + modechange=0; +} + + +// +// enddrawing() -- unlocks the framebuffer +// +void enddrawing(void) +{ + if (bpp > 8) { + if (!offscreenrendering) frameplace = 0; + return; + } + + if (!frameplace) return; + if (lockcount > 1) { lockcount--; return; } + if (!offscreenrendering) frameplace = 0; + lockcount = 0; +} + + +// +// showframe() -- update the display +// +void showframe(int w) +{ + HRESULT result; + DDSURFACEDESC ddsd; + char *p,*q; + int i,j; + +#if defined(USE_OPENGL) && defined(POLYMOST) + if (bpp > 8) { + if (palfadedelta) { + bglMatrixMode(GL_PROJECTION); + bglPushMatrix(); + bglLoadIdentity(); + bglMatrixMode(GL_MODELVIEW); + bglPushMatrix(); + bglLoadIdentity(); + + bglDisable(GL_DEPTH_TEST); + bglDisable(GL_ALPHA_TEST); + bglDisable(GL_TEXTURE_2D); + + bglEnable(GL_BLEND); + bglColor4ub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + + bglBegin(GL_QUADS); + bglVertex2i(-1, -1); + bglVertex2i(1, -1); + bglVertex2i(1, 1); + bglVertex2i(-1, 1); + bglEnd(); + + bglMatrixMode(GL_MODELVIEW); + bglPopMatrix(); + bglMatrixMode(GL_PROJECTION); + bglPopMatrix(); + } + + bwglSwapBuffers(hDC); + return; + } +#endif + + w = 1; // wait regardless. ken thinks it's better to do so. + + if (offscreenrendering) return; + + if (lockcount) { + initprintf("Frame still locked %ld times when showframe() called.\n", lockcount); + while (lockcount) enddrawing(); + } + + if (!fullscreen) { + BitBlt(hDC, 0, 0, xres, yres, hDCSection, 0, 0, SRCCOPY); + } else { + if (!w) { + if ((result = IDirectDrawSurface_GetBltStatus(lpDDSBack, DDGBS_CANBLT)) == DDERR_WASSTILLDRAWING) + return; + + if ((result = IDirectDrawSurface_GetFlipStatus(lpDDSPrimary, DDGFS_CANFLIP)) == DDERR_WASSTILLDRAWING) + return; + } + + // lock the backbuffer surface + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + result = IDirectDrawSurface_Lock(lpDDSBack, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); + if (result == DDERR_SURFACELOST) { + if (!appactive) + return; // not in a position to restore display anyway + + IDirectDrawSurface_Restore(lpDDSPrimary); + result = IDirectDrawSurface_Lock(lpDDSBack, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); + } + if (result != DD_OK) { + if (result != DDERR_WASSTILLDRAWING) + initprintf("Failed locking back-buffer surface: %s\n", GetDDrawError(result)); + return; + } + + // copy each scanline + p = (char *)ddsd.lpSurface; + q = (char *)lpOffscreen; + j = xres >> 2; + + for (i=0; i0; i++, n--) { + /* + lpal.palPalEntry[i].peBlue = dapal[0] << 2; + lpal.palPalEntry[i].peGreen = dapal[1] << 2; + lpal.palPalEntry[i].peRed = dapal[2] << 2; + */ + curpalettefaded[i].f = lpal.palPalEntry[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE; + //dapal += 4; + } + + + if (bpp > 8) return 0; // no palette in opengl + + if (!fullscreen) { + if (num > 0) { + rgb = (RGBQUAD *)Bmalloc(sizeof(RGBQUAD)*num); + for (i=start, n=0; n 8) return 0; // only if an 8bit desktop do we do what follows + + // set 0 and 255 to black and white + lpal.palVersion = 0x300; + lpal.palNumEntries = 256; + lpal.palPalEntry[0].peBlue = 0; + lpal.palPalEntry[0].peGreen = 0; + lpal.palPalEntry[0].peRed = 0; + lpal.palPalEntry[0].peFlags = 0; + lpal.palPalEntry[255].peBlue = 255; + lpal.palPalEntry[255].peGreen = 255; + lpal.palPalEntry[255].peRed = 255; + lpal.palPalEntry[255].peFlags = 0; + + if (SetSystemPaletteUse(hDC, SYSPAL_NOSTATIC) == SYSPAL_ERROR) { + initprintf("Problem setting system palette use.\n"); + return -1; + } + + if (hPalette) { + if (num == 0) { start = 0; num = 256; } // refreshing the palette only + SetPaletteEntries(hPalette, start, num, lpal.palPalEntry+start); + } else { + hPalette = CreatePalette((LOGPALETTE *)lpal.palPalEntry); + if (!hPalette) { + initprintf("Problem creating palette.\n"); + return -1; + } + } + + if (SelectPalette(hDC, hPalette, FALSE) == NULL) { + initprintf("Problem selecting palette.\n"); + return -1; + } + + if (RealizePalette(hDC) == GDI_ERROR) { + initprintf("Failure realizing palette.\n"); + return -1; + } + + SetBWSystemColours(); + + } else { + if (!lpDDPalette) return -1; + result = IDirectDrawPalette_SetEntries(lpDDPalette, 0, start, num, (PALETTEENTRY*)&lpal.palPalEntry[start]); + if (result != DD_OK) { + initprintf("Palette set failed: %s\n", GetDDrawError(result)); + return -1; + } + } + + return 0; +} + +// +// getpalette() -- get palette values +// +/* +int getpalette(int start, int num, char *dapal) +{ + int i; + + for (i=num; i>0; i--, start++) { + dapal[0] = curpalette[start].b >> 2; + dapal[1] = curpalette[start].g >> 2; + dapal[2] = curpalette[start].r >> 2; + dapal += 4; + } + + return 0; +}*/ + + +// +// setgamma +// +static int setgammaramp(WORD gt[3][256]) +{ + if (!fullscreen || bpp > 8) { + // GL and windowed mode use DIB method + int i; + HDC hDC = GetDC(hWindow); + i = SetDeviceGammaRamp(hDC, gt) ? 0 : -1; + ReleaseDC(hWindow, hDC); + return i; + } else { + // fullscreen uses DirectX + LPDIRECTDRAWGAMMACONTROL gam; + HRESULT hr; + + if (!(DDdwCaps2 & DDCAPS2_PRIMARYGAMMA)) return -1; + + hr = IDirectDrawSurface_QueryInterface(lpDDSPrimary, &IID_IDirectDrawGammaControl, (LPVOID)&gam); + if (hr != DD_OK) { + ShowDDrawErrorBox("Error querying gamma control", hr); + return -1; + } + + hr = IDirectDrawGammaControl_SetGammaRamp(gam, 0, (LPDDGAMMARAMP)gt); + if (hr != DD_OK) { + IDirectDrawGammaControl_Release(gam); + ShowDDrawErrorBox("Error setting gamma ramp", hr); + return -1; + } + + IDirectDrawGammaControl_Release(gam); + return 0; + } +} + +int setgamma(float ro, float go, float bo) +{ + int i; + WORD gt[3][256]; + + if (!hWindow) return -1; + + ro = 1.0 / ro; go = 1.0 / go; bo = 1.0 / bo; + for (i=0;i<256;i++) { + gt[0][i] = (WORD)min(65535, max(0, (int)(pow((double)i / 256.0, ro) * 65535.0 + 0.5))); + gt[1][i] = (WORD)min(65535, max(0, (int)(pow((double)i / 256.0, go) * 65535.0 + 0.5))); + gt[2][i] = (WORD)min(65535, max(0, (int)(pow((double)i / 256.0, go) * 65535.0 + 0.5))); + } + + return setgammaramp(gt); +} + +static int getgammaramp(WORD gt[3][256]) +{ + if (!hWindow) return -1; + if (!fullscreen || bpp > 8) { + int i; + HDC hDC = GetDC(hWindow); + i = GetDeviceGammaRamp(hDC, gt) ? 0 : -1; + ReleaseDC(hWindow, hDC); + return i; + } else { + LPDIRECTDRAWGAMMACONTROL gam; + HRESULT hr; + + if (!(DDdwCaps2 & DDCAPS2_PRIMARYGAMMA)) return -1; + + hr = IDirectDrawSurface_QueryInterface(lpDDSPrimary, &IID_IDirectDrawGammaControl, (LPVOID)&gam); + if (hr != DD_OK) { + ShowDDrawErrorBox("Error querying gamma control", hr); + return -1; + } + + hr = IDirectDrawGammaControl_GetGammaRamp(gam, 0, (LPDDGAMMARAMP)gt); + if (hr != DD_OK) { + IDirectDrawGammaControl_Release(gam); + ShowDDrawErrorBox("Error getting gamma ramp", hr); + return -1; + } + + IDirectDrawGammaControl_Release(gam); + + return 0; + } +} + +// +// InitDirectDraw() -- get DirectDraw started +// + +// device enumerator +static BOOL WINAPI InitDirectDraw_enum(GUID *lpGUID, LPSTR lpDesc, LPSTR lpName, LPVOID lpContext) +{ + initprintf(" * %s\n", lpDesc); + return 1; +} + +static BOOL InitDirectDraw(void) +{ + HRESULT result; + HRESULT (WINAPI *aDirectDrawCreate)(GUID *, LPDIRECTDRAW *, IUnknown *); + HRESULT (WINAPI *aDirectDrawEnumerate)(LPDDENUMCALLBACK, LPVOID); + DDCAPS ddcaps; + + if (bDDrawInited) return FALSE; + + initprintf("Initialising DirectDraw...\n"); + + // load up the DirectDraw DLL + if (!hDDrawDLL) { + initprintf(" - Loading DDRAW.DLL\n"); + hDDrawDLL = LoadLibrary("DDRAW.DLL"); + if (!hDDrawDLL) { + ShowErrorBox("Error loading DDRAW.DLL"); + return TRUE; + } + } + + // get the pointer to DirectDrawEnumerate + aDirectDrawEnumerate = (void *)GetProcAddress(hDDrawDLL, "DirectDrawEnumerateA"); + if (!aDirectDrawEnumerate) { + ShowErrorBox("Error fetching DirectDrawEnumerate()"); + UninitDirectDraw(); + return TRUE; + } + + // enumerate the devices to make us look fancy + initprintf(" - Enumerating display devices\n"); + aDirectDrawEnumerate(InitDirectDraw_enum, NULL); + + // get the pointer to DirectDrawCreate + aDirectDrawCreate = (void *)GetProcAddress(hDDrawDLL, "DirectDrawCreate"); + if (!aDirectDrawCreate) { + ShowErrorBox("Error fetching DirectDrawCreate()"); + UninitDirectDraw(); + return TRUE; + } + + // create a new DirectDraw object + initprintf(" - Creating DirectDraw object\n"); + result = aDirectDrawCreate(NULL, &lpDD, NULL); + if (result != DD_OK) { + ShowDDrawErrorBox("DirectDrawCreate() failed", result); + UninitDirectDraw(); + return TRUE; + } + + // fetch capabilities + initprintf(" - Checking capabilities\n"); + ddcaps.dwSize = sizeof(DDCAPS); + result = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL); + if (result != DD_OK) { + initprintf(" Unable to get capabilities.\n"); + } else { + DDdwCaps = ddcaps.dwCaps; + DDdwCaps2 = ddcaps.dwCaps2; + } + + bDDrawInited = TRUE; + + return FALSE; +} + + +// +// UninitDirectDraw() -- clean up DirectDraw +// +static void UninitDirectDraw(void) +{ + if (bDDrawInited) initprintf("Uninitialising DirectDraw...\n"); + + ReleaseDirectDrawSurfaces(); + + RestoreDirectDrawMode(); + + if (lpDD) { + initprintf(" - Releasing DirectDraw object\n"); + IDirectDraw_Release(lpDD); + lpDD = NULL; + } + + if (hDDrawDLL) { + initprintf(" - Unloading DDRAW.DLL\n"); + FreeLibrary(hDDrawDLL); + hDDrawDLL = NULL; + } + + bDDrawInited = FALSE; +} + + +// +// RestoreDirectDrawMode() -- resets the screen mode +// +static int RestoreDirectDrawMode(void) +{ + HRESULT result; + + if (fullscreen == 0 || /*bpp > 8 ||*/ !bDDrawInited) return FALSE; + + if (modesetusing == 1) ChangeDisplaySettings(NULL,0); + else if (modesetusing == 0) { + // restore previous display mode and set to normal cooperative level + result = IDirectDraw_RestoreDisplayMode(lpDD); + if (result != DD_OK) { + ShowDDrawErrorBox("Error restoring display mode", result); + UninitDirectDraw(); + return TRUE; + } + + result = IDirectDraw_SetCooperativeLevel(lpDD, hWindow, DDSCL_NORMAL); + if (result != DD_OK) { + ShowDDrawErrorBox("Error setting cooperative level", result); + UninitDirectDraw(); + return TRUE; + } + } + modesetusing = -1; + + return FALSE; +} + + +// +// ReleaseDirectDrawSurfaces() -- release the front and back buffers +// +static void ReleaseDirectDrawSurfaces(void) +{ + if (lpDDPalette) { + initprintf(" - Releasing palette\n"); + IDirectDrawPalette_Release(lpDDPalette); + lpDDPalette = NULL; + } + + if (lpDDSBack) { + initprintf(" - Releasing back-buffer surface\n"); + IDirectDrawSurface_Release(lpDDSBack); + lpDDSBack = NULL; + } + + if (lpDDSPrimary) { + initprintf(" - Releasing primary surface\n"); + IDirectDrawSurface_Release(lpDDSPrimary); + lpDDSPrimary = NULL; + } + + if (lpOffscreen) { + initprintf(" - Freeing offscreen buffer\n"); + free(lpOffscreen); + lpOffscreen = NULL; + } +} + + +// +// SetupDirectDraw() -- sets up DirectDraw rendering +// +static int SetupDirectDraw(int width, int height) +{ + HRESULT result; + DDSURFACEDESC ddsd; + + // now create the DirectDraw surfaces + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.dwBackBufferCount = 2; // triple-buffer + + initprintf(" - Creating primary surface\n"); + result = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSPrimary, NULL); + if (result != DD_OK) { + ShowDDrawErrorBox("Failure creating primary surface", result); + UninitDirectDraw(); + return TRUE; + } + + ZeroMemory(&ddsd.ddsCaps, sizeof(ddsd.ddsCaps)); + ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; + numpages = 1; // KJS 20031225 + + initprintf(" - Getting back buffer\n"); + result = IDirectDrawSurface_GetAttachedSurface(lpDDSPrimary, &ddsd.ddsCaps, &lpDDSBack); + if (result != DD_OK) { + ShowDDrawErrorBox("Failure fetching back-buffer surface", result); + UninitDirectDraw(); + return TRUE; + } + + initprintf(" - Allocating offscreen buffer\n"); + lpOffscreen = (char *)malloc((width|1)*height); + if (!lpOffscreen) { + ShowErrorBox("Failure allocating offscreen buffer"); + UninitDirectDraw(); + return TRUE; + } + + // attach a palette to the primary surface + initprintf(" - Creating palette\n"); + result = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT | DDPCAPS_ALLOW256, (PALETTEENTRY*)curpalette, &lpDDPalette, NULL); + if (result != DD_OK) { + ShowDDrawErrorBox("Failure creating palette", result); + UninitDirectDraw(); + return TRUE; + } + + result = IDirectDrawSurface_SetPalette(lpDDSPrimary, lpDDPalette); + if (result != DD_OK) { + ShowDDrawErrorBox("Failure setting palette", result); + UninitDirectDraw(); + return TRUE; + } + + return FALSE; +} + + +// +// UninitDIB() -- clean up the DIB renderer +// +static void UninitDIB(void) +{ + if (desktopbpp <= 8) + RestoreSystemColours(); + + if (hPalette) { + DeleteObject(hPalette); + hPalette = NULL; + } + + if (hDCSection) { + DeleteDC(hDCSection); + hDCSection = NULL; + } + + if (hDIBSection) { + DeleteObject(hDIBSection); + hDIBSection = NULL; + } + + if (hDC) { + ReleaseDC(hWindow, hDC); + hDC = NULL; + } +} + + +// +// SetupDIB() -- sets up DIB rendering +// +static int SetupDIB(int width, int height) +{ + struct binfo { + BITMAPINFOHEADER header; + RGBQUAD colours[256]; + } dibsect; + int i; + + if (!hDC) { + hDC = GetDC(hWindow); + if (!hDC) { + ShowErrorBox("Error getting device context"); + return TRUE; + } + } + + if (hDCSection) { + DeleteDC(hDCSection); + hDCSection = NULL; + } + + // destroy the previous DIB section if it existed + if (hDIBSection) { + DeleteObject(hDIBSection); + hDIBSection = NULL; + } + + // create the new DIB section + memset(&dibsect, 0, sizeof(dibsect)); + numpages = 1; // KJS 20031225 + dibsect.header.biSize = sizeof(dibsect.header); + dibsect.header.biWidth = width|1; // Ken did this + dibsect.header.biHeight = -height; + dibsect.header.biPlanes = 1; + dibsect.header.biBitCount = 8; + dibsect.header.biCompression = BI_RGB; + dibsect.header.biClrUsed = 256; + dibsect.header.biClrImportant = 256; + for (i=0; i<256; i++) { + dibsect.colours[i].rgbBlue = curpalette[i].b; + dibsect.colours[i].rgbGreen = curpalette[i].g; + dibsect.colours[i].rgbRed = curpalette[i].r; + } + + hDIBSection = CreateDIBSection(hDC, (BITMAPINFO *)&dibsect, DIB_RGB_COLORS, &lpPixels, NULL, 0); + if (!hDIBSection) { + ReleaseDC(hWindow, hDC); + hDC = NULL; + + ShowErrorBox("Error creating DIB section"); + return TRUE; + } + + memset(lpPixels, 0, width*height); + + // create a compatible memory DC + hDCSection = CreateCompatibleDC(hDC); + if (!hDCSection) { + ReleaseDC(hWindow, hDC); + hDC = NULL; + + ShowErrorBox("Error creating compatible DC"); + return TRUE; + } + + // select the DIB section into the memory DC + if (!SelectObject(hDCSection, hDIBSection)) { + ReleaseDC(hWindow, hDC); + hDC = NULL; + DeleteDC(hDCSection); + hDCSection = NULL; + + ShowErrorBox("Error creating compatible DC"); + return TRUE; + } + + return FALSE; +} + +#if defined(USE_OPENGL) && defined(POLYMOST) +// +// ReleaseOpenGL() -- cleans up OpenGL rendering stuff +// + +static HWND hGLWindow = NULL; + +static void ReleaseOpenGL(void) +{ + if (hGLRC) { + polymost_glreset(); + if (!bwglMakeCurrent(0,0)) { } + if (!bwglDeleteContext(hGLRC)) { } + hGLRC = NULL; + } + if (hGLWindow) { + if (hDC) { + ReleaseDC(hGLWindow, hDC); + hDC = NULL; + } + + DestroyWindow(hGLWindow); + hGLWindow = NULL; + } +} + + +// +// UninitOpenGL() -- unitialises any openGL libraries +// +static void UninitOpenGL(void) +{ + ReleaseOpenGL(); +} + + +// +// SetupOpenGL() -- sets up opengl rendering +// +static int SetupOpenGL(int width, int height, int bitspp) +{ + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, //Version Number + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, //Must Support these + PFD_TYPE_RGBA, //Request An RGBA Format + 0, //Select Our Color Depth + 0,0,0,0,0,0, //Color Bits Ignored + 0, //No Alpha Buffer + 0, //Shift Bit Ignored + 0, //No Accumulation Buffer + 0,0,0,0, //Accumulation Bits Ignored + 32, //16/24/32 Z-Buffer depth + 0, //No Stencil Buffer + 0, //No Auxiliary Buffer + PFD_MAIN_PLANE, //Main Drawing Layer + 0, //Reserved + 0,0,0 //Layer Masks Ignored + }; + GLuint PixelFormat; + int minidriver; + int err; + static int warnonce = 0; + pfd.cColorBits = bitspp; + + hGLWindow = CreateWindow( + WindowClass, + "OpenGL Window", + WS_CHILD|WS_VISIBLE, + 0,0, + width,height, + hWindow, + (HMENU)1, + hInstance, + NULL); + if (!hGLWindow) { + ShowErrorBox("Error creating OpenGL child window."); + return TRUE; + } + + hDC = GetDC(hGLWindow); + if (!hDC) { + ReleaseOpenGL(); + ShowErrorBox("Error getting device context"); + return TRUE; + } + + minidriver = Bstrcasecmp(gldriver,"opengl32.dll"); + + if (minidriver) PixelFormat = bwglChoosePixelFormat(hDC,&pfd); + else PixelFormat = ChoosePixelFormat(hDC,&pfd); + if (!PixelFormat) { + ReleaseOpenGL(); + ShowErrorBox("Can't choose pixel format"); + return TRUE; + } + + if (minidriver) err = bwglSetPixelFormat(hDC, PixelFormat, &pfd); + else err = SetPixelFormat(hDC, PixelFormat, &pfd); + if (!err) { + ReleaseOpenGL(); + ShowErrorBox("Can't set pixel format"); + return TRUE; + } + + hGLRC = bwglCreateContext(hDC); + if (!hGLRC) { + ReleaseOpenGL(); + ShowErrorBox("Can't create GL RC"); + return TRUE; + } + + if (!bwglMakeCurrent(hDC, hGLRC)) { + ReleaseOpenGL(); + ShowErrorBox("Can't activate GL RC"); + return TRUE; + } + + polymost_glreset(); + + bglEnable(GL_TEXTURE_2D); + bglShadeModel(GL_SMOOTH); //GL_FLAT + bglClearColor(0,0,0,0.5); //Black Background + bglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho! + bglHint(GL_LINE_SMOOTH_HINT,GL_NICEST); + bglHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); + bglDisable(GL_DITHER); + + { + GLubyte *p,*p2,*p3; + int i; + + glinfo.vendor = bglGetString(GL_VENDOR); + glinfo.renderer = bglGetString(GL_RENDERER); + glinfo.version = bglGetString(GL_VERSION); + glinfo.extensions = bglGetString(GL_EXTENSIONS); + + glinfo.maxanisotropy = 1.0; + glinfo.bgra = 0; + glinfo.texcompr = 0; + + // process the extensions string and flag stuff we recognize + p = Bstrdup(glinfo.extensions); + p3 = p; + while ((p2 = Bstrtoken(p3==p?p:NULL, " ", (char**)&p3, 1)) != NULL) { + if (!Bstrcmp(p2, "GL_EXT_texture_filter_anisotropic")) { + // supports anisotropy. get the maximum anisotropy level + bglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy); + } else if (!Bstrcmp(p2, "GL_EXT_texture_edge_clamp") || + !Bstrcmp(p2, "GL_SGIS_texture_edge_clamp")) { + // supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS + glinfo.clamptoedge = 1; + } else if (!Bstrcmp(p2, "GL_EXT_bgra")) { + // support bgra textures + glinfo.bgra = 1; + } else if (!Bstrcmp(p2, "GL_ARB_texture_compression")) { + // support texture compression + glinfo.texcompr = 1; + } else if (!Bstrcmp(p2, "GL_ARB_texture_non_power_of_two")) { + // support non-power-of-two texture sizes + glinfo.texnpot = 1; + } else if (!Bstrcmp(p2, "WGL_3DFX_gamma_control")) { + // 3dfx cards have issues with fog + nofog = 1; + if (!(warnonce&1)) initprintf("3dfx card detected: OpenGL fog disabled\n"); + warnonce |= 1; + } + } + Bfree(p); + } + numpages = 2; // KJS 20031225: tell rotatesprite that it's double buffered! + + return FALSE; +} +#endif + +// +// CreateAppWindow() -- create the application window +// +static BOOL CreateAppWindow(int modenum, char *wtitle) +{ + RECT rect; + int w, h, x, y, stylebits = 0, stylebitsex = 0; + int width, height, fs, bitspp; + + HRESULT result; + + if (modenum == 0x7fffffff) { + width = customxdim; + height = customydim; + fs = customfs; + bitspp = custombpp; + } else { + width = validmode[modenum].xdim; + height = validmode[modenum].ydim; + fs = validmode[modenum].fs; + bitspp = validmode[modenum].bpp; + } + + if (width == xres && height == yres && fs == fullscreen && bitspp == bpp && !videomodereset) return FALSE; + + if (hWindow) { + if (bpp > 8) { +#if defined(USE_OPENGL) && defined(POLYMOST) + ReleaseOpenGL(); // release opengl +#endif + } else { + ReleaseDirectDrawSurfaces(); // releases directdraw surfaces + } + + if (!fs && fullscreen) { + // restore previous display mode and set to normal cooperative level + RestoreDirectDrawMode(); +#if defined(USE_OPENGL) && defined(POLYMOST) + } else if (fs && fullscreen) { + // using CDS for GL modes, so restore from DirectDraw + if (bpp != bitspp) RestoreDirectDrawMode(); +#endif + } + + + ShowWindow(hWindow, SW_HIDE); // so Windows redraws what's behind if the window shrinks + } + + if (fs) { + stylebitsex = WS_EX_TOPMOST; + stylebits = WS_POPUP; + } else { + stylebitsex = 0; + stylebits = WINDOW_STYLE; + } + + if (!hWindow) { + hWindow = CreateWindowEx( + stylebitsex, + "buildapp", + apptitle, + stylebits, + CW_USEDEFAULT, + CW_USEDEFAULT, + 320, + 200, + NULL, + NULL, + hInstance, + 0); + if (!hWindow) { + ShowErrorBox("Unable to create window"); + return TRUE; + } + + if (startupdlg) { + DestroyWindow(startupdlg); + } + } else { + SetWindowLong(hWindow,GWL_EXSTYLE,stylebitsex); + SetWindowLong(hWindow,GWL_STYLE,stylebits); + } + + // resize the window + if (!fs) { + rect.left = 0; + rect.top = 0; + rect.right = width-1; + rect.bottom = height-1; + AdjustWindowRect(&rect, stylebits, FALSE); + + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + x = (desktopxdim - w) / 2; + y = (desktopydim - h) / 2; + } else { + x=y=0; + w=width; + h=height; + } + SetWindowPos(hWindow, HWND_TOP, x, y, w, h, 0); + + SetWindowText(hWindow, wtitle); + ShowWindow(hWindow, SW_SHOWNORMAL); + SetForegroundWindow(hWindow); + SetFocus(hWindow); + + // fullscreen? + if (!fs) { + if (bitspp > 8) { +#if defined(USE_OPENGL) && defined(POLYMOST) + // yes, start up opengl + if (SetupOpenGL(width,height,bitspp)) { + return TRUE; + } +#endif + } else { + // no, use DIB section + if (SetupDIB(width,height)) { + return TRUE; + } + } + + modesetusing = -1; + + } else { + // yes, set up DirectDraw + + // clean up after the DIB renderer if it was being used + UninitDIB(); + + if (!bDDrawInited) { + DestroyWindow(hWindow); + hWindow = NULL; + return TRUE; + } + +#if defined(USE_OPENGL) && defined(POLYMOST) + if (bitspp > 8) { + DEVMODE dmScreenSettings; + + ZeroMemory(&dmScreenSettings, sizeof(DEVMODE)); + dmScreenSettings.dmSize = sizeof(DEVMODE); + dmScreenSettings.dmPelsWidth = width; + dmScreenSettings.dmPelsHeight = height; + dmScreenSettings.dmBitsPerPel = bitspp; + dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + if (modenum != 0x7fffffff) { + dmScreenSettings.dmDisplayFrequency = validmode[modenum].extra; + dmScreenSettings.dmFields |= DM_DISPLAYFREQUENCY; + } + + if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { + ShowErrorBox("Video mode not supported"); + return TRUE; + } + + ShowWindow(hWindow, SW_SHOWNORMAL); + SetForegroundWindow(hWindow); + SetFocus(hWindow); + + modesetusing = 1; + } else +#endif + { + // set exclusive cooperative level + result = IDirectDraw_SetCooperativeLevel(lpDD, hWindow, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN); + if (result != DD_OK) { + ShowDDrawErrorBox("Error setting cooperative level", result); + UninitDirectDraw(); + return TRUE; + } + + result = IDirectDraw_SetDisplayMode(lpDD, width, height, bitspp); + if (result != DD_OK) { + ShowDDrawErrorBox("Error setting display mode", result); + UninitDirectDraw(); + return TRUE; + } + + modesetusing = 0; + } + + if (bitspp > 8) { +#if defined(USE_OPENGL) && defined(POLYMOST) + // we want an opengl mode + if (SetupOpenGL(width,height,bitspp)) { + return TRUE; + } +#endif + } else { + // we want software + if (SetupDirectDraw(width,height)) { + return TRUE; + } + } + } + +#if defined(USE_OPENGL) && defined(POLYMOST) + if (bitspp > 8) loadglextensions(); +#endif + + xres = width; + yres = height; + bpp = bitspp; + fullscreen = fs; + curvidmode = modenum; + + frameplace = 0; + lockcount = 0; + + // bytesperline is set when framebuffer is locked + //bytesperline = width; + //imageSize = bytesperline*yres; + + modechange = 1; + OSD_ResizeDisplay(xres,yres); + + UpdateWindow(hWindow); + + return FALSE; +} + + +// +// DestroyAppWindow() -- destroys the application window +// +static void DestroyAppWindow(void) +{ + if (hWindow && gammabrightness) { + setgammaramp(sysgamma); + gammabrightness = 0; + } + +#if defined(USE_OPENGL) && defined(POLYMOST) + UninitOpenGL(); +#endif + UninitDirectDraw(); + UninitDIB(); + + if (hWindow) { + DestroyWindow(hWindow); + hWindow = NULL; + } +} + + +// +// SaveSystemColours() -- save the Windows-reserved colours +// +static void SaveSystemColours(void) +{ + int i; + + if (system_colours_saved) return; + + for (i=0; i + Intensities range from 0-63, and palettes 26, 27, 28 and 29 are pre-defined for you as + white, red, green and blue respectively. Sector visibility controls fog density. + - Added movement_lock[] member to player struct. Functionality will be explained upon request + until the wiki is updated. As can be guessed, this is used to lock player movement. + - Fixed a couple of reload bugs + - Projectile system internally optimized and improved (ripped out remnants of variable based + system as well as modified the system to restore projectile defaults on game restart) + - Added the following primitives: + - movesprite + - checkavailweapon + - updatesectorz + - ssp + - stopallsounds + - soundoncevar + - stopsoundvar + Movesprite, checkavailweapon, updatesectorz and ssp work exactly as their + internal counterparts do. The sound commands are self-explanatory. + - Minor fixes to the error handling system -- it is now impossible to redefine internal + pointer gamevars. Some error messages also made more descriptive. + - Fixed handling of bad CON files + - Added "-condebug" command line parameter which prints one line to the init window per line + compiled. This is useful in cases where you've encountered a bug in the CON parser which + throws you into an infinite loop on compile, as you can see where the problem happened. + - Fixed "DNITEMS" cheat not triggering item cheat events + - CON commands "addlog" and "addlogvar" now print to console and log to eduke32.log + with all of the other log information rather than log.log + - Fixed multiplayer menu problem + - Added PROJECTILE_FLAG_RPG_IMPACT (defined as 32768) to projectile flags. This flag causes + an RPG type projectile to directly damage whatever it hits rather than do radius damage. + - By request, changed how Duke moves when submerging into and emerging from underwater sectors + - Various minor code clean-ups and fixes + + - Mapster32 changes: + - Added ' 5 2D mode key combination for changing the shade of every parallaxed ceiling + on the map at once + - Added ' 6 2D mode key combination for changing the height of every parallaxed ceiling + on the map at once + - Added ' Z 2D mode key combination for offsetting an entire map on the Z plane. This + is useful for merging sections of maps into other maps. + - Added Left ALT ' 7 2D mode key combination for scaling the entire map (multiply) + - Added Left ALT ' 8 2D mode key combination for scaling the entire map (divide) + - Added ' M key combination for setting .extra member (this is the SW middle tag) + - Help menus re-organized to be more useful + - Added ' P 3D mode key combination to set palette on all sectors selected in 2D mode + - Added ; V 3D mode key combination to set visibility on all sectors selected in 2D mode + - Added support for running without lookup.dat (obviously, this will disable alt pals) + +==1.2.1== + - Updated to current JFDuke3D and JFBuild release, see releasenotes.html for details + - Mapster32 updated to 1.0.1, hit F1 in 2D mode for new feature rundown + - Added "spritenoshade" command. This command works just like spritenvg and spriteshadow, and does + exactly what it claims to do. + - Fixed 1.2.0 bug which made the player's APLAYER sprite's position shift across the map each time a + bullet hole was left on a wall. + +==1.2.0== + - Updated to current JFDuke3D and JFBuild release, see releasenotes.html for details + - Introduction of Mapster32, the enhanced Build editor version 1.0.0 + - Lots of miscellaneous code clean-ups and bug fixes + - Fixed pre-placed tripbomb bug from EDuke32 1.0.0 + - Increased MAXCYCLERS to 1024 + - Renumbered EVENT_AIMDOWN to be event 63 + - Ripped out unused NAM and WW2GI-specific code + - Ripped out unused code specific to foreign, demo and beta versions of Duke + - Added several new primitives, as follows: + - whilevarn + - switch + - case + - default + - endswitch + - shootvar + - soundvar + - findplayer + - findotherplayer + - activatebysector + - operatesectors + - operateactivators + - operatemasterswitches + - checkactivatormotion + - zshoot + - dist + - ldist + - shiftvarl + - shitvarr + - spritenvg + - getangle + - whilevarvarn + - hitscan + - getplayervar + - setplayervar + - mulscale + - setaspect + Descriptions of these commands will be available soon on EDukeWiki + - Added "reloading" member to player struct (1 when reloading, 0 when not, weapon changes blocked while 1) + - Fixed setuserdef + - Fixed eventloadactor + - Added ud.statusbarscale to get/setuserdef + - Restricted all screen drawing commands to events + - Fixed issues with several events + - SHOTSPARK1 now sets temp_data[6-8] to hitwall, hitsect and hitspr, in that order + - Tweaked the operation of weapons to allow identical operation to Duke3D 1.5 (may cause issues with some existing mods) + - All effector sprites now made non-blockable non-hitscan-sensitive on map start + - Added "range" field to custom projectile system diff --git a/polymer/eduke32/GNU.TXT b/polymer/eduke32/GNU.TXT new file mode 100644 index 000000000..358ef6fb3 --- /dev/null +++ b/polymer/eduke32/GNU.TXT @@ -0,0 +1,87 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +Preamble +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +END OF TERMS AND CONDITIONS diff --git a/polymer/eduke32/MakeDistributions b/polymer/eduke32/MakeDistributions new file mode 100644 index 000000000..d59bb3d8e --- /dev/null +++ b/polymer/eduke32/MakeDistributions @@ -0,0 +1,43 @@ +# GNU Makefile to prepare source and binary distributions. +# make -f MakeDistributions [source|binary] + +SOURCEFILES=build.cfg GNU.TXT \ + Makefile Makefile.deps Makefile.msvc Makefile.watcom MakeDistributions \ + makemsc.bat makew.bat jfduke_releasenotes.html duke3d.def.sample \ + SEHELP.HLP STHELP.HLP ChangeLog enhance.con.sample + +BINARYFILES=build.cfg mapster32.exe eduke32.exe GNU.TXT \ + jfduke_releasenotes.html setup.exe duke3d.def.sample SEHELP.HLP STHELP.HLP \ + ChangeLog enhance.con.sample + +.PHONY: source binary + +datenow=$(shell date +%Y%m%d) + +sourcedir=eduke32_src_$(datenow) +binarydir=eduke32_$(datenow) + +all: source binary + +source: + rm -rf $(sourcedir) $(sourcedir).zip + mkdir -p $(sourcedir) $(sourcedir)/eobj $(sourcedir)/obj + touch $(sourcedir)/eobj/keep.me $(sourcedir)/obj/keep.me + cp $(SOURCEFILES) $(sourcedir) + find . -name "*~" -exec rm -rf '{}' ';'; + find . -name "*.orig" -exec rm -rf '{}' ';'; + find . -name "*.rej" -exec rm -rf '{}' ';'; + cp -R source rsrc $(sourcedir) + find $(sourcedir) | grep -i svn | xargs rm -rf + kzip -r $(sourcedir).zip $(sourcedir) + +binary: + make RELEASE=1 + upx mapster32.exe eduke32.exe + rm -rf $(binarydir) + mkdir $(binarydir) +# mkdir $(binarydir) $(binarydir)/models + cp $(BINARYFILES) $(binarydir) +# cp models/* $(binarydir)/models + kzip -r $(binarydir).zip $(binarydir) + diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile new file mode 100644 index 000000000..26f438284 --- /dev/null +++ b/polymer/eduke32/Makefile @@ -0,0 +1,222 @@ +# EDuke32 Makefile for GNU Make + +# SDK locations - adjust to match your setup +# DXROOT=c:/sdks/msc/dx61 + +# Engine options +SUPERBUILD = 1 +POLYMOST = 1 +USE_OPENGL = 1 +DYNAMIC_OPENGL = 1 +USE_A_C = 0 +NOASM = 0 + +# Debugging options +RELEASE?=1 + +# build locations + +SRC=source/ +RSRC=rsrc/ +EROOT=../build/ +EINC=$(EROOT)include/ +INC=$(SRC) +o=o + +ifneq (0,$(RELEASE)) + # debugging disabled + debug=-fomit-frame-pointer -O1 +else + # debugging enabled + debug=-ggdb -O0 +endif + +CC=gcc +CXX=g++ +# -Werror-implicit-function-declaration +OURCFLAGS=$(debug) -W -Wall -Wimplicit -Wno-char-subscripts -Wno-unused \ + -funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS -DNOCOPYPROTECT \ + -I$(INC:/=) -I$(EINC:/=) -I$(SRC)jmact -I$(SRC)jaudiolib -I../jfaud/src +OURCXXFLAGS=-fno-exceptions -fno-rtti +LIBS=-lm +#JFAUDLIBS=../jfaud/libjfaud.a ../jfaud/mpadec/libmpadec/libmpadec.a +NASMFLAGS=-s #-g +EXESUFFIX= + +include $(EROOT)Makefile.shared + +ifeq ($(PLATFORM),LINUX) + OBJ=obj.nix/ + EOBJ=eobj.nix/ + NASMFLAGS+= -f elf +else + OBJ=obj/ + EOBJ=eobj/ +endif + +JMACTOBJ=$(OBJ)util_lib.$o \ + $(OBJ)file_lib.$o \ + $(OBJ)control.$o \ + $(OBJ)keyboard.$o \ + $(OBJ)mouse.$o \ + $(OBJ)mathutil.$o \ + $(OBJ)scriplib.$o + +AUDIOLIB_FX_STUB=$(OBJ)audiolib_fxstub.$o +AUDIOLIB_MUSIC_STUB=$(OBJ)audiolib_musicstub.$o +AUDIOLIB_JFAUD=$(OBJ)jfaud_sounds.$o +AUDIOLIB_FX=$(OBJ)mv_mix.$o \ + $(OBJ)mv_mix16.$o \ + $(OBJ)mvreverb.$o \ + $(OBJ)pitch.$o \ + $(OBJ)multivoc.$o \ + $(OBJ)ll_man.$o \ + $(OBJ)fx_man.$o \ + $(OBJ)dsoundout.$o +AUDIOLIB_MUSIC=$(OBJ)midi.$o \ + $(OBJ)mpu401.$o \ + $(OBJ)music.$o + +GAMEOBJS=$(OBJ)game.$o \ + $(OBJ)actors.$o \ + $(OBJ)anim.$o \ + $(OBJ)animlib.$o \ + $(OBJ)config.$o \ + $(OBJ)gamedef.$o \ + $(OBJ)gameexec.$o \ + $(OBJ)global.$o \ + $(OBJ)menus.$o \ + $(OBJ)namesdyn.$o \ + $(OBJ)player.$o \ + $(OBJ)premap.$o \ + $(OBJ)savegame.$o \ + $(OBJ)sector.$o \ + $(OBJ)sounds.$o \ + $(OBJ)rts.$o \ + $(OBJ)testcd.$o \ + $(OBJ)osdfuncs.$o \ + $(OBJ)osdcmds.$o \ + $(JMACTOBJ) + +EDITOROBJS=$(OBJ)astub.$o + +ifeq ($(PLATFORM),WINDOWS) + OURCFLAGS+= -DUNDERSCORES -I$(DXROOT)/include + NASMFLAGS+= -DUNDERSCORES -f win32 + GAMEOBJS+= $(OBJ)gameres.$o $(OBJ)winbits.$o + EDITOROBJS+= $(OBJ)buildres.$o +endif + +ifeq ($(RENDERTYPE),SDL) + OURCFLAGS+= $(subst -Dmain=SDL_main,,$(shell sdl-config --cflags)) + AUDIOLIBOBJ=$(AUDIOLIB_MUSIC_STUB) $(AUDIOLIB_FX_STUB) $(OBJ)sounds.$o + #AUDIOLIBOBJ=$(AUDIOLIB_JFAUD) + + ifeq (1,$(HAVE_GTK2)) + OURCFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0) + GAMEOBJS+= $(OBJ)game_banner.$o + EDITOROBJS+= $(OBJ)editor_banner.$o + endif + + GAMEOBJS+= $(OBJ)game_icon.$o + EDITOROBJS+= $(OBJ)build_icon.$o +endif + +ifeq ($(RENDERTYPE),WIN) + AUDIOLIBOBJ=$(AUDIOLIB_MUSIC) $(AUDIOLIB_FX) $(OBJ)sounds.$o + #AUDIOLIBOBJ=$(AUDIOLIB_JFAUD) +endif + +GAMEOBJS+= $(AUDIOLIBOBJ) +OURCFLAGS+= $(BUILDCFLAGS) +OURCXXFLAGS+= $(BUILDCFLAGS) + +.PHONY: clean all engine $(EOBJ)$(ENGINELIB) $(EOBJ)$(EDITORLIB) + +# TARGETS + +# Invoking Make from the terminal in OSX just chains the build on to xcode +ifeq ($(PLATFORM),DARWIN) +ifeq ($(RELEASE),0) +style=Development +else +style=Deployment +endif +.PHONY: alldarwin +alldarwin: + cd osx && xcodebuild -target All -buildstyle $(style) +endif + +all: eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) + +eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)$(ENGINELIB) + $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(JFAUDLIBS) $(LIBS) $(STDCPPLIB) -Wl,-Map=$@.map + -rm eduke32.sym$(EXESUFFIX) + cp eduke32$(EXESUFFIX) eduke32.sym$(EXESUFFIX) + strip eduke32$(EXESUFFIX) + +mapster32$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)$(EDITORLIB) $(EOBJ)$(ENGINELIB) + $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) -Wl,-Map=$@.map + -rm mapster32.sym$(EXESUFFIX) + cp mapster32$(EXESUFFIX) mapster32.sym$(EXESUFFIX) + strip mapster32$(EXESUFFIX) + +include Makefile.deps + +.PHONY: enginelib editorlib +enginelib editorlib: + -mkdir $(EOBJ) + $(MAKE) -C $(EROOT) "OBJ=$(CURDIR)/$(EOBJ)" \ + SUPERBUILD=$(SUPERBUILD) POLYMOST=$(POLYMOST) \ + USE_OPENGL=$(USE_OPENGL) DYNAMIC_OPENGL=$(DYNAMIC_OPENGL) \ + USE_A_C=$(USE_A_C) NOASM=$(NOASM) RELEASE=$(RELEASE) $@ + +$(EOBJ)$(ENGINELIB): enginelib +$(EOBJ)$(EDITORLIB): editorlib + +# RULES +$(OBJ)%.$o: $(SRC)%.nasm + nasm $(NASMFLAGS) $< -o $@ +$(OBJ)%.$o: $(SRC)jaudiolib/%.nasm + nasm $(NASMFLAGS) $< -o $@ + +$(OBJ)%.$o: $(SRC)%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 +$(OBJ)%.$o: $(SRC)%.cpp + $(CXX) $(CXXFLAGS) $(OURCXXFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 +$(OBJ)%.$o: $(SRC)jmact/%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 +$(OBJ)%.$o: $(SRC)jaudiolib/%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(SRC)misc/%.rc + windres -i $< -o $@ + +$(OBJ)%.$o: $(SRC)util/%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)%.$o: $(RSRC)%.c + $(CC) $(CFLAGS) $(OURCFLAGS) -c $< -o $@ 2>&1 + +$(OBJ)game_banner.$o: $(RSRC)game_banner.c +$(OBJ)editor_banner.$o: $(RSRC)editor_banner.c +$(RSRC)game_banner.c: $(RSRC)game.bmp + echo "#include " > $@ + gdk-pixbuf-csource --extern --struct --raw --name=startbanner_pixdata $^ | sed 's/load_inc//' >> $@ +$(RSRC)editor_banner.c: $(RSRC)build.bmp + echo "#include " > $@ + gdk-pixbuf-csource --extern --struct --raw --name=startbanner_pixdata $^ | sed 's/load_inc//' >> $@ + +# PHONIES +clean: +ifeq ($(PLATFORM),DARWIN) + cd osx && xcodebuild -target All clean +else + -rm -f $(OBJ)* eduke32$(EXESUFFIX) eduke32.sym$(EXESUFFIX) mapster32$(EXESUFFIX) mapster32.sym$(EXESUFFIX) core* +endif + +veryclean: clean +ifeq ($(PLATFORM),DARWIN) +else + -rm -f $(EOBJ)* +endif diff --git a/polymer/eduke32/Makefile.deps b/polymer/eduke32/Makefile.deps new file mode 100644 index 000000000..401b5a001 --- /dev/null +++ b/polymer/eduke32/Makefile.deps @@ -0,0 +1,60 @@ +duke3d_h=$(EINC)build.h $(EINC)pragmas.h $(EINC)compat.h $(EINC)cache1d.h $(EINC)baselayer.h $(SRC)jmact/types.h $(SRC)jmact/file_lib.h $(SRC)jmact/util_lib.h $(SRC)jmact/keyboard.h $(SRC)jmact/control.h $(INC)develop.h $(INC)gamedefs.h $(INC)function.h $(INC)config.h $(INC)sounds.h $(INC)rts.h $(INC)_rts.h $(INC)soundefs.h $(SRC)jaudiolib/fx_man.h $(SRC)jaudiolib/music.h $(INC)namesdyn.h $(INC)funct.h $(INC)duke3d.h $(EINC)mmulti.h +gamedef_h=$(SRC)gamedef.h + +$(OBJ)game.$o: $(SRC)*.c $(SRC)jmact/scriplib.h $(duke3d_h) $(INC)osdfuncs.h $(INC)osdcmds.h +$(OBJ)actors.$o: $(SRC)actors.c $(duke3d_h) +$(OBJ)anim.$o: $(SRC)anim.c $(duke3d_h) $(SRC)jmact/animlib.h +$(OBJ)gamedef.$o: $(SRC)gamedef.c $(duke3d_h) $(gamedef_h) +$(OBJ)gameexec.$o: $(SRC)gameexec.c $(duke3d_h) $(gamedef_h) +$(OBJ)global.$o: $(SRC)global.c $(duke3d_h) +$(OBJ)menus.$o: $(SRC)menus.c $(duke3d_h) $(SRC)jmact/mouse.h +$(OBJ)namesdyn.$o: $(SRC)namesdyn.c $(duke3d_h) +$(OBJ)player.$o: $(SRC)player.c $(duke3d_h) +$(OBJ)premap.$o: $(SRC)premap.c $(duke3d_h) $(EINC)osd.h +$(OBJ)savegame.$o: $(SRC)savegame.c $(duke3d_h) +$(OBJ)sector.$o: $(SRC)sector.c $(duke3d_h) +$(OBJ)sounds.$o: $(SRC)sounds.c $(duke3d_h) +$(OBJ)jfaud_sounds.$o: $(SRC)jfaud_sounds.cpp $(duke3d_h) $(EINC)osd.h +$(OBJ)rts.$o: $(SRC)rts.c $(duke3d_h) +$(OBJ)config.$o: $(SRC)config.c $(duke3d_h) $(SRC)jmact/scriplib.h $(INC)_functio.h +$(OBJ)testcd.$o: $(SRC)testcd.c +$(OBJ)winbits.$o: $(SRC)winbits.c +$(OBJ)osdfuncs.$o: $(SRC)names.h $(EINC)build.h +$(OBJ)osdcmds.$o: $(SRC)osdcmds.c $(INC)osdcmds.h $(EINC)osd.h $(duke3d_h) + +$(OBJ)astub.$o: $(SRC)astub.c $(EINC)build.h $(EINC)pragmas.h $(EINC)compat.h $(EINC)editor.h + +$(OBJ)game_icon.$o: $(RSRC)game_icon.c +$(OBJ)build_icon.$o: $(RSRC)build_icon.c + +$(OBJ)gameres.$o: $(SRC)misc/gameres.rc $(RSRC)game.bmp $(RSRC)game_icon.ico +$(OBJ)buildres.$o: $(SRC)misc/buildres.rc $(RSRC)build.bmp $(RSRC)build_icon.ico + +# jMACT objects +$(OBJ)animlib.$o: $(SRC)jmact/animlib.c $(SRC)jmact/types.h $(INC)develop.h $(SRC)jmact/util_lib.h $(SRC)jmact/animlib.h $(EINC)compat.h +$(OBJ)util_lib.$o: $(SRC)jmact/util_lib.c $(SRC)jmact/util_lib.h $(SRC)jmact/types.h $(EINC)compat.h +$(OBJ)file_lib.$o: $(SRC)jmact/file_lib.c $(SRC)jmact/file_lib.h $(SRC)jmact/types.h +$(OBJ)control.$o: $(SRC)jmact/control.c $(SRC)jmact/types.h $(SRC)jmact/control.h $(SRC)jmact/keyboard.h $(SRC)jmact/mouse.h $(EINC)baselayer.h +$(OBJ)keyboard.$o: $(SRC)jmact/keyboard.c $(SRC)jmact/types.h $(SRC)jmact/keyboard.h $(EINC)compat.h $(EINC)baselayer.h +$(OBJ)mouse.$o: $(SRC)jmact/mouse.c $(SRC)jmact/types.h $(SRC)jmact/mouse.h $(EINC)baselayer.h +$(OBJ)mathutil.$o: $(SRC)jmact/mathutil.c $(SRC)jmact/types.h +$(OBJ)scriplib.$o: $(SRC)jmact/scriplib.c $(SRC)jmact/scriplib.h $(SRC)jmact/util_lib.h $(SRC)jmact/_scrplib.h $(SRC)jmact/types.h $(EINC)compat.h + +# jAudioLib objects +$(OBJ)audiolib_fxstub.$o: $(SRC)jaudiolib/audiolib_fxstub.c $(SRC)jaudiolib/fx_man.h +$(OBJ)audiolib_musicstub.$o: $(SRC)jaudiolib/audiolib_musicstub.c $(SRC)jaudiolib/music.h + +$(OBJ)audiolib_fx_fmod.$o: $(SRC)jaudiolib/audiolib_fx_fmod.c $(SRC)jaudiolib/fx_man_fmod.h $(INC)duke3d.h + +$(OBJ)mv_mix.$o: $(SRC)jaudiolib/mv_mix.nasm +$(OBJ)mv_mix16.$o: $(SRC)jaudiolib/mv_mix16.nasm +$(OBJ)mvreverb.$o: $(SRC)jaudiolib/mvreverb.nasm +$(OBJ)pitch.$o: $(SRC)jaudiolib/pitch.c $(SRC)jaudiolib/pitch.h +$(OBJ)multivoc.$o: $(SRC)jaudiolib/multivoc.c $(SRC)jaudiolib/usrhooks.h $(SRC)jaudiolib/linklist.h $(SRC)jaudiolib/pitch.h $(SRC)jaudiolib/multivoc.h $(SRC)jaudiolib/_multivc.h +$(OBJ)fx_man.$o: $(SRC)jaudiolib/fx_man.c $(SRC)jaudiolib/multivoc.h $(SRC)jaudiolib/ll_man.h $(SRC)jaudiolib/fx_man.h +$(OBJ)dsoundout.$o: $(SRC)jaudiolib/dsoundout.c $(SRC)jaudiolib/dsoundout.h + +$(OBJ)midi.$o: $(SRC)jaudiolib/midi.c $(SRC)jaudiolib/standard.h $(SRC)jaudiolib/usrhooks.h $(SRC)jaudiolib/music.h $(SRC)jaudiolib/_midi.h $(SRC)jaudiolib/midi.h +$(OBJ)mpu401.$o: $(SRC)jaudiolib/mpu401.c $(SRC)jaudiolib/mpu401.h +$(OBJ)music.$o: $(SRC)jaudiolib/music.c $(SRC)jaudiolib/music.h $(SRC)jaudiolib/midi.h $(SRC)jaudiolib/mpu401.h + diff --git a/polymer/eduke32/Makefile.msvc b/polymer/eduke32/Makefile.msvc new file mode 100644 index 000000000..f21705b03 --- /dev/null +++ b/polymer/eduke32/Makefile.msvc @@ -0,0 +1,151 @@ +# EDuke32 Makefile for Watcom Make + +SRC=source\ # +OBJ=obj\ # +EROOT=..\build\ # +EINC=$(EROOT)include\ # +EOBJ=eobj\ # +INC=$(SRC) +o=obj + +ENGINELIB=engine.lib +EDITORLIB=build.lib + +!ifdef DEBUG +# debugging options +flags_cl=/G6 /Ot /Z7 +flags_link=/DEBUG +!else +# release options +flags_cl=/G6Fy /Ox #/Ob1gity +flags_link=/RELEASE +!endif + + +DXROOT=c:\sdks\msc\dx7 + +ENGINEOPTS=/DSUPERBUILD /DPOLYMOST /DUSE_OPENGL /DDYNAMIC_OPENGL + +CC=cl +AS=ml +LINK=link /opt:nowin98 /nologo /opt:ref +CFLAGS= /MD /J /nologo $(flags_cl) \ + /I$(INC) /I$(EINC) /I$(SRC)jmact /I$(SRC)jaudiolib /I..\jfaud\src \ + /DNOCOPYPROTECT $(ENGINEOPTS) \ + /I$(DXROOT)\include /DRENDERTYPEWIN=1 +LIBS=user32.lib gdi32.lib shell32.lib dxguid.lib winmm.lib wsock32.lib \ + ..\jfaud\jfaud.lib ..\jfaud\mpadec\libmpadec\mpadec.lib /NODEFAULTLIB:libFLAC.lib \ + #opengl32.lib + ASFLAGS=/nologo /coff +ASFLAGS=/nologo /coff +EXESUFFIX=.exe + +JMACTOBJ=$(OBJ)util_lib.$o \ + $(OBJ)file_lib.$o \ + $(OBJ)control.$o \ + $(OBJ)keyboard.$o \ + $(OBJ)mouse.$o \ + $(OBJ)mathutil.$o \ + $(OBJ)scriplib.$o + +#AUDIOLIB_FX=$(OBJ)jaudiolib_fxstub.$o +#AUDIOLIB_MUSIC=$(OBJ)jaudiolib_musicstub.$o +#AUDIOLIB_FX=$(OBJ)jaudiolib_fx_fmod.$o +AUDIOLIB_JFAUD=$(OBJ)jfaud_sounds.$o +AUDIOLIB_FX=$(OBJ)mv_mix.$o \ + $(OBJ)mv_mix16.$o \ + $(OBJ)mvreverb.$o \ + $(OBJ)pitch.$o \ + $(OBJ)multivoc.$o \ + $(OBJ)ll_man.$o \ + $(OBJ)fx_man.$o \ + $(OBJ)dsoundout.$o +AUDIOLIB_MUSIC=$(OBJ)midi.$o \ + $(OBJ)mpu401.$o \ + $(OBJ)music.$o +#AUDIOLIBOBJ=$(AUDIOLIB_MUSIC) $(AUDIOLIB_FX) $(OBJ)sounds.$o +AUDIOLIBOBJ=$(AUDIOLIB_JFAUD) + + GAMEOBJS=$(OBJ)game.$o \ + $(OBJ)actors.$o \ + $(OBJ)anim.$o \ + $(OBJ)gamedef.$o \ + $(OBJ)gameexec.$o \ + $(OBJ)global.$o \ + $(OBJ)menus.$o \ + $(OBJ)namesdyn.$o \ + $(OBJ)player.$o \ + $(OBJ)premap.$o \ + $(OBJ)savegame.$o \ + $(OBJ)sector.$o \ + $(OBJ)rts.$o \ + $(OBJ)config.$o \ + $(OBJ)animlib.$o\ + $(OBJ)testcd.$o \ + $(OBJ)osdfuncs.$o \ + $(OBJ)osdcmds.$o \ + $(JMACTOBJ) \ + $(AUDIOLIBOBJ) \ + $(OBJ)winbits.$o $(OBJ)gameres.res + +EDITOROBJS=$(OBJ)astub.$o \ + $(OBJ)buildres.res + + +# RULES +.SUFFIXES: .masm + +{$(SRC)}.masm{$(OBJ)}.$o: + $(AS) /c $(ASFLAGS) /Fo$@ $< + +{$(SRC)jaudiolib}.masm{$(OBJ)}.$o: + $(AS) /c $(ASFLAGS) /Fo$@ $< + +{$(SRC)jmact}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)jaudiolib}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)util}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)}.c{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)}.cpp{$(OBJ)}.$o: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{$(SRC)misc}.rc{$(OBJ)}.res: + $(RC) /fo$@ /r $< + + +# TARGETS +all: eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) ; + +eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)$(ENGINELIB) + $(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib $(flags_link) /MAP $** $(LIBS) msvcrt.lib + +mapster32$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)$(ENGINELIB) $(EOBJ)$(EDITORLIB) + $(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib $(flags_link) /MAP $** $(LIBS) msvcrt.lib + +!include Makefile.deps + +enginelib editorlib: AlwaysBuild + -mkdir $(EOBJ) + echo OBJ=$(MAKEDIR)\$(EOBJ) > $(EOBJ)overrides.mak + echo CFLAGS=$(ENGINEOPTS) >> $(EOBJ)overrides.mak + cd $(EROOT) + nmake /f Makefile.msvc "OVERRIDES=$(MAKEDIR)\$(EOBJ)overrides.mak" $@ + cd $(MAKEDIR) + +AlwaysBuild: ; +$(EOBJ)$(EDITORLIB): editorlib ; +$(EOBJ)$(ENGINELIB): enginelib ; + +# PHONIES +clean: + -del $(OBJ)* eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) + +veryclean: clean + -del $(EOBJ)* diff --git a/polymer/eduke32/Makefile.watcom b/polymer/eduke32/Makefile.watcom new file mode 100644 index 000000000..bbc08bf7b --- /dev/null +++ b/polymer/eduke32/Makefile.watcom @@ -0,0 +1,143 @@ +# EDuke32 Makefile for Watcom Make + +SRC=source\ +OBJ=obj\ +EROOT=..\build\ +EINC=$(EROOT)include\ +EOBJ=eobj\ +INC=$(SRC) +o=obj + +ENGINELIB=engine.lib +EDITORLIB=build.lib + +!ifdef __LOADDLL__ +! loaddll wcc386 wccd386 +!endif + +DXROOT=c:\sdks\msc\dx7 + +ENGINEOPTS=-dSUPERBUILD -dPOLYMOST -dUSE_OPENGL -dDYNAMIC_OPENGL + +CC=wcc386 +CFLAGS= -5r -s -orb -fp5 -d2 -db & + -i=$(INC) -i=$(EINC) -i=$(SRC)jmact -i=$(SRC)jaudiolib -i=$(DXROOT)\include & + -dRENDERTYPEWIN=1 -dNOCOPYPROTECT $(ENGINEOPTS) +LIBS=winmm.lib wsock32.lib dxguid.lib #opengl32.lib +WASMFLAGS=-d1 +EXESUFFIX=.exe + +JMACTOBJ=$(OBJ)util_lib.$o & + $(OBJ)file_lib.$o & + $(OBJ)control.$o & + $(OBJ)keyboard.$o & + $(OBJ)mouse.$o & + $(OBJ)mathutil.$o & + $(OBJ)scriplib.$o + +#JAUDIOLIB_FX=$(OBJ)jaudiolib_fxstub.$o +#JAUDIOLIB_MUSIC=$(OBJ)jaudiolib_musicstub.$o +#JAUDIOLIB_FX=$(OBJ)jaudiolib_fx_fmod.$o +JAUDIOLIB_FX=$(OBJ)mv_mix.$o & + $(OBJ)mv_mix16.$o & + $(OBJ)mvreverb.$o & + $(OBJ)pitch.$o & + $(OBJ)multivoc.$o & + $(OBJ)ll_man.$o & + $(OBJ)fx_man.$o & + $(OBJ)dsoundout.$o +JAUDIOLIB_MUSIC=$(OBJ)midi.$o & + $(OBJ)mpu401.$o & + $(OBJ)music.$o +JAUDIOLIBOBJ=$(JAUDIOLIB_MUSIC) $(JAUDIOLIB_FX) + +GAMEOBJS=$(OBJ)game.$o & + $(OBJ)actors.$o & + $(OBJ)anim.$o & + $(OBJ)gamedef.$o & + $(OBJ)gameexec.$o & + $(OBJ)global.$o & + $(OBJ)menus.$o & + $(OBJ)namesdyn.$o & + $(OBJ)player.$o & + $(OBJ)premap.$o & + $(OBJ)savegame.$o & + $(OBJ)sector.$o & + $(OBJ)sounds.$o & + $(OBJ)rts.$o & + $(OBJ)config.$o & + $(OBJ)animlib.$o & + $(OBJ)testcd.$o & + $(OBJ)osdfuncs.$o & + $(OBJ)osdcmds.$o & + $(OBJ)winbits.$o & + $(JMACTOBJ) & + $(JAUDIOLIBOBJ) + +EDITOROBJS=$(OBJ)astub.$o + +# RULES +.EXTENSIONS: .wasm .res .rc + +.wasm: $(SRC) +.wasm: $(SRC)jaudiolib/ +.c: $(SRC) +.c: $(SRC)jmact/ +.c: $(SRC)jaudiolib/ +.c: $(SRC)util/ +.rc: $(SRC)misc/ + +.wasm.$o: + wasm $(WASMFLAGS) -fo=$(OBJ).$o $[@ + +.c.$o: + $(CC) $(CFLAGS) -fo=$(OBJ).$o $[@ + +.rc.res: + wrc -fo=$^*.res -r $[@ + + +# TARGETS +all: eduke32$(EXESUFFIX) build$(EXESUFFIX) .SYMBOLIC + %null + +eduke32$(EXESUFFIX): $(GAMEOBJS) $(OBJ)gameres.res $(EOBJ)$(ENGINELIB) + wlink NAME $@ & + SYSTEM WIN95 & + DEBUG ALL & + FILE { $(GAMEOBJS) $(ENGINEOBJS) } & + RESOURCE $(OBJ)gameres.res & + LIBPATH $(DXROOT)\lib & + LIBPATH $(EOBJ) & + LIBRARY { $(ENGINELIB) $(LIBS) } + +mapster32$(EXESUFFIX): $(EDITOROBJS) $(OBJ)buildres.res $(EOBJ)$(ENGINELIB) $(EOBJ)$(EDITORLIB) + wlink NAME $@ & + SYSTEM WIN95 & + DEBUG ALL & + FILE { $(EDITOROBJS) } & + RESOURCE $(OBJ)buildres.res & + LIBPATH $(DXROOT)\lib & + LIBPATH $(EOBJ) & + LIBRARY { $(LIBS) $(ENGINELIB) $(EDITORLIB) } + +!include Makefile.deps + +cwd=$+ $(%cwd) $- +enginelib editorlib: .SYMBOLIC + -mkdir $(EOBJ) + %write $(EOBJ)overrides.mak OBJ=$(cwd)\$(EOBJ) + %write $(EOBJ)overrides.mak CFLAGS=$(ENGINEOPTS) + cd $(EROOT) + wmake -f Makefile.watcom OVERRIDES=$(cwd)\$(EOBJ)overrides.mak $@ + cd $(cwd) + +$(EOBJ)$(EDITORLIB): editorlib .SYMBOLIC +$(EOBJ)$(ENGINELIB): enginelib .SYMBOLIC + +# PHONIES +clean: .SYMBOLIC + -del $(OBJ)* eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) + +veryclean: clean .SYMBOLIC + -del $(EOBJ)* diff --git a/polymer/eduke32/SEHELP.HLP b/polymer/eduke32/SEHELP.HLP new file mode 100644 index 000000000..ce375c4bb --- /dev/null +++ b/polymer/eduke32/SEHELP.HLP @@ -0,0 +1,35 @@ +-SECTOR EFFECTOR HELP- + + 0 : ROTATED SECTOR + 1 : PIVOT SPRITE FOR SE 0 + 2 : EARTHQUAKE + 3 : RANDOM LIGHTS AFTER SHOT OUT + 4 : RANDOM LIGHTS + 6 : SUBWAY + 7 : TRANSPORT (UNDERWATER ST 1 or 2) + 8 : UP OPEN DOOR LIGHTS + 9 : DOWN OPEN DOOR LIGHTS + 10 : DOOR AUTO CLOSE (H=DELAY) + 11 : ROTATE SECTOR DOOR + 12 : LIGHT SWITCH + 13 : C-9 EXPLOSIVE + 14 : SUBWAY CAR + 15 : SLIDE DOOR (ST 25) + 16 : ROTATE REACTOR SECTOR + 17 : ELEVATOR TRANSPORT (ST 15) + 18 : INCREMENTAL SECTOR RISE/FALL + 19 : SHOT TOUCHPLATE CIELING DOWN + 20 : BRIDGE (ST 27) + 21 : DROP FLOOR (ST 28) + 22 : PRONG (ST 29) + 23 : TRANSPORT DESTINATION (H=SE 7) + 24 : CONVAIRBELT + 25 : ENGINE + 28 : LIGHTNING (H= TILE#4890) + 27 : CAMERA FOR PLAYBACK + 29 : FLOAT + 30 : 2 WAY TRAIN (ST=31) + 31 : FLOOR RISE + 32 : CEILING FALL + 33 : SPAWN JIB W/QUAKE + 36 : SKRINK RAY SHOOTER diff --git a/polymer/eduke32/STHELP.HLP b/polymer/eduke32/STHELP.HLP new file mode 100644 index 000000000..e70885dfb --- /dev/null +++ b/polymer/eduke32/STHELP.HLP @@ -0,0 +1,24 @@ +-SECTOR TAGS HELP- + + 1 : WATER (SE 7) + 2 : UNDERWATER (SE 7) + 9 : STAR TREK DOORS + 15 : ELEVATOR TRANSPORT (SE 17) + 16 : ELEVATOR PLATFORM DOWN + 17 : ELEVATOR PLATFORM UP + 18 : ELEVATOR DOWN + 19 : ELEVATOR UP + 20 : CEILING DOOR + 21 : FLOOR DOOR + 22 : SPLIT DOOR + 23 : SWING DOOR + 25 : SLIDE DOOR (SE 15) + 26 : SPLIT STAR TREK DOOR + 27 : BRIDGE (SE 20) + 28 : DROP FLOOR (SE 21) + 29 : TEETH DOOR (SE 22) + 30 : ROTATE RISE BRIDGE + 31 : 2 WAY TRAIN (SE=30) + 10000+ : 1 TIME SOUND + 32767 : SECRET ROOM + 65535 : END OF LEVEL diff --git a/polymer/eduke32/build.cfg b/polymer/eduke32/build.cfg new file mode 100644 index 000000000..60c444b2d --- /dev/null +++ b/polymer/eduke32/build.cfg @@ -0,0 +1,104 @@ +; Build editor configuration + +; Video mode selection +; 0 - Windowed +; 1 - Fullscreen +fullscreen = 0 + +; Video resolution selection +; 0 - 320 x 200 +; 1 - 360 x 200 +; 2 - 320 x 240 +; 3 - 360 x 240 +; 4 - 320 x 400 +; 5 - 360 x 400 +; 6 - 640 x 350 +; 7 - 640 x 400 +; 8 - 640 x 480 +; 9 - 800 x 600 +; 10 - 1024 x 768 +; 11 - 1280 x 1024 +; 12 - 1600 x 1200 +; You can select a seperate 2D editor resolution by +; removing the semicolon from the second line below +; and selecting a mode number. The minimum 2D mode +; is 640x480 (mode #8) +resolution = 8 +;2dresolution = 8 + +; 3D mode colour depth +bpp = 8 + +; Maximum OpenGL mode refresh rate (Windows only, in Hertz) +maxrefreshfreq = 60 + +; 3D mode brightness setting +; 0 - lowest +; 15 - highest +brightness = 0 + +; Sound sample frequency +; 0 - 6 KHz +; 1 - 8 KHz +; 2 - 11.025 KHz +; 3 - 16 KHz +; 4 - 22.05 KHz +; 5 - 32 KHz +; 6 - 44.1 KHz +samplerate = 4 + +; Music playback +; 0 - Off +; 1 - On +music = 1 + +; Enable mouse +; 0 - No +; 1 - Yes +mouse = 1 + +; Mouse sensitivity +mousesensitivity = 1.0 + +; Key Settings +; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex! +; +---------------------------------------------------------------------------------------------+ +; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 | +; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL | +; | | +; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A | +; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- | +; | | +; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E | +; |TAB Q W E R T Y U I O P [ ] \ DEL END PGDN KP7 KP8 KP9 KP+ | +; | | +; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D | +; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C | +; | KPENTER| +; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 | +; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 | +; | | +; | 1D 38 39 B8 9D CB D0 CD 52 53 | +; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. | +; +---------------------------------------------------------------------------------------------+ + +keyforward = C8 +keybackward = D0 +keyturnleft = CB +keyturnright = CD +keyrun = 2A +keystrafe = 9D +keyfire = 1D +keyuse = 39 +keystandhigh = 1E +keystandlow = 2C +keylookup = D1 +keylookdown = C9 +keystrafeleft = 33 +keystraferight = 34 +key2dmode = 9C +keyviewcycle = 1C +key2dzoomin = D +key2dzoomout = C +keychat = F + diff --git a/polymer/eduke32/duke3d.def.sample b/polymer/eduke32/duke3d.def.sample new file mode 100644 index 000000000..7a3c2ef61 --- /dev/null +++ b/polymer/eduke32/duke3d.def.sample @@ -0,0 +1,69 @@ +// Duke Nukem 3D Sample Defs file +// +// For an explanation of the contents of this file, read releasenotes.html +// in the section titled "DEF-file Language" + +include DEFS.CON + +// These entries define Hightile tints +// definetint +definetint 1 110 110 255 1 +definetint 2 255 110 80 1 +definetint 4 0 0 0 0 +definetint 6 192 255 138 3 +definetint 7 228 200 172 0 +definetint 8 180 255 200 0 + +// This entry defines a texture replacement +// definetexture 0 0 -1 -1 +//definetexture FEMPIC7 0 0 0 -1 -1 "textures/rikaa.png" + +// These entries demonstrate replacing the Pig Cop character with a model + // Editart tile indices: + // walk 2000-2019 + // pump 2025-2027 + // stand 2030-2034 + // shoot 2035-2037 + // dive 2040-2044 + // dived 2045-2049 + // dshoot 2050-2052 + // hit 2055 + // die 2056-2059 + // dead 2060 +// definemodel +// defineskin +// definemodelanim +// definemodelframe +definemodel "models/pigcop.md2" 1.30 0 +definemodelskin 0 "models/pigcop.jpg" + +definemodelanim "walk0" "walk13" 20 0 +definemodelframe "walk0" 2000 2019 + +definemodelanim "pump0" "pump2" 10 1 +definemodelframe "pump0" 2025 2027 + +definemodelframe "stand" 2030 2034 + +definemodelanim "shoot0" "shoot2" 10 1 +definemodelframe "shoot0" 2035 2037 + +definemodelanim "dive0" "dive3" 8 1 +definemodelframe "dive0" 2040 2044 +definemodelframe "dive3" 2045 2049 + +definemodelanim "dshoot0" "dshoot2" 10 1 +definemodelframe "dshoot0" 2050 2052 + +definemodelframe "die0" 2055 2055 +definemodelanim "die1" "dead" 13 1 +definemodelframe "die1" 2056 2059 +definemodelframe "dead" 2060 2060 + + +// These entries demonstrate voxel replacements +// definevoxel +// definevoxeltiles +//definevoxel "voxels/barstool.kvx" +//definevoxeltiles 1006 1006 + diff --git a/polymer/eduke32/eduke32.exe b/polymer/eduke32/eduke32.exe new file mode 100644 index 0000000000000000000000000000000000000000..2d041050d0b3f9e8571cda281bbd2ceeb8aa1a95 GIT binary patch literal 1214976 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�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%0Aut!zf@aF3&#|HT`UMv^B`ZJ}9E7 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%0D4F_dR9&0|z245Q1qS{!CwHc^qyO2#>=9XB*)H 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�h-}uL& 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
R#??Q*`oxcW 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 MsRn!>;i^+tU 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
  • Ebqn;uAdJr{>ouSU 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�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%0DEhKKG;^MOc@yM4vjAgu(e<^puX>?Ey#R+R8J!@ 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

    IwNYRC@5mL*R)%+Nw#$tK)sb|w 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

    NW+PZOhwI+La*YQT{TQ?=TSS{#wyP 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 + + + + + Release Notes for JFDuke3D + + + + +

    Release Notes for JFDuke3D

    +

    Release date: 9 October 2005

    + +

    New Features and Improvements

    +
    + +

    Known Issues

    +
      +
    • You may have instances where the game goes out of sync. The master can often restart the game + from the menu without everyone having to restart the game from scratch, and things should be + fine.
    • +
    • A test version in the near future will include my new sound code that supports OggVorbis and + other sound formats. For now, the existing AudioLib code is in use.
    • +
    + +

    Individual User Profiles

    + +

    With Windows 2000 and XP, having multiple user accounts for different people on the one computer has + been very easy, with XP especially so. Linux, BSD, and other *nix-like OS users have had this ability + forever and now JFDuke3D properly supports installations where each user can have his/her own set of + configuration and savegame files without interfering with other players on the same PC. On Windows the + default mode of behaviour is the same as in previous versions: everything is shared, but it is now possible + to enable "user profile mode". Linux/BSD users will run in "user profile mode" permanently; your personal + files will be located in ~/.jfduke3d so if you used previous versions of the port, you will + have to move your config and savegames there. Windows users can turn on "user profile mode" by creating an + empty file in the JFDuke3D directory named 'user_profiles_enabled'. Here is how:

    +
      +
    1. In Windows Explorer, navigate to the JFDuke3D directory.
    2. +
    3. Open the File menu, move to the "New" option, and select "Text Document".
    4. +
    5. Type user_profiles_enabled and press Enter.
    6. +
    7. If a dialog box appears asking to confirm changing the filename extension to one that may + make the file unusable, choose "Yes".
    8. +
    +

    When you next run JFDuke3D, a JFDuke3D directory will be created in C:\Documents and + Settings\your username\Application Data along with a new configuration file. You will + then have to move your existing DUKE3D.CFG file to this location if you have used the game previously.

    + +

    Multiplayer games

    + +

    Multiplayer games are started via command-line parameters passed to DUKE3D.EXE. This is a short guide + to getting a multiplayer game running between these three hypothetical computers:

    + + + + + + + + + + +
    Host nameIP address
    faye192.168.1.2
    asuka192.168.1.5
    kaoru192.168.1.6
    +

    Keep in mind that the networking features are still being refined and there are + certain issues and caveats to be aware of when using it. The basic syntax of the network command + line is like so: DUKE3D (normal game parameters) /net (network parameters)

    + + + + + + + + + + + + + + + + + +
    Network parameters
    /nx:yGame comm type. x = 0 for master/slave or 1 for peer-to-peer.
    + If unspecified, y defaults to 2. For more than two players in a + master-slave game, you have to indicate the number on the master. + eg: /n0 or /n0:4
    /pxOverrides the default port (23513) with x being the new port value.
    address:portAn address of a machine. See the items below for more information.
    + +

    Master/Slave mode

    +

    This mode is the easiest mode for use with Internet play since it requires only the address of the master + of the game (the person hosting the game) be specified by each slave who joins. Here are example command + lines each machine must run to join the game hosted by the machine named 'asuka': +

    + + + + +
    asukaDUKE3D.EXE /net /n0:3
    fayeDUKE3D.EXE /net /n0 192.168.1.5
    kaoruDUKE3D.EXE /net /n0 192.168.1.5
    + +

    Peer-to-peer mode

    +

    This mode is often useful for playing on a LAN where it is easier to coordinate and organise the order of + peers in the game. This mode will become simpler to set up in the future but for now this is how to do + it. Peer-to-peer mode requires each machine specify the addresses of each other machine in the game in the + same order, but indicating its own position in the sequence with the /n1 option.

    + + + + +
    asukaDUKE3D.EXE /net /n1 192.168.1.2 192.168.1.6
    fayeDUKE3D.EXE /net 192.168.1.5 /n1 192.168.1.6
    kaoruDUKE3D.EXE /net 192.168.1.5 192.168.1.2 /n1
    + +

    Addresses and ports

    +

    The networking code is capable of resolving WINS host names (on Windows) and DNS names to their + corresponding addresses, so if your network is configured with such services, instead of having to specify + raw IP addresses, you can give the computer's WINS host name or a DNS host name.

    +

    The default port the game communicates on is 23513. Some users may find it necessary to set up a + forward through their Internet firewall in order to get games working when playing across the Internet. + You can override the default port via the /p??? switch where ??? is the new + port number. If a master is running a game on a port other than the default, the slaves will have to + specify the alternative port with address:port notation, eg. 192.168.1.5:20000

    + +

    3D Models

    + +

    Polymost uses the Quake II MD2 and Quake III MD3 format for 3D models. You can replace any wall-aligned or + face sprite in the game with a 3D model using a declaration in the DUKE3D.DEF file. For more information + on the specifics of the DEF-file commands for 3D models, see here.

    +

    Included in this release is a model of the Pig Cop by Parkar, and the skin by Motionblur. You should + visit this site for a much larger pack of + textures and models. I shall use this model to demonstrate how to replace the Pig Cop character in Duke.

    + +

    Here is the definition for the pig cop which is also included in the sample DUKE3D.DEF file.

    +
    +   //New syntax:
    +model "models/pigcop.md2"
    +{
    +   scale 1.30 shade 0
    +   skin { pal 0 file "models/pigcop.jpg" }
    +   anim { frame0 "walk0" frame1 "walk13" fps 20 flags 0 }
    +   frame { name "walk0" tile0 2000 tile1 2019 }
    +
    +   anim { frame0 "pump0" frame1 "pump2" fps 10 flags 1 }
    +   frame { name "pump0" tile0 2025 tile1 2027 }
    +
    +   frame { name "stand" tile0 2030 tile1 2034 }
    +
    +   anim { frame0 "shoot0" frame1 "shoot2" fps 10 flags 1 }
    +   frame { name "shoot0" tile0 2035 tile1 2037 }
    +
    +   anim { frame0 "dive0" frame1 "dive3" fps 8 flags 1 }
    +   frame { name "dive0" tile0 2040 tile1 2044 }
    +   frame { name "dive3" tile0 2045 tile1 2049 }
    +
    +   anim { frame0 "dshoot0" frame1 "dshoot2" fps 10 flags 1 }
    +   frame { name "dshoot0" tile0 2050 tile1 2052 }
    +
    +   frame { name "die0" tile 2055 }
    +   anim { frame0 "die1" frame1 "dead" fps 13 flags 1 }
    +   frame { name "die1" tile0 2056 tile1 2059 }
    +   frame { name "dead" tile 2060 }
    +}
    +
    +
    +   //Old syntax:
    +definemodel "models/pigcop.md2" 1.30 0
    +definemodelskin 0 "models/pigcop.jpg"
    +
    +definemodelanim "walk0" "walk13" 20 0
    +definemodelframe "walk0" 2000 2019
    +
    +definemodelanim "pump0" "pump2" 10 1
    +definemodelframe "pump0" 2025 2027
    +
    +definemodelframe "stand" 2030 2034
    +
    +definemodelanim "shoot0" "shoot2" 10 1
    +definemodelframe "shoot0" 2035 2037
    +
    +definemodelanim "dive0" "dive3" 8 1
    +definemodelframe "dive0" 2040 2044
    +definemodelframe "dive3" 2045 2049
    +
    +definemodelanim "dshoot0" "dshoot2" 10 1
    +definemodelframe "dshoot0" 2050 2052
    +
    +definemodelframe "die0" 2055 2055
    +definemodelanim "die1" "dead" 13 1
    +definemodelframe "die1" 2056 2059
    +definemodelframe "dead" 2060 2060
    +

    Without going through every line of the example, here is the basis of how the definitions work. + You must put a + definemodel line before any other definemodelframe or definemodelanim lines. The frame and anim lines + refer the the definemodel line which precedes them. You can define frames and animations in any order, ie. + the animations do not need to be given before the frames, but it is a good convention to keep them + together for clarity.

    +

    The walking loop for the pig cop spans tiles 2000 to 2019. The model contains a fourteen frame walking + animation which we play at 20 frames per second. The first line of the example specifies the + "models/pigcop.md2" model should be drawn at 1.3 times its normal scale and be left undarkened or + lightened. The definemodelskin line specifies the skin to use for palette 0 for all the definemodelframe + lines that follow it. The first of the definemodelanim lines declares the fourteen frame walking animation + at 20fps which should loop (the 0 for the flags parameter says to loop). The definemodelframe line which + follows it maps the ART tiles from 2000 through to 2019 to play the walking animation. Because the name in + the definemodelframe line matches the first frame of the definemodelanim line, the animation will + automatically play.

    + +

    Quake II and Quake III are registered trademarks of id + Software

    + +

    DEF-file Language

    + +

    Documentation of the DEF file language can now be found on my website as the information there is + common to all JFBuild-based ports.

    + +

    Map Hack scripts

    + +

    "Map Hack" scripts are files that override certain aspects of a map file when it is rendered in OpenGL + Polymost mode. Currently they allow for angle adjustment on sprites, and the ability to prevent particular + sprites from being drawn as a model. These are useful for making small corrections to ornamental sprites in + a way that doesn't require modifying the original map.

    +

    The game will automatically load a map hack script whenever a map is loaded. The script should have the + same base name as the original .MAP file, but with an .MHK extension. The map hack language is described + below. It uses the same parser as DEF files, so you can use comments in the same way.

    + +
    +
    sprite number
    +
    Begins a sprite definition. number is the sprite number to affect. You can find this in + the Build editor by highlighting the sprite in 2D mode and pressing Control+Tab. The next group of + commands describe the changes to make to the sprite. +
    +
    notmd
    + notmd2
    + notmd3
    +
    Prevents the sprite from being drawn as a model. It gets drawn as a regular sprite + instead. notmd2 and notmd3 are synonyms for + notmd.
    + +
    nomdanim
    + nomd2anim
    + nomd3anim
    +
    Prevents model animation from playing if the sprite is being drawn as a model. + nomd2anim and nomd3anim are synonyms for + nomdanim.
    + +
    angleoff angle
    + angoff angle
    +
    Adds angle to the angle of the sprite just before it is rendered. This is good + for fixing up things like toilet sprites that are facing the wrong way. + angoff is a synonym for angleoff.
    +
    +
    + +

    Here is an example map hack script:

    +
    // Map hack file for JFDuke3D
    +// Level: E1L2.MAP (Original Atomic Edition version)
    +// Prepared by jonof@edgenetwork.org
    +
    +// Invisible switch behind hand dryer in toilet of porn shop
    +sprite 191 notmd2
    +
    +// Invisible switches on telephones near billiards room in club
    +sprite 254 notmd2
    +sprite 517 notmd2
    +
    +// Toilet in restroom in club
    +sprite 478 angoff -512
    + +

    Hightile

    + +

    This release features the "Hightile" texturing improvements to Polymost. Hightile allows Polymost to use + true-colour textures instead of the artwork in the game's usual .ART file.

    +

    Replacement textures can be saved as JPEG, PNG (alpha channel supported), TGA, BMP, CEL, GIF, and PCX + formats. Hightile uses Ken Silverman's picture library to provide rapid picture file loading.

    +

    Hightile textures are defined in the DUKE3D.DEF file. See the DEF-file language + reference for information on how to specify Hightile textures.

    + +

    Limitations to Hightile

    +
      +
    • Hightile will squash or stretch the replacement to fit in the dimensions of the original tile + it replaces. Artists should keep their replacements in the same ratio as the original tile for the + art to not look distorted.
    • +
    + +

    ZIP file support

    + +

    Duke (and Build games in general) can load game resources from a ZIP file.

    +

    ZIP files are used in Duke in the same manner as extra GRP files are specified. Use the "/g" command-line + switch to specify the ZIP to load. eg. DUKE3D.EXE /gMYFILE.ZIP

    + +

    Polymost

    + +

    Polymost is a full 3D implementation of the Build engine renderer, with hardware acceleration capability, + and perspective in six degrees of freedom. In Ken's own words (copied from POLYMOST.C in my Build engine + source distribution):

    +
    +"POLYMOST" code written by Ken Silverman
    +Ken Silverman's official web site: http://www.advsys.net/ken
    +
    +Motivation:
    +When 3D Realms released the Duke Nukem 3D source code, I thought somebody would do a OpenGL or
    +Direct3D port. Well, after a few months passed, I saw no sign of somebody working on a true
    +hardware-accelerated port of Build, just people saying it wasn't possible. Eventually, I realized
    +the only way this was going to happen was for me to do it myself. First, I needed to port Build to
    +Windows. I could have done it myself, but instead I thought I'd ask my Australian buddy, Jonathon
    +Fowler, if he would upgrade his Windows port to my favorite compiler (MSVC) - which he did. Once
    +that was done, I was ready to start the "POLYMOST" project.
    +
    +About:
    +This source file is basically a complete rewrite of the entire rendering part of the Build engine.
    +There are small pieces in ENGINE.C to activate this code, and other minor hacks in other source
    +files, but most of it is in here. If you're looking for polymost-related code in the other source
    +files, you should find most of them by searching for either "polymost" or "rendmode". Speaking of
    +rendmode, there are now 4 rendering modes in Build:
    +
    +    rendmode 0: The original code I wrote from 1993-1997
    +    rendmode 1: Solid-color rendering: my debug code before I did texture mapping
    +    rendmode 2: Software rendering before I started the OpenGL code (Note: this is just a quick
    +                hack to make testing easier - it's not optimized to my usual standards!)
    +    rendmode 3: The OpenGL code
    +
    +The original Build engine did hidden surface removal by using a vertical span buffer on the tops
    +and bottoms of walls. This worked nice back in the day, but it it's not suitable for a polygon
    +engine. So I decided to write a brand new hidden surface removal algorithm - using the same idea
    +as the original Build - but one that worked with vectors instead of already rasterized data.
    +		
    +

    Polymost is the default renderer choice for any video mode with a colour depth greater than 256 + colours.

    +

    NOTE: If your computer does not have an OpenGL graphics card, Polymost in OpenGL mode + will most likely use the default Windows OpenGL rasterising facility which does all rendering in software. + This may be extremely slow. If your Windows installation doesn't have any form of OpenGL rendering ability, + Polymost will probably crash.

    +

    NOTE 2: OpenGL Polymost has been tested on an nVidia Riva TNT 16MB, an nVidia GeForce2 + GTS 32MB, an nVidia GeForce4 Ti4600 128MB, an nVidia GeForce 6800GT 256MB, an ATi Radeon Mobility 9000 64MB, + and a 3D-Labs Oxygen GVX420 128MB (minor texturing issues).

    + +

    Console Commands

    + +

    This is a list of console commands and variables and their purpose:

    + +
    +
    changelevel <episode> <level>
    +
    Warps to a new level.
    + +
    dumpbuildinfo
    +
    Displays the compilation information for the game when it was built.
    + +
    echo <text...>
    +
    Displays to the console what is passed as parameters to the command.
    + +
    fileinfo <filename>
    +
    Displays some information about a given file, eg. size, CRC-32 checksum.
    + +
    glinfo
    +
    Displays some information about the OpenGL driver.
    + +
    glredbluemode <0 or 1>
    +
    Enables or disables the red-blue stereovision mode in OpenGL. This mode is experimental + at this time. We know the flicker is nasty and the menu background will mix into the screen. + To avoid the menu bug, run the game in fullscreen mode and type "glredbluemode 1" AFTER + beginning the game. Sorry, there is no way to change parallax or separation. Do not contact + us about bugs with this mode... if you do, we'll think twice about documenting hidden features + in future releases. :P
    + +
    gltextureanisotropy <level>
    +
    Sets the OpenGL anisotropic filtering level.
    + +
    gltexturemode <mode-number>
    +
    Sets the OpenGL texturing mode. Valid values are: + + + + + + + +
    0GL_NEAREST (looks rather like the original software renderer)
    1GL_LINEAR
    2GL_NEAREST_MIPMAP_NEAREST
    3GL_LINEAR_MIPMAP_NEAREST (bilinear)
    4GL_NEAREST_MIPMAP_LINEAR
    5GL_LINEAR_MIPMAP_LINEAR (trilinear)
    + +
    glusetexcompr <0 or 1>
    +
    Enables or disables the use of OpenGL texture compression for hightile textures. You need + to use 'restartvid' to apply any changes to this value.
    + +
    god
    +
    Enables God mode.
    + +
    help <name>
    +
    Displays a help message for a particular console variable or command.
    + +
    listsymbols
    +
    Displays the names of all commands and variables available in the console.
    + +
    map <mapname>
    +
    Loads a user map.
    + +
    noclip
    +
    Disables player collisions with world objects.
    + +
    novoxmips <0 or 1>
    +
    Disables or enables the use of voxel mipmaps to improve voxel visual quality.
    + +
    osdrows <num>
    +
    Sets the number of visible lines of the console when it is open.
    + +
    quit
    +
    Exits the game.
    + +
    restartvid
    +
    Resets the video system, reinitialising the video mode.
    + +
    screencaptureformat <0 or 1>
    +
    0 = Targa, 1 = PCX
    + +
    setrendermode <mode>
    +
    Sets the current Polymost render mode.
    + +
    setstatusbarscale <percent>
    +
    Sets the size of the status bar as a percentage of its original full-width size. Minimum size is + 10%, maximum 100%.
    + +
    showcoords <0 or 1>
    +
    Same as typing "DNCOORDS" cheat.
    + +
    showfps <0 or 1>
    +
    Shows/hides the framerate counter. Same as typing "DNRATE" cheat.
    + +
    spawn <tile-number or name> [pal] [cstat] [angle] [x y z]
    +
    Places a sprite of the given tile number or name at the current position, or if given, the "x + y z" location. A name is a label defined in the CON code. The sprite may be spawned with a + specific palette, cstat value, and angle if those parameters are given.
    + +
    usegoodalpha <0 or 1>
    +
    If 1, a lower alpha cutoff value is used when rendering textures with transparency, which + gives better looking transparent textures at the expense of some sprites behind the transparent + item potentially being invisible in certain circumstances. 0 is a more compatible value (and is + the default) for this option but slight visual degradation will result.
    + +
    usehightile <0 or 1>
    +
    Disables or enables the use of Hightile textures in GL Polymost mode if any are defined.
    + +
    usemodels <0 or 1>
    +
    Disables or enables the use of 3D models in GL Polymost mode if any are defined.
    + +
    usevoxels <0 or 1>
    +
    Disables or enables the use of voxels in the classic renderer if any are defined.
    + +
    vidmode [xres yres] [bpp]
    +
    Changes the current video mode. You may pass either a new resolution (eg 640 480), + a new colour depth (eg 32), or both a resolution and colour depth (eg 640 480 32).
    + +
    bpp <colourdepth>
    +
    Sets the display colour depth. Does not apply it immediately though. You need to use + 'restartvid' after setting this if you want to apply the change.
    +
    + +
    Happy Duke'ing!
    + Jonathon Fowler (jonof@edgenetwork.org)
    + + + diff --git a/polymer/eduke32/makemsc.bat b/polymer/eduke32/makemsc.bat new file mode 100644 index 000000000..19243ed20 --- /dev/null +++ b/polymer/eduke32/makemsc.bat @@ -0,0 +1 @@ +nmake /f Makefile.msvc %1 %2 %3 %4 %5 diff --git a/polymer/eduke32/makew.bat b/polymer/eduke32/makew.bat new file mode 100644 index 000000000..7184b0f08 --- /dev/null +++ b/polymer/eduke32/makew.bat @@ -0,0 +1 @@ +wmake -f Makefile.watcom %1 %2 %3 %4 %5 diff --git a/polymer/eduke32/mapster32.exe b/polymer/eduke32/mapster32.exe new file mode 100644 index 0000000000000000000000000000000000000000..949dcd57b6a16ce70b2f1f7290d6069ad1661f80 GIT binary patch literal 677888 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%0A4VO~}SGE-9%03FTEY%VPXE~f*5dj_%qs(b|` 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

    v(X z>z~0C zb59M(QJc!GGw@ZDrBN+ZsO^O$(M)I`P!FcNkJ}df&=?29wGkN!5r{@aMDgVwu^$(q zGDXoNG@%z;kAlAxE!*%6z}F-3HHs(LwOu?AS@HqQ*XjbYJ;4sKQM4WznViQ$BS}yd zf59B)Dg>*XSi)l-Se4~EAftM6UVB4e|E`i(8;kNjYkgVwRV?c4)HZess$Ju@mneRlalM8H71_= zOHY^eC!BLHuHu%wbuEJa06k?&MKn2f_XzOZ!v7uJd#%e{7k^E1K7>pl8+a|5(ou+F$r~|Xmxij?`@l`!YIy@B} z-e812WG-#m!)$3iI=SD`-yRn%Yjx-lRw6%?0SNxIhhYjAvwC(FEk`6o6cgdOq#^|b z*tRGF9slpK-xQK(*p3{XmjZPq&S09|446I+1pA3ES`F~W#q)?o!& z9;6&i4AO`{<=#BVaFt-T#$W-t5z&fudkpa^ajOt0= z>xm8?9@O`*!+7#NTob~hm61D!@&9}tt)xMqxV>qV`}QOT=BrRq3Ip@cVkR2{vQ``M zJ9y}k^<(vxL*}nF2HEKzvGHyIr`fmPSoCw4$>r)wBQD3-!rNvKLU)qG&JL_$5m(6( zs;v9s)+V4`xQ$XQm8D*ca&VHy(wT$7T;W*n-I-WjKHwM9yP||H@ya>|_tkfUeJ{()I5Kq8O zip@LZnzUyiJHlTIW1}%rYuS@fnYMBp3#Y?e2Qhk)l7po?S%I&43EMj;>zL}4QSVOQ z!uTcUv{C{W{|&oMssEa|Qo_YswRh7&Ob@{8 z>6mz$y@htdprY{_evBGavfqx0CDXx(ziqa#Blc9e8%68c-{5rgl-)($zd|Bn#^Jvn zN}+yq4y7IiaK%t#vI!0VXpvhBx9^s|%M8p!k1D%IP-Zs>`kqXwB$xOtX)}fFsd%L? z#2vIa9K;tQ%i5rjM}ALe>&@dsMV1t&ha(UsV^5Hs4uCXf`C%XrayOd_pi$j9bZIPW z47mL)pmdf`!fuwF3VP>yjy7j?;||bZN}x=EQ<{@TcrrMUwy5brDWjUIj&1=tcXm^u z=MC;3TN~d;=`=|qyaV8YGIT-^cYhj@Rd^FStlvi*#U2-PjhJU+m98ShGwD0d_p-41 z7=vNU+7b`R&1k;nk`Lu{mo8h5#z@8V2x%shaNL|$a;!5>Z28bIcljv}Q_ydX6K^Z& zk8=>b9c^s_-jx2V^AJ|rW#zEgy9DBQci8KSIpRle_!G6hDEpbjUROXfle-BKwMh$@ zJUmY=k@N68&d}HsmXgFCIm@B32e$#i-lxP~e6zU3L^f}2Q?W~O2j*|C1yyux-QnIf zcIq>-Zh2gjm;a`YCpj0cISKW}kO!1d+mlZWVg2k^xbW zA%qNAOnCJ$%r$bGJWOcIpmj6`7)%O33?qdfKYqwXIVWlZ_}3Vq|4$K2>-fRj?fgMN zH-6(`GB7&+0O!T#6QxLO4BU$Uc}(o3zCmo@TOTDTYyav3xaO}tVKxrojVnLESW~5+ z6l_`}H_TL{w}@7=TE{ONh%I_?Nx~fw%#ZG=hhY8CiF4kJkU?;OGPanlP+g*oKkW6{Y|xgiq9s(e?239R~0G0tBqt^4mYP5{H`ie zepibD0L94D{H{9QNwwzSz6z018>pEYs6xbY;o=D}_3RPM%Gzm!eh%i;U9TKHa`0gb zQ5Eb(44y9CET8U#xq!X5E|!YFDZ9;AURqYTB?;JHSctYnRJ$Paaxky?Hj^7hx3 zA3R;WQ;>=CiK zM@esZ9GmyjX$Kxn{2`&bn+iM1#OZ}U&@A}DdL9C`eQRI0@WFDO2A?a%E}1k^S!0M1 z?dPl*)|qcGMf=EhW>}|M@GN#!b~CZC0AiU|#T*msP;#Gep39&4AIW`2c-Genfa+`GFAY~wQx)teu580IVVKqS&xQm`&sIJ7(w>byN^<*B z>d`hehumRB|Ju=U>Q``yZ`~mqtl{W;LL$_HlU60!?Gw`zpPa>iD!IG*XdR1uwks0_ zD^WP$?ez}MXv5pfdfb*&$_7~Npj#z%U+kL;Lukb(NC=3b)?KobTSu)QfudE9?u0Rt zBNO|H|A_8vuosY%bZdN7hFPcOmG)Q_Ef*6|xiD+rWiir1RUeP+<6x*onAa)ZBA)dB zp3P@cR@&=frDb5e$h{1S7ny&m4BxiW4yJ8)9OyubkB!_x`y6n=aYXK=l@99)ZL+Mm zv0SXO+F(oLtofRlXXg&@-ZU%F@ONXHeMLmUvZJhp|X>O7Uxd>7Mg-?es%@!m4CYDo9@01lTxcwj60%xt}TI+Py@lQ=#)@c~8p3mhQ zmQeh+njq-tZcq!?re8MS7@&zCKQ!)xdLmqil~q@ISD{L#8O9r>(xOIbp~$*PvWOQv z&_iVqHk#C?w(=%O?QE-kaGak;=0k69D`N}h_`sOf-QsssPQvu@u*Oxl33H)p<*FB?swpUK7vRDZMN!DndNzE2&I4G_;ZughNq^FKNJ3+Lzv` z&-I$3e;|Ww;!90v#@?IvB=)S3;)(A3wj`K+Gs z_&*CBK9x985hf4S^=rOq1Fxd%R^x7ANMtMPxyvJa8Z~s0vNz}@)Sh?_T=*(!ZjkH( z)wgDwduYK`t{SJ~lg%aL^I6>2R)Ab8-_|SMqKaHMHj8ZUWTQ z+7}lAbWmD~Z2JqSFnKva0{RN`qRRKMgU83#*Hg?KRc+)JDx1N+taSBWRKPk5wy@SA zQfnxTL{!DRs49UCANB{cgDI^o={3sTI*uAAu&^3|?ry)zWX)%&npuW5qmz7WeLq!Y za?4k?$0GA7M^Gd|2b4I`jty__+Tm#DRj;6_>Wn<@w$EpLUF%|`AV5s`6OPHK82Ub- z%_mqHRc!J5xT3`)+yicpu?E%WsJ&py8I&?!n%m!O0**6i&}yHMeQ~fZ&$oZx zzl``=2?pBQUtJ*9o)wl01mbH))21El=qUM!*w)@WW#!fr5G>O*ymK}&z&aE7k%E=5Iw@0}7YIQ(HL1cc=4yRVdcPXVEly(9_JAto3J4FYl9naxt zrxE5v+GW<$teD)Swe2=pw%O((eolIN(QNY>H3eCF6rUo;>dL1c5JI&1RKFCL3gJVF zOR=!xQup$)^(|esW>9J)8xmY(zVj}P`P>Ats+-b!Zfgp9aw{heJ-O-EVV(FT&J1VJ z$;E|T5bYpq<&4|!{Dy!m?e zMTrAE?b9FSATY2Z26<-REc(y}KiInmWLji|E(WJrK_@!jd@**$&O<_QQ>JyMupsS5 zueY2rE@A5ST_nY(N7fmmVk29y?BY)veGkl*+g6H_x2?#=8GQDs@zC`^R-*Ao_2RSg zZa50}x!Il$NAE>wM-?z43Pc&Es zVC%vLtjk{#D3R;SfiuOwV!3yzU7stm<$xKuKV!l1Odf=Y%*5~&?HxFYwD2-mYC*Oh z>!0MBin-b%T8_{RMA=!^?Jqb{LGv0(#hThBnMkoNRLN<|DimSiqpSWz0nVttmyGlg zLJ?o69NS0H<@EU@Md|}}=SP&`Mx02BtJKl+`3qR0Y8rE`njcXwm^XO2125M6dS`zr z9aYQacsM20( zTPcL#T*c&D+no%=SL)5=(hfZN%6P zBGzQAAM9ws9%VQyHb?5WR91U-Vl-?y!S@8pUEc=UX=-_c~au^u7^1{!?$4 z;!QD#(Rh;Blz!`cCT5_3bvm9@d_K%ZE05{e3wBvY^9jC6E-N#ccU)RtUo!6*$-IO4 zgb}-}WAUUL%f{p3$Fd!;cDKQGe$ijrzfS&XONhw){nktf29@fM@j=UX4uvv-reXNS zWxwP3!UI!7pb$>=dP|Nhe}Ng~m>xLDP_p*WmJD@8Dujky3Yyv<3$#8oHVN@Av%Iu# z)h4h9h6hh#+-4OJ{W^@5(#G&nBVltp#s6weAqF3tf+C<(h#rYelGEH^*8Bem>FJcb z*erK!u6H=j9PqU_jwQ7AL-_b3M&;pg6y7E3OUcg0p00^T^_Y(IbpKGNKbP;ot+^^+ z&-831f0z9cbCeg;ZwN-^Nz|z>hlgOY2EGITa5-IGeMD=oi}32-KdQHX550?*H)ptF zQ-^o7_A>XVx{nO(L*MEG``B5Aq$%lxyCD1-fqi{SJigt(dK<_s0!S}y^bE1DKU48v z0Y7#i*QoZK4f1BD$oQk&0K0b#v{Wy_9T+v-a2@F z6Xu>D)^5k9B<@BSft*Fe1hKaVJvKLlx78pk4o9?uerxiG2AnUd{SXBN7cCszwy$U| zE$z?eG8BUzdRHBe8&~Cg|7R{FO1auklVuW5sR9F7;4-$;5Zqw|_h%Uk9!4|C68lmm zW~&k-SR&U^;`WoHo;P+uo2YsP|M2`zJ~!bX9P{n?s&)^0ePZ`IF+|nZm-W5!T81i~ zY`AYKV+T}jj7>6DF(d0vX3R-teAAKf*Ub2W$|#oY+7p-&1Y@=&{@}=XIWyL&jJ1R= zJg5Qx+LMtz5mFhm*~cNsShwBt$dSA|z#h-ARO?r&yhkzbm#-=mWb|@oJ|~r#hx9Ne z$^4p~`3PrbUn+C^ffN89LFTHpP5>09GQOcQN_XcVBZ;WsY)`7Y7p3w(sqz-GyO&B2 zN{{CA7(55t`Y|x7t85@s&O%DT7WB3c-v+bZ28hc%#)bq%S(m3Op6uxDKmUT>dU34= zGS-rcCAZms*S9ZKe5rO?vY^>__H_XHQL4C5@}E&WNy#jeZ13h|vBdWMDbf!)3$VIi zA&X)1e2yvFnBf70-Kxh6lQlGEWH7lgBNIQ!)SEvX>H<}BE?dneWni@yBb6udn^!Vi zkMu>xWRLDl)|a^K;N`}#Tt8J#k>!Idr^s?Zs$4DG6ZS5f4~ZjL&TzK(RI0tdVkZaa z>8_t!Uq-oXXSr3Wa=+_T4lyz@LSd@+vD{IroO4#JN9n}Poys}j@-vn@+Sy)Hs=f0L zUhWK*JH}bAIaRK`Ejhl`0+%i5W2UTEyI(@N9A~+=Qso*`U9a!@+)Os8@V{8h2s@y_;6Nws&|!OPvmawj;;4NH~#PO4mI{GG#c zxz2JIq{{V5mFo?+s#HY!mlxMR9)- z4nw{$;wM*cz_RLGab=ZrF1xatSw0X|u#h~k!wB~PQ^iT-+tFZ6M7Nqa_DtUBU^e(O zYUhC41ozK@FcjQ>l@^Blr-;B?#VXVjS*dyoAkF#%*j2$M?4b$cR!rSmjzn`0gw^G! za!vR%bf5A4b--jmU@*qz5Nei+pqW7st&T9a+Wm(vD9~1#0^S5?%5?y5f_ZgRA8$fG zA#VUJ;!UU!QN-~mggo9m8;>#I|9G2)Bnv;R`q{k4IrG z2%n5c;ZEbdQ}HMaZoKzOJPMCQ9C$nmn^h-6$f@7U5af;b@|+x5{(Dosqd+lx>Mf~I`okT41qkfCor!m* zAk&@5Bw%Dur6K?6fi>(+rhmE`gYNVq?j`E;+rby+iXJAI@JUZg5MoV6F*1YVTS+Yd zqNIten#(%1jdqV$ooijH#u?XRa16HQGC~7AwnzQ=24E1;xa2*FoTyd>H-Ur5Xjkiz z^1_3mz)hAw6iq&k96}$-p&H@iF(x4%H3%cjZ3jJmBm5P`F^b0E0WBRo#4qgvn7ojPPA7|y$>nQlU(h|r zEadznF=wrx!S5a~E?k31lUe&YU#W{9E7^JXi-(;XqDn*K_NxSbHydOk2X|&-?yjNX zBQY7O1)F0Tk18Vrvc3(}1>0sAp?6?W3APpE5Ihi5|8aKlca8A#c+>+x`2KCAi`5r% z6jPN%NPI2;YXEHo+aON|iF(SzTWTgV8&D1ea{MGo8VIg*(+@eyM5!$E|4{e-@l_XB{{Own4MZD!N1D{AL1TMs ziA76VXcGxFkQk#<8%wHGsnRZG*)6-JHNjv*NVtjS-8UCw)fQc9vh1(u0aydX;F>zcLa=zR^w8j5b-2o#&AWlW%il@d+!Bz_ zB4IWw{5ko@OGsDLY@#aiUj}a_kwjDwF(dyEu&E@!OA#}OsLIzV%L(~A2}{#g5jUTh zGNe?T$?x=Lrsr=ac0uqDly|)h)+H1_A-^LUIxo0qh=U@o*jAtX!JWqJQw6RpZ@N6I zGQH_q7-V?Ur3}-(6gb95DE?Vf8|a{+Fp8Mlcc|TLelz)*Ff_c3_nIs@Nk%?yF_1h1lC!|$=dSQ`m-)F3pX0x>xfAaqijwxWFMs4Hq%f1YFo6K{3fj+_~ zYQb_|tn$YyBh)IJvF@qOLjwI9;Kj;t=9$+hmfq5#SC*-wCj=csm24!nd zHCBnl0+N}Z&7_APn@=0+0=ChSt@C-XYzs#grE%#{QN3TJE{e#W%e`S*UDw3omwtlD zVJHljCu~^TI$eFw-kmA6p!P?N>XjSEB`hp~gaqC8{uJJn&^dskAkPc>Q6 zhuLGORiTLt;biy477@3xy>tIyfx73#+rBWdexx)343FxsI&SU@2uus zH79tRB#b}Vf#$yIk9pHF;lQ6f)%w+2-JMLYA)|q}HhcekD+?+`=sh0$bZN#~Y`-m` zUp>70*1*~UJ|0SbtmLC5_gDYM&()288=zV0_xmJPf8$wE=S}*RXrs^@TD_Yxy)Qz> zXN=13O})N$oLBa++TyQb))Jzx2WIh6f7o=}((te&!)~68@~lQ>qAO zHgfdnr-Z>iRe#}8~TPYcB2F_d|1SNE&0^mNA_S#)uC7tqCA ziCmr`>Mv|5A60#cR(H8((ilU_Hy;EfYZySyD_+P@?2dA+AoacghQm(NSE#Hdr0GsR zMa0w%h>B0pv_XQJzaz+-GEEJd_to6ne6adl6X@h7zchOfVo$0Q`?lST4x zLW7U6={31ZF_Gt)$-iO7zbJtT2ILPLsx}Y@jep>yZ9ixoct}J9am@CoHgl;aPdcpBEPAJY47+W3>pa@ zg_28Ko)b&f__c2CbDGbkaeO&#%cTgTo4-rjyH`u8t$>Ea zScya*{o9mB0b$df7liZF!3zd#uQ45-u6gGbY{!G?&Pxm0ll}X`WLH60=_Q@j7rC#P zK60Gl^$cAasrsW=Dm^vbo0*A{`_yxiiQd#3YO}qv-wZa+O0Llbpf~QK+&luX_5v@} z9jzhv`-BVHdw(j9euwYgCrPm#p!XHkXJYIv)2qyKnU!>`qw7^7O88fZ4mi(*_jLd9 zl^*Jr_Xx9=Fclt89<9xALG&M}MXlYF_)3M)S0CRrtJ?tn_KY-lDgA_qlzsw@h0sxu9C#tNJCVz0cbD7O-Ie$=3bDH@*-nvJO6m6TICp;rCR!wk=}L)_ zVjAl1OGq&da_7dwuTsh`+g6Di1!h5Xo9YOr?}qKWVW$}X_W!{6-7tRFa8|+iEq{mY zyP_>;WIIiU*KW(Bbjvfa{SUDH4;_EXbc@5SzMAC8t>{rE^HVaycU-ty>~?p1#Xk|Z zJKoC-^2#M$t|fF{X)w{dAAQ(;0Ded+7v&_?=&0rHT@h)3>YRR zbU?z5J5O{J?8@Jg;H_5^V&CO?u25Wv-L` zF;S6t3g35L>y?)j9OTq0hYISi^2)Qktd*#y3w-q%4Xu>&9LVmRvzkd(7OSNlAz8o( zl$4UKsH=CUE$iyu`@BWP%;JtSh}38Ho~QAP5n)G&Q6rO~g0}%TDmUCc z&uiMsreFP|$-&KAl$Xe|<3DfEYqFgjLqgSOM?+tsyLAoR9?<-l@dXW=$>P$VIcktG zOTx^^dnwgvR+yrNhym;gZ&33REVhkY8J*7sAUw&yCl%#dla!`7gx!X9e z=7#N~K2xx(y!T?sTWDg-D4p(fBK>DAy@F7AFtR-*@~*S=^Uk`ejLc~*oz{9ydi}o8 z%|p-%^>((5npWHl!mY z@BDksxQ3}utA%RD_?i1~^R5}~b|u!LpTHT9Jj_umJPS{=XGV@`&6J5t)%AsRge>D}c#1jL^m)AReSU1n%9yOupcY(UFWAnR)1=w{^;(yHWpf8hx1`zHGeAFv*gNH?jwxQxhv2O zd7{QypLGip7zH7y0?*D{ybyPZhOPrgY*$gNeoSmvVgW4bK2Q`}`i?R`=jSKGbwJ() zo^<6vH@iE{s^JXv&jQL!R^j197&eJYXZB7(Z6T8~_uF^G7g&qTPKh+}?v`kYEMFM{ zh~5!IYK_I_F$gL;Rkt;=HEVc*nAm(!%TNXb4!*78s3o10aIj0SkiYO{5G`gj11t+h| zqCr2vZ&{R>(CF=DD^fARthjdZzT|jG^`8x}uA?@gO@Z;OMim;!ZvVz=89>259?)0E zScrk_0HZze)HvN&AW9p^u0+vp2$Em#rpu^>&Cbtg6Wh|y*Ok#MP6fei*BBSYe;GtI z7Uqffs?bn@8EqkTR9ezNGuv2*9*-Ogqx|AO_)k_t&==V{!Ek%^M7YKCtkL2^qQ$1B z7!AfmqxdI1kNp&e!FPPTPIg_gMa95+x8qu;2w3ri%!)2#eLVn?C&`Viu=!i!dC#p`eV8`rUiabjaXMWO7K(7W=&Dol8d8NzYdMmpOGsAHRDPmn?pri zb?*d^(|DogtVSNLwMDe|K0*lv?G`;^OfOUCfcI)6v79UuOq1Zn$|Z7JI^Mt7JzTII zs4VXC>Fnsg*xga^a{dk?a`HPkDoe!Xg5CL>^AFd2%l$*qsU@S_6HIqr_OfeL(|$UT zmmN1EGHM{SY|7-vi00Ww^E+i~n+=)YXn9KXW*$4<98B9u^y>M0zZn=P$sN{4sOc?O zu^w_??tM_*(7xwRSEv08k^W3fCv|3zh;0dEql7rAr^@`e+Uw$iokYkaTb1AcP(dfJ z2~rJ$v+|FdU_Sn(PV+}tHp7P;Gi}PD=jBQHXi?2oUb#!ojWGD6l1rD;=Nb%`tFFYz zo}259QFVEx%h^=+lN9gH5@%D@PXZ;*6WfEG-p$3_ z8#_BKTD>fE=SM*{o9mTlGtl#C>$XcoQD#;VTTM>%O|)LYL7r#Kb)sANmi!38okfsJ z=4dsUiOEZG?!7}*()OC@W48&2tYCkBS4D6)70A%+RQ&X^(``jEz00K>0Ant*nH(A3 z)C!WECteD620N?@_@@pji%a^w&@%2Lyv)}GIyacqk5(-eW$+NsZ_U7ziT!GEqOGB! z0Uh;7sUd!OIepWz1s~rmBr(UkrlbgKZFJJz&hqn>YFL-te9KZ(Ow+q4D=wm51qY25 z5KlIhJ(VI(!clJgt9lBX1#FE@TIQ8A_CDg*KGzF97d%kvmi;KCL$*&de5ha!>SsAC z+C`^nBU@d6rTXkNPzF<0ey0kuWp-8c{y>F`eJ0}!76zU9@rqzf#8Aid#B${wLR>ryaYo`h zN~9(rC`L>rgEJ^Q*1OdZjtr2J72G*g=!{^Ov8)eozrh(qZlqmPDDs35u`JX1${yq{ z=Bft+(Tp5K=0)%JV!C29@Xh%}G5^GWR$sL+yRFA<1ax@g#9&$%x zn)txo+mT3l=jW?U&zAZer`}DKkj1LCDF|jx@I-XRl|k>05@JK%t(5QwisFD^TQnmb z`NRaLvLgShg8UA`K8CX*3z;-J(yPq%N^-dDI6A2l))dZjM~P?i+?!Iwv3c$ds&Uyo z_qMa4fr)axwEm2FZuvRDakc18>QPnh2_QcPc)Ox>6-w}EK-C_hxzmZD&K zWb@hAE{^$P`hQ@Mv%WkNWVykepwD#H-*5qKpX;o@iSP1J!30HI0M?xRPG|jXxxo%n z#*)G${DyGweag(u?+k7smK)7S5xi7@HzAs!yNE9?H!n{yaUU~rO#N>Y0N6V zXTYBdezmHOdlkPGiLbMH3tP>Qlc*#BR3SOb$XU#HnV(aR0NQ?**Fmw#`3dEm z0kB*en0^vjNn#;@>Lz806pKw0d0`SA#p*+e1e^22g*|aXsD^2;#27je1A{-`&}1Fm zqJh4kZ%SGhD&ED|TR0^<&gUHyy>Zg|MX@_B^(Jd1aGuythcJ&wO6{-i(u8jJ{y#Fm z@-kX4c@cY#or5v0ki7~gHWa+OrFxuKQj8_#Dz7w$pYdKP`|364Qda!kpJ@rV{6VdyIo!=TEoXs>en8xolXwf|0G6H1QUG z+3%D^sYKfXeNHl0SQQ7WZD@_Ic$Q-fekG`lgaF)Eth_;){*1*S%|I zX%S_%&aSD_=Lgc6*UZ-E>*jNgK8?rKHPo-Vfi}srG$h6fUmq_OHT|PcL?-<4>GJzHVkI3tpe7#3pHi7O|_@2jvr@dx@chAr4*DOy|*Oa2klT^=E`CzExH}NS5SKt~2 z96xZS0w)gSldjFXkQ?lytF z`fuz^;nRY?9wT$Jn>~xaYXmSPzbyJ>8f^=7rkDkvo$j;hiGP+-R#yN_jVdBrbF6$> z!*yt7sY=*HSMW>xlSxqIKmYw=d+!s#wE}2gBh>tiw?Bpam_kmor!t>z3vf3og5WPk zq4@aD6@mBa*^aPC$SU!$mXw9H>;nMsy4jkAtIcg&;ulc9u@f14 zPtra#JDiuSfgBl{E@NV2S#9dzL}Io|VM9N?rfDY;7{>X#k!HcGU_GCvRSNcb#Vbws zc2;Oa(F4Zj%+<-Rg1$?r4x==Cp=N);jTh4O?*_^}?A@A&gTb3HoWcWbVMR(Z+Tgr& z(nj`K2C8SW!P}&(WZm*SoGLVppWv2;_?hUIYN-%*Y4oiRr3Fg#@o7HX(v0SIo12YR z0Kn>%W+=IiWHBd0%(?yRvKUM#D&=huqj|ttRGRKI&!J!j>?UKa6SC@NW&ZO@dQUBB z@olgm@x1!cHN}Z}#3c7)Zbm+2e=PC2>oo0#bj#TdzzsMNE-4LsP|%LmIg=e~%&ot) zLSMWxaupNgdx_E@^g&^sXu7uX}SL-uBqq zZr6Ab-$VYy1j@Dgf&C7@rVLRsx{gPq$nZL}yUtdJZNMp)t78}qaK}x!N@%CR^p0zr z2iijFNGkC+pqmFY{*-dyMzYr9xzn$gI9*IL0eC8ZP|hcPWA1v(0)Wo^f66 z`9&*5YRw5FF>Z?j5fT<#Er`M#?H7h?iHl(Vs2}HK>0o~=3x|Oo+dlMnce_r^B58tL z^&=zy@sQK4BG#RI4{1)Y# zZ1|xK>jU6z)2w8pCfm;jXh!5N#IAwBqEE6o0+VK56#kthp`>&3parl^^BBfF<%-`R z0KWv`BQm{B6C4-wjQ}nO;GmfWnTP&lp~bOLMa9xqsUBpY9t8&vX>WL34l|;IX)1w@ z`f=k;Na)x(9#=>x9<2|JJkP3$mQVa9T%^SqL;90-AxwY|nCf6U49l6P;|R|?vhq-P zEa7NqnTsB0p6WKO$|J(x(5(LjJu}e2+ulgoz|#X4gZ9aAu3BWAmgw<2AHeV@)0+;V zI86iRk&+c&tu!kESYD%{<|IerCxJJnKY98Pobz6pS}* zDl+TC9=<`~wO`sqlkf!0aQDepXcvNp;!y+DdC}REv47Eq@1?cGFh^<;F`Iwc;^0}K zhi_QiY1mFV^9QVtyCK4~LU3D=@Agf7oaMLC)TYJ&_E18y;>+c$*IRnSO%<9n_XS&PmA&&KV#EFhpo-w8e&4635p`g#N zGOSa-fi>ySfVnFi|J`DEW}u5+WEnHxiT+e#J={LzXLi=*j%s+Hx$+$VP#e|I_t{1( zJkXBO#U3Pgnt#Jqx`yyy@M{=SF~ygGrXMRx6;hPQcbb}r5>G4S1b3$bV^qCp-DFwC zwV1J%mtyx_F8b;ukF{y0QHKg^-f0SJf^WX}_aH(Q&7mJSO{+v9t1#n>8_gKK|A@QO z-3!ga(b1pQoUyF>`zqOe*MQ`AoC)Gw0NcPL8RMR}m|5d~1kRS%P8EztKVkWtf!*oE- zD2Lp2GeC)wezpBaTUl~g)hj9d8TziE-P8m=zYb8rLHfHppMhcZd|E`K#9l7KH7iU7 z)+(T#1qGHWU^N;iWeB(jIQ1`$XQy50rcL+x<4!#NK0D}qSLuU;&h#4k!QjSO%Xg_M zi5sK@qfOxtL^cMg=&Eo(pU?WbF%4eW$0G zUZa#Yr7#W-W&(eF4Uq?%OyON)9#vIfxweTHU9!TrqnX7H7tQ7s8 zK}4@TmTMyH>0H#hHNYjp8RM8V|d7&wY0z&5l7Xbt+b z1H0lDS)rQXaSI7khQ?9Ywt#{(jtUrY6E+Q>va1dsPE!bLIOTpaGn_70kML>_9li41|UyY@GT7;pRyD#d^nXh$&;DBgVtCJ_c4>Cz%XK4vJU}|A#@5tdhfL zwW;S`UO|KI)!jyf>NCwwU$DJs^V0X$D8-EC73MQJl+#E{mX8?uzm*Llf8^hUz#DH4 zysL(d{qK`QI@>lsENO!R1j;mjw5nA*AEEeD>O8P}ob3(nmiTLYo06Wop)KF$X)VR)U8#5gZ ztwbEQrl!LRWaAlvj7E%AzbmpQ${6ys!mPV2p)GQhngKC`kpP1>*#~x_;ybkZcvOO9 zIoRc_ubRf~d!cFh$ZS$vJFA~4;QFwef`F+IXWd1S?Wv@0CD2zskQpsL-)Wk57ATjS zIQPB$osoD_a41KB(Fv)1DL+s2gy^T}y7)1kJSgg2^4aA2&sjIB9I-HT`FcDz%*KV8 zRko8izWY_>sQZJ@X=zKXK9V)IGdfdmzs};LSdgsy@(|ETl`fQ&Cm{&J>0~o3cTxLP z#91lfLzKg|FTPOk-6U8QqZpT`F<@^a>E-9SUZd|Q5#q=&#PI&CQ)mUDL_@*P?FrKi_h@-FIBGC&=unXPJu++>P()-AV0cG9wr1w=1q^hH;O)CG94bayeR6#)v2?@znhFJ<7f^6X^?sL9-~AW2ug_r z^r)hJzz_8xpx`?wt2)!Ttpq7pKO1@;pRVD%7BlHtZIAwnKv}rfP_m;W7l7f*8(aP` z9cU_KWR1h^qT)|b!PWGHg*Ik&Ao?sdE54^z*W}@9>bl}GLPH8$8@$XK z|BCvESiYr1p0O?Itk_QM(|`~7vc-;srlHZfaM3dE%Y2PkFIYyyua7I`L;QMp7{6A! z84ugy?>+AGYgdwA%Prf)ucH`*;MeEAM)m%87Wv8$A5Eq#5xz0123w>bHo`%*h^_C6Ou-Gdi2TvKY^f|Ha=t&+Uv6k@!Zd)E@FP znB&}gmH2)J`91H9?J-P#bBD=qk63{Go~b=W_W9~dWQdN zk>CHG|5+d6f4bqn)_EiOk4;Vd_d>rxTT3ep@&DI`|Avt)+XnfcPV~qgkw?twePG32 zcstlA%O5`@|CbYs!jn$Zc=Q@fWgu6OUZWojy6M;h%_gi=)#J-B-K<1KEAUeSNp(T6 zRcRXDWcxjIKUORH9oH@~x17n0qzxf)*&|E@iT8@@0H}v*^E1nt~ zE~L@}i3M+qVOpc_c7GQz^SY$5#q(%ioE`7bf2dFc9@<^FhDk_Up`wBSB>W{LH7SS?z-nI-sF;GOu#9i?SM zAZ0#?YT(T*^FjFXzFo3nu4!##a|)B7CKD=K zo8q@hbbd18v?TE=duK54NkOv;dlUdh)p+4Q zg>a!J(o9zq%Z~x&8)vh^y*(Q=F_6n!;MwsimZ=Cu{*16SYhes{u22aOFlH`xoK+^# zTEL9C*k2c^%wzw+N{%I;(9sb7?h1N6zVGyu9N|<-n^KU?!AwH5Mv<~*$0 zj^q_I(dh=K&bt53;FKX^H10wSTTS<&wNV?!I8`w4tmaE<>0yhl_z%dze#GMxY9=3; z81(H#Jw$fceuM>Kdm*_W@fc8a=Q++3@3SAFkQ3GAO~dvhEGj0;bKr=9UuBvR4T=-m z{2-oWq0+%-a#p+wl4w&n&JWExw|6Gor!Flqx7+B$j=$kWepcug(SHrv<&+?O)SSl| zF!GELsRHq7T-?pKnyF&2jQW3tL`GL73rhFJ%9pA5f6T#%x&F!UF`)XI!f)}D z$*g2f+>~Q z7d)Bd-f}q{m^J`JRY*3)@}<&#%MI(K1+J+@EBR83#C9RED58gX7Qr*R)@k}rl#53W?+=*KgPYP@lKQd?DEz@$7$*TRt%}m+gj$wXAII&!c-P#MqtP3DLQKPsAtY*e4HA->cP@KP*ryHMG zG)%X@p@0T~#8^RDlZRUNUF=qaT-lU_k{b980g7mVGJ0I16F{&(svxNkkgEK>R{5J~ z2w9>`R@p;q;ssJio*!sDc1&IP$#4%p*j$b)#8p4~c_#e2evZStI3Mxjub7#^Cm>hp zK$}b!j2&13HEtC?or+}o%19G``d0M(4$N%>wL6&4n^7ey7o4QA?cuKjP;4)2^j)ap zpTC`92%xFgmQ{YXI#)lRbDBzmT9#^2P>wq0Ea4r9m_HF|n=3|WwAl#nt$nZh`W>m- zW@tP6` z0D<1YHTAjdHh585>3utg0|vyTd!@4gG-JG>=@EYO&4g4rdGb<1Yw?Tr}tf@Dt%_~Typ_--r7RB2h);3CTfo8|Q4CkvIT=q~>~0DI2rDd(TG*6Bh#H>tAm0 z!8N{oHtKCsaHm^72c27p2S@o_-n*=@=V6VK=%N~y-kTseb z??fhB{SCN+;vN+U%lWm1Y2)NfIwW_lYW zPB1l{LgSBqjRJ3)B_J3kuj`wt6o_VhMebQ#k?-9$+ni}A^U7y%GU>HYkUuFPpJXx} z@NSp`&)K>6Zm3jD$E&HF8^EzTm1@a#yPT7h9WJHi)O1s^=0gv-aD?TLt++x2aagRpZ(m5jLGU)b7XY2D~J`+*!O-p2>I*tF`v5cha z-=fv>XD%|{ymb?q5(h%iPS-Y`cFO-}^5bYq)`9BjjcEdxWo?Z-@jM(X1#@e^23@zq zLgm`4Gc1OTRvXgkOL<0ej{rW#@qgOSGC$%E^YYhiJoW)tpAN_f=zBicJ?nyfC5-it zlE}}`?2oR|A@sQYS!;iu-4 zx3#p#rl-g70ktLJK4-US=Q-=9XU(g8B@~WqO<`st=tE;3BWrA023NeiU?4LnFV+!j z3hTqT;;k~CF0uB*FT{Ed?cs)(Rc0rZD_frD%9mAUgVkC0m2B{D9)`Xj^nGcM=0pMw z0zAAMufA0VYZCeHuH|O8m1|>Gh1*4YlGKBo>TmuA2BL#$=B^@J6K_oCn1_fueshF9 z!iH}x=X&Cu&)rV_pHwAwb#VdB;XQ{>Kz>@AiHY@a-O!2Q1#eX`wsI!Js_^frr;sKDWEvFE!)q=s&CKW~3bXcq}0d#m`iD%>e-(?hYecCzQkeWZs( z+paFV1?_WUtwqvqe@uurFu2++t}cEKrp-A~7dYG-OWO*Hd>$s>W@{SzBknW^c0?Q1)69$1jU54$Q{$@xG~+Aw{cZ64-qLG+(soiMU&Ivg zO4C_-r5g`V=AT_Zv#=tmQ<>Uf&I>e%3A{k;A&W}kuIFRVlWh;YF|p6XFo~uK2tyY@ z-PYLOomMDDSX2L@F)J+t>}rHqEmgYHS`@p791R4!b{|fVqR%8eD8-TPwDAH=@~NBc zqpm%NH+QGaSG3y4bSLYmI0%NsFpLs3r0?qD`Y%Ovr->E>g-57J6i4WhyQs3Lr)@Z; zl+3gnIk2vkd~h5WG2g6ozgh;kxNCQ^%C=gTc;ZYQeFoU1WPNNchbY|xPr2C1XGAwU zy*>v-|KXn zr;sPr{7h_V*)3pUiEVQX%Ds9y0M#U0S0Dm~CSdyi9!Mw#F-w24bNX!v=R%-Vcky_w z#WJ6!T*x(ASZ4Uk2B#%gM3`Dxl>)LkMj(}|J1yM^xhc|gv^`xNMuR97aeT|%)dsSa zAam|sgzdJWI{XD@HQ_t;XG#ObP2%IKhIuEq2SS9ZP5wD5ybPgM4b+JiDuTXfe_DmE zc`oQ!QKeJXKz1v4UHJ5HSsAxq+iT*M^`#l002@04*%Qr08QMcD!`ERT`}l3TxI*DH zbk;z2-tEb-y+A|hJeAke!yUQVkD`SEW(@v-5}i#ix_i9ZQ1Css)6TIr7wzT7vHkfm zFT3Pxb%7fXYLpGlyNS`3agpl~xjU4*Pi#PUiynU04#csvE@{Dc;j5~eN#&A*sL7~H zN4wrOX<5V4{K5V3+o-)&oUeqY_21(;_wA3RRDY>&Yl_p%JTB0-<*(zfg1ITO)#|pA zYF*`VWU%_Z)16Jz&T-c5b2c@Z_uhB=9x^K&%9?&n~r(R4m@=?A8_?569?rgDC- zFSDph?9W8~JP*VyApFjyk=%3@Q^uaI7Y^-a;9YL+qC$>v5dl`335q7^XBXXSp+1yY zNuueMxWp^2hxv~BWwLJ;DpK8f27nF8Km`G#Or&DUlHIgqR;;9o9<3qid5Yms(ZQ0+ zt}%ybYIW$YlG*Suz+nM~HI8blLv}qLZWUHWDgAJs7UiS&bAP z{aIkZD*?B%J=6`n`6XYqf^Mb+jM|6ahW^)SPp_g(f-}YM2#7*J*z9ovtXS$rUDj2e zl1y4tI0Oj!dz8O4%L}z?rFcHG2o?*OS_5eHijA9@e1=zAtU3A@*m&`-&$5)cq5EK~ z_7w-RA4MhT08hx@C}72A_a%HO^XBJbcUiHBB8|afVk=$hxJtG&V`%&fp`zLMG0VOJ z8vOb7b28C*IvICM4hv*XPgiC+>(hgK*={^W65)?I>nl=BMBGGF@Q!e0PISV#Bkh0A z`qK2|B~#W7pXLO#bktC+SQ*O=qny4WW%N;VB9Fd{{JS#2y;LTho)5e?^Sx4!9PINmqf z;9raO-pChb&JXxWI-|3u1BF%C{!K`Uepc&52GRP7G?s|;mg3|Hqd}$G3@UyvV}PX& z4WKk1Mjfm&T8e`QEIoyY)*r|&F=I?8Js2{X^Q3b-q*|uc3@e$5?*NRxee8>g->FQi zZ{5!6>`F{N)e2SzqOLM6Ey#jt`4S(0ovoG3s!3vc z{w^`vZkUN(EZw6lcjqT{aLLPRu9b(%zH0xz=uOkpi+1A0HI{pnPu$u@v4JhD5zj8_ zs_Er7K++TClS$7=-ftFIb8+J9cT$f=8c)3-l$$ba3O)77rh#uzu#HGTbe-M8|MMi_U z^1Sc5#jhp)>+#d=>o>>ZI`W&z@{s%Rbk7+VS37rKK|NPDeN*=m){pgjTDQGb_M_rF zhkPBK>m54Ci;L31amo?nyzc5clhtXF7gnS{t^Vvb2HL3$4>JidLW(kW`3+Gqo7ZZ*ciVGV+6@v%Sq0qQ_6ee zTy#1Lu!Cvh!NyZfMjt23lKc*2_t5*j3n?SbPEx>@+tXZsTJw=>A_J-QCph!m``Z7Pgx*~}*a~f?6^58L)Cy{Y z8LEi6RJJ_vDH&SrRSmWQ|9)1v6_NWUa;V$gyh-A0x{x>db=b+>9$y{aA16I)`r~EE zVXZvmUF7pex@7RCSd5%p_3$sZVsY!MiD5X*Fd4tR_}O^>V;IcFb0ssH4Ab>E71Nzv z!NQ_@oLO4G)tx=dgbMk~mNB+Aw95Ikvx;a_*b0I!y`|%jAfn_IMp9d#!3aunb89g) zXj-yqP3?{Uz@-A2(m6^0|C`zZ>3G9yx{KNfGljK62Fh=l8FM9Lu=*y}QR2R7;!6BD zv^8=6Fe1*v%^e;Wm1&V?W4@$q=Pdr|&Z}JV&NFa%j52Mh%rR7uZQm3^42#rn^)bBP zNI-LyHB5a*w|rJlX_)$~`S^HbYMkUCs3tWB0_V4v0~RrA)5JEk9Qu2JObL!=j_jpws^@*4ecH;B_z1*9$y zXqw8$#uSd0%D@XP=^+&ufK4W+p&l0^Y1%Y3f;Y9~h3}Yq$Rk_rvaM$JUAM&2T9h_9 zb5qyZfE{+U=h=j*f`OoKt?$K-Pkx$p-@)%uJ#9 zFxwo|I5tiMu-G)y8LmeT2btyD+4jLSUAbP+ZWc<`vKia;0ker{T{!cdU)qJ1&ZXSvI_pbbBgdjQFip4?n(&ZL_NQm&sb9apt8U;kRGRa-rc;^wYo1mDW0-NR zM!r$h$0fg#Ek@+TZeO+!X6WpFF^30MNC+S3{d(aW>c0b34V#R;EDOb<_Jp6PkGsep&7LBj{~d zoEoUUAd(1OzxXed5DGFq`_kfF$%0$)a@}VR6=xOnH6N_Muwn5)pgNmZUrw2Mue0vE zA2{n4|BbS;rm*$7sgrT!R`E{=??R0qu4Dp_h~o3S$`SyWHi(@Qt-uC zAsT^G4A+k~27|g*(0ryS2ba}OS~7vCLJNP%5IoQNCE?Adf#>}KF2(+rrI+yT)_BGn zE+Xu2Ik#mRH*a!LSj&wms;GInLHB0QiM+>5J^&o|4sw-BOE7wk`JJZsrn7KWRphjk z;qyO(K%U&NJ2P>mMy2xL-hO4(kIh-4uN3ZU53MuzvP7FQ8<4$@{&e6%n@*1-6VydR zKm1TaO7Fd=oj0)ZHQU_}$Ez3tkzG8S7P1q);#{VD-k2U@qU8f5R}}564lC#BU5kh6}A`+1js>7U)W`TY~~>{@5Jh9N3cxmS1Tl~g#(UniY|1XXOSbCjFj zRqRByaJpqulG;*9{zUVot6V0Suhe1l zE2N_^vLzJhkRyZT+j5;RAzpkgG5lYCH!-*aN$8oM-GcR^g-_DU$fb75l6=j8XBk%h zP>}nN0LC;P|MjyuEv zwKveUPaDBxE~EArePEPwu7-v@rVw;up)lnjdZG--GIK4c`cB5+Rl-zo2CGa7Qb}YW zh>((8c`br!H@NlOLS*Y~qppVtD0$WpfKLI%)S*Zjeo)C3M#OYLLAT1)LPj3xWn8z) zorX;1^aQh+k}+m8OG?ziU^{$av`d^rQAPxTEKB?u-#^n^-FRXq-$<Ql81VvDeRx*On9}?eMT;PJ!nNE88Fh345TLBfFyI@O|euL;S<@76!b{`siwRd^XcTdxp3gJuYYJNEUxB~9EPNHV`X>X&zp|9yXRL|4c_wPi zXh8@p>kaLlOYfq2>-scPkh^qA?`Zlj@g+rd;gY&OQ0lHgoX(S1gE!oOTLgN90l_L% z`EdOayegfQ>e{wPurB~n=rq5qXza^oj%0*s`}CB+_UXX@cKPkoQ-dNi==VKYJeemb zLmm6bzIaoM}*aR4~dTf9;Sv@kJmDR(TKHSS?`|v4c8E&l_ zLk5iJ{1y0c^Mzfli+bOHF;r0>Y{Wu+(0J29p(B6g>&hLXgu33PWE)YU(4n7VZQJLDuS)Hx3)j-YseL+vDOkZ>wWA~x<^zgOOKM+k z1D4Ei(GJ7<3@7>pYDWRJOcE~F-S049qPa4^<7i6cNU-A#EjT8@JaayZ!K6q-OhsKf zOE8T<6{zTmAcfxGUM9I^OG@a7{`p;snm}#pInni#b~@$^|Ilppg6-2%1Et%i(VM2x zse%D{QY{K7f8A~~n4q-4Sr!eo@}q%M-gpz8<%?1FLmjW_9@H^Blon96Bkk&2v~#;z z45cUjk@TW>+yiwf`6mFVaGrQMRb6~tR;GP&%xSuZypW^uvl`LXE%zi#g-?R^3EB$m z!HJ~>O&WUeRefp39D4AG`AjK=^hBwq$&1KmVe#`y(~AQ`c?M&K@(x9%l=f~kC|i_gqQ{u@_Uu4-<+?g`P2cXL`?NHo@wt-c<9T z%Ru$#yfJ#Hg|kWdUUnwZsng)eCtbb(56zP@fi;fe9zUTc)A-gC*5?a038^7VFIKQjD1mx=$c-gC+OzkJUH5zvX^S>gwpmCq{s zsoPVGjWHB|y8?=RufR~eRByKoJ?)~`rs@0YogX1X{P#Ok%G{@pYg$h&tzb4Yj!xyMwDKPD0<&%?(-?IC4wcIv5m?GVvQ=& z(q*ju|A)ah_K?u4IEp~UYoH6cjVi!xRCyHRQ&w=W=$$237wpnB+)>h87kxtT$W#V^9gg=Qg7{j2WeCX4S`gJZ%rlg{P7x(idS#M=b|xGm_O zw5)XpSv##ebiy^sruv%Ix0>p=s`?|i`(?*{3`Qnu;c)U1nY%ARqImFguzAC$H}6MB zHt*kbUjQ(o!;L}4waF&-8`f#jE?0Ni3$|Ix{zmKLt=4r!Ewty*0%U7X*O9|G@8OPO zWFjdFUv^ryLmxuW^uESYM5$ZZ?W=Ux(bt9(`svdNyfD)ORP>o^`8 zdsqU)jbGiNE|@a|o7=-iE-B0kVTXWAMSpi_XLqPy)W-HmNTHKQ9CsgD@HeVpgjfE4 zrXCNA<<9bH&{%LVaV0-qaX9f=Lvmu7hEC3j#I>Fy`V&Ma4eORZ26QuFVireNN28=u zId~gwlQ5=$+Lp5)ZB^cQam+#4>3@ICfl zNk*u!K7=B;vz|7;zS-otX=XIH0f@|w*HWWT`-L*8lIUgpa7X9`m8(Lc8SC%~_wExb z-TU>|yHDWm{U+0WBHF#*^rQQXEZ(ob-hJv#?*01f*^Y3(q5nSNb??_-@4hF^xBhzf zwV7}I_3nFyzl|NHl;2u-#dtSz6KW=Z#g5QRCSjT}{g1HE#n1|?RTdwZ*sH&KTK%J; z24Blq!dNt+;#9Hjqk1Lq;#i{sgUV;oIbNg4!n$~_(I=g(e>UoMPM%ZKkI~OuOgwmB z_yT7W%LiI^E)7!0v}(4>w912~pA%h{dF_t^ZimJpmMQZ+?46@|0gKgq0|M*@$)-sk z_qH$1mEK~*3QQ;(eDS=+4Mu<>Nt`X{lT1XH4z5Q5B1g2lcoup z_m~3S+PV6BZ7BaGJnQkm&wo)zVNP(bez5aD!871)sTtGJn=#MJ_FCWd zfw5l+?2or3=6Rv3`}f_*w-7T+tiBm4C!9RYRTFj0k*pPKJaN_eyH6hFS(@YSA5QY- z!MP`#$2(J*DNp3JuA0yDk(p9`A@F*cU~jS@=Mlv} zxD(mBV9PM@u|7DQ1=cXh=S}Y#qkl0>uVl*Bj;9x_;|-3^3nOAS14hTYIgwW#njn2Y zH`*2)jJ$ePecmVADR!#Lt}a>{j`WvQ&ln+3nE!MRM&k|WB0QKgRXJ+@RZhv&rSr45&RkYXLzx226JNf&2e>DO>dsGhcG9Ci6AWiSw zbB3Y;jnLO{5pA1-h~%m5YcB8_a)Hl}~;BM=9Bdz8lYOcqYEM@l?I;jW^Xz8P&P96p(J)h}6%_#$ZDE~cT zCVW_0T=V2arkij!ExSxLX5U64BFnsw)cb9c6+GDkGsFbT*8h&5xu^3p>;EVGG<1&S zXFB|ZkNKO`2@F@^=>N>mkDtcRq#*q=$%f79uqhPy^8x z$rJKA$=5Q|w9pza9Ym^UQoROg9;7QwQXYuL3ejL@ufd?e&gLx+fyoH9QDWrC|1&Wm zVDl3o$naW?_!@-BdmhcMM|jK|gCN(Y&G?gt^EIZAcXylTmO>wrEqkm7OA3$1k{^*8 zZ;OF*nQ&B6`N|n{h2VBNE;b7(i*aQm1N%Vrmz3diMAX)L**eys!VTi7I@pkZ6aqsK zwZrXnKdcr-j6qwl`Q*NiqZdQX1h)rX=-1r$QC`*(qy}9|C?iu#vvyh{cc$CnY+4nly?Q32A>#JcnN04w+nCsNhqkrV-o);hySF#p*|hwu+H66;FaqZt ze`I~tb*sBOu~kN4)*pmp|2_Pz?#{%IfYxN$)XI<qi-ySahvDSrAr7_;+p`C)qYf^pPQ&UXl3|zHnnOzb~ZJP<;UI63C*T(0|n4S z>iipSfUf0*xSq5rI4_a}-BOqKB)${fK+ATg#h<%9kTzcvIHO|7lLHNfUbZ(_fmaLI1V+z1EXd2}mYGO7w+l#t(I(mK0L2Y5Mr z#hdQU0vEEv>Vg8F=iwajuOlx4z(m-Oq4yE>?jcm`s#LNI!UDQ=y zD}J5?0m!7!~<8$1Ey`8cP&0nLtiNUTv~Ks>3(N@nvq`iSML23=o`06 zG2SZM32#;O50L;pO|7QmHm`t6Sh4WN{KO#N-3ii6u|4P}q-h~?z9)bCOao6EmS{#Bt>c>b8L*^lsN&RwINrjWS1r~3_} zag&MddL%}b&B=}NPP5)FaDMO(f4dKM9|S;0@8nWdXdL^o(Q0e5;GjJ~fNz%Wk6S~O z+ZQWaHIaj*xOZ_lRDX9{qtiWFPY(wEOQ>m*?zGO#?@+l|)vAeyIYHL*&3cY&t;##x z(VdnF_vv?Od9jt+atd{)J&Ka0myvG%PNXxXEo7XHC4K*8!!28-(Wd zt0Nr}m){P%tVexhYZ*>`bQ7^L`M-@sufnWHYH*ZOLTq>9eOiqVYsYo&xf&$!zJwp@ zYhIR4$hn7;HsaK7b5(GXVa6M+n9zj8Hqf+2jul6yrnBplQh%fM-;1S9lxDFb_FW}4 zU)*8b`j{nbg3;eK&R@P`8DZ^#4P+06?J*@ktobZ3FgIWw?pV95o*>UVhJUl=%s$PT zobJq-0y)IR;v9)!`he^H_=9P3+KcTXa~}R{$2aj2=JaL`9{r?e9!wKzzSxY+G)$hT z!awX~m(UfgzL@&{Lb@VddRcv^&e?>|K}%KmW-nVWM^nr!c1nu9jHq^jm}{4K8O{Eu z&%M-|%*Ls?0Phr%rVjp^PM6$sV_V2%_Oi9Z);Kp@BDX4ji}l-agk8O+6zvzCMc);$ zcA4nkeB1bz9gSQSiH(jlZ96gBpOsAO=*c{bGXS;(R%?TqKvp~q8Q*6{mW(%uKv0~x z6slGmzg@Pr%NQKtBt3Mv@2>XOxb#^Ly8sW!N0jaKkMJq3H?Rkt`I$5^uTb|8u-BrI zys%)`(@LX|bQl?;N5mfj%y>af0)P!Sr)3XCQNc;vT!Q z-5qbFMsqt)v-cJ3i_VxlY`k~-dG^pw?V1`pzf%#Y4s8!zFu>i*qw8NQZ`=}~sK}|& z^*aVAyOG8103|r)%3dR&gEVP!hEf$x#vK6q3L(r;BmYAGO|OVo zoKQf<&;|3@1)CLcT8`aF(eDsYVv0$O|9HM zl>tQ*CpmJr4~`e`s~TJjVTVK#g=YO<@Wi;8?)+<7((Q`0j}mUmUg&0h25&7-aR(S=XV%pQie-1S(3%E5mWg|AGU4 zMOM@7v9w9j?>Je-(u(a@S%L035>JLWVsFlJ)}=Jjd$rRmAF7+5O$VrDGg2{e|KGSj zqvzuGqiL0}`=D9*LDj^rF@<1_hB_&t(m$%xHKs%*=@=#)X3Vb~IYt_jvP>Zp7F$RoR%+5mhSZ2%`U9W~O_?TG=l2g1DgKQE*Wc_gv~y@4<$KufCX@V~>gF zIgb`g69b``1`^v6w~#}1jI^gG9%ZUUTPfcr>0b1ssZu8b>rPe-6-zXLCYhsx9O{8r znfbZqV|q_9PcOcG4NPT}U>t=C`kroO0gRIm_H=!zIpWV>8B%}wCQ$KqzCFCh%#Kz$ z$~jnwpvp!V&; zWa$O_cuw|7V^*Vn*nMT!&qEnza=ZsKZRCpq=Mj7(oThrn62QtXJS^$P;--e3b--C1GIN{VTH&XH~i?alr zA5Y?JAxrNsymFs0V*zn@B>vS7jQK(;2!r%vAT>^*qP2J!tz#_S&w%&bBwl&PB))9X zTqiV&Flc`F1<*_;MdaN+jJ)liGF8q7O<@v^j!7iaE%1ha8CK>)7C0Z^8P;Di@hUwU zPSmS3O5E(G$tGzjv9z_=Du>t}~iaGpi* zX^PxUbo}J!0sOi}@w!k5r$N!Jlv1CDzX^rkAiuxV)Ywst-KjcGl*qMU8$L1sm@f;z zvS8N&_UR;J`~ub{^G>#@65Aone@UjEXHzAUL#dO3e!1@!7^)<28$|lXYNaI0J!n%UOGA0v zlX;)DsS=@~)Yp@#Keef9|Dn`yieGM{O;uyta$A&=EcYL5s+w>p@9&d&uePaDV?(Jq zsXpdU+0=0(Qmc}wXOSAg)57e>e6?WL&6_kS(!iRF`klmLpv>T^)+%2OkI<}ZM9NTGO=I6aP*!>-5?o2_lf?dI#&ibrEcP|FxL>hb79r2I2 zd-lGc-^HXW|3F92M><|j5rq@=`#3)GA(d<3fY~V;0UzdlTWw}NPczH57XpR=2WMgwo zCE61SIAH1579C5YXl`b3PxN|b;&OMK8H)6zVyJI8k{aOo&S@zo7&70f?LDIcoh_r1 zknQo5b{tQ8QUNB5g(q@E7GO-Sa**2s+T)@2qbg=(Hd}DABw%bdTxE4qrIb9Q+T)|z zj|`SGs=X%^V99tRh}r|2TW*qfKCH!pGsIe~fhhVxwtkxF*xzAm8_Pz{W|%=;M?xkh z71=u%4Y4)J)K`dOl++9g6X$ahtEc6^%ee?UCaa|~N9YTP!<993-Zd?w$|D1#>;J3< zF=rLqloKh0_Vl6!;mkX((Ee1xK(A_&qkLTVye?Fj%$ZPhq&>4JF7f%^9|mjpvhWNF z%{D?tbR{%@w|3cQs9lh_#AuWxi~YDHP&+r3S`|v@fE6-xs0-#$ zVh-{q&)sK~inW2V)vf25MuGzSM>aw7kX&uF!$Y$-+}w?<6)VmQtXMi z?y5d2vif{Q4z3*OzOi3%a+{(Kzs2Sl@a#S+x2$S;cWIxA@+$ z`X-QMo{B7aJ!W((VXu0x1DuR&i`t&O4M-b0qTGd@1|c5hK*A1xz^EiU zS@#SWYWs;z*UYC*JHJpOrwI*^DGzX-&>7Jve<$TThf7;8 zW%GRsdrvY7ObPk0h!0(_v=+1fkzGS$(`;-3N#ASqeVNiQw@b6%t8pRuMEciA&uu0F zLn`Y^)|g0rb^Cq3%k8Y9X9_&+UBA1`nr3w6fpLMqo!ytdzX*{e>Z$kNz4WI*V{z1lVw%r9UA= zO=fxtKl(h0Y}M-T@A@noT^6Os#WTh~6#aqHw|WF?M*4)N6jV%-{GC`F8n6Q`!M`(Bn;o}s#jU!Qld?sZs2vYO;fw`(;!FPLf z(D1wdfZ;6CZEp?y`Wb=`*ifb=*$KBXl(U>YLmpmnpJr9_udlX)Fs7@?3d-r+?gl`|Q)#kKo_CFdcmD9`}%trTY; zEFGKt3OBVZoCQ3c#i^itWo$>Lu7vgm_nv`>4ELZzA~~P?lW;eBc9aiN-SE&VY|ORMs6oZEEM6Co&i- z7wSO$j0cgv#z|*>mHQzrom-FHowcjY_Y|`Y%JKre`?oja8 zu6_FG+E9CW+<%O@kEw6+@h6~H5bo!`CYg4$-KFiszt^_mXA_hZ`gE3VPiSM=a?3w) z#U_nKE$PyH)|&AFj1V2ge}Gz}1C2c$pDEyya_(D5$0T=Z!1Sp7LQb&(*v62pUq?5r z2aHlXgRZ%vks1~bacO&R_CsBpgVg0Dq8RPZ>GX=ZA@Kai$~n@?u3oxUwCLKv13I`G zk-micJL2m+{%x)eokzE!;dEwg2vGyX-0PI~Y;Jf2T}wP*N8}<;$LmOSfr0nueylR+ z|H9kIjh)@PB9#=vPy%Y_GGpMxeU38)N0xYU{2kBRl^g$x4Dn8s%JDwUt0jkv7&GCv zp!@%vKq{0!laWtn%q2(maU_awa>iW%opG1y(c%#bn1#NW(KVNH@$BdRijl(w#o*kH znMLZf>L$FzA&SjbS91RZCvikJcgFL6ZL+cHA+D#_ThoOj3JO{LKBH4m!b7H-fX_W@ z2VA-P@h+O)$>Gt!3e#3U{^n^V~5a zM*Cv`pg_S2R?jwYo6YpwW13gC%IBJ(T!gyV3S^H@JbQ}&sL&wcc2o_Gy@S*gAKSzG_$@A!l zyHJ3OqV69#X5P*yI}&v3hG#cyazm)dj94`(v(jCw>e_kU1@*zV{bb@>{`nTDY&39E zjbIV6U3s~t^Fa;}q*Sg&iIl>Lr2)Ac1QneVNg49{aB9?*0LRA$8za~#RbCA21 zo#X_Mnn#W5I6&NRCtId>S(2u+g#e(w<>VmbVd@%Q{jC>tk=6o@3(m3wW|W^{mt4%i zbT^~@P?XqciMrCIvHcJhrjSoLFv|>MkB6fwD_ZG1~$+3J@(^=+CqD zMiV9?zk>My%~K-?mOays*kgYLToWkBDBMWCXcxCs&dWLmkf6`9r~R8$rXcmCs^Wbr zRZ*ZRM3kPZYR%d+#MkUL5wq2pusD8ELH4FJW0pSOCYw^OZ8*<&tZHsjn^@0qVp*!* z&WMq|qcI)ZmHuke=i92%(^>}NLtMmKKBUKnp*T*R%|r3e6KuxIf*S>gqxth{`xiZs zy8u{P4}fUyFJKXd&>w?+cfAz>oi$uycDAoMOUMj%_!&3Ru{Znda zpkN)A!g>LSN(1N+Hs8@8@R>Q(*R2VvVe#{VWwl$blXN$p;0OWk>r#zmx4RFf7ImM- ztp^nhpi8*w%CMe_Q9XWQzOE58orykvV)wSF3Kl={6Hn4vCaw1x#6`OP684faPoL@x z)<4vZqo1KOMGrUqj5%e@m!8~{`J|t^jD10;E+6ae%k9!97&=C;aBbYIpsSmdj`KI@ z-o*uH187Eio^FHK+6cLt+de3s&%_sJW)vKw-)G}O+5@ChZ|bX1aPpK(V<7d z1kGt@gi%P^bSX)3lIGJZCDJlNCfI-d5tQ^W7}{5#h=@)zWIY-M3vT?$iE=Y*t!&T9 z^7ntcu@s-N+-Kf2m>Qy!58)`_VxsuD8Dg4J;3jO|o*~;{VEQ?CAD@A*+?k8YxLLUG zYmEiE_qg-X*x-wuj}{L89B+zuidgtWxV08_?ogQHgFpbf1ie`^iy{2n%nA$U0WW4u z8+UDvi!7OudE=}s8u&iiOE1x5T8!#;EU$ga+vd|^HAhmfWYqQsUEf21;nVSB*3nYcWzD$X8neO`3t)9K<(hYT4Bbx zOb>H1<~-}K_&?xJ=CsprX|8@645sBcwJe58wm^;eha zFjo^nDuVTUyH{3f#XLIf12J?~0KtRH=?)OzCmu|8?-lYao6nr*KX3}9cc7k|)cYHY zIbre~frk{!LQ-j9^8ia8J*==DDa%7Qth4~Fe9KZjZ$rwmh4P$DaV0TLSh+2-mJc9X zNdK8~;ln*9-(4=>L+B&r-T47nwbGS-9v(j#J4^p#F9o;9T zA3CZ}F3a~x_X^h`gygt;bF3$FdQ7=n;T^bK70`S|!TS0#)-vkEL%qd8>J|3Z26hot zQ0C}$)M?^egSDr;^j0rArs5jnvj@5OQ z!nu5r3aLb~DO!N-nO?AMu<5~u*e=I9;iDeA&KD=m855bz5Blh!$1c9Q2KMjnza;U@ zPNI4!OxCE;K4zegpm1>D5psziY?#_1CJr(^s)54?MFTO^6h0U!hwUtG+V8ceh#VR7C_7r z0B~y+Q;%z>8Uha3%V>h;u|u7rt&^M**sod46}aE zJR+bGQ^C%3t_%n!aK@z^1bY!Wc>%1KNc0})^`mvJDo+{mh|7G)A_qz>^O41r;QPfz zKO^?pES1%PHx(4d`(1Q2)^EJ{=x0t67Z1%^ z!rGTQee5$2@8SI`?E)^2;4lXX**)_i##ftqW_da18X8B*35vg?h|QM%`Pl8=WLk(_~OUEnJBc|%Pv zYND?Sg{wS5Pmh{RIyA%NYY;-Pq9x|PsnPk`X_H!=rwJ#YA~L!56W}f7+T)_fiEP$v zPYh2bg&wlz@3eli?ow83u|DbnNTMtQOxnYkwn2pzF07zRRg(*;049O zgdygUF<*bwT`Ep}ErO(|Vm^Im|Dyws(zUac{-|$@uf}-G8lewkFgN(t1Q#9cQTlBR zl?_&vfR5>+ft?*|E9K_Yao|M>$`mULQ0Eu`1)777CNdYmM=CPXw?}4=&&jKSR9brBNn+`kc-Uw{o<*V8N+8 zeNRt8>cTVldvC`|-sYgBcRf+Y<{q%M0M&e%FVFeS)9>)PQWMKZ;*){JOi0l(u(9&r zRN=iT`|TgU0-5N1%2Snh^5wvr19#cO(=OI2Zz{lu{sBLJJ^^j%#AB*m6;=C5Zh`mu zf(r_CCJE6L4IWM4(R>UZxBe&bFkRdvyRb=c?NeiHC%5E?hM60s>{*1%XI)gw#m~DC zm!~Uu<-jiTiNd4u9oXrzIN^@acaxPb?nS;*mqU$bQyvZi-%zmpHprcDhH9%sy!nlv z54!KC6XA(&CAhT#=MhK{q=B88x-NBSCcaKT3Wka=CHYqBD{oX;!DA*-!qWtvawqX8 z&mvuAyanrHO~Lx2r%kb8l+KE#fA&ypAv0H+Y%_q9`B@e}&zf3@b^)N0?oKU63>~0jXlAeu*AjL!*3@_lkE3AQ|R?y&u#*StIeoGR1=oXR_}c=Z z7y^`1AU-YRML;6H^4n;ztVdPSb*<+ME5P!LVp?}Op71l8>v+3qoRioR?0Ff_bq%ce z`_zGcg`Ai0JtXGd&&Gp+Q)Rh%ubUxEYmB2;h5y2Re9R+%*Rl8zf}mru&cAnPCG2IY zU+!vQtYt4jQ>oASy?QwzrzBt#9^x+EfA-2iw*1Y#fMcRpv!GFKW>AxW;aVp z4ry7fDu1TJ(ej=5xVp?N4Zp*3QQ=I@njpBlM^=rtTHE!^qpSxGQp>0ny8_ZGNTd2? zo<)<)8yOx3jSg@IiGvQQA^oWMya+LMq*Q`Y^AG_{ZH?HLUn2r~t{tCmL#!zB9F~Ff z)uUI6D_n5p)W0&N?eEV=yjDM^&mM_*JuptIM7LthuM~HKy<08*+Q=ChJ3vvGVTkcs zv#s^a79tw6I_zbAn0;pVQ7c5xdJ3;>?G<$%K{3*VxVS;*rFyEqv<5~#5k?ADAKs4r&9wk1sXxM&%Xdj{lqP=MHG7iwb9^}jKvKI7VvHe8u2>$ym1R>>$$^z<+ zmVsIT_6ad9y`+`FSG!mMK1Y9A^EFz2Bm8!fVx)CpE1}vFM|bpPzm8MhVu1UyWKc<4 zmG#(zg|}99qtG#P zE{HA}^o9^+M$Rwxn5x+u(R3|(_&ns8F;dFFrmRW%N?7sefUj~1^E_B>F;^Op zWNlqi*<;o7F2wU$U?*Nl-Jn#TON2M7iQRl7Jc6#3`5KSHT*9q|GEzQ(*#k@)IMO}@ z(6`_~j`vZRn&$Yl;;9;12Js#rB3zv7W z5c3T%Rlu6$7NnzaG(jENVE{X-gJ4XC9I|efA<@9sQH`Jy@nZ_I~yeW4hzjgi#HaE&hXGAFR4dWcmHigAyZm{W9(>?7Vo7YiN z{n8el1|WE{-Q`sS3~aned$5NodT=(vqZVmjFShyg%UYcMnf`pC16Z?pn68Ie{GVZf zD+I#Y1|Vsu2G|rGr^I=U^-#Sco&KcM95MjTN$%zN%D8G*%lI#|H;47Z&0%lvOGUcp zsyC-Q^*f)7aih=^Cvqk7t{|mfZ7!W82$S%mrU>u;^-0jSaOBzqM^Sglguhn7!yua} zEX~@{TV=%8{X!Pt-``Fkd%{t60_Fv8DbN$Vr~Y5IE)%>VV0HsirI`W_0*Nym{EytABM2M;h=$Rf8Y;1u zY*%=Q$Mj`Q>H6~YMYF>v6!ELBH$A}lmF5f*nrnukYNsVwo@v6+U&;jA`XAFyy)VF&G4$Ee0f4!mj$b{oSgXpHl)Atp-o z|G+IDqy=e#@4Qw>wI1IMuztYj-vMA!R*e{P_$+b4Miyt|TA2$(R1wQSIzn2SI3f3E z`2N$VXyuaIIE2eLllsS<$4CK_dhTO9n|9$07${U&2u!i?_7iU#a$XO)+i?-e3qfuF zp{4w{%>*Uzaqfv62r;v%Q7LC*XUfx?c+RXK&algy6{s7;OyM08)?ZfUH@tIy{M>Pq z&;MoKU!Cc-Ab$g!baN>;NIQAm^Hb-3s`=p~;Z0MO%{=3NQ=u=KUz_ZNS=`r-Mo|i$ zGHS>P2mckEU!IZkOFhmJ6z~Et`{PID3B6#!5iePnm}J#arg;cP!Kl4WQZ`t&Q*N(b z@U~Uq6WcX`Stzf7wYd6mHb=J`Gg;k+taNc(okxvio^z{_jsO66W0vGp{M__QeiPIYk@5WsFx$AFp z7Z&C2#*FHFbn+`McI~J>eVO*tfzP;~hxv*6^fx?bSV!s0v3+WtiHq{Pcjk)^;~cn+ zyFL!#TmLlO<@Cx!Q>B3KMe*jpT{g*DK{@%PZv% zocz?9KR#9$zXk|sCU$lW>b|EkuJa`1(Y!la3s=SPtd3g?PaZ`^HO4p@8-N~1YvJDU z?dqAjsLEXKTEB!M)qM+tf(lTl{16-bl)JBDdi?VStH{9Eh?ri?9aqt~s6TdGbRAl> z!wrahB@6xus+#IHRg0Fc$`ani8g5Tdohhe5l0QK* z*uG3M{9z@g&kVOBvED)(V``ZMKu<}ON)ja2GYQizd8^@#DF^cr|7Vj>sRX~nqjVWu zs+1-@x5fT8k<{d}ndLy)nn{}#WvjPr+Er9f*tVj9cKvfp;>R;e0I>N85Ddf6+^Q!aG|sl`6ktSipDm|0ki4lqh$?-&CT158OA zEZu1rGBkQ1n%w|WhxVdJGHBp9AQ+t91<0)qlLi3+7&HeTB?4*+pzJ&5%{-{t>4um@ zcfN%y9E7Na_R8j|OO0BnSKmUPL6gHs3&+45Y2tDRC2FExeG~1A(}Eq8X0UG(Zv3Kg zjbIo-!=9u@LOL0LWX)3hb~rTPgIyG6N{kv76~irOY*X~=n_^!u0_U63G8P7#!LIB~ zbsB`V*L-T!EaN@bb3VgQ^AMwE6~nTt1k9b8$~O?WSlJvG?-t9k;izm*Nj55RzctFd zJj)u;t99SC`Wm-X)0nM;wZ3r_5iF_n{a|2A0Cyd6@XhUFj=!7vxwhuXhq(6W8n3^2k#j-%PiJLH zFN^i3%a^C8LQ}8F@c6rHGItKHc0wEEvbXdj&)h)PA&;AQ%{`8E-2h&aXqt#}ji|9v zf))_D`(L$-m&YwZm_pYM@(zq!t`{xr@mjlzs>Ifot&}*qYW^SUOo~_Q zN4`!*T5W4-8=%VQOsXwy+;&MWvtP6}qc4B{QpQW~z8SfG(wXIWR&T05)%ME{=G}$w z-pu9b(I$`gF>p=`bnDLC8BaOKcAAGN%chD|?>beKu?nE`#@yAK+xu%jDcuC-d>uO} zeVV0@RIJ;%#DR~t9J-Zf=*mR3ij|J1pvIshteIi8Sq4QUsAtf&nfAme)iwi^m6UVl z7L)O25@v8@Rsm^EDB3k^WrML1pv#&ra&- zP1Awn6O#d?9!}8e+;6y>nby@oIrEm6Mv?v2FBC{Kx3tf`IkI?FAoo2eiFS48ALojB z;`Z*(ACI*6Lmt4!ey7fPlYRiuw;iF!R`(yGxK;NFp2nOnP(b&qCLhsp^Ujx>(|DVK ze07@ryh9x1>{4`P&JcrzG+VVRf25YKXyuy9IpOru^fV%uO+Q07u}i*b9GlH3zduYHA$8yZcYO9cDyrkN%Hvd1-+Ud3 zt0%io-RcTr-CClnmUWQEZZA3JyzGJ*oRxipg%ihqrf@X&CHGjzEGypsVh%3KOK9#fDE17L`8-Zf@M>beXYHvOMj&AA0veWNHgt3 z;>@UTzP}+lZN86%MTqu!&x4#QR5#c`!w$e@|9n#sSb`I%sLyrKP7t($c$f@;)io=m z6ledV+fIs3((+(HOvq(iWXW)~6F(FdI~DWV!7K1|SA?lfcDd=hva!BPB=5ffp@H_w z>jEyny)L?(wsl}$W$V)ttMe+avoYu*d2e_pm5<~NRXz5|Ue22zH0wj+kn1rP_>-yC z=Ws`!V@W!MzBxA7Hk?_UYZR6mx$wvgc!YXqPCoLWMg`wB=&c(sT@U+=90h==xRERq~h%9@T0o(B?OtuAy3-r_E~&P@T~L9?uvWz zTsIGO0~Qc>|Glt-FNjo>`YSy5aDS;IHZCc z00c8@0RZM|3`NZqRVx0$L~hsj1&9{-%PVKsJ{DwjWr7VnH8b4CdDjj~F!38VW z*K22A7r&sht0!&gehS1{fwz9#GP|7lGp__m*v@I!?cM#BlrQxDu>S&g#+3}5Z&ld| z-BWe*V_Ro$To`>5?vOuV6ouhZ0!B5AEAXKgbOj}E3ew=t(7N{u{QgebqC?XYRPIQ@ zNeb^)tbThA zha{ctBp>nVqXCn83<2fC&Tq1K^l-c%Ku3q6&))~|E@A3@v7gv21DLq-`Oy^Sc0Fxj z>gR@~mD%Z!n1w(h436&MXHNJPuH;7+cTYV9;U@9x#a`#Zc<*pw*Un5+;X*E6Jc0AI z%p`q5ifHhXp#qX9?w-aqAt^U8xU}wR<2?n!i#72gy4%j@a+?t

    &|6bW^d>DEC91 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

    ow-mgd)(c2a}A)@KAa&}O*J2>DeE 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%0DM7rT{4i;xA~}g{wjLTk9x{#QU;Z<-t>C`tYd*3 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�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[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

    R3fIcEi81OV`CDs)+Xr(0L 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�@l3|S{KgPwXU(h9Pj;I559X>iQEIMg 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%0DsOcNKYQ(P~kbk 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

  • eVd-yzrqo1aYXCiHBBc2UG>0w7S3r(h zkP|?9d0RCpITj%_amGU90!_nudW$uLK4@to_Q;gjdDx*HU?MEN1!zJnNH-uOEyxfc z;TGgpAY)8^m`^;A=@ujnNQJV4Hqz9*mV%~I(a4{-01@}-*6JZ3B^Kl*rm`Tf0|~oV zPxU^KG82iLndk`YgI>1O;v3Lp-DjjSM$=g!AGv0}|vxj8uJrR9I+k z0#a!r_L;M1!dwdfhxL5IKoe>~W&jDZASpm1EC>#76%Grs6G)Z?xerK%1$hpL?<0Cm zUnlaI&QAr9^2c?WpMdy3p(D+%L0>$nr}6`G_;Ow90)UiTXnFw&E!FcG38ct_7~aK9 zAZeD~Nd%H-K{A1CwIIuZ_`j;>yaPz+L7l_z@tThOjrsgT&*wuRS=dfU z&&ufKlRyr4&}(`QNckIjK8;~rD?Esi${$Fi&OK%&t1X5|Kdj}vv$8?(hK(aiDAsZur`2VQW%mC6bK<|rqAO#khR3N2| zbecs#Dl7GTRs#t-p(A%Ql|`N(0CLcRJO!lKB8RU45x?m9yiFQQ>7M{8ve0}7B=k2U zl~L0(K>QmtkS%5)KG>fagzcza5C1YC{=PcWn#dJ8(jG{~mwL`YL_Bh6jVK zB|?@FIMFWUhfl|#@$3bSjEaltUVV>$32WL-_t2gOvehE1uK_8r(0o87NTuSw_ZaLf zC@~Q-@+D}BE&2Qeq|}1c^M|Zj5MLmUR)%bxZzpPN(3E>jp6#K=;lSD5|W)U zqS8c|>UyLK3o>YozUToYtGh}?nt?z{EXYV8WqnjCdqT#1IE+0?lT4lsr02ovNcS`^ zGMjU1)U2;w)@{hS*h^#N(<`q!61>%mc(N($ujdnmd>Xr;1uthwcTBF!eyykkL% zfcTrKNK*pju!ZIYARk+h*MU@6kPm=-X+gdPa@2yH0TN`EWxO+z7<0^|VND?(qS8dj zPs8i+-w4k*wGpX#wE<0uqLDub11T7(kM40m!ba&x91w>E$zm!CvK>f~1$huii3NEX zNSOtB2Z-;@N^g*%BS69|$O)#hAU-!hR>$b6S^z1tAnk#an+RKsul9$Tt;(|cg2pjU z&u1u*uo7Kb#set`(_3Q-5Z_69swf~?x9P}yAdbiMe3k(z_t5yTaIurA!u6b=08(K= z-UZ@6MW;CeB-B!i<3Nf$G<9Uo=YT{!qL<#V9eAFsbJ&82rS2VohzUB)Kp-V%O_f$R zWQ>}&C49C$7D-cD-PDJ+VaOD(J7|~k4^2&LD?gz9EI*oB9V_E(Eg#z)qtP@%rPUAM z7mt6Koal&5wMJ?22MJIM|7cIWEZllCn+zIPNNZBks z)kYvCu{yF3NLaj%JO`xc4juVBX=dxl2S6&#oK;^K^lOHA&r-Aq@4kc0_vxQI# z(hNwJ1-S-Dkp=0*R6UgyW=4I0L|Bj!K*}sgIFJep5)VZ5((_pWB-DcB0ZFqU8-SQ? zC~L73$U+Ov13E!difQ-t)ZrnFdBU`VT^CCHSPCQa}cE%aa-rlZ4EwVhd zsIBgdq7NH0MjTYqD@$q60lmCI)tyjtAVuqRq#ckT6H)DBl*RU0gPr^DS$X!nl3o=2 z`=hB$@ngd>K($M?PiVRtP55I|)h;!f>S0J4nr&vJGp6PeR3FsBcZX50+S-TNjss1E zqLJl90&!T7H0D$2$w$&G2U5OMM>aB_BGrbf#f;L~Vwcv#K75&0{ih_#+hYFs31r%( zB&xz}G3`gsN7Z8G3ssBxSTg~gYO!W!i#bvv@%Bk|6|@Jn@W0zr3yb`F%Y76yVTwk= zF9IpCAa5|AUDaE|$eFEy7i_Ctsx`{~fc#vrH5jQt-q)Em#Y?|Ed(=?1pMt|I#bFI@ z4Ca0Sjain2eq+6Mt9lWt7XaC?AkBbOsGMagKOp5MqGZD;ovraMs0`0UlHqf+7>d^6JWrf5g<9OAKYGKYacDow=Bxn64IOo4?37Gey^F`$X?)ct(p zD;zWhibm!f3#8oAVhe#d_UNs;9!Qx5DJHU4r+J?F?AMWZfE3}Sb8r0TTObwp>WB+S z=>0l!Wk=N1f^-H_@PJM;5QzVSIuZ`V@sN(p0a9|Gj^qRJHEW^z-DolP`($YTvDW@l z2YXEZeJyJCmkmL=YM0Up71>5#`FPHO)X9`=j51{-A!C-k=Dh!I)S^t)w3d;g>SfTd zUR5Zjc6r8ui1L@(q($jEUnOI;mE{@T6D>SP)fn9mljjmoU(}Y5=NvPGhCB}e!&X8y z2LCFaqfDL?qkC23*d8``*sxLKMwn#@`|zYFyu~X*A2n)GTZ^$bUqDT>6b;|6?3J7p z6_fR}E{Cs!rs63bIZUKfAxy`{1$HX0*W$q)9}mJw+#*(HKyDn3AM?OeWF1l zp7F>SGZt-;kG};822$qDISGT%k(yHZ#WfyVz}PYX;TWl`gFOlF!!peGrI#jhb__zd z72Z@HlCnW&s@WN{oZz6`EDNu!CLxh1I;d#K;b8FN`>f9M7$8L!WD1ezbeb3-Vb3ds zyUH_=SB1B9&)ct+UL-y#H6b!eM1-o+?eXc!v*5-BX-Jwx{B^{c>VRx$NV-JAOoX*a z20sq7ruKM)AzzaQZRlWF-Qh(@LeNB*PbO<>=0hY8NP(rr)&t2h5xgOr5Cyu>eyUzf zwF5LIW6eb`L5#Xi8mLViNQ5HSULwtFiiWwq0VK$ja3UW8DfwEJPUI+%%5Qb#BoN0x zR6h3fl$j|p&~0y+NOTk%RrsE|)-%5NtqQ69>-lL&qt2kQAkBgJTli^18Vk}9NO@g7 zpT0mMEcuKE5^6!F00}b@dsIr|T!^M4Smk4nnrR?&6+)h8BbB3_j-(N3t`MFX!fovi zGiRpC1x*Ex{Gk_T_?c^fl)a}TTY;2+tRuUC6n$nOhVOAd5Z})gVxOCo5fA0-U&kyR z-?0To`1>e?r9XjGL1z2NcMPMWgs(SM+}v5*D;s3#(=w#;H&Zd6av)h2}k5Pfq;~1jGGW3Q-DzW8<78`Gk8Ht3$90la? zO5|L0L`kMhg)vt-LZu>&A88JoG%O1=4hu~HX-uuoR6U4Pn5i5oF|*>+MAl)|&UPmb zaRuUdTp>&~0I9ML=*S2n2X$lub2i(@jzbTUFyehr>LVorG?gcGBoRoMrN1&HjpC4{ zFDEibrLrePAyyh6UEwWDBGFNm)ex8mQ+n;OMkw*<1=qCk^dM9H9Y~17Pff%=J0sZv zAuI6HX)XngxK2m>fP`6)PC&}c(%}^(aXM3OBCJI}(3D@V*YqYJzJ96}C|xeqhTfo; zg(K2MMW8}JBUhzGHw}@C&<-8JSz=Mx)u7SDB*S)>>4;pYuGA1m1~+8;2dPwQc4PQa z7)`c}d8oI=6;__G>7Ck&tWycpyQU}X`<0>H*eb@QW^JawYU>GAHb(s{pK8|D#PpVp zbD!dqW+kghh2lA^J8MCnEm;`(cxIXv%B!r6#zs8d^6o>`l>UQm~^hTg(dU;Nwk^2{{xvZ-fQg3~Kw zk}Rtyc8(LkS+bpL=h;qa22EK{B~j!xjxrytBPl=}CW80l5^$VWO1T%I!~^lgA#KLU zRlRJK&X%7DUfX$_0-yfs*68MKjkMUg@il@4nH;B*L!N-oE8l`Bo)wLct*rVW_{(|j zWAZ$7!X%t5qR%W9KSlli%t)~eepyR3x-U3VJQ6iX=Vum=>Qdtt{pFGHKf+JtpBlNf z@a*Adgvn28TB?|AnyQak8G%;^4?u5*j_4ka^+R9SVCrQJRi=d>( z*ZoiN9Aol~QDC3t=pN+d7hf@zib<`!0MF#>Db&lPFNo0q5@>5`DpZ6pgUk4Y?~Y5j9SYd|3CNkg6$@npe%b zb6i-(LFo;XXPd8?UVTv3^9m?bBRSusqyUMq&@2Yh(n7Nm zNQozBuTC)dVefo}YQXK)F4a3`S+%viM<Oq5sJl|TQ6&26^s_r!?ynd!bwOB1Qj+Eq?G2m%3j(6qH^+h!P&pR_#7pO@2lo6;zLQ{Z;&^vdUH6Yu419JD7bc z0^{kv-_VDrdyp?5g#@QU$yktHJY(L1^q$n%L_C(L;$JE~uSV&^YLp&cqx3_Ks+V5* zFO|NhM(GhXO6ML9Yu#_CQFk%Kqci_h%kQXBdU%b}6Ka&+q(HA)YyQ99Sy zt#$wZdV3r2xUTBn`y?1JjR6&0Fc5B4FeQMK=*u4oE?2hXFR)|9a!3fKqmgDLO+3;} zW=67P0#~$#hGL3JLkTqH6%g8R>w+$X;$A`#y@94}3Mx&DU+T6hH8h1>P^l>?4dwpU z{yJyPcHD<~`k;s4bN;jU{_nN++H0@rS5V6m-#C|Gbm+!%;{?&6^#J(+JpKpnMK4RY=u@6P;=b|3B z&=UKd5&PkYeLP}MBH0&PV!tC|m(@3|`9j3Ln#%6xl`jnO^C(-9nW3D^artr;|E4~3 zv@t$4d6a#Sl*`ZBycBRY|NWOm1$KPzl6j$#^pf>l>7^1E18m;zYj_D4O@A&;&w$s@ zh0-|vtY7Qr7qNbPl(O{Wlf7sDVs*Cq*?il7F8kIcZ$Fn@)})ZYaK%C7deXT^@4@I({jAUPkWIq|n-qsTPnn?EhBKGBo zeN$w0?JcqMQc11V%_k!EJ0tdTBzs3o?A1v2E24Ja9<}?nsNH*8Vjqv#+ava#h<#(k zKF|{T;fP&!-;{;-v`6gcqjn!^iG5SVelBYFN27MXGh(l{#NH9H%h%Vm?2kq43laNV zOYEm3_G+a06Ora0joN*_CH8F*`)VZnnuz^$B>O^3?Ds|NjY#&}Bla~<4Xxum?P5#p z_eAVN5ql$Ie=ySgQcLVh5&KNUellX0cm0!0R>Pd^%Pq0r9?$>2GCxe;{I?i`ego*sqA#+gf5T zN9-FT_H7Y+N2K}ome@~3?As&ufrz~tv3In@z8JBON9?yn>?;v_Z%gd=M(pK?eJ)~u zBw`?xJRP#{kCX~ zn`?=^KVp9@VsDFNmv0N9qKu!PZ;Ac#i2b36{ozRVM#R3*68oJIyPSM*a#_FHQ;1|= zh}wOzC3bmdx8mA-B4X!rTRP2_p2+5xT4G-tu`flMe<;%Ywn+2KEwT4T?2kt5>mu17 zh}c(JVsAw3n>UyNhDi3d zme?PP*iT063laPN$mZKyV!u0LKN7K5Bli0v**jWdzanB^iERFS)Z^rBY%5Xn9h$$lo1eV`@w?GgL=NcOc6`%)zPP)qD9(Yno@5&Nk~^Y=yTHr1Bc=Ofwo zMw&ko$$m1@{9H@y8zc6!k?gCH>?b14&$q-r7qM@PWZxgjJ|4-w&=UK}h`m2zzbRrr z5wS0}#C})AemG(ukJwK|>`N`N-xRU8MeG|R_Q#@jUv7#0Y{Y&?#C}i2UWoksN=xi* z5&Hv?&7X~Iejt*4wI%j}h<$A&`{j}Bk3{Ur?pDV4{So_`h`N`Nua9j0!H9h&VjqgEZn-7)o{0UCh&_pV+^Lk^op{-JkrOZeL{Pe;>Q4k^ zc3s_^XvIr`#La*I)hB|sLx6kXeE8#^2%7WSxX@`Ix3YAHZ=DOJar*i2MfBr$SbmJM z_nh)=dZ9YI(+GEZ-~0G!wyt>lxyXs2AlHv{DrT9-H%#mJ(>|N!EpZCzIptf>r`d9r zlW8uEv#3>XQ9lyG@ zvGW;(CfVm&Vt*iFpO4t@j@XwX_W73BPe<%?5&Inxdo^NTXo-C_Vm}?RKNzvkMD4!V z68lobetX1zSH#Ze2b##CbaHxCnEMcBlZ&!`*KU{XCrn#z^?1lb2?(*5NUp; zCH99Rc0MED#J(7@^XV9$#zj`Yf04+_N1pSc93OdR##0|Bcqx7iktfx$Qd}hRoblRt z{OGIaWGII)wdv14>v}2k6#J~}>|&l|6KO1k9zyL1Oc1=d_*1O z`jKM4xn~9&bM@&+t_ZWI zTg1LGV&5OhzSt7`oe}%qi2X>+9?8Dc68olz{cL3OtC7uDBb#4tiG6#-{z$}*`D;tq zvKXiV((~){V~5*>7%C2ry};HNb@J7F|M~I z_A4UU&qVBxMC{{{>;o;a&qVB3L^i)Y()?0n^FuAM-x0C*N9;F6?As$xTWyKG9I;;> zv3Er5w@0$iwZy(ZVt*`Z_qK@rv8dhWTVh{`*asrn3lV!Y()>b8>>DEX2O`Q4Z?BfyphDi2Jk?iHD-IrQo?}^yYMY2B{$vz*+zT6Ufd&IsRv7d|Bdn5Lhme`Ys zeKBIcKVn~qJnd>r>?b4k?NPfAMD4yIviandt&Hz&5&Kdk`$LiJk4Cb$wZy(IV!tn9 zUyj(%MeOY@vELrCZ;Ld)Khk^>X}+T+_7f3%PsF}AVm}}C_uiJ+=Ogysi2ZQHenlkv zKuhfRMC><3?B$64&WL@eCH6HD`@NCXJrG&leUa5wTVmf9u|FKKKNhhsM80mWCH5l` z`?^T;?UClUM^-oA68lXN``U>8@`!y?#J7FD{hE z>F3-<^y63Be~hyCG<=(0sLpQ1e#l$GG!9GJhJ8X^gTp*>W!4*K3Kr8nO38vhR&#zbBG? zwI%kUh<#(kzAa+k9-<#ozF5fwfj&@?1hN^ib(eD5&KP%=Bq8S?~mBqBKD0D``JkLxt7@1MeNIw=Fdg_ zeJSei^DVI-iP+mC*?S_{H$|FXXo>xB#J(Y7-xRU0iP#rgV(*FAAB{A>E@Cf4?Y`6! zdt1c*P{jUl)b7hsyDzuI-XF2AjWmCGB>TOQ>?e>h@)EMjku*xOoSZ;#l|MeL78?CT=-_LkVUN9;+| z?(3s=KN+!iw8TCTv9FKVuZY-JBlg~w*!M>4>mv5{i2Z?xeV`@wj)?ty)b48|_QMhT zP)qC^BKETp`)Xu$=ObTNZHawN#Qs3Uel}v~L&3hkyE&{pt@C)N;QSmvEyvICGhEJZ z%y}u$ck|zW_46s~y<8VLC3wHr#^cX(d(MP%FxsX+e@gHvJkj%b`tfu8AEWF&`@KCs zzFeEP`9ApgX|^`J{anIgW7A(G*N-&Iek9sWUhwNJeoozUuU}p9$d+ol=IJc+ITz8q zx6HI0Z(k0;6KWdB{{h zgkdrj%>4bAd99H~rB>(5&cP1F+ca@Gxy~W7^)~g|$kq9)CiC?PUnO6krOo~eQ!j7l zD?+NEtN1)^r99P;JU{%QoYRxPKSLX(tu9wGE?@ZVOp-6Bh5Og8cF^&Amk!NlKfjhjHF#7$qzNsGm<>{n$Yf2PUlGS)D#h}ElKjs z6fs>|LWYZD$zLm^K3Re5{#;gy zOFELIrjVzCyg?z)j*u6E{Gv*8CCHl&yl*>QER4TzNd zLDF2NklzLQ$$+?AJ(mYWa($9CFHp#5L0+VgKLvT2LjDruDuw(VNRLAP3FKOZ{0m60 zLVf_UTOpS*%Iyz`tMlgJW@O7)GqSbXjBJ|#A!8s9t28p2e@h{AAmx5?8w&nw?Wn_8} zqmT+nP9bjqnN`SJLEfm4cY*wpLf#K@QX#(!Qr?->^Y4SqDddkqZV!l9=EQX8mXpoM z=65tBUGHo{u1W4}LOMI%*Mw|M?ruW1B_D4>Iy-;A8R_|K6Vj9XQ4_Ky`ST`ZbMoaT zq_g|)nvm|~t4&B}@^BNCZs2sYeF_B^G(Q>WT6S!nk+UU+mfXw7lXnJ0xZX%P?^VcKLE3kFxf)KcW~3{*BBYUW-b1dd z6!KdjT?$zQ=?O@~$(}*P5@?HSLmDahf0JvcLOvfMUjo@1(%3q8M@UaH*py~-^4fq1 z*Ez}=QOLJJuH56bF;O39o3OA-m{b;F*jpYI&>}!#| z8juMohq7w{ku)1fb6g=W0y!BFldHRsMe5_+C&@e0H1%=jKS}bg6fv4FB=6A(vi^S> z*;+_Glp^)<%~H5No4BK}D z0&#LR+E};Ox0fK-fc#BB8m$u&x@4u!~U{S^T*T(n^Zac$b4rg3e$Cq<-&wDYSpLYrQ%5!&>| z6mf0(x-4SabSOonWZJZ#5!&>YfQVdgK#Dg7#7KdrQ$*7I5@~*^DNT~RHAP&z|9U_q z*RPW6&VZPbsbh*rn%^MJ`*a%m@Id;gJaWUW8o2O45^5u5}UeERc07%?m)Dp^!}= z8x*nyq+KC9K%PJ)({@jFRUCgqx&6L4Tx>H%ie5d^wWlZ6HGmxf7(IkpCGW z_kxsEnm+(3E93!?hC;psa$F&2LEfa0uY;^y=WAFq<3%y~sz$ns$u~68T})Or(o;C^}-z}IMm_2(TL zVI_H=M!JWSgBsa9oZO%hR-0d|kk@dMgoNg+?B8w?Ei_Ntkntur~)gmfi0HzD20 zP!qB_8Ery(l3SaQEy=MABEueIb3mkq&!9fPppfTF4X^h#yww;`S8=cj=`P;fg!B}L z0wN{9jB*+Z*#dIhntYD;g2>U-NT<~ zLV89%)r=HA8xWDJ4=MgaA=iQ2ddO>Rx-!EIwKKUbiwsvmP6R~CxtUz=4v5XwmE4_0 z$kmm6G>e$XOk=@jBRp);ISqbdI^Iectg(L((Cs3!;#@=GNDl>S+ zbvbFqH)Ppg4ASPCQX|=VQX`}0_0SXRPrB?G)jjzf(&i*wkm0=lE#d}qOsg` zwLDS;-jUVM8%Q(1HJj_bk}H&xD-KtO^GB05m8#>y6q-zL9kB$jT*&PqRdtYGBVvnu#iF)Y&v=NYk#^zX387+ADV~U#^TCO*&MX z?~%rzk+wQ~Dm$(nZ^+92Y!Ls9yiL;yaypbOI_w2m-ICSMYe43Lgp@Pap8EnxqpbI8kO7tJ<$|a*yFl(&)_V|SNacDhNHrii7HVsyMsY4h>cxC*WPEn+ zZ(f|~xnty-S4acIpV_vuzYSzTrFl1qe`?;Q`ClOI-^iBy8IYya!Y7UvN;O(}hqt=i zWM#B6Mq3067tNm`*PQZx-vn6I8XASyV5`35t|bZOPY3E>)kO2a!LT!=;%3IjQXD1jxM#SpeCutmPvh9pBGt?Ds)> z6>>j_{VGkn;k;;lq-Pp*$TOE@8)hNml)@qZLWXODj#!I?D zn(d0~lfo6eL~g7wE2RzujhXSQQA~zXq$a0Z=ohNwKc<`xCHr52^r$-jJ;(=?4!;Ys zpe*4@?CL+L+Vq(q3##4aw8Gsg&32HX?{_)t%^jO1I;4gHk-NR5nN!FSkRz&f#snnD&F`ih<(z(9j@Fovxy?sqNMo0l1m}q0~reAMXpvn zR>JD-cS5Bc`MY!nb>3_xu!x+wkiS%}PLR1!axPb{RT|}_YQ7HO%lSFd%!f3RU(Qnu z7;BNz%}6~%4MTk-&GnM&SF>&LI*_W056d9(cM1R58r}xtpBfX(JX$If^Ize9w`tx@ zn%>ZtbEDNMIVd~N#wKR(%K0tQ%qy->fVBU7HtPPoq%o^=B57`H3K`H?C?|KEQ*q1) zAN$Abxbr1)?G1e}S1&fENw%oG&EJw{F_a^vJ`6Gt>MY2kAWI=lj=4=^wpv_yRyN*v z!cHVr@#-@{meX9-sYac$>{rM|3i*2xX@(S6C&-E#3;IBAS6<>qNt2d5J;}_Iv02Gp zB8`9E;Zno(W{{x}X9^@|Nj9pIKLg_5(`9r01&Dvf&?0i0!@q;eBA52DCalVNnjkQs zd?)G8fUJf(3;WAKPF~^TXF>LWB=61I#;ZY2s5C<$bIN*;f-EZbV<7V(O>Vk~U1BW( zk-ImMrcH7EDoC&D?;is3Z{V?#ei9@Jb0R6{4<(oKhhG3$QW24y0a*-VQ?6R6%h0%} z>hm4aw12?Mo@41^IA5OW2#9d~fHWtAJqxm~AFiMDdd`j38%!^fg`GZ%lQb_NO|L5F zN|373*vmog2zoZNNLFs;TTvpnm3@!o3bN;BYDKZ!h>F2kE#rJFk2lh=1#Xm0||u zfhT4qeJ4n-s^J32oZ|W@$kNYbS0O$ti0W~F2GXY5;_pC~pKLX1*}nyHr{a1HWIk{i z>y>VxTKOk9Jz>9vEw+)HwLOLIW!lP?yq+}6O0I5@1r?LXX_uAImvaoA5{%9%J>Ni@ z4rR}IkTzB4S&*t4o8AU8ugZBZ$bv$CTgrKh@26rLp9Jx5thG{n5k&rQ6wVI+9>l*7 z)~0zBWKOX^g)<-vL5Gt6`5^v1z&2MW$f8Q~3Q40{a36^OHj~YDGe{EJG9DF5?% z(kv=Te+6WSRp2yQejkW`Zz|=Cl}nSOmE`Ua`{hh+lB74(N7#RtT#1TcPlG(D?B@$0 z%b|vn>nk8X#lN=Bf;=DY@j3iVEYmmRc2U)#zi?^soX@bdCvaGz;H%T+!pS7PyLE4q?UBh__WX;T*o(Zz7 z(!2nq-Mx#_viE?j9{220!gU~3<)3c`x%^4lI^PPy^eZF9n?c%@55EIsMM)uNWENDv z_&CTprJv78u8qD|N`3wm>(qf#QtylS0Gi8YefXC-X|Sqff) zUz3-D%%|nBhFzQ-OIB5ce=TV`f<@)nl#=#J-r!5d+nBY218H6T(>nKY{eQK?0}31oe!p``g0kfbd;PkA3mLvft~ z={=OSvEKvf2sIR+ATx~HLwqPD-%pwip$`i31(5l`p2IuRQIeI=7P+IvSs5yy%70>m z)(-!MTMNXH$b_xwz${;+D( z50mC^6mlA5Rr!tkrQ`$IlK%o^j`JdE4ZjAmtfHp#APXp>QkuX~;3Qc{#a+HcC{ng%(K2c!a& zl^d>Bg}qJ132%{H%2wY6vYPt3k#V!~zoJ$YKR}v!#r{!{Q>uoa0=ZYs5dRFMUG2jB zEy#kJQ$Hez(tN@xo*~sMp8?Vv`c7_wZTzFuC$Q&c*yUt?`e0zsO^g#r6%&~Wq$L5r&4>m`^KYu0S&%v9A>S(H zC~dq8q+QKw-w(2&^!#yxaWp^ zzsQvfrD?I2;GZSUvq`gXMYb2b0Ay8_d=*H0@Dh@12Z;QovETI|_deNb-TH(aNJoe+ zm^Ycd?76^>M=Ikb^66TolvpK~|C)>~=dDssV8mF7Dj?W*K8#5Ds-htC8l zhdK-U&q$iUE=V`Xkjf?T(VUXvm69viv*gNyvip#2obEH}R(`+lxgRCgz zeNyssLMzKiEghA=)WYv2P3l)=Me(>KSoCcwrxEf6w5nz||3`9>%-WA+kkf6eiv29e zVz8gwtX(`^N|EV_ymYyTLNCZM>Pf1$z%C{KU&?7$o?p(y-5q+9q+*4+TwbUJHl8X#4%Mc=2C}TY--kfjRXLvo z*%YM6&Dh?(9D28u{5dI^f72TN|5A=x;XDVjptSlO$)&h{2r{7byzbScQ5N+aL4NAx znf7`i$cn1Zl^}A8E3MBfKo%AIL69Ydu#L@;j_lgl!+(8YjA znk}TcU6p)2NW1c)uM{{t;wB_4j`PNy6wLX)b*Y zzXxRb6QNBxa9gX;bCFo|NDLq&BNKrEWrrUm*Q&CX{{`|AlS6XJ-yeXiq$THylLfbG zO$DT66VDftMb$61p^_dwcGZH$hTEA=98obVRTnG-qHIU_4?sa#KaExVjb zs~bQDRR4MzNbjz!?AL(ED<{%6-38Ld?pj*%jUbzX4oxew2D^~fhc%)xw!rRFHeVpu z+=JPYYas1GE(%QEBwRtyg1k*~-PfO~&u@bCs5bo_ka?Bn_dp(2vfmG~q$0+@kX*`V zehp+nmGfPYj^Lv>`Cw-BLjjQ*{!r2=DcX+UHx$>;fZVhptHUcn_Np3Q3vyqWLFefG za*BLm`>u@adr7mX*at!80wSYBCv{p>xpJhLSAOhP5Hy|f*uM-y1s#{{1?;YjjrIn) z98wwxh?H=rDaX&>1^J&KON#w8$RlAMCu#l&WFspKDBoBW-Ug&Yt27JQG3sWFN>H zRr0GrJ`yZESHHE^AYHGTqYaT}WhUE#HIQnMLQ1|3i~KvtSykt! z{5&g1X?^m;6;a1huuLguJ!ziBzhp%7^7qpqtB>x_AXf|0Z-2LGc7n_)jlBkBQ_zoD zr)5TVI`kbW`4-YF2e||}4$`iC%UeO_RmtxHN&YQcpAUdMtgQEwAafxi$~Eko@POLi z`8;V}N>L(#jJZX5>u1uYO8ydQ{$0gUUkB+>Yq^)Q;XI`5@TnkeECZ)H+yJtmVz$j7 z9bwi_6_Q<&MoIc=kVSxQ=9N~rgA6DOUq|O!es;E;8%WcxVw+n)mQ|gnK~@4HGlh|31zu6)<0z@m3DT@8 z_IH6Ks=eMX2s>h_&HpaQoU+XOK+XrhksECkWl}w${NbOHW?8lSS3ug8R?mYh1WS+_ z{s%}k>|hG=bc|y$w6Y-22boi8UIMZ%^e;)nL;OjH>M6SfQN8jOklRA*6c+i9cbtH%C`msEatXh2dS$VsaX@OWSLla@thyZh$N(*-wDnu_jx?cY<85`p)}79#)e69>`qqTDei&jjYNl z+xP-$78TbSkgA$H{1b@$r566gBC@Nt*Z`u_bbz!gOSl$fId~*Vy&Gf(Rak9^C2$~# z$zRqV4w2^ekVbM%fOM#m{|88~Lf#It@WiafJ_<6wCX0Ly0c38R#w^!#j)yOnKh1X=lPDA_#O zPCTaca}{aU2Ptv|yMwSAatYV9q^W+vmm|ntkO8H!n?cU-i)#yxLXDRi^*NPG4uTD- z)#f_Ll8HQh-+430$4-AVaF0OUGn150cs~`lLPdQ>o8$NHbr!A)#=i5uzB71%+$@NmM*G z0J7#uSsUYJ*vZlsDWjeL>=VQ@$$90qYNQeWlXCq6$Q?@3J3$u4eSOSx&@{$kK**ka zfHWN)A!=dps*-(?H2#YQ($egMfDD8-l|9xO&?PnQ{1s`IIcbsl`G-MHJuxfk z6UNb)viYZh=rd*=AaklduK-EZjAJi|{~Cy`;m?E2t6UQxtICty2C{h5tDO#Wx7N+< zZ$VkzFO%jGrPU9DtXHGn$E4)LSxNr@q_UIwxpxF{jH24qpyXFo`XibaPc%{5+%oV*u;lSRGc zPUV^;%{ImLHV}CXJGIPr3BsR5PPTPE1hS&)^HD*L__mPLp9NV`HT)vT0~Cu1xpMv< zWGKvPCD*q>IAD@t|GuPA8vBV`ND%yn+xU$TbfGh=s6{@54{B-f1VHH$z?Ig|F zU{N`{z?rlwKYu-GR+U_@1xdn_q*6`^#DCe@>gSChmj`x9a}wnH$^+a5vKplLUG8$Z zvB{}iab~1w))DD6Hd_CbRc9mL?B0L7X42 zMZj}6uREeZQX%os_SHbegb$8}k`d_Gl{AjCSGaf2(@^<&Z-GiL}Ph=m) zuHGEKsv~p9RGXSy)oJUvtEZ#CmOmD5`s4(KNVls{a;mXqJ1DKCPh$l3{Q1IwJ=SwL zKU}7uLxeqhSWkB-Hpt^8_52t=O>}qV>Ih)om&5DG>qqyE4o=nhMNDdVwo&Zq;5Dk& z!emf4ZCAu<2dl-AQod{@@2iySNp2sO**8^hR3^BWuhdB5fm$)!*4$>zfLqChJ=Y5( z6NTKZQ*vXo^^F%tj=oBcW9Q`my9(U}^HT;N%^xlDNJ6pZI#`k$#FqB&JFqLrYMR5A zf=TT-TscaNYMvUm)|_zSdy*E*8tM&`wo-#;U&NYEeRqYfRig?D-I*Ub>fy$o9T{S3 za^sG}yAFk#0PH+CIM^8g)4G|Kllx55#%;fYU8C9KMXPhvG9bqj@gl6ZP%Tr^b+j`_ zfOvSD1GAuVC7%PzUXGW>#!W}B@j|F_i6bi^gZ&B9ba^UeB2sykl3mpiLqI3YmMG6P z8PAQ0ADia&I3D8KdVrDINWlWNK08ut*h8bn&1lFNpGiXad8_HOq^;H~?4Ov0 zP+5AB3fkwS%Bd@)kL7acVY1;YoD-FZP|Y{SrLWbCWeO-3hAT9rFMuP-`Ziy!8js97 znynAId4M=Dx1-Fioiq=k7ipW)B+rB<%qgnHe8c#@8Fe>{m1SzuwRwvKkkiFuwusTv zOx?7Ym5D+pij!zsYA6b*R7;cMN@*KT8M#cx(aTBb+=z6J{1lIpV7x4qGc3rzRqnYN zsZ?jZu8!fZi*oL`&I4mft^h*=7iAS`?|d#P)Ba+RB0SP=7AhG3Dfdztdq+Fae#6BY zdbUZ8NcKl#DifuGn9gwCBq6;iScW#R z+=7#tzzj`p5lxrp#K~%3@)dBg4e1IayaWkNgvy(y*?}&zO+12287uPtD1o-J%}gs9 zsl4rQKUGCqTFwnCAhdC99G5FbLLf<7<_p$R<>3lw6VL$y9lKuIq$&qmag+k@nK&>*;D-!lsvM_aJJjI#2ff<8E zihQj&QL5FXVo*$%ipNagP|ni;cGRd#@W4aC6ZuK;5Awz)bKA(5Xc+lHq~l#%gaJMR zphnZYabP@Ox4%`SVB#F!og%|bWo9;CXTYGn%^SLG*Y8qy#^^akUZ>E?h`hUi8p?E7 z48qirGo9jA%IH^AVA5p)!L2)^Im{2XtRj`2EY36xByMV=AVHMCN{3M-O#vS9U zcr&fEo%s!g@m$e3f>`t6g4c}H@x zJXJJyW5l3@k#c^bI?m8Ru@%W?vKJfU6?hNtx~XqR-`-vQ`wpQK+GVUPKaW)=h08;( zSPP9&lNt8}l(8h9X5p}_6>qXopTd8eI}CtVstAtA{13Uf#t>ZF3+f@0i*m!glbj4j z7+0!vE9rwwNNnfe9UGhr$PjZZO_ZuKYj7m8re04V$Es+_$I?DC#ugJDiT*OihKsu*<|&WP(ETSnJB&Rd;zXX82~1OYj7tRf zx{~f{?n;vcaq{^@#B2hP*kKHSxSbZ0H z)PcO>B1UT!v0dL0IRJr!bfCSKj?QQ=xOA&bS{WMsXk-6n|G7}C+5T#VAq!Bs@pSN% z0i`Ar8u@=549yVe&FBMW1{b4h5ntNYX<2R&qF&+b7RO(F?BolW&P({_@64=^fNPY> z1E)Pg3KQ+pQRETGadBK}yJre;t_=22X48OZ{HYl`>jX=a=Bn$e?o0+5lqEN=h^ENu z%nbXPR>&&fc>LKB#u74>E641HH^EWSgf&Pm8Es3aSH^}WnC(xCbHTL~OK!I5@~g_& z6XjAjJ8;O!Y`J5Us7a`3qD*^f9H6~4ZU=3`BE&X83dAWiRwD*B(Nl_H-g%4F@&&F< z_Y{pvK?o}H$aT{|=6-SGndMbCE`f=u?Vw}j7|Zteq=G=kyVS4RoN1s!h1V_7xou=A zgNweGqNHLb7V?SQTmGsILIQ>X^C*|RRgbN1>4YUlG4wb#JA=65j)9BEX57fGO7x1f z^-k|pBC8)8uBH*N4`3aF5ENoVRbyMyE1M9LMk4GY>m2f{8Pq4ojJfzmk*MMruAPJW zj4Ig_a&6fpW}wNW@ubeudX|&^?5jFNv5btEnOiyQXa@$dlCU;| zGF+-r0#cEKskgDI93v{HHB5*{4cry!hV&$kE+W(HB$H?tA#&X1LE!(&dfDy9$27D5Z84%!_~xL;8y!?1jN!n}OeEb@Q-X zV~nWG%^X1kB6ptR|6n$0#N_9~64 zfa9{X<6GGVGqmB14BR+(3K5SaGRSD2y&W$(4f-ho6Sp+mNUkv2zwecmS>|^mM{||J zC~_I>fUId{0Tu|2$Fo?u+TTAoP-9+E!wUNQ3&&Vp<~!3l`C-7$l9?5SD`tR48F~6Lm~Y(#+mhaKn^$W48*>69H{9Qk!R~W2-9m9XKf(RtJVffa%gmkqHwT>fa}eYQD;5sf4CuPw!faXUwQGW8XRgOBF-h6_A9E|F zS!Z%>Jm6HLQIVM>a>`p8?3JXTxet@sS~55N%%aSz*oN)Iz*O(pc+t$EZKX`L&6;0v zn#OC4m+Bm=Gu7tbQPu#7=OOaeV)~3x$Y|N@mKf(tzslF^tO<+}Efh^#q)Nm;vgShb zq)=tj#ThBY9Epq)@6el%){m7MZh->#F5}VoF)6~|&~aU>2qKZgu?u7~)|5#)!9##! zCRjK&k(-_LSK>gbY|%8#SZ#N&c(2hIb49xVP%2`vLEO!<8qHZ}nkMVK z#3xgfMMNjIfGBqLZP<*ga*cYa0*h!2EOm)SUCRTS7K>q;rU{faHmp$ zn+o-tJ{C9&=-_xoW>sj8I;8g!6dUa%xf@KhoRR9nVjB6TN(Crv`I%0Ngl4(HcnzZz zNiC}~21)2Wc{br_Oj(^bMu?{=vLYt&4zPq5;hs-rpmtoE@jVQJ;aVC^e4T4ES)+DK zFGjE7C!U{D`ECNqISwu5dQG-H5lmoY4u<_LkIqiIgzhZIsf#(g`#Cjb6n-Cwep56qT{RHHjlC z%31)mo~k;D#CkIABer82-_FF0ue6ucj**Va*nMqN3EvE+AEZ`dZe_SeJ{cdJG1{q{ zyRrV=QQ4ip;xx+(WU=YoPxdBL5AR#-55871yRQ;zi2CI@DA_HttJv=Cn11o;=y8TZ z;WHC5pG`~xPnPDDLvVI2M%KmX@yD5R$lLqO1l6rw%CfqfE!L;lytgZwOaR>#iz9Rs zxXh_BH|3*;Fp?G6C-C)@YDCu5nxzzY(mV4efb>=xDAZciYvslexWQw&>E)RG zYuC}urCnlkI-~C~qjfo{jfFG7QK>?Y1Z+|_vq#4?7cH1ld10AU^QaV$AT*jpSmst% zUEQUXrF{Gtt6fNjBcO)d@=TN6j^H}|;b_6VB~O;nL`I2lxGc^TN8Hv2cQld2*c8M~ zdL^4Rc8NxEuwx^~2V`@kKoH&TbHC7$%orDbHfG>{G;TWlLNITu z!MHh5l}VoY$=yx?5}am^&d3 zTh>9BMwkdTm5)%b`1A)x6Gg9n$y7PTBaNg#QJ8oMwu?h8Gb)l!Rh-F>H0rYx!=j^u zgZ;Ta^gAj0b8>?p++P{nZD!i;emB-CaX*@J$bbwoOnAk$n-c7P+^dS%yximB@eutS zLMi7RWJeBEDYl5cW&^RE$4VS|5a|M?yi3nG@||f@NEamDx9fVcYDzSog=DTW$?QWGbZEk( zvo3b9yN4b(yLA3Wf}S#4OzK`XnG_(~9ttpljzav6v=a=n;mLES3=1ayG_5C8ZvQI1 z48KT@VS-*?5Sr&SyfHzULb38qNQy(o$8#?pSFB!CYkY*v26Fc2v9f6_5>HJ^^7P)` zp)wR?`wXTdyBoQ}lsvjlE0}lA;cM2Y*Q!OXR53f2fpRb$XHlei#=z1n%Y zO3Fyji4DqAXrVG?4vT4YxMpMC49ak9EI<_?L54MeOiI&Zt^drRlJo)<^Yh%aQWEGG z_hS}Y6`g4>`=cl(%@Zi&Jp9D4FJ~Ld$48lKrU8W9r*{YXdk)L~C38E{P8524D{|@D zP`3AFr+{$fxEy(~ewxsc2ms@%${vIbLnLLnB5Nf_t1^ADs6>3j1Q4=@?TREuM1OYT zGd^V=_LznKR&z}hBom_SwG>rlDFIW)W@UxMt{}=rn7s0pA2>lYL(Q03xhveY{4AeK z;pgn)uqh1#l&w{Mf=FtB4$U5gm`a6)@da2lTbKYEq32ItYO7SuU$xI08_yTz%bcrXHA1a zT-p&0B7|I_Lw5y6`#6j%Y=HDE@W^4023r@NSEo$&RljSXx6OXn9chwJ&C$;rS*iOW%dIX(m?8Nkdu=H?s0jtXYT0UnLDVY z8hp^&937BXTJWwmf(2rCS^;w{O?KvO4ea59fDT)9!ouR>T}k0`#8gRcJJZ4@Y_^8Y z<_-{;8klQh2hM)Wm|{vBvDcuTDaulw=vNYD3T_yMPS?jfJHnM!t6*Ij8O&>)q zlS{%?m(503au`<*BWQIPR}LdbcgW$czHUpSK;|aRW7Ob(@ip(x6rWxj zJvArI)+)V*FU@DP>htkSn#}0Y|6)|>Z+uNsof!Q#|7_&Apqe*lMA(wK-kQ1ImbTD@ z>k!uTjWrqNr}tf%#KQ^AoBl+R*1gwl4=}FYUHi&)))TvZZ<5$84k^VYGpjtZqu}qe zWlTul@IPbE6yq32Ga5ZeN=pGK^%3<^$hjC>w5g2FaD{6l>AZ_Xt(rJ|^bG#o_Aly3Dc67$TDr?je<(o79)6ZwjI1s{1FpN;8m=~nD`EimE2EY4)tWKfPAS@6iWu%nF!#Q50o|p^cB{`P zRSP#{aMx0bzhnV}AH*m-lk~bPbKT>v>*f5gNh76(8#2qa$>4u5H@5%CZ{3*!%(YLK z{lT#KAF`C2CAa?pr;D%P8|$T#zmkuzI}qnhtj`lpX17AZ-5UGUa+WeznyBV-yNQ%{ z%OTa>1gkq_tIXo=BZ}_MKAviJXxL9-^F|WxxnW;_Zh#kz%6qn6&60L;rhAlCcU!<7 z^PRQ>95SlS4l+fZs>_pzb(YrH#+J#dnOEd;hiCV<1DrEp{x9bl`sA@j_w1%=CfW9~6ZJv%9nH=v zPuET44>2)K8?8^y2ilcU5q$7f`}XfYaIk+Da>(N`b^sK;?q=U(e~E>b+N^y(wEytI zLqY4vc#xnM!|B^UNE`R3yUdoFeNx-E%$S|qN1A;$Q9l~!lLzto{7Qf3$3a;D<5Y{R zVq%oGM_#aq0e{}bPJv`yo|%eSNU<$#zsj7uu#wqJa4SRK%2@`O zkp{>LYGh!B&-#Y52D8k}EY81Z+S#SNgvnbwOY_W7&Guz4^K91#iVgaOtTpbM*wT%1^;2(tvjn{ zlh|%)9fwf_&O_$&vh!#cC^JTqIXiG86~*l7XQY&gGt90<250LB=)HIhgy(zDOo@=h1zZLY4H|j6T+t6SMO&%pfYyADj;LFn2Hs2 zKg)bOdWl2KE52>pnP`z-g$2-&`|w=5&0$PiD9)?DJl4l+Q}*>srE%JgQS%Uk{hjUj z8}p?G51t;7N0k{X4!ScXU1HYd((pumdIUY>S=BbSl9PRF`C*KiJ!=nH!`Q(>gf@H{ z&iDt^BKdFp@idqvJs67t>CyP7+G0>Vr$Smy(f;KVjq&=v_1L?zj$K%9zSQE zhd4&Vl1kJ}W^+l_LNNvU9LvL40>dM_XPjl6$r`;?jJ$O$?bhgUA3aK3uk|*wZYj(=K zXjPl0YPN_N*CAr7uelpoUrt}JsYfyg?|Gm;TQymss!bP-?N8)y;lX`*4$B@Tlr0Jz zocw0$t=xK!ZHPv0rkwU2>F;r;HzUJ!93md2p6Q0ojzS?=&@tCLsIPo}+paK*Q*-YS zNOxN|qiLO|Al>-UdV@uF)^<2|YY&{#XS~_k(b5Q2a_=d2t!&-F zAj?2imW&9cq<7N+2W7|pfb4kj043W|eP*xUbY|L)$2m$R2}!UKEYZZac0{y>B(`Zz zen?H|1{5fT9LVEZW^jhK=@{hji%mmNumL&zOK4*BTHyT zIpUxaPd3@&rAx?hT3Pfarr0amu+QP|=JCMa{G(y$inAclAL3+K8ZG#qr!~;P>u2An0!Up=*=8{F>aVqiQp~c zPh^0SNX#va+p`x=Po)aW;^sML6GIAPHrhi=H2PH8g=5+Y?yhjwRb<>*YV0gGdb=?d zI}@{h+eFrw9C3$xCSnFvn-fMhKp-&j0|y<(*2oO>QxeXKlP0~m=hRKh;O=%FLwflr zjXgEw#Eix?LN4hkVtI1#uvnm7-P0DCQ_Y;RlD7`vZ{))+-YOZ@Slb7bM+vZhc@>7G zwlsEhGXedMUU7*1#Zfz~4X~SQP0FUv^!*zq{W;dX6**FCg5P0|w;Fu}FBG)NAY;q0 zUsKLHLF06~`}fPKSmvlc;SJ{DY8Oa|@m^$#vg^A3G$62U0+)1vJz`D}8((1pKKl+r zCHyWqJZ5DaWS?QA;YTPL7C9bSlCyQhDD?i|jIpt5W|**YNr+UCcS1_Q6OPgw3)*Q; zkNW1At>z~=UWuo`iTG(tSAUXoeU4Liwm#PSSPZXJ8sj%$A(ja7@Lhykyk4UsZ=O%% zTz}#s3~!<~Be{D=y-*JDsEYMlY&o$OP%{s$+e_QQ>qi8;FnH?{X8edwt{2gWuz1}X}W zNpR7qgOSQ3?y(6omBVvbPveeGF=R0F<*7;8_oGuiZfIb~&1!1ZfxoX@q6rRRF+y*9 zQpT8uk1^y>CpouI5XUZ^siPmicGhSGF-#i7PT9K{MKUfAd2C!DPagVIIvkd`BcpA-|W=Q071mBxNU&36EZWP&N1^6UZyFVj32G9$lrN}gRdUc--HKGvpx z*f5S-*ips=du}pxb6BguRhv^Z;*?A`ex-X5#TbEAu$?oYWu~u>GbHY-XWXCZ#{;}X zKJ;!Ay!tBg@`ZBQjoGIR~Qp$whPULt#;_6?nMZ+O^wZYd1TbI zg*3f{m*&YV7TQgKOj#U+lXF!4=3JJsITNti*@2!|=w$~9pWM<%W>9u-U^I^ou)HM? zqS?k|E0rNN^cHy?ko}=~3B{<%zHDET?_^qxncAfen*+x*RmA{g43#xNn$m1OAfZ{= zaPgSz7n{P|Nnn4A(1VhGs=AL4W1G6W2N#_!(Cg5)d6bsDaB)Xu_05z91niYZ4>MT8 z3#k=f!s9e%%63>fsR?U&2-0mF$WsBZTyznSwPt2)@(3IHpaprM(&PE$?0nEPn|W~=fJZl}NOf(?WOKXNV(As=`BEd1u3pLI9xh`%A> zSb(g&WE=&V%-TnTafjzMimWg7m^V?lXe%4#o1vY$gy%ZO!up1ZluYB9X^HqV**`X3 zRNNF*--RdfV=ol)=BLoTYzvxMt$9GvE5W|j&}k%&G{)pn4_p+JPccp7Yl%T}WiMA}&Th>;|P-uVGzg`4XN%H*5YY?)41g(Bhs&Bc*@BOm+TpAc^-y0m*&N*?=Y|V zvChv7u@We_-s=}<%-Q~ef4D_fh3#?xSR3rmX~7KH77G7+%S1`(md;C`I#=sYg=py zgJx=tWG?)@p?L_TI?O8h77?2X^dvm_`A8bFgFMDim{#=cDWXrf0Gaf~!aZRRr@yaR-j zM>qrYpUEpRm9tH+6Z_WXoH$wDOqAIH=9P}}_7xUFnd3H8 zJzJP}GVzhRtc*3rMO4Ar?ynx5`1|^dzyJjivA9_j@0oz}2z;^Ov z0?U2$hB2197^LkfDQB{_*JYz6+llBGnfZWSLC2jDm{84QW~a=&ccAH^!%!(%-MWr> z9uqGN(CkPtbTbon=j=nsMe_zz^+sK=D>Bx?kB2Vh^62Rt{TvzSmMoo8wTnidJc2w{ z95j)!H8%Im5W=EFJ--#KDJZcjlLzih+gn+A(8ey!T-asw^Ul)oL$WYK>zclAp6jPi zhDSd`Ic7?1dVW6#Kx&m)+xumV39djQFB2F%jw>~qHamDUm3yGm5>P~D?qr(9DtM;b zK85KXy2Xw=b~rnBZfLR)noB%kbC0pjCaY=kEV^ww%SrG#B5&iNg=!6~hRu;-mP@Q( zMns+%kohbfc89!VNgiCV=HQ||uQM5;nBL1cG0Xl2HFag0buN*4R(3vZV3A#6req1I z_Q|tR=EW-jJL!D|OBHSL*lLSwarNrQt2BzDb^AcFoGE4PN#3sDWA^&2JgFit7BOPl z#UWb|M#M@EcGM_JEBe=5rm={ISFguMVYaGrV)5q*W6UELJP9#Ffk(s?ahNY z_O}ZzZ+WUoV54MD=IKN8y|Q~| zhb!VZDk_l;dNRE;a{w!{a6cHJX8eqKVsEmL_D&mUR3MWd3v`$VSTM{NQAQ5_NznL0n0gYTLvi^X!YteeSW~cXUmSkHs#~*pf|UX?J{N+ z%^0jbAZXvig%qc=SrL_ z$VB>9lk!NHY@5>oP2-3D=e~_7>d3l5o6CAuyKW}im2Py!3!#g#u=Fdde#i1v+XE>X zqqL^rgJNdNZlTIsi!*3zZ!D#vXMRdgx@4{1bc#On0uSGxBwUouOS34Q*&sA4o#J%Z zZJ|872-iqMVy_-~7qtwD_Kn!|Hwl^Sgc2>dZ4bn-A%~tGWVRofg<`l&{|d(I1*IYl z1DNw9uc{NJ(V-i%1Z-CdWv9n(wuseL*^9TarPaD@7EqL|S=e~i);hZ@468hxnTFQp zjS*%RFZ&&}G1hl%VN}H|B85BS#*Ipu;vqGaa`NrU92pQab>t=zu_c(H+MGGEp4#*_ ziDP6?u}N5Ml-+Y@EIwc~TgK)&4Y9C4^t^CBLRS27TBvZ@dc5?DiWQ3N}| zRE(d)5d&w$=Di2$bNjeCnC)+<_@d{~Ogm&YuI&ir96}Gh&%9{Ptp%BhosD>SVTGI= zF|*6;riro3bWPkm;>$C$W{1pdt~yz!YycsCR}L8VOo@X8C*+cf*cPyQNRMM>$6&g6)*ITSKH9LoSW2-%Y_#LZ1pRZ2I$g&ipK5?@;Yp<3;5UZs*Ik9v3?);~GcIB(oA7=3G=uS}Pmt9p@#7 zGFSCuIa5t$7g%E$c`tNakN{Dte4JNhazt>(zll$RJUh5zsj|u(4#OY_qNV$)c(s8; zyqC_NA{Nz#16j?Fju<6L2aEYrAW5 znz7NYYIt`XHo#a>32|?#EpsA8*`GTM;-|1Fb!L}|)-toP;VOGfX0@1(-zfTbS;%qv zW@pFv8cFG^%}MWS;woLyEHRL66E-{ zeF7pK(WD=#BO)0; zz2Cdm`fmHXxO`1nf?)a2aY8(cvn}{H?Fk{C5Kr>wukRMZ@hSO_KTzIAMn=TQ2XBhu z3m*u-2@{0VxN*YI$w^GWak{g!_;YKk=-V77hV<`>BR)$+|0-WGko<<|`)#x6T;w8V zOqw7D+WsIsoTiAutUY3=SR*>GG>f7Cxh>vsv4^e+!o1O2xH^4T{Nd;MVhOH?PM3>; z_fLsi_+98+7ttR&SMWKNSO?{kKSa&K~&VMDFtw#SGw>@_r%)Ycs{I*58P~$4(b1izkbtfzIMs$PCe` zPZ7iC^2A_Mskm^wOl)(r7ol_PMbM0KqAz8>XixJKx3gA>!6WNMV^WA1sM#x=CQlGI zKRhmOU#b=JU4J0@5}jd}apJQb(?!d{c&P&zq7b^V1{Vk_B}Cl$W{FPz&tUOyHuExpA*Bye&WRI&x$Yemx;ks z+kwAdyt*bxcrWr0!~4gHd(d|w++O@~$G1hbg{4;UMRwRoWu*q_j{ide|>wR=r5ij?&0^t z?|KMr=>HM__{C097V&LdyNZufX9!c4hZwH*2F5s1`^I>&FXTH&*ErEtJWc$e#8-4( z%7wmnMbjP!v0}kQ(RFI282;}R@wdWpBK!q=(ecL*L?-mT>@`lj{JgWc+K?;)VDC%0 zlf|F$+ik($7G15yqG0!Tge&ycWIBtYgRWxF)^CfyU78`j=R8h)c;Z>{`m58#OaAs^ z&(0ZQ-D(FhYvx1|5&mtlbjdg|0XBPf{y6ahzW?5{_Ts6z^w|V44*9#aqocQ{w+}Kj z*x!%8yS;rwy}cbxCSyfKYeiO81*EaDJu53XI5<*gy!vrkT9cvr6=Q6ZwtWA}rx*D* z8ERIy1hSN!wBnA4Eg!_#l=RWu_;aG z9}~1PDE4S@$ldl{fI#mM^bZd95A_Z84-NHnbazxRiL44;g)XZjtF=|9vorzYSH_Af zO(wHR_u^KqQLELOnwm_en1~2XeoRV4j3GLvxY(rAZQU9fxj%Mman}CWkRO0XZ+p+s z&=7He^Z=uuh_q%Ah7Nx^9oY*44C7~?S#%Y~CR0VLuba_m$ZslcGUY=(c%-GIM5h!N z=NomASFS|rR_+g68RWMua1CQzztImf-MU48L%pyWVN`TfWL3nrRse%M(+WC9V0_$S zGzJ;>w;tWP+(oM^F4h+31H+)H*2ENRz`~$4;=ah(z{veg{{DXc+d{yjy|1T-I1Jyp zGl;)_U=T=qMZ6&GHBA^3E1hX z7PmJ=W@QCN2Kle_^V=2~Qh%zwr?;p51|hHv_V@JPg7bTN5lLCC%)@8|gs~NeCZqXd zQ+{#2p(Wa&Yg)Z=<;Iw3V5G&EQ?8o9CM_+^XpC%vfdc~rgZ)c0hq z0lbC>hX!vA!z1nO?G&~kQh_J|1l*!CnOcx=v)PamZHhLeq)mTO8*MPOtV?TaxoR*2 z0)}e35?hfKc{DIMcx6yfWMJ^Zkge@KJ&ZvBcLwU21EYSuSBP4+OGOLEsBmwGqfdWG;JTHw4}te zAT^O$v5}F13xfkAw+3!oxNt(SpMOU?1roeH02%)3&R|~;g)lI(A)L#J16UY!mgprP zn#|FL=}sDr#?bQVGZ`PXw6vKGG5IkqS6kqZ7I?cNGWJSruwP(oMAsRekZLwZCpf*5pwa8~)oI&X%y168ZZ@|V zOwswp#@341E0GnEe*Rlyr%jtc5P^X!+uM6Mb1=qNcL?K_3|{8Jen+uFZr2$#2`y%W z=1r#*jb4+IsZZZmU0vO*$6IxEZgm9y={5QJP1;ER{qRKagxF~dCjewZWBc`f5V?im zMO497_j)OI$sgI-jmRU&B*=rrqt%q6NAzg6r{`vV`rdoF$Ma4cKarDsB4<=iB%jF5 z&8)7DNXggwuMC_PxOHow-^#4^8~s#{+`4sV;MU;qKL_u^AIKj)h$~qVW>s)LH(HFQ zh}<@P=AOb6$)j42<>VY5y|Ot2nm!>vf4{%qHp1v(kUMu^q<`M&9pbQ3FeX<3aohI)Fa(7ko%+Tif; zot}P)(UHZ5qWF!iFdAYqtB+l^wT9J4Up0?LZ390oIYJt3$Q%p2U)@WUmzQ@ zwXO}`xpk|zA6XElY6nIK%J;?!twB%vVU?VdCktz#oE4ubJp=V;KKTSEXFkCT*JnN< z#4~3~aRd~o6#%III!P~Li^6Moc#z6O0_gw|_*-kp%sp|80P+fIrFK$HB0=b^L3#0~ z0OKRxa7IXtDh8?zUT*n2Wh5poZVs1hXz zP6sf0uD7E!86wX^yIQt4wi=oN04XR;XX_{lEGbF1Rh-}q}0tE#;LKvCvZcn?3!}Mf9I^u^7)KK!_p4|A%Q6U^v zn29tNy%WaUKmF<3^irfTyWIu@CTlW(N=7?mScM{4d`c4 zF|I2ZcfsX)Plq{|a&kctI{_9-|7C7wGYZ)U<$f@Rk(Pt8_@yvme{{4XJHS{#puz_T zuo8kk{YZ7DUY~HE=o9!OyfJX5-ijv8#}0zgU@$4|+3-1G0KrfVfSdwEDp)j>?90v6 zCukDz$1l`NiqMDju@s4AMPeL8VvdXe;ptVV%|5#vZ6mK2I5_ZU5Ev;Ql6E^p`Ml9UIWDgdr8Q(jqnQ~4RFaoM*AXt?@s2WXmYOUJ}r2(k`F^FnEVgv^z5Tol^W@)C= zrvY*V2)LgOW21&zark?f@W;xn{7beUQ=({~NXXPuyyn$1LQ$&TzzMP@U(rmh>W7HL zRMR545FHSTRtXUwnX3sRoe;oU6{+7=H8r*%Xr7{@AO)AGje{HU;+8AfQAMG!fh1_C zWJ*7MIz9bJGY}N9QBN94pvfw96`UPXnY1iCye1%^E}+h#uCC5LARu6Fcz9J(VmA5{ zFt{3(8U!pM6jf`aeyE3u730`yr=}3nimqXHVp3HN^g7r+x3WEVs0*08Yz>eYNMis* zdV2aV_0b$HOn|N6M`@?jLvwI8zi@>5WpnEsMr<`c>U_jLAUv^=aMDi~r59F5Q$Vr{ znSp8?bWosPk&sHH{?UnlIFv(Ocx84``o2ASs8~2{Nqb0kNC?tT`X5X_p6rbb z)YaXosR^jLQ&%@I;y};(?h}V1kQj?Vt|bDbKar)f3icWMLsDIp9b6w9*%Skz-hT>? z=tR|LWmkc&Ez({h0bwV|@R9nnNquEvB`job`vc+N5O6KA!Vr^Eox119k;1~lef#hy zrD)&2H;<&IrlA9UDye2bNtgyPWQ))!?N9pGR93D@3LnE@#37)vqA4XebuU^{Qn;nd zE#9J{bTqD1*^-);ADLZ40YV5&f;mV8X0T=r;(xAIDLb*aHAoh1P!_x5@L+#>SZnR8a7K zK|w8EDh|OA4nt5@BR{Yg2*4I$Bp^wfq5`08OLaa;o&;b7$pZ}WV)IEu!f*rw5*(`% z0X|5oT2>VvVCCRY)2PYK+nWb-$iBLfDF(MIg+h5Me+sHNTOW2w_?HTzfUU z*(Vuu^8f(JIfnETg=3@LKXL{A0YdRPunOO21P(Yx0tm`}#SsdG)zx)CNG2nJ!C|!b z4@(->9wzynA#80$x*^J&!h?Lx(aN44HIqY`q~( z`h<^!!feP+AYm>2MiMpbhaA;P@~9FaD2^w@P$2-Ai(*PqS@=FmTPkr! z9j$`NBMeog#*;%M0v4W7l#V$_pYuCWKrG4ML-*^7P<@C?dPV~`j8*^zV4*?;7{dtS z*cjdSU63=B@`;N2y?J}^tSTi2Pub~Vbwu?ZSwZfjI)s2YA0pUrfDuQBC_ez}F+PTVojS-Zwk3ABCY{ZXVa#IYA ziPj()qulnwA-u9to01A=?JJTH4!RX6!XFKRUKSAcCg-LY(R#Ag^>ycU;fbv=fZ==U zjJbe#q$?1qd3njnVS3{u2yol*p@ws)Ni?PqMt~OKzz`2}IQanxxrW9nH5)03A8~LP zu&=9Qj|bGur6alsW7~)VBd7$iat~^vN3dXoyyRSMC)KiBnJSk~SVj`+*7HU1MK?4&|M2n3F zn7MU;D9GWm^r0}v^76ur(tjfk=*;+@RhcFQb0zgwA?f39CA$ST;&3!ZhWkVTE5<{30w+Iv0pwp}3pnyZwhNcs$ z1$O%VC^NV)SqAaci5_*#8MlP$F zI~O5E-cUf;R`(eU*2+v`kh(Ql3;+sHuh+*P4@-vR@K6OE=ql`ZrrrP?^kIllVr5l0 z+8^{H7(xP*2L#rN<_r>`qh!KPhJ?&`){YtxrA#t-K#~cOKS@rG2TnFxw}44ZQ~;1c z2AaeoFJ6+|;$H)SZ2XD#GX(jV4-yx-eHEl&R5WSJI;m z9)@B4(q4pcKL`?=Qbi#46&e^wnuaP_jBBRl2Vn#o!;L}yLH=4lKmVYWhG>m~ldF%; zN~}r(HxzpSfxXyV5@ak)LBsYYwpL{(nJ8~h;o69Zl$ezmZcd9?3GG3Vz<~Jq>4Jic z7=nt9PN^n3VYwPzA~2*!q~`%fUKuMzr5PEoTqGhRXjbe?-QwBsVSH-D$|W&r5ivo2 z(?~lYg8U;1Bhnb;7X(87F%fLFTs>hx&>CkNfB=y(AUP#xAluW}S~bN}r%pXTZ{BRr zbty|UG%CL`b{cqq3Bd#tk05`>@QYlzGA1G?CoD`t90M0g0rp}LD^MW~{gj?LP=*O8 zkY^{2cXD~^sqxbntxNNa0LK2UM;XH(EMO}?_y)t~etv<$vHp>RnrYvWP2*20&T z&Ymtia&Fz}Wi0*dI6us^}CUB1}V} z@^)>;S$LaB0K(30)sA<_T6HVehOM14d+JjzPdU0Q@b%u{7ZbD6h$drfU@VpPS;1M^ zfx**)L;M2k>l+u&6#@uW5Q;7vkfO6-!6X>MZr6cr+-_JCliCm#mNwq;TQ2a6OWaOi z1fdW{x`X+NV{kS-0K>p`eSQ7+QQK0_SQWIRI4?4foYMqxmh5y1BuG|m=1d}VxvwYZ zy}n}YM5oD5Jh5QD)3;n!`ZrCRb`L%WNN{lCnrR`yfsI+QSqpzmSr>hv|57nWDUTc*3X=4<^H zMn=NZAt7smLzqu}Y~wOm3OvvTwJ{e{fmce(fKf(vvVnlLUOPoU5<&5YsNI*hbcyGR zv~|_~jxL_tf4Hz>YgTq+a3Y>^W&tI;zP^$J@fP(I(Ow<{bnNhHJ3!dFLM0NlfiubX zr>|Iw^7ruJu=va^4Ie)<({al9$xj=NSryrd*{3kLPtR-{FCwN;#%(182BC&I%*Ikw z_Up2hqn{ z*Ok3q0%N$GqO*2oWxu}PP7-F-&d(`v_7f(~o;_#9ioJ#LsVQj@AAY)Y;-u+UA{(22 z_d8t&W^19<5R%Bg8z?@YA`k%C4DKn&00ieeHT5>f@+g@}#!a6xWzxLaOT%)Hq#lX? z!|#7OZ{n0InCqnb)oUNuH&(#ui5!C?v75{3*%K72Twt)1rNn}Q)<*T{>8j23Y=Q|B zCyt*ue)jCyD>4gCT=?|U>g~@MTk9_-Hfq+7kEphUOp}e|svS{wvIk5+^6ccvhOdR7 zB86*`?>;ke%EXDVn5So0?)!hZ(EO3s1ZOn*MVI_^yPH#S#VxX_!?pwEDux1u7F|)9 z-LK2+c0Gax`0P5cl^fYVfVBu^;vCNvVY&aU*PFFhVlTEg8n@5(T<@~rIc9rtGs4EI zTsbK`YiCy`3))fpj6G8_$;bpoU@lAJ_hdGIYHDrmsLwKHOj=jH;^kL~Mhz@AiouVC z(Pb|!xBK-&GR7E`RWg(O$Mo^ziN}=jbLPwr%gp_43)*h26}o&krzz8EUa=V1T1L^2 z6xh$>-Vx)3B4zgZLq7QQ_$_ z3Gody$XfNJMND9aIDyB+*-MvtdTQEke))$sLj|WGX@{g?hi5YYP~;3H_ZuxmHz}Fq zM;n}+KxE3q@ss9ESvqH4s-dl=O>g21RJZL#rMR;Kq<>IUVu#A&F)Rg)T~V?od3OHO zXlx|blp2V_0FztNi_Q=PFyuF1|GsN8*CY;Gr_TJ= zQUC5lI%p$2H7V0ya+)_D;WcIH(xoZO2zviU)f;wp@B=VPFzkHB?h+6l zm&U579kCRlb@^A*E+i~@X8L%inJ9&)ES()eJRCmXuyK`YEZB%4N=}~zjZ3>8tX{2@ zZBEKpWo)bBg7p_ytE(G6N{NW@Trp=hJU?fS=QLp8Y0}Z1s}w2>fmvs#OSvR`JR0Ru zJC6piCee5`BI4@Rlob7vgcY8i)190q&GzS}f^ays;eZ68fiIRb<(JA)YpDEe68*qw z`HMSFaTXBbb90+UA5)F#!RUH!d1m_5Nlud{VcIs!FBGRp3`{BE#?)icD34ml?FLx= z`t6pMloUf#WaFvN-#Jz9zt#0=-@gU*VlGP44&Zg*rwX0lkoO3{N3jkd##(j?fVRZrjMPR zLDT?KoqJ3gJGr15$u=2M_WzjUmz520dCsRJZ@s*J%hS*Q2VLCR5CvOd5>aUbqU!NX zRsN!E!&T{w`4!;`MBO`I9Bpbkdhs3k5K4$wUp~LvX#$%IM1Vl^xiT(2CXZbi7fEql zV^&A|HBPm-b8*|w%^Nc|X1ug>L%o6mkblhQcEhzDQ4CR9T1F6$lgX9J=?11#DG;ZM zH@{dOg`%#!JSys?9re;?Z!JE5e#8HvL~Q$+f?;=#dDukg!%xc(a83T?(fSUq>`-a% zr0`UwJZkf{JEVE!;9nPbF_DX#<;2x9<>$!d-&{NGDyyeZy>`7(w#tRtE>J=2q7H0h zd;RN$xbrXk3-?y;ped|pO3z+m44VX5e>3)E)y^MNDhGQSrQu^oYa;bVwfp;)_jztC z25jItl;n=b3*D$4zW~HQd%Nt0y(1fGs(N``wfQK8#lQ=3i^*6c+rWeR`4VI7y$`u6 zk18flzuJ@a1&3|1Y(R~@vs`&taL_CCAl-F^d7QC3$2`W~`;aU2a42kQdb;~@5ZTl! ze^Ag?rE2&s@5|4T^Xi#~#Mt%FAB<5E6?K%{_(exA2hX+xW4=`{(2pmJKKcCR7brzv z(DSb|8IK!QQ9ol-f6;!O>Fj(&s&?@MiIEpBzwjeqyt5q$XU^_AxBJ|#UAv;9keMF+ zDlcDkmY@CHXunQIsC-RL`F+QzjhvK&yPtoOZd?D#`t|Ey+xW&CZ)}8QZ2tP!#`Rg` z#Tymu@@HSVPq%s*^#+^t*-bD16L%-!Sx|izp3gj<#9pK}phJ5WHyG-Ft}4Cnh|plC zZ}NT%x68r>C;yJzX_p1bqcPs#@O$g;p$GpRy|(vW>uBW%@LxRIR@^Op*8B1c#OHq@ z%Q`wcuajHe*?gak)XQ?k=ia+F9kkZO7&t+uAB%_erSy@_r!>?!P zym_;&tF6nLPEE->GMsXzog))>(ei%vyju^{I}ae8iNSI@Qn8`pbV&27zZA8Wq(>ES6;YL7QJ zf7xX=n+%=show(rwsd!QaP}Rs>5{Rv%F7RI;CL8$!N-UE;pXO6WdsjHZhAvQVNTB3 zzLdfKVI39)^tG7urmnX4U(Za?|MaD&UpvukHnrV0nQ#8TwoW_}X=>{3kj;{Tt(&Pg ztV(%QhOExTK@T4{SSk)Y!gUymGgM<~L2V9|(*Fx1<%S)~%+zX5 z6qM$h|EJApx%uVo+pWF5mfKzTl%~|h4H+n}spW&VPuY&6vUqyyWgj0vu&w3-18dJP zF~2A$C;xUvFLFfB_1<1h!bhdE=Y%!4-TXA?WV2z#Jf}r)+s#f>XE)ThTDmPA?feuB zwPO8-oxeMKpsXxo=Z3AaMTGh(&Y5_`5s!c@nzx&j($OW^fx!E@ohUN&`ym(sa6w}*t7fV5Udp}0b__8Z{`qZiOW=AI&^lQWRCYW2C z#?Q`dy9tcmzV7aO743?-pmo4uV6^yq>t$zW-^o641Obc@1TP$tiuOrCPTo4>-QNDY zST@sPXzS|k{PN42%}eG?b(-g?)nMtt)lNO0A+7z(&6cJsy?vcu9_{F;8db~$@HX`hE4D}B6S$$u-JK)vonmv5QMP|7|{lON$Hu> zc{yuW(~40Nb6Ypb?asDb&#t!Dr#}74+Ie|q%Zlx(`Y$_8t-Jr&VQRthmyYhcci*Y0 zqY{}IJo(mh&oBPYcNQ;R?Cj<|ic!OXrFpaT6Xf*db+ihvzx~GMRqeffy|8*`r@1TD zV5lzLzGD5PMaIsyg!BlbrNeTy!x$S99zJ;EdRF9>;Ka($tCHS%?)jG&&zkj}mtQ#e z*1_jq_Hpy|jXQt-ysxjQLtvrAN=2&|5k~56eO_Oo+uF20I%c}d6D}^ZUViRXYJxeu`hvnE&P|MD z)1-GzE}V{BXdW8;>Z`$?#Ov)txBC#r2%pYQ6i~=Vd%Noc*Po0b=OV> z1~s*$L`;9eW$_CK`I#$O?#bt+)8P-1WCVr*PCtVja-sLmSO4l6?71QK5H^dF+f z24i*H8u;hnQ2+J2=dqA*sHg89SfI)x#MyxIkWb#`l`cect-RQu-5)=s7s#o=0g@k?^Ja^!`-Qe4I1yKo~d49QH#qQ8Qi z=dXCoac6Ru+ow8!u74_ogojW#c*s$}p zm!hJSPK?rQc=cspMl%yZ2hXg1Le>?>^*R|yRX$y zZ8n)Yjon6VW=dyw=f}Ug&i23luqKIG<>Jw-e5~@LmtiZ;OG$^>$j2 z!-x9r-8O+ox5b>I(NZR9Ye5Ke^*8W{Hlm86j*UI%bKbX=vWtU`Ffvb|JZZoXp{1wq zFP~W~-Bb~EL;XFf4(C(43jDBs%7%S>MuTYHQX~(~a8+RrCn&8>IY2Ic# z2_pbRu!8M4LaVg)a8C8r3z_@HOs1>V7NgdWW4-5YaPqUHCZC6&3b*xqRkl7STbk!k|i1gSFlw(9*+h}%me&b z0&9iW@8{5}N}wgOhu%F+v6Xi$r@1qFJuDWp@#%SU=FRc+oHK9BLW*-ST2MWh^7}rK zMI+W@uP@;|A}R>t&>^xGxg_VN=lXUi9 z)M72|dO7c@F8V#TRvs{@(U??gax(R-#o>Z z&XU%8mjbu}S@A@hIn8b6Gx=!`K~TMdtKj%RYTEDJ=ozrvYBRAvGKdGR;}S3@mk8C5UY z5v$d_=Jp&}YGAAFL+QsrKpt6D%;UjWj<3wA6Ita~BD1`Ss7@-o`9K*@S1(lMU1eI2)yML;wWLFN12J_2c|O%AKzxcxT@sxd@>!5|pJYf$}O z6HT@PN_-(a|4HdSIT86Co1x?}I=<-wvp%fWYFHm5AA$s+!U7M-1vq8Ed=_H6gGqeK8jt)QLkQ*vS2eQ=3=+X*WGc-F@yHh7mD9O_LuUj#N&Q7U&L8*o|MQ7!1YE z2S|FF%#5NgI6>y{y8Rhv?al!Mvinbp%{Zlmgua=4(K+dsat?{2pNzraWq+8bQL;Xb z8>nbURwi;mwQxP=*kVLUqF7-#v7jY&Dkppe2I{?+%H%3Zb?F&L08I^8C#MBT$B6JW znq^yBnt|~*=0d51)p*>J095PKIX+hOgT}e?vNH{}%49oU;U=L_`=+OFQDT@-9FD%W z5hF@8Bbg?`Dk_jpvNlxO3e3+2VxwNNJ9`F$wMB)P_DORGc?O}3fI_lYdWx(Wf$`3| z3_?%^)8$m70S1If>*$M!;_BQbyRr-_Qh@;?Ji(GDb<#{l5}>4~r^RynQ8+ZQH&h55 zF>mR`w1{g_7RAjVM)_0Y3E>>!=ISnN+ux4d?Y5^Z~mCs~IT-tSFz5W5{Am1uy^t8#)03 zK4xE#p_oNFFwi+C5Ui4-Y2maE1T*O|&0PX1B>>egqbTfs22o%LM_Oqt0t}U2L>QvZ zxc7C;kTtezGGFc6dDO!Ge1V#I|*jNLD}sAl6MaiEOB`GR}_h+4uB13Ikt=T&Q% zK2NI-XcoN$A`~hIWO=D_fgw~bWE-g-M;WpdP%@$zqL7PKJh#L`NCtuGx78&k5|FuY zamK6rX=a<^eYizBMh#|JHj3tE~wmpeCjk{m%x=5yqd3}x{L9heSaWGQ2HK4(gH zzJdb=5`nS>zNLJ@ENTnh4_DW|CdJUo{~VQr4GcUZEe3-rUa`966Xs&`_6g^034vw^ zEw3#YUD;j}%_Ye(8|})vYIueX#xXXEqIe%Ah84qVCSsvNoWv?gl}Vj0mlo*Sf~d>4 zDaruD&X?^Z)h(R&p&E4y?b}8+WD?kW1uY$(-F%YP->D!D*;u0gh_%A-%c#M4X9p@? z*!$2*>4!-D#6e*}7$;9+;b#EWU2+Ixv|5{!jFM5I0#l8yLPtPbL1e>{G+9w7{Sdmw z$H)~$DvOgj^e`Tx?#fV?mB~xR;1t>-iy;&o#Va6+#G%~>Eh-9PnVh2{Fa#PoOagY1 z5TgrXN0Op>@!T=qQ;c^nvjzdY!c;i3$Sws<1eG=;252^^B-C}`fKV}LA0WkEqf}_$ zGTOb2ND&a_eyhD`(*j!k%_szf7Yo^mT580Ws=b^XTFMIHrJ4$e2-hAbF2`8+A<`}d z*5X2$>VGJJ9%_kOQ3!z@fzK5P+{hRNA;r3xjYFa)j6jaDR}_B$2gQucDY69P);OU+ zm<}T_3%P(^LV$-oFK8XGcd%UzU6-ZDszwy_u+k_77njmn%8mnM6ec5)@J?L-wo?J@ zbP^j;z*hDHbp!Um!C)vYoK@{5YIK>z#Tv+pxs(uA3uD^b#TEwV)Wc+7@OlrJDhJD> z?dzm^g23`wD@r&}*vH4Lg&6#y8Vf|oDeqIqSed>KLd-(aP(2PFq?j2%KfP=~L`{W) zqU1{Q2Ya2??Q`iRJ#RIaEd-o_GL}TuPf!ekL02miRQ6d3*gb>qA1=@VK|K$m1HEG6M46k#aB9Eb%FY(a!Wwt?57BH_3lE3^p0x=DlFX@`tN?j~D7 z@F59B60T~GWj!DslG!{}#e@a*}4F!U6*p`w8AZTD3Bpw0* zAcsU_LUkBQe(Nqm(&NxWwz07lT~b`po)&ys`1)Q>KM`O%JqiObb%{Dd1Z|UptsRsd zIM@|z9hHYQmnbLLKO?m|hLn$5X^g*ZTrW=ts<7u$b*^0WVxtaQMe!_o98j9zAKLtA zVD3AzwmKz0E2$3q1xW_dR1fIA|AV@utVk?4PQ@ml&_bJ0StrPID*=;}AVsxDFjc&% zA~Aq|pBT=b0L~*^K~B0)>gFb88JlR6t<)_?Q1*g^c zF`L(8F~kGPpc@braSsBCx@%ZsSKk`hMEiHM7@C@}((6>B?KTLMJS?kDbsrC7NKgT7x2^dP@Z&PMIcce7?63@aNKqxWU!$3U z^iI1bV2cL4LwMJ;D#*3)@R#1iGvZwGN+q_R8QsB4r9_ruk5FBPbdt4b=M69c3aN)e z+9p8?>z4p*C+0hU{%eJxl4(qY!9o(N0>)Zd^*PKTZNVV4MFrW5P?!Vn{2=wiM1+j5 zXpbc_Rrvh*^Iv+iAUQcKp`x-12CE!{!tRifW!-XxTF49nLy#tw3_;M|dxT0Kv!Mtg zeEy92uB$f}VI!1yO;%D>Wk`1AGPPlf5G8lW;3c=hTCkV0`AStdl1a*v)-X&ZF(6iq zkW|GqXcrJ*cyEf^^povHFj%~{k=&A7qNxkxqKOzWr z20A#d-d=HW9-G`&m%?DlnOej#ES9KjEo1{BvpVsp;ann7RC`g75d=6X5Cp(1YQkN; zLmhoLxyQN9-<+P8lN@G6Ny4lu1Q(kMJdi`UvB#lB<{}~#U8=#@WD+2089RghjoWH` zW;i}E-*uDQ0$;b88JH)7U3|2SyaPpIrD8I+6f&X0M2TN%u4@P{#Vd+_g$MSELK28< zc#VgL;}fo~p>d9mzLVWnXGkuFEJnem9di3bi9$J@vk2vO=@LXRQBeX+MWGJ>eQg=? zA8j$?Zyq6gfAk2h9j-D3t+&7@%E&AY5>fu_O_~ zkX|82kN`(|g7)27lRe9KldH3@`wVY5WinX!(9}g|a!koyl$L-oV5bvgWZJlefOx+f zX)n1wkzx|s0?8Um_-xrS?ERA+OuO^U@|dy7+1bO})pgS*cg*l~cc&?TzWBF$7eyJv zXpC7<4jgOY%9|7_+W9~Um%fJXHP{m%n>Mg#shH{I?jGl}$<^C?@&X?ZFE4jDx0yZ& zW8d?W;s0G{D40=VW+p`QJ~Xf!fUw%1c0{ypa>^yHEZ>8J`M+LZ_1HUyHs{fKA^pCg zo4mX{;F-zpK0fZ7Lfzebe89v}VS_kh=g@vPI^I|Zl^h|_uDiVPF75Lp1^dvl(3ZT| zW1jZUNyzka4fTn0_uAy{0T5>&-}7!h=iPl^F*j$-&LWAsyt=Hk2-^`5A8dS7fGvTsl@PW)Kcc10H3l{JUPv~~@@%8yD{0{*bX6L!>j@r1r1eGS^;Qjb$& zrsD$Gjb7)0wW};+dud4thBn3s?Tmls?5{8V>HPTxq@KkKwwmwi4FoS&_yXEPJ>U-y z_sL`-)(NCIxW~uGalwKGj`Ze&gQG8|8DIXR9R0#FS%8_u?vB1(yqup*dVPJ|L&5I6FN$ae0@8w6cq5JY*;ut>FlKuB zxX*X>@ zKroXTXfgsDDd$fdXTeG&e66HvtYVw1P@hfSUTB<9`N1Dc^`m#VEO17;nF&%ajpI0L z`7Gi@JV*fYb>idZfqrQO$(7hk<|rQ$Q9V4bH$Ik+Dn2 zqlp=#^u7x(53f*Qpe*rm_w`*)JZyz*!Vr$g_sD*fMI4z0?xHVjZ+_JICNFms>?9~C zU~jU)=)EqK^*Lf4sQ?CuGvd~oDQxZ>{mp}C-~oRSLMZ+Lgc7NQ3E-$i;v!?Y&vMF& q%az>sprWt&#G4}5L!m-g9xw=dlz!xbL<0jT%aQtj$IrHqLi~Tbq_BAa literal 0 HcmV?d00001 diff --git a/polymer/eduke32/rsrc/build_icon.bmp b/polymer/eduke32/rsrc/build_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fdb5e8899642d955b5730a268ef8131074945c57 GIT binary patch literal 2102 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 HV&MM(5_RRZ literal 0 HcmV?d00001 diff --git a/polymer/eduke32/rsrc/editor_banner.c b/polymer/eduke32/rsrc/editor_banner.c new file mode 100644 index 000000000..08b17c49a --- /dev/null +++ b/polymer/eduke32/rsrc/editor_banner.c @@ -0,0 +1,3310 @@ +#include +/* GdkPixbuf RGB C-Source image dump */ + +const GdkPixdata startbanner_pixdata = { + 0x47646b50, /* Pixbuf magic: 'GdkP' */ + 24 + 84000, /* header length + pixel_data length */ + 0x1010001, /* pixdata_type */ + 300, /* rowstride */ + 100, /* width */ + 280, /* height */ + /* pixel_data: */ + "\232\255\332\241\264\345\241\264\345\241\264\345\255\274\347\250\266" + "\334\241\264\345\255\274\347\255\274\347\255\274\347\255\274\347\255" + "\274\347\255\274\347\255\274\347\255\274\347\255\274\347\267\307\352" + "\250\266\334\267\307\352\306\313\352\326\332\371\326\332\353\335\345" + "\373\355\357\373\355\357\373\355\357\373\377\377\377\377\377\377\377" + "\377\377\377\377\377\355\357\373\326\332\353\311\324\353\335\345\373" + "\355\357\373\355\357\373\335\345\373\355\357\373\335\345\373\335\345" + "\373\311\324\353\311\324\353\335\345\373\335\345\373\335\345\373\355" + "\357\373\355\357\373\355\357\373\355\357\373\355\357\373\355\357\373" + "\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\241\264\345\250\266\334" + "\241\264\345\241\264\345\267\307\352\255\274\347\255\274\347\255\274" + "\347\267\307\352\267\307\352\253\304\355\255\274\347\267\307\352\267" + "\307\352\267\307\352\267\307\352\311\324\353\311\324\353\326\332\353" + "\335\345\373\355\357\373\377\377\377\355\357\373\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\355\357\373\355\357\373\355" + "\357\373\335\345\373\326\332\353\335\345\373\355\357\373\355\357\373" + "\335\345\373\335\345\373\335\345\373\335\345\373\311\324\353\267\307" + "\352\311\324\353\306\312\367\326\332\371\326\332\371\326\332\371\311" + "\324\353\326\332\371\326\332\353\326\332\353\335\345\373\355\357\373" + "\355\357\373\355\357\373\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\243\275\346\241\264\345\255\274\347\241\264\345" + "\255\274\347\255\274\347\255\274\347\255\274\347\255\274\347\255\274" + "\347\267\307\352\267\307\352\271\325\373\267\307\352\267\307\352\311" + "\324\353\335\345\373\355\357\373\355\357\373\355\357\373\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\355\357\373\355\357\373\311" + "\324\353\326\332\353\355\357\373\335\345\373\355\357\373\335\345\373" + "\335\345\373\335\345\373\326\332\371\267\307\352\267\307\352\267\307" + "\352\306\313\352\306\313\352\267\307\352\306\313\352\306\313\352\326" + "\332\371\326\332\353\311\324\353\335\345\373\335\345\373\355\357\373" + "\355\357\373\355\357\373\377\377\377\355\357\373\377\377\377\355\357" + "\373\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\241" + "\264\345\250\266\334\241\264\345\253\304\355\250\266\334\255\274\347" + "\267\307\352\255\274\347\255\274\347\255\274\347\267\307\352\255\274" + "\347\310\327\371\310\327\371\311\324\353\311\324\353\355\357\373\355" + "\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\355\357\373\326\332\353\326\332\353\355" + "\357\373\355\357\373\355\357\373\355\357\373\355\357\373\335\345\373" + "\326\332\371\306\313\352\306\313\352\255\274\347\306\313\352\267\307" + "\352\306\313\352\326\332\371\335\345\373\335\345\373\335\345\373\326" + "\332\371\311\324\353\326\332\353\335\345\373\355\357\373\355\357\373" + "\377\377\377\377\377\377\377\377\377\355\357\373\355\357\373\355\357" + "\373\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\255\274\347\241\264\345\241" + "\264\345\267\307\352\250\266\334\255\274\347\267\307\352\267\307\352" + "\255\274\347\267\307\352\270\311\367\255\274\347\335\345\373\335\345" + "\373\335\345\373\311\324\353\355\357\373\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\355\357\373\377\377\377\377\377\377\377\377\377\377\377" + "\377\355\357\373\355\357\373\326\332\353\335\345\373\377\377\377\355" + "\357\373\355\357\373\355\357\373\355\357\373\335\345\373\310\327\371" + "\310\327\371\267\307\352\306\313\352\310\327\371\335\345\373\335\345" + "\373\335\345\373\335\345\373\335\345\373\335\345\373\306\313\352\311" + "\324\353\326\332\371\335\345\373\355\357\373\355\357\373\377\377\377" + "\377\377\377\355\357\373\355\357\373\355\357\373\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\270\311\367\241\264\345\232\255\332\241\264\345\267" + "\307\352\255\274\347\270\311\367\310\327\371\270\311\367\310\327\371" + "\310\327\371\267\307\352\267\307\352\306\341\374\326\332\371\311\324" + "\353\355\357\373\355\357\373\377\377\377\355\357\373\377\377\377\355" + "\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\355\357\373\355\357" + "\373\326\332\353\324\324\334\355\357\373\377\377\377\377\377\377\355" + "\357\373\355\357\373\335\345\373\326\332\371\326\332\371\306\313\352" + "\311\324\353\310\327\371\335\345\373\335\345\373\326\332\353\311\324" + "\353\326\332\353\326\332\353\306\312\367\310\327\371\311\324\353\326" + "\332\353\335\345\373\355\357\373\355\357\373\355\357\373\355\357\373" + "\355\357\373\355\357\373\355\357\373\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\274\330" + "\350\271\325\373\232\254\344\241\264\345\243\275\346\243\275\346\243" + "\275\346\255\274\347\255\274\347\326\332\371\326\332\371\267\307\352" + "\250\266\334\266\276\323\311\324\353\306\313\352\355\357\373\355\357" + "\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\355\357\373\377\377\377\355\357\373" + "\377\377\377\377\377\377\377\377\377\377\377\377\355\357\373\311\324" + "\353\306\312\367\377\377\377\355\357\373\355\357\373\326\332\371\335" + "\345\373\335\345\373\355\357\373\355\357\373\310\327\371\267\307\352" + "\267\307\352\311\324\353\267\307\352\306\313\352\306\313\352\306\313" + "\352\311\324\353\335\345\373\355\357\373\355\357\373\326\332\353\326" + "\332\353\355\357\373\377\377\377\355\357\373\355\357\373\355\357\373" + "\355\357\373\355\357\373\355\357\373\355\357\373\355\357\373\355\357" + "\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\271\325\373\270\311\367\241\264" + "\345\241\264\345\241\264\345\241\264\345\255\274\347\243\275\346\250" + "\266\334\270\311\367\267\307\352\255\274\347\326\332\371\326\332\371" + "\335\345\373\326\332\353\355\357\373\335\345\373\377\377\377\355\357" + "\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\355\357\373\306\313\352\255\274\347\355\357" + "\373\355\357\373\335\345\373\326\332\371\326\332\371\326\332\371\335" + "\345\373\355\357\373\310\327\371\267\307\352\306\313\352\311\324\353" + "\326\332\353\326\332\371\335\345\373\355\357\373\311\324\353\326\332" + "\371\335\345\373\355\357\373\355\357\373\355\357\373\355\357\373\355" + "\357\373\355\357\373\355\357\373\335\345\373\355\357\373\355\357\373" + "\355\357\373\355\357\373\335\345\373\377\377\377\355\357\373\377\377" + "\377\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\267\307\352\270\311\367\241\264\345\232\255\332\232\254" + "\344\241\264\345\253\304\355\255\274\347\250\266\334\274\330\350\267" + "\307\352\267\307\352\355\357\373\355\357\373\355\357\373\355\357\373" + "\355\357\373\355\357\373\355\357\373\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\355\357\373\311\324\353\266\276\323\326\332\353\326\332\371\326\332" + "\371\306\312\367\310\327\371\306\313\352\306\313\352\311\324\353\306" + "\313\352\311\324\353\326\332\371\335\345\373\335\345\373\355\357\373" + "\355\357\373\335\345\373\326\332\371\335\345\373\335\345\373\355\357" + "\373\355\357\373\355\357\373\355\357\373\355\357\373\355\357\373\355" + "\357\373\335\345\373\326\332\353\335\345\373\335\345\373\355\357\373" + "\355\357\373\377\377\377\377\377\377\355\357\373\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\253\304\355" + "\267\307\352\243\275\346\232\255\332\241\264\345\232\254\344\232\255" + "\332\241\264\345\255\274\347\270\311\367\267\307\352\267\307\352\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\355\357\373" + "\377\377\377\355\357\373\377\377\377\355\357\373\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\355\357\373\335\345\373" + "\306\313\352\306\313\352\311\324\353\326\332\371\326\332\371\326\332" + "\371\310\327\371\310\327\371\310\327\371\326\332\371\335\345\373\355" + "\357\373\335\345\373\335\345\373\335\345\373\355\357\373\355\357\373" + "\335\345\373\326\332\371\326\332\353\311\324\353\326\332\353\335\345" + "\373\335\345\373\335\345\373\335\345\373\355\357\373\355\357\373\335" + "\345\373\355\357\373\355\357\373\355\357\373\355\357\373\355\357\373" + "\377\377\377\355\357\373\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\243\275\346\253\304\355\271\325\373" + "\253\304\355\252\271\371\253\304\355\241\264\345\232\255\332\241\264" + "\345\267\307\352\250\266\334\255\274\347\355\357\373\355\357\373\355" + "\357\373\377\377\377\377\377\377\355\357\373\377\377\377\377\377\377" + "\377\377\377\377\377\377\355\357\373\377\377\377\355\357\373\377\377" + "\377\355\357\373\377\377\377\355\357\373\355\357\373\377\377\377\355" + "\357\373\355\357\373\355\357\373\335\345\373\326\332\371\306\312\367" + "\326\332\371\326\332\371\326\332\371\326\332\371\310\327\371\306\312" + "\367\310\327\371\335\345\373\335\345\373\355\357\373\335\345\373\335" + "\345\373\355\357\373\355\357\373\355\357\373\335\345\373\326\332\371" + "\326\332\371\326\332\353\326\332\353\335\345\373\355\357\373\355\357" + "\373\355\357\373\355\357\373\355\357\373\335\345\373\335\345\373\355" + "\357\373\355\357\373\355\357\373\377\377\377\355\357\373\377\377\377" + "\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\255\274\347\253\304\355\271\325\373\267\307\352\243\275\346" + "\270\311\367\252\271\371\243\275\346\250\266\334\255\274\347\255\274" + "\347\267\307\352\377\377\377\326\332\353\335\345\373\377\377\377\377" + "\377\377\355\357\373\377\377\377\355\357\373\377\377\377\355\357\373" + "\377\377\377\377\377\377\377\377\377\355\357\373\377\377\377\355\357" + "\373\335\345\373\355\357\373\355\357\373\335\345\373\326\332\371\326" + "\332\371\326\332\371\326\332\371\310\327\371\326\332\371\326\332\371" + "\310\327\371\310\327\371\310\327\371\310\327\371\310\327\371\326\332" + "\371\335\345\373\335\345\373\335\345\373\335\345\373\326\332\371\326" + "\332\371\311\324\353\306\313\352\311\324\353\326\332\371\335\345\373" + "\355\357\373\355\357\373\355\357\373\355\357\373\355\357\373\355\357" + "\373\355\357\373\335\345\373\355\357\373\335\345\373\355\357\373\355" + "\357\373\355\357\373\377\377\377\355\357\373\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\252\271\371\241" + "\264\345\267\307\352\255\274\347\213\242\343\232\254\344\241\264\345" + "\241\264\345\232\255\332\250\266\334\250\266\334\306\312\367\355\357" + "\373\311\324\353\326\332\353\355\357\373\355\357\373\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\355\357\373" + "\355\357\373\355\357\373\335\345\373\335\345\373\335\345\373\326\332" + "\371\326\332\371\310\327\371\310\327\371\306\312\367\310\327\371\310" + "\327\371\310\327\371\326\332\371\326\332\371\335\345\373\335\345\373" + "\326\332\371\310\327\371\310\327\371\326\332\371\306\341\374\306\312" + "\367\267\307\352\306\312\367\306\313\352\267\307\352\306\313\352\266" + "\276\323\306\313\352\326\332\371\335\345\373\335\345\373\335\345\373" + "\355\357\373\335\345\373\355\357\373\335\345\373\335\345\373\335\345" + "\373\335\345\373\355\357\373\355\357\373\335\345\373\377\377\377\355" + "\357\373\377\377\377\377\377\377\355\357\373\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\241\264\345\232\254\344\271\325\373\274" + "\330\350\232\254\344\216\232\326\232\255\332\241\264\345\243\275\346" + "\255\274\347\255\274\347\270\311\367\335\345\373\306\313\352\311\324" + "\353\355\357\373\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\355\357\373\335\345\373\326\332\353\306\313\352" + "\306\313\352\255\274\347\326\332\371\310\327\371\271\325\373\306\312" + "\367\271\325\373\310\327\371\310\327\371\306\341\374\306\312\367\326" + "\332\371\335\345\373\335\345\373\335\345\373\310\327\371\267\307\352" + "\255\274\347\253\304\355\267\307\352\267\307\352\271\325\373\306\341" + "\374\310\327\371\267\307\352\310\327\371\326\332\371\326\332\371\326" + "\332\371\335\345\373\335\345\373\335\345\373\335\345\373\355\357\373" + "\335\345\373\335\345\373\326\332\353\335\345\373\355\357\373\335\345" + "\373\355\357\373\355\357\373\355\357\373\377\377\377\355\357\373\377" + "\377\377\377\377\377\355\357\373\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\241\264\345\232\255\332\255\274\347\253\304\355\213\242\343\232" + "\254\344\232\255\332\255\274\347\255\274\347\255\274\347\241\264\345" + "\232\254\344\326\332\371\310\327\371\306\313\352\267\307\352\255\274" + "\347\267\307\352\253\304\355\250\266\334\270\311\367\270\311\367\267" + "\307\352\250\266\334\255\274\347\306\312\367\306\312\367\310\327\371" + "\310\327\371\306\341\374\326\332\371\306\341\374\326\332\371\306\341" + "\374\326\332\371\326\332\371\310\327\371\310\327\371\271\325\373\267" + "\307\352\267\307\352\255\274\347\267\307\352\267\307\352\326\332\371" + "\335\345\373\335\345\373\335\345\373\326\332\371\326\332\371\335\345" + "\373\335\345\373\335\345\373\355\357\373\335\345\373\326\332\371\326" + "\332\371\326\332\371\310\327\371\270\311\367\271\325\373\271\325\373" + "\251\324\374\214\304\354\214\274\374\212\304\374\212\304\374\212\304" + "\374\204\274\374\204\274\374\214\274\374\204\274\374\204\274\374\214" + "\274\374\212\304\374\212\304\374\230\311\374\246\313\373\230\311\374" + "\251\324\374\271\325\373\306\341\374\306\341\374\335\345\373\355\357" + "\373\355\357\373\355\357\373\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\241\264\345\241\264" + "\345\253\304\355\267\307\352\232\254\344\232\254\344\241\264\345\255" + "\274\347\267\307\352\255\274\347\255\274\347\255\274\347\306\313\352" + "\310\327\371\310\327\371\267\307\352\250\266\334\255\274\347\253\304" + "\355\255\274\347\255\274\347\267\307\352\255\274\347\267\307\352\267" + "\307\352\271\325\373\310\327\371\310\327\371\306\341\374\326\332\371" + "\310\327\371\310\327\371\310\327\371\306\313\352\270\311\367\267\307" + "\352\267\307\352\270\311\367\306\312\367\310\327\371\310\327\371\310" + "\327\371\310\327\371\326\332\371\335\345\373\306\341\374\326\332\371" + "\306\341\374\326\332\371\306\341\374\326\332\371\306\341\374\306\341" + "\374\271\325\373\271\325\373\246\313\373\214\274\374t\264\374g\252\372" + "]\240\374T\244\374E\233\374E\233\3744\224\374,\214\374$\214\374$\214" + "\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$" + "\214\374$\214\374$\214\374$\214\374$\214\374,\224\374<\234\374E\233\374" + "T\244\374\\\254\374l\264\374t\274\374\212\304\374\234\324\374\306\341" + "\374\306\341\374\335\345\373\335\345\373\355\357\373\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\232\254\344\232\254\344\253\304\355\270\311\367\232\254\344\232\255" + "\332\243\275\346\253\304\355\255\274\347\250\266\334\255\274\347\252" + "\271\371\266\276\323\310\327\371\306\341\374\310\327\371\310\327\371" + "\306\341\374\326\332\371\326\332\371\270\311\367\270\311\367\306\312" + "\367\310\327\371\310\327\371\310\327\371\310\327\371\310\327\371\310" + "\327\371\306\312\367\310\327\371\306\313\352\267\307\352\267\307\352" + "\267\307\352\306\313\352\270\311\367\310\327\371\310\327\371\310\327" + "\371\310\327\371\310\327\371\310\327\371\306\341\374\310\327\371\271" + "\325\373\271\325\373\246\313\373\246\313\373\230\311\374}\274\377g\252" + "\372T\244\3744\224\374$\214\374\34\204\374\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\26|\372\24\204\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\26|\372\26|\372\14|\374\26|\372\26|\372" + "\14|\374\26|\372\26|\372\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\24\204\374\34\204\374$\214\3744\234\374T\244\374}\274\377\230" + "\311\374\251\324\374\306\341\374\335\345\373\355\357\373\377\377\377" + "\377\377\377\232\255\332\232\255\332\255\274\347\253\304\355\241\264" + "\345\232\254\344\241\264\345\255\274\347\255\274\347\250\266\334\250" + "\266\334\255\274\347\267\307\352\311\324\353\310\327\371\335\345\373" + "\335\345\373\306\341\374\306\341\374\306\341\374\310\327\371\310\327" + "\371\310\327\371\310\327\371\310\327\371\270\311\367\267\307\352\310" + "\327\371\267\307\352\274\330\350\270\311\367\310\327\371\310\327\371" + "\310\327\371\310\327\371\310\327\371\306\312\367\310\327\371\310\327" + "\371\306\341\374\310\327\371\271\325\373\270\311\367\246\313\373\204" + "\264\374w\251\371]\240\374E\233\374,\214\374\24\204\374\26|\372\24\204" + "\374\26|\372\26|\372\26|\372\26|\372\26|\372\24\204\374\26|\372\14}\362" + "\14}\362\26x\351\26x\351\6h\330\32h\327\7e\311\32h\327\7e\311\7e\311" + "\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\6h\330\32h\327\32h" + "\327\6h\330\26x\351\26x\351\26x\351\14}\362\14}\362\26|\372\26|\372\24" + "\204\374\26|\372\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374,\224\374E\233\374\\\254\374\212\304\374\251\324\374\232\254" + "\344\232\254\344\253\304\355\270\311\367\253\304\355\241\264\345\232" + "\255\332\243\275\346\255\274\347\232\255\332\250\266\334\250\266\334" + "\326\332\371\267\307\352\306\313\352\306\341\374\326\332\371\310\327" + "\371\306\313\352\270\311\367\270\311\367\270\311\367\267\307\352\270" + "\311\367\267\307\352\267\307\352\255\274\347\306\312\367\310\327\371" + "\310\327\371\310\327\371\310\327\371\310\327\371\306\341\374\326\332" + "\371\306\341\374\270\311\367\270\311\367\270\311\367\230\311\374\204" + "\264\374g\252\372L\244\3745\214\373\34\204\374\24\204\374\24\204\374" + "\24\204\374\26|\372\26|\372\26|\372\26|\372\26x\351\26x\351\6h\330\7" + "e\311\7e\311\6V\251\6V\251\5I\230\5I\230\5F\210\4=~\5;t\5""6l\5""6d\5" + "*f\5""6d\4,X\5*f\4,X\5""6d\5*f\5""6d\5*f\5""6d\5""6d\5""6l\5""6l\5;t" + "\4=~\5F\210\5I\230\5K\246\6V\251\6V\251\5Y\270\7e\311\6h\330\6h\330\26" + "x\351\26x\351\26|\372\26|\372\26|\372\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\241\264\345\232\254\344\253\304\355\267\307\352" + "\271\325\373\255\274\347\241\264\345\243\275\346\255\274\347\250\266" + "\334\250\266\334\267\307\352\335\345\373\306\313\352\267\307\352\310" + "\327\371\306\341\374\270\311\367\267\307\352\306\341\374\255\274\347" + "\267\307\352\255\274\347\255\274\347\270\311\367\270\311\367\306\313" + "\352\306\341\374\310\327\371\310\327\371\310\327\371\310\327\371\310" + "\327\371\310\327\371\271\325\373\251\324\374\227\273\372t\264\374T\244" + "\3744\224\374\34\204\374\34\204\374\24\204\374\26|\372\26|\372\26|\372" + "\26r\367\26x\351\6h\330\7e\311\6V\251\5K\246\5F\210\5;t\5""6l\5""6d\4" + ",X\4$L\4$D\4\34E\4\34E\4$L\4$L\4$L\4,X\4,X\4,X\4,X\4,X\4,X\4,X\4,X\4" + ",X\4,X\4,X\4,X\5*f\4,X\5""6d\5*f\5*f\4,X\4,X\4,X\4,X\4,X\5""6d\5;t\4" + "=~\4=~\5F\210\6Z\230\5Y\270\5Y\270\7e\311\5l\346\26x\351\26x\351\26|" + "\372\26|\372\241\264\345\232\254\344\243\275\346\243\275\346\310\327" + "\371\253\304\355\243\275\346\241\264\345\241\264\345\250\266\334\267" + "\307\352\335\345\373\326\332\371\306\312\367\255\274\347\267\307\352" + "\267\307\352\255\274\347\243\275\346\253\304\355\255\274\347\270\311" + "\367\267\307\352\267\307\352\310\327\371\310\327\371\310\327\371\326" + "\332\371\310\327\371\310\327\371\310\327\371\271\325\373\246\313\373" + "\214\274\374g\252\372E\233\374$\214\374\24\204\374\24\204\374\26|\372" + "\26|\372\26|\372\26x\351\6h\330\7e\311\6V\251\5F\210\4=~\5""6l\4,X\4" + "$L\4$D\4$D\4$D\4\34E\4$L\4$L\4,X\4,X\5*f\5""6d\5*f\5""6d\5*f\5*f\5""6" + "d\5*f\5""6l\5""6l\5""6l\5""6l\5""6l\5""6l\5""6l\5""6l\5""6l\5""6l\5""6" + "l\5""6l\5;t\5""6l\5;t\5;t\5;t\5;t\5;t\5;t\5""6l\5*f\5""6d\5*f\5""6l\5" + "6d\5""6l\4=~\5F\210\5I\230\6V\251\5[\306\6h\330\252\271\371\241\264\345" + "\255\274\347\255\274\347\271\325\373\267\307\352\243\275\346\232\254" + "\344\232\255\332\232\255\332\306\312\367\335\345\373\267\307\352\250" + "\266\334\241\264\345\241\264\345\255\274\347\270\311\367\270\311\367" + "\252\271\371\267\307\352\310\327\371\306\312\367\270\311\367\310\327" + "\371\306\341\374\306\312\367\270\311\367\271\325\373\246\313\373\214" + "\274\374\\\254\374<\224\374\34\204\374\24\204\374\26|\372\26|\372\26" + "|\372\26r\367\6h\330\5[\306\5K\246\5F\210\5""6l\4,X\4$D\4$D\4\35<\4\35" + "<\4$L\4$L\4,X\4,X\5*f\4,X\5*f\5""6d\4,X\4,X\4,X\4,X\4,X\5#V\4$L\4$L\4" + "$L\4$L\4$L\4$L\4$L\4$L\4$L\4$L\4$L\5#V\4,X\4,X\4,X\4,X\4,X\5*f\5*f\5" + "6d\5""6l\5""6l\5""6l\5;t\5;t\4=~\4=~\4=~\4=~\5;t\5;t\5;t\5""6l\5""6l" + "\5""6l\5;t\4=~\326\332\353\250\266\334\216\232\326\243\275\346\306\313" + "\352\306\313\352\250\266\334\232\255\332\232\254\344\232\254\344\243" + "\275\346\243\275\346\255\274\347\267\307\352\270\311\367\270\311\367" + "\255\274\347\255\274\347\270\311\367\310\327\371\310\327\371\271\325" + "\373\310\327\371\310\327\371\310\327\371\271\325\373\246\313\373\214" + "\274\374g\252\372<\224\374\34\204\374\24\204\374\24\204\374\26|\372\26" + "|\372\26x\351\7e\311\5Y\270\5F\210\5""6l\4$L\4$D\4\35<\4$D\4$D\4$L\4" + ",X\4,X\4,X\4,X\4,X\4,X\4$L\4$L\4$L\4$D\4\35<\4\35<\4\34""4\4\34""4\4" + "\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24" + ",\4\24""4\4\24,\4\24,\4\24,\4\34""4\4\24""4\4\24""4\4\34""4\4\34""4\4" + "\34""4\4\24""4\4\35<\4\34E\4\34E\4$L\5#V\4,X\4,X\5""6d\5""6l\5;t\4=~" + "\4=~\4=~\4=~\4=~\4=~\5;t\326\332\353\310\327\371\243\275\346\232\254" + "\344\306\313\352\310\327\371\255\274\347\216\232\326\232\255\332\232" + "\254\344\243\275\346\253\304\355\306\312\367\310\327\371\310\327\371" + "\306\312\367\267\307\352\267\307\352\267\307\352\270\311\367\271\325" + "\373\306\313\352\271\325\373\270\311\367\227\273\372t\264\374E\233\374" + "$\203\373\24\204\374\24\204\374\26|\372\26|\372\26x\351\7e\311\6V\251" + "\4=~\4,X\4$D\4\35<\4$D\4$D\4$L\4$L\4,X\4,X\4,X\4$L\4$L\4$D\4\35<\4\24" + "4\4\24,\4\24$\4\14$\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4" + "\14\34\4\14$\4\14$\4\24$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24,\4\24,\4" + "\24,\4\24,\4\24""4\4\24""4\4\24""4\4\24""4\4\24""4\4\24""4\4\24,\4\24" + "4\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24""4\4\24""4\4\35" + "<\4\34E\4$L\4,X\5*f\5""6l\5;t\4=~\4=~\267\307\352\335\345\373\326\332" + "\371\232\254\344\255\274\347\310\327\371\253\304\355\232\255\332\232" + "\255\332\243\275\346\271\325\373\271\325\373\306\312\367\271\325\373" + "\310\327\371\310\327\371\271\325\373\267\307\352\255\274\347\250\266" + "\334\270\311\367\253\304\355\204\264\374T\244\3744\224\374\24\204\374" + "\26|\372\26|\372\26|\372\26x\351\7e\311\5K\246\5;t\4,X\4\35<\4\35<\4" + "\35<\4$L\4,X\4,X\4,X\4$L\4$L\4$D\4\24""4\4\24,\4\24$\4\14\34\4\14\24" + "\4\14\24\4\14\24\4\14\24\4\4\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14" + "$\4\24$\4\24$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24""4" + "\4\34""4\4\34""4\4\24""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34" + "4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\24""4\4\34" + "4\4\24""4\4\24,\4\24,\4\24,\4\24$\4\24$\4\24$\4\24$\4\24,\4\34""4\4\35" + "<\4\34E\4,X\232\255\332\355\357\373\355\357\373\232\255\332\232\255\332" + "\270\311\367\267\307\352\232\255\332\241\264\345\270\311\367\310\327" + "\371\271\325\373\270\311\367\270\311\367\270\311\367\310\327\371\310" + "\327\371\306\312\367\253\304\355\241\264\345|\264\374E\233\374$\214\374" + "\24\204\374\26|\372\26|\372\26r\367\6h\330\5Y\270\4=~\4,X\4\35<\4\35" + "<\4$D\4$L\4,X\4,X\4,X\4$L\4$D\4\34""4\4\24,\4\14\34\4\14\24\4\4\14\4" + "\4\14\4\4\14\4\4\14\4\4\24\4\14\24\4\14\24\4\14\34\4\14\34\4\14$\4\14" + "\34\4\14$\4\24$\4\24$\4\14$\4\24$\4\24,\4\24$\4\24,\4\24,\4\24,\4\24" + ",\4\24,\4\24,\4\24""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4" + "\4\24""4\4\35<\4\34""4\4\34""4\4\34""4\4\34""4\4\24""4\4\34""4\4\24""4" + "\4\34""4\4\34""4\4\34""4\4\34""4\4\24,\4\34""4\4\24,\4\24""4\4\24,\4" + "\24,\4\24$\4\24$\4\14$\4\14\34\4\14\34\4\14$\232\254\344\335\345\373" + "\355\357\373\232\255\332\232\255\332\255\274\347\253\304\355\250\266" + "\334\253\304\355\310\327\371\306\312\367\255\274\347\271\325\373\270" + "\311\367\270\311\367\270\311\367\271\325\373\246\313\373|\264\374E\233" + "\374$\214\374\24\204\374\26|\372\26r\367\26x\351\7e\311\5I\230\5""6d" + "\4$D\4\34""4\4\35<\4$L\4,X\4,X\4,X\4$L\4\35<\4\24,\4\14\34\4\14\24\4" + "\4\14\4\4\4\4\4\4\4\4\14\4\4\14\4\14\24\4\14\24\4\14\24\4\14\24\4\14" + "\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14$\4\14$\4\24" + "$\4\24,\4\24$\4\24,\4\24,\4\24,\4\24,\4\24,\4\34""4\4\24""4\4\34""4\4" + "\24""4\4\34""4\4\34""4\4\24""4\4\35<\4\34""4\4\35<\4\34""4\4\34""4\4" + "\35<\4\34""4\4\35<\4\34""4\4\34""4\4\34""4\4\34""4\4\24""4\4\34""4\4" + "\24,\4\24""4\4\24""4\4\34""4\4\24,\4\24,\4\24,\4\24,\4\24,\4\24,\4\24" + ",\4\24$\4\14$\241\264\345\306\313\352\355\357\373\306\313\352\232\254" + "\344\243\275\346\253\304\355\267\307\352\310\327\371\326\332\371\271" + "\325\373\270\311\367\310\327\371\271\325\373\270\311\367\227\273\372" + "t\264\374<\224\374$\203\373\24\204\374\26|\372\26r\367\5l\346\6V\251" + "\4=~\4$L\4\34""4\4\34""4\4$D\4$L\4,X\4,X\4$L\4\35<\4\24,\4\14\34\4\4" + "\14\4\4\4\0\0\0\0\0\0\4\4\4\4\4\14\4\4\14\4\4\14\4\14\24\4\14\24\4\4" + "\24\4\14\24\4\14\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34\4\14$\4\24" + "$\4\14$\4\24$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24,\4\24,\4\34""4\4\24" + "4\4\34""4\4\24""4\4\34""4\4\34""4\4\34""4\4\35<\4\34""4\4\35<\4\35<\4" + "\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\24""4\4\34""4\4\34""4\4\24""4\4" + "\24""4\4\34""4\4\34""4\4\34""4\4\24,\4\24""4\4\24,\4\24,\4\24,\4\24," + "\4\24,\4\24,\4\24,\4\24$\250\266\334\250\266\334\326\332\371\377\377" + "\377\232\254\344\232\254\344\253\304\355\271\325\373\326\332\371\326" + "\332\371\310\327\371\306\312\367\270\311\367\227\273\372g\252\372<\224" + "\374\34\204\374\24\204\374\26|\372\26r\367\6h\330\6V\251\5""6l\4$D\4" + "\34""4\4\35<\4$L\4,X\4,X\4$L\4$D\4\24,\4\14\24\4\4\14\0\0\0\0\0\0\0\0" + "\0\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\14\24\4\4\24\4\14\24\4" + "\14\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\24$" + "\4\14$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24,\4\24,\4\24""4\4\24""4\4\24" + "4\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\35<\4\35<\4\35<\4\35<\4\35" + "<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\34""4\4\34""4\4\34" + "4\4\34""4\4\24""4\4\34""4\4\24""4\4\34,\4\24""4\4\34,\4\24,\4\24,\4\24" + ",\4\24$\4\24$\4\24$\267\307\352\216\232\326\326\332\371\377\377\377\213" + "\242\343\232\254\344\243\275\346\270\311\367\335\345\373\310\327\371" + "\270\311\367\252\271\371g\252\372E\233\374\34\204\374\24\204\374\26|" + "\372\26r\367\7e\311\5I\230\5""6d\4$D\4\34""4\4\35<\4$L\4,X\4$L\4$D\4" + "\24""4\4\14\34\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\14\4\4\14\4\4" + "\14\4\4\14\4\4\14\4\4\14\4\14\24\4\4\14\4\14\24\4\14\24\4\14\24\4\14" + "\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34\4\14$\4\24$\4\24$\4\14$\4" + "\24$\4\24,\4\24,\4\24,\4\24,\4\24""4\4\34,\4\24""4\4\24""4\4\34""4\4" + "\24""4\4\34""4\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<" + "\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\34""4\4\34""4" + "\4\24""4\4\24""4\4\24""4\4\24,\4\24""4\4\24,\4\24,\4\24,\4\24,\4\24," + "\4\24$\232\254\344\232\255\332\253\304\355\326\332\371\310\327\371\243" + "\275\346\255\274\347\271\325\373\270\311\367\213\242\343i\236\352<\224" + "\374\34\204\374\24\204\374\26|\372\26r\367\6h\330\5I\230\4,X\4\35<\4" + "\35<\4$D\4$L\4,X\4$L\4\35<\4\24$\4\14\24\4\4\4\0\0\0\0\0\0\0\0\0\4\4" + "\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\4\4\4\14\4\4\14\4\14\14\4\4\14\4\4\14" + "\4\4\24\4\14\24\4\4\24\4\14\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34" + "\4\14$\4\14\34\4\14$\4\14$\4\24$\4\24,\4\24,\4\24,\4\24""4\4\24,\4\24" + "4\4\34""4\4\34""4\4\34""4\4\24""4\4\34""4\4\35<\4\35<\4\35<\4\35<\4\35" + "<\4\35<\4\35<\4\34E\4\35<\4$D\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\35" + "<\4\24""4\4\35<\4\34""4\4\34""4\4\34""4\4\34""4\4\34""4\4\24""4\4\24" + ",\4\24,\4\24,\4\24,\4\24,\4\24,\4\24$\232\254\344\232\255\332\241\264" + "\345\271\325\373\271\325\373\250\266\334\243\275\346\270\311\367\227" + "\273\372T\244\374$\214\374\26|\372\26|\372\26|\372\6h\330\5I\230\4,X" + "\4\35<\4\35<\4$D\4$L\4,X\4$L\4\34""4\4\14$\4\4\14\0\0\0\0\0\0\0\0\0\0" + "\0\0\4\4\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\4\4\4\14\4\4\14\4\4\14" + "\4\4\14\4\4\14\4\14\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\34\4\14\24" + "\4\14\34\4\14\34\4\24$\4\14\34\4\14$\4\24$\4\24$\4\24$\4\24,\4\24,\4" + "\24,\4\24,\4\24""4\4\34""4\4\34""4\4\34""4\4\34""4\4\35<\4\35<\4\35<" + "\4\35<\4\35<\4\35<\4\35<\4\34E\4$D\4$D\4$D\4\34E\4$D\4\35<\4\34E\4\35" + "<\4\35<\4\35<\4\35<\4\35<\4\35<\4\34""4\4\35<\4\34""4\4\34""4\4\24""4" + "\4\24,\4\34""4\4\24,\4\24,\4\24,\4\24,\4\24$\4\24,\213\242\343\216\232" + "\326\232\255\332\243\275\346\271\325\373\243\275\346\214\264\354]\240" + "\3744\224\374\24\204\374\26|\372\26|\372\5l\346\5I\230\5""6d\4\35<\4" + "\35<\4$D\4,X\4,X\4$L\4\24""4\4\14\34\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\4\4\4\14\4" + "\4\14\4\4\14\4\4\14\4\14\24\4\4\14\4\14\24\4\14\24\4\14\24\4\14\34\4" + "\14\34\4\14\34\4\14$\4\14\34\4\14$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24" + ",\4\24""4\4\34""4\4\24""4\4\34""4\4\24""4\4\35<\4\35<\4\35<\4\35<\4\35" + "<\4\35<\4\34E\4$D\4$D\4$D\4\34E\4$D\4$D\4$D\4\34E\4$D\4$D\4$D\4\34E\4" + "\35<\4\35<\4\35<\4\35<\4\35<\4\34""4\4\35<\4\24""4\4\34""4\4\34""4\4" + "\34""4\4\24""4\4\24,\4\24,\4\24,\4\24,\4\24$\213\242\343\216\232\326" + "\213\242\343\232\254\344\227\273\372i\236\3524\224\374\34\204\374\26" + "|\372\26|\372\5l\346\5Y\270\5""6l\4\35<\4\34""4\4$D\5#V\4,X\4$D\4\24" + "4\4\14\24\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0" + "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\14\14\4" + "\4\14\4\4\24\4\4\24\4\14\24\4\4\24\4\14\24\4\14\34\4\14\24\4\14\34\4" + "\14\34\4\14$\4\14$\4\24$\4\14$\4\24,\4\24,\4\24,\4\34""4\4\24,\4\34""4" + "\4\24""4\4\34""4\4\35<\4\35<\4\35<\4\35<\4\35<\4\34E\4\35<\4$D\4$D\4" + "\34E\4$D\4$D\4$L\4\34E\4$D\4$D\4\34E\4$D\4\34E\4$D\4\34E\4\35<\4\35<" + "\4\35<\4\35<\4\35<\4\34""4\4\35<\4\24""4\4\34""4\4\24""4\4\34""4\4\34" + "4\4\24,\4\24,\4\24,\4\24,\213\242\343\213\242\343\213\242\343v\236\352" + "=\216\361$\214\374\26|\372\26|\372\26r\367\5[\306\5;t\4$D\4\34""4\4$" + "D\4$L\4,X\4$D\4\34""4\4\14\34\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4" + "\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\14\14\4\4\24\4\14\24\4\14\24\4" + "\14\34\4\14\34\4\14\34\4\14\34\4\24$\4\14$\4\24$\4\24$\4\24,\4\24,\4" + "\24,\4\24,\4\24""4\4\34""4\4\34""4\4\34""4\4\35<\4\35<\4\35<\4\35<\4" + "\35<\4$D\4$D\4\34E\4$D\4$L\4$L\4$L\4$L\4$L\4$L\4$L\4$D\4$L\4$D\4$D\4" + "$D\4\34E\4$D\4\34E\4\35<\4\35<\4\35<\4\35<\4\34""4\4\34""4\4\34""4\4" + "\34""4\4\34,\4\24""4\4\24,\4\24,\4\24,\4\24,\213\242\343\213\242\343" + "^\231\357,\214\374\24\204\374\26|\372\26|\372\6h\330\5F\210\4$L\4\35" + "<\4\35<\4$L\5#V\4$L\4\34""4\4\14\34\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4" + "\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\14\24\4\4\14\4\14\24\4\14" + "\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14$\4\24$\4\24" + "$\4\24,\4\24,\4\24,\4\24,\4\24""4\4\24""4\4\34""4\4\34""4\4\35<\4\35" + "<\4\35<\4$D\4\34E\4$D\4\34E\4$D\4$D\4$L\4$D\4$L\4$L\4$L\4$L\4$L\4$L\4" + "$L\4$L\4$L\4$L\4\34E\4$D\4$D\4$D\4\34E\4$D\4\35<\4\35<\4\35<\4\35<\4" + "\24""4\4\34""4\4\24""4\4\34""4\4\24""4\4\24,\4\24,\4\24,v\236\352=\216" + "\361\24\204\374\24\204\374\26|\372\26x\351\6V\251\5*f\4\35<\4\35<\4$" + "D\4,X\4$L\4\35<\4\14\34\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4" + "\14\4\4\4\4\4\14\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\14\24\4\14\24\4" + "\4\24\4\14\24\4\14\34\4\14\34\4\14\34\4\14\34\4\14$\4\24$\4\24$\4\14" + "$\4\24,\4\24,\4\24,\4\24""4\4\34""4\4\34""4\4\35<\4\35<\4\35<\4$D\4$" + "D\4\34E\4$D\4$L\4$L\4$L\4,X\5#V\4,X\4,X\4,X\4,X\4,X\4,X\4,X\4,X\4$L\4" + "$L\4$L\4$L\4$L\4$L\4$D\4$D\4\35<\4\35<\4\35<\4\35<\4\35<\4\35<\4\34""4" + "\4\34""4\4\34""4\4\34""4\4\24""4\4\24,\4\24,$\214\374\24\204\374\26|" + "\372\26|\372\7e\311\4=~\4$L\4\35<\4$D\4$L\4,X\4\35<\4\24$\4\4\14\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\4\4\14\4" + "\4\14\4\4\14\4\4\14\4\4\14\4\4\24\4\14\24\4\14\24\4\14\24\4\14\34\4\14" + "\24\4\14\34\4\14\34\4\14$\4\24$\4\24$\4\24,\4\24,\4\24,\4\24""4\4\34" + "4\4\35<\4\35<\4\35<\4\34E\4$D\4\34E\4$D\4\34E\4\34E\4$D\4$D\4$D\4\34" + "E\4$D\4\34E\4$D\4$D\4$D\4$D\4$L\4$L\4$L\5#V\4$L\4,X\4$L\4$L\4$L\4$L\4" + "$L\4$L\4$D\4$D\4\35<\4\35<\4\35<\4\34""4\4\34""4\4\34""4\4\34""4\4\34" + ",\4\24,\4\24,\24\204\374\26|\372\26x\351\6V\251\4,X\4\35<\4\35<\4$L\4" + ",X\4$L\4\24,\4\4\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4" + "\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\14\14\4\4\14\4\4\14\4\14\24" + "\4\4\24\4\14\24\4\14\24\4\14\34\4\14\34\4\14\34\4\24$\4\14$\4\24,\4\24" + ",\4\24,\4\24""4\4\24""4\4\34""4\4\34""4\4\24""4\4\24,\4\24,\4\24$\4\14" + "$\4\14$\4\14\34\4\14\34\4\14\34\4\14\24\4\14\24\4\4\14\4\14\24\4\4\14" + "\4\4\24\4\4\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\34\4\14\34\4\14\34" + "\4\24$\4\24$\4\24,\4\24,\4\34""4\4\35<\4\35<\4\34E\4$D\4\34E\4$L\4\34" + "E\4$D\4\35<\4\35<\4\34""4\4\34""4\4\24""4\4\24,\4\24,\26|\372\7e\311" + "\4=~\4$D\4\35<\4$D\4,X\5#V\4\34""4\4\14\34\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\4" + "\4\4\14\4\4\14\4\4\14\4\14\24\4\14\24\4\14\24\4\14\24\4\14\34\4\14\34" + "\4\14\34\4\14$\4\24$\4\24$\4\24$\4\24$\4\24$\4\14\34\4\14\34\4\14\24" + "\4\14\24\4\4\24\4\4\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4\4\14\4\14\24\4\14\24\4" + "\14\34\4\24$\4\24,\4\24""4\4\35<\4\35<\4\35<\4\35<\4\35<\4\34""4\4\34" + "4\4\24,\6V\251\5*f\4\35<\4\35<\4$L\4,X\4$D\4\24$\4\4\14\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4" + "\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\14\14\4\4\24\4\14\14\4\4\24\4\14" + "\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\24\4\4\24\4\4\14\4\4" + "\14\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\14\4\4\14\4\14\34\4\14$\4\24$\4\24,\4" + "\24""4\4\34""4\4\34""4\4$D\4\35<\4$D\4,X\4,X\4\34""4\4\14\24\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\14\4\14\24\4\14\24\4" + "\14\24\4\14\24\4\14\24\4\14\24\4\4\14\4\4\14\4\4\14\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4" + "\4\14\4\4\24\4\14\34\4\24$\4\35<\4$L\4,X\4$L\4\24$\4\4\14\0\0\0\0\0\0" + "\0\0\0\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4" + "\4\14\4\4\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\4\4\4\4\14\14\4\14\14\4\14\24\4\14\14\4\14\24\4\14\14" + "\4\14\24\4\14\14\4\14\24\4\14\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4$L\4,X\4\35<\4\14\24\0\0\0\0\0\0" + "\0\0\0\4\4\4\4\4\4\0\0\0\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\14\4\4\4\4\4" + "\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\4\34,\4$L\4,X\14/" + "Q\32Aj\11Ly\30F\210\31[\231\6V\251\27]\251\27]\251\27]\251\27]\251\27" + "]\251\27]\251\27]\251\27]\251\6V\251\31[\231\31[\231\11Ly\32Aj\26""9" + "X\14/Q\4$L\4\35<\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4$L\4\24,\4\4\14\0\0\0\4\4\4" + "\4\4\4\4\4\4\4\4\14\4\4\4\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\4\14\24\4\14$\4\35<\5""6l\5F\210\31[\231\31^\270\31f\306\30" + "w\330'\177\347'\177\3477\204\360,\212\3645\214\3734\224\3744\224\374" + "5\214\3734\224\3745\214\3735\214\373<\224\3745\214\373<\224\3745\214" + "\373<\224\374<\224\3744\224\374=\216\3617\204\3600\212\341'\177\347\30" + "w\330\30w\330\31^\270\31[\231\26D\226\5;t\4$D\4\24$\4\14\24\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\34\4\4\14\0\0\0\4\4\14\4" + "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\4" + "\35<\5""6l\30F\210\5Y\270\31f\306\32h\327'\177\347,\214\374,\214\374" + "4\224\3744\224\3745\214\3735\214\373<\224\3744\224\374<\224\374<\224" + "\374<\234\374<\224\374<\234\374<\234\374E\233\374<\234\374E\233\374E" + "\233\374<\234\374E\233\374E\233\374<\234\374<\234\374<\224\374<\224\374" + "E\233\374<\224\374<\224\374<\224\374<\224\3744\224\374,\224\374,\212" + "\364-t\315\31f\306\31f\306\31[\231\5;t\4$L\4\14\34\0\0\0\0\0\0\0\0\0" + "\0\0\0\4\4\4\4\4\4\4\4\14\4\4\4\4\4\14\4\4\14\4\4\4\4\4\14\4\4\4\4\4" + "\4\4\4\4\4\4\4\0\0\0\0\0\0\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\4\14\14\4\34""4\4,X\5I\230\31f\306\30w\330\26x\351$\214\374,\214\374" + ",\214\374,\214\374,\214\374,\224\3744\224\3744\224\3744\224\3744\224" + "\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\374<" + "\224\374<\224\374<\224\374<\234\374<\224\374<\234\374<\234\374<\234\374" + "<\224\374<\224\374<\234\374<\234\374<\234\374<\224\374<\234\374<\234" + "\374<\234\3744\224\374<\224\374<\224\3744\224\3744\224\3745\214\3735" + "\214\373,\212\364)v\367\30w\330\31f\306\27]\251\5""6l\4\35<\4\14\24\4" + "\4\14\4\4\14\4\4\14\4\4\14\4\4\4\4\4\4\4\4\14\4\4\4\4\4\4\4\4\14\4\4" + "\4\4\4\4\4\4\4\4\4\4\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\4$L\4=~\6V\251" + "\32h\327\26x\351\34\204\374\34\204\374$\203\373$\203\373,\214\374,\214" + "\374,\224\374,\214\374,\214\374,\214\374,\224\374,\214\374,\224\374," + "\214\374,\214\374,\224\374,\214\374,\224\374,\224\374,\224\374,\224\374" + ",\224\374,\224\374,\224\3744\224\3744\224\3744\224\3744\224\3744\224" + "\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744" + "\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\374" + "4\224\3744\224\3744\224\3745\214\373,\214\374,\214\374'\177\347\30w\330" + "\31^\270\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\4\4\4\14\4\4\14" + "\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4$L\5F\210\5[\306\30w\330" + "\26r\367$\203\373\34\204\374\34\204\374$\203\373$\214\374$\214\374$\214" + "\374$\214\374$\214\374$\214\374\34\214\374\34\214\374\34\214\374$\214" + "\374\34\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374" + ",\214\374,\224\374,\214\374,\224\374,\224\3744\224\374,\224\3744\224" + "\3744\224\3744\224\3744\224\3744\224\374,\224\3744\224\374,\224\374," + "\214\374,\224\374,\214\374,\224\374,\214\374,\214\374$\214\374$\214\374" + ",\214\374,\214\374,\214\374,\224\374,\224\374,\214\374,\224\374,\214" + "\374,\214\374,\214\374-\203\374$\203\373\4\4\14\4\4\14\4\4\14\4\4\14" + "\4\4\14\4\4\4\4\4\14\4\4\4\4\4\14\4\4\14\4\4\14\4\4\14\4\4\4\4\4\14\4" + "\4\4\4\4\4\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\24," + "\4=~\5Y\270\26x\351\26|\372\34\204\374\34\204\374\34\204\374\34\204\374" + "$\214\374$\214\374\34\214\374\34\214\374\34\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\34\204\374\34\204\374\34\204\374\34\204\374" + "\34\204\374\34\214\374$\214\374$\214\374$\214\374$\214\374,\224\374," + "\214\374,\224\374,\224\374,\214\374,\224\374,\224\3744\224\3744\224\374" + "4\224\3744\224\3744\224\3744\224\3744\224\374,\224\374,\224\374,\214" + "\374,\224\374,\214\374$\214\374,\224\374$\214\374$\214\374$\214\374$" + "\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374" + "$\214\374,\214\374,\224\374,\224\374\4\4\14\4\4\14\4\4\14\4\4\14\4\4" + "\14\4\4\14\4\4\14\4\4\14\4\4\4\4\4\14\4\4\4\4\4\14\4\4\4\4\4\14\4\4\4" + "\4\4\4\4\4\4\4\4\4\0\0\0\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4,X\6V\251\5l\346\26" + "|\372\26|\372\26|\372\24\204\374\34\204\374\34\204\374\34\214\374\24" + "\204\374\24\204\374\24\204\374\14\204\374\24\204\374\14\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34\214\374" + "\34\214\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374,\224" + "\374$\214\374,\214\374,\224\374,\224\374,\224\3744\224\3744\224\374," + "\224\3744\224\3744\224\3744\224\374,\224\3744\224\3744\224\374,\224\374" + ",\224\374,\224\374,\224\374,\224\374$\214\374,\224\374$\214\374$\214" + "\374$\214\374$\214\374$\214\374\34\214\374\34\214\374\34\214\374\34\204" + "\374\34\214\374\34\204\374\34\214\374$\214\374$\214\374\4\4\14\4\14\14" + "\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14" + "\4\4\14\4\4\4\4\4\14\4\4\4\4\4\14\0\0\0\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\34\5""6l\5[\306" + "\26x\351\26|\372\34\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\14|\374\14|\374\14|\374\14|\374\14|\374\14|\374" + "\24\204\374\14\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34" + "\204\374\34\214\374\34\204\374\34\214\374\34\214\374$\214\374$\214\374" + "$\214\374$\214\374,\224\374,\214\374,\214\374,\224\374,\214\374,\224" + "\3744\224\374,\224\3744\224\3744\224\3744\224\3744\224\3744\224\374," + "\224\3744\224\374,\224\374,\224\374,\214\374,\224\374,\214\374,\224\374" + "$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374\34\204\374\34" + "\214\374\34\204\374\34\214\374\34\214\374\34\214\374\24\204\374\24\204" + "\374\24\204\374\4\14\24\4\4\14\4\4\14\4\4\14\4\4\14\4\14\14\4\4\14\4" + "\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\4\4\4\14\4\4\4\4\4\14\4\4\4\4\4" + "\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\4\24$\5;t\6h\330\26r\367\14|\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\24\204\374\14\204\374\4|\374\4|\374\4|\374\4|\374\4|\374\14" + "|\374\4|\374\14|\374\14\204\374\14\204\374\14|\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\34\214\374\34\204\374\34\204\374\34\214\374" + "$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374,\214\374,\224" + "\374,\224\374,\224\374,\224\374,\224\3744\224\3744\224\3744\224\3744" + "\224\3744\224\3744\224\3744\224\374,\224\374,\224\374,\214\374,\224\374" + ",\224\374,\224\374$\214\374$\214\374$\214\374$\214\374$\214\374$\214" + "\374\34\214\374\34\214\374\34\214\374\34\214\374\34\214\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\4\4\14\4\14\24\4\14\24\4" + "\4\24\4\14\24\4\4\14\4\14\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14" + "\4\4\14\4\4\14\4\4\14\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\4\24,\4=~\6h\330\26r\367\14|\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\14\204\374\14|\374\4|\374\4|\374\4|\374\4" + "|\374\4|\374\4|\374\4|\374\4|\374\14\204\374\14\204\374\14|\374\14\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34\204\374" + "\34\214\374\34\204\374\34\214\374$\214\374\34\214\374$\214\374$\214\374" + "$\214\374$\224\374,\214\374,\224\374,\214\374,\224\374,\214\3744\224" + "\374,\224\3744\224\3744\224\3744\224\3744\224\374,\224\3744\224\3744" + "\224\374,\224\374,\224\374,\214\374,\224\374,\224\374,\224\374$\214\374" + "$\214\374$\214\374$\214\374$\214\374$\214\374$\214\374\34\214\374\34" + "\204\374\34\214\374\34\204\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\4\14\24\4\4\24\4\14\14\4\14\24\4\14\14\4\4\24\4\4\24\4\14\24\4\4" + "\24\4\14\14\4\4\14\4\14\14\4\4\14\4\4\14\4\4\14\4\4\14\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\24$\4=~\6h\330\26r\367\26" + "|\372\24\204\374\24\204\374\24\204\374\24\204\374\14\204\374\4|\374\4" + "|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\14|\374\14\204\374\14|\374\14\204\374\24\204\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\24\204\374\34\204\374\34\214\374\34\214" + "\374$\214\374$\214\374$\214\374$\214\374,\224\374$\214\374,\224\374," + "\214\374,\224\374,\224\374,\224\3744\224\3744\224\3744\224\3744\224\374" + "4\224\3744\224\3744\224\3744\224\374,\214\374,\224\374,\224\374,\214" + "\374,\224\374,\214\374,\214\374$\214\374$\214\374$\214\374$\214\374\34" + "\214\374$\214\374\34\214\374\34\214\374\34\214\374\34\214\374\34\204" + "\374\24\204\374\24\204\374\24\204\374\4\14\24\4\14\24\4\4\24\4\14\24" + "\4\4\24\4\14\24\4\14\24\4\4\24\4\14\14\4\4\24\4\4\14\4\4\24\4\4\14\4" + "\4\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\5" + "6l\7e\311\26r\367\26|\372\26|\372\14|\374\24\204\374\14\204\374\4|\374" + "\4t\374\4|\374\4t\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\14\204\374\14|\374\14\204\374\14|\374\14\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\34\204\374\34\214\374\34\204\374" + "\34\214\374$\214\374$\214\374$\214\374$\214\374$\214\374,\224\374,\214" + "\374,\224\374,\224\374,\224\3744\224\3744\224\3744\224\3744\224\3744" + "\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\374" + "4\224\374,\224\374,\224\374,\214\374,\224\374,\224\374$\214\374$\214" + "\374$\214\374$\214\374$\214\374\34\204\374\34\214\374\34\204\374\34\214" + "\374\24\204\374\34\214\374\24\204\374\24\204\374\24\204\374\4\14\24\4" + "\14\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\24\4\14\24" + "\4\14\24\4\14\24\4\4\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\4\4\14\4$L\5Y\270\26r\367\26|\372\24\204\374\24\204\374\14\204\374" + "\14\204\374\4|\374\4|\374\4t\374\4t\374\4|\374\4t\374\4|\374\4|\374\4" + "|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\14|\374\4|\374\14|\374" + "\14\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34" + "\204\374\34\214\374\34\214\374$\214\374$\214\374$\214\374$\214\374$\214" + "\374,\224\374,\214\374,\224\3744\224\3744\224\3744\224\3744\224\3744" + "\224\3744\224\3744\224\374<\224\374<\234\374<\234\374<\234\374<\234\374" + "<\224\3744\224\3744\224\3744\224\3744\224\3744\224\3744\224\374,\224" + "\374,\214\374,\224\374,\214\374$\214\374$\214\374$\214\374$\214\374$" + "\214\374\34\214\374\34\214\374\34\214\374\34\204\374\24\204\374\24\204" + "\374\24\204\374\4\14\24\4\14\24\4\14\34\4\14\24\4\14\24\4\14\24\4\14" + "\24\4\4\24\4\14\24\4\14\24\4\14\24\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\4\24,\5I\230\14}\362\26|\372\26|\372\24\204\374" + "\24\204\374\14\204\374\4|\374\4|\374\4|\374\4t\374\4|\374\4t\364\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\14|\374" + "\14|\374\14\204\374\14\204\374\14|\374\24\204\374\24\204\374\24\204\374" + "\34\204\374\34\214\374\34\214\374\34\214\374$\214\374$\214\374$\214\374" + ",\214\374,\224\374,\224\374,\224\3744\224\3744\224\3744\224\3744\224" + "\374<\224\374<\234\374<\234\374<\234\374<\234\374<\234\374<\234\374<" + "\234\374<\234\374<\234\374<\234\374<\234\374<\224\3744\224\3744\224\374" + "4\224\3744\224\374,\224\374,\224\374,\224\374,\224\374,\224\374$\214" + "\374$\214\374$\214\374$\214\374\34\214\374\34\214\374\34\214\374\34\214" + "\374\34\204\374\24\204\374\24\204\374\4\14\34\4\14\34\4\14\34\4\14\34" + "\4\14\34\4\14\34\4\14\34\4\14\24\4\14\34\4\14\24\4\4\14\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\5""6l\6h\330\26|\372\24\204\374" + "\24\204\374\24\204\374\24\204\374\4|\374\4|\374\4t\374\4t\374\4t\374" + "\4t\374\4|\374\4t\374\4t\374\4t\374\4|\374\4|\374\4|\374\4t\374\4|\374" + "\4|\374\4|\374\4|\374\14\204\374\14|\374\14|\374\14|\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\34\204\374\34\214\374$\214\374$\214\374" + "$\214\374$\214\374,\214\374,\224\374,\224\3745\214\3734\224\3744\224" + "\3744\224\374<\224\374<\234\374<\234\374<\234\374<\234\374<\234\374<" + "\234\374<\234\374E\233\374<\234\374E\233\374<\234\374<\234\374<\234\374" + "<\234\374<\234\374<\234\374<\224\3744\224\3744\224\3744\224\374,\224" + "\374,\214\374,\224\374,\224\374$\214\374$\214\374$\214\374$\214\374\34" + "\214\374\34\204\374\34\214\374\34\204\374\24\204\374\24\204\374\4\14" + "\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4\14\24\4" + "\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\35<\5K\246\26|\372" + "\26|\372\24\204\374\24\204\374\24\204\374\14\204\374\4t\374\4|\374\4" + "t\374\4t\374\4t\374\4t\364\4|\374\4t\374\4t\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\14|\374\14\204\374" + "\14\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34\204\374\34" + "\204\374\34\214\374$\214\374$\214\374$\214\374,\214\374,\214\374,\224" + "\3744\224\3744\224\3744\224\374<\224\374<\234\374<\234\374<\234\374<" + "\234\374E\233\374E\233\374E\233\374E\233\374E\233\374E\233\374E\233\374" + "E\233\374E\233\374E\233\374E\233\374<\224\374<\234\374<\234\374<\234" + "\374<\224\3744\224\3744\224\3744\224\3744\224\374,\224\374,\224\374," + "\214\374$\214\374$\214\374$\214\374$\214\374$\214\374\34\214\374\34\204" + "\374\24\204\374\24\204\374\4\14\34\4\14\34\4\14\34\4\14\34\4\14\34\4" + "\14\34\4\14\34\4\14\24\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14" + "\24\5""6l\6h\330\26|\372\24\204\374\24\204\374\24\204\374\24\204\374" + "\4|\374\4|\374\4|\374\4t\374\4t\374\4|\374\4|\374\4t\374\4|\374\4|\374" + "\4|\374\4|\374\4t\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\14|\374" + "\14|\374\14\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34\204" + "\374\34\214\374\34\204\374$\214\374$\214\374$\214\374$\214\374,\224\374" + ",\214\3744\224\3744\224\3744\224\374<\234\374<\234\374<\234\374<\234" + "\374E\233\374E\233\374E\233\374E\233\374E\233\374E\233\374L\244\374E" + "\233\374L\244\374L\244\374L\244\374L\244\374E\233\374E\233\374E\233\374" + "E\233\374<\234\374<\234\374<\234\374<\234\374<\224\3744\224\3744\224" + "\3744\224\374,\224\374,\214\374,\224\374$\214\374$\214\374$\214\374\34" + "\214\374\34\214\374\34\214\374\34\204\374\24\204\374\4\14$\4\24$\4\14" + "$\4\14\34\4\24$\4\14\34\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\4\34,\5I\230\24\204\374\26|\372\34\204\374\24\204\374\24\204\374" + "\14\204\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4t\374\4|\374\4" + "|\374\4t\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\14\204\374\14|\374\14\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\34\204\374\34\214\374$\214\374$\214\374$\214\374,\214\374" + ",\224\374,\224\3744\224\3744\224\3744\224\374<\234\374<\234\374<\234" + "\374<\234\374E\233\374E\233\374E\233\374E\233\374L\244\374L\244\374L" + "\244\374L\244\374L\244\374L\244\374L\244\374L\244\374L\244\374L\244\374" + "L\244\374L\244\374E\233\374E\233\374E\233\374E\233\374<\234\374<\234" + "\374<\234\374<\224\3744\224\3744\224\3744\224\3744\224\374,\214\374," + "\224\374$\214\374$\214\374$\214\374$\214\374\34\214\374\34\214\374\24" + "\204\374\4\24$\4\14$\4\24$\4\24$\4\14$\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\4\4\14\4,X\7e\311\26|\372\34\204\374\34\214\374\34\204\374" + "\24\204\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4" + "|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\14|\374\14|\374\14|\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\34\204\374\34\214\374$\214\374$\214\374$\214\374,\224\374" + ",\214\3744\224\3744\224\3744\224\374<\224\374<\224\374<\234\374E\233" + "\374E\233\374E\233\374E\233\374E\233\374L\244\374L\244\374L\244\374L" + "\244\374L\244\374T\244\374T\244\374T\244\374T\244\374T\244\374T\244\374" + "T\244\374L\244\374L\244\374L\244\374E\233\374E\233\374E\233\374E\233" + "\374E\233\374<\234\374<\234\374<\234\374<\234\3744\224\3744\224\3744" + "\224\374,\224\374,\224\374,\224\374$\214\374$\214\374$\214\374\34\214" + "\374\34\214\374\4\24$\4\24,\4\24$\4\14$\4\4\14\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\4\14\24\4=~\26x\351$\203\373\34\204\374\34\204\374\34" + "\204\374\14\204\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4t\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\14|\374\14\204\374\14\204\374\14\204\374\24\204\374\24" + "\204\374\24\204\374\34\204\374\34\214\374\34\214\374$\214\374$\214\374" + ",\224\374,\224\374,\224\3744\224\3744\224\3744\224\374<\234\374<\234" + "\374<\234\374E\233\374E\233\374E\233\374L\244\374L\244\374L\244\374T" + "\244\374T\244\374T\244\374T\244\374T\244\374T\244\374T\244\374\\\254" + "\374T\244\374\\\254\374T\254\374T\244\374T\244\374T\244\374L\244\374" + "L\244\374L\244\374L\244\374L\244\374E\233\374E\233\374E\233\374<\234" + "\374<\224\374<\234\3744\224\374,\224\3744\224\374,\214\374,\224\374$" + "\214\374$\214\374$\214\374$\214\374\34\214\374\4\24,\4\24,\4\24$\4\4" + "\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\24$\5K\246\34\204\374\34\204" + "\374\34\204\374\34\214\374\34\204\374\14\204\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4t\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\14|\374\14|\374\14\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\34\214\374$\214\374" + "$\214\374$\214\374$\214\374,\224\374,\224\3744\224\3744\224\3744\224" + "\374<\234\374<\234\374<\234\374E\233\374E\233\374E\233\374L\244\374L" + "\244\374L\244\374T\244\374T\244\374T\244\374\\\254\374T\254\374T\244" + "\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254" + "\374\\\254\374\\\254\374T\244\374T\244\374T\244\374T\244\374L\244\374" + "L\244\374L\244\374E\233\374E\233\374E\233\374E\233\374<\234\374<\234" + "\3744\224\3744\224\3744\224\374,\224\374,\224\374$\214\374$\214\374$" + "\214\374\34\214\374\4\24,\4\14$\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\4\35<\31^\270\34\204\374$\203\373\34\214\374\34\214\374\24\204" + "\374\14|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\14\204\374\14\204\374\14\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\34\204\374\34\214\374$\214\374$\214\374$\214\374,\224\374,\224" + "\3744\224\3744\224\3744\224\374<\234\374<\234\374<\234\374E\233\374E" + "\233\374L\244\374L\244\374L\244\374T\244\374T\244\374T\244\374T\254\374" + "\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374\\\254\374T\254\374T\254\374T\244\374T\244\374L\244\374L\244" + "\374L\244\374E\233\374E\233\374E\233\374<\234\374<\234\3744\224\3744" + "\224\3744\224\374,\224\374,\224\374$\214\374$\214\374$\214\374\4\14$" + "\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4,X\32h\327$\203\373\34\204" + "\374$\214\374\34\214\374\24\204\374\14\204\374\4|\374\4|\374\4|\374\4" + "|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\14|\374\14|\374\14|\374\14\204\374\14|\374\24\204" + "\374\24\204\374\24\204\374\34\214\374\34\214\374\34\214\374$\214\374" + "$\214\374$\214\374,\224\374,\214\3744\224\3744\224\374<\224\374<\234" + "\374<\234\374E\233\374E\233\374L\244\374L\244\374L\244\374L\244\374T" + "\244\374T\254\374T\244\374\\\254\374\\\254\374\\\254\374\\\254\374\\" + "\254\374\\\254\374\\\254\374g\252\372g\252\372g\252\372g\252\372g\252" + "\372g\252\372g\252\372g\252\372\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374\\\254\374T\244\374T\244\374L\244\374L\244\374L\244\374E\233" + "\374E\233\374E\233\374<\234\374<\234\374<\224\3744\224\3744\224\374," + "\224\374,\224\374$\214\374$\224\374\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\4\4\14\5""6d\26x\351$\203\373\34\214\374$\214\374\34\214\374\24" + "\204\374\14|\374\14|\374\14|\374\14|\374\14|\374\4|\374\14|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\14\204\374\14|\374\14|\374" + "\14\204\374\14|\374\14\204\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\24\204\374\34\204\374\34\214\374$\214\374$\214\374$\214\374,\224" + "\374,\214\3744\224\3744\224\3744\224\374<\234\374<\234\374<\234\374E" + "\233\374E\233\374E\233\374L\244\374L\244\374T\244\374T\244\374T\244\374" + "\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374g\252\372g\252\372" + "g\252\372l\264\374g\252\372l\264\374g\252\372l\264\374l\264\374l\264" + "\374l\264\374l\264\374g\252\372g\252\372\\\254\374\\\254\374\\\254\374" + "\\\254\374T\244\374T\244\374T\244\374T\244\374L\244\374L\244\374L\244" + "\374E\233\374E\233\374<\234\374<\234\374<\224\3744\224\3744\224\3744" + "\224\374,\224\374,\224\374\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\14\4=~" + "\34\177\364$\203\373$\203\373$\214\374\34\214\374\24\204\374\14|\374" + "\14|\374\14\204\374\14|\374\14|\374\14\204\374\14|\374\14\204\374\14" + "|\374\14\204\374\14|\374\14|\374\14|\374\14|\374\14|\374\14\204\374\14" + "|\374\14\204\374\14\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\34\204\374\34\214\374\34\214\374$\214\374$\214\374$\214\374,\214\374" + ",\224\374,\224\3744\224\3744\224\374<\224\374<\234\374<\234\374E\233" + "\374E\233\374E\233\374L\244\374T\244\374T\244\374T\244\374T\244\374\\" + "\254\374\\\254\374\\\254\374\\\254\374g\252\372g\252\372l\264\374g\252" + "\372l\264\374l\264\374g\252\372l\264\374l\264\374l\264\374l\264\374l" + "\264\374l\264\374l\264\374g\252\372l\264\374g\252\372g\252\372g\252\372" + "\\\254\374\\\254\374\\\254\374\\\254\374T\244\374T\244\374T\244\374T" + "\244\374L\244\374E\233\374E\233\374E\233\374<\234\374<\234\374<\224\374" + "4\224\3744\224\374,\224\374,\214\374\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24" + "\5F\210$\203\373-\203\374$\214\374$\214\374\34\214\374\24\204\374\14" + "|\374\14\204\374\14|\374\14|\374\14\204\374\14\204\374\14\204\374\14" + "\204\374\14|\374\14|\374\14|\374\14\204\374\14|\374\14\204\374\14\204" + "\374\14\204\374\14\204\374\14\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\34\214\374\34\214\374\34\214\374$\214\374$\214" + "\374$\224\374,\224\374,\224\3744\224\3744\224\3744\224\374<\234\374<" + "\234\374E\233\374E\233\374L\244\374L\244\374L\244\374T\244\374T\244\374" + "T\244\374T\244\374\\\254\374\\\254\374\\\254\374g\252\372g\252\372g\252" + "\372l\264\374l\264\374l\264\374l\264\374l\264\374l\264\374l\264\374l" + "\264\374t\264\374t\264\374t\264\374l\264\374l\264\374l\264\374l\264\374" + "l\264\374l\264\374g\252\372g\252\372\\\254\374g\252\372\\\254\374\\\254" + "\374T\244\374T\254\374T\244\374L\244\374L\244\374E\233\374E\233\374E" + "\233\374<\234\374<\234\374<\224\3744\224\3744\224\374,\224\374\0\0\0" + "\0\0\0\0\0\0\4\14\24\5I\230$\203\373-\203\374,\224\374$\214\374$\214" + "\374\24\204\374\14\204\374\24\204\374\24\204\374\14\204\374\24\204\374" + "\14|\374\24\204\374\14\204\374\14|\374\14\204\374\14\204\374\14\204\374" + "\14\204\374\14\204\374\14|\374\24\204\374\24\204\374\14|\374\24\204\374" + "\24\204\374\24\204\374\34\214\374$\214\374$\214\374$\214\374$\214\374" + "$\214\374$\214\374,\224\374,\224\3744\224\3744\224\374<\224\374<\234" + "\374<\234\374E\233\374E\233\374E\233\374L\244\374L\244\374T\244\374T" + "\244\374T\244\374\\\254\374\\\254\374\\\254\374\\\254\374g\252\372g\252" + "\372l\264\374l\264\374l\264\374l\264\374l\264\374t\264\374l\264\374t" + "\264\374t\264\374t\264\374t\264\374t\274\374t\264\374t\274\374t\264\374" + "t\264\374t\264\374l\264\374l\264\374l\264\374l\264\374l\264\374g\252" + "\372g\252\372\\\254\374\\\254\374\\\254\374T\244\374T\244\374T\244\374" + "L\244\374L\244\374E\233\374E\233\374E\233\374<\234\374<\234\374<\224" + "\3744\224\3744\224\374\0\0\0\0\0\0\4\14\34\5I\230$\203\373-\203\374," + "\224\374$\214\374\34\214\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\14\204\374" + "\14|\374\24\204\374\24\204\374\24\204\374\14|\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\34\214\374$\214\374,\224" + "\3744\224\3744\224\3744\224\3744\224\374,\224\374,\214\3744\224\3744" + "\224\374<\224\374<\234\374<\234\374E\233\374E\233\374E\233\374L\244\374" + "L\244\374T\244\374T\244\374T\254\374T\244\374\\\254\374\\\254\374\\\254" + "\374g\252\372g\252\372g\252\372l\264\374l\264\374l\264\374t\264\374l" + "\264\374t\264\374t\264\374t\264\374t\274\374t\264\374t\274\374t\274\374" + "t\264\374t\274\374}\274\377t\264\374t\264\374t\274\374t\264\374t\264" + "\374l\264\374l\264\374g\252\372l\264\374l\264\374g\252\372g\252\372\\" + "\254\374\\\254\374\\\254\374T\244\374T\244\374T\244\374L\244\374L\244" + "\374E\233\374E\233\374<\234\374<\234\374<\224\3744\224\374\0\0\0\4\14" + "\34\5I\230-\203\374,\214\374,\224\374,\214\374$\214\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\24\204\374\14|\374\24\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34\204" + "\374$\214\374,\224\3744\224\3744\224\3745\214\373<\224\374<\224\374<" + "\234\374<\224\3744\224\3744\224\374<\234\374<\234\374E\233\374E\233\374" + "E\233\374L\244\374L\244\374T\244\374T\244\374T\244\374T\244\374\\\254" + "\374\\\254\374\\\254\374g\252\372l\264\374l\264\374l\264\374l\264\374" + "l\264\374t\264\374t\264\374t\264\374t\264\374t\274\374t\274\374}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377t\274\374t\274\374t\264\374t\264\374l\264\374" + "l\264\374l\264\374l\264\374\\\254\374g\252\372\\\254\374\\\254\374\\" + "\254\374T\244\374T\244\374T\244\374L\244\374L\244\374E\233\374E\233\374" + "<\234\374<\234\3744\224\374\4\14\24\5I\230-\203\374,\214\374,\214\374" + ",\224\374\34\214\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\34\214\374\34\214\374$\214\374,\224\3744\224\3744\224\374<\224" + "\3745\214\373'\177\347'\177\347<\224\374E\233\374<\234\374<\224\374<" + "\224\374<\234\374E\233\374E\233\374L\244\374L\244\374T\244\374T\244\374" + "T\244\374T\244\374\\\254\374\\\254\374\\\254\374g\252\372g\252\372l\264" + "\374g\252\372g\252\372l\264\374l\264\374t\264\374l\264\374t\264\374t" + "\274\374t\264\374t\274\374t\264\374t\274\374}\274\377t\274\374}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377t\264\374t\274\374t\264\374t\264\374t\264\374l\264\374l\264\374l" + "\264\374g\252\372g\252\372\\\254\374\\\254\374\\\254\374T\244\374T\244" + "\374T\244\374L\244\374L\244\374E\233\374E\233\374<\234\374<\234\374\30" + "F\210$\203\3735\214\373,\224\374,\214\374$\214\374\34\214\374\24\204" + "\374\34\204\374\34\214\374\34\204\374\24\204\374\34\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\34\214\374\34\204\374\34\214\374\34\214\374\34\214\374$\214" + "\3744\224\3744\224\374<\224\374<\224\3747\204\360\31^\270\5:Y\27@x7\204" + "\360Q\221\372L\244\374E\233\374E\233\374E\233\374E\233\374L\244\374L" + "\244\374T\244\374T\244\374\\\254\374\\\254\374\\\254\374\\\254\374g\252" + "\372g\252\372g\252\372l\264\374g\252\372l\264\374l\264\374l\264\374l" + "\264\374l\264\374l\264\374l\264\374l\264\374t\264\374t\264\374t\264\374" + "t\264\374t\264\374}\274\377t\264\374}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377t\274\374}\274\377t\264\374t\264\374t" + "\264\374l\264\374t\264\374l\264\374l\264\374l\264\374l\264\374g\252\372" + "\\\254\374\\\254\374\\\254\374T\244\374T\244\374T\244\374L\244\374E\233" + "\374E\233\374E\233\374<\234\374,\212\364-\203\374,\224\374,\224\374$" + "\214\374\34\214\374\34\204\374\34\214\374\34\214\374\34\214\374\24\204" + "\374\34\214\374\34\204\374\34\214\374\34\204\374\34\204\374\34\204\374" + "\34\214\374\34\204\374\34\204\374\34\204\374\34\214\374\34\214\374\34" + "\214\374$\214\374,\224\3744\224\3744\224\374<\224\3745\214\373-t\315" + "\30F\210\4\24$\0\0\0\4\14\24(b\246Q\221\372T\244\374L\244\374L\244\374" + "L\244\374L\244\374T\244\374T\244\374\\\254\374\\\254\374\\\254\374\\" + "\254\374\\\254\374g\252\372\\\254\374l\264\374\\\254\374g\252\372g\252" + "\372l\264\374g\252\372l\264\374g\252\372l\264\374l\264\374t\264\374t" + "\264\374t\274\374}\274\377}\274\377\204\274\374\212\304\374\212\304\374" + "\212\304\374\212\304\374\212\304\374\212\304\374\212\304\374\212\304" + "\374\212\304\374\212\304\374\212\304\374\204\274\374\204\274\374}\274" + "\377}\274\377t\264\374t\264\374l\264\374l\264\374l\264\374g\252\372g" + "\252\372g\252\372\\\254\374\\\254\374\\\254\374T\254\374T\244\374T\244" + "\374L\244\374L\244\374E\233\374E\233\3745\214\3734\224\374,\224\374$" + "\214\374\34\214\374\34\214\374\34\204\374\34\214\374\34\204\374\34\214" + "\374\34\214\374\34\204\374\34\214\374\34\204\374\34\214\374\34\204\374" + "\34\214\374\34\204\374\34\214\374\34\214\374\34\214\374\34\214\374$\214" + "\374,\214\3744\224\3744\224\374<\224\374<\224\3747\204\360\31^\270\4" + "$D\4\4\4\0\0\0\0\0\0\0\0\0\14/Q7\204\360]\240\374T\244\374T\244\374T" + "\244\374T\244\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\" + "\254\374g\252\372\\\254\374l\264\374\\\254\374g\252\372\\\254\374\\\254" + "\374\\\254\374g\252\372l\264\374t\264\374}\274\377\204\274\374\212\304" + "\374\230\311\374\230\311\374\230\311\374\246\313\373\234\324\374\246" + "\313\373\246\313\373\246\313\373\251\324\374\251\324\374\251\324\374" + "\251\324\374\251\324\374\246\313\373\246\313\373\246\313\373\246\313" + "\373\234\324\374\230\311\374\230\311\374\212\304\374\212\304\374}\274" + "\377t\264\374l\264\374l\264\374\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374\\\254\374T\244\374T\244\374T\244\374L\244\374E\233\374E\233" + "\3744\224\374,\224\374$\214\374\34\214\374\34\204\374\34\214\374\34\214" + "\374\34\214\374\34\214\374\34\214\374\34\214\374\34\204\374\34\214\374" + "\34\214\374\34\214\374\34\214\374\34\214\374$\214\374$\214\374$\214\374" + "$\214\374$\214\374,\214\3744\224\374<\234\374<\224\374<\224\374-t\315" + "\27@x\4\14\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\31[\231Q\221\372g" + "\252\372\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374\\\254\374" + "\\\254\374l\264\374l\264\374t\264\374\204\274\374\212\304\374\230\311" + "\374\230\311\374\246\313\373\251\324\374\246\313\373\251\324\374\251" + "\324\374\251\324\374\251\324\374\251\324\374\251\324\374\251\324\374" + "\251\324\374\246\313\373\251\324\374\246\313\373\251\324\374\251\324" + "\374\251\324\374\251\324\374\251\324\374\251\324\374\251\324\374\251" + "\324\374\251\324\374\246\313\373\234\324\374\230\311\374\230\311\374" + "\204\274\374}\274\377t\264\374g\252\372\\\254\374\\\254\374T\244\374" + "T\244\374T\254\374T\244\374L\244\374L\244\374E\233\3744\224\374,\214" + "\374$\214\374\34\214\374\34\204\374\34\214\374\34\214\374$\214\374\34" + "\214\374$\214\374\34\214\374\34\214\374\34\214\374$\214\374$\214\374" + "$\214\374$\214\374$\214\374$\214\374$\214\374,\214\3744\224\374<\234" + "\374<\234\374E\233\374<\224\374\31f\306\14/Q\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\14$@G\6YZv\310" + "\374;\225\326\6Z\205\6Z\205\6eu\7IO\6YZ\6eu\6eu\6eu\12j\253\31f\306\5" + "Y\270\34iu\6eu\6Z\205\6Z\205\6Z\230\31^\270\34x\300\34x\300\6Z\230\6" + "Z\230\6Z\205\6Z\230\5Y\270\7e\311\5""6d\4\4\14\0\0\0\0\0\0\0\0\0\0\0" + "\0\26""9Xi\236\352\204\274\374}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377\215\264\374i\236\352\26""9X\0\0\0\0\0\0\0\0\0" + "\0\0\0\14\17\24~\212\244\271\325\373\267\307\352\4\35<\0\0\0\0\0\0\0" + "\0\0\0\0\0\4\35<\6V\251\5[\306\5[\306\6h\330\6h\330\5l\3464\224\374T" + "\244\374T\244\374T\244\3744\224\374\24\204\374\24\204\374\10w\321\5(" + "\31\5>:\7IO\11m\217\6Z\205\6YZ\6eu\6eu\5>:\6YZ\34iu$\200\223\6Z\230\6" + "Z\205\6Z\230\6Z\230\6eu\6Z\205\12j\253\31f\306\5Y\270\5I\230\6Z\205\6" + "Z\205\6Z\230\6Z\230\7u\273\34x\300\6Z\230\6Z\205\11m\217\4\34$\0\0\0" + "\0\0\0\0\0\0\0\0\0\4\14\14""9f\242|\264\374}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377\204\274\374\204\264\3749f\242\4\14\34\0\0" + "\0\0\0\0\0\0\0\0\0\0[aq\267\307\352\306\341\374\310\327\371\4\14\24\0" + "\0\0\0\0\0\0\0\0\0\0\0\5""6l\5Y\270\5[\306\5[\306\7e\311\7e\311\26x\351" + "E\233\374T\244\374T\244\374L\244\374\34\214\374\24\204\374\24\204\374" + "\11Ly\4%\13\4""45\6Kf\6Kf\6eu\30Wb\34iu\6YZ\5>:\7IO\30Wb\6eu\6YZ\11L" + "y\6V\251\30w\330\12j\253\6Z\230\6Z\230\11m\217\5F\210\6eu\5F\210\5I\230" + "\6h\330\31f\306\11m\217\6eu\11m\217G\232\344W\244\352\4""2J\4\14\14\0" + "\0\0\0\0\0\0\0\0\0\0\0\4""2J\\\224\337\204\274\374}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377\215\264\374\\\224\337\14/Q\0\0\0\0\0\0\0" + "\0\0\0\0\0\14\17\24\230\243\270\306\341\374\306\341\374\310\327\371\4" + "\4\4\0\0\0\0\0\0\0\0\0\4\24$\5F\210\5Y\270\5Y\270\5[\306\7e\311\6h\330" + ",\212\364T\244\374T\244\374T\244\3744\224\374\24\204\374\24\204\374\10" + "w\321\5>:\5(\31\5>:(b\246\6Z\205\6Kf\6YZ\6YZ\6YZ\11Ly\11Ly\6Kf\7IO\6" + "Kf\6Z\205\6Z\230\6Z\230\6Kf\6eu\6Z\205\6Z\205\11m\217\31[\231\12j\253" + "\6Z\230\6Z\205\6Z\205\6Z\230\5l\346<\224\374\30w\330\5F\210\6Kf\4$D\4" + "\4\4\0\0\0\0\0\0\0\0\0\0\0\0,V\216w\251\371\204\274\374}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374\204\274" + "\374\204\264\374\204\264\374\204\264\374\204\264\374\204\264\374\204" + "\264\374\214\274\374\204\274\374\204\274\374\204\274\374}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374|\264\374" + "(b\246\4\4\24\0\0\0\0\0\0\0\0\0\0\0\0[aq\253\304\355\310\327\371\306" + "\341\374\271\325\373\0\0\0\0\0\0\0\0\0\0\0\0\4$L\5K\246\5Y\270\5Y\270" + "\5[\306\7e\311\5l\346E\233\374T\244\374T\254\374L\244\374$\214\374\24" + "\204\374\24\204\374\5I\230\4)(\5(\31\4""45\27]\251i\257\351\6eu\6Kf\34" + "iu\34iu\33V\206\11Ly\7IO\6Kf\34iu\34iu\11m\217\11m\217\6eu\6Kf\6Z\205" + "\27]\251\6Z\230\6Z\205\6eu\6eu\5[\3064\224\3743\226\361\5Y\270\5Y\270" + "\5Y\270\11Ly\6eu\5:Y\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\4\34,\\\224\337" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\214\274\374\204" + "\264\374\205\253\372i\236\352\\\224\337O\204\314Ls\266Ls\266Ls\266\\" + "\224\337^\231\357v\236\352\204\264\374\204\264\374\214\274\374\204\274" + "\374}\274\377}\274\377}\274\377}\274\377}\274\377\215\264\374\\\224\337" + "\14$@\0\0\0\0\0\0\0\0\0\0\0\0!$)\230\243\270\310\327\371\306\341\374" + "\310\327\371\310\327\371\0\0\0\0\0\0\0\0\0\4\4\24\5;t\6V\251\5Y\270\5" + "Y\270\5[\306\7e\311\31\207\352T\244\374T\244\374T\244\374<\234\374\24" + "\204\374\24\204\374\10w\321\4,X\5(\31\4)(\4)(\5F\210\227\273\372\11L" + "y\5:Y\7IO\7IO\7IO\6YZ\6YZ\6eu\6Kf\6Kf\11Ly\6Z\205\6Z\230\12j\253\11m" + "\217\6Z\205\6Kf\6Z\230\32h\327)v\367\34x\300\12j\253\12j\253\7u\273\12" + "j\253\6Z\230\6Kf\6eu\5F\210\4,\77\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\27@x" + "w\251\371}\274\377}\274\377\204\274\374\204\274\374\204\264\374i\236" + "\352O\204\3149f\242\32Aj\4,\77\15\37\40\14\14\14\26\26\32\15\37\40\14" + "$@\26""9X$Mz9f\242O\204\314i\236\352\205\253\372\214\274\374\204\274" + "\374\204\274\374}\274\377\204\274\374|\264\374,V\216\4\14\14\0\0\0\0" + "\0\0\0\0\0\4\4\4[aq\274\330\350\310\327\371\306\341\374\306\341\374\310" + "\327\371\0\0\0\0\0\0\0\0\0\4\24,\5F\210\5Y\270\6V\251\5Y\270\5Y\270\6" + "h\330<\224\374T\244\374T\254\374T\244\374$\214\374\24\204\374\26|\372" + "\6Kf\5(\31\4)(\4%\13\4)(\4,\77\234\324\374Ls\266\5>G\5>G\7IO\5>:\4""4" + "5\4""45\7IO\6Z\205\6Z\205\5F\210\5F\210\34iu\7IO\6Z\205\6Z\205,\210\315" + "F\252\354\26\205\251\11m\217\6V\251\5Y\270\6Z\230\11m\217$\200\223\34" + "iu\6eu\5F\210\11Ly\5;t\4\14\34\0\0\0\0\0\0\0\0\0\0\0\0\4\14\14O\204\314" + "\204\274\374\214\274\374\204\264\374i\236\352Ls\266\32Aj\4\34,\4\14\14" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\4\34," + "\26""9X,V\216O\204\314i\236\352\204\264\374\214\274\374\215\264\374O" + "\204\314\14$@\0\0\0\0\0\0\0\0\0\0\0\0,17\250\266\334\306\341\374\306" + "\341\374\306\341\374\306\341\374\310\327\371\0\0\0\0\0\0\0\0\0\4$L\5" + "I\230\5K\246\6V\251\5Y\270\5Y\270\15\202\340E\233\374T\244\374T\244\374" + "E\233\374\34\204\374\24\204\374\26x\351\4,\77\5(\31\4\26\31\5(\31\4)" + "(\4""2J,V\216\271\325\373\5:Y\5>:\4""45\4""45\4""45\30Wb$\200\223$\200" + "\223\11Ly\6Kf\11Ly\6eu\6Z\205,\210\315\6Z\230\6Z\205\6Z\205\11m\217," + "\210\315\26\205\251\6Z\230\11m\217\26\205\251\11m\217\6eu\5I\230\5K\246" + "\\\224\337\11Ly\4$L\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\5:Yi\236\352i\236" + "\352Ls\266\32Aj\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4\34,\32Aj/p\267v\236" + "\352w\251\371$Mz\4\4\14\0\0\0\0\0\0\0\0\0\4\4\4ox\214\274\330\350\306" + "\341\374\306\341\374\306\341\374\310\327\371\271\325\373\0\0\0\0\0\0" + "\4\4\14\5""6d\5K\246\6V\251\5Y\270\5Y\270\5[\306$\214\360T\244\374T\244" + "\374T\244\3744\224\374\24\204\374\24\204\374\6V\251\4\34,\4\26\31\4\26" + "\31\4)(\26""8J\4""45\5>G\224\324\354\214\304\334\7IO\5>:\5>:\5>:\4""4" + "5\7IO\6eu\11Ly\11m\217\26\205\251\33V\206\11Ly\6Z\205\6Z\230\6Z\230\6" + "Z\230\6Z\205\11m\217\12j\253\7e\311\5Y\270\6Z\205\6eu\11Ly\5K\246\27" + "]\251\11Ly\5F\210\5F\210\14$@\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4$Mz\32Aj\4" + "\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\34\26""9" + "X$Mz\4\34""4\0\0\0\0\0\0\0\0\0\0\0\0,17\232\255\332\271\325\373\251\324" + "\374\271\325\373\271\325\373\271\325\373\270\311\367\0\0\0\0\0\0\4\14" + "$\4=~\5K\246\5K\246\5K\246\6V\251\7e\3113\226\361T\244\374T\244\374L" + "\244\374$\214\374\24\204\374\24\204\374\6Kf\4\34$\4\14\14\15\37\40\4" + ")(\5>:\4""45\4""2J\30Wb\306\341\374\30Wb\5>G\4)(\5>:\5>G\6YZ\34iu\11" + "m\217\11m\217\6Z\205\6eu\6Z\205\6Z\205\6Z\230\6Z\230\6Z\230\12j\253\11" + "m\217\6V\251\20X\367\5[\306\6Z\205\6eu\5F\210\5K\246;\225\326W\244\352" + "g\252\372W\244\352\33V\206\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4\14\34\4\14\34\4" + "\14\34\4\14\34\4\14\24\14\14\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14ox\214\253\304" + "\355\270\311\367\271\325\373\251\324\374\271\325\373\270\311\367\270" + "\311\367\0\0\0\0\0\0\4\35<\5F\210\5K\246\5K\246\6V\251\6V\251\30w\330" + "E\233\374T\244\374\\\254\374E\233\374\34\204\374\24\204\374\31\207\352" + "\7IO\4\26\31\4%\13\14\14\14\5>G\4)(\5>G\4,\77\5>:Ls\266\34iu\7IO\5>:" + "\7IO\6YZ$\200\223$\200\223\6eu\6eu\6Z\205\6eu$\200\223\11m\217\11m\217" + "\6Z\230\11m\217\26\205\251;\225\326\6Z\230\32c\347E\233\374$\200\223" + "\6Z\205)v\3677c\367\31f\306;\225\326/p\267\5I\230\5F\210\4\35<\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\14" + "\4\24$\4\34E\5*f\4=~\26D\226\34L\24249\221ox\214EMW!$)\14\14\14\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0,17\232\255" + "\332\270\311\367\270\311\367\251\324\374\270\311\367\271\325\373\270" + "\311\367\270\311\367\0\0\0\4\4\4\4,X\5I\230\5K\246\5K\246\6V\251\5Y\270" + "\26x\351L\244\374T\244\374T\244\374,\224\374\24\204\374\24\204\374\12" + "j\253\5>:\4)(\4%\13\4%\13\4)(\5>G\4$L\4""2J\5:Y\5>:$\200\223\6YZ\5>:" + "\5>:\6YZ\6YZ\6eu\6eu\11m\217\11m\217\11m\217\6Z\205\6Z\205\6Z\205\6Z" + "\230\12j\253\6Z\230\12j\253\5K\246Iw\371H\210\355\6Z\205\12j\253jt\371" + "Iw\371\5I\230\5F\210\5F\210/p\267\5F\210\33V\206\4\24$\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\4\34,\14/Q\17""3v\26D\226" + "\31[\231\34x\300\31f\306\32h\3277S\323\377\377\377\355\357\373\266\276" + "\323ox\214EMW!$)\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\26\26" + "\32~\212\244\267\307\352\270\311\367\271\325\373\271\325\373\271\325" + "\373\271\325\373\270\311\367\270\311\367\0\0\0\4\14\24\5""6l\5I\230\5" + "I\230\5K\246\5K\246\5Y\270'\177\347T\244\374\\\254\374T\244\374$\214" + "\374\24\204\374\24\204\374\6Z\230\4""45\4""45\5(\31\4""45\7IO~\212\244" + "\27@xl\215\315l\215\315\5:Y\34iu\7IO\5>:\6YZ\6YZ\6YZ\6eu\11m\217\26\205" + "\251\12j\253\6Z\205\6Z\230\12j\253\12j\253\31^\270\6V\251\6Z\205\5Y\270" + "X^\367Iw\371\5K\246\6Z\230\34x\300\7e\311\6V\251\5F\210\31^\270G\232" + "\344/p\267\6Z\205(b\246\5:Y\4\34,\4\14\24\0\0\0\0\0\0\0\0\0\4\4\4\4\14" + "\24\4\34$\15.C\32Aj\5;t\4=~,V\216\31[\231(b\246\5K\246\31^\2707S\323" + "\355\357\373\377\377\377\355\357\373\355\357\373\326\332\353\230\243" + "\270[aq!$)\14\14\14\0\0\0\0\0\0\0\0\0\4\4\14!$)ox\214\267\307\352\271" + "\325\373\271\325\373\271\325\373\271\325\373\271\325\373\271\325\373" + "\271\325\373\270\311\367\0\0\0\4\24$\4=~\5I\230\5I\230\5K\246\6Z\230" + "\5Y\270=\216\361T\244\374T\254\374E\233\374\34\214\374\24\204\374\26" + "|\372G\4""45\4""45\4""45\4""45\5:Y\4,\77i\236\352\215\264\374" + "\5:Y\7IO\6YZ\7IO\7IO\6YZ\6eu\11m\217\11m\217\12j\253\26\205\251'\177" + "\347\6V\251\6V\251\30w\330T\244\374]\240\374\32c\347Q\221\372jt\371Z" + "\200\345\5F\210\11m\217\7u\273\5[\306<\224\374\32h\327\5F\210\6Z\205" + "\6Kf\6Z\205,\210\315\6Kf\5F\210\27@x\5#V\4\24,\4\24,\4)(\4,\77\4""2J" + "\5""6l\30F\210\33V\206\5*f\4$L\4$D\15.C\4\34""4\4\35<\14$@[aq~\212\244" + "\230\243\270\266\276\323\326\332\353\326\332\353\324\324\334\230\243" + "\270ox\214EMW,17EMW[aq\230\243\270\267\307\352\270\311\367\310\327\371" + "\310\327\371\271\325\373\306\341\374\306\341\374\306\341\374\310\327" + "\371\310\327\371\0\0\0\4\24""4\5F\210\5I\230\5I\230\5K\246\6V\251\7e" + "\311E\233\374T\244\374\\\254\374<\234\374\34\204\374\24\204\374)v\367" + "\227\273\372\4""45\4)(\4""45\5>:\5>:\5>:\5>:\5>:\12j\253\7u\273\6eu\6" + "eu\6eu\6eu\6eu$\200\223\11m\217\7u\273\26x\351\25N\344\26\205\251\7u" + "\273-\203\374\204\224\373\233\255\373H\210\355)v\367Iw\371\34\204\374" + "\12j\253\6Z\205\32c\347]\240\374'\177\347\7e\311(\246\275\11m\217\6Z" + "\230\11Ly\246\313\373\214\304\354\6Kf\6Z\230\34x\300\5:Y\5:Y\5>G\6Kf" + "\6eu\30Wb\30Wb\14$@\4\24$\4\14\24\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0" + "\4\4\4\14\14\14\26\26\32,17[aq~\212\244\266\276\323\324\324\334\324\324" + "\334\266\276\323\266\276\323\266\276\323\306\313\352\270\311\367\306" + "\313\352\267\307\352\271\325\373\271\325\373\271\325\373\271\325\373" + "\271\325\373\271\325\373\270\311\367\270\311\367\0\0\0\4$D\5F\210\5I" + "\230\5I\230\5I\230\5K\246\30w\330E\233\374T\244\374T\244\374,\224\374" + "\24\204\374\14\204\374\25N\344O\204\314\5:Y\4)(\4""45\5>:\5>:\7IO\5>" + ":\6YZ\6Z\205\12j\253\11m\217\6eu\6eu\11m\217\11m\217\26\205\251\26\205" + "\251\7u\273\10w\321\7e\311\5K\246\26x\351)v\367:\5>G\5>:\6" + "Kf\6V\251\7u\273\26\205\251\6eu\11m\217(\246\275(\246\275\17\214\304" + "\10w\321\6B\3127c\367\204\224\373u\210\372Iw\371\25N\344\5I\230\5Y\270" + "\7e\311\5[\306\5Y\270,\210\315\11m\217\7e\311%V\370%V\370%V\370)v\367" + "v\310\374\17\214\304\34x\300\31[\231\33V\206\7IO\6YZ\11m\217(\246\275" + "$Mz\6Kf\6Kf\4\34""4\4\14\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\14" + "\14\14EMW\230\243\270\326\332\353\306\313\352\311\324\353\310\327\371" + "\267\307\352\267\307\352\270\311\367\271\325\373\271\325\373\271\325" + "\373\271\325\373\271\325\373\270\311\367\270\311\367\4\4\24\5""6d\5I" + "\230\5I\230\5I\230\5I\230\5Y\270,\212\364L\244\374T\244\374L\244\374" + "\34\214\374\24\204\374$\214\374u\210\372\31^\270\7IO\5>G\30Wb\5>:\7I" + "O\5>G\7IO\7IOG\232\344\12j\253\7u\273\11m\217(\246\275\26\205\251\5K" + "\2467S\323\204\224\373\204\224\373Iw\371%V\370\5K\246\5[\306\6V\251\7" + "e\311)v\367\26r\367$\203\373\5[\306\12j\253\34x\300u\210\372X^\367%V" + "\370\6h\330\7u\273\17\214\304\11m\217\6eu\6Kf\7IO\6YZ\6eu\6eu\34iu\5" + ";t\5:Y\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4" + "\14\14\4\4\14\4\14\14\4\14\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0,17\230\243\270\306\313\352\306\313\352\310\327\371\306" + "\312\367\267\307\352\271\325\373\271\325\373\251\324\374\271\325\373" + "\271\325\373\271\325\373\270\311\367\270\311\367\4\14\34\5""6l\5I\230" + "\5I\230\5I\230\5I\230\5[\3065\214\373L\244\374T\244\374E\233\374\34\204" + "\374\24\204\374\10w\321}\274\377Q\221\372\7IO\5>:\5>:\6YZ\7IO\5>:\7I" + "O\7IO0\212\341\12j\253\6Z\230\7u\273\6B\3127c\367u\210\372\204\224\373" + "jt\371-t\315\7e\311\17\214\304\4|\3637\250\374\10w\321\6h\330\6B\312" + "\6B\312Iw\371\31f\306\5I\230:\5>G\5>G\4""2J\7IO\7IO\5Y\270" + "\5[\3060\212\341T\244\374%V\3707c\367\26r\367\10w\321\7u\273\17\214\304" + "\15\202\340\24\204\374\34\214\374\10w\321\6V\251\32c\347Iw\371u\210\372" + "Z\200\345\5I\230\5Y\270'\177\347\17\214\304\11m\217\6Z\230\11m\217\6" + "eu$\200\223\26\205\251\34iu\11Ly\6Z\205\6eu\6Z\205\6Kf\5:Y\4\34$\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\24$\32AjLs\266\\\224\337i\257\351" + "l\264\374|\264\374t\264\374t\264\374g\252\372\\\224\337Ls\266,V\216\4" + "\34""4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\26\26\32~\212\244\271\325" + "\373\306\313\352\267\307\352\270\311\367\270\311\367\251\324\374\271" + "\325\373\271\325\373\271\325\373\270\311\367\270\311\367\4\24,\4=~\5" + "I\230\5I\230\5I\230\6V\251\30w\330<\224\374L\244\374T\244\374,\224\374" + "\24\204\374\24\204\374\30w\330\11LyIw\371\4,\77\4)(\5(\31$\200\223\5" + ">G\7IO\7IO\34iu\34x\300\6h\330L\244\374T\244\374\4\224\374\17\214\304" + "\7u\273\7u\273\26x\351\26r\367\4t\364\6h\330\6h\330\5I\230\5Y\270\24" + "\204\364$\214\374T\244\374\27]\251\12j\253\34\304\344\7u\273\5F\210\6" + "Z\205\17\214\304(\246\275$\200\223$\200\223\11Ly\7IO\7IO\6Z\205$\200" + "\223\26\205\251\34iu\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\26""9" + "XLs\266g\252\372\204\264\374\204\264\374\204\274\374\204\274\374\204" + "\274\374\204\274\374\204\264\374\204\274\374\204\264\374\204\264\374" + "t\264\374O\204\314$Mz\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0,17\230\243" + "\270\267\307\352\267\307\352\270\311\367\251\324\374\270\311\367\251" + "\324\374\251\324\374\271\325\373\270\311\367\270\311\367\4\34""4\5F\210" + "\5I\230\5K\246\5I\230\6V\251\26x\351<\224\374L\244\374L\244\374,\214" + "\374\24\204\374\24\204\374l\264\374\6YZ\31f\306\4)(\4""45\5(\31\4=~\5" + ">G\5>G\5>:\6YZ\34x\300\6Z\230\7e\311\6Z\230\26\205\251\7u\273$\224\374" + "-\203\374\6h\330\5[\306\7e\311\4t\374v\236\352\233\255\373^\231\357\24" + "\204\364\10w\321\12j\253\6Z\230\7u\273$\200\223\6Z\230\12j\253\17\214" + "\304\4\220\344\7u\273\11m\217\11Ly\5;t\4=~\31[\231\31[\231\6eu\6Kf\4" + "\34,\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\14,V\216i\236\352}\274\377\204" + "\274\374\204\274\374}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377\204\274\374\204\264\374g\252\3729f\242" + "\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0EMW\250\266\334\267\307\352\270\311" + "\367\270\311\367\251\324\374\270\311\367\271\325\373\271\325\373\270" + "\311\367\270\311\367\4\34E\5F\210\5K\246\5I\230\5I\230\5K\246'\177\347" + "E\233\374L\244\374E\233\374$\214\374\24\204\374\24\204\364/p\267<\224" + "\374\26x\351\11m\217\26\205\251\5>G\4\34,\4""45\4,\77\4""2J\7IO\11Ly" + "\12j\253\7u\273\10w\321\4|\374\14\204\374\10w\321\17\214\304\15\202\340" + "\14|\374\27""1\352\27""1\352,\224\374\14}\362\10w\321\10w\321(\246\275" + "\26\205\251\12j\253\12j\253\6Z\230\6V\251\11m\217\26\205\251\11m\217" + "\26\205\251\6Z\205\6YZ\5Y\270\12j\253\6Z\205\6eu\6eu\6Kf\4\14\24\0\0" + "\0\0\0\0\0\0\0\0\0\0\4\4\4,V\216w\251\371\204\274\374}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377\204\274\374\204\274\374|\264\374Ls\266" + "\14\34,\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4ox\214\267\307\352\267\307\352\253" + "\304\355\270\311\367\246\313\373\251\324\374\270\311\367\270\311\367" + "\270\311\367\4$L\5I\230\5I\230\5K\246\5I\230\5Y\270'\177\347<\224\374" + "L\244\374E\233\374\34\214\374\24\204\374\30w\330\11Ly,\210\315\7u\273" + "(\246\275$\200\223\5>G\5(\31\4%\13\4""2J\26""9X\5>:\6Kf\34x\300,\234" + "\3745\214\373\24\204\364\15\202\340\10w\321\34\177\364E\233\374Q\221" + "\372\26r\367\10w\321\17\214\304\7u\273\7u\273\12j\253\26\205\251\26\205" + "\251\6Z\230\5Y\270;\225\326\6Z\230\12j\253\11m\217\11m\217l\264\374\6" + "Z\205\34iu$\200\223\11m\217\6Z\205\6Z\205\34x\300\15.C\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0$Mzw\251\371\204\274\374}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374\204\264\374" + "9f\242\4\26\31\0\0\0\0\0\0\0\0\0\0\0\0,17\230\243\270\253\304\355\270" + "\311\367\253\304\355\251\324\374\251\324\374\271\325\373\270\311\367" + "\270\311\367\4$L\5I\230\5K\246\5K\246\5K\246\5Y\270$\214\360E\233\374" + "L\244\374<\234\374\34\214\374\24\204\374\10w\321\4,\77\11Ly\6YZ$\200" + "\223\5>:\5(\31\15\37\40\5(\31\4,X$Mz\34iu\6YZ\6Z\205\11m\217\12j\253" + "\17\214\3047\250\374\205\253\372g\252\372<\224\374\7u\273\17\214\304" + "\17\214\304\17\214\304\7u\273\26\205\251\7u\273\11m\217\6V\251\7e\311" + "\32h\327\6Z\205\6V\251\30w\330F\252\354\10w\321T\254\374\6Z\230\6eu\6" + "eu\12j\253\12j\253\12j\253\11Ly\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\15.C" + "\\\224\337\204\274\374}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377\214\274\374w\251\371$M" + "z\4\14\14\0\0\0\0\0\0\0\0\0\4\4\14ox\214\253\304\355\253\304\355\246" + "\313\373\270\311\367\251\324\374\270\311\367\270\311\367\246\313\373" + "\4,X\5K\246\5K\246\6V\251\5K\246\7e\311,\212\364E\233\374E\233\374<\224" + "\374\34\204\374\26|\372\31^\270\4""2J\4""45\7IO\7IO\4""45\5(\31\4)(\4" + "%\13\4)(\4,\77\5>G\6YZ\6Kf\7u\2737\250\374\6YZ\6eu\17\214\304\12j\253" + "\7u\273\11m\217\26\205\251(\246\275\12j\253\7u\273\6Z\2300\212\341\7" + "u\273\11m\217\7e\311\6Z\230\6V\251t\264\374\34x\300\26\205\251\26\205" + "\251\6eu\6Z\205\6Z\205\5Y\270\6V\251\6Z\205\6Z\205\5>G\4\4\4\0\0\0\0" + "\0\0\0\0\0\4\4\4/p\267\215\264\374}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377\215\264\374\\\224\337\14$@\0\0\0\0\0\0\0\0\0\0\0\0EMW\250\266" + "\334\253\304\355\251\324\374\251\324\374\251\324\374\271\325\373\270" + "\311\367\270\311\367\5*f\6V\251\5Y\270\6V\251\5Y\270\6h\330,\214\374" + "<\224\374E\233\374<\224\374\34\204\374\26|\372\6V\251\4\34""4\4)(\30" + "Wb\4""45\4""45\4\34$\4\26\31\4%\13\4)(\4)(\26""8J\6YZ\6Kf\12j\253\26" + "\205\251\6YZ\6eu(\246\275\26\205\251\26\205\251\11m\217\6Z\230\6Z\230" + "\32c\347Iw\371'\177\347\7e\311\11m\217\26\205\251F\252\354\30w\330i\257" + "\351\12j\253\6Z\205\26\205\251\11m\217\26\205\251v\310\374\6eu\6Z\205" + "\11m\217\6Z\205\6eu\4\34""4\0\0\0\0\0\0\0\0\0\0\0\0\4,Xw\251\371}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374w\251\371,V" + "\216\4\14\24\0\0\0\0\0\0\0\0\0!$)\230\243\270\253\304\355\270\311\367" + "\246\313\373\251\324\374\251\324\374\246\313\373\270\311\367\4\24$\4" + "$D\4$D\4\34E\4$D\4,X\5""6l\32Aj\32Aj\32Aj\5""6l\5""6l\4,X\4\14\34\4\14" + "\24\4\26\31\4\14\14\4\14\14\4\14\14\4\14\14\4\14\14\4\14\24\4\26\31\4" + "\26\31\4\26\31\14$@\14/Q\4)(\4)(\4)(\15.C\4""45\5>:\5>G\5:Y\5#V\5#V\5" + "#V\5#V\4\35<\4\35<\30Wb\4""2J\4,\77\4\34""4\4\35<\4\35<\4""45\6YZ\6K" + "f,\210\315\6Z\205\11m\217\11m\217\6Z\230\31[\231\14\34,\0\0\0\0\0\0\0" + "\0\0\0\0\0""9f\242|\264\374}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377\204\274\374\204\264\374O\204\314\14\34,\0\0\0\0\0\0\0\0\0\14" + "\17\24~\212\244\253\304\355\246\313\373\251\324\374\251\324\374\270\311" + "\367\232\255\332~\212\244\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4" + "\4\4\4\4\14\0\0\0\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\4\0\0\0" + "\4\4\4\0\0\0\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\4\4\4\4\4\4\0\0\0\0\0\0\4\14\14\4\14\24\4,\77\6Kf\6" + "Z\205\34x\300\34x\300\11Ly\4\14\24\0\0\0\0\0\0\0\0\0\4\34,G\232\344\204" + "\274\374}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\214" + "\274\374i\236\352\26""9X\0\0\0\0\0\0\0\0\0\4\4\4[aq\243\275\346\246\313" + "\373\251\324\374\243\275\346[aq!$)\14\17\24\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\4\24""4\6Kf\11m\217\11m\217\4""2J\4\4\4\0\0\0\0\0\0\0\0\0\14" + "$@i\236\352}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377\204\274\374w\251\371$Mz\4\4\4\0\0\0\0\0\0\0\0\0EMW\232\255" + "\332\246\313\373\243\275\346EMW\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\4\34,\6Kf\11Ly\4\35<\0\0\0\0\0\0\0\0\0\0\0\0\26" + "8Jv\236\352}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377\204\264\374\204\264\364,V\216\4\14\14\0\0\0\0\0\0\0\0\0""0" + "8P\232\255\332\251\324\374ox\214\4\14\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\26\31\5:Y\6Kf\4\34""4\0\0\0\0\0\0\0" + "\0\0\0\0\0\32Ajz\257\352}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377\204\274\374\204\264\3649f\242\4\14\24\0\0" + "\0\0\0\0\0\0\0,17\214\304\334\253\304\355EMW\0\0\0\0\0\0\0\0\0\0\0\0" + "\5""6l\5;t\5""6l\32Aj\5""6l\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32" + "Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32" + "Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32Aj\32" + "Aj\32Aj\32Aj\32Aj\32Aj\27@x\26""9X\4\24,\0\0\0\0\0\0\0\0\0\4\4\14\5:" + "Y\5""6l\4\34""4\4\4\4\0\0\0\0\0\0\0\0\0\32Ajz\257\352}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374\204" + "\264\3749f\242\4\14\14\0\0\0\0\0\0\0\0\0,17\243\275\346\232\255\332," + "17\0\0\0\0\0\0\0\0\0\4\14\24Q\221\372H\210\355Q\221\372Q\221\372Q\221" + "\372^\231\357w\251\371\204\264\364\204\264\364\204\264\364w\251\371w" + "\251\371w\251\371w\251\371g\252\372i\236\352g\252\372i\236\352g\252\372" + "i\236\352g\252\372i\236\352g\252\372i\236\352g\252\372i\236\352g\252" + "\372i\236\352g\252\372i\236\352g\252\372i\236\352g\252\372i\236\352g" + "\252\372i\236\352g\252\372i\236\352g\252\372i\236\352g\252\372i\236\352" + "g\252\372i\236\352g\252\372i\236\352w\251\371Q\221\372\5""6l\4\4\4\0" + "\0\0\0\0\0\0\0\0\4,\77\5;t\26""8J\4\4\4\0\0\0\0\0\0\0\0\0""08Pv\236\352" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "\204\264\374\204\264\364$Mz\14\14\14\0\0\0\0\0\0\0\0\0""08P\243\275\346" + "\230\243\270\15\37\40\0\0\0\0\0\0\0\0\0\4\35<]\240\374\\\254\374\\\254" + "\374g\252\372\\\254\374l\264\374\214\274\374\230\311\374\246\313\373" + "\230\311\374\214\274\374\214\274\374\214\274\374\204\264\374\204\264" + "\374\204\274\374\204\264\374\204\274\374\204\264\374\204\274\374\204" + "\264\374\204\274\374\204\264\374\204\274\374\204\264\374\204\274\374" + "\204\264\374\204\274\374\204\264\374\204\274\374\204\264\374\204\274" + "\374\204\264\374\204\274\374\204\264\374\204\274\374\204\264\374\204" + "\274\374\204\264\374\204\274\374\204\264\374\204\274\374\204\264\374" + "\204\274\374\204\274\374\204\274\374\215\264\374l\264\374$Mz\4\4\14\0" + "\0\0\0\0\0\0\0\0\4,\77\5:Y\4""2J\4\4\14\0\0\0\0\0\0\0\0\0\4$D^\231\357" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "\204\264\374w\251\371$Mz\4\4\4\0\0\0\0\0\0\0\0\0EMW\246\313\373~\212" + "\244\26\26\32\0\0\0\0\0\0\0\0\0\4$D\\\254\374\\\254\374\\\254\374\\\254" + "\374\\\254\374g\252\372\204\274\374\230\311\374\230\311\374\212\304\374" + "\212\304\374\212\304\374\212\304\374}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\264\374" + "|\264\364$Mz\4\4\4\0\0\0\0\0\0\0\0\0\26""8J\5:Y\4""2J\4\14\24\0\0\0\0" + "\0\0\0\0\0\4\24$\\\224\337\204\274\374}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377\214\274\374i\236\352\26""9X\0\0\0\0\0\0\0" + "\0\0\4\4\4ox\214\251\324\374ox\214\14\17\24\0\0\0\0\0\0\0\0\0\14$@T\244" + "\374T\244\374\\\254\374\\\254\374\\\254\374\\\254\374}\274\377\230\311" + "\374\230\311\374\230\311\374\212\304\374\214\274\374\204\274\374}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377\204\264\374\204\264\374$Mz\14\14\14\0\0\0\0\0\0\0\0" + "\0\26""8J\6Kf\7IO\4\26\31\0\0\0\0\0\0\0\0\0\0\0\0""9f\242|\264\374}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374\204\264\374" + "O\204\314\14\34,\0\0\0\0\0\0\0\0\0\26\26\32~\212\244\251\324\374ox\214" + "\4\14\24\0\0\0\0\0\0\0\0\0\26""8JT\244\374T\244\374T\244\374T\244\374" + "T\244\374\\\254\374}\274\377\230\311\374\230\311\374\230\311\374\212" + "\304\374\212\304\374\212\304\374}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\274\374\204" + "\264\3749f\242\4\14\24\0\0\0\0\0\0\0\0\0\4\24$\5>G\6eu\4""45\0\0\0\0" + "\0\0\0\0\0\0\0\0\4,Xi\236\352\204\274\374}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377\214\274\374w\251\371$Mz\4\14\14\0\0\0\0\0\0\0\0\0," + "17\232\255\332\251\324\374[aq\4\4\14\0\0\0\0\0\0\0\0\0\32AjL\244\374" + "T\244\374T\244\374\\\254\374\\\254\374\\\254\374t\264\374\212\304\374" + "\230\311\374\230\311\374\212\304\374\212\304\374\212\304\374}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377\204\274\374\204\264\374/p\267\4\34,\0\0\0\0\0\0\0\0\0!" + "$)\5>G\5""6l\26""8J\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0/p\267\204\264\374}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377\204\274\374\215\264\374O\204\314\14$" + "@\0\0\0\0\0\0\0\0\0\0\0\0EMW\241\264\345\253\304\355EMW\4\4\4\0\0\0\0" + "\0\0\0\0\0\33V\206T\244\374T\244\374T\244\374T\244\374T\244\374T\244" + "\374t\264\374\212\304\374\230\311\374\230\311\374\212\304\374\212\304" + "\374\212\304\374\204\274\374}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377\204\264\374O\204\314" + "\14\34,\0\0\0\0\0\0\0\0\0\4\14\14\5:Y\5:Y\4$D\4\4\14\0\0\0\0\0\0\0\0" + "\0\0\0\0\14$@\\\224\337\204\264\374}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\215\264\374" + "i\236\352$Mz\4\4\4\0\0\0\0\0\0\0\0\0\4\14\14ox\214\271\325\373\266\276" + "\32308P\0\0\0\0\0\0\0\0\0\4\4\4""9f\242L\244\374T\244\374T\244\374T\244" + "\374\\\254\374T\244\374l\264\374\212\304\374\230\311\374\230\311\374" + "\212\304\374\212\304\374\212\304\374\204\274\374}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\215" + "\264\374\\\224\337\25*H\0\0\0\0\0\0\0\0\0\0\0\0\4)(\5>G\5""6d\4\24$\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27@xw\251\371\204\274\374}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\214\274" + "\374|\264\3749f\242\4\14\34\0\0\0\0\0\0\0\0\0\0\0\0,17\232\255\332\306" + "\341\374\230\243\270!$)\0\0\0\0\0\0\0\0\0\4\14\34Ls\266L\244\374L\244" + "\374T\244\374T\244\374T\244\374T\244\374\\\254\374\204\274\374\230\311" + "\374\230\311\374\212\304\374\212\304\374\212\304\374\212\304\374}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377\214\274\374t\264\374\32Aj\4\4\14\0\0\0\0\0\0\0\0\0" + "\4\34,\4""2J\5""6d\4$L\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$Mzw\251" + "\371\204\264\374}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377\204\264\374|\264\3749f\242\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\14\14\14" + "ox\214\271\325\373\306\341\374ox\214\14\14\14\0\0\0\0\0\0\0\0\0\4$DO" + "\204\314L\244\374L\244\374L\244\374T\244\374T\244\374T\244\374T\244\374" + "}\274\377\230\311\374\212\304\374\230\311\374\212\304\374\212\304\374" + "\212\304\374}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377\204\274\374|\264\3749f\242\4\14\24\0" + "\0\0\0\0\0\0\0\0\26\26\32$Mz\32Aj\6Kf\4\34""4\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\4\4\4$Mz\\\224\337|\264\374\204\274\374}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\204" + "\274\374\204\264\374i\236\3529f\242\4\26\31\0\0\0\0\0\0\0\0\0\0\0\0\4" + "\4\4EMW\274\330\350\335\345\373\241\264\34508P\0\0\0\0\0\0\0\0\0\0\0" + "\0\26""9Xi\236\352L\244\374L\244\374L\244\374T\244\374T\244\374T\244" + "\374T\244\374t\264\374\212\304\374\230\311\374\212\304\374\212\304\374" + "\214\274\374\212\304\374\204\274\374}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\215\264\374" + "O\204\314\4\34""4\0\0\0\0\0\0\0\0\0\0\0\0\4,\77\5:Y\5:Y\5:Y\4\34,\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\14/Q/p\267i\236\352\205\253\372\204" + "\274\374\204\264\374\204\274\374\204\274\374\204\274\374\204\274\374" + "\204\274\374\204\264\374\204\264\374v\236\352O\204\314\32Aj\4\14\24\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0,17\266\276\323\306\341\374\306\341\374L" + "s\266\21\24$\0\0\0\0\0\0\0\0\0\0\0\0""9f\242|\264\364L\244\374L\244\374" + "L\244\374L\244\374T\244\374T\244\374L\244\374g\252\372\212\304\374\212" + "\304\374\230\311\374\212\304\374\212\304\374\212\304\374\204\274\374" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377\214\274\374g\252\372\26""9X\4\4\4\0\0\0\0\0\0" + "\0\0\0\4\14\24\5""6d\5""6l\6Kf\5:Y\4\34,\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\4\26\31\26""9X9f\242\\\224\337i\236\352w\251\371g\252\372w\251" + "\371g\252\372v\236\352\\\224\337Ls\266\32Aj\4\24$\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0!$)\230\243\270\306\341\374\224\324\354\213\242\3430" + "8P\0\0\0\0\0\0\0\0\0\0\0\0\4\34,O\204\314\204\264\374E\233\374E\233\374" + "L\244\374L\244\374L\244\374T\244\374L\244\374\\\254\374\204\274\374\212" + "\304\374\212\304\374\212\304\374\212\304\374\212\304\374\204\274\374" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377\204\274\374\205\253\3729f\242\4\14\34\0\0\0\0" + "\0\0\0\0\0\0\0\0\4\34""4\4=~\5F\210\27]\251\5;t\4\24,\4\4\4\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\24\14$@\26""8J$Mz\31[\231\31[\231$Mz" + "\26""9X\14$@\4\24$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!$)\230\243" + "\270\306\341\374\246\313\373u\210\37249\221\14\16\34\0\0\0\0\0\0\0\0" + "\0\0\0\0\27@xi\236\352\204\274\374E\233\374L\244\374L\244\374L\244\374" + "L\244\374L\244\374L\244\374T\244\374}\274\377\212\304\374\230\311\374" + "\212\304\374\212\304\374\212\304\374\204\274\374}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377\215\264\374\\\224\337\14/Q\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4," + "X\6Z\230\6V\251\31f\306(b\246\25*H\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\4\14\14\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4,17\230\243\270Q\221\3727\204\360\233" + "\255\373~\212\244\20\24,\0\0\0\0\0\0\0\0\0\0\0\0\4\26\31Ls\266\204\264" + "\374}\274\377E\233\374E\233\374E\233\374E\233\374L\244\374L\244\374L" + "\244\374L\244\374t\264\374\212\304\374\212\304\374\212\304\374\212\304" + "\374\212\304\374\212\304\374}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}" + "\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377" + "}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274" + "\377}\274\377}\274\377}\274\377}\274\377}\274\377}\274\377\214\274\374" + "\204\264\3749f\242\4\14\24\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\5""6d,\210" + "\315\5K\246\5I\230\5I\230\4""2J\4\14\34\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\14\16\34[aq\266\276\323\241\264\345" + "G\5""6d\6V\251\26x\351\24\204\374\14\204\374\24\204\374\34\204\374,\214" + "\374<\234\374E\233\374E\233\374E\233\374E\233\374E\233\3745\214\373\30" + "w\330\7e\311\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\5K\246" + "\6V\251\5K\246\6V\251\5K\246\5K\246\5K\246\5K\246\5K\246\5I\230\5K\246" + "\5K\246\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230" + "\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230\5I\230" + "\5I\230\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246" + "\5K\246\6V\251\6V\251\6V\251\6V\251\6V\251\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5Y\270\5Y\270\5[\306\5[\306\5[\306\5[\306\5[\306\7e\311" + "\7e\311\7e\311\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346\6h\330\5l\346" + "\5l\346\5:Y\4""2J\4""2J\5>G\5:Y\5:Y\6Z\205\31f\306\14}\362\24\204\374" + "\24\204\374\24\204\374$\214\3744\224\374E\233\374E\233\374E\233\374E" + "\233\374E\233\374E\233\3745\214\373\26x\351\7e\311\5Y\270\6V\251\6V\251" + "\5Y\270\5Y\270\6V\251\5Y\270\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251" + "\6V\251\6V\251\5K\246\5K\246\6V\251\5K\246\5K\246\5K\246\5K\246\5K\246" + "\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246\5K\246" + "\6V\251\5K\246\5K\246\6V\251\5K\246\6V\251\5K\246\6V\251\6V\251\6V\251" + "\6V\251\6V\251\6V\251\6V\251\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5[\306\5[\306\5[\306\5[\306\5[\306\7e\311\5[\306\7e\311" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346\5l\346\5l\346" + "\5l\346\5l\346\5t\352\4t\364\4,X\4""2J\4""2J\5:Y\5:Y\5:Y\5:Y\5:Y\31[" + "\231\10w\321\24\204\364\24\204\374\14\204\374\24\204\374$\214\3744\234" + "\374E\233\374L\244\374L\244\374L\244\374E\233\374L\244\374<\224\374\31" + "\207\352\6h\330\5[\306\6V\251\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\6V\251\6V\251\6V\251\5Y\270\6V\251" + "\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251\6V\251" + "\6V\251\6V\251\6V\251\6V\251\6V\251\5Y\270\6V\251\5Y\270\6V\251\5Y\270" + "\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\7e\311\7e\311\7e\311" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346\5l\346\5l\346" + "\5l\346\5l\346\5t\352\5t\352\4t\364\4t\364\4t\364\5:Y\4""2J\4""2J\5>" + "G\5:Y\5:Y\5:Y\5:Y\6Kf\6Kf\6Z\230\26x\351\24\204\364\24\204\374\24\204" + "\374\24\204\374$\214\374<\224\374E\233\374L\244\374L\244\374L\244\374" + "L\244\374L\244\374<\224\374$\214\360\30w\330\7e\311\5Y\270\5Y\270\5Y" + "\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5" + "Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5[\306\5Y\270\5[\306\5[\306\5[\306" + "\5[\306\5[\306\5[\306\7e\311\5[\306\7e\311\7e\311\7e\311\6h\330\6h\330" + "\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346\6h\330\5l\346\5l\346\5l\346" + "\5l\346\5t\352\5t\352\4t\364\4t\364\4t\364\4t\374\4|\374\4t\374\4|\374" + "\5:Y\4,X\4""2J\5:Y\5:Y\6Kf\5:Y\5>G\6Kf\5>G\5>G\6Kf\6V\251\30w\330\24" + "\204\374\24\204\374\24\204\374\24\204\374$\214\374<\224\374E\233\374" + "L\244\374E\233\374T\244\374T\244\374L\244\374E\233\3745\214\373\26x\351" + "\6h\330\7e\311\5[\306\5Y\270\5[\306\5[\306\5Y\270\5[\306\5Y\270\5[\306" + "\5Y\270\5[\306\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270\5Y\270" + "\5Y\270\5Y\270\5Y\270\5[\306\5Y\270\5[\306\5[\306\5[\306\5[\306\5Y\270" + "\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\7e\311\5[\306\5[\306" + "\7e\311\7e\311\7e\311\6h\330\7e\311\6h\330\6h\330\6h\330\6h\330\6h\330" + "\6h\330\6h\330\5l\346\5l\346\5l\346\5l\346\5l\346\5t\352\5t\352\5t\352" + "\4t\364\4t\364\4t\364\4t\364\4t\364\4t\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\5""6d\4""2J\4""2J\5:Y\5:Y\6Kf\5:Y\5>G\6Kf\6Kf\7IO\5>G\5>G\6K" + "f\12j\253\26x\351\14|\374\24\204\374\24\204\374\24\204\374$\214\3744" + "\224\374E\233\374L\244\374T\244\374T\244\374L\244\374T\244\374L\244\374" + "<\224\374,\212\364\30w\330\6h\330\7e\311\7e\311\5[\306\5[\306\5[\306" + "\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306\5[\306" + "\5[\306\5[\306\5[\306\7e\311\5[\306\7e\311\5[\306\5[\306\5[\306\5[\306" + "\7e\311\5[\306\5[\306\7e\311\7e\311\7e\311\7e\311\7e\311\6h\330\7e\311" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346" + "\5l\346\5l\346\5l\346\5l\346\5l\346\5t\352\5t\352\4t\364\4t\364\4t\364" + "\4t\364\4t\364\4t\374\4t\374\4t\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\5""6d\4""2J\5:Y\5>G\5""6d\5:Y\5:Y\5>G\5>G\30Wb\5:Y\5>" + "G\5>G\4""2J\5>G\6Kf\12j\253\26x\351\24\204\364\24\204\374\24\204\374" + "\24\204\374$\214\3744\224\374E\233\374T\244\374T\244\374T\244\374T\244" + "\374T\244\374T\244\374E\233\374<\224\374$\214\360\26x\351\6h\330\10w" + "\321\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7" + "e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311\7e\311" + "\7e\311\7e\311\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346\5l\346\5l\346" + "\5t\352\5l\346\5t\352\5t\352\5t\352\5t\352\4t\364\4t\364\4t\364\4t\364" + "\4t\374\4|\374\4t\374\4|\374\4t\374\4|\374\4t\374\4t\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\5""6d\4,X\5:Y\5>G\5""6d\5:Y\5:Y\5>G\5>G" + "\7IO\5>G\5>G\5>G\5>:\5>:\4""45\5>G\31[\231\12j\253\15\202\340\14}\362" + "\24\204\374\24\204\374\24\204\374\34\214\374,\224\374E\233\374L\244\374" + "T\244\374\\\254\374T\244\374T\244\374T\244\374T\244\374L\244\374<\224" + "\374,\212\364\26x\351\5t\352\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\5l\346" + "\6h\330\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5t\352\5l\346" + "\5t\352\4t\364\5t\352\4t\364\4t\364\4t\374\4t\364\4t\374\4t\364\4t\374" + "\4t\374\4|\374\4t\374\4t\374\4t\374\4t\374\4t\374\4t\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\5""6d\4""2J\4""2J\5>G\5""6d\5:Y\5" + ":Y\5>G\5>G\7IO\5>G\5>G\5>G\5>:\4""45\4""45\5>G\30Wb\5>G\5:Y\6Z\230\30" + "w\330\14}\362\24\204\374\24\204\374\24\204\374\34\214\374$\214\374<\224" + "\374L\244\374T\244\374T\244\374T\254\374\\\254\374T\244\374T\244\374" + "T\244\374L\244\374E\233\3743\226\361\34\177\364\26x\351\5l\346\6h\330" + "\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330\6h\330" + "\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346\5l\346" + "\5l\346\5l\346\5t\352\5l\346\5t\352\5t\352\5l\346\4t\364\4t\364\4t\364" + "\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\374\4t\364\4t\374" + "\4t\364\4|\374\4t\374\4t\374\4|\374\4t\374\4|\374\4t\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374\5""6d\4""2J\4""2J\5:Y\5:Y" + "\5:Y\7IO\4""2J\5>:\7IO\5>G\5>G\4""2J\4""45\4""45\4""45\5>:\6Kf\5>:\4" + "45\4""45\7IO\6Z\230\10w\321\26x\351\24\204\374\14\204\374\24\204\374" + "\24\204\374\34\214\374,\224\374<\234\374E\233\374T\244\374T\244\374\\" + "\254\374T\244\374T\244\374T\244\374T\244\374T\244\374E\233\374<\234\374" + ",\212\364\31\207\352\14}\362\26x\351\5l\346\5l\346\6h\330\5l\346\5l\346" + "\5l\346\5l\346\6h\330\5l\346\6h\330\5l\346\5l\346\5l\346\5l\346\5l\346" + "\5t\352\5l\346\5t\352\5t\352\5t\352\5t\352\4t\364\4t\364\4t\364\5t\352" + "\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\364\4t\374" + "\4t\364\4t\374\4t\364\4t\374\4|\374\4|\374\4|\374\4|\374\4|\374\4|\374" + "\4|\374\4|\374\4|\374\4|\374\4|\374\14\204\374\24\204\374\34\214\374" + "\4,X\4""2J\4""2J\5>G\5:Y\5:Y\5:Y\5>:\4""45\5>G\5>:\5>G\4""45\4""45\4" + ")(\4)(\4""45\30Wb\4""45\4)(\4)(\4""45\5>:\5:Y\6Z\205\7e\311\26x\351\14" + "}\362\24\204\374\24\204\374\24\204\374\24\204\374\34\214\374,\224\374" + "<\234\374E\233\374T\244\374T\244\374T\244\374T\244\374\\\254\374\\\254" + "\374T\244\374T\244\374T\244\374L\244\374<\234\374,\224\374,\212\364\31" + "\207\352\14}\362\15\202\340\5t\352\5l\346\5t\352\5l\346\5t\352\5l\346" + "\5l\346\5t\352\5l\346\5l\346\5t\352\5t\352\5t\352\5l\346\5t\352\5t\352" + "\5l\346\5t\352\5t\352\5t\352\4t\364\5t\352\4t\364\4t\364\4t\364\4t\364" + "\4t\364\4t\364\4t\364\4|\363\4|\374\4|\363\4|\374\4|\363\4|\374\4|\374" + "\4|\374\4|\374\4|\374\14\204\374\14\204\374\24\204\374\34\214\374,\224" + "\3744\224\374<\234\374L\244\374T\244\374\5""6d\4""2J\4""2J\5>G\4""2J" + "\5:Y\7IO\5>G\4""45\5>:\5>G\5>:\4""45\4)(\5(\31\4)(\4""45\7IO\4""45\4" + ")(\4)(\4""45\5>:\5>G\5:Y\5""6d\11Ly\6V\251\10w\321\26x\351\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374$\214\374,\214\374<\224\374" + "E\233\374L\244\374T\244\374T\244\374T\244\374T\254\374\\\254\374T\244" + "\374T\244\374T\244\374T\244\374T\244\374E\233\374E\233\374<\224\3743" + "\226\361$\214\374\34\204\374\31\207\352\26x\351\14}\362\14}\362\4|\363" + "\5t\352\5t\352\5t\352\5t\352\5t\352\4t\364\5t\352\4t\364\5t\352\4t\364" + "\4t\364\4t\364\4t\364\4t\364\4t\364\4|\363\4|\363\4|\363\4|\363\4|\363" + "\4|\374\4|\374\4|\374\14|\374\14|\374\24\204\374\34\204\374$\214\374" + "$\214\3744\224\374<\234\374E\233\374L\244\374T\244\374T\244\374T\244" + "\374T\244\374T\244\374T\244\374\5""6d\4""2J\4""2J\4""2J\4""2J\4""2J\7" + "IO\4""45\4""45\5>:\4""45\4""45\4""45\4)(\5(\31\4)(\4)(\7IO\4""45\4)(" + "\5(\31\4)(\4""45\5>:\5>G\5:Y\5""6l\5""6d\5;t\5I\230\12j\253\32h\327\26" + "x\351\24\204\374\24\204\374\14\204\374\24\204\374\24\204\374\34\214\374" + "$\214\3744\224\374<\234\374E\233\374L\244\374T\244\374T\244\374\\\254" + "\374\\\254\374T\244\374T\244\374\\\254\374T\244\374\\\254\374T\244\374" + "T\244\374T\244\374T\244\374L\244\374E\233\374<\234\3744\224\3744\224" + "\3744\224\374,\214\374,\212\364$\214\374$\203\373\34\214\374\34\204\374" + "\34\204\374\34\204\374\34\204\374\34\204\374\34\204\374\34\204\374\34" + "\204\374$\214\374$\214\374$\214\374,\214\374,\214\3744\224\374<\224\374" + "<\224\374<\234\374E\233\374L\244\374T\244\374T\244\374T\244\374T\244" + "\374T\244\374\\\254\374T\244\374T\244\374\\\254\374T\244\374\\\254\374" + "T\244\374T\244\374\32Aj\4""2J\4""2J\4""2J\4""2J\4""2J\7IO\4""45\4""4" + "5\4""45\4""45\4""45\4""45\4)(\5(\31\5(\31\4)(\7IO\4""45\4)(\4)(\4)(\4" + "45\5>G\5>G\6Kf\6Kf\5""6l\5""6d\5""6l\5;t\11Ly\5I\230\6V\251\6h\330\26" + "x\351\24\204\364\14\204\374\24\204\374\14\204\374\24\204\374\24\204\374" + "\34\204\374$\214\374,\224\374<\234\374E\233\374L\244\374T\244\374T\244" + "\374T\244\374\\\254\374T\244\374T\244\374T\244\374T\244\374T\244\374" + "T\244\374T\244\374\\\254\374T\244\374\\\254\374T\244\374T\244\374T\244" + "\374T\244\374T\244\374T\244\374T\244\374L\244\374T\244\374L\244\374T" + "\244\374L\244\374T\244\374L\244\374T\244\374T\244\374T\244\374T\244\374" + "T\244\374\\\254\374T\254\374\\\254\374T\244\374T\244\374T\244\374T\244" + "\374T\244\374\\\254\374T\244\374T\244\374T\244\374\\\254\374T\244\374" + "T\244\374L\244\374E\233\374<\234\3744\224\374\5""6l\5*f\4""45\26""8J" + "\5>G\5>G\5>G\4""45\4)(\4)(\4\34$\4\34$\4\34,\4)(\4\26\31\4\34$\4\34$" + "\7IO\4""45\5(\31\4)(\4""45\5>G\5>G\5:Y\5:Y\5""6l\5""6d\5;t\6Kf\5;t\5" + ";t\5""6l\5""6d\5;t\5I\230\6V\251\7e\311\30w\330\14}\362\24\204\374\24" + "\204\374\14\204\374\24\204\374\24\204\374\24\204\374\34\214\374\34\214" + "\374,\214\374,\224\374<\224\374<\234\374E\233\374L\244\374T\244\374T" + "\244\374T\244\374T\244\374\\\254\374T\244\374\\\254\374T\244\374T\244" + "\374T\244\374\\\254\374T\254\374T\254\374\\\254\374T\244\374\\\254\374" + "\\\254\374T\254\374\\\254\374T\254\374\\\254\374T\244\374\\\254\374T" + "\244\374\\\254\374T\254\374T\244\374T\244\374T\244\374T\244\374\\\254" + "\374\\\254\374T\244\374T\254\374T\244\374T\244\374L\244\374E\233\374" + "<\234\3744\224\3744\224\374,\224\374$\214\374\34\204\374\24\204\374\24" + "\204\374\5""6l\5""6d\4,\77\5>:\5>G\5>G\5>:\4)(\4)(\4)(\4\34$\4\26\31" + "\4\34,\4)(\5(\31\5(\31\4\26\31\5>G\4""45\4\26\31\4)(\4""45\5>:\5>G\5" + ">G\6Kf\5""6l\5""6d\5;t\5""6l\5""6l\5;t\5""6l\5""6l\5""6l\5;t\27@x\5;" + "t\5F\210\6V\251\31^\270\6h\330\30w\330\14}\362\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\34" + "\214\374$\214\374$\214\374,\214\3744\224\374<\224\374<\234\374E\233\374" + "E\233\374L\244\374L\244\374L\244\374L\244\374T\244\374T\244\374T\244" + "\374T\244\374T\244\374T\244\374T\244\374T\244\374T\244\374T\244\374T" + "\244\374T\244\374T\244\374T\244\374L\244\374L\244\374L\244\374L\244\374" + "L\244\374E\233\374<\234\374<\234\3744\224\374,\224\374$\214\374$\214" + "\374\34\214\374\34\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\5""6l\5:Y\4,\77\4""45\5>G\5>:\4""4" + "5\4)(\4)(\4\34$\4\26\31\4\26\31\4\34$\4)(\4)(\15\37\40\4\26\31\7IO\5" + ">:\4\26\31\4)(\4""45\5>:\5>G\5>G\5:Y\5""6d\5""6d\5""6d\5""6d\5""6l\5" + ";t\5""6l\5""6d\5""6l\5;t\4=~\5;t\5;t\5;t\4=~\6Z\205\6Z\230\6V\251\7u" + "\273\5t\352\24\204\364\14}\362\24\204\364\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\34\214\374\34\214\374$\214\374$\214\374$\214\374,\214\374" + ",\224\374,\214\374,\224\3744\224\3744\224\3744\224\3744\224\3744\224" + "\374,\224\3744\224\3744\224\374,\224\374,\224\374,\214\374,\214\374$" + "\214\374$\214\374\34\214\374\34\214\374\34\214\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\26|\372\26x\351\30w\330\7e\311-t\315\5""6l\5:" + "Y\4,\77\4""45\5>:\4""45\4)(\4)(\4\34$\4\34$\4\26\31\4\14\14\4\34$\4)" + "(\5(\31\15\37\40\4)(\30Wb\5>G\4)(\4)(\4""45\4""45\5>G\5>G\5:Y\5""6d\5" + "6d\5""6d\5""6d\5""6l\5""6l\5""6l\5""6l\5""6l\5;t\5F\210\5;t\5;t\11Ly" + "\11Ly\5F\210\6Z\205\5F\210\6Z\230\32h\327\26x\351\7u\273\7e\311\6h\330" + "\34\177\364,\214\374\24\204\364\26|\372\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\14\204\374\24\204\374\24\204\374\14|\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24" + "\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204" + "\374\26|\372\24\204\364\26x\351\7e\311\5[\306\27]\251\27]\251(b\246\15" + "8\214\5-z9f\242\5""6d\5:Y\4""2J\4""45\4,\77\4""45\4)(\4\34$\5(\31\4\26" + "\31\4\26\31\4\14\14\4\26\31\5(\31\4%\13\4\26\31\4)(\34iu\7IO\4\34$\4" + ")(\4""45\4""45\5>:\5>G\5:Y\5:Y\4,X\4,X\5""6d\5""6d\5;t\5""6l\5""6l\5" + ";t\11Ly\5F\210\5;t\5;t\5F\210\5F\210\5F\210\5F\210\11Ly\6Z\230\31f\306" + "\7e\311\6V\251\12j\253\6V\251\5Y\270]\240\374<\224\374\26x\351\6h\330" + "\15\202\340\5t\352\5t\352\26x\351\14}\362\34\204\374\24\204\364\14}\362" + "\24\204\364\24\204\374\26|\372\24\204\364\24\204\374\24\204\374\24\204" + "\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374\24\204\374" + "\24\204\374\24\204\374\24\204\364\26|\372\24\204\364\26x\351\26x\351" + "\6h\330\30w\330\30w\330\32h\327\31f\306\27]\251\5I\230\15""8\214\34L" + "\242\17""3v\5\27j\17""3v,V\216,V\216\17""3v\5-z\34L\242\5:Y\5:Y\5>G\4" + "45\4""45\4""45\4)(\4\34$\4\26\31\4\26\31\4\14\14\4\14\14\4\14\24\4%\13" + "\4\26\31\4\14\14\4)(\30Wb\5>:\4\34$\4)(\4)(\4""45\5>:\5>G\5:Y\4,X\4," + "X\4,X\4,X\5""6l\5""6l\5;t\5;t\5;t\11Ly\5F\210\11Ly\11Ly\5F\210\5F\210" + "\11Ly\5F\210\4=~\5F\210\5Y\270\5[\306\34x\300\12j\253\6V\251\5Y\270=" + "\216\361u\210\372\31f\306\5Y\270\7e\311\5Y\270\31f\306\6h\330\7e\311" + "<\224\3745\214\373\30w\330\30w\330\30w\330\10w\321\7e\311\30w\330\30" + "w\330\30w\330\30w\330\30w\330\26x\351\30w\330\32h\327\30w\330\26x\351" + "\30w\330\7e\311\5Y\270\27]\251\27]\251\31[\231\5I\230\30F\210\15""8\214" + "(b\246,V\216\27@x\5*f\5*f49\221\27@x\5\27j\35""3k49\221\27@x\17""3v\17" + "3v49\221\6Kf\5:Y\7IO\4,\77\4""45\4)(\4)(\4\26\31\4\26\31\4\26\31\4\14" + "\14\4\14\14\4\14\24\5(\31\4\14\14\4\14\14\4)(\30Wb\5>:\4)(\4\34$\4)(" + "\4""45\5>:\5>G\5:Y\4,X\4,X\4,X\5*f\5""6d\5;t\5;t\5;t\5;t\11Ly\6Z\230" + "\5F\210\5F\210\5F\210\5F\210\5F\210\5F\210\4=~\11m\217\5K\246\5[\306" + "'\177\347\12j\253\12j\253\5K\246\5[\306u\210\372H\210\355\5[\306\5Y\270" + "\7e\311\7e\311\7e\311\30w\330-t\315]\240\374\34x\300\12j\253\12j\253" + "\12j\253\6V\251\6V\251\27]\251\12j\253\12j\253\12j\253\34x\300\6V\251" + "\6Z\230\5K\246\27]\251/p\267\5F\210\11Ly\5;t\27@x\33V\206\30F\210\5;" + "t\30F\210\5-z\15""8\214,V\216\27@x\5\27j\5\27j49\221\5*f\17""3v\27@x" + "\17""3v\17""3v\17""3v\34L\242\6Kf\5:Y\7IO\4""45\4)(\4""45\4)(\4\26\31" + "\4\26\31\4\14\14\4\14\14\4\14\14\4\14\14\5(\31\4%\13\4\26\31\4)(\6YZ" + "\5>G\4)(\4)(\4)(\4)(\5>:\5>G\5:Y\4,X\4,X\4,X\4,X\5""6l\5;t\5;t\5;t\5" + ";t\11Ly\6Z\205\5F\210\11Ly\5F\210\11Ly\4=~\5F\210\4=~\6Z\205\5K\246\6" + "B\3123\226\361\6Z\230\12j\253\5K\246\6V\2517S\323u\210\372\5Y\270\5Y" + "\270\5Y\270\6V\251\34x\300\15\202\340\35E\270g\252\3720\212\341\34x\300" + "\34x\300\7u\273\12j\253\6V\251\31^\270\27]\251\31^\270\34x\300,\210\315" + "\34x\300\27]\251\27]\251\6V\251\34x\300\31[\231\30F\210\5""6l\5;t\30" + "F\210\27@x\33V\206\27@x\5*f\5-z\17""3v\27@x\30F\210\5\27j\26D\226\5\27" + "j\5*f\17""3v\27@x\17""3v\5*f9f\242\7IO\5:Y\5>G\7IO\7IO\5>G\4""45\5(\31" + "\4\26\31\4\14\14\4\26\31\4\26\31\4\26\31\4\14\14\4\14\24\4\34$\4)(\5" + ">:\4)(\4\26\31\4\26\31\4)(\4""45\5>:\5>G\5:Y\5:Y\5""6d\5""6l\5""6l\5" + "6l\5;t\4=~\5;t\5;t\5F\210\5I\230\4=~\5F\210\11Ly\5F\210\5F\210\4=~\5" + "F\210\4=~\12j\253\6V\2510\212\341\5I\230\5I\230\6V\251\6V\251\27]\251" + "\233\255\373H\210\355\5K\246\31f\306\5Y\270\7u\273,\210\315\15""8\214" + "u\210\372Z\200\345\5K\246\31^\270-t\315\6V\251\7u\273\5[\306\5Y\270\5" + "Y\270\7u\2730\212\341\31f\306\34x\300\31f\306\31^\270\34x\300\5I\230" + "\5F\210\5F\210\30F\210\5""6l\27@x\30F\210\30F\210\17""3v\35""3k\5*f\17" + "3v\30F\210,V\216\17""3v9f\242\35""3k\35""3k49\221\5*f\5-z\15""8\214\5" + ":Y\5>G\5>G\5>G\7IO\5>G\4""45\4\34$\4\14\14\4\26\31\4\14\14\4\26\31\4" + "\26\31\4\14\14\4\14\24\4\34$\4)(\5>:\4)(\4\26\31\5(\31\4)(\4""45\5>:" + "\4""2J\5:Y\5""6d\5""6d\5""6l\5""6l\5;t\5;t\4=~\5;t\5;t\5F\210\5I\230" + "\5F\210\5F\210\11Ly\6Z\205\5F\210\11Ly\4=~\4=~\27]\251\6Z\230\34x\300" + "\5K\246\5I\230\5K\246\6Z\230\5I\230G\232\344G\232\344\31^\270\5K\246" + "\6Z\230\31f\306\7u\273\15""8\214Z\200\345]\240\374\5I\230\5K\246\5Y\270" + "\5Y\270-t\315-t\315\31f\306\5Y\270\31^\270,\210\315\12j\253\31^\270\27" + "]\251\34x\300-t\315\5F\210\4=~\5F\210,V\216\30F\210\5*f\4=~\27@x,V\216" + "$Mz\5*f\5*f\17""3v9f\242\5-z,V\216\27@x\5*f$Mz\17""3v\5*f\34L\242\7I" + "O\5>G\7IO\5>G\7IO\5>G\4""45\4\34$\4\26\31\4\26\31\4\26\31\4\14\14\4\26" + "\31\4\14\14\4\26\31\5(\31\4)(\5>:\4)(\4\34$\5(\31\4""45\4""45\5>:\5:" + "Y\5:Y\5:Y\5""6l\5;t\5;t\5;t\11Ly\4=~\5;t\5;t\5F\210\5F\210\5F\210\11" + "Ly\5F\210\11Ly\4=~\4=~\4=~\4=~\6Z\230\6Z\230\34x\300-t\315\5I\230\6V" + "\251\12j\253\12j\253\6V\251\31f\306\5K\246\6Z\230\5K\246\6V\251\31f\306" + "-t\3157S\323\205\253\372\5I\230\5K\246\6V\251\6V\251\34x\300G" + "\7IO\5>G\5:Y\4,\77\4)(\5(\31\4\26\31\4\26\31\4\26\31\4\26\31\4\26\31" + "\4\26\31\4\26\31\4)(\4""45\5>G\4""45\4\34$\4)(\4""45\4""45\5>G\7IO\5" + ":Y\5""6l\5""6l\5""6l\11Ly\27@x\11Ly\5;t\5;t\4=~\5F\210\5F\210\4=~\11" + "Ly\11Ly\5F\210\11Ly\5F\210\5F\210\4=~\31[\231\5F\210\12j\253G\232\344" + "\6Z\230\27]\251/p\267\27]\251\6V\251\34x\300\5K\246\6V\251\4=~\31[\231" + "\227\273\372w\251\371\34L\242w\251\371\31^\270\5K\246\6V\251\27]\251" + "\12j\253-t\315\31^\270\12j\253\31f\306,\210\315\12j\253\27]\251\27]\251" + "\6V\251-t\315-t\315-t\315\5F\210\5F\210\30F\210\31[\231\4=~\5""6l\5;" + "t\17""3v\17""3v\17""3v\5*f\5-z\34L\242\15""8\214\26D\22649\221\5*f\5" + "*f\5*f\35""3k\6Kf\5:Y\6YZ\5>G\5>G\4""45\4)(\4)(\4)(\5(\31\4\26\31\4\26" + "\31\4)(\4\26\31\4\26\31\4)(\4""45\7IO\4""45\4)(\4)(\4""45\5>:\5>G\5:" + "Y\6Kf\5""6d\5;t\5""6l\5;t\11Ly\4=~\5;t\5""6l\4=~\4=~\5F\210\4=~\4=~\11" + "Ly\11Ly\11Ly\4=~\5F\210\4=~\6Z\230\5F\210\5K\246W\244\352\6V\251\6Z\230" + "\6Z\230\5F\210\31[\231/p\267\5F\210\30F\210\4,X9f\242\306\341\374H\210" + "\355\15""8\214\\\224\337-t\315\5I\230\6V\251\27]\251\12j\253\31[\231" + "\6Z\230\6V\251\5Y\270-t\315\6V\251\27]\251\27]\251\5K\246\31^\270/p\267" + ",\210\315\5I\230\4=~\4=~\5F\210\31[\231\30F\210\5""6l\5""6l\17""3v\30" + "F\210\26D\226\15""8\214\34L\242\5-z\5-z9f\242\30F\210\5#V\32Aj\14/Q\6" + "Kf\7IO\7IO\7IO\4""2J\4,\77\4""45\4""45\4""45\4)(\4\34$\4\34$\4)(\4\34" + "$\4\34$\4)(\5>:\7IO\4""45\4)(\4""45\5>:\5>G\7IO\6Kf\5;t\6Kf\5;t\5""6" + "l\5;t\27@x\11Ly\5;t\5;t\4=~\4=~\5F\210\5;t\5;t\11Ly\11Ly\4=~\5;t\4=~" + "\5F\210\31[\231\4=~\5F\210G\232\344\34x\300\5F\210\5F\210\26D\226\5F" + "\210(b\246\11Ly$Mz,V\216\311\324\353\355\357\373\5I\230\4=~/p\267/p\267" + "\5I\230/p\267\27]\251\6Z\230\27]\251\27]\251\6V\251\5Y\270\30w\330\5" + "Y\270\31^\270/p\267\5Y\270\6V\251\5K\246\31^\270\6V\251\5I\230\5F\210" + "\4=~\5F\210\31[\231\30F\210\27@x\17""3v\30F\210(b\246\31[\231\15""8\214" + "\15""8\214\5-z\15""8\2149f\242\5#V\5#V\27%V\6Kf\7IO\7IO\7IO\5:Y\5>G\5" + ">:\5>:\5>:\4""45\4)(\4)(\4)(\4)(\4)(\4)(\5>G\6YZ\5>:\4""45\4""45\5>:" + "\5>G\7IO\6Kf\11Ly\5""6l\5;t\5""6l\5""6l\5;t\4=~\5""6l\5;t\4=~\4=~\4=" + "~\5;t\5;t\5;t\5;t\5;t\5;t\5;t\6Z\205\31[\231\4=~\5F\210;\225\326;\225" + "\326\6Z\205\4=~\5;t\5F\210\31[\231\6Z\230\5;t\11Ly\310\327\371\270\311" + "\367\5F\210\5F\210\6V\251\27]\251\31[\231/p\267\31[\231\6Z\230\27]\251" + "\27]\251\31^\270\31f\306-t\315\5Y\270\31f\306-t\315\31f\306\31f\306\5" + "K\246\31f\306/p\267/p\267\27]\251\5F\210\4=~\30F\210\33V\206\33V\206" + "\30F\210\4=~\34L\242(b\246\17""3v\34L\242\26D\226\5-z9f\242\17""3v\4" + "\34E\27%V\30Wb\5:Y\7IO\7IO\7IO\5>G\7IO\7IO\5>:\5>:\4)(\4)(\4)(\4)(\4" + ")(\4""45\5>:\6YZ\5>:\4""45\5>:\5>:\5>G\6Kf\6eu\6Kf\5;t\5;t\5""6l\5""6" + "l\5;t\5;t\5""6l\5;t\4=~\5;t\4=~\5""6l\6Kf\5""6l\11Ly\11Ly\4=~\4=~\6Z" + "\205\31[\231\4=~\11Ly,\210\315W\244\352\5F\210\5;t\33V\206\31[\231\6" + "Z\230\12j\253\6Z\230\4=~\205\253\372,V\216\5I\230\5F\210\5I\230\5I\230" + "\5I\230\6Z\230\31[\231\31[\231\6Z\230\6Z\230\31^\270\32h\327\32h\327" + "\5Y\270\27]\251\31^\270\31f\306\32h\327\31^\270\6V\251\5K\246\31^\270" + "/p\267/p\267\6Z\230\4=~\4=~,V\216,V\216\30F\210\30F\210(b\246\27@x,V" + "\216/p\267\5""6l(b\246\27@x\5#V\27%V\6Kf\6Kf\7IO\7IO\5>G\5>G\6YZ\6YZ" + "\6YZ\6YZ\4""45\4)(\4""45\4""45\4)(\4)(\4)(\30Wb\7IO\7IO\5>:\5>G\7IO\6" + "Kf\5F\210\5F\210\11Ly\11Ly\11Ly\5;t\5""6l\5""6l\5;t\5;t\5;t\4=~\11Ly" + "\5""6l\5""6d\5""6d\5""6l\5""6l\5""6l\5""6l\5\27j\30F\210\4=~\11Ly,\210" + "\315G\232\344\5K\246\5F\210\6Z\205\5I\230\31^\270\31f\306\5F\210\11L" + "y\31[\231\5I\230/p\267\30F\210\26D\226\\\224\337\5-z\4=~\31[\231\31[" + "\231$\200\223(b\246\27]\251\5Y\270-t\315\5Y\270\31f\306\31f\306\31f\306" + "G\7IO\6YZ\6YZ\6YZ\6YZ\5>:\4)(\4""45" + "\4""45\4)(\4""45\4""45\30Wb\7IO\6YZ\5>:\7IO\7IO\6Kf\31[\231\6Z\230\5" + "F\210\5;t\5;t\11Ly\5;t\5""6l\5""6l\5;t\5;t\5;t\5;t\5""6d\5""6d\5:Y\5" + "6l\5""6l\5*f\5*f\5*f\30F\210\4=~\5F\210,\210\315G\232\344-t\315-t\315" + "\31[\231\6V\251\30w\330H\210\355\5F\210\27@x\31[\231\5I\230\204\274\374" + "(b\246\34L\242\233\255\373Z\200\345\15""8\214\31[\231\27]\251(b\246\27" + "]\251\6V\251\5Y\270\32h\327\32h\327-t\315\5Y\270\31f\306\31f\306\31f" + "\306\31f\306\34x\300\27]\251\5I\230\6Z\230(b\246\30F\210\6Z\230\31[\231" + "\5F\210(b\246\26D\226\5-z\31^\270\26D\226\26D\226,V\216\17""3v\17""3" + "v\35""3k\5#V", +}; + + diff --git a/polymer/eduke32/rsrc/game.bmp b/polymer/eduke32/rsrc/game.bmp new file mode 100644 index 0000000000000000000000000000000000000000..db0f6b5ba3c76b6989d61c87d7860b83a8098651 GIT binary patch literal 29080 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 +/* GdkPixbuf RGB C-Source image dump */ + +const GdkPixdata startbanner_pixdata = { + 0x47646b50, /* Pixbuf magic: 'GdkP' */ + 24 + 84000, /* header length + pixel_data length */ + 0x1010001, /* pixdata_type */ + 300, /* rowstride */ + 100, /* width */ + 280, /* height */ + /* pixel_data: */ + "\40""3Z\40""3Z\31*W\31*W\26$I\31*W\31*W\31*W\26$I\26$I\26$I\31*W\31*" + "W\31*W\26$I\31*W\26$I\40""3Z\26$I\15$;\24\26*\10\25*\13\26\32\14\13\31" + "\4\6\30\4\4\14\0\0\0\0\0\0\0\0\0\4\4\14\4\6\30\10\25*\24\26*\5\13(\4" + "\4\14\4\6\30\4\6\30\4\6\30\4\6\30\4\6\30\26\33""8\26\33""8\5\13(\5\13" + "(\5\13(\4\6\30\4\6\30\4\6\30\4\4\14\4\6\30\4\6\30\4\4\14\4\4\14\4\4\4" + "\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\40""3Z\31*W\31*W\34,e\26$I\31*W\31*W\31*W\26$I\10$L\26$I\26$I\26" + "$I\26$I\26$I\26$I\24\26*\26\33""8\24\26*\5\13(\4\4\14\4\4\14\4\4\14\4" + "\4\4\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\14\13\31\26\33""8\14" + "\13\31\4\6\30\4\4\14\4\6\30\4\6\30\5\13(\4\6\30\7\27""9\26$I\7\27""9" + "\7\27""9\5\13(\5\13(\10\25*\24\14,\10\25*\24\14,\14\13\31\5\13(\4\4\14" + "\4\4\14\4\4\14\4\4\14\4\4\4\0\0\0\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\31*W\31*W\31*W\31*W\31*W\26$I\31*W\26$I\31*W\26$I\26$I\26" + "$I\7\31G\15$;\26$I\15$;\4\6\30\4\6\30\4\4\14\4\4\14\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\4\4\14\4\6\30\24\26*\24\26" + "*\4\6\30\14\13\31\4\6\30\4\6\30\4\6\30\4\6\30\5\13(\26$I\26\33""8\26" + "$I\26\33""8\26\33""8\26$I\26\33""8\24\26*\10\25*\24\14,\24\26*\5\13(" + "\4\6\30\4\6\30\4\4\14\4\4\14\4\4\4\4\4\4\4\4\4\4\4\14\4\4\14\4\4\4\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\31*W\31*W\31*W\26$I\40""3Z\31*W\26$I\26$I\31*W\31*W" + "\26$I\26$I\7\27""9\7\27""9\15$;\26\33""8\4\6\30\4\4\14\4\4\4\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\4\4\4\4\4" + "\14\13\26\32\24\26*\4\6\30\4\4\14\4\6\30\4\6\30\4\6\30\4\6\30\5\13(\26" + "\33""8\7\27""9\26$I\26\33""8\26\33""8\26\33""8\5\13(\5\13(\4\6\30\4\6" + "\30\5\13(\26\33""8\24\26*\5\13(\4\6\30\4\4\14\4\4\14\4\4\4\0\0\0\4\4" + "\14\4\4\14\4\4\14\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31*W\40""3Z\31*W\10$L\31*W\31*W" + "\26$I\26$I\26$I\26$I\7\31G\26$I\10\25*\5\13(\10\25*\24\26*\4\4\14\0\0" + "\0\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\0\0\0" + "\0\0\0\4\4\4\4\4\14\4\6\30\24\26*\13\26\32\4\4\4\4\4\14\4\4\14\4\6\30" + "\4\6\30\5\13(\10\25*\5\12""9\26$I\26\33""8\7\27""9\5\13(\4\6\30\4\6\30" + "\4\6\30\4\6\30\5\13(\26\33""8\7\27""9\10\25*\5\13(\4\6\30\4\4\14\4\4" + "\14\4\4\4\4\6\30\4\6\30\4\4\14\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\31G\34,e%7g\31*W\26" + "$I\26$I\15$;\7\27""9\15$;\7\27""9\7\27""9\26$I\26$I\10\25*\10\25*\35" + "#/\14\13\31\4\4\14\14\4\4\14\4\4\4\14\4\4\14\4\4\14\4\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4\4\14\24\26*\35#/\4\4\14\4\4" + "\4\4\4\14\4\4\14\4\6\30\5\13(\5\13(\5\13(\7\27""9\26\33""8\7\27""9\4" + "\6\30\5\13(\10\25*\26\33""8\24\26*\24\26*\7\27""9\7\27""9\24\26*\10\25" + "*\13\26\32\14\13\31\4\14\14\4\14\14\4\6\30\4\6\30\4\4\14\4\4\14\4\4\14" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\15$;\15$;\33""5e\34,e\31*W\40""3Z\31*W\31*W\31*W\5\13(\5\13(\15" + "$;\31*W\26$I\10\25*\26\33""8\4\6\30\14\13\31\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\4\4\4\4\4\4\4\4\14\4\4\14\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0" + "\14\13\31\7\27""9\5\12""9\4\4\4\4\4\14\4\6\30\5\13(\5\13(\5\13(\4\6\30" + "\4\4\14\7\27""9\26$I\26$I\15$;\26\33""8\26$I\26\33""8\26\33""8\24\26" + "*\5\13(\4\6\30\4\6\30\13\26\32\24\26*\4\6\30\4\4\14\4\4\14\4\6\30\4\6" + "\30\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\14\4\4\4\0\0\0\0\0\0\4\4\4" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\10$L\7\31G\34,e\31*W\34,e\31*W\31*W\31*W\40" + "3Z\7\31G\15$;\31*W\24\14,\24\26*\4\6\30\24\26*\4\4\14\14\13\31\0\0\0" + "\4\4\4\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\4\4\4\14\4\4\0\0\0\0\0\0\4" + "\14\4\0\0\0\0\0\0\14\13\31\26\33""8\26$I\4\4\14\4\4\14\4\6\30\5\13(\5" + "\13(\5\13(\10\25*\4\6\30\7\27""9\26\33""8\26\33""8\26\33""8\24\26*\5" + "\13(\4\6\30\4\6\30\26\33""8\10\25*\4\6\30\4\4\14\4\6\30\4\4\14\4\4\14" + "\4\4\14\4\4\14\4\4\14\14\13\31\14\13\31\4\6\30\14\13\31\14\13\31\14\13" + "\31\4\4\14\0\0\0\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\26$I\10" + "$L\40""3Z%7g\34,e\33""5e\31*W\31*W\31*W\15$;\26$I\26$I\4\4\14\4\6\30" + "\4\4\14\4\6\30\4\4\14\14\13\31\4\4\14\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\4\4\4\4\4\4\0\0\0\4\4\14\24\14,\26" + "$I\24\26*\5\13(\5\13(\7\27""9\5\12""9\26\33""8\26\33""8\15$;\26\33""8" + "\26\33""8\5\13(\4\6\30\4\6\30\4\6\30\4\6\30\4\6\30\5\13(\5\13(\4\6\30" + "\4\6\30\4\4\14\4\4\14\4\4\14\4\6\30\4\6\30\14\13\31\14\13\31\13\26\32" + "\13\26\32\14\13\31\4\6\30\14\13\31\0\0\0\4\4\14\4\4\4\4\4\4\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\31*W\10$L\31*W%7g\40""3Z\34,e\33""5e\40""3Z\31" + "*W\7\31G\26$I\26$I\0\0\0\4\14\14\4\4\4\4\4\4\0\0\0\4\14\14\4\4\4\4\4" + "\14\0\0\0\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\4\0\0\0\0\0" + "\0\0\0\0\0\0\0\4\4\14\4\6\30\26\33""8\26\33""8\24\14,\5\13(\5\13(\5\13" + "(\5\12""9\7\27""9\5\12""9\5\13(\4\6\30\4\6\30\4\6\30\5\13(\4\6\30\4\6" + "\30\4\6\30\4\6\30\5\13(\24\26*\24\26*\10\25*\14\13\31\14\13\31\13\26" + "\32\13\26\32\4\6\30\14\13\31\13\26\32\14\13\31\4\4\14\4\4\14\4\4\14\4" + "\4\4\4\4\14\4\4\14\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31*W\10$L\7" + "\31G\10$L\31*W\10$L\34,e\40""3Z\40""3Z\26$I\40""3Z\31*W\4\14\4\13\26" + "\32\4\14\14\0\0\0\0\0\0\4\4\14\0\0\0\0\0\0\4\4\4\0\0\0\4\4\14\4\4\4\4" + "\4\4\4\4\4\4\14\4\14\14\4\4\4\14\4\4\4\4\4\4\4\4\14\4\4\14\4\6\30\4\6" + "\30\24\14,\5\12""9\5\12""9\5\13(\5\13(\5\13(\5\13(\5\12""9\5\12""9\5" + "\13(\4\6\30\4\6\30\4\6\30\4\6\30\4\6\30\4\4\14\4\4\14\5\13(\5\13(\10" + "\25*\24\26*\24\26*\14\13\31\4\6\30\4\4\14\4\6\30\4\4\14\4\6\30\4\6\30" + "\5\13(\4\6\30\4\4\14\4\6\30\4\4\4\0\0\0\4\4\14\4\4\14\0\0\0\0\0\0\0\0" + "\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\31*W\31*W\7\31G\26$I\4+X\7\31G\10$L\31*W\40""3Z\26$" + "I\31*W\7\27""9\4\4\14\24\26*\13\26\32\4\4\4\4\4\4\4\4\14\4\4\4\4\4\14" + "\0\0\0\4\4\4\4\4\4\0\0\0\4\4\14\4\4\14\4\4\14\4\4\14\4\6\30\4\6\30\4" + "\6\30\5\13(\5\13(\10\25*\5\13(\5\12""9\5\13(\5\13(\5\12""9\10\25*\5\12" + "9\7\27""9\5\12""9\5\12""9\5\13(\5\13(\4\6\30\5\13(\5\13(\5\13(\24\14" + ",\10\25*\26\33""8\26\33""8\5\13(\4\6\30\4\6\30\4\6\30\4\6\30\4\4\14\4" + "\4\14\4\6\30\4\6\30\4\6\30\14\13\31\4\6\30\4\6\30\4\6\30\4\4\14\4\4\14" + "\4\4\14\4\4\4\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10$L\31*W\10$L\40""3Z%7" + "g\34,e\34,e\31*W%7g\31*W\40""3Z\7\27""9\4\6\30\24\26*\24\26*\4\4\14\4" + "\4\14\4\4\14\4\4\4\4\4\4\0\0\0\0\0\0\4\4\4\4\4\14\4\4\14\4\6\30\4\6\30" + "\4\6\30\5\13(\5\13(\5\13(\7\27""9\7\27""9\7\27""9\7\27""9\7\27""9\5\12" + "9\5\13(\5\13(\5\13(\5\13(\5\13(\5\12""9\5\13(\5\13(\5\12""9\7\27""9\15" + "$;\15$;\26$I\26$I\26\33""8\26$I\26\33""8\10\25*\5\13(\4\6\30\4\6\30\4" + "\6\30\4\6\30\4\6\30\5\13(\10\25*\13\26\32\4\6\30\4\6\30\4\6\30\4\6\30" + "\4\4\14\4\4\4\4\4\14\4\4\4\0\0\0\4\4\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34,e\33""5" + "e\7\31G\15$;\34,e!6u%7g\34,e\31*W\26$I\31*W\7\27""9\4\6\30\26\33""8\26" + "\33""8\4\4\14\4\4\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\4\14\4\6\30\5\13" + "(\24\14,\26\33""8\26$I\5\12""9\7\27""9\7\27""9\7\27""9\5\12""9\7\27""9" + "\7\27""9\5\13(\7\27""9\5\13(\5\13(\5\13(\5\13(\7\27""9\26$I\26$I\31*" + "W\10$L\26$I\7\31G\5\12""9\7\27""9\15$;\7\27""9\5\13(\5\13(\5\13(\5\13" + "(\4\6\30\4\6\30\4\6\30\4\6\30\4\6\30\10\25*\10\25*\5\13(\4\6\30\4\6\30" + "\4\6\30\4\6\30\4\4\14\4\4\14\0\0\0\4\4\4\4\4\14\4\4\4\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\34,e\33""5e\31*W\31*W\34,e%7g\40""3Z\40""3Z\31*W\31*W\31*W\34,e" + "\5\13(\7\27""9\7\31G\26$I\26$I\10$L\26$I\31*W\7\31G\7\31G\26$I\31*W\31" + "*W\7\31G\5\12""9\7\27""9\10\25*\5\12""9\10\25*\5\12""9\5\13(\5\12""9" + "\5\13(\5\13(\7\27""9\7\27""9\7\27""9\15$;\26$I\31*W\26$I\10$L\10\25*" + "\5\13(\5\13(\5\13(\10\25*\10\25*\5\13(\5\13(\4\6\30\4\6\30\5\13(\5\13" + "(\10\25*\5\12""9\5\12""9\7\31G\7\31G\7\31G\10$L\4""4i\4!1q+CZ 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 HV&MM(5_RRZ literal 0 HcmV?d00001 diff --git a/polymer/eduke32/source/GNU.TXT b/polymer/eduke32/source/GNU.TXT new file mode 100644 index 000000000..2f3289afb --- /dev/null +++ b/polymer/eduke32/source/GNU.TXT @@ -0,0 +1,87 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +Preamble +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +END OF TERMS AND CONDITIONS diff --git a/polymer/eduke32/source/_functio.h b/polymer/eduke32/source/_functio.h new file mode 100644 index 000000000..951392053 --- /dev/null +++ b/polymer/eduke32/source/_functio.h @@ -0,0 +1,324 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +// _functio.h + +// file created by makehead.exe +// these headers contain default key assignments, as well as +// default button assignments and game function names +// axis defaults are also included + + +#ifndef _function_private_ +#define _function_private_ +#ifdef __cplusplus +extern "C" { +#endif +char * gamefunctions[] = + { + "Move_Forward", + "Move_Backward", + "Turn_Left", + "Turn_Right", + "Strafe", + "Fire", + "Open", + "Run", + "AutoRun", + "Jump", + "Crouch", + "Look_Up", + "Look_Down", + "Look_Left", + "Look_Right", + "Strafe_Left", + "Strafe_Right", + "Aim_Up", + "Aim_Down", + "Weapon_1", + "Weapon_2", + "Weapon_3", + "Weapon_4", + "Weapon_5", + "Weapon_6", + "Weapon_7", + "Weapon_8", + "Weapon_9", + "Weapon_10", + "Inventory", + "Inventory_Left", + "Inventory_Right", + "Holo_Duke", + "Jetpack", + "NightVision", + "MedKit", + "TurnAround", + "SendMessage", + "Map", + "Shrink_Screen", + "Enlarge_Screen", + "Center_View", + "Holster_Weapon", + "Show_Opponents_Weapon", + "Map_Follow_Mode", + "See_Coop_View", + "Mouse_Aiming", + "Toggle_Crosshair", + "Steroids", + "Quick_Kick", + "Next_Weapon", + "Previous_Weapon", + "Show_Console" + }; +#ifdef __SETUP__ + +#define NUMKEYENTRIES 53 + +static char * keydefaults[] = + { + "Move_Forward", "Up", "Kpad8", + "Move_Backward", "Down", "Kpad2", + "Turn_Left", "Left", "Kpad4", + "Turn_Right", "Right", "KPad6", + "Strafe", "LAlt", "RAlt", + "Fire", "LCtrl", "RCtrl", + "Open", "Space", "", + "Run", "LShift", "RShift", + "AutoRun", "CapLck", "", + "Jump", "A", "/", + "Crouch", "Z", "", + "Look_Up", "PgUp", "Kpad9", + "Look_Down", "PgDn", "Kpad3", + "Look_Left", "Insert", "Kpad0", + "Look_Right", "Delete", "Kpad.", + "Strafe_Left", ",", "", + "Strafe_Right", ".", "", + "Aim_Up", "Home", "KPad7", + "Aim_Down", "End", "Kpad1", + "Weapon_1", "1", "", + "Weapon_2", "2", "", + "Weapon_3", "3", "", + "Weapon_4", "4", "", + "Weapon_5", "5", "", + "Weapon_6", "6", "", + "Weapon_7", "7", "", + "Weapon_8", "8", "", + "Weapon_9", "9", "", + "Weapon_10", "0", "", + "Inventory", "Enter", "KpdEnt", + "Inventory_Left", "[", "", + "Inventory_Right", "]", "", + "Holo_Duke", "H", "", + "Jetpack", "J", "", + "NightVision", "N", "", + "MedKit", "M", "", + "TurnAround", "BakSpc", "", + "SendMessage", "T", "", + "Map", "Tab", "", + "Shrink_Screen", "-", "Kpad-", + "Enlarge_Screen", "=", "Kpad+", + "Center_View", "KPad5", "", + "Holster_Weapon", "ScrLck", "", + "Show_Opponents_Weapon", "W", "", + "Map_Follow_Mode", "F", "", + "See_Coop_View", "K", "", + "Mouse_Aiming", "U", "", + "Toggle_Crosshair", "I", "", + "Steroids", "R", "", + "Quick_Kick", "`", "", + "Next_Weapon", "'", "", + "Previous_Weapon", ";", "", + "Show_Console", "NumLck", "" + }; + + +static char * mousedefaults[] = + { + "Fire", + "Strafe", + "Move_Forward", + "", + "", + "", + }; + + +static char * mouseclickeddefaults[] = + { + "", + "Open", + "", + "", + "", + "", + }; + + +static char * joystickdefaults[] = + { + "Fire", + "Strafe", + "Run", + "Open", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "Aim_Down", + "Look_Right", + "Aim_Up", + "Look_Left", + }; + + +static char * joystickclickeddefaults[] = + { + "", + "Inventory", + "Jump", + "Crouch", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + }; + + +static char * mouseanalogdefaults[] = + { + "analog_turning", + "analog_moving", + }; + + +static char * mousedigitaldefaults[] = + { + "", + "", + "", + "", + }; + + +static char * gamepaddigitaldefaults[] = + { + "Turn_Left", + "Turn_Right", + "Move_Forward", + "Move_Backward", + }; + + +static char * joystickanalogdefaults[] = + { + "analog_turning", + "analog_moving", + "analog_strafing", + "", + "", + "", + "", + "", + }; + + +static char * joystickdigitaldefaults[] = + { + "", + "", + "", + "", + "", + "", + "Run", + "", + "", + "", + "", + "", + "", + "", + "", + "", + }; +#endif +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/_rts.h b/polymer/eduke32/source/_rts.h new file mode 100644 index 000000000..5c1b16cd0 --- /dev/null +++ b/polymer/eduke32/source/_rts.h @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef __rts_private__ +#define __rts_private__ + +//=============== +// TYPES +//=============== + +typedef struct + { + char name[8]; + int32 handle,position,size; + } lumpinfo_t; + +typedef struct + { + char identification[4]; // should be IWAD + int32 numlumps; + int32 infotableofs; + } wadinfo_t; + +typedef struct + { + int32 filepos; + int32 size; + char name[8]; + } filelump_t; + +#endif diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c new file mode 100644 index 000000000..cc8fdf140 --- /dev/null +++ b/polymer/eduke32/source/actors.c @@ -0,0 +1,7526 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" + +extern char numenvsnds,actor_tog; + +void updateinterpolations() //Stick at beginning of domovethings +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i]; +} + +void setinterpolation(long *posptr) +{ + long i; + + if (numinterpolations >= MAXINTERPOLATIONS) return; + for(i=numinterpolations-1;i>=0;i--) + if (curipos[i] == posptr) return; + curipos[numinterpolations] = posptr; + oldipos[numinterpolations] = *posptr; + numinterpolations++; +} + +void stopinterpolation(long *posptr) +{ + long i; + + for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--) + if (curipos[i] == posptr) + { + numinterpolations--; + oldipos[i] = oldipos[numinterpolations]; + bakipos[i] = bakipos[numinterpolations]; + curipos[i] = curipos[numinterpolations]; + } +} + +void dointerpolations(long smoothratio) //Stick at beginning of drawscreen +{ + long i, j, odelta, ndelta; + + ndelta = 0; j = 0; + for(i=numinterpolations-1;i>=0;i--) + { + bakipos[i] = *curipos[i]; + odelta = ndelta; ndelta = (*curipos[i])-oldipos[i]; + if (odelta != ndelta) j = mulscale16(ndelta,smoothratio); + *curipos[i] = oldipos[i]+j; + } +} + +void restoreinterpolations() //Stick at end of drawscreen +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i]; +} + +long ceilingspace(short sectnum) +{ + if( (sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 ) + { + if ((sector[sectnum].ceilingpicnum==MOONSKY1)||(sector[sectnum].ceilingpicnum==BIGORBIT1)) return 1; + + } + return 0; +} + +long floorspace(short sectnum) +{ + if( (sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 ) + { + if ((sector[sectnum].floorpicnum==MOONSKY1)||(sector[sectnum].floorpicnum==BIGORBIT1)) return 1; + } + return 0; +} + +void addammo( short weapon,struct player_struct *p,short amount) +{ + p->ammo_amount[weapon] += amount; + + if( p->ammo_amount[weapon] > max_ammo_amount[weapon] ) + p->ammo_amount[weapon] = max_ammo_amount[weapon]; +} + +void addweaponnoswitch( struct player_struct *p, short weapon) +{ + if ( p->gotweapon[weapon] == 0 ) + { + p->gotweapon[weapon] = 1; + if(weapon == SHRINKER_WEAPON) + p->gotweapon[GROW_WEAPON] = 1; + } + switch(weapon) + { + case KNEE_WEAPON: + case TRIPBOMB_WEAPON: + case HANDREMOTE_WEAPON: + case HANDBOMB_WEAPON: break; + case SHOTGUN_WEAPON: spritesound(SHOTGUN_COCK,p->i);break; + case PISTOL_WEAPON: spritesound(INSERT_CLIP,p->i);break; + default: spritesound(SELECT_WEAPON,p->i);break; + } +} + +void addweapon( struct player_struct *p,short weapon) +{ + short snum; + snum = sprite[p->i].yvel; + + addweaponnoswitch(p,weapon); + + if (p->reloading) return; + + p->random_club_frame = 0; + + if(p->holster_weapon == 0) + { + p->weapon_pos = -1; + p->last_weapon = p->curr_weapon; + } + else + { + p->weapon_pos = 10; + p->holster_weapon = 0; + p->last_weapon = -1; + } + + p->kickback_pic = 0; + + if(p->curr_weapon != weapon) + { + p->curr_weapon = weapon; + + SetGameVarID(g_iWeaponVarID,p->curr_weapon, p->i, snum); + if(p->curr_weapon>=0) + { + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID,-1, p->i, snum); + } + OnEvent(EVENT_CHANGEWEAPON,p->i, snum, -1); + } +} + +void checkavailinven( struct player_struct *p ) +{ + + if(p->firstaid_amount > 0) + p->inven_icon = 1; + else if(p->steroids_amount > 0) + p->inven_icon = 2; + else if(p->holoduke_amount > 0) + p->inven_icon = 3; + else if(p->jetpack_amount > 0) + p->inven_icon = 4; + else if(p->heat_amount > 0) + p->inven_icon = 5; + else if(p->scuba_amount > 0) + p->inven_icon = 6; + else if(p->boot_amount > 0) + p->inven_icon = 7; + else p->inven_icon = 0; +} + +void checkavailweapon( struct player_struct *p ) +{ + short i,snum; + int32 weap; + + if(p->reloading == 1) return; + + if(p->wantweaponfire >= 0) + { + weap = p->wantweaponfire; + p->wantweaponfire = -1; + + if(weap == p->curr_weapon) return; + else if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 ) + { + addweapon(p,weap); + return; + } + } + + weap = p->curr_weapon; + if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 ) + return; + if( p->gotweapon[weap] && !(p->weaponswitch & 2)) + return; + + snum = sprite[p->i].yvel; + + for(i=0;i<10;i++) + { + weap = ud.wchoice[snum][i]; + if (VOLUMEONE && weap > 6) continue; + + if(weap == 0) weap = 9; + else weap--; + + if( weap == 0 || ( p->gotweapon[weap] && p->ammo_amount[weap] > 0 ) ) + break; + } + + if(i == 10) weap = 0; + + // Found the weapon + + p->last_weapon = p->curr_weapon; + p->random_club_frame = 0; + p->curr_weapon = weap; + SetGameVarID(g_iWeaponVarID,p->curr_weapon, p->i, snum); + if(p->curr_weapon>=0) + { + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID,-1, p->i, snum); + } + OnEvent(EVENT_CHANGEWEAPON,p->i, snum, -1); + p->kickback_pic = 0; + if(p->holster_weapon == 1) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + } + else p->weapon_pos = -1; +} + +long ifsquished(short i, short p) +{ + sectortype *sc; + char squishme; + long floorceildist; + + if(PN == APLAYER && ud.clipping) + return 0; + + sc = §or[SECT]; + floorceildist = sc->floorz - sc->ceilingz; + + if(sc->lotag != 23) + { + if(sprite[i].pal == 1) + squishme = floorceildist < (32<<8) && (sc->lotag&32768) == 0; + else + squishme = floorceildist < (12<<8); // && (sc->lotag&32768) == 0; + } + else squishme = 0; + + if( squishme ) + { + FTA(10,&ps[p]); + + if(badguy(&sprite[i])) sprite[i].xvel = 0; + + if(sprite[i].pal == 1) + { + hittype[i].picnum = SHOTSPARK1; + hittype[i].extra = 1; + return 0; + } + + return 1; + } + return 0; +} + +void hitradius( short i, long r, long hp1, long hp2, long hp3, long hp4 ) +{ + spritetype *s,*sj; + walltype *wal; + long d, q, x1, y1; + long sectcnt, sectend, dasect, startwall, endwall, nextsect; + short j,k,p,x,nextj,sect; + char statlist[] = {0,1,6,10,12,2,5}; + short *tempshort = (short *)tempbuf; + + s = &sprite[i]; + + if(s->picnum == RPG && s->xrepeat < 11) goto SKIPWALLCHECK; + + if(s->picnum != SHRINKSPARK) + { + tempshort[0] = s->sectnum; + dasect = s->sectnum; + sectcnt = 0; sectend = 1; + + do + { + dasect = tempshort[sectcnt++]; + if(((sector[dasect].ceilingz-s->z)>>8) < r) + { + d = klabs(wall[sector[dasect].wallptr].x-s->x)+klabs(wall[sector[dasect].wallptr].y-s->y); + if(d < r) + checkhitceiling(dasect); + else + { + d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)+klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y-s->y); + if(d < r) + checkhitceiling(dasect); + } + } + + startwall = sector[dasect].wallptr; + endwall = startwall+sector[dasect].wallnum; + for(x=startwall,wal=&wall[startwall];xx-s->x)+klabs(wal->y-s->y) ) < r) + { + nextsect = wal->nextsector; + if (nextsect >= 0) + { + for(dasect=sectend-1;dasect>=0;dasect--) + if (tempshort[dasect] == nextsect) break; + if (dasect < 0) tempshort[sectend++] = nextsect; + } + x1 = (((wal->x+wall[wal->point2].x)>>1)+s->x)>>1; + y1 = (((wal->y+wall[wal->point2].y)>>1)+s->y)>>1; + updatesector(x1,y1,§); + if( sect >= 0 && cansee(x1,y1,s->z,sect,s->x,s->y,s->z,s->sectnum ) ) + checkhitwall(i,x,wal->x,wal->y,s->z,s->picnum); + } + } + while (sectcnt < sectend); + } + +SKIPWALLCHECK: + + q = -(16<<8)+(TRAND&((32<<8)-1)); + + for(x = 0;x<7;x++) + { + j = headspritestat[statlist[x]]; + while(j >= 0) + { + nextj = nextspritestat[j]; + sj = &sprite[j]; + + if( x == 0 || x >= 5 || AFLAMABLE(sj->picnum) ) + { + if( s->picnum != SHRINKSPARK || (sj->cstat&257) ) + if( dist( s, sj ) < r ) + { + if( badguy(sj) && !cansee( sj->x, sj->y,sj->z+q, sj->sectnum, s->x, s->y, s->z+q, s->sectnum) ) + goto BOLT; + checkhitsprite( j, i ); + } + } + else if( sj->extra >= 0 && sj != s && ( sj->picnum == TRIPBOMB || badguy(sj) || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL || (sj->cstat&257) || sj->picnum == DUKELYINGDEAD ) ) + { + if( s->picnum == SHRINKSPARK && sj->picnum != SHARK && ( j == s->owner || sj->xrepeat < 24 ) ) + { + j = nextj; + continue; + } + if( s->picnum == MORTER && j == s->owner) + { + j = nextj; + continue; + } + + if(sj->picnum == APLAYER) sj->z -= PHEIGHT; + d = dist( s, sj ); + if(sj->picnum == APLAYER) sj->z += PHEIGHT; + + if ( d < r && cansee( sj->x, sj->y, sj->z-(8<<8), sj->sectnum, s->x, s->y, s->z-(12<<8), s->sectnum) ) + { + hittype[j].ang = getangle(sj->x-s->x,sj->y-s->y); + + if ( s->picnum == RPG && sj->extra > 0) + hittype[j].picnum = RPG; + else + { + if( s->picnum == SHRINKSPARK ) + hittype[j].picnum = SHRINKSPARK; + else hittype[j].picnum = RADIUSEXPLOSION; + } + + if(s->picnum != SHRINKSPARK) + { + if ( d < r/3 ) + { + if(hp4 == hp3) hp4++; + hittype[j].extra = hp3 + (TRAND%(hp4-hp3)); + } + else if ( d < 2*r/3 ) + { + if(hp3 == hp2) hp3++; + hittype[j].extra = hp2 + (TRAND%(hp3-hp2)); + } + else if ( d < r ) + { + if(hp2 == hp1) hp2++; + hittype[j].extra = hp1 + (TRAND%(hp2-hp1)); + } + + if( sprite[j].picnum != TANK && sprite[j].picnum != ROTATEGUN && sprite[j].picnum != RECON && sprite[j].picnum != BOSS1 && sprite[j].picnum != BOSS2 && sprite[j].picnum != BOSS3 && sprite[j].picnum != BOSS4 ) + { + if(sj->xvel < 0) sj->xvel = 0; + sj->xvel += (s->extra<<2); + } + + if( sj->picnum == PODFEM1 || sj->picnum == FEM1 || + sj->picnum == FEM2 || sj->picnum == FEM3 || + sj->picnum == FEM4 || sj->picnum == FEM5 || + sj->picnum == FEM6 || sj->picnum == FEM7 || + sj->picnum == FEM8 || sj->picnum == FEM9 || + sj->picnum == FEM10 || sj->picnum == STATUE || + sj->picnum == STATUEFLASH || sj->picnum == SPACEMARINE || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL) + checkhitsprite( j, i ); + } + else if(s->extra == 0) hittype[j].extra = 0; + + if ( sj->picnum != RADIUSEXPLOSION && + s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS ) + { + if(sj->picnum == APLAYER) + { + p = sj->yvel; + if(ps[p].newowner >= 0) + { + ps[p].newowner = -1; + ps[p].posx = ps[p].oposx; + ps[p].posy = ps[p].oposy; + ps[p].posz = ps[p].oposz; + ps[p].ang = ps[p].oang; + updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum); + setpal(&ps[p]); + + k = headspritestat[1]; + while(k >= 0) + { + if(sprite[k].picnum==CAMERA1) + sprite[k].yvel = 0; + k = nextspritestat[k]; + } + } + } + hittype[j].owner = s->owner; + } + } + } +BOLT: + j = nextj; + } + } +} + +int movesprite(short spritenum, long xchange, long ychange, long zchange, unsigned long cliptype) +{ + long daz,h, oldx, oldy; + short retval, dasectnum, a, cd; + char bg; + + bg = badguy(&sprite[spritenum]); + + if(sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4 ) ) + { + sprite[spritenum].x += (xchange*TICSPERFRAME)>>2; + sprite[spritenum].y += (ychange*TICSPERFRAME)>>2; + sprite[spritenum].z += (zchange*TICSPERFRAME)>>2; + if(bg) + setsprite(spritenum,sprite[spritenum].x,sprite[spritenum].y,sprite[spritenum].z); + return 0; + } + + dasectnum = sprite[spritenum].sectnum; + + daz = sprite[spritenum].z; + h = ((tilesizy[sprite[spritenum].picnum]*sprite[spritenum].yrepeat)<<1); + daz -= h; + + if( bg ) + { + oldx = sprite[spritenum].x; + oldy = sprite[spritenum].y; + + if( sprite[spritenum].xrepeat > 60 ) + retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),1024L,(4<<8),(4<<8),cliptype); + else + { + if(sprite[spritenum].picnum == LIZMAN) + cd = 292L; + else if( (actortype[sprite[spritenum].picnum]&3) ) + cd = sprite[spritenum].clipdist<<2; + else + cd = 192L; + + retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),cd,(4<<8),(4<<8),cliptype); + } + + if( dasectnum < 0 || ( dasectnum >= 0 && + ( ( hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum ) || + ( ( sprite[spritenum].picnum == BOSS2 ) && sprite[spritenum].pal == 0 && sector[dasectnum].lotag != 3 ) || + ( ( sprite[spritenum].picnum == BOSS1 || sprite[spritenum].picnum == BOSS2 ) && sector[dasectnum].lotag == 1 ) || + ( sector[dasectnum].lotag == 1 && ( sprite[spritenum].picnum == LIZMAN || ( sprite[spritenum].picnum == LIZTROOP && sprite[spritenum].zvel == 0 ) ) ) + ) ) + ) + { + sprite[spritenum].x = oldx; + sprite[spritenum].y = oldy; + if(sector[dasectnum].lotag == 1 && sprite[spritenum].picnum == LIZMAN) + sprite[spritenum].ang = (TRAND&2047); + else if( (hittype[spritenum].temp_data[0]&3) == 1 && sprite[spritenum].picnum != COMMANDER ) + sprite[spritenum].ang = (TRAND&2047); + setsprite(spritenum,oldx,oldy,sprite[spritenum].z); + if(dasectnum < 0) dasectnum = 0; + return (16384+dasectnum); + } + if( (retval&49152) >= 32768 && (hittype[spritenum].cgg==0) ) sprite[spritenum].ang += 768; + } + else + { + if(sprite[spritenum].statnum == 4) + retval = + clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),8L,(4<<8),(4<<8),cliptype); + else + retval = + clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),(long)(sprite[spritenum].clipdist<<2),(4<<8),(4<<8),cliptype); + } + + if( dasectnum >= 0) + if ( (dasectnum != sprite[spritenum].sectnum) ) + changespritesect(spritenum,dasectnum); + daz = sprite[spritenum].z + ((zchange*TICSPERFRAME)>>3); + if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz)) + sprite[spritenum].z = daz; + else + if (retval == 0) + return(16384+dasectnum); + + return(retval); +} + +short ssp(short i,unsigned long cliptype) //The set sprite function +{ + spritetype *s; + long movetype; + + s = &sprite[i]; + + movetype = movesprite(i, + (s->xvel*(sintable[(s->ang+512)&2047]))>>14, + (s->xvel*(sintable[s->ang&2047]))>>14,s->zvel, + cliptype); + + return (movetype==0); +} + +void insertspriteq(short i) +{ + if(spriteqamount > 0) + { + if(spriteq[spriteqloc] >= 0) + sprite[spriteq[spriteqloc]].xrepeat = 0; + spriteq[spriteqloc] = i; + spriteqloc = (spriteqloc+1)%spriteqamount; + } + // else sprite[i].xrepeat = sprite[i].yrepeat = 0; + else deletesprite(i); +} + +void lotsofmoney(spritetype *s, short n) +{ + short i ,j; + for(i=n;i>0;i--) + { + j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MONEY,-32,8,8,TRAND&2047,0,0,0,5); + sprite[j].cstat = TRAND&12; + } +} + +void lotsofmail(spritetype *s, short n) +{ + short i ,j; + for(i=n;i>0;i--) + { + j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MAIL,-32,8,8,TRAND&2047,0,0,0,5); + sprite[j].cstat = TRAND&12; + } +} + +void lotsofpaper(spritetype *s, short n) +{ + short i ,j; + for(i=n;i>0;i--) + { + j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),PAPER,-32,8,8,TRAND&2047,0,0,0,5); + sprite[j].cstat = TRAND&12; + } +} + +void guts(spritetype *s,short gtype, short n, short p) +{ + long gutz,floorz; + short i,a,j; + char sx,sy; + signed char pal; + + if(badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z-(8<<8); + floorz = getflorzofslope(s->sectnum,s->x,s->y); + + if( gutz > ( floorz-(8<<8) ) ) + gutz = floorz-(8<<8); + + if(s->picnum == COMMANDER) + gutz -= (24<<8); + + if( badguy(s) && s->pal == 6) + pal = 6; + else pal = 0; + + for(j=0;jsectnum,s->x+(TRAND&255)-128,s->y+(TRAND&255)-128,gutz-(TRAND&8191),gtype,-32,sx,sy,a,48+(TRAND&31),-512-(TRAND&2047),ps[p].i,5); + if(PN == JIBS2) + { + sprite[i].xrepeat >>= 2; + sprite[i].yrepeat >>= 2; + } + if(pal == 6) + sprite[i].pal = 6; + } +} + +void gutsdir(spritetype *s,short gtype, short n, short p) +{ + long gutz,floorz; + short i,a,j; + char sx,sy; + + if(badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z-(8<<8); + floorz = getflorzofslope(s->sectnum,s->x,s->y); + + if( gutz > ( floorz-(8<<8) ) ) + gutz = floorz-(8<<8); + + if(s->picnum == COMMANDER) + gutz -= (24<<8); + + for(j=0;jsectnum,s->x,s->y,gutz,gtype,-32,sx,sy,a,256+(TRAND&127),-512-(TRAND&2047),ps[p].i,5); + } +} + +void setsectinterpolate(short i) +{ + long j, k, startwall,endwall; + + startwall = sector[SECT].wallptr; + endwall = startwall+sector[SECT].wallnum; + + for(j=startwall;j= 0) + { + setinterpolation(&wall[k].x); + setinterpolation(&wall[k].y); + k = wall[k].point2; + setinterpolation(&wall[k].x); + setinterpolation(&wall[k].y); + } + } +} + +void clearsectinterpolate(short i) +{ + short j,startwall,endwall; + + startwall = sector[SECT].wallptr; + endwall = startwall+sector[SECT].wallnum; + for(j=startwall;j= 0) + { + stopinterpolation(&wall[wall[j].nextwall].x); + stopinterpolation(&wall[wall[j].nextwall].y); + } + } +} + +void ms(short i) +{ + //T1,T2 and T3 are used for all the sector moving stuff!!! + + short startwall,endwall,x; + long tx,ty,j,k; + spritetype *s; + + s = &sprite[i]; + + s->x += (s->xvel*(sintable[(s->ang+512)&2047]))>>14; + s->y += (s->xvel*(sintable[s->ang&2047]))>>14; + + j = T2; + k = T3; + + startwall = sector[s->sectnum].wallptr; + endwall = startwall+sector[s->sectnum].wallnum; + for(x=startwall;xx+tx,s->y+ty); + + j++; + } +} + +void movefta(void) +{ + long x, px, py, sx, sy; + short i, j, p, psect, ssect, nexti; + spritetype *s; + + i = headspritestat[2]; + while(i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = findplayer(s,&x); + + ssect = psect = s->sectnum; + + if(sprite[ps[p].i].extra > 0 ) + { + if( x < 30000 ) + { + hittype[i].timetosleep++; + if( hittype[i].timetosleep >= (x>>8) ) + { + if(badguy(s)) + { + px = ps[p].oposx+64-(TRAND&127); + py = ps[p].oposy+64-(TRAND&127); + updatesector(px,py,&psect); + if(psect == -1) + { + i = nexti; + continue; + } + sx = s->x+64-(TRAND&127); + sy = s->y+64-(TRAND&127); + updatesector(px,py,&ssect); + if(ssect == -1) + { + i = nexti; + continue; + } + j = cansee(sx,sy,s->z-(TRAND%(52<<8)),s->sectnum,px,py,ps[p].oposz-(TRAND%(32<<8)),ps[p].cursectnum); + } + else + j = cansee(s->x,s->y,s->z-((TRAND&31)<<8),s->sectnum,ps[p].oposx,ps[p].oposy,ps[p].oposz-((TRAND&31)<<8),ps[p].cursectnum); + + // j = 1; + + if(j) switch(dynamictostatic[s->picnum]) + { + case RUBBERCAN__STATIC: + case EXPLODINGBARREL__STATIC: + case WOODENHORSE__STATIC: + case HORSEONSIDE__STATIC: + case CANWITHSOMETHING__STATIC: + case CANWITHSOMETHING2__STATIC: + case CANWITHSOMETHING3__STATIC: + case CANWITHSOMETHING4__STATIC: + case FIREBARREL__STATIC: + case FIREVASE__STATIC: + case NUKEBARREL__STATIC: + case NUKEBARRELDENTED__STATIC: + case NUKEBARRELLEAKED__STATIC: + case TRIPBOMB__STATIC: + if (sector[s->sectnum].ceilingstat&1 && checkspriteflags(j,SPRITE_FLAG_NOSHADE) == 0) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + + hittype[i].timetosleep = 0; + changespritestat(i,6); + break; + default: + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i,1); + break; + } + else hittype[i].timetosleep = 0; + } + } + if( badguy( s ) && checkspriteflags(i,SPRITE_FLAG_NOSHADE) == 0) + { + if (sector[s->sectnum].ceilingstat&1) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + } + } + i = nexti; + } +} + +short ifhitsectors(short sectnum) +{ + short i; + + i = headspritestat[5]; + while(i >= 0) + { + if( PN == EXPLOSION2 && sectnum == SECT ) + return i; + i = nextspritestat[i]; + } + return -1; +} + +short ifhitbyweapon(short sn) +{ + short j, k, p; + spritetype *npc; + + if( hittype[sn].extra >= 0 ) + { + if(sprite[sn].extra >= 0 ) + { + npc = &sprite[sn]; + + if(npc->picnum == APLAYER) + { + if(ud.god && hittype[sn].picnum != SHRINKSPARK ) return -1; + + p = npc->yvel; + j = hittype[sn].owner; + + if( j >= 0 && + sprite[j].picnum == APLAYER && + (gametype_flags[ud.coop] & GAMETYPE_FLAG_COOP) && + ud.ffire == 0 ) + return -1; + + npc->extra -= hittype[sn].extra; + + if(j >= 0) + { + if(npc->extra <= 0 && hittype[sn].picnum != FREEZEBLAST) + { + npc->extra = 0; + + ps[p].wackedbyactor = j; + + if( sprite[hittype[sn].owner].picnum == APLAYER && p != sprite[hittype[sn].owner].yvel ) + ps[p].frag_ps = sprite[j].yvel; + + hittype[sn].owner = ps[p].i; + } + } + + if(checkspriteflagsp(hittype[sn].picnum,SPRITE_FLAG_PROJECTILE) && (thisprojectile[sn].workslike & PROJECTILE_FLAG_RPG)) + { + ps[p].posxv += + hittype[sn].extra*(sintable[(hittype[sn].ang+512)&2047])<<2; + ps[p].posyv += + hittype[sn].extra*(sintable[hittype[sn].ang&2047])<<2; + } + + switch(dynamictostatic[hittype[sn].picnum]) + { + case RADIUSEXPLOSION__STATIC: + case RPG__STATIC: + case HYDRENT__STATIC: + case HEAVYHBOMB__STATIC: + case SEENINE__STATIC: + case OOZFILTER__STATIC: + case EXPLODINGBARREL__STATIC: + ps[p].posxv += + hittype[sn].extra*(sintable[(hittype[sn].ang+512)&2047])<<2; + ps[p].posyv += + hittype[sn].extra*(sintable[hittype[sn].ang&2047])<<2; + break; + default: + ps[p].posxv += + hittype[sn].extra*(sintable[(hittype[sn].ang+512)&2047])<<1; + ps[p].posyv += + hittype[sn].extra*(sintable[hittype[sn].ang&2047])<<1; + break; + } + } + else + { + if(hittype[sn].extra == 0 ) + if( hittype[sn].picnum == SHRINKSPARK && npc->xrepeat < 24 ) + return -1; + + npc->extra -= hittype[sn].extra; + if(npc->picnum != RECON && npc->owner >= 0 && sprite[npc->owner].statnum < MAXSTATUS ) + npc->owner = hittype[sn].owner; + } + + hittype[sn].extra = -1; + return hittype[sn].picnum; + } + } + + hittype[sn].extra = -1; + return -1; +} + +void movecyclers(void) +{ + short q, j, x, t, s, *c; + walltype *wal; + char cshade; + + for(q=numcyclers-1;q>=0;q--) + { + + c = &cyclers[q][0]; + s = c[0]; + + t = c[3]; + j = t+(sintable[c[1]&2047]>>10); + cshade = c[2]; + + if( j < cshade ) j = cshade; + else if( j > t ) j = t; + + c[1] += sector[s].extra; + if(c[5]) + { + wal = &wall[sector[s].wallptr]; + for(x = sector[s].wallnum;x>0;x--,wal++) + if( wal->hitag != 1 ) + { + wal->shade = j; + + if( (wal->cstat&2) && wal->nextwall >= 0) + wall[wal->nextwall].shade = j; + + } + sector[s].floorshade = sector[s].ceilingshade = j; + } + } +} + +void movedummyplayers(void) +{ + short i, p, nexti; + + i = headspritestat[13]; + while(i >= 0) + { + nexti = nextspritestat[i]; + + p = sprite[OW].yvel; + + if( ps[p].on_crane >= 0 || sector[ps[p].cursectnum].lotag != 1 || sprite[ps[p].i].extra <= 0 ) + { + ps[p].dummyplayersprite = -1; + KILLIT(i); + } + else + { + if(ps[p].on_ground && ps[p].on_warping_sector == 1 && sector[ps[p].cursectnum].lotag == 1 ) + { + CS = 257; + SZ = sector[SECT].ceilingz+(27<<8); + SA = ps[p].ang; + if(T1 == 8) + T1 = 0; + else T1++; + } + else + { + if(sector[SECT].lotag != 2) SZ = sector[SECT].floorz; + CS = (short) 32768; + } + } + + SX += (ps[p].posx-ps[p].oposx); + SY += (ps[p].posy-ps[p].oposy); + setsprite(i,SX,SY,SZ); + +BOLT: + + i = nexti; + } +} + +short otherp; +void moveplayers(void) //Players +{ + short i , nexti; + long otherx; + spritetype *s; + struct player_struct *p; + + i = headspritestat[10]; + while(i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = &ps[s->yvel]; + if(s->owner >= 0) + { + if(p->newowner >= 0 ) //Looking thru the camera + { + s->x = p->oposx; + s->y = p->oposy; + hittype[i].bposz = s->z = p->oposz+PHEIGHT; + s->ang = p->oang; + setsprite(i,s->x,s->y,s->z); + } + else + { + if(ud.multimode > 1) + otherp = findotherplayer(s->yvel,&otherx); + else + { + otherp = s->yvel; + otherx = 0; + } + + execute(i,s->yvel,otherx); + + if(ud.multimode > 1) + if( sprite[ps[otherp].i].extra > 0 ) + { + if( s->yrepeat > 32 && sprite[ps[otherp].i].yrepeat < 32) + { + if( otherx < 1400 && p->knee_incs == 0 ) + { + p->knee_incs = 1; + p->weapon_pos = -1; + p->actorsqu = ps[otherp].i; + } + } + } + if(ud.god) + { + s->extra = max_player_health; + s->cstat = 257; + p->jetpack_amount = 1599; + } + + + if( s->extra > 0 ) + { + hittype[i].owner = i; + + if(ud.god == 0) + if( ceilingspace(s->sectnum) || floorspace(s->sectnum) ) + quickkill(p); + } + else + { + + p->posx = s->x; + p->posy = s->y; + p->posz = s->z-(20<<8); + + p->newowner = -1; + + if( p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS ) + { + p->ang += getincangle(p->ang,getangle(sprite[p->wackedbyactor].x-p->posx,sprite[p->wackedbyactor].y-p->posy))>>1; + p->ang &= 2047; + } + + } + s->ang = p->ang; + } + } + else + { + if(p->holoduke_on == -1) + KILLIT(i); + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + s->cstat = 0; + + if(s->xrepeat < 42) + { + s->xrepeat += 4; + s->cstat |= 2; + } + else s->xrepeat = 42; + if(s->yrepeat < 36) + s->yrepeat += 4; + else + { + s->yrepeat = 36; + if(sector[s->sectnum].lotag != 2) + makeitfall(i); + if(s->zvel == 0 && sector[s->sectnum].lotag == 1) + s->z += (32<<8); + } + + if(s->extra < 8) + { + s->xvel = 128; + s->ang = p->ang; + s->extra++; + ssp(i,CLIPMASK0); + } + else + { + s->ang = 2047-p->ang; + setsprite(i,s->x,s->y,s->z); + } + } + + if (sector[s->sectnum].ceilingstat&1) + s->shade += (sector[s->sectnum].ceilingshade-s->shade)>>1; + else + s->shade += (sector[s->sectnum].floorshade-s->shade)>>1; + +BOLT: + i = nexti; + } +} + +void movefx(void) +{ + short i, j, nexti, p; + long x, ht; + spritetype *s; + + i = headspritestat[11]; + while(i >= 0) + { + s = &sprite[i]; + + nexti = nextspritestat[i]; + + switch(dynamictostatic[s->picnum]) + { + case RESPAWN__STATIC: + if(sprite[i].extra == 66) + { + j = spawn(i,SHT); + // sprite[j].pal = sprite[i].pal; + KILLIT(i); + } + else if(sprite[i].extra > (66-13)) + sprite[i].extra++; + break; + + case MUSICANDSFX__STATIC: + + ht = s->hitag; + + if(T2 != SoundToggle) + { + T2 = SoundToggle; + T1 = 0; + } + + if(s->lotag >= 1000 && s->lotag < 2000) + { + x = ldist(&sprite[ps[screenpeek].i],s); + if( x < ht && T1 == 0 ) + { + FX_SetReverb( s->lotag - 1000 ); + T1 = 1; + } + if( x >= ht && T1 == 1 ) + { + FX_SetReverb(0); + FX_SetReverbDelay(0); + T1 = 0; + } + } + else if(s->lotag < 999 && (unsigned)sector[s->sectnum].lotag < 9 && AmbienceToggle && sector[SECT].floorz != sector[SECT].ceilingz) + { + if( (soundm[s->lotag]&2) ) + { + x = dist(&sprite[ps[screenpeek].i],s); + if( x < ht && T1 == 0 && FX_VoiceAvailable(soundpr[s->lotag]-1) ) + { + if(numenvsnds == NumVoices) + { + j = headspritestat[11]; + while(j >= 0) + { + if( PN == MUSICANDSFX && j != i && sprite[j].lotag < 999 && hittype[j].temp_data[0] == 1 && dist(&sprite[j],&sprite[ps[screenpeek].i]) > x ) + { + stopenvsound(sprite[j].lotag,j); + break; + } + j = nextspritestat[j]; + } + if(j == -1) goto BOLT; + } + spritesound(s->lotag,i); + T1 = 1; + } + if( x >= ht && T1 == 1 ) + { + T1 = 0; + stopenvsound(s->lotag,i); + } + } + if( (soundm[s->lotag]&16) ) + { + if(T5 > 0) T5--; + else for(p=connecthead;p>=0;p=connectpoint2[p]) + if( p == myconnectindex && ps[p].cursectnum == s->sectnum ) + { + j = s->lotag+((unsigned)global_random%(s->hitag+1)); + sound(j); + T5 = 26*40 + (global_random%(26*40)); + } + } + } + break; + } +BOLT: + i = nexti; + } +} + +void movefallers(void) +{ + short i, nexti, sect, j; + spritetype *s; + long x; + + i = headspritestat[12]; + while(i >= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sect = s->sectnum; + + if( T1 == 0 ) + { + s->z -= (16<<8); + T2 = s->ang; + x = s->extra; + IFHIT + { + if( j == FIREEXT || j == RPG || j == RADIUSEXPLOSION || j == SEENINE || j == OOZFILTER ) + { + if(s->extra <= 0) + { + T1 = 1; + j = headspritestat[12]; + while(j >= 0) + { + if(sprite[j].hitag == SHT) + { + hittype[j].temp_data[0] = 1; + sprite[j].cstat &= (65535-64); + if(sprite[j].picnum == CEILINGSTEAM || sprite[j].picnum == STEAM) + sprite[j].cstat |= 32768; + } + j = nextspritestat[j]; + } + } + } + else + { + hittype[i].extra = 0; + s->extra = x; + } + } + s->ang = T2; + s->z += (16<<8); + } + else if(T1 == 1) + { + if(s->lotag > 0) + { + s->lotag-=3; + if(s->lotag <= 0) + { + s->xvel = (32+(TRAND&63)); + s->zvel = -(1024+(TRAND&1023)); + } + } + else + { + if( s->xvel > 0) + { + s->xvel -= 8; + ssp(i,CLIPMASK0); + } + + if( floorspace(s->sectnum) ) x = 0; + else + { + if(ceilingspace(s->sectnum)) + x = gc/6; + else + x = gc; + } + + if( s->z < (sector[sect].floorz-FOURSLEIGHT) ) + { + s->zvel += x; + if(s->zvel > 6144) + s->zvel = 6144; + s->z += s->zvel; + } + if( (sector[sect].floorz-s->z) < (16<<8) ) + { + j = 1+(TRAND&7); + for(x=0;x= 0) + { + nexti = nextspritestat[i]; + + t = &hittype[i].temp_data[0]; + s = &sprite[i]; + sect = s->sectnum; + + if( sect < 0 ) KILLIT(i); + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + IFWITHIN(CRANE,CRANE+3) + { + //t[0] = state + //t[1] = checking sector number + + if(s->xvel) getglobalz(i); + + if( t[0] == 0 ) //Waiting to check the sector + { + j = headspritesect[t[1]]; + while(j>=0) + { + nextj = nextspritesect[j]; + switch( sprite[j].statnum ) + { + case 1: + case 2: + case 6: + case 10: + s->ang = getangle(msx[t[4]+1]-s->x,msy[t[4]+1]-s->y); + setsprite(j,msx[t[4]+1],msy[t[4]+1],sprite[j].z); + t[0]++; + goto BOLT; + } + j = nextj; + } + } + + else if(t[0]==1) + { + if( s->xvel < 184 ) + { + s->picnum = CRANE+1; + s->xvel += 8; + } + ssp(i,CLIPMASK0); + if(sect == t[1]) + t[0]++; + } + else if(t[0]==2 || t[0]==7) + { + s->z += (1024+512); + + if(t[0]==2) + { + if( (sector[sect].floorz - s->z) < (64<<8) ) + if(s->picnum > CRANE) s->picnum--; + + if( (sector[sect].floorz - s->z) < (4096+1024)) + t[0]++; + } + if(t[0]==7) + { + if( (sector[sect].floorz - s->z) < (64<<8) ) + { + if(s->picnum > CRANE) s->picnum--; + else + { + if(s->owner==-2) + { + spritesound(DUKE_GRUNT,ps[p].i); + p = findplayer(s,&x); + if(ps[p].on_crane == i) + ps[p].on_crane = -1; + } + t[0]++; + s->owner = -1; + } + } + } + } + else if(t[0]==3) + { + s->picnum++; + if( s->picnum == (CRANE+2) ) + { + p = checkcursectnums(t[1]); + if(p >= 0 && ps[p].on_ground) + { + s->owner = -2; + ps[p].on_crane = i; + spritesound(DUKE_GRUNT,ps[p].i); + ps[p].ang = s->ang+1024; + } + else + { + j = headspritesect[t[1]]; + while(j>=0) + { + switch( sprite[j].statnum ) + { + case 1: + case 6: + s->owner = j; + break; + } + j = nextspritesect[j]; + } + } + + t[0]++;//Grabbed the sprite + t[2]=0; + goto BOLT; + } + } + else if(t[0]==4) //Delay before going up + { + t[2]++; + if(t[2] > 10) + t[0]++; + } + else if(t[0]==5 || t[0] == 8) + { + if(t[0]==8 && s->picnum < (CRANE+2)) + if( (sector[sect].floorz-s->z) > 8192) + s->picnum++; + + if(s->z < msx[t[4]+2]) + { + t[0]++; + s->xvel = 0; + } + else + s->z -= (1024+512); + } + else if(t[0]==6) + { + if( s->xvel < 192 ) + s->xvel += 8; + s->ang = getangle(msx[t[4]]-s->x,msy[t[4]]-s->y); + ssp(i,CLIPMASK0); + if( ((s->x-msx[t[4]])*(s->x-msx[t[4]])+(s->y-msy[t[4]])*(s->y-msy[t[4]]) ) < (128*128) ) + t[0]++; + } + + else if(t[0]==9) + t[0] = 0; + + setsprite(msy[t[4]+2],s->x,s->y,s->z-(34<<8)); + + if(s->owner != -1) + { + p = findplayer(s,&x); + + IFHIT + { + if(s->owner == -2) + if(ps[p].on_crane == i) + ps[p].on_crane = -1; + s->owner = -1; + s->picnum = CRANE; + goto BOLT; + } + + if(s->owner >= 0) + { + setsprite(s->owner,s->x,s->y,s->z); + + hittype[s->owner].bposx = s->x; + hittype[s->owner].bposy = s->y; + hittype[s->owner].bposz = s->z; + + s->zvel = 0; + } + else if(s->owner == -2) + { + ps[p].oposx = ps[p].posx = s->x-(sintable[(ps[p].ang+512)&2047]>>6); + ps[p].oposy = ps[p].posy = s->y-(sintable[ps[p].ang&2047]>>6); + ps[p].oposz = ps[p].posz = s->z+(2<<8); + setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz); + ps[p].cursectnum = sprite[ps[p].i].sectnum; + } + } + + goto BOLT; + } + + IFWITHIN(WATERFOUNTAIN,WATERFOUNTAIN+3) + { + if(t[0] > 0) + { + if( t[0] < 20 ) + { + t[0]++; + + s->picnum++; + + if( s->picnum == ( WATERFOUNTAIN+3 ) ) + s->picnum = WATERFOUNTAIN+1; + } + else + { + p = findplayer(s,&x); + + if(x > 512) + { + t[0] = 0; + s->picnum = WATERFOUNTAIN; + } + else t[0] = 1; + } + } + goto BOLT; + } + + if( AFLAMABLE(s->picnum) ) + { + if(T1 == 1) + { + T2++; + if( (T2&3) > 0) goto BOLT; + + if( s->picnum == TIRE && T2 == 32 ) + { + s->cstat = 0; + j = spawn(i,BLOODPOOL); + sprite[j].shade = 127; + } + else + { + if(s->shade < 64) s->shade++; + else KILLIT(i); + } + + j = s->xrepeat-(TRAND&7); + if(j < 10) + { + KILLIT(i); + } + + s->xrepeat = j; + + j = s->yrepeat-(TRAND&7); + if(j < 4) { KILLIT(i); } + s->yrepeat = j; + } + if(s->picnum == BOX) + { + makeitfall(i); + hittype[i].ceilingz = sector[s->sectnum].ceilingz; + } + goto BOLT; + } + + if(s->picnum == TRIPBOMB) + { + // long lTripBombControl=GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1); + // if(lTripBombControl & TRIPBOMB_TIMER) + if (hittype[i].temp_data[6] == 1) + { + + if(hittype[i].temp_data[7] >= 1) + { + hittype[i].temp_data[7]--; + } + + if(hittype[i].temp_data[7] <= 0) + { + // s->extra = *actorscrptr[s->picnum]; + T3=16; + hittype[i].temp_data[6]=3; + spritesound(LASERTRIP_ARMING,i); + } + // we're on a timer.... + } + if(T3 > 0 && hittype[i].temp_data[6] == 3) + { + T3--; + if(T3 == 8) + { + spritesound(LASERTRIP_EXPLODE,i); + for(j=0;j<5;j++) RANDOMSCRAP; + x = s->extra; + hitradius( i, tripbombblastradius, x>>2,x>>1,x-(x>>2),x); + + j = spawn(i,EXPLOSION2); + sprite[j].ang = s->ang; + sprite[j].xvel = 348; + ssp(j,CLIPMASK0); + + j = headspritestat[5]; + while(j >= 0) + { + if(sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag) + sprite[j].xrepeat = sprite[j].yrepeat = 0; + j = nextspritestat[j]; + } + KILLIT(i); + } + goto BOLT; + } + else + { + x = s->extra; + s->extra = 1; + l = s->ang; + IFHIT { hittype[i].temp_data[6] = 3; T3 = 16; } + s->extra = x; + s->ang = l; + } + + if( T1 < 32 ) + { + p = findplayer(s,&x); + if( x > 768 ) T1++; + else if(T1 > 16) T1++; + } + if( T1 == 32 ) + { + l = s->ang; + s->ang = T6; + + T4 = s->x;T5 = s->y; + s->x += sintable[(T6+512)&2047]>>9; + s->y += sintable[(T6)&2047]>>9; + s->z -= (3<<8); + setsprite(i,s->x,s->y,s->z); + + x = hitasprite(i,&m); + + hittype[i].lastvx = x; + + s->ang = l; + + k = 0; + + // if(lTripBombControl & TRIPBOMB_TRIPWIRE) + if (hittype[i].temp_data[6] != 1) + { + // we're on a trip wire + + while(x > 0) + { + j = spawn(i,LASERLINE); + setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z); + sprite[j].hitag = s->hitag; + hittype[j].temp_data[1] = sprite[j].z; + + s->x += sintable[(T6+512)&2047]>>4; + s->y += sintable[(T6)&2047]>>4; + + if( x < 1024 ) + { + sprite[j].xrepeat = x>>5; + break; + } + x -= 1024; + } + } + T1++; + s->x = T4;s->y = T5; + s->z += (3<<8); + setsprite(i,s->x,s->y,s->z); + T4 = 0; + // if( m >= 0 && lTripBombControl & TRIPBOMB_TRIPWIRE) + if (m >= 0 && hittype[i].temp_data[6] != 1) + { + hittype[i].temp_data[6] = 3; + T3 = 13; + spritesound(LASERTRIP_ARMING,i); + } + else T3 = 0; + } + if(T1 == 33) + { + T2++; + + + T4 = s->x;T5 = s->y; + s->x += sintable[(T6+512)&2047]>>9; + s->y += sintable[(T6)&2047]>>9; + s->z -= (3<<8); + setsprite(i,s->x,s->y,s->z); + + x = hitasprite(i,&m); + + s->x = T4;s->y = T5; + s->z += (3<<8); + setsprite(i,s->x,s->y,s->z); + + // if( hittype[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE) + if( hittype[i].lastvx != x && hittype[i].temp_data[6] != 1) + { + hittype[i].temp_data[6] = 3; + T3 = 13; + spritesound(LASERTRIP_ARMING,i); + } + } + goto BOLT; + } + + + if( s->picnum >= CRACK1 && s->picnum <= CRACK4 ) + { + if(s->hitag > 0) + { + t[0] = s->cstat; + t[1] = s->ang; + j = ifhitbyweapon(i); + if(j == FIREEXT || j == RPG || j == RADIUSEXPLOSION || j == SEENINE || j == OOZFILTER ) + { + j = headspritestat[6]; + while(j >= 0) + { + if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE ) ) + if(sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + + goto DETONATE; + } + else + { + s->cstat = t[0]; + s->ang = t[1]; + s->extra = 0; + } + } + goto BOLT; + } + + if( s->picnum == FIREEXT ) + { + j = ifhitbyweapon(i); + if( j == -1 ) goto BOLT; + + for(k=0;k<16;k++) + { + j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5); + sprite[j].pal = 2; + } + + spawn(i,EXPLOSION2); + spritesound(PIPEBOMB_EXPLODE,i); + spritesound(GLASS_HEAVYBREAK,i); + + if(s->hitag > 0) + { + j = headspritestat[6]; + while(j >= 0) + { + if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE ) ) + if(sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + + x = s->extra; + spawn(i,EXPLOSION2); + hitradius( i, pipebombblastradius,x>>2, x-(x>>1),x-(x>>2), x); + spritesound(PIPEBOMB_EXPLODE,i); + + goto DETONATE; + } + else + { + hitradius(i,seenineblastradius,10,15,20,25); + KILLIT(i); + } + goto BOLT; + } + + if(s->picnum == OOZFILTER || s->picnum == SEENINE || s->picnum == SEENINEDEAD || s->picnum == (SEENINEDEAD+1) ) + { + if(s->shade != -32 && s->shade != -33) + { + if(s->xrepeat) + j = (ifhitbyweapon(i) >= 0); + else + j = 0; + + if( j || s->shade == -31 ) + { + if(j) s->lotag = 0; + + t[3] = 1; + + j = headspritestat[6]; + while(j >= 0) + { + if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == SEENINE || sprite[j].picnum == OOZFILTER ) ) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + } + } + else + { + if(s->shade == -32) + { + if(s->lotag > 0) + { + s->lotag-=3; + if(s->lotag <= 0) s->lotag = -99; + } + else + s->shade = -33; + } + else + { + if( s->xrepeat > 0 ) + { + T3++; + if(T3 == 3) + { + if( s->picnum == OOZFILTER ) + { + T3 = 0; + goto DETONATE; + } + if( s->picnum != (SEENINEDEAD+1) ) + { + T3 = 0; + + if(s->picnum == SEENINEDEAD) s->picnum++; + else if(s->picnum == SEENINE) + s->picnum = SEENINEDEAD; + } + else goto DETONATE; + } + goto BOLT; + } + +DETONATE: + + earthquaketime = 16; + + j = headspritestat[3]; + while(j >= 0) + { + if( s->hitag == sprite[j].hitag ) + { + if(sprite[j].lotag == 13) + { + if( hittype[j].temp_data[2] == 0 ) + hittype[j].temp_data[2] = 1; + } + else if(sprite[j].lotag == 8) + hittype[j].temp_data[4] = 1; + else if(sprite[j].lotag == 18) + { + if(hittype[j].temp_data[0] == 0) + hittype[j].temp_data[0] = 1; + } + else if(sprite[j].lotag == 21) + hittype[j].temp_data[0] = 1; + } + j = nextspritestat[j]; + } + + s->z -= (32<<8); + + if( ( t[3] == 1 && s->xrepeat ) || s->lotag == -99 ) + { + x = s->extra; + spawn(i,EXPLOSION2); + hitradius( i,seenineblastradius,x>>2, x-(x>>1),x-(x>>2), x); + spritesound(PIPEBOMB_EXPLODE,i); + } + + if(s->xrepeat) + for(x=0;x<8;x++) RANDOMSCRAP; + + KILLIT(i); + } + } + goto BOLT; + } + + if(s->picnum == MASTERSWITCH) + { + if(s->yvel == 1) + { + s->hitag--; + if(s->hitag <= 0) + { + operatesectors(sect,i); + + j = headspritesect[sect]; + while(j >= 0) + { + if(sprite[j].statnum == 3) + { + switch(sprite[j].lotag) + { + case 2: + case 21: + case 31: + case 32: + case 36: + hittype[j].temp_data[0] = 1; + break; + case 3: + hittype[j].temp_data[4] = 1; + break; + } + } + else if(sprite[j].statnum == 6) + { + switch(dynamictostatic[sprite[j].picnum]) + { + case SEENINE__STATIC: + case OOZFILTER__STATIC: + sprite[j].shade = -31; + break; + } + } + j = nextspritesect[j]; + } + KILLIT(i); + } + } + goto BOLT; + } + switchpicnum = s->picnum; + if ((s->picnum > SIDEBOLT1) && (s->picnum <= SIDEBOLT1+3)) { + switchpicnum = SIDEBOLT1; + } + if ((s->picnum > BOLT1) && (s->picnum <= BOLT1+3)) { + switchpicnum = BOLT1; + } + + switch(dynamictostatic[switchpicnum]) + { + case VIEWSCREEN__STATIC: + case VIEWSCREEN2__STATIC: + + if(s->xrepeat == 0) KILLIT(i); + + p = findplayer(s, &x); + + if( x < 2048 ) + { + if( SP == 1 ) + camsprite = i; + } + else if( camsprite != -1 && T1 == 1) + { + camsprite = -1; + T1 = 0; + //loadtile(s->picnum); + //invalidatetile(s->picnum,-1,255); + walock[TILE_VIEWSCR] = 199; + } + + goto BOLT; + + case TRASH__STATIC: + + if(s->xvel == 0) s->xvel = 1; + IFMOVING + { + makeitfall(i); + if(TRAND&1) s->zvel -= 256; + if( klabs(s->xvel) < 48 ) + s->xvel += (TRAND&3); + } + else KILLIT(i); + break; + + case SIDEBOLT1__STATIC: + // case SIDEBOLT1+1: + // case SIDEBOLT1+2: + // case SIDEBOLT1+3: + p = findplayer(s, &x); + if( x > 20480 ) goto BOLT; + +CLEAR_THE_BOLT2: + if(t[2]) + { + t[2]--; + goto BOLT; + } + if( (s->xrepeat|s->yrepeat) == 0 ) + { + s->xrepeat=t[0]; + s->yrepeat=t[1]; + } + if( (TRAND&8) == 0 ) + { + t[0]=s->xrepeat; + t[1]=s->yrepeat; + t[2] = global_random&4; + s->xrepeat=s->yrepeat=0; + goto CLEAR_THE_BOLT2; + } + s->picnum++; + + if(l&1) s->cstat ^= 2; + + if( (TRAND&1) && sector[sect].floorpicnum == HURTRAIL ) + spritesound(SHORT_CIRCUIT,i); + + if(s->picnum == SIDEBOLT1+4) s->picnum = SIDEBOLT1; + + goto BOLT; + + case BOLT1__STATIC: + // case BOLT1+1: + // case BOLT1+2: + // case BOLT1+3: + p = findplayer(s, &x); + if( x > 20480 ) goto BOLT; + + if( t[3] == 0 ) + t[3]=sector[sect].floorshade; + +CLEAR_THE_BOLT: + if(t[2]) + { + t[2]--; + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + goto BOLT; + } + if( (s->xrepeat|s->yrepeat) == 0 ) + { + s->xrepeat=t[0]; + s->yrepeat=t[1]; + } + else if( (TRAND&8) == 0 ) + { + t[0]=s->xrepeat; + t[1]=s->yrepeat; + t[2] = global_random&4; + s->xrepeat=s->yrepeat=0; + goto CLEAR_THE_BOLT; + } + s->picnum++; + + l = global_random&7; + s->xrepeat=l+8; + + if(l&1) s->cstat ^= 2; + + if( s->picnum == (BOLT1+1) && (TRAND&7) == 0 && sector[sect].floorpicnum == HURTRAIL ) + spritesound(SHORT_CIRCUIT,i); + + if(s->picnum==BOLT1+4) s->picnum=BOLT1; + + if(s->picnum&1) + { + sector[sect].floorshade = 0; + sector[sect].ceilingshade = 0; + } + else + { + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + } + goto BOLT; + + case WATERDRIP__STATIC: + + if( t[1] ) + { + t[1]--; + if(t[1] == 0) + s->cstat &= 32767; + } + else + { + makeitfall(i); + ssp(i,CLIPMASK0); + if(s->xvel > 0) s->xvel -= 2; + + if(s->zvel == 0) + { + s->cstat |= 32768; + + if(s->pal != 2 && s->hitag == 0) + spritesound(SOMETHING_DRIPPING,i); + + if(sprite[s->owner].picnum != WATERDRIP) + { + KILLIT(i); + } + else + { + hittype[i].bposz = s->z = t[0]; + t[1] = 48+(TRAND&31); + } + } + } + + + goto BOLT; + + case DOORSHOCK__STATIC: + j = klabs(sector[sect].ceilingz-sector[sect].floorz)>>9; + s->yrepeat = j+4; + s->xrepeat = 16; + s->z = sector[sect].floorz; + goto BOLT; + + case TOUCHPLATE__STATIC: + if( t[1] == 1 && s->hitag >= 0) //Move the sector floor + { + x = sector[sect].floorz; + + if(t[3] == 1) + { + if(x >= t[2]) + { + sector[sect].floorz = x; + t[1] = 0; + } + else + { + sector[sect].floorz += sector[sect].extra; + p = checkcursectnums(sect); + if(p >= 0) ps[p].posz += sector[sect].extra; + } + } + else + { + if(x <= s->z) + { + sector[sect].floorz = s->z; + t[1] = 0; + } + else + { + sector[sect].floorz -= sector[sect].extra; + p = checkcursectnums(sect); + if(p >= 0) + ps[p].posz -= sector[sect].extra; + } + } + goto BOLT; + } + + if(t[5] == 1) goto BOLT; + + p = checkcursectnums(sect); + if( p >= 0 && ( ps[p].on_ground || s->ang == 512) ) + { + if( t[0] == 0 && !check_activator_motion(s->lotag) ) + { + t[0] = 1; + t[1] = 1; + t[3] = !t[3]; + operatemasterswitches(s->lotag); + operateactivators(s->lotag,p); + if(s->hitag > 0) + { + s->hitag--; + if(s->hitag == 0) t[5] = 1; + } + } + } + else t[0] = 0; + + if(t[1] == 1) + { + j = headspritestat[6]; + while(j >= 0) + { + if(j != i && sprite[j].picnum == TOUCHPLATE && sprite[j].lotag == s->lotag) + { + hittype[j].temp_data[1] = 1; + hittype[j].temp_data[3] = t[3]; + } + j = nextspritestat[j]; + } + } + goto BOLT; + + case CANWITHSOMETHING__STATIC: + case CANWITHSOMETHING2__STATIC: + case CANWITHSOMETHING3__STATIC: + case CANWITHSOMETHING4__STATIC: + makeitfall(i); + IFHIT + { + spritesound(VENT_BUST,i); + for(j=0;j<10;j++) + RANDOMSCRAP; + + if(s->lotag) spawn(i,s->lotag); + + KILLIT(i); + } + goto BOLT; + + case EXPLODINGBARREL__STATIC: + case WOODENHORSE__STATIC: + case HORSEONSIDE__STATIC: + case FLOORFLAME__STATIC: + case FIREBARREL__STATIC: + case FIREVASE__STATIC: + case NUKEBARREL__STATIC: + case NUKEBARRELDENTED__STATIC: + case NUKEBARRELLEAKED__STATIC: + case TOILETWATER__STATIC: + case RUBBERCAN__STATIC: + case STEAM__STATIC: + case CEILINGSTEAM__STATIC: + p = findplayer(s, &x); + execute(i,p,x); + goto BOLT; + case WATERBUBBLEMAKER__STATIC: + p = findplayer(s, &x); + execute(i,p,x); + goto BOLT; + } + +BOLT: + i = nexti; + } +} + +void bounce(short i) +{ + long k, l, daang, dax, day, daz, xvect, yvect, zvect; + short hitsect; + spritetype *s = &sprite[i]; + + xvect = mulscale10(s->xvel,sintable[(s->ang+512)&2047]); + yvect = mulscale10(s->xvel,sintable[s->ang&2047]); + zvect = s->zvel; + + hitsect = s->sectnum; + + k = sector[hitsect].wallptr; l = wall[k].point2; + daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y); + + if ( s->z < (hittype[i].floorz+hittype[i].ceilingz)>>1) + k = sector[hitsect].ceilingheinum; + else + k = sector[hitsect].floorheinum; + + dax = mulscale14(k,sintable[(daang)&2047]); + day = mulscale14(k,sintable[(daang+1536)&2047]); + daz = 4096; + + k = xvect*dax+yvect*day+zvect*daz; + l = dax*dax+day*day+daz*daz; + if ((klabs(k)>>14) < l) + { + k = divscale17(k,l); + xvect -= mulscale16(dax,k); + yvect -= mulscale16(day,k); + zvect -= mulscale16(daz,k); + } + + s->zvel = zvect; + s->xvel = ksqrt(dmulscale8(xvect,xvect,yvect,yvect)); + s->ang = getangle(xvect,yvect); +} + +void moveweapons(void) +{ + short i, j=0, k, f, nexti, p, q, tempsect; + long dax,day,daz, x, l, ll, x1, y1; + unsigned long qq; + spritetype *s; + + i = headspritestat[4]; + while(i >= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + if(s->sectnum < 0) KILLIT(i); + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + // here + + if(checkspriteflags(i,SPRITE_FLAG_PROJECTILE)) + { + /* Custom projectiles. This is a big hack. */ + + if (thisprojectile[i].pal >= 0) + s->pal=thisprojectile[i].pal; + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_KNEE) + KILLIT(i); + + if (thisprojectile[i].trail > -1) + { + for(f=0;f<=thisprojectile[i].tnum;f++) + { + j = spawn(i,thisprojectile[i].trail); + if (thisprojectile[i].toffset != 0) + sprite[j].z += (thisprojectile[i].toffset<<8); + else + sprite[j].z += (1<<8); + if (thisprojectile[i].txrepeat >= 0) sprite[j].xrepeat=thisprojectile[i].txrepeat; + if (thisprojectile[i].tyrepeat >= 0) sprite[j].yrepeat=thisprojectile[i].tyrepeat; + + } + } + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_RPG) + { + // if (thisprojectile[i].workslike & COOLEXPLOSION1) + // if( Sound[WIERDSHOT_FLY].num == 0 ) + // spritesound(WIERDSHOT_FLY,i); + + p = -1; + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_COOLEXPLOSION1) + { + s->shade++; + if(s->shade >= 40) KILLIT(i); + } + + if(sector[s->sectnum].lotag == 2) + { + k = s->xvel>>1; + ll = s->zvel>>1; + } + else + { + k = s->xvel; + ll = s->zvel; + } + + if (thisprojectile[i].drop) s->zvel=s->zvel-thisprojectile[i].drop; + + dax = s->x; day = s->y; daz = s->z; + + if(thisprojectile[i].range > 0) + { + if (!(hittype[i].temp_data[8])) + hittype[i].temp_data[8] = 1; + else + hittype[i].temp_data[8]++; + + if(hittype[i].temp_data[8] > thisprojectile[i].range) + { + if (thisprojectile[i].workslike & PROJECTILE_FLAG_EXPLODEONTIMER) + { + if (thisprojectile[i].spawns >= 0 ) + { + k = spawn(i,thisprojectile[i].spawns); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (thisprojectile[i].sxrepeat > 4) sprite[k].xrepeat=thisprojectile[i].sxrepeat; + if (thisprojectile[i].syrepeat > 4) sprite[k].yrepeat=thisprojectile[i].syrepeat; + } + if (thisprojectile[i].isound > -1) + spritesound(thisprojectile[i].isound,i); + + s->extra=thisprojectile[i].extra; + + if(thisprojectile[i].extra_rand > 0) + s->extra += (TRAND&thisprojectile[i].extra_rand); + + x = s->extra; + hitradius( i,thisprojectile[i].hitradius, x>>2,x>>1,x-(x>>2),x); + } + KILLIT(i); + } + } + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS) + { + /* if(s->yvel < 1 || s->extra < 2 || (s->xvel|s->zvel) == 0) + Did this cause the bug with prematurely exploding projectiles? */ + if (s->yvel < 1) + { + + if (thisprojectile[i].spawns >= 0 ) + { + k = spawn(i,thisprojectile[i].spawns); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (thisprojectile[i].sxrepeat > 4) sprite[k].xrepeat=thisprojectile[i].sxrepeat; + if (thisprojectile[i].syrepeat > 4) sprite[k].yrepeat=thisprojectile[i].syrepeat; + } + if (thisprojectile[i].isound > -1) + spritesound(thisprojectile[i].isound,i); + + s->extra=thisprojectile[i].extra; + + if(thisprojectile[i].extra_rand > 0) + s->extra += (TRAND&thisprojectile[i].extra_rand); + + x = s->extra; + hitradius( i,thisprojectile[i].hitradius, x>>2,x>>1,x-(x>>2),x); + + KILLIT(i); + } + + } + + + getglobalz(i); + qq = CLIPMASK1; + + for(f=1;f<=thisprojectile[i].velmult;f++) + j = movesprite(i, + (k*(sintable[(s->ang+512)&2047]))>>14, + (k*(sintable[s->ang&2047]))>>14,ll,qq); + + + if(!(thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS) && s->yvel >= 0) + if( FindDistance2D(s->x-sprite[s->yvel].x,s->y-sprite[s->yvel].y) < 256 ) + j = 49152|s->yvel; + + if(s->sectnum < 0) { KILLIT(i); } + + if( (j&49152) != 49152) + if(!(thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS)) + { + if(s->z < hittype[i].ceilingz) + { + j = 16384|(s->sectnum); + s->zvel = -1; + } + else + if( ( s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1 ) || + ( s->z > hittype[i].floorz+(16<<8) && sector[s->sectnum].lotag == 1 ) ) + { + j = 16384|(s->sectnum); + if(sector[s->sectnum].lotag != 1) + s->zvel = 1; + } + } + + if(thisprojectile[i].workslike & 8192) + { + for(k=-3;k<2;k++) + { + + x = EGS(s->sectnum, + s->x+((k*sintable[(s->ang+512)&2047])>>9), + s->y+((k*sintable[s->ang&2047])>>9), + s->z+((k*ksgn(s->zvel))*klabs(s->zvel/24)),s->picnum,-40+(k<<2), // FIRELASER + s->xrepeat,s->yrepeat,0,0,0,s->owner,5); + + sprite[x].cstat = 128; + sprite[x].pal = s->pal; + + } + } + else if(thisprojectile[i].workslike & PROJECTILE_FLAG_SPIT) if(s->zvel < 6144) + s->zvel += gc-112; + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_WATERBUBBLES && sector[s->sectnum].lotag == 2 && rnd(140)) + spawn(i,WATERBUBBLE); + + if( j != 0 ) + { + if(thisprojectile[i].workslike & PROJECTILE_FLAG_COOLEXPLOSION1) + { + /* if( (j&49152) == 49152 && sprite[j&(MAXSPRITES-1)].picnum != APLAYER) + goto BOLT; */ + s->xvel = 0; + s->zvel = 0; + } + + if( (j&49152) == 49152 ) + { + j &= (MAXSPRITES-1); + + /* if(thisprojectile[i].workslike & PROJECTILE_FLAG_FREEZEBLAST && sprite[j].pal == 1 ) + if( badguy(&sprite[j]) || sprite[j].picnum == APLAYER ) + { + j = spawn(i,TRANSPORTERSTAR); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + + KILLIT(i); + }*/ + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_NOENEMYHITS) + { + if( wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR ) + s->yvel--; + + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + + if (thisprojectile[i].bsound > -1) + spritesound(thisprojectile[i].bsound,i); + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_LOSESVELOCITY) + { + s->xvel=s->xvel>>1; + s->zvel=s->zvel>>1; + } + goto BOLT; + } + + checkhitsprite(j,i); + + if(sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + spritesound(PISTOL_BODYHIT,j); + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_SPIT) + { + ps[p].horiz += 32; + ps[p].return_to_center = 8; + + if(ps[p].loogcnt == 0) + { + if(Sound[DUKE_LONGTERM_PAIN].num < 1) + spritesound(DUKE_LONGTERM_PAIN,ps[p].i); + + j = 3+(TRAND&3); + ps[p].numloogs = j; + ps[p].loogcnt = 24*4; + for(x=0;x < j;x++) + { + ps[p].loogiex[x] = TRAND%xdim; + ps[p].loogiey[x] = TRAND%ydim; + } + } + } + } + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_RPG_IMPACT) + { + + hittype[j].owner = s->owner; + hittype[j].picnum = s->picnum; + hittype[j].extra = thisprojectile[i].extra; + + if (thisprojectile[i].spawns >= 0 ) + { + k = spawn(i,thisprojectile[i].spawns); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (thisprojectile[i].sxrepeat > 4) sprite[k].xrepeat=thisprojectile[i].sxrepeat; + if (thisprojectile[i].syrepeat > 4) sprite[k].yrepeat=thisprojectile[i].syrepeat; + } + + if (thisprojectile[i].isound > -1) + spritesound(thisprojectile[i].isound,i); + + KILLIT(i); + + } + + } + else if( (j&49152) == 32768 ) + { + j &= (MAXWALLS-1); + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFMIRRORS && ( wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR ) ) + { + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + s->owner = i; + spawn(i,TRANSPORTERSTAR); + goto BOLT; + } + else + { + setsprite(i,dax,day,daz); + checkhitwall(i,j,s->x,s->y,s->z,s->picnum); + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS) + { + if( wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR ) + s->yvel--; + + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + + if (thisprojectile[i].bsound > -1) + spritesound(thisprojectile[i].bsound,i); + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_LOSESVELOCITY) + { + s->xvel=s->xvel>>1; + s->zvel=s->zvel>>1; + } + goto BOLT; + } + } + } + else if( (j&49152) == 16384) + { + setsprite(i,dax,day,daz); + + if(s->zvel < 0) + { + if( sector[s->sectnum].ceilingstat&1 ) + if(sector[s->sectnum].ceilingpal == 0) + KILLIT(i); + + checkhitceiling(s->sectnum); + } + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS) + { + bounce(i); + ssp(i,qq); + + /* if(s->xrepeat > 8) + s->xrepeat -= 2; + if(s->yrepeat > 8) + s->yrepeat -= 2;*/ + s->yvel--; + + if (thisprojectile[i].bsound > -1) + spritesound(thisprojectile[i].bsound,i); + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_LOSESVELOCITY) + { + s->xvel=s->xvel>>1; + s->zvel=s->zvel>>1; + } + + goto BOLT; + } + } + + + if(thisprojectile[i].workslike & RPG && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) + spawn(i,WATERBUBBLE); + + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_RPG) + { + if (thisprojectile[i].spawns > 0) + { + k = spawn(i,thisprojectile[i].spawns); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (thisprojectile[i].sxrepeat > 4) sprite[k].xrepeat=thisprojectile[i].sxrepeat; + if (thisprojectile[i].syrepeat > 4) sprite[k].yrepeat=thisprojectile[i].syrepeat; + } + /* if(s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + }*/ + /* else if( (j&49152) == 16384) + { + if( s->zvel > 0) + spawn(i,EXPLOSION2BOT); + else + { + sprite[k].cstat |= 8; + sprite[k].z += (48<<8); + } + } + */ + } + + + if (thisprojectile[i].workslike & PROJECTILE_FLAG_BULLET) + { + p = findplayer(s,&x); + execute(i,p,x); + goto BOLT; + } + + + if(thisprojectile[i].workslike & PROJECTILE_FLAG_RPG) + { + if (thisprojectile[i].isound > -1) + spritesound(thisprojectile[i].isound,i); + + /* if(s->xrepeat >= 10) + {*/ + s->extra=thisprojectile[i].extra; + if(thisprojectile[i].extra_rand > 0) + s->extra += (TRAND&thisprojectile[i].extra_rand); + + x = s->extra; + hitradius( i,thisprojectile[i].hitradius, x>>2,x>>1,x-(x>>2),x); + /* } + else + { + x = s->extra+(global_random&3); + hitradius( i,(thisprojectile[i].hitradius>>1),x>>2,x>>1,x-(x>>2),x); + }*/ + // if (!(thisprojectile[i].workslike & PROJECTILE_FLAG_COOLEXPLOSION1)) + KILLIT(i); + } + } + + + goto BOLT; + + + } + } + else + + { + + // here + switch(dynamictostatic[s->picnum]) + { + case RADIUSEXPLOSION__STATIC: + case KNEE__STATIC: + KILLIT(i); + case TONGUE__STATIC: + T1 = sintable[(T2)&2047]>>9; + T2 += 32; + if(T2 > 2047) KILLIT(i); + + if(sprite[s->owner].statnum == MAXSTATUS) + if(badguy(&sprite[s->owner]) == 0) + KILLIT(i); + + s->ang = sprite[s->owner].ang; + s->x = sprite[s->owner].x; + s->y = sprite[s->owner].y; + if(sprite[s->owner].picnum == APLAYER) + s->z = sprite[s->owner].z-(34<<8); + for(k=0;ksectnum, + s->x+((k*sintable[(s->ang+512)&2047])>>9), + s->y+((k*sintable[s->ang&2047])>>9), + s->z+((k*ksgn(s->zvel))*klabs(s->zvel/12)),TONGUE,-40+(k<<1), + 8,8,0,0,0,i,5); + sprite[q].cstat = 128; + sprite[q].pal = 8; + } + q = EGS(s->sectnum, + s->x+((k*sintable[(s->ang+512)&2047])>>9), + s->y+((k*sintable[s->ang&2047])>>9), + s->z+((k*ksgn(s->zvel))*klabs(s->zvel/12)),INNERJAW,-40, + 32,32,0,0,0,i,5); + sprite[q].cstat = 128; + if( T2 > 512 && T2 < (1024) ) + sprite[q].picnum = INNERJAW+1; + + goto BOLT; + + case FREEZEBLAST__STATIC: + if(s->yvel < 1 || s->extra < 2 || (s->xvel|s->zvel) == 0) + { + j = spawn(i,TRANSPORTERSTAR); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + KILLIT(i); + } + case SHRINKSPARK__STATIC: + case RPG__STATIC: + case FIRELASER__STATIC: + case SPIT__STATIC: + case COOLEXPLOSION1__STATIC: + + if( s->picnum == COOLEXPLOSION1 ) + if( !issoundplaying(WIERDSHOT_FLY) ) + spritesound(WIERDSHOT_FLY,i); + + p = -1; + + if(s->picnum == RPG && sector[s->sectnum].lotag == 2) + { + k = s->xvel>>1; + ll = s->zvel>>1; + } + else + { + k = s->xvel; + ll = s->zvel; + } + + dax = s->x; day = s->y; daz = s->z; + + getglobalz(i); + qq = CLIPMASK1; + + switch(dynamictostatic[s->picnum]) + { + case RPG__STATIC: + if(hittype[i].picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i,SMALLSMOKE); + sprite[j].z += (1<<8); + } + break; + } + + j = movesprite(i, + (k*(sintable[(s->ang+512)&2047]))>>14, + (k*(sintable[s->ang&2047]))>>14,ll,qq); + + if(s->picnum == RPG && s->yvel >= 0) + if( FindDistance2D(s->x-sprite[s->yvel].x,s->y-sprite[s->yvel].y) < 256 ) + j = 49152|s->yvel; + + if(s->sectnum < 0) { KILLIT(i); } + + if( (j&49152) != 49152) + if(s->picnum != FREEZEBLAST) + { + if(s->z < hittype[i].ceilingz) + { + j = 16384|(s->sectnum); + s->zvel = -1; + } + else + if( ( s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1 ) || + ( s->z > hittype[i].floorz+(16<<8) && sector[s->sectnum].lotag == 1 ) ) + { + j = 16384|(s->sectnum); + if(sector[s->sectnum].lotag != 1) + s->zvel = 1; + } + } + + if(s->picnum == FIRELASER) + { + for(k=-3;k<2;k++) + { + x = EGS(s->sectnum, + s->x+((k*sintable[(s->ang+512)&2047])>>9), + s->y+((k*sintable[s->ang&2047])>>9), + s->z+((k*ksgn(s->zvel))*klabs(s->zvel/24)),FIRELASER,-40+(k<<2), + s->xrepeat,s->yrepeat,0,0,0,s->owner,5); + + sprite[x].cstat = 128; + sprite[x].pal = s->pal; + } + } + else if(s->picnum == SPIT) if(s->zvel < 6144) + s->zvel += gc-112; + + if( j != 0 ) + { + if(s->picnum == COOLEXPLOSION1) + { + if( (j&49152) == 49152 && sprite[j&(MAXSPRITES-1)].picnum != APLAYER) + goto BOLT; + s->xvel = 0; + s->zvel = 0; + } + + if( (j&49152) == 49152 ) + { + j &= (MAXSPRITES-1); + + if(s->picnum == FREEZEBLAST && sprite[j].pal == 1 ) + if( badguy(&sprite[j]) || sprite[j].picnum == APLAYER ) + { + j = spawn(i,TRANSPORTERSTAR); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + + KILLIT(i); + } + + checkhitsprite(j,i); + + if(sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + spritesound(PISTOL_BODYHIT,j); + + if(s->picnum == SPIT) + { + ps[p].horiz += 32; + ps[p].return_to_center = 8; + + if(ps[p].loogcnt == 0) + { + if(!isspritemakingsound(ps[p].i, DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,ps[p].i); + + j = 3+(TRAND&3); + ps[p].numloogs = j; + ps[p].loogcnt = 24*4; + for(x=0;x < j;x++) + { + ps[p].loogiex[x] = TRAND%xdim; + ps[p].loogiey[x] = TRAND%ydim; + } + } + } + } + } + else if( (j&49152) == 32768 ) + { + j &= (MAXWALLS-1); + + if(s->picnum != RPG && s->picnum != FREEZEBLAST && s->picnum != SPIT && ( wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR ) ) + { + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + s->owner = i; + spawn(i,TRANSPORTERSTAR); + goto BOLT; + } + else + { + setsprite(i,dax,day,daz); + checkhitwall(i,j,s->x,s->y,s->z,s->picnum); + + if(s->picnum == FREEZEBLAST) + { + if( wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR ) + { + s->extra >>= 1; + s->yvel--; + } + + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + goto BOLT; + } + } + } + else if( (j&49152) == 16384) + { + setsprite(i,dax,day,daz); + + if(s->zvel < 0) + { + if( sector[s->sectnum].ceilingstat&1 ) + if(sector[s->sectnum].ceilingpal == 0) + KILLIT(i); + + checkhitceiling(s->sectnum); + } + + if(s->picnum == FREEZEBLAST) + { + bounce(i); + ssp(i,qq); + s->extra >>= 1; + if(s->xrepeat > 8) + s->xrepeat -= 2; + if(s->yrepeat > 8) + s->yrepeat -= 2; + s->yvel--; + goto BOLT; + } + } + + if(s->picnum != SPIT) + { + if(s->picnum == RPG) + { + k = spawn(i,EXPLOSION2); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if(s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if( (j&49152) == 16384) + { + if( s->zvel > 0) + spawn(i,EXPLOSION2BOT); + else { sprite[k].cstat |= 8; sprite[k].z += (48<<8); } + } + } + else if(s->picnum == SHRINKSPARK) + { + spawn(i,SHRINKEREXPLOSION); + spritesound(SHRINKER_HIT,i); + hitradius(i,shrinkerblastradius,0,0,0,0); + } + else if( s->picnum != COOLEXPLOSION1 && s->picnum != FREEZEBLAST && s->picnum != FIRELASER) + { + k = spawn(i,EXPLOSION2); + sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat>>1; + if( (j&49152) == 16384) + { + if( s->zvel < 0) + { sprite[k].cstat |= 8; sprite[k].z += (72<<8); } + } + } + if( s->picnum == RPG ) + { + spritesound(RPG_EXPLODE,i); + + if(s->xrepeat >= 10) + { + x = s->extra; + hitradius( i,rpgblastradius, x>>2,x>>1,x-(x>>2),x); + } + else + { + x = s->extra+(global_random&3); + hitradius( i,(rpgblastradius>>1),x>>2,x>>1,x-(x>>2),x); + } + } + } + if(s->picnum != COOLEXPLOSION1) KILLIT(i); + } + if(s->picnum == COOLEXPLOSION1) + { + s->shade++; + if(s->shade >= 40) KILLIT(i); + } + else if(s->picnum == RPG && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) + spawn(i,WATERBUBBLE); + + goto BOLT; + + + case SHOTSPARK1__STATIC: + p = findplayer(s,&x); + execute(i,p,x); + goto BOLT; + } + } +BOLT: + i = nexti; + } +} + +void movetransports(void) +{ + char warpspriteto; + short i, j, k, l, p, sect, sectlotag, nexti, nextj, nextk; + long ll,onfloorz,q; + + i = headspritestat[9]; //Transporters + + while(i >= 0) + { + sect = SECT; + sectlotag = sector[sect].lotag; + + nexti = nextspritestat[i]; + + if(OW == i) + { + i = nexti; + continue; + } + + onfloorz = T5; + + if(T1 > 0) T1--; + + j = headspritesect[sect]; + while(j >= 0) + { + nextj = nextspritesect[j]; + + switch(sprite[j].statnum) + { + case 10: // Player + + if( sprite[j].owner != -1 ) + { + p = sprite[j].yvel; + + ps[p].on_warping_sector = 1; + + if( ps[p].transporter_hold == 0 && ps[p].jumping_counter == 0 ) + { + if(ps[p].on_ground && sectlotag == 0 && onfloorz && ps[p].jetpack_on == 0 ) + { + if(sprite[i].pal == 0) + { + spawn(i,TRANSPORTERBEAM); + spritesound(TELEPORTER,i); + } + + for(k=connecthead;k>=0;k=connectpoint2[k]) + if(ps[k].cursectnum == sprite[OW].sectnum) + { + ps[k].frag_ps = p; + sprite[ps[k].i].extra = 0; + } + + ps[p].ang = sprite[OW].ang; + + if(sprite[OW].owner != OW) + { + T1 = 13; + hittype[OW].temp_data[0] = 13; + ps[p].transporter_hold = 13; + } + + ps[p].bobposx = ps[p].oposx = ps[p].posx = sprite[OW].x; + ps[p].bobposy = ps[p].oposy = ps[p].posy = sprite[OW].y; + ps[p].oposz = ps[p].posz = sprite[OW].z-PHEIGHT; + + changespritesect(j,sprite[OW].sectnum); + ps[p].cursectnum = sprite[j].sectnum; + + if(sprite[i].pal == 0) + { + k = spawn(OW,TRANSPORTERBEAM); + spritesound(TELEPORTER,k); + } + + break; + } + } + else if( !(sectlotag == 1 && ps[p].on_ground == 1) ) break; + + if(onfloorz == 0 && klabs(SZ-ps[p].posz) < 6144 ) + if( (ps[p].jetpack_on == 0 ) || (ps[p].jetpack_on && (sync[p].bits&1) ) || + (ps[p].jetpack_on && (sync[p].bits&2) ) ) + { + ps[p].oposx = ps[p].posx += sprite[OW].x-SX; + ps[p].oposy = ps[p].posy += sprite[OW].y-SY; + + if( ps[p].jetpack_on && ( (sync[p].bits&1) || ps[p].jetpack_on < 11 ) ) + ps[p].posz = sprite[OW].z-6144; + else ps[p].posz = sprite[OW].z+6144; + ps[p].oposz = ps[p].posz; + + hittype[ps[p].i].bposx = ps[p].posx; + hittype[ps[p].i].bposy = ps[p].posy; + hittype[ps[p].i].bposz = ps[p].posz; + + changespritesect(j,sprite[OW].sectnum); + ps[p].cursectnum = sprite[OW].sectnum; + + break; + } + + k = 0; + + if( onfloorz && sectlotag == 1 && ps[p].on_ground && ps[p].posz > (sector[sect].floorz-1080) && ( (sync[p].bits&2) || ps[p].poszv > 2048 ) ) + // if( onfloorz && sectlotag == 1 && ps[p].posz > (sector[sect].floorz-(6<<8)) ) + { + k = 1; + if(screenpeek == p) + { + FX_StopAllSounds(); + clearsoundlocks(); + } + if(sprite[ps[p].i].extra > 0) + spritesound(DUKE_UNDERWATER,j); + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].ceilingz; + + ps[p].posxv = 4096-(TRAND&8192); + ps[p].posyv = 4096-(TRAND&8192); + // ps[p].poszv += 1080; + } + + if( onfloorz && sectlotag == 2 && ps[p].posz < (sector[sect].ceilingz+1080) && ps[p].poszv == 0) + { + k = 1; + // if( sprite[j].extra <= 0) break; + if(screenpeek == p) + { + FX_StopAllSounds(); + clearsoundlocks(); + } + spritesound(DUKE_GASP,j); + + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].floorz; + + ps[p].jumping_toggle = 1; + ps[p].jumping_counter = 0; + ps[p].poszv += 1024; + } + + if(k == 1) + { + ps[p].oposx = ps[p].posx += sprite[OW].x-SX; + ps[p].oposy = ps[p].posy += sprite[OW].y-SY; + + if(sprite[OW].owner != OW) + ps[p].transporter_hold = -2; + ps[p].cursectnum = sprite[OW].sectnum; + + changespritesect(j,sprite[OW].sectnum); + setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz+PHEIGHT); + + setpal(&ps[p]); + + if( (TRAND&255) < 32 ) + spawn(j,WATERSPLASH2); + + if(sectlotag == 1) + for(l = 0;l < 9;l++) + { + q = spawn(ps[p].i,WATERBUBBLE); + sprite[q].z += TRAND&16383; + } + } + } + break; + + case 1: + if ( (sprite[j].picnum == SHARK) + || (sprite[j].picnum == COMMANDER) + || (sprite[j].picnum == OCTABRAIN) + || ((sprite[j].picnum >= GREENSLIME) && (sprite[j].picnum >= GREENSLIME+7)) + ) { + if(sprite[j].extra > 0) + goto JBOLT; + } + case 4: + case 5: + case 12: + case 13: + + ll = klabs(sprite[j].zvel); + + { + warpspriteto = 0; + if( ll && sectlotag == 2 && sprite[j].z < (sector[sect].ceilingz+ll) ) + warpspriteto = 1; + + if( ll && sectlotag == 1 && sprite[j].z > (sector[sect].floorz-ll) ) + warpspriteto = 1; + + if( sectlotag == 0 && ( onfloorz || klabs(sprite[j].z-SZ) < 4096) ) + { + if( sprite[OW].owner != OW && onfloorz && T1 > 0 && sprite[j].statnum != 5 ) + { + T1++; + goto BOLT; + } + warpspriteto = 1; + } + + if (warpspriteto && checkspriteflags(j,SPRITE_FLAG_DECAL)) goto JBOLT; + + if( warpspriteto ) switch(dynamictostatic[sprite[j].picnum]) + { + case TRANSPORTERSTAR__STATIC: + case TRANSPORTERBEAM__STATIC: + case TRIPBOMB__STATIC: + case BULLETHOLE__STATIC: + case WATERSPLASH2__STATIC: + case BURNING__STATIC: + case BURNING2__STATIC: + case FIRE__STATIC: + case FIRE2__STATIC: + case TOILETWATER__STATIC: + case LASERLINE__STATIC: + goto JBOLT; + case PLAYERONWATER__STATIC: + if(sectlotag == 2) + { + sprite[j].cstat &= 32767; + break; + } + default: + if(sprite[j].statnum == 5 && !(sectlotag == 1 || sectlotag == 2) ) + break; + + case WATERBUBBLE__STATIC: + // if( rnd(192) && sprite[j].picnum == WATERBUBBLE) + // break; + + if(sectlotag > 0) + { + k = spawn(j,WATERSPLASH2); + if( sectlotag == 1 && sprite[j].statnum == 4 ) + { + sprite[k].xvel = sprite[j].xvel>>1; + sprite[k].ang = sprite[j].ang; + ssp(k,CLIPMASK0); + } + } + + switch(sectlotag) + { + case 0: + if(onfloorz) + { + if( sprite[j].statnum == 4 || ( checkcursectnums(sect) == -1 && checkcursectnums(sprite[OW].sectnum) == -1 ) ) + { + sprite[j].x += (sprite[OW].x-SX); + sprite[j].y += (sprite[OW].y-SY); + sprite[j].z -= SZ - sector[sprite[OW].sectnum].floorz; + sprite[j].ang = sprite[OW].ang; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + if(sprite[i].pal == 0) + { + k = spawn(i,TRANSPORTERBEAM); + spritesound(TELEPORTER,k); + + k = spawn(OW,TRANSPORTERBEAM); + spritesound(TELEPORTER,k); + } + + if( sprite[OW].owner != OW ) + { + T1 = 13; + hittype[OW].temp_data[0] = 13; + } + + changespritesect(j,sprite[OW].sectnum); + } + } + else + { + sprite[j].x += (sprite[OW].x-SX); + sprite[j].y += (sprite[OW].y-SY); + sprite[j].z = sprite[OW].z+4096; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j,sprite[OW].sectnum); + } + break; + case 1: + sprite[j].x += (sprite[OW].x-SX); + sprite[j].y += (sprite[OW].y-SY); + sprite[j].z = sector[sprite[OW].sectnum].ceilingz+ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j,sprite[OW].sectnum); + + break; + case 2: + sprite[j].x += (sprite[OW].x-SX); + sprite[j].y += (sprite[OW].y-SY); + sprite[j].z = sector[sprite[OW].sectnum].floorz-ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j,sprite[OW].sectnum); + + break; + } + + break; + } + } + break; + + } +JBOLT: + j = nextj; + } +BOLT: + i = nexti; + } +} + +void moveactors(void) +{ + long x, m, l, *t; + short a, i, j, nexti, nextj, sect, p; + spritetype *s; + unsigned short k; + int switchpicnum; + + i = headspritestat[1]; + while(i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + + sect = s->sectnum; + + if( s->xrepeat == 0 || sect < 0 || sect >= MAXSECTORS) + KILLIT(i); + + t = &hittype[i].temp_data[0]; + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + switchpicnum=s->picnum; + if ((s->picnum > GREENSLIME)&&(s->picnum <= GREENSLIME+7)) { + switchpicnum = GREENSLIME; + } + switch(dynamictostatic[switchpicnum]) + { + case DUCK__STATIC: + case TARGET__STATIC: + if(s->cstat&32) + { + t[0]++; + if(t[0] > 60) + { + t[0] = 0; + s->cstat = 128+257+16; + s->extra = 1; + } + } + else + { + j = ifhitbyweapon(i); + if( j >= 0 ) + { + s->cstat = 32+128; + k = 1; + + j = headspritestat[1]; + while(j >= 0) + { + if( sprite[j].lotag == s->lotag && + sprite[j].picnum == s->picnum ) + { + if( ( sprite[j].hitag && !(sprite[j].cstat&32) ) || + ( !sprite[j].hitag && (sprite[j].cstat&32) ) + ) + { + k = 0; + break; + } + } + + j = nextspritestat[j]; + } + + if(k == 1) + { + operateactivators(s->lotag,-1); + operateforcefields(i,s->lotag); + operatemasterswitches(s->lotag); + } + } + } + goto BOLT; + + case RESPAWNMARKERRED__STATIC: + case RESPAWNMARKERYELLOW__STATIC: + case RESPAWNMARKERGREEN__STATIC: + T1++; + if(T1 > respawnitemtime) + { + KILLIT(i); + } + if( T1 >= (respawnitemtime>>1) && T1 < ((respawnitemtime>>1)+(respawnitemtime>>2)) ) + PN = RESPAWNMARKERYELLOW; + else if( T1 > ((respawnitemtime>>1)+(respawnitemtime>>2)) ) + PN = RESPAWNMARKERGREEN; + makeitfall(i); + break; + + case HELECOPT__STATIC: + case DUKECAR__STATIC: + + s->z += s->zvel; + t[0]++; + + if(t[0] == 4) spritesound(WAR_AMBIENCE2,i); + + if( t[0] > (26*8) ) + { + sound(RPG_EXPLODE); + for(j=0;j<32;j++) RANDOMSCRAP; + earthquaketime = 16; + KILLIT(i); + } + else if((t[0]&3) == 0) + spawn(i,EXPLOSION2); + ssp(i,CLIPMASK0); + break; + case RAT__STATIC: + makeitfall(i); + IFMOVING + { + if( (TRAND&255) < 3 ) spritesound(RATTY,i); + s->ang += (TRAND&31)-15+(sintable[(t[0]<<8)&2047]>>11); + } + else + { + T1++; + if(T1 > 1) { KILLIT(i); } + else s->ang = (TRAND&2047); + } + if(s->xvel < 128) + s->xvel+=2; + s->ang += (TRAND&3)-6; + break; + case QUEBALL__STATIC: + case STRIPEBALL__STATIC: + if(s->xvel) + { + j = headspritestat[0]; + while(j >= 0) + { + nextj = nextspritestat[j]; + if( sprite[j].picnum == POCKET && ldist(&sprite[j],s) < 52 ) KILLIT(i); + j = nextj; + } + + j = clipmove(&s->x,&s->y,&s->z,&s->sectnum, + (((s->xvel*(sintable[(s->ang+512)&2047]))>>14)*TICSPERFRAME)<<11, + (((s->xvel*(sintable[s->ang&2047]))>>14)*TICSPERFRAME)<<11, + 24L,(4<<8),(4<<8),CLIPMASK1); + + if(j&49152) + { + if( (j&49152) == 32768 ) + { + j &= (MAXWALLS-1); + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + s->ang = ((k<<1) - s->ang)&2047; + } + else if( (j&49152) == 49152 ) + { + j &= (MAXSPRITES-1); + checkhitsprite(i,j); + } + } + s->xvel --; + if(s->xvel < 0) s->xvel = 0; + if( s->picnum == STRIPEBALL ) + { + s->cstat = 257; + s->cstat |= 4&s->xvel; + s->cstat |= 8&s->xvel; + } + } + else + { + p = findplayer(s,&x); + + if( x < 1596) + { + + // if(s->pal == 12) + { + j = getincangle(ps[p].ang,getangle(s->x-ps[p].posx,s->y-ps[p].posy)); + if( j > -64 && j < 64 && (sync[p].bits&(1<<29)) ) + if(ps[p].toggle_key_flag == 1) + { + a = headspritestat[1]; + while(a >= 0) + { + if(sprite[a].picnum == QUEBALL || sprite[a].picnum == STRIPEBALL) + { + j = getincangle(ps[p].ang,getangle(sprite[a].x-ps[p].posx,sprite[a].y-ps[p].posy)); + if( j > -64 && j < 64 ) + { + findplayer(&sprite[a],&l); + if(x > l) break; + } + } + a = nextspritestat[a]; + } + if(a == -1) + { + if(s->pal == 12) + s->xvel = 164; + else s->xvel = 140; + s->ang = ps[p].ang; + ps[p].toggle_key_flag = 2; + } + } + } + } + if( x < 512 && s->sectnum == ps[p].cursectnum ) + { + s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy); + s->xvel = 48; + } + } + + break; + case FORCESPHERE__STATIC: + + if(s->yvel == 0) + { + s->yvel = 1; + + for(l=512;l<(2048-512);l+= 128) + for(j=0;j<2048;j += 128) + { + k = spawn(i,FORCESPHERE); + sprite[k].cstat = 257+128; + sprite[k].clipdist = 64; + sprite[k].ang = j; + sprite[k].zvel = sintable[l&2047]>>5; + sprite[k].xvel = sintable[(l+512)&2047]>>9; + sprite[k].owner = i; + } + } + + if(t[3] > 0) + { + if(s->zvel < 6144) + s->zvel += 192; + s->z += s->zvel; + if(s->z > sector[sect].floorz) + s->z = sector[sect].floorz; + t[3]--; + if(t[3] == 0) + KILLIT(i); + } + else if(t[2] > 10) + { + j = headspritestat[5]; + while(j >= 0) + { + if(sprite[j].owner == i && sprite[j].picnum == FORCESPHERE) + hittype[j].temp_data[1] = 1+(TRAND&63); + j = nextspritestat[j]; + } + t[3] = 64; + } + + goto BOLT; + + case RECON__STATIC: + + getglobalz(i); + + if (sector[s->sectnum].ceilingstat&1) + s->shade += (sector[s->sectnum].ceilingshade-s->shade)>>1; + else s->shade += (sector[s->sectnum].floorshade-s->shade)>>1; + + if( s->z < sector[sect].ceilingz+(32<<8) ) + s->z = sector[sect].ceilingz+(32<<8); + + if( ud.multimode < 2 ) + { + if( actor_tog == 1) + { + s->cstat = (short)32768; + goto BOLT; + } + else if(actor_tog == 2) s->cstat = 257; + } + IFHIT + { + if( s->extra < 0 && t[0] != -1 ) + { + t[0] = -1; + s->extra = 0; + } + spritesound(RECO_PAIN,i); + RANDOMSCRAP; + } + + if(t[0] == -1) + { + s->z += 1024; + t[2]++; + if( (t[2]&3) == 0) spawn(i,EXPLOSION2); + getglobalz(i); + s->ang += 96; + s->xvel = 128; + j = ssp(i,CLIPMASK0); + if(j != 1 || s->z > hittype[i].floorz) + { + for(l=0;l<16;l++) + RANDOMSCRAP; + spritesound(LASERTRIP_EXPLODE,i); + spawn(i,PIGCOP); + ps[myconnectindex].actors_killed++; + KILLIT(i); + } + goto BOLT; + } + else + { + if( s->z > hittype[i].floorz-(48<<8) ) + s->z = hittype[i].floorz-(48<<8); + } + + p = findplayer(s,&x); + j = s->owner; + + // 3 = findplayerz, 4 = shoot + + if( t[0] >= 4 ) + { + t[2]++; + if( (t[2]&15) == 0 ) + { + a = s->ang; + s->ang = hittype[i].tempang; + spritesound(RECO_ATTACK,i); + shoot(i,FIRELASER); + s->ang = a; + } + if( t[2] > (26*3) || !cansee(s->x,s->y,s->z-(16<<8),s->sectnum, ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum ) ) + { + t[0] = 0; + t[2] = 0; + } + else hittype[i].tempang += + getincangle(hittype[i].tempang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))/3; + } + else if(t[0] == 2 || t[0] == 3) + { + t[3] = 0; + if(s->xvel > 0) s->xvel -= 16; + else s->xvel = 0; + + if(t[0] == 2) + { + l = ps[p].posz-s->z; + if( klabs(l) < (48<<8) ) t[0] = 3; + else s->z += ksgn(ps[p].posz-s->z)<<10; + } + else + { + t[2]++; + if( t[2] > (26*3) || !cansee(s->x,s->y,s->z-(16<<8),s->sectnum, ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum ) ) + { + t[0] = 1; + t[2] = 0; + } + else if( (t[2]&15) == 0 ) + { + spritesound(RECO_ATTACK,i); + shoot(i,FIRELASER); + } + } + s->ang += getincangle(s->ang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>2; + } + + if( t[0] != 2 && t[0] != 3 ) + { + l = ldist(&sprite[j],s); + if(l <= 1524) + { + a = s->ang; + s->xvel >>= 1; + } + else a = getangle(sprite[j].x-s->x,sprite[j].y-s->y); + + if(t[0] == 1 || t[0] == 4) // Found a locator and going with it + { + l = dist(&sprite[j],s); + + if( l <= 1524 ) { if(t[0] == 1) t[0] = 0; else t[0] = 5; } + else + { + // Control speed here + if(l > 1524) { if( s->xvel < 256 ) s->xvel += 32; } + else + { + if(s->xvel > 0) s->xvel -= 16; + else s->xvel = 0; + } + } + + if(t[0] < 2) t[2]++; + + if( x < 6144 && t[0] < 2 && t[2] > (26*4) ) + { + t[0] = 2+(TRAND&2); + t[2] = 0; + hittype[i].tempang = s->ang; + } + } + + if(t[0] == 0 || t[0] == 5) + { + if(t[0] == 0) + t[0] = 1; + else t[0] = 4; + j = s->owner = LocateTheLocator(s->hitag,-1); + if(j == -1) + { + s->hitag = j = hittype[i].temp_data[5]; + s->owner = LocateTheLocator(j,-1); + j = s->owner; + if(j == -1) KILLIT(i); + } + else s->hitag++; + } + + t[3] = getincangle(s->ang,a); + s->ang += t[3]>>3; + + if(s->z < sprite[j].z) + s->z += 1024; + else s->z -= 1024; + } + + if(!isspritemakingsound(i,RECO_ROAM)) + spritesound(RECO_ROAM,i); + + ssp(i,CLIPMASK0); + + goto BOLT; + + case OOZ__STATIC: + case OOZ2__STATIC: + + getglobalz(i); + + j = (hittype[i].floorz-hittype[i].ceilingz)>>9; + if(j > 255) j = 255; + + x = 25-(j>>1); + if(x < 8) x = 8; + else if(x > 48) x = 48; + + s->yrepeat = j; + s->xrepeat = x; + s->z = hittype[i].floorz; + + goto BOLT; + + case GREENSLIME__STATIC: + // case GREENSLIME+1: + // case GREENSLIME+2: + // case GREENSLIME+3: + // case GREENSLIME+4: + // case GREENSLIME+5: + // case GREENSLIME+6: + // case GREENSLIME+7: + + // #ifndef VOLUMEONE + if( ud.multimode < 2 ) + { + if( actor_tog == 1) + { + s->cstat = (short)32768; + goto BOLT; + } + else if(actor_tog == 2) s->cstat = 257; + } + // #endif + + t[1]+=128; + + if(sector[sect].floorstat&1) + KILLIT(i); + + p = findplayer(s,&x); + + if(x > 20480) + { + hittype[i].timetosleep++; + if( hittype[i].timetosleep > SLEEPTIME ) + { + hittype[i].timetosleep = 0; + changespritestat(i,2); + goto BOLT; + } + } + + if(t[0] == -5) // FROZEN + { + t[3]++; + if(t[3] > 280) + { + s->pal = 0; + t[0] = 0; + goto BOLT; + } + makeitfall(i); + s->cstat = 257; + s->picnum = GREENSLIME+2; + s->extra = 1; + s->pal = 1; + IFHIT + { + if(j == FREEZEBLAST) goto BOLT; + for(j=16; j >= 0 ;j--) + { + k = EGS(SECT,SX,SY,SZ,GLASSPIECES+(j%3),-32,36,36,TRAND&2047,32+(TRAND&63),1024-(TRAND&1023),i,5); + sprite[k].pal = 1; + } + spritesound(GLASS_BREAKING,i); + KILLIT(i); + } + else if(x < 1024 && ps[p].quick_kick == 0) + { + j = getincangle(ps[p].ang,getangle(SX-ps[p].posx,SY-ps[p].posy)); + if( j > -128 && j < 128 ) + ps[p].quick_kick = 14; + } + + goto BOLT; + } + + if(x < 1596) + s->cstat = 0; + else s->cstat = 257; + + if(t[0] == -4) //On the player + { + if( sprite[ps[p].i].extra < 1 ) + { + t[0] = 0; + goto BOLT; + } + + setsprite(i,s->x,s->y,s->z); + + s->ang = ps[p].ang; + + if( ( (sync[p].bits&4) || (ps[p].quick_kick > 0) ) && sprite[ps[p].i].extra > 0 ) + if( ps[p].quick_kick > 0 || ( ps[p].curr_weapon != HANDREMOTE_WEAPON && ps[p].curr_weapon != HANDBOMB_WEAPON && ps[p].curr_weapon != TRIPBOMB_WEAPON && ps[p].ammo_amount[ps[p].curr_weapon] >= 0) ) + { + for(x=0;x<8;x++) + { + j = EGS(sect,s->x,s->y,s->z-(8<<8),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(s->zvel>>2),i,5); + sprite[j].pal = 6; + } + + spritesound(SLIM_DYING,i); + spritesound(SQUISHED,i); + if( (TRAND&255) < 32 ) + { + j = spawn(i,BLOODPOOL); + sprite[j].pal = 0; + } + ps[p].actors_killed ++; + t[0] = -3; + if(ps[p].somethingonplayer == i) + ps[p].somethingonplayer = -1; + KILLIT(i); + } + + s->z = ps[p].posz+ps[p].pyoff-t[2]+(8<<8); + + s->z += (100-ps[p].horiz)<<4; + + if( t[2] > 512) + t[2] -= 128; + + if( t[2] < 348) + t[2] += 128; + + if(ps[p].newowner >= 0) + { + ps[p].newowner = -1; + ps[p].posx = ps[p].oposx; + ps[p].posy = ps[p].oposy; + ps[p].posz = ps[p].oposz; + ps[p].ang = ps[p].oang; + + updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum); + setpal(&ps[p]); + + j = headspritestat[1]; + while(j >= 0) + { + if(sprite[j].picnum==CAMERA1) sprite[j].yvel = 0; + j = nextspritestat[j]; + } + } + + if(t[3]>0) + { + short frames[] = {5,5,6,6,7,7,6,5}; + + s->picnum = GREENSLIME+frames[t[3]]; + + if( t[3] == 5 ) + { + sprite[ps[p].i].extra += -(5+(TRAND&3)); + spritesound(SLIM_ATTACK,i); + } + + if(t[3] < 7) t[3]++; + else t[3] = 0; + + } + else + { + s->picnum = GREENSLIME+5; + if(rnd(32)) + t[3] = 1; + } + + s->xrepeat = 20+(sintable[t[1]&2047]>>13); + s->yrepeat = 15+(sintable[t[1]&2047]>>13); + + s->x = ps[p].posx + (sintable[(ps[p].ang+512)&2047]>>7); + s->y = ps[p].posy + (sintable[ps[p].ang&2047]>>7); + + goto BOLT; + } + + else if(s->xvel < 64 && x < 768) + { + if(ps[p].somethingonplayer == -1) + { + ps[p].somethingonplayer = i; + if(t[0] == 3 || t[0] == 2) //Falling downward + t[2] = (12<<8); + else t[2] = -(13<<8); //Climbing up duke + t[0] = -4; + } + } + + IFHIT + { + spritesound(SLIM_DYING,i); + + ps[p].actors_killed ++; + if(ps[p].somethingonplayer == i) + ps[p].somethingonplayer = -1; + + if(j == FREEZEBLAST) + { + spritesound(SOMETHINGFROZE,i); t[0] = -5 ; t[3] = 0 ; + goto BOLT; + } + + if( (TRAND&255) < 32 ) + { + j = spawn(i,BLOODPOOL); + sprite[j].pal = 0; + } + + for(x=0;x<8;x++) + { + j = EGS(sect,s->x,s->y,s->z-(8<<8),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(s->zvel>>2),i,5); + sprite[j].pal = 6; + } + t[0] = -3; + KILLIT(i); + } + // All weap + if(t[0] == -1) //Shrinking down + { + makeitfall(i); + + s->cstat &= 65535-8; + s->picnum = GREENSLIME+4; + + // if(s->yrepeat > 62) + // guts(s,JIBS6,5,myconnectindex); + + if(s->xrepeat > 32) s->xrepeat -= TRAND&7; + if(s->yrepeat > 16) s->yrepeat -= TRAND&7; + else + { + s->xrepeat = 40; + s->yrepeat = 16; + t[5] = -1; + t[0] = 0; + } + + goto BOLT; + } + else if(t[0] != -2) getglobalz(i); + + if(t[0] == -2) //On top of somebody + { + makeitfall(i); + sprite[t[5]].xvel = 0; + + l = sprite[t[5]].ang; + + s->z = sprite[t[5]].z; + s->x = sprite[t[5]].x+(sintable[(l+512)&2047]>>11); + s->y = sprite[t[5]].y+(sintable[l&2047]>>11); + + s->picnum = GREENSLIME+2+(global_random&1); + + if(s->yrepeat < 64) s->yrepeat+=2; + else + { + if(s->xrepeat < 32) s->xrepeat += 4; + else + { + t[0] = -1; + x = ldist(s,&sprite[t[5]]); + if(x < 768) { + sprite[t[5]].xrepeat = 0; + + // JBF 20041129: a slimer eating another enemy really ought + // to decrease the maximum kill count by one. + if (sprite[t[5]].extra > 0) ps[myconnectindex].max_actors_killed--; + } + } + } + + goto BOLT; + } + + //Check randomly to see of there is an actor near + if(rnd(32)) + { + j = headspritesect[sect]; + while(j>=0) + { + switch(dynamictostatic[sprite[j].picnum]) + { + case LIZTROOP__STATIC: + case LIZMAN__STATIC: + case PIGCOP__STATIC: + case NEWBEAST__STATIC: + if( ldist(s,&sprite[j]) < 768 && (klabs(s->z-sprite[j].z)<8192) ) //Gulp them + { + t[5] = j; + t[0] = -2; + t[1] = 0; + goto BOLT; + } + } + + j = nextspritesect[j]; + } + } + + //Moving on the ground or ceiling + + if(t[0] == 0 || t[0] == 2) + { + s->picnum = GREENSLIME; + + if( (TRAND&511) == 0 ) + spritesound(SLIM_ROAM,i); + + if(t[0]==2) + { + s->zvel = 0; + s->cstat &= (65535-8); + + if( (sector[sect].ceilingstat&1) || (hittype[i].ceilingz+6144) < s->z) + { + s->z += 2048; + t[0] = 3; + goto BOLT; + } + } + else + { + s->cstat |= 8; + makeitfall(i); + } + + if( everyothertime&1 ) ssp(i,CLIPMASK0); + + if(s->xvel > 96) + { + s->xvel -= 2; + goto BOLT; + } + else + { + if(s->xvel < 32) s->xvel += 4; + s->xvel = 64 - (sintable[(t[1]+512)&2047]>>9); + + s->ang += getincangle(s->ang, + getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>3; + // TJR + } + + s->xrepeat = 36 + (sintable[(t[1]+512)&2047]>>11); + s->yrepeat = 16 + (sintable[t[1]&2047]>>13); + + if(rnd(4) && (sector[sect].ceilingstat&1) == 0 && + klabs(hittype[i].floorz-hittype[i].ceilingz) + < (192<<8) ) + { + s->zvel = 0; + t[0]++; + } + + } + + if(t[0]==1) + { + s->picnum = GREENSLIME; + if(s->yrepeat < 40) s->yrepeat+=8; + if(s->xrepeat > 8) s->xrepeat-=4; + if(s->zvel > -(2048+1024)) + s->zvel -= 348; + s->z += s->zvel; + if(s->z < hittype[i].ceilingz+4096) + { + s->z = hittype[i].ceilingz+4096; + s->xvel = 0; + t[0] = 2; + } + } + + if(t[0]==3) + { + s->picnum = GREENSLIME+1; + + makeitfall(i); + + if(s->z > hittype[i].floorz-(8<<8)) + { + s->yrepeat-=4; + s->xrepeat+=2; + } + else + { + if(s->yrepeat < (40-4)) s->yrepeat+=8; + if(s->xrepeat > 8) s->xrepeat-=4; + } + + if(s->z > hittype[i].floorz-2048) + { + s->z = hittype[i].floorz-2048; + t[0] = 0; + s->xvel = 0; + } + } + goto BOLT; + + case BOUNCEMINE__STATIC: + case MORTER__STATIC: + j = spawn(i, (PLUTOPAK ? FRAMEEFFECT1 : FRAMEEFFECT1_13) ); + hittype[j].temp_data[0] = 3; + + case HEAVYHBOMB__STATIC: + + if( (s->cstat&32768) ) + { + t[2]--; + if(t[2] <= 0) + { + spritesound(TELEPORTER,i); + spawn(i,TRANSPORTERSTAR); + s->cstat = 257; + } + goto BOLT; + } + + p = findplayer(s,&x); + + if( x < 1220 ) s->cstat &= ~257; + else s->cstat |= 257; + + if(t[3] == 0 ) + { + j = ifhitbyweapon(i); + if(j >= 0) + { + t[3] = 1; + t[4] = 0; + l = 0; + s->xvel = 0; + goto DETONATEB; + } + } + + if( s->picnum != BOUNCEMINE ) + { + makeitfall(i); + + if( sector[sect].lotag != 1 && s->z >= hittype[i].floorz-(FOURSLEIGHT) && s->yvel < 3 ) + { + if( s->yvel > 0 || (s->yvel == 0 && hittype[i].floorz == sector[sect].floorz )) + spritesound(PIPEBOMB_BOUNCE,i); + s->zvel = -((4-s->yvel)<<8); + if(sector[s->sectnum].lotag== 2) + s->zvel >>= 2; + s->yvel++; + } + if( s->z < hittype[i].ceilingz ) // && sector[sect].lotag != 2 ) + { + s->z = hittype[i].ceilingz+(3<<8); + s->zvel = 0; + } + } + + j = movesprite(i, + (s->xvel*(sintable[(s->ang+512)&2047]))>>14, + (s->xvel*(sintable[s->ang&2047]))>>14, + s->zvel,CLIPMASK0); + + if(sector[SECT].lotag == 1 && s->zvel == 0) + { + s->z += (32<<8); + if(t[5] == 0) + { + t[5] = 1; + spawn(i,WATERSPLASH2); + } + } + else t[5] = 0; + + if(t[3] == 0 && ( s->picnum == BOUNCEMINE || s->picnum == MORTER ) && (j || x < 844) ) + { + t[3] = 1; + t[4] = 0; + l = 0; + s->xvel = 0; + goto DETONATEB; + } + + if(sprite[s->owner].picnum == APLAYER) + l = sprite[s->owner].yvel; + else l = -1; + + if(s->xvel > 0) + { + s->xvel -= 5; + if(sector[sect].lotag == 2) + s->xvel -= 10; + + if(s->xvel < 0) + s->xvel = 0; + if(s->xvel&8) s->cstat ^= 4; + } + + if( (j&49152) == 32768 ) + { + j &= (MAXWALLS-1); + + checkhitwall(i,j,s->x,s->y,s->z,s->picnum); + + k = getangle( + wall[wall[j].point2].x-wall[j].x, + wall[wall[j].point2].y-wall[j].y); + + s->ang = ((k<<1) - s->ang)&2047; + s->xvel >>= 1; + } + + // long lPipeBombControl=GetGameVar("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, -1); + +DETONATEB: + + // if(lPipeBombControl & PIPEBOMB_TIMER) + // { + + if( s->picnum == HEAVYHBOMB && hittype[i].temp_data[6] == 1) + { + /* if(s->extra >= 1) + { + s->extra--; + } + + if(s->extra <= 0) + s->lotag=911; + */ + + if(hittype[i].temp_data[7] >= 1) + { + hittype[i].temp_data[7]--; + } + + if(hittype[i].temp_data[7] <= 0) + { + hittype[i].temp_data[6] = 3; + // s->extra = *actorscrptr[s->picnum]; + } + } + // } + + if(( l >= 0 && ps[l].hbomb_on == 0 && hittype[i].temp_data[6] == 2) || t[3] == 1) + hittype[i].temp_data[6] = 3; + + if(hittype[i].temp_data[6] == 3) + + { + t[4]++; + + if(t[4] == 2) + { + x = s->extra; + m = 0; + switch(dynamictostatic[s->picnum]) + { + case HEAVYHBOMB__STATIC: m = pipebombblastradius;break; + case MORTER__STATIC: m = morterblastradius;break; + case BOUNCEMINE__STATIC: m = bouncemineblastradius;break; + } + + hitradius( i, m,x>>2,x>>1,x-(x>>2),x); + spawn(i,EXPLOSION2); + if( s->zvel == 0 ) + spawn(i,EXPLOSION2BOT); + spritesound(PIPEBOMB_EXPLODE,i); + for(x=0;x<8;x++) + RANDOMSCRAP; + } + + if(s->yrepeat) + { + s->yrepeat = 0; + goto BOLT; + } + + if(t[4] > 20) + { + if(s->owner != i || ud.respawn_items == 0) + { + KILLIT(i); + } + else + { + t[2] = respawnitemtime; + spawn(i,RESPAWNMARKERRED); + s->cstat = (short) 32768; + s->yrepeat = 9; + goto BOLT; + } + } + } + else if(s->picnum == HEAVYHBOMB && x < 788 && t[0] > 7 && s->xvel == 0) + if( cansee(s->x,s->y,s->z-(8<<8),s->sectnum,ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum) ) + if(ps[p].ammo_amount[HANDBOMB_WEAPON] < max_ammo_amount[HANDBOMB_WEAPON] ) + { + if((gametype_flags[ud.coop] & GAMETYPE_FLAG_WEAPSTAY) && s->owner == i) + { + for(j=0;jpicnum) + goto BOLT; + + if(ps[p].weapreccnt < 255) + ps[p].weaprecs[ps[p].weapreccnt++] = s->picnum; + } + + addammo(HANDBOMB_WEAPON,&ps[p],1); + spritesound(DUKE_GET,ps[p].i); + + if( ps[p].gotweapon[HANDBOMB_WEAPON] == 0 || s->owner == ps[p].i ) + addweapon(&ps[p],HANDBOMB_WEAPON); + + if( sprite[s->owner].picnum != APLAYER ) + { + ps[p].pals[0] = 0; + ps[p].pals[1] = 32; + ps[p].pals[2] = 0; + ps[p].pals_time = 32; + } + + if( s->owner != i || ud.respawn_items == 0 ) + { + if(s->owner == i && (gametype_flags[ud.coop] & GAMETYPE_FLAG_WEAPSTAY)) + goto BOLT; + KILLIT(i); + } + else + { + t[2] = respawnitemtime; + spawn(i,RESPAWNMARKERRED); + s->cstat = (short) 32768; + } + } + + if(t[0] < 8) t[0]++; + goto BOLT; + + case REACTORBURNT__STATIC: + case REACTOR2BURNT__STATIC: + goto BOLT; + + case REACTOR__STATIC: + case REACTOR2__STATIC: + + if( t[4] == 1 ) + { + j = headspritesect[sect]; + while(j >= 0) + { + switch(dynamictostatic[sprite[j].picnum]) + { + case SECTOREFFECTOR__STATIC: + if(sprite[j].lotag == 1) + { + sprite[j].lotag = (short) 65535; + sprite[j].hitag = (short) 65535; + } + break; + case REACTOR__STATIC: + sprite[j].picnum = REACTORBURNT; + break; + case REACTOR2__STATIC: + sprite[j].picnum = REACTOR2BURNT; + break; + case REACTORSPARK__STATIC: + case REACTOR2SPARK__STATIC: + sprite[j].cstat = (short) 32768; + break; + } + j = nextspritesect[j]; + } + goto BOLT; + } + + if(t[1] >= 20) + { + t[4] = 1; + goto BOLT; + } + + p = findplayer(s,&x); + + t[2]++; + if( t[2] == 4 ) t[2]=0; + + if( x < 4096 ) + { + if( (TRAND&255) < 16 ) + { + if(!isspritemakingsound(ps[p].i, DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,ps[p].i); + + spritesound(SHORT_CIRCUIT,i); + + sprite[ps[p].i].extra --; + ps[p].pals_time = 32; + ps[p].pals[0] = 32; + ps[p].pals[1] = 0; + ps[p].pals[2] = 0; + } + t[0] += 128; + if( t[3] == 0 ) + t[3] = 1; + } + else t[3] = 0; + + if( t[1] ) + { + t[1]++; + + t[4] = s->z; + s->z = sector[sect].floorz-(TRAND%(sector[sect].floorz-sector[sect].ceilingz)); + + switch( t[1] ) + { + case 3: + //Turn on all of those flashing sectoreffector. + hitradius( i, 4096, + impact_damage<<2, + impact_damage<<2, + impact_damage<<2, + impact_damage<<2 ); + /* + j = headspritestat[3]; + while(j>=0) + { + if( sprite[j].lotag == 3 ) + hittype[j].temp_data[4]=1; + else if(sprite[j].lotag == 12) + { + hittype[j].temp_data[4] = 1; + sprite[j].lotag = 3; + sprite[j].owner = 0; + hittype[j].temp_data[0] = s->shade; + } + j = nextspritestat[j]; + } + */ + j = headspritestat[6]; + while(j >= 0) + { + if(sprite[j].picnum == MASTERSWITCH) + if(sprite[j].hitag == s->hitag) + if(sprite[j].yvel == 0) + sprite[j].yvel = 1; + j = nextspritestat[j]; + } + break; + + case 4: + case 7: + case 10: + case 15: + j = headspritesect[sect]; + while(j >= 0) + { + l = nextspritesect[j]; + + if(j != i) + { + deletesprite(j); + break; + } + j = l; + } + break; + } + for(x=0;x<16;x++) + RANDOMSCRAP; + + s->z = t[4]; + t[4] = 0; + + } + else + { + IFHIT + { + for(x=0;x<32;x++) + RANDOMSCRAP; + if(s->extra < 0) + t[1] = 1; + } + } + goto BOLT; + + case CAMERA1__STATIC: + + if( t[0] == 0 ) + { + t[1]+=8; + if(camerashitable) + { + IFHIT + { + t[0] = 1; // static + s->cstat = (short)32768; + for(x=0;x<5;x++) RANDOMSCRAP; + goto BOLT; + } + } + + if(s->hitag > 0) + { + if(t[1]hitag) + s->ang+=8; + else if(t[1]<(s->hitag*3)) + s->ang-=8; + else if(t[1] < (s->hitag<<2) ) + s->ang+=8; + else + { + t[1]=8; + s->ang+=16; + } + } + } + goto BOLT; + } + + + // #ifndef VOLOMEONE + if( ud.multimode < 2 && badguy(s) ) + { + if( actor_tog == 1) + { + s->cstat = (short)32768; + goto BOLT; + } + else if(actor_tog == 2) s->cstat = 257; + } + // #endif + + p = findplayer(s,&x); + + execute(i,p,x); + +BOLT: + + i = nexti; + } + +} + +void moveexplosions(void) // STATNUM 5 +{ + short i, j, k, nexti, sect, p; + long l, x, *t; + spritetype *s; + int switchpicnum; + + i = headspritestat[5]; + while(i >= 0) + { + nexti = nextspritestat[i]; + + t = &hittype[i].temp_data[0]; + s = &sprite[i]; + sect = s->sectnum; + + if( sect < 0 || s->xrepeat == 0 ) KILLIT(i); + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + switchpicnum = s->picnum; + if ((s->picnum > NUKEBUTTON)&&(s->picnum <= NUKEBUTTON+3)) { + switchpicnum = NUKEBUTTON; + } + if ((s->picnum > GLASSPIECES)&&(s->picnum <= GLASSPIECES+2)) { + switchpicnum = GLASSPIECES; + } + if (s->picnum ==INNERJAW+1) { + switchpicnum--; + } + if ( (s->picnum == MONEY+1) || (s->picnum == MAIL+1) || (s->picnum == PAPER+1) ) + hittype[i].floorz = s->z = getflorzofslope(s->sectnum,s->x,s->y); + else switch(dynamictostatic[switchpicnum]) + { + case NEON1__STATIC: + case NEON2__STATIC: + case NEON3__STATIC: + case NEON4__STATIC: + case NEON5__STATIC: + case NEON6__STATIC: + + if( (global_random/(s->lotag+1)&31) > 4) s->shade = -127; + else s->shade = 127; + goto BOLT; + + case BLOODSPLAT1__STATIC: + case BLOODSPLAT2__STATIC: + case BLOODSPLAT3__STATIC: + case BLOODSPLAT4__STATIC: + + if( t[0] == 7*26 ) goto BOLT; + s->z += 16+(TRAND&15); + t[0]++; + if( (t[0]%9) == 0 ) s->yrepeat++; + goto BOLT; + + case NUKEBUTTON__STATIC: + // case NUKEBUTTON+1: + // case NUKEBUTTON+2: + // case NUKEBUTTON+3: + + if(t[0]) + { + t[0]++; + if(t[0] == 8) s->picnum = NUKEBUTTON+1; + else if(t[0] == 16) + { + s->picnum = NUKEBUTTON+2; + ps[sprite[s->owner].yvel].fist_incs = 1; + } + if( ps[sprite[s->owner].yvel].fist_incs == 26 ) + s->picnum = NUKEBUTTON+3; + } + goto BOLT; + + case FORCESPHERE__STATIC: + + l = s->xrepeat; + if(t[1] > 0) + { + t[1]--; + if(t[1] == 0) + { + KILLIT(i); + } + } + if(hittype[s->owner].temp_data[1] == 0) + { + if(t[0] < 64) + { + t[0]++; + l += 3; + } + } + else + if(t[0] > 64) + { + t[0]--; + l -= 3; + } + + s->x = sprite[s->owner].x; + s->y = sprite[s->owner].y; + s->z = sprite[s->owner].z; + s->ang += hittype[s->owner].temp_data[0]; + + if(l > 64) l = 64; + else if(l < 1) l = 1; + + s->xrepeat = l; + s->yrepeat = l; + s->shade = (l>>1)-48; + + for(j=t[0];j > 0;j--) + ssp(i,CLIPMASK0); + goto BOLT; + case WATERSPLASH2__STATIC: + + t[0]++; + if(t[0] == 1 ) + { + if(sector[sect].lotag != 1 && sector[sect].lotag != 2) + KILLIT(i); + /* else + { + l = getflorzofslope(sect,s->x,s->y)-s->z; + if( l > (16<<8) ) KILLIT(i); + } + else */ if (!issoundplaying(ITEM_SPLASH)) + spritesound(ITEM_SPLASH,i); + } + if(t[0] == 3) + { + t[0] = 0; + t[1]++; + } + if(t[1] == 5) + deletesprite(i); + goto BOLT; + case FRAMEEFFECT1_13__STATIC: + if (PLUTOPAK) goto BOLT; // JBF: ideally this should never happen... + + case FRAMEEFFECT1__STATIC: + + if(s->owner >= 0) + { + t[0]++; + + if( t[0] > 7 ) + { + KILLIT(i); + } + else if( t[0] > 4 ) + s->cstat |= 512+2; + else if( t[0] > 2 ) + s->cstat |= 2; + s->xoffset = sprite[s->owner].xoffset; + s->yoffset = sprite[s->owner].yoffset; + } + goto BOLT; + case INNERJAW__STATIC: + // case INNERJAW+1: + + p = findplayer(s,&x); + if(x < 512) + { + ps[p].pals_time = 32; + ps[p].pals[0] = 32; + ps[p].pals[1] = 0; + ps[p].pals[2] = 0; + sprite[ps[p].i].extra -= 4; + } + + case FIRELASER__STATIC: + if(s->extra != 999) + s->extra = 999; + else KILLIT(i); + break; + case TONGUE__STATIC: + KILLIT(i); + + case MONEY__STATIC: + case MAIL__STATIC: + case PAPER__STATIC: + + s->xvel = (TRAND&7)+(sintable[T1&2047]>>9); + T1 += (TRAND&63); + if( (T1&2047) > 512 && (T1&2047) < 1596) + { + if(sector[sect].lotag == 2) + { + if(s->zvel < 64) + s->zvel += (gc>>5)+(TRAND&7); + } + else + if(s->zvel < 144) + s->zvel += (gc>>5)+(TRAND&7); + } + + ssp(i,CLIPMASK0); + + if( (TRAND&3) == 0 ) + setsprite(i,s->x,s->y,s->z); + + if(s->sectnum == -1) KILLIT(i); + l = getflorzofslope(s->sectnum,s->x,s->y); + + if( s->z > l ) + { + s->z = l; + + insertspriteq(i); + PN ++; + + j = headspritestat[5]; + while(j >= 0) + { + if(sprite[j].picnum == BLOODPOOL) + if(ldist(s,&sprite[j]) < 348) + { + s->pal = 2; + break; + } + j = nextspritestat[j]; + } + } + + break; + + case JIBS1__STATIC: + case JIBS2__STATIC: + case JIBS3__STATIC: + case JIBS4__STATIC: + case JIBS5__STATIC: + case JIBS6__STATIC: + case HEADJIB1__STATIC: + case ARMJIB1__STATIC: + case LEGJIB1__STATIC: + case LIZMANHEAD1__STATIC: + case LIZMANARM1__STATIC: + case LIZMANLEG1__STATIC: + case DUKETORSO__STATIC: + case DUKEGUN__STATIC: + case DUKELEG__STATIC: + + if(s->xvel > 0) s->xvel--; + else s->xvel = 0; + + if( t[5] < 30*10 ) + t[5]++; + else { KILLIT(i); } + + + if(s->zvel > 1024 && s->zvel < 1280) + { + setsprite(i,s->x,s->y,s->z); + sect = s->sectnum; + } + + l = getflorzofslope(sect,s->x,s->y); + x = getceilzofslope(sect,s->x,s->y); + if(x == l || sect < 0 || sect >= MAXSECTORS) KILLIT(i); + + if( s->z < l-(2<<8) ) + { + if(t[1] < 2) t[1]++; + else if(sector[sect].lotag != 2) + { + t[1] = 0; + if( s->picnum == DUKELEG || s->picnum == DUKETORSO || s->picnum == DUKEGUN ) + { + if(t[0] > 6) t[0] = 0; + else t[0]++; + } + else + { + if(t[0] > 2) + t[0] = 0; + else t[0]++; + } + } + + if(s->zvel < 6144) + { + if(sector[sect].lotag == 2) + { + if(s->zvel < 1024) + s->zvel += 48; + else s->zvel = 1024; + } + else s->zvel += gc-50; + } + + s->x += (s->xvel*sintable[(s->ang+512)&2047])>>14; + s->y += (s->xvel*sintable[s->ang&2047])>>14; + s->z += s->zvel; + + } + else + { + if(t[2] == 0) + { + if( s->sectnum == -1) { KILLIT(i); } + if( (sector[s->sectnum].floorstat&2) ) { KILLIT(i); } + t[2]++; + } + l = getflorzofslope(s->sectnum,s->x,s->y); + + s->z = l-(2<<8); + s->xvel = 0; + + if(s->picnum == JIBS6) + { + t[1]++; + if( (t[1]&3) == 0 && t[0] < 7) + t[0]++; + if(t[1] > 20) KILLIT(i); + } + else { s->picnum = JIBS6; t[0] = 0; t[1] = 0; } + } + goto BOLT; + + case BLOODPOOL__STATIC: + case PUKE__STATIC: + + if(t[0] == 0) + { + t[0] = 1; + if(sector[sect].floorstat&2) { KILLIT(i); } + else insertspriteq(i); + } + + makeitfall(i); + + p = findplayer(s,&x); + + s->z = hittype[i].floorz-(FOURSLEIGHT); + + if(t[2] < 32) + { + t[2]++; + if(hittype[i].picnum == TIRE) + { + if(s->xrepeat < 64 && s->yrepeat < 64) + { + s->xrepeat += TRAND&3; + s->yrepeat += TRAND&3; + } + } + else + { + if(s->xrepeat < 32 && s->yrepeat < 32) + { + s->xrepeat += TRAND&3; + s->yrepeat += TRAND&3; + } + } + } + + if(x < 844 && s->xrepeat > 6 && s->yrepeat > 6) + { + if( s->pal == 0 && (TRAND&255) < 16 && s->picnum != PUKE) + { + if(ps[p].boot_amount > 0) + ps[p].boot_amount--; + else + { + if(!isspritemakingsound(ps[p].i,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,ps[p].i); + sprite[ps[p].i].extra --; + ps[p].pals_time = 32; + ps[p].pals[0] = 16; + ps[p].pals[1] = 0; + ps[p].pals[2] = 0; + } + } + + if(t[1] == 1) goto BOLT; + t[1] = 1; + + if(hittype[i].picnum == TIRE) + ps[p].footprintcount = 10; + else ps[p].footprintcount = 3; + + ps[p].footprintpal = s->pal; + ps[p].footprintshade = s->shade; + + if(t[2] == 32) + { + s->xrepeat -= 6; + s->yrepeat -= 6; + } + } + else t[1] = 0; + goto BOLT; + + case BURNING__STATIC: + case BURNING2__STATIC: + case FECES__STATIC: + case WATERBUBBLE__STATIC: + case SMALLSMOKE__STATIC: + case EXPLOSION2__STATIC: + case SHRINKEREXPLOSION__STATIC: + case EXPLOSION2BOT__STATIC: + case BLOOD__STATIC: + case LASERSITE__STATIC: + case FORCERIPPLE__STATIC: + case TRANSPORTERSTAR__STATIC: + case TRANSPORTERBEAM__STATIC: + p = findplayer(s,&x); + execute(i,p,x); + goto BOLT; + + case SHELL__STATIC: + case SHOTGUNSHELL__STATIC: + + ssp(i,CLIPMASK0); + + if(sect < 0 || ( sector[sect].floorz + 256 ) < s->z ) KILLIT(i); + + if(sector[sect].lotag == 2) + { + t[1]++; + if(t[1] > 8) + { + t[1] = 0; + t[0]++; + t[0] &= 3; + } + if(s->zvel < 128) s->zvel += (gc/13); // 8 + else s->zvel -= 64; + if(s->xvel > 0) + s->xvel -= 4; + else s->xvel = 0; + } + else + { + t[1]++; + if(t[1] > 3) + { + t[1] = 0; + t[0]++; + t[0] &= 3; + } + if(s->zvel < 512) s->zvel += (gc/3); // 52; + if(s->xvel > 0) + s->xvel --; + // else KILLIT(i); + } + + goto BOLT; + + case GLASSPIECES__STATIC: + // case GLASSPIECES+1: + // case GLASSPIECES+2: + + makeitfall(i); + + if(s->zvel > 4096) s->zvel = 4096; + if(sect < 0) KILLIT(i); + + if( s->z == hittype[i].floorz-(FOURSLEIGHT) && t[0] < 3) + { + s->zvel = -((3-t[0])<<8)-(TRAND&511); + if(sector[sect].lotag == 2) + s->zvel >>= 1; + s->xrepeat >>= 1; + s->yrepeat >>= 1; + if( rnd(96) ) + setsprite(i,s->x,s->y,s->z); + t[0]++;//Number of bounces + } + else if( t[0] == 3 ) KILLIT(i); + + if(s->xvel > 0) + { + s->xvel -= 2; + s->cstat = ((s->xvel&3)<<2); + } + else s->xvel = 0; + + ssp(i,CLIPMASK0); + + goto BOLT; + } + + IFWITHIN(SCRAP6,SCRAP5+3) + { + if(s->xvel > 0) + s->xvel--; + else s->xvel = 0; + + if(s->zvel > 1024 && s->zvel < 1280) + { + setsprite(i,s->x,s->y,s->z); + sect = s->sectnum; + } + + if( s->z < sector[sect].floorz-(2<<8) ) + { + if(t[1] < 1) t[1]++; + else + { + t[1] = 0; + + if(s->picnum < SCRAP6+8) + { + if(t[0] > 6) + t[0] = 0; + else t[0]++; + } + else + { + if(t[0] > 2) + t[0] = 0; + else t[0]++; + } + } + if(s->zvel < 4096) s->zvel += gc-50; + s->x += (s->xvel*sintable[(s->ang+512)&2047])>>14; + s->y += (s->xvel*sintable[s->ang&2047])>>14; + s->z += s->zvel; + } + else + { + if(s->picnum == SCRAP1 && s->yvel > 0) + { + j = spawn(i,s->yvel); + setsprite(j,s->x,s->y,s->z); + getglobalz(j); + sprite[j].hitag = sprite[j].lotag = 0; + } + KILLIT(i); + } + goto BOLT; + } + +BOLT: + i = nexti; + } +} + +void moveeffectors(void) //STATNUM 3 +{ + long q=0, l, m, x, st, j, *t; + short i, k, nexti, nextk, p, sh, nextj; + spritetype *s; + sectortype *sc; + walltype *wal; + + fricxv = fricyv = 0; + + i = headspritestat[3]; + while(i >= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sc = §or[s->sectnum]; + st = s->lotag; + sh = s->hitag; + + t = &hittype[i].temp_data[0]; + + switch(st) + { + case 0: + { + long zchange = 0; + + zchange = 0; + + j = s->owner; + + if( sprite[j].lotag == (short) 65535 ) + KILLIT(i); + + q = sc->extra>>3; + l = 0; + + if(sc->lotag == 30) + { + q >>= 2; + + if( sprite[i].extra == 1 ) + { + if(hittype[i].tempang < 256) + { + hittype[i].tempang += 4; + if(hittype[i].tempang >= 256) + callsound(s->sectnum,i); + if(s->clipdist) l = 1; + else l = -1; + } + else hittype[i].tempang = 256; + + if( sc->floorz > s->z ) //z's are touching + { + sc->floorz -= 512; + zchange = -512; + if( sc->floorz < s->z ) + sc->floorz = s->z; + } + + else if( sc->floorz < s->z ) //z's are touching + { + sc->floorz += 512; + zchange = 512; + if( sc->floorz > s->z ) + sc->floorz = s->z; + } + } + else if(sprite[i].extra == 3) + { + if(hittype[i].tempang > 0) + { + hittype[i].tempang -= 4; + if(hittype[i].tempang <= 0) + callsound(s->sectnum,i); + if( s->clipdist ) l = -1; + else l = 1; + } + else hittype[i].tempang = 0; + + if( sc->floorz > T4 ) //z's are touching + { + sc->floorz -= 512; + zchange = -512; + if( sc->floorz < T4 ) + sc->floorz = T4; + } + + else if( sc->floorz < T4 ) //z's are touching + { + sc->floorz += 512; + zchange = 512; + if( sc->floorz > T4 ) + sc->floorz = T4; + } + } + + s->ang += (l*q); + t[2] += (l*q); + } + else + { + if( hittype[j].temp_data[0] == 0 ) break; + if( hittype[j].temp_data[0] == 2 ) KILLIT(i); + + if( sprite[j].ang > 1024 ) + l = -1; + else l = 1; + if( t[3] == 0 ) + t[3] = ldist(s,&sprite[j]); + s->xvel = t[3]; + s->x = sprite[j].x; + s->y = sprite[j].y; + s->ang += (l*q); + t[2] += (l*q); + } + + if( l && (sc->floorstat&64) ) + { + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + if( ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1) + { + + ps[p].ang += (l*q); + ps[p].ang &= 2047; + + ps[p].posz += zchange; + + rotatepoint( sprite[j].x,sprite[j].y, + ps[p].posx,ps[p].posy,(q*l), + &m,&x); + + ps[p].bobposx += m-ps[p].posx; + ps[p].bobposy += x-ps[p].posy; + + ps[p].posx = m; + ps[p].posy = x; + + if(sprite[ps[p].i].extra <= 0) + { + sprite[ps[p].i].x = m; + sprite[ps[p].i].y = x; + } + } + } + + p = headspritesect[s->sectnum]; + while(p >= 0) + { + if(sprite[p].statnum != 3 && sprite[p].statnum != 4) + if( sprite[p].picnum != LASERLINE ) + { + if(sprite[p].picnum == APLAYER && sprite[p].owner >= 0) + { + p = nextspritesect[p]; + continue; + } + + sprite[p].ang += (l*q); + sprite[p].ang &= 2047; + + sprite[p].z += zchange; + + rotatepoint(sprite[j].x,sprite[j].y, + sprite[p].x,sprite[p].y,(q*l), + &sprite[p].x,&sprite[p].y); + + } + p = nextspritesect[p]; + } + + } + + ms(i); + } + + break; + case 1: //Nothing for now used as the pivot + if(s->owner == -1) //Init + { + s->owner = i; + + j = headspritestat[3]; + while(j >= 0) + { + if( sprite[j].lotag == 19 && sprite[j].hitag == sh ) + { + t[0] = 0; + break; + } + j = nextspritestat[j]; + } + } + + break; + case 6: + k = sc->extra; + + if(t[4] > 0) + { + t[4]--; + if( t[4] >= (k-(k>>3)) ) + s->xvel -= (k>>5); + if( t[4] > ((k>>1)-1) && t[4] < (k-(k>>3)) ) + s->xvel = 0; + if( t[4] < (k>>1) ) + s->xvel += (k>>5); + if( t[4] < ((k>>1)-(k>>3)) ) + { + t[4] = 0; + s->xvel = k; + } + } + else s->xvel = k; + + j = headspritestat[3]; + while( j >= 0) + { + if( (sprite[j].lotag == 14) && (sh == sprite[j].hitag) && (hittype[j].temp_data[0] == t[0]) ) + { + sprite[j].xvel = s->xvel; + // if( t[4] == 1 ) + { + if(hittype[j].temp_data[5] == 0) + hittype[j].temp_data[5] = dist(&sprite[j],s); + x = ksgn( dist(&sprite[j],s)-hittype[j].temp_data[5] ); + if(sprite[j].extra) + x = -x; + s->xvel += x; + } + hittype[j].temp_data[4] = t[4]; + } + j = nextspritestat[j]; + } + x = 0; + + + case 14: + if(s->owner==-1) + s->owner = LocateTheLocator((short)t[3],(short)t[0]); + + if(s->owner == -1) + { + Bsprintf(tempbuf,"Could not find any locators for SE# 6 and 14 with a hitag of %ld.\n",t[3]); + gameexit(tempbuf); + } + + j = ldist(&sprite[s->owner],s); + + if( j < 1024L ) + { + if(st==6) + if(sprite[s->owner].hitag&1) + t[4]=sc->extra; //Slow it down + t[3]++; + s->owner = LocateTheLocator(t[3],t[0]); + if(s->owner==-1) + { + t[3]=0; + s->owner = LocateTheLocator(0,t[0]); + } + } + + if(s->xvel) + { + x = getangle(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y); + q = getincangle(s->ang,x)>>3; + + t[2] += q; + s->ang += q; + + if(s->xvel == sc->extra ) + { + if( (sc->floorstat&1) == 0 && (sc->ceilingstat&1) == 0 ) + { + if( !issoundplaying(hittype[i].lastvx) ) + spritesound(hittype[i].lastvx,i); + } + else if( ud.monsters_off == 0 && sc->floorpal == 0 && (sc->floorstat&1) && rnd(8) ) + { + p = findplayer(s,&x); + if(x < 20480) + { + j = s->ang; + s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy); + shoot(i,RPG); + s->ang = j; + } + } + } + + if(s->xvel <= 64 && (sc->floorstat&1) == 0 && (sc->ceilingstat&1) == 0 ) + stopspritesound(hittype[i].lastvx,i); + + if( (sc->floorz-sc->ceilingz) < (108<<8) ) + { + if(ud.clipping == 0 && s->xvel >= 192) + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(sprite[ps[p].i].extra > 0) + { + k = ps[p].cursectnum; + updatesector(ps[p].posx,ps[p].posy,&k); + if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) ) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i,s->x,s->y,s->z); + quickkill(&ps[p]); + } + } + } + + m = (s->xvel*sintable[(s->ang+512)&2047])>>14; + x = (s->xvel*sintable[s->ang&2047])>>14; + + for(p = connecthead;p >= 0;p=connectpoint2[p]) + if(sector[ps[p].cursectnum].lotag != 2) + { + if(po[p].os == s->sectnum) + { + po[p].ox += m; + po[p].oy += x; + } + + if(s->sectnum == sprite[ps[p].i].sectnum) + { + rotatepoint(s->x,s->y,ps[p].posx,ps[p].posy,q,&ps[p].posx,&ps[p].posy); + + ps[p].posx += m; + ps[p].posy += x; + + ps[p].bobposx += m; + ps[p].bobposy += x; + + ps[p].ang += q; + + if(numplayers > 1) + { + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + } + if( sprite[ps[p].i].extra <= 0 ) + { + sprite[ps[p].i].x = ps[p].posx; + sprite[ps[p].i].y = ps[p].posy; + } + } + } + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if (sprite[j].statnum != 10 && sector[sprite[j].sectnum].lotag != 2 && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS ) + { + rotatepoint(s->x,s->y, + sprite[j].x,sprite[j].y,q, + &sprite[j].x,&sprite[j].y); + + sprite[j].x+= m; + sprite[j].y+= x; + + sprite[j].ang+=q; + + if(numplayers > 1) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + } + j = nextspritesect[j]; + } + + ms(i); + setsprite(i,s->x,s->y,s->z); + + if( (sc->floorz-sc->ceilingz) < (108<<8) ) + { + if(ud.clipping == 0 && s->xvel >= 192) + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(sprite[ps[p].i].extra > 0) + { + k = ps[p].cursectnum; + updatesector(ps[p].posx,ps[p].posy,&k); + if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) ) + { + ps[p].oposx = ps[p].posx = s->x; + ps[p].oposy = ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i,s->x,s->y,s->z); + quickkill(&ps[p]); + } + } + + j = headspritesect[sprite[OW].sectnum]; + while(j >= 0) + { + l = nextspritesect[j]; + if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS ) + { + k = sprite[j].sectnum; + updatesector(sprite[j].x,sprite[j].y,&k); + if( sprite[j].extra >= 0 && k == s->sectnum ) + { + gutsdir(&sprite[j],JIBS6,72,myconnectindex); + spritesound(SQUISHED,i); + deletesprite(j); + } + } + j = l; + } + } + } + + break; + + case 30: + if(s->owner == -1) + { + t[3] = !t[3]; + s->owner = LocateTheLocator(t[3],t[0]); + } + else + { + + if(t[4] == 1) // Starting to go + { + if( ldist( &sprite[s->owner],s ) < (2048-128) ) + t[4] = 2; + else + { + if(s->xvel == 0) + operateactivators(s->hitag+(!t[3]),-1); + if(s->xvel < 256) + s->xvel += 16; + } + } + if(t[4] == 2) + { + l = FindDistance2D(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y); + + if(l <= 128) + s->xvel = 0; + + if( s->xvel > 0 ) + s->xvel -= 16; + else + { + s->xvel = 0; + operateactivators(s->hitag+(short)t[3],-1); + s->owner = -1; + s->ang += 1024; + t[4] = 0; + operateforcefields(i,s->hitag); + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS ) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + j = nextspritesect[j]; + } + + } + } + } + + if(s->xvel) + { + l = (s->xvel*sintable[(s->ang+512)&2047])>>14; + x = (s->xvel*sintable[s->ang&2047])>>14; + + if( (sc->floorz-sc->ceilingz) < (108<<8) ) + if(ud.clipping == 0) + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(sprite[ps[p].i].extra > 0) + { + k = ps[p].cursectnum; + updatesector(ps[p].posx,ps[p].posy,&k); + if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) ) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i,s->x,s->y,s->z); + quickkill(&ps[p]); + } + } + + for(p = connecthead;p >= 0;p = connectpoint2[p]) + { + if( sprite[ps[p].i].sectnum == s->sectnum ) + { + ps[p].posx += l; + ps[p].posy += x; + + if(numplayers > 1) + { + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + } + + ps[p].bobposx += l; + ps[p].bobposy += x; + } + + if( po[p].os == s->sectnum ) + { + po[p].ox += l; + po[p].oy += x; + } + } + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS ) + { + if(numplayers < 2) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + + sprite[j].x += l; + sprite[j].y += x; + + if(numplayers > 1) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + } + j = nextspritesect[j]; + } + + ms(i); + setsprite(i,s->x,s->y,s->z); + + if( (sc->floorz-sc->ceilingz) < (108<<8) ) + { + if(ud.clipping == 0) + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(sprite[ps[p].i].extra > 0) + { + k = ps[p].cursectnum; + updatesector(ps[p].posx,ps[p].posy,&k); + if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) ) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i,s->x,s->y,s->z); + quickkill(&ps[p]); + } + } + + j = headspritesect[sprite[OW].sectnum]; + while(j >= 0) + { + l = nextspritesect[j]; + if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS ) + { + // if(sprite[j].sectnum != s->sectnum) + { + k = sprite[j].sectnum; + updatesector(sprite[j].x,sprite[j].y,&k); + if( sprite[j].extra >= 0 && k == s->sectnum ) + { + gutsdir(&sprite[j],JIBS6,24,myconnectindex); + spritesound(SQUISHED,j); + deletesprite(j); + } + } + + } + j = l; + } + } + } + + break; + + + case 2://Quakes + if(t[4] > 0 && t[0] == 0 ) + { + if( t[4] < sh ) + t[4]++; + else t[0] = 1; + } + + if(t[0] > 0) + { + t[0]++; + + s->xvel = 3; + + if(t[0] > 96) + { + t[0] = -1; //Stop the quake + t[4] = -1; + KILLIT(i); + } + else + { + if( (t[0]&31) == 8 ) + { + earthquaketime = 48; + spritesound(EARTHQUAKE,ps[screenpeek].i); + } + + if( klabs( sc->floorheinum-t[5] ) < 8 ) + sc->floorheinum = t[5]; + else sc->floorheinum += ( ksgn(t[5]-sc->floorheinum)<<4 ); + } + + m = (s->xvel*sintable[(s->ang+512)&2047])>>14; + x = (s->xvel*sintable[s->ang&2047])>>14; + + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + ps[p].posx += m; + ps[p].posy += x; + + ps[p].bobposx += m; + ps[p].bobposy += x; + } + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + nextj = nextspritesect[j]; + + if (sprite[j].picnum != SECTOREFFECTOR) + { + sprite[j].x+=m; + sprite[j].y+=x; + setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z); + } + j = nextj; + } + ms(i); + setsprite(i,s->x,s->y,s->z); + } + break; + + //Flashing sector lights after reactor EXPLOSION2 + + case 3: + + if( t[4] == 0 ) break; + p = findplayer(s,&x); + + // if(t[5] > 0) { t[5]--; break; } + + if( (global_random/(sh+1)&31) < 4 && !t[2]) + { + // t[5] = 4+(global_random&7); + sc->ceilingpal = s->owner>>8; + sc->floorpal = s->owner&0xff; + t[0] = s->shade + (global_random&15); + } + else + { + // t[5] = 4+(global_random&3); + sc->ceilingpal = s->pal; + sc->floorpal = s->pal; + t[0] = t[3]; + } + + sc->ceilingshade = t[0]; + sc->floorshade = t[0]; + + wal = &wall[sc->wallptr]; + + for(x=sc->wallnum;x > 0;x--,wal++) + { + if( wal->hitag != 1 ) + { + wal->shade = t[0]; + if((wal->cstat&2) && wal->nextwall >= 0) + { + wall[wal->nextwall].shade = wal->shade; + } + } + } + + break; + + case 4: + + if((global_random/(sh+1)&31) < 4 ) + { + t[1] = s->shade + (global_random&15);//Got really bright + t[0] = s->shade + (global_random&15); + sc->ceilingpal = s->owner>>8; + sc->floorpal = s->owner&0xff; + j = 1; + } + else + { + t[1] = t[2]; + t[0] = t[3]; + + sc->ceilingpal = s->pal; + sc->floorpal = s->pal; + + j = 0; + } + + sc->floorshade = t[1]; + sc->ceilingshade = t[1]; + + wal = &wall[sc->wallptr]; + + for(x=sc->wallnum;x > 0; x--,wal++) + { + if(j) wal->pal = (s->owner&0xff); + else wal->pal = s->pal; + + if( wal->hitag != 1 ) + { + wal->shade = t[0]; + if((wal->cstat&2) && wal->nextwall >= 0) + wall[wal->nextwall].shade = wal->shade; + } + } + + j = headspritesect[SECT]; + while(j >= 0) + { + if(sprite[j].cstat&16 && checkspriteflags(j,SPRITE_FLAG_NOSHADE) == 0) + { + if (sc->ceilingstat&1) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + + j = nextspritesect[j]; + } + + if(t[4]) KILLIT(i); + + break; + + //BOSS + case 5: + p = findplayer(s,&x); + if(x < 8192) + { + j = s->ang; + s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy); + shoot(i,FIRELASER); + s->ang = j; + } + + if(s->owner==-1) //Start search + { + t[4]=0; + l = 0x7fffffff; + while(1) //Find the shortest dist + { + s->owner = LocateTheLocator((short)t[4],-1); //t[0] hold sectnum + + if(s->owner==-1) break; + + m = ldist(&sprite[ps[p].i],&sprite[s->owner]); + + if(l > m) + { + q = s->owner; + l = m; + } + + t[4]++; + } + + s->owner = q; + s->zvel = ksgn(sprite[q].z-s->z)<<4; + } + + if(ldist(&sprite[s->owner],s) < 1024) + { + short ta; + ta = s->ang; + s->ang = getangle(ps[p].posx-s->x,ps[p].posy-s->y); + s->ang = ta; + s->owner = -1; + goto BOLT; + + } + else s->xvel=256; + + x = getangle(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y); + q = getincangle(s->ang,x)>>3; + s->ang += q; + + if(rnd(32)) + { + t[2]+=q; + sc->ceilingshade = 127; + } + else + { + t[2] += + getincangle(t[2]+512,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>2; + sc->ceilingshade = 0; + } + IFHIT + { + t[3]++; + if(t[3] == 5) + { + s->zvel += 1024; + FTA(7,&ps[myconnectindex]); + } + } + + s->z += s->zvel; + sc->ceilingz += s->zvel; + sector[t[0]].ceilingz += s->zvel; + ms(i); + setsprite(i,s->x,s->y,s->z); + break; + + + case 8: + case 9: + + // work only if its moving + + j = -1; + + if(hittype[i].temp_data[4]) + { + hittype[i].temp_data[4]++; + if( hittype[i].temp_data[4] > 8 ) KILLIT(i); + j = 1; + } + else j = getanimationgoal(&sc->ceilingz); + + if( j >= 0 ) + { + short sn; + + if( (sc->lotag&0x8000) || hittype[i].temp_data[4] ) + x = -t[3]; + else + x = t[3]; + + if ( st == 9 ) x = -x; + + j = headspritestat[3]; + while(j >= 0) + { + if( ((sprite[j].lotag) == st ) && (sprite[j].hitag) == sh ) + { + sn = sprite[j].sectnum; + m = sprite[j].shade; + + wal = &wall[sector[sn].wallptr]; + + for(l=sector[sn].wallnum;l>0;l--,wal++) + { + if( wal->hitag != 1 ) + { + wal->shade+=x; + + if(wal->shade < m) + wal->shade = m; + else if(wal->shade > hittype[j].temp_data[2]) + wal->shade = hittype[j].temp_data[2]; + + if(wal->nextwall >= 0) + if(wall[wal->nextwall].hitag != 1) + wall[wal->nextwall].shade = wal->shade; + } + } + + sector[sn].floorshade += x; + sector[sn].ceilingshade += x; + + if(sector[sn].floorshade < m) + sector[sn].floorshade = m; + else if(sector[sn].floorshade > hittype[j].temp_data[0]) + sector[sn].floorshade = hittype[j].temp_data[0]; + + if(sector[sn].ceilingshade < m) + sector[sn].ceilingshade = m; + else if(sector[sn].ceilingshade > hittype[j].temp_data[1]) + sector[sn].ceilingshade = hittype[j].temp_data[1]; + + } + j = nextspritestat[j]; + } + } + break; + case 10: + + if( (sc->lotag&0xff) == 27 || ( sc->floorz > sc->ceilingz && (sc->lotag&0xff) != 23 ) || sc->lotag == (short) 32791 ) + { + j = 1; + + if( (sc->lotag&0xff) != 27) + for(p=connecthead;p>=0;p=connectpoint2[p]) + if( sc->lotag != 30 && sc->lotag != 31 && sc->lotag != 0 ) + if(s->sectnum == sprite[ps[p].i].sectnum) + j = 0; + + if(j == 1) + { + if(t[0] > sh ) + switch(sector[s->sectnum].lotag) + { + case 20: + case 21: + case 22: + case 26: + if( getanimationgoal(§or[s->sectnum].ceilingz) >= 0 ) + break; + default: + activatebysector(s->sectnum,i); + t[0] = 0; + break; + } + else t[0]++; + } + } + else t[0]=0; + break; + case 11: //Swingdoor + + if( t[5] > 0) + { + t[5]--; + break; + } + + if( t[4] ) + { + short startwall,endwall; + + startwall = sc->wallptr; + endwall = startwall+sc->wallnum; + + for(j=startwall;j= 0) + { + if( sprite[k].extra > 0 && badguy(&sprite[k]) && clipinsidebox(sprite[k].x,sprite[k].y,j,256L) == 1 ) + goto BOLT; + k = nextspritestat[k]; + } + + k = headspritestat[10]; + while(k >= 0) + { + if( sprite[k].owner >= 0 && clipinsidebox(sprite[k].x,sprite[k].y,j,144L) == 1 ) + { + t[5] = 8; // Delay + k = (SP>>3)*t[3]; + t[2]-=k; + t[4]-=k; + ms(i); + setsprite(i,s->x,s->y,s->z); + goto BOLT; + } + k = nextspritestat[k]; + } + } + + k = (SP>>3)*t[3]; + t[2]+=k; + t[4]+=k; + ms(i); + setsprite(i,s->x,s->y,s->z); + + if(t[4] <= -511 || t[4] >= 512) + { + t[4] = 0; + t[2] &= 0xffffff00; + ms(i); + setsprite(i,s->x,s->y,s->z); + break; + } + } + break; + case 12: + if( t[0] == 3 || t[3] == 1 ) //Lights going off + { + sc->floorpal = 0; + sc->ceilingpal = 0; + + wal = &wall[sc->wallptr]; + for(j = sc->wallnum;j > 0; j--, wal++) + if(wal->hitag != 1) + { + wal->shade = t[1]; + wal->pal = 0; + } + + sc->floorshade = t[1]; + sc->ceilingshade = t[2]; + t[0]=0; + + j = headspritesect[SECT]; + while(j >= 0) + { + if(sprite[j].cstat&16 && checkspriteflags(j,SPRITE_FLAG_NOSHADE) == 0) + { + if (sc->ceilingstat&1) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + j = nextspritesect[j]; + + } + + if(t[3] == 1) KILLIT(i); + } + if( t[0] == 1 ) //Lights flickering on + { + if( sc->floorshade > s->shade ) + { + sc->floorpal = s->pal; + sc->ceilingpal = s->pal; + + sc->floorshade -= 2; + sc->ceilingshade -= 2; + + wal = &wall[sc->wallptr]; + for(j=sc->wallnum;j>0;j--,wal++) + if(wal->hitag != 1) + { + wal->pal = s->pal; + wal->shade -= 2; + } + } + else t[0] = 2; + + j = headspritesect[SECT]; + while(j >= 0) + { + if(sprite[j].cstat&16) + { + if (sc->ceilingstat&1 && checkspriteflags(j,SPRITE_FLAG_NOSHADE) == 0) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + j = nextspritesect[j]; + } + } + break; + + + case 13: + if( t[2] ) + { + j = (SP<<5)|1; + + if( s->ang == 512 ) + { + if( s->owner ) + { + if( klabs(t[0]-sc->ceilingz) >= j ) + sc->ceilingz += ksgn(t[0]-sc->ceilingz)*j; + else sc->ceilingz = t[0]; + } + else + { + if( klabs(t[1]-sc->floorz) >= j ) + sc->floorz += ksgn(t[1]-sc->floorz)*j; + else sc->floorz = t[1]; + } + } + else + { + if( klabs(t[1]-sc->floorz) >= j ) + sc->floorz += ksgn(t[1]-sc->floorz)*j; + else sc->floorz = t[1]; + if( klabs(t[0]-sc->ceilingz) >= j ) + sc->ceilingz += ksgn(t[0]-sc->ceilingz)*j; + sc->ceilingz = t[0]; + } + + if( t[3] == 1 ) + { + //Change the shades + + t[3]++; + sc->ceilingstat ^= 1; + + if(s->ang == 512) + { + wal = &wall[sc->wallptr]; + for(j=sc->wallnum;j>0;j--,wal++) + wal->shade = s->shade; + + sc->floorshade = s->shade; + + if(ps[0].one_parallax_sectnum >= 0) + { + sc->ceilingpicnum = + sector[ps[0].one_parallax_sectnum].ceilingpicnum; + sc->ceilingshade = + sector[ps[0].one_parallax_sectnum].ceilingshade; + } + } + } + t[2]++; + if(t[2] > 256) + KILLIT(i); + } + + + if( t[2] == 4 && s->ang != 512) + for(x=0;x<7;x++) RANDOMSCRAP; + break; + + + case 15: + + if(t[4]) + { + s->xvel = 16; + + if(t[4] == 1) //Opening + { + if( t[3] >= (SP>>3) ) + { + t[4] = 0; //Turn off the sliders + callsound(s->sectnum,i); + break; + } + t[3]++; + } + else if(t[4] == 2) + { + if(t[3]<1) + { + t[4] = 0; + callsound(s->sectnum,i); + break; + } + t[3]--; + } + + ms(i); + setsprite(i,s->x,s->y,s->z); + } + break; + + case 16: //Reactor + + t[2]+=32; + if(sc->floorzceilingz) s->shade=0; + + else if( sc->ceilingz < t[3] ) + { + + //The following code check to see if + //there is any other sprites in the sector. + //If there isn't, then kill this sectoreffector + //itself..... + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == REACTOR || sprite[j].picnum == REACTOR2) + break; + j = nextspritesect[j]; + } + if(j == -1) { KILLIT(i); } + else s->shade=1; + } + + if(s->shade) sc->ceilingz+=1024; + else sc->ceilingz-=512; + + ms(i); + setsprite(i,s->x,s->y,s->z); + + break; + + case 17: + + q = t[0]*(SP<<2); + + sc->ceilingz += q; + sc->floorz += q; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].statnum == 10 && sprite[j].owner >= 0) + { + p = sprite[j].yvel; + if(numplayers < 2) + ps[p].oposz = ps[p].posz; + ps[p].posz += q; + ps[p].truefz += q; + ps[p].truecz += q; + if(numplayers > 1) + ps[p].oposz = ps[p].posz; + } + if( sprite[j].statnum != 3 ) + { + hittype[j].bposz = sprite[j].z; + sprite[j].z += q; + } + + hittype[j].floorz = sc->floorz; + hittype[j].ceilingz = sc->ceilingz; + + j = nextspritesect[j]; + } + + if( t[0] ) if(t[0]) //If in motion + { + if( klabs(sc->floorz-t[2]) <= SP) + { + activatewarpelevators(i,0); + break; + } + + if(t[0]==-1) + { + if( sc->floorz > t[3] ) + break; + } + else if( sc->ceilingz < t[4] ) break; + + if( t[1] == 0 ) break; + t[1] = 0; + + j = headspritestat[3]; + while(j >= 0) + { + if( i != j && (sprite[j].lotag) == 17) + if( (sc->hitag-t[0]) == + (sector[sprite[j].sectnum].hitag) + && sh == (sprite[j].hitag)) + break; + j = nextspritestat[j]; + } + + if(j == -1) break; + + k = headspritesect[s->sectnum]; + while(k >= 0) + { + nextk = nextspritesect[k]; + + if(sprite[k].statnum == 10 && sprite[k].owner >= 0) + { + p = sprite[k].yvel; + + ps[p].posx += sprite[j].x-s->x; + ps[p].posy += sprite[j].y-s->y; + ps[p].posz = sector[sprite[j].sectnum].floorz-(sc->floorz-ps[p].posz); + + hittype[k].floorz = sector[sprite[j].sectnum].floorz; + hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz; + + ps[p].bobposx = ps[p].oposx = ps[p].posx; + ps[p].bobposy = ps[p].oposy = ps[p].posy; + ps[p].oposz = ps[p].posz; + + ps[p].truefz = hittype[k].floorz; + ps[p].truecz = hittype[k].ceilingz; + ps[p].bobcounter = 0; + + changespritesect(k,sprite[j].sectnum); + ps[p].cursectnum = sprite[j].sectnum; + } + else if( sprite[k].statnum != 3 ) + { + sprite[k].x += + sprite[j].x-s->x; + sprite[k].y += + sprite[j].y-s->y; + sprite[k].z = sector[sprite[j].sectnum].floorz- + (sc->floorz-sprite[k].z); + + hittype[k].bposx = sprite[k].x; + hittype[k].bposy = sprite[k].y; + hittype[k].bposz = sprite[k].z; + + changespritesect(k,sprite[j].sectnum); + setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z); + + hittype[k].floorz = sector[sprite[j].sectnum].floorz; + hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz; + + } + k = nextk; + } + } + break; + + case 18: + if(t[0]) + { + if(s->pal) + { + if(s->ang == 512) + { + sc->ceilingz -= sc->extra; + if(sc->ceilingz <= t[1]) + { + sc->ceilingz = t[1]; + KILLIT(i); + } + } + else + { + sc->floorz += sc->extra; + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz += sc->extra; + if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z += sc->extra; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + if(sc->floorz >= t[1]) + { + sc->floorz = t[1]; + KILLIT(i); + } + } + } + else + { + if(s->ang == 512) + { + sc->ceilingz += sc->extra; + if(sc->ceilingz >= s->z) + { + sc->ceilingz = s->z; + KILLIT(i); + } + } + else + { + sc->floorz -= sc->extra; + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz -= sc->extra; + if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z -= sc->extra; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + if(sc->floorz <= s->z) + { + sc->floorz = s->z; + KILLIT(i); + } + } + } + + t[2]++; + if(t[2] >= s->hitag) + { + t[2] = 0; + t[0] = 0; + } + } + break; + + case 19: //Battlestar galactia shields + + if(t[0]) + { + if(t[0] == 1) + { + t[0]++; + x = sc->wallptr; + q = x+sc->wallnum; + for(j=x;j= 0) + { + wall[wall[j].nextwall].overpicnum = 0; + wall[wall[j].nextwall].cstat &= (128+32+8+4+2); + } + } + } + + if(sc->ceilingz < sc->floorz) + sc->ceilingz += SP; + else + { + sc->ceilingz = sc->floorz; + + j = headspritestat[3]; + while(j >= 0) + { + if(sprite[j].lotag == 0 && sprite[j].hitag==sh) + { + q = sprite[sprite[j].owner].sectnum; + sector[sprite[j].sectnum].floorpal = sector[sprite[j].sectnum].ceilingpal = + sector[q].floorpal; + sector[sprite[j].sectnum].floorshade = sector[sprite[j].sectnum].ceilingshade = + sector[q].floorshade; + + hittype[sprite[j].owner].temp_data[0] = 2; + } + j = nextspritestat[j]; + } + KILLIT(i); + } + } + else //Not hit yet + { + IFHITSECT + { + FTA(8,&ps[myconnectindex]); + + l = headspritestat[3]; + while(l >= 0) + { + x = sprite[l].lotag&0x7fff; + switch( x ) + { + case 0: + if(sprite[l].hitag == sh) + { + q = sprite[l].sectnum; + sector[q].floorshade = + sector[q].ceilingshade = + sprite[sprite[l].owner].shade; + sector[q].floorpal = + sector[q].ceilingpal = + sprite[sprite[l].owner].pal; + } + break; + + case 1: + case 12: + // case 18: + case 19: + + if( sh == sprite[l].hitag ) + if( hittype[l].temp_data[0] == 0 ) + { + hittype[l].temp_data[0] = 1; //Shut them all on + sprite[l].owner = i; + } + + break; + } + l = nextspritestat[l]; + } + } + } + + break; + + case 20: //Extend-o-bridge + + if( t[0] == 0 ) break; + if( t[0] == 1 ) s->xvel = 8; + else s->xvel = -8; + + if( s->xvel ) //Moving + { + x = (s->xvel*sintable[(s->ang+512)&2047])>>14; + l = (s->xvel*sintable[s->ang&2047])>>14; + + t[3] += s->xvel; + + s->x += x; + s->y += l; + + if( t[3] <= 0 || (t[3]>>6) >= (SP>>6) ) + { + s->x -= x; + s->y -= l; + t[0] = 0; + callsound(s->sectnum,i); + break; + } + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + nextj = nextspritesect[j]; + + if( sprite[j].statnum != 3 && sprite[j].zvel == 0) + { + sprite[j].x += x; + sprite[j].y += l; + setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z); + if( sector[sprite[j].sectnum].floorstat&2 ) + if(sprite[j].statnum == 2) + makeitfall(j); + } + j = nextj; + } + + dragpoint((short)t[1],wall[t[1]].x+x,wall[t[1]].y+l); + dragpoint((short)t[2],wall[t[2]].x+x,wall[t[2]].y+l); + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if(ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + ps[p].posx += x; + ps[p].posy += l; + + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + + setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz+PHEIGHT); + } + + sc->floorxpanning-=x>>3; + sc->floorypanning-=l>>3; + + sc->ceilingxpanning-=x>>3; + sc->ceilingypanning-=l>>3; + } + + break; + + case 21: // Cascading effect + + if( t[0] == 0 ) break; + + if( s->ang == 1536 ) + l = (long) &sc->ceilingz; + else + l = (long) &sc->floorz; + + if( t[0] == 1 ) //Decide if the s->sectnum should go up or down + { + s->zvel = ksgn(s->z-*(long *)l) * (SP<<4); + t[0]++; + } + + if( sc->extra == 0 ) + { + *(long *)l += s->zvel; + + if(klabs(*(long *)l-s->z) < 1024) + { + *(long *)l = s->z; + KILLIT(i); //All done + } + } + else sc->extra--; + break; + + case 22: + + if( t[1] ) + { + if(getanimationgoal(§or[t[0]].ceilingz) >= 0) + sc->ceilingz += sc->extra*9; + else t[1] = 0; + } + break; + + case 24: + case 34: + + if(t[4]) break; + + x = (SP*sintable[(s->ang+512)&2047])>>18; + l = (SP*sintable[s->ang&2047])>>18; + + k = 0; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + nextj = nextspritesect[j]; + if(sprite[j].zvel >= 0) + switch(sprite[j].statnum) + { + case 5: + switch(dynamictostatic[sprite[j].picnum]) + { + case BLOODPOOL__STATIC: + case PUKE__STATIC: + case FOOTPRINTS__STATIC: + case FOOTPRINTS2__STATIC: + case FOOTPRINTS3__STATIC: + case FOOTPRINTS4__STATIC: + case BULLETHOLE__STATIC: + case BLOODSPLAT1__STATIC: + case BLOODSPLAT2__STATIC: + case BLOODSPLAT3__STATIC: + case BLOODSPLAT4__STATIC: + sprite[j].xrepeat = sprite[j].yrepeat = 0; + j = nextj; + continue; + case LASERLINE__STATIC: + j = nextj; + continue; + } + case 6: + if(sprite[j].picnum == TRIPBOMB) break; + case 1: + case 0: + if( + sprite[j].picnum == BOLT1 || + sprite[j].picnum == BOLT1+1 || + sprite[j].picnum == BOLT1+2 || + sprite[j].picnum == BOLT1+3 || + sprite[j].picnum == SIDEBOLT1 || + sprite[j].picnum == SIDEBOLT1+1 || + sprite[j].picnum == SIDEBOLT1+2 || + sprite[j].picnum == SIDEBOLT1+3 || + wallswitchcheck(j) + ) + break; + + if( !(sprite[j].picnum >= CRANE && sprite[j].picnum <= (CRANE+3))) + { + if( sprite[j].z > (hittype[j].floorz-(16<<8)) ) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + + sprite[j].x += x>>2; + sprite[j].y += l>>2; + + setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z); + + if( sector[sprite[j].sectnum].floorstat&2 ) + if(sprite[j].statnum == 2) + makeitfall(j); + } + } + break; + } + j = nextj; + } + + p = myconnectindex; + if(ps[p].cursectnum == s->sectnum && ps[p].on_ground) + if( klabs(ps[p].posz-ps[p].truefz) < PHEIGHT+(9<<8) ) + { + fricxv += x<<3; + fricyv += l<<3; + } + + sc->floorxpanning += SP>>7; + + break; + + case 35: + if(sc->ceilingz > s->z) + for(j = 0;j < 8;j++) + { + s->ang += TRAND&511; + k = spawn(i,SMALLSMOKE); + sprite[k].xvel = 96+(TRAND&127); + ssp(k,CLIPMASK0); + setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z); + if( rnd(16) ) + spawn(i,EXPLOSION2); + } + + switch(t[0]) + { + case 0: + sc->ceilingz += s->yvel; + if(sc->ceilingz > sc->floorz) + sc->floorz = sc->ceilingz; + if(sc->ceilingz > s->z+(32<<8)) + t[0]++; + break; + case 1: + sc->ceilingz-=(s->yvel<<2); + if(sc->ceilingz < t[4]) + { + sc->ceilingz = t[4]; + t[0] = 0; + } + break; + } + break; + + case 25: //PISTONS + + if( t[4] == 0 ) break; + + if(sc->floorz <= sc->ceilingz) + s->shade = 0; + else if( sc->ceilingz <= t[3]) + s->shade = 1; + + if(s->shade) + { + sc->ceilingz += SP<<4; + if(sc->ceilingz > sc->floorz) + sc->ceilingz = sc->floorz; + } + else + { + sc->ceilingz -= SP<<4; + if(sc->ceilingz < t[3]) + sc->ceilingz = t[3]; + } + + break; + + case 26: + + s->xvel = 32; + l = (s->xvel*sintable[(s->ang+512)&2047])>>14; + x = (s->xvel*sintable[s->ang&2047])>>14; + + s->shade++; + if( s->shade > 7 ) + { + s->x = t[3]; + s->y = t[4]; + sc->floorz -= ((s->zvel*s->shade)-s->zvel); + s->shade = 0; + } + else + sc->floorz += s->zvel; + + j = headspritesect[s->sectnum]; + while( j >= 0 ) + { + nextj = nextspritesect[j]; + if(sprite[j].statnum != 3 && sprite[j].statnum != 10) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + + sprite[j].x += l; + sprite[j].y += x; + + sprite[j].z += s->zvel; + setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z); + } + j = nextj; + } + + p = myconnectindex; + if(sprite[ps[p].i].sectnum == s->sectnum && ps[p].on_ground) + { + fricxv += l<<5; + fricyv += x<<5; + } + + for(p = connecthead;p >= 0;p = connectpoint2[p]) + if(sprite[ps[p].i].sectnum == s->sectnum && ps[p].on_ground) + ps[p].posz += s->zvel; + + ms(i); + setsprite(i,s->x,s->y,s->z); + + break; + + + case 27: + + if(ud.recstat == 0) break; + + hittype[i].tempang = s->ang; + + p = findplayer(s,&x); + if( sprite[ps[p].i].extra > 0 && myconnectindex == screenpeek) + { + if( t[0] < 0 ) + { + ud.camerasprite = i; + t[0]++; + } + else if(ud.recstat == 2 && ps[p].newowner == -1) + { + if(cansee(s->x,s->y,s->z,SECT,ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum)) + { + if(x < (long)((unsigned)sh)) + { + ud.camerasprite = i; + t[0] = 999; + s->ang += getincangle(s->ang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>3; + SP = 100+((s->z-ps[p].posz)/257); + + } + else if(t[0] == 999) + { + if(ud.camerasprite == i) + t[0] = 0; + else t[0] = -10; + ud.camerasprite = i; + + } + } + else + { + s->ang = getangle(ps[p].posx-s->x,ps[p].posy-s->y); + + if(t[0] == 999) + { + if(ud.camerasprite == i) + t[0] = 0; + else t[0] = -20; + ud.camerasprite = i; + } + } + } + } + break; + case 28: + if(t[5] > 0) + { + t[5]--; + break; + } + + if(T1 == 0) + { + p = findplayer(s,&x); + if( x > 15500 ) + break; + T1 = 1; + T2 = 64 + (TRAND&511); + T3 = 0; + } + else + { + T3++; + if(T3 > T2) + { + T1 = 0; + ps[screenpeek].visibility = ud.const_visibility; + break; + } + else if( T3 == (T2>>1) ) + spritesound(THUNDER,i); + else if(T3 == (T2>>3) ) + spritesound(LIGHTNING_SLAP,i); + else if( T3 == (T2>>2) ) + { + j = headspritestat[0]; + while(j >= 0) + { + if( sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag) + sprite[j].cstat |= 32768; + j = nextspritestat[j]; + } + } + else if(T3 > (T2>>3) && T3 < (T2>>2) ) + { + if( cansee(s->x,s->y,s->z,s->sectnum,ps[screenpeek].posx,ps[screenpeek].posy,ps[screenpeek].posz,ps[screenpeek].cursectnum ) ) + j = 1; + else j = 0; + + if( rnd(192) && (T3&1) ) + { + if(j) + ps[screenpeek].visibility = 0; + } + else if(j) + ps[screenpeek].visibility = ud.const_visibility; + + j = headspritestat[0]; + while(j >= 0) + { + if( sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag) + { + if ( rnd(32) && (T3&1) ) + { + sprite[j].cstat &= 32767; + spawn(j,SMALLSMOKE); + + p = findplayer(s,&x); + x = ldist(&sprite[ps[p].i], &sprite[j]); + if( x < 768 ) + { + if(!isspritemakingsound(ps[p].i,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,ps[p].i); + spritesound(SHORT_CIRCUIT,ps[p].i); + sprite[ps[p].i].extra -= 8+(TRAND&7); + ps[p].pals_time = 32; + ps[p].pals[0] = 16; + ps[p].pals[1] = 0; + ps[p].pals[2] = 0; + } + break; + } + else sprite[j].cstat |= 32768; + } + + j = nextspritestat[j]; + } + } + } + break; + case 29: + s->hitag += 64; + l = mulscale12((long)s->yvel,sintable[s->hitag&2047]); + sc->floorz = s->z + l; + break; + case 31: // True Drop Floor + if(t[0] == 1) + { + // Choose dir + + if(t[3] > 0) + { + t[3]--; + break; + } + + if(t[2] == 1) // Retract + { + if(SA != 1536) + { + if( klabs( sc->floorz - s->z ) < SP ) + { + sc->floorz = s->z; + t[2] = 0; + t[0] = 0; + t[3] = s->hitag; + callsound(s->sectnum,i); + } + else + { + l = ksgn(s->z-sc->floorz)*SP; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz += l; + if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if( klabs( sc->floorz - t[1] ) < SP ) + { + sc->floorz = t[1]; + callsound(s->sectnum,i); + t[2] = 0; + t[0] = 0; + t[3] = s->hitag; + } + else + { + l = ksgn(t[1]-sc->floorz)*SP; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz += l; + if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 ) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + break; + } + + if( (s->ang&2047) == 1536) + { + if( klabs( s->z-sc->floorz ) < SP ) + { + callsound(s->sectnum,i); + t[0] = 0; + t[2] = 1; + t[3] = s->hitag; + } + else + { + l = ksgn(s->z-sc->floorz)*SP; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz += l; + if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 ) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if( klabs( sc->floorz-t[1] ) < SP ) + { + t[0] = 0; + callsound(s->sectnum,i); + t[2] = 1; + t[3] = s->hitag; + } + else + { + l = ksgn(s->z-t[1])*SP; + sc->floorz -= l; + + j = headspritesect[s->sectnum]; + while(j >= 0) + { + if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if( ps[sprite[j].yvel].on_ground == 1 ) + ps[sprite[j].yvel].posz -= l; + if(sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 ) + { + hittype[j].bposz = sprite[j].z -= l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + } + break; + + case 32: // True Drop Ceiling + if(t[0] == 1) + { + // Choose dir + + if(t[2] == 1) // Retract + { + if(SA != 1536) + { + if( klabs( sc->ceilingz - s->z ) < + (SP<<1) ) + { + sc->ceilingz = s->z; + callsound(s->sectnum,i); + t[2] = 0; + t[0] = 0; + } + else sc->ceilingz += + ksgn(s->z-sc->ceilingz)*SP; + } + else + { + if( klabs( sc->ceilingz - t[1] ) < + (SP<<1) ) + { + sc->ceilingz = t[1]; + callsound(s->sectnum,i); + t[2] = 0; + t[0] = 0; + } + else sc->ceilingz += + ksgn(t[1]-sc->ceilingz)*SP; + } + break; + } + + if( (s->ang&2047) == 1536) + { + if( klabs(sc->ceilingz-s->z ) < + (SP<<1) ) + { + t[0] = 0; + t[2] = !t[2]; + callsound(s->sectnum,i); + sc->ceilingz = s->z; + } + else sc->ceilingz += + ksgn(s->z-sc->ceilingz)*SP; + } + else + { + if( klabs(sc->ceilingz-t[1] ) < (SP<<1) ) + { + t[0] = 0; + t[2] = !t[2]; + callsound(s->sectnum,i); + } + else sc->ceilingz -= ksgn(s->z-t[1])*SP; + } + } + break; + + case 33: + if( earthquaketime > 0 && (TRAND&7) == 0 ) + RANDOMSCRAP; + break; + case 36: + + if( t[0] ) + { + if( t[0] == 1 ) + shoot(i,sc->extra); + else if( t[0] == 26*5 ) + t[0] = 0; + t[0]++; + } + break; + + case 128: //SE to control glass breakage + + wal = &wall[t[2]]; + + if(wal->cstat|32) + { + wal->cstat &= (255-32); + wal->cstat |= 16; + if(wal->nextwall >= 0) + { + wall[wal->nextwall].cstat &= (255-32); + wall[wal->nextwall].cstat |= 16; + } + } + else break; + + wal->overpicnum++; + if(wal->nextwall >= 0) + wall[wal->nextwall].overpicnum++; + + if(t[0] < t[1]) t[0]++; + else + { + wal->cstat &= (128+32+8+4+2); + if(wal->nextwall >= 0) + wall[wal->nextwall].cstat &= (128+32+8+4+2); + KILLIT(i); + } + break; + + case 130: + if(t[0] > 80) { KILLIT(i); } + else t[0]++; + + x = sc->floorz-sc->ceilingz; + + if( rnd(64) ) + { + k = spawn(i,EXPLOSION2); + sprite[k].xrepeat = sprite[k].yrepeat = 2+(TRAND&7); + sprite[k].z = sc->floorz-(TRAND%x); + sprite[k].ang += 256-(TRAND%511); + sprite[k].xvel = TRAND&127; + ssp(k,CLIPMASK0); + } + break; + case 131: + if(t[0] > 40) { KILLIT(i); } + else t[0]++; + + x = sc->floorz-sc->ceilingz; + + if( rnd(32) ) + { + k = spawn(i,EXPLOSION2); + sprite[k].xrepeat = sprite[k].yrepeat = 2+(TRAND&3); + sprite[k].z = sc->floorz-(TRAND%x); + sprite[k].ang += 256-(TRAND%511); + sprite[k].xvel = TRAND&127; + ssp(k,CLIPMASK0); + } + break; + } +BOLT: + i = nexti; + } + + //Sloped sin-wave floors! + for(i=headspritestat[3];i>=0;i=nextspritestat[i]) + { + s = &sprite[i]; + if (s->lotag != 29) continue; + sc = §or[s->sectnum]; + if (sc->wallnum != 4) continue; + wal = &wall[sc->wallptr+2]; + alignflorslope(s->sectnum,wal->x,wal->y,sector[wal->nextsector].floorz); + } +} + diff --git a/polymer/eduke32/source/anim.c b/polymer/eduke32/source/anim.c new file mode 100644 index 000000000..b56d5c040 --- /dev/null +++ b/polymer/eduke32/source/anim.c @@ -0,0 +1,292 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "animlib.h" + +void endanimsounds(long fr) +{ + switch(ud.volume_number) + { + case 0:break; + case 1: + switch(fr) + { + case 1: + sound(WIND_AMBIENCE); + break; + case 26: + sound(ENDSEQVOL2SND1); + break; + case 36: + sound(ENDSEQVOL2SND2); + break; + case 54: + sound(THUD); + break; + case 62: + sound(ENDSEQVOL2SND3); + break; + case 75: + sound(ENDSEQVOL2SND4); + break; + case 81: + sound(ENDSEQVOL2SND5); + break; + case 115: + sound(ENDSEQVOL2SND6); + break; + case 124: + sound(ENDSEQVOL2SND7); + break; + } + break; + case 2: + switch(fr) + { + case 1: + sound(WIND_REPEAT); + break; + case 98: + sound(DUKE_GRUNT); + break; + case 82+20: + sound(THUD); + sound(SQUISHED); + break; + case 104+20: + sound(ENDSEQVOL3SND3); + break; + case 114+20: + sound(ENDSEQVOL3SND2); + break; + case 158: + sound(PIPEBOMB_EXPLODE); + break; + } + break; + } +} + +void logoanimsounds(long fr) +{ + switch(fr) + { + case 1: + sound(FLY_BY); + break; + case 19: + sound(PIPEBOMB_EXPLODE); + break; + } +} + +void intro4animsounds(long fr) +{ + switch(fr) + { + case 1: + sound(INTRO4_B); + break; + case 12: + case 34: + sound(SHORT_CIRCUIT); + break; + case 18: + sound(INTRO4_5); + break; + } +} + +void first4animsounds(long fr) +{ + switch(fr) + { + case 1: + sound(INTRO4_1); + break; + case 12: + sound(INTRO4_2); + break; + case 7: + sound(INTRO4_3); + break; + case 26: + sound(INTRO4_4); + break; + } +} + +void intro42animsounds(long fr) +{ + switch(fr) + { + case 10: + sound(INTRO4_6); + break; + } +} + +void endanimvol41(long fr) +{ + switch(fr) + { + case 3: + sound(DUKE_UNDERWATER); + break; + case 35: + sound(VOL4ENDSND1); + break; + } +} + +void endanimvol42(long fr) +{ + switch(fr) + { + case 11: + sound(DUKE_UNDERWATER); + break; + case 20: + sound(VOL4ENDSND1); + break; + case 39: + sound(VOL4ENDSND2); + break; + case 50: + FX_StopAllSounds(); + break; + } +} + +void endanimvol43(long fr) +{ + switch(fr) + { + case 1: + sound(BOSS4_DEADSPEECH); + break; + case 40: + sound(VOL4ENDSND1); + sound(DUKE_UNDERWATER); + break; + case 50: + sound(BIGBANG); + break; + } +} + +void playanm(char *fn,char t) +{ + char *animbuf, *palptr; + long i, j, k, length=0, numframes=0; + int32 handle=-1; + + // return; + + if(t != 7 && t != 9 && t != 10 && t != 11) + KB_FlushKeyboardQueue(); + + if( KB_KeyWaiting() ) + { + FX_StopAllSounds(); + goto ENDOFANIMLOOP; + } + + handle = kopen4load(fn,0); + if(handle == -1) return; + length = kfilelength(handle); + + walock[TILE_ANIM] = 219+t; + + allocache((long *)&animbuf,length,&walock[TILE_ANIM]); + + tilesizx[TILE_ANIM] = 200; + tilesizy[TILE_ANIM] = 320; + + kread(handle,animbuf,length); + kclose(handle); + + ANIM_LoadAnim (animbuf); + numframes = ANIM_NumFrames(); + + palptr = ANIM_GetPalette(); + for(i=0;i<256;i++) + { + /* + j = (i<<2); k = j-i; + tempbuf[j+0] = (palptr[k+2]>>2); + tempbuf[j+1] = (palptr[k+1]>>2); + tempbuf[j+2] = (palptr[k+0]>>2); + tempbuf[j+3] = 0; + */ + j = i*3; + tempbuf[j+0] = (palptr[j+0]>>2); + tempbuf[j+1] = (palptr[j+1]>>2); + tempbuf[j+2] = (palptr[j+2]>>2); + } + + //setpalette(0L,256L,tempbuf); + //setbrightness(ud.brightness>>2,tempbuf,2); + setgamepalette(&ps[myconnectindex],tempbuf,2); + + ototalclock = totalclock + 10; + + for(i=1;i=20 && sprite[j].picnum<=59) + { + if(sprite[j].picnum==26) { + sprite[j].xrepeat = 8; sprite[j].yrepeat = 8; + } + else + { + sprite[j].xrepeat = 32; sprite[j].yrepeat = 32; + } + } + + } + + Bstrcpy(levelname,mapname); + pskyoff[0]=0; + for(i=0;i<8;i++) pskyoff[i]=0; + + for(i=0;i 10000 && sector[sectnum].lotag < 32767) + Bsprintf(lo,"%d 1 TIME SOUND",sector[sectnum].lotag); + if(qsetmode != 200) + Bsprintf(tempbuf,"%hu,%s",sector[sectnum].hitag,lo); + else Bstrcpy(tempbuf,lo); + } + return(tempbuf); +} + +const char *ExtGetWallCaption(short wallnum) +{ + long i=0; + + if(!(onnames==2 || onnames==4)) + { + tempbuf[0] = 0; + return(tempbuf); + } + + // HERE + + if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",wall[wallnum].hitag,wall[wallnum].lotag); + } + return(tempbuf); +} //end + +const char *SectorEffectorText(short spritenum) +{ + switch(sprite[spritenum].lotag) + { + case 0: Bsprintf(tempbuf,"SE: ROTATED SECTOR"); break; + case 1: Bsprintf(tempbuf,"SE: PIVOT SPRITE FOR SE 0"); break; + case 2: Bsprintf(tempbuf,"SE: EARTHQUAKE"); break; + case 3: Bsprintf(tempbuf,"SE: RANDOM LIGHTS AFTER SHOT OUT"); break; + case 4: Bsprintf(tempbuf,"SE: RANDOM LIGHTS"); break; + case 6: Bsprintf(tempbuf,"SE: SUBWAY"); break; + case 7: Bsprintf(tempbuf,"SE: TRANSPORT"); break; + case 8: Bsprintf(tempbuf,"SE: UP OPEN DOOR LIGHTS"); break; + case 9: Bsprintf(tempbuf,"SE: DOWN OPEN DOOR LIGHTS"); break; + case 10: Bsprintf(tempbuf,"SE: DOOR AUTO CLOSE (H=DELAY)"); break; + case 11: Bsprintf(tempbuf,"SE: ROTATE SECTOR DOOR"); break; + case 12: Bsprintf(tempbuf,"SE: LIGHT SWITCH"); break; + case 13: Bsprintf(tempbuf,"SE: EXPLOSIVE"); break; + case 14: Bsprintf(tempbuf,"SE: SUBWAY CAR"); break; + case 15: Bsprintf(tempbuf,"SE: SLIDE DOOR (ST 25)"); break; + case 16: Bsprintf(tempbuf,"SE: ROTATE REACTOR SECTOR"); break; + case 17: Bsprintf(tempbuf,"SE: ELEVATOR TRANSPORT (ST 15)"); break; + case 18: Bsprintf(tempbuf,"SE: INCREMENTAL SECTOR RISE/FALL"); break; + case 19: Bsprintf(tempbuf,"SE: CEILING FALL ON EXPLOSION"); break; + case 20: Bsprintf(tempbuf,"SE: BRIDGE (ST 27)"); break; + case 21: Bsprintf(tempbuf,"SE: DROP FLOOR (ST 28)"); break; + case 22: Bsprintf(tempbuf,"SE: TEETH DOOR (ST 29)"); break; + case 23: Bsprintf(tempbuf,"SE: 1-WAY SE7 DESTINATION (H=SE 7)"); break; + case 24: Bsprintf(tempbuf,"SE: CONVAYER BELT"); break; + case 25: Bsprintf(tempbuf,"SE: ENGINE"); break; + case 28: Bsprintf(tempbuf,"SE: LIGHTNING (H= TILE#4890)"); break; + case 27: Bsprintf(tempbuf,"SE: CAMERA FOR PLAYBACK"); break; + case 29: Bsprintf(tempbuf,"SE: FLOAT"); break; + case 30: Bsprintf(tempbuf,"SE: 2 WAY TRAIN (ST=31)"); break; + case 31: Bsprintf(tempbuf,"SE: FLOOR RISE"); break; + case 32: Bsprintf(tempbuf,"SE: CEILING FALL"); break; + case 33: Bsprintf(tempbuf,"SE: SPAWN JIB W/QUAKE"); break; + case 36: Bsprintf(tempbuf,"SE: SKRINK RAY SHOOTER"); break; + default: SpriteName(spritenum,tempbuf); break; + } + return (tempbuf); +} + +const char *ExtGetSpriteCaption(short spritenum) +{ + if((onnames!=5 && onnames!=6 &&(!(onnames==3 || onnames==4 || onnames==7 || onnames==8))) || (onnames==7 && sprite[spritenum].picnum!=1)) + { + tempbuf[0] = 0; + return(tempbuf); + } + + if (onnames==5) + { + switch(sprite[spritenum].picnum) + { + case FIRSTGUNSPRITE: + case CHAINGUNSPRITE : + case RPGSPRITE: + case FREEZESPRITE: + case SHRINKERSPRITE: + case HEAVYHBOMB: + case TRIPBOMBSPRITE: + case SHOTGUNSPRITE: + case DEVISTATORSPRITE: + case FREEZEAMMO: + case AMMO: + case BATTERYAMMO: + case DEVISTATORAMMO: + case RPGAMMO: + case GROWAMMO: + case CRYSTALAMMO: + case HBOMBAMMO: + case AMMOLOTS: + case SHOTGUNAMMO: + case COLA: + case SIXPAK: + case FIRSTAID: + case SHIELD: + case STEROIDS: + case AIRTANK: + case JETPACK: + case HEATSENSOR: + case ACCESSCARD: + case BOOTS: + break; + default: + { + tempbuf[0] = 0; + return(tempbuf); + } + } + } + + if( onnames==6 && sprite[spritenum].picnum != sprite[cursprite].picnum) + { + tempbuf[0] = 0; + return(tempbuf); + } + + tempbuf[0] = 0; + if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) + { + SpriteName(spritenum,lo); + if(lo[0]!=0) + { + if(sprite[spritenum].pal==1) Bsprintf(tempbuf,"%s (MULTIPLAYER)",lo); + else Bsprintf(tempbuf,"%s",lo); + } + } + else + if(sprite[spritenum].picnum==SECTOREFFECTOR) + { + if (onnames==8) + tempbuf[0] = 0; + else + { + Bsprintf(lo,"%s: %hu",SectorEffectorText(spritenum),sprite[spritenum].lotag); + Bsprintf(tempbuf,"%s, %hu",lo,sprite[spritenum].hitag); + } + } + else + { + SpriteName(spritenum,lo); + if (sprite[spritenum].extra != -1) + Bsprintf(tempbuf,"%hu,%hu,%d %s",sprite[spritenum].hitag,sprite[spritenum].lotag,sprite[spritenum].extra,lo); + else + Bsprintf(tempbuf,"%hu,%hu %s",sprite[spritenum].hitag,sprite[spritenum].lotag,lo); + } + return(tempbuf); + +} //end + +//printext16 parameters: +//printext16(long xpos, long ypos, short col, short backcol, +// char name[82], char fontsize) +// xpos 0-639 (top left) +// ypos 0-479 (top left) +// col 0-15 +// backcol 0-15, -1 is transparent background +// name +// fontsize 0=8*8, 1=3*5 + +//drawline16 parameters: +// drawline16(long x1, long y1, long x2, long y2, char col) +// x1, x2 0-639 +// y1, y2 0-143 (status bar is 144 high, origin is top-left of STATUS BAR) +// col 0-15 + +void ExtShowSectorData(short sectnum) //F5 +{ + short statnum=0; + int x,x2,y; + int nexti; + int i,c=0; + int secrets=0; + int totalactors1=0,totalactors2=0,totalactors3=0,totalactors4=0; + int totalrespawn=0; + + if(qsetmode==200) + return; + + for(i=0;ixmax) xmax=x; + } + tempbuf[x]=0; + printext16(xx*4,ydim16+(y*6)+2,11,-1,tempbuf,1); + x=0; y++; + if(y>18) {col++; y=6; xx+=xmax; xmax=0; + } + } + enddrawing(); + + kclose(fp); + +}// end Show2dText + +void Show3dText(char *name) +{ + int i,fp; + char x=0,y=4,xmax=0,xx=0,col=0; + int t; + if((fp=kopen4load(name,0)) == -1) + { + begindrawing(); + printext256(1*4,4*8,whitecol,-1,"ERROR: file not found.",0); + enddrawing(); + return; + } + t=65; + begindrawing(); + while(t!=EOF && col<5) + { + t = 0; + if (kread(fp,&t,1)<=0) + t = EOF; + while(t!=EOF && t!='\n' && x<250) + { + tempbuf[x]=t; + t = 0; if (kread(fp,&t,1)<=0) t = EOF; + x++; if(x>xmax) xmax=x; + } + tempbuf[x]=0; + printext256(xx*4,(y*6)+2,whitecol,-1,tempbuf,1); + x=0; y++; + if(y>18) {col++; y=6; xx+=xmax; xmax=0; + } + } + enddrawing(); + + kclose(fp); +}// end Show3dText + +void ShowHelpText(char *name) +{ + BFILE *fp; + int i,t; + char x=0,y=4,xmax=0,xx=0,col=0; + if((fp=fopenfrompath("helpdoc.txt","rb")) == NULL) + { + begindrawing(); + printext256(1*4,4*8,whitecol,-1,"ERROR: file not found.",0); + enddrawing(); + return; + } + /* + Bfgets(tempbuf,80,fp); + while(!Bfeof(fp) && Bstrcmp(tempbuf,"SectorEffector")) + { + Bfgets(tempbuf,80,fp); + } + */ + y=2; + Bfgets(tempbuf,80,fp); + Bstrcat(tempbuf,"\n"); + begindrawing(); + while(!Bfeof(fp) && !(Bstrcmp(tempbuf,"SectorEffector")==0)) + { + Bfgets(tempbuf,80,fp); + Bstrcat(tempbuf,"\n"); + printext256(x*4,(y*6)+2,whitecol,-1,tempbuf,1); + y++; + } + enddrawing(); + + Bfclose(fp); +}// end ShowHelpText + +void ExtShowSpriteData(short spritenum) //F6 +{ + if (qsetmode != 200) + Show2dText("sehelp.hlp"); + /* if (qsetmode == 200) // In 3D mode + return; + + while (KEY_PRESSED(KEYSC_F6)); + ResetKeys(); + ContextHelp(spritenum); // Get context sensitive help */ +}// end ExtShowSpriteData + +// Floor Over Floor (duke3d) + +// If standing in sector with SE42 or SE44 +// then draw viewing to SE41 and raise all =hi SE43 cielings. + +// If standing in sector with SE43 or SE45 +// then draw viewing to SE40 and lower all =hi SE42 floors. + +int fofsizex = -1; +int fofsizey = -1; +void ResetFOFSize() +{ + if (fofsizex != -1) tilesizx[FOF] = fofsizex; + if (fofsizey != -1) tilesizy[FOF] = fofsizey; +} + +static void ExtSE40Draw(int spnum,long x,long y,long z,short a,short h) +{ + static long tempsectorz[MAXSECTORS]; + static long tempsectorpicnum[MAXSECTORS]; + + int i=0,j=0,k=0; + int floor1=0,floor2=0,ok=0,fofmode=0,draw_both=0; + long offx,offy,offz; + + if(sprite[spnum].ang!=512) return; + + // Things are a little different now, as we allow for masked transparent + // floors and ceilings. So the FOF textures is no longer required + // if (!(gotpic[FOF>>3]&(1<<(FOF&7)))) + // return; + // gotpic[FOF>>3] &= ~(1<<(FOF&7)); + + if (tilesizx[562]) + { + fofsizex = tilesizx[562]; + tilesizx[562] = 0; + } + if (tilesizy[562]) + { + fofsizey = tilesizy[562]; + tilesizy[562] = 0; + } + + floor1=spnum; + + if(sprite[spnum].lotag==42) fofmode=40; + if(sprite[spnum].lotag==43) fofmode=41; + if(sprite[spnum].lotag==44) fofmode=40; + if(sprite[spnum].lotag==45) fofmode=41; + + // fofmode=sprite[spnum].lotag-2; + + // sectnum=sprite[j].sectnum; + // sectnum=cursectnum; + ok++; + + /* recursive? + for(j=0;j= 1024) + offz = sprite[floor2].z; + else if (fofmode==41) + offz = sector[sprite[floor2].sectnum].floorz; + else + offz = sector[sprite[floor2].sectnum].ceilingz; + + if (sprite[floor1].ang >= 1024) + offz -= sprite[floor1].z; + else if (fofmode==40) + offz -= sector[sprite[floor1].sectnum].floorz; + else + offz -= sector[sprite[floor1].sectnum].ceilingz; + + // if(ok==2) { Message("no floor2",RED); return; } + + for(j=0;j 0) //ALT + { + keystatus[67] = 0; + wallsprite=0; + curwall = 0; + curwallnum = 0; + cursearchspritenum = 0; + cursectornum=0; + cursector_lotag = sector[sectnum].lotag; + cursector_lotag=getnumber16("Enter search sector lotag : ", cursector_lotag, 65536L,0); + Bsprintf(tempbuf,"Search sector lotag %d",cursector_lotag); + printmessage16(tempbuf); + } + else EditSectorData(sectnum); +}// end ExtEditSectorData + +void ExtEditWallData(short wallnum) //F8 +{ + if(qsetmode==200) + return; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + wallsprite=1; + curwall = wallnum; + curwallnum = 0; + cursearchspritenum = 0; + cursectornum = 0; + search_lotag = wall[curwall].lotag; + search_hitag = wall[curwall].hitag; + search_lotag=getnumber16("Enter wall search lotag : ", search_lotag, 65536L,0); + search_hitag=getnumber16("Enter wall search hitag : ", search_hitag, 65536L,0); + // Bsprintf(tempbuf,"Current wall %d lo=%d hi=%d", + // curwall,wall[curwall].lotag,wall[curwall].hitag); + Bsprintf(tempbuf,"Search wall lo=%d hi=%d",search_lotag,search_hitag); + printmessage16(tempbuf); + } + else EditWallData(wallnum); +} + +void ExtEditSpriteData(short spritenum) //F8 +{ + if(qsetmode==200) + return; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + wallsprite=2; + cursearchsprite = spritenum; + curwallnum = 0; + cursearchspritenum = 0; + cursectornum = 0; + search_lotag = sprite[cursearchsprite].lotag; + search_hitag = sprite[cursearchsprite].hitag; + search_lotag=getnumber16("Enter sprite search lotag : ", search_lotag, 65536L,0); + search_hitag=getnumber16("Enter sprite search hitag : ", search_hitag, 65536L,0); + Bsprintf(tempbuf,"Search sprite lo=%d hi=%d",search_lotag,search_hitag); + printmessage16(tempbuf); + } + else EditSpriteData(spritenum); +} + +void PrintStatus(char *string,int num,char x,char y,char color) +{ + Bsprintf(tempbuf,"%s %d",string,num); + begindrawing(); + printext16(x*8,ydim16+y*8,color,-1,tempbuf,0); + enddrawing(); +} + +void SpriteName(short spritenum, char *lo2) +{ + Bsprintf(lo2,names[sprite[spritenum].picnum]); +}// end SpriteName + +void ReadPaletteTable() +{ + int i,j,fp; + char lookup_num; + if((fp=kopen4load("lookup.dat",0)) == -1) + { + if((fp=kopen4load("lookup.dat",1)) == -1) + { + initprintf("LOOKUP.DAT not found, creating dummy palette lookups\n"); + for(i=0;i<256;i++) + tempbuf[i] = ((i+32)&255); //remap colors for screwy palette sectors + makepalookup(MAXPALOOKUPS,tempbuf,0,0,0,1); + return; + } + } + initprintf("Loading palette lookups... "); + kread(fp,&num_tables,1); + for(j=0;j 640); + + if(totalclock > lastupdate) + { + mousecol += mouseadd; + if(mousecol >= 30 || mousecol <= 0) + { + mouseadd = -mouseadd; + mousecol += mouseadd; + } + lastupdate = totalclock + 3; + } + + switch(whitecol) + { + case 1: // Shadow Warrior + col = whitecol+mousecol; + break; + case 31: // Duke Nukem 3D + col = whitecol-mousecol; + break; + default: + col = whitecol; + break; + } + + if(col != whitecol) + { + for(i=(j?3:2);i<=(j?7:3);i++) + { + plotpixel(searchx+i,searchy,col); + plotpixel(searchx-i,searchy,col); + plotpixel(searchx,searchy-i,col); + plotpixel(searchx,searchy+i,col); + } + for(i=1;i<=(j?2:1);i++) + { + plotpixel(searchx+i,searchy,whitecol); + plotpixel(searchx-i,searchy,whitecol); + plotpixel(searchx,searchy-i,whitecol); + plotpixel(searchx,searchy+i,whitecol); + } + i=(j?8:4); + plotpixel(searchx+i,searchy,0); + plotpixel(searchx-i,searchy,0); + plotpixel(searchx,searchy-i,0); + plotpixel(searchx,searchy+i,0); + } +} + +int AskIfSure(void) +{ + int retval=0; + + begindrawing(); //{{{ + printext256(0,0,whitecol,0,"Are you sure you want to proceed?",0); + enddrawing(); //}}} + + showframe(1); + + while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) + { + if (handleevents()) { + if (quitevent) { + retval = 0; + break; + } + } + if (keystatus[0x15] != 0) { + keystatus[0x15] = 0; + retval = 0; break; + } + } + while(keystatus[1]) + { + keystatus[1] = 0; + retval = 1; + break; + } + return(retval); +} + +void Keys3d(void) +{ + long i,count,rate,nexti; + short statnum=0; + + char smooshyalign=0, repeatpanalign=0, *ptr, buffer[80]; + short sectnum, nextsectnum, startwall, endwall, dasector, daang; + long j, k, cnt, templong, doubvel, changedir, wallfind[2], daz[2]; + long dashade[2], goalz, xvect, yvect, hiz, loz; + short hitsect, hitwall, hitsprite; + long hitx, hity, hitz, dax, day, hihit, lohit; + long repeatcountx=0,repeatcounty=0; + + /* start Mapster32 */ + + if (sidemode != 0) + { + setviewback(); + rotatesprite(320<<15,200<<15,65536,(horiz-100)<<2,4094,0,0,2+4,0,0,0,0); + lockbyte4094 = 0; + searchx = ydim-1-searchx; + searchx ^= searchy; searchy ^= searchx; searchx ^= searchy; + + // overwritesprite(160L,170L,1153,0,1+2,0); + rotatesprite(160<<16,170<<16,65536,(100-horiz+1024)<<3,1153,0,0,2,0,0,0,0); + + } + + if(usedcount && !helpon) + { + if(searchstat!=3) + { + count=0; + for(i=0;i640?0:1; + i = (ydimgame>>6)+(j<<2); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2,0,-1,"Clipboard",j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1),whitecol,-1,"Clipboard",j); + Bsprintf(tempbuf,"Pic: %d %s",temppicnum,names[temppicnum]); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Shd: %d",tempshade); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Pal: %d",temppal); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Cst: %d",tempcstat); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Lot: %d",templotag); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i+i+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Hit: %d",temphitag); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i+i+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i+i+i+i+i,whitecol,-1,tempbuf,j); + Bsprintf(tempbuf,"Ext: %d",tempextra); + printext256((xdimgame>>6)+2,ydimgame-(ydimgame>>1)+2+i+i+i+i+i+i+i+i,0,-1,tempbuf,j); + printext256((xdimgame>>6),ydimgame-(ydimgame>>1)+i+i+i+i+i+i+i+i,whitecol,-1,tempbuf,j); + enddrawing(); + }// end if usedcount + + if ((totalclock > (lastmessagetime + 120*3))) + { + char msgbuf[2048]; + switch (searchstat) + { + case 0: + case 4: + { + long dax, day, dist; + dax = wall[searchwall].x-wall[wall[searchwall].point2].x; + day = wall[searchwall].y-wall[wall[searchwall].point2].y; + dist = ksqrt(dax*dax+day*day); + Bsprintf(msgbuf,"Wall %d: length:%ld lo:%d hi:%d",searchwall,dist,wall[searchwall].lotag,wall[searchwall].hitag); + _message(msgbuf); + break; + } + case 1: + Bsprintf(msgbuf,"Sector %d ceiling: lo:%s hi:%d",searchsector,ExtGetSectorCaption(searchsector),sector[searchsector].hitag); + _message(msgbuf); + break; + case 2: + Bsprintf(msgbuf,"Sector %d floor: lo:%s hi:%d",searchsector,ExtGetSectorCaption(searchsector),sector[searchsector].hitag); + _message(msgbuf); + break; + case 3: + { + if (strlen(names[sprite[searchwall].picnum]) > 0) { + if (sprite[searchwall].picnum==SECTOREFFECTOR) + Bsprintf(msgbuf,"Sprite %d %s: lo:%d hi:%d",searchwall,SectorEffectorText(searchwall),sprite[searchwall].lotag,sprite[searchwall].hitag); + else Bsprintf(msgbuf,"Sprite %d %s: lo:%d hi:%d ex:%d",searchwall,names[sprite[searchwall].picnum],sprite[searchwall].lotag,sprite[searchwall].hitag,sprite[searchwall].extra); + } + else Bsprintf(msgbuf,"Sprite %d picnum %d: lo:%d hi:%d ex:%d",searchwall,sprite[searchwall].picnum,sprite[searchwall].lotag,sprite[searchwall].hitag,sprite[searchwall].extra); + _message(msgbuf); + break; + } + } + } + + if (keystatus[0x4] > 0) /* 3 (toggle floor-over-floor (cduke3d only) */ + { + floor_over_floor = !floor_over_floor; + if (!floor_over_floor) ResetFOFSize(); + keystatus[0x4] = 0; + } + + if (keystatus[KEYSC_F3]) + { + mlook = 1-mlook; + Bsprintf(tempbuf,"Mouselook: %d",mlook); + message(tempbuf); + keystatus[KEYSC_F3] = 0; + } + + // 'P - Will copy palette to all sectors highlighted with R-Alt key + if (keystatus[KEYSC_QUOTE] && keystatus[KEYSC_P]) // ' P + { + short w, start_wall, end_wall, currsector; + unsigned char pal; + + keystatus[KEYSC_P] = 0; + + if(highlightsectorcnt == -1) + { + message("You didn't select any sectors!"); + return; + } + + pal = (unsigned char)getnumber256("Palette: ",0,MAXPALOOKUPS,0); + if(AskIfSure()) return; + + for (i = 0; i < highlightsectorcnt; i++) + { + currsector = highlightsector[i]; + sector[currsector].ceilingpal = pal; + sector[currsector].floorpal = pal; + // Do all the walls in the sector + start_wall = sector[currsector].wallptr; + end_wall = start_wall + sector[currsector].wallnum; + + for (w = start_wall; w < end_wall; w++) + { + wall[w].pal = pal; + } + } + message("Palettes changed"); + } + + // ;P - Will copy palette to all sectors & sprites within highlighted with R-Alt key + if (keystatus[KEYSC_SEMI] && keystatus[KEYSC_P]) // ; P + { + short w, start_wall, end_wall, currsector; + unsigned char pal; + + keystatus[KEYSC_P] = 0; + + if(highlightsectorcnt == -1) + { + message("You didn't select any sectors!"); + return; + } + + pal = (unsigned char)getnumber256("Palette: ",0,MAXPALOOKUPS,0); + if(AskIfSure()) return; + + for (i = 0; i < highlightsectorcnt; i++) + { + currsector = highlightsector[i]; + sector[currsector].ceilingpal = pal; + sector[currsector].floorpal = pal; + // Do all the walls in the sector + start_wall = sector[currsector].wallptr; + end_wall = start_wall + sector[currsector].wallnum; + for (w = start_wall; w < end_wall; w++) + { + wall[w].pal = pal; + } + for (k=0;k= 0) + { + j = nextspritesect[w]; + sprite[i].pal = pal; + w = j; + } + } + } + message("Palettes changed"); + } + + if (keystatus[KEYSC_SEMI] && keystatus[KEYSC_V]) // ; V + { + short w, start_wall, end_wall, currsector; + unsigned char visval; + + keystatus[KEYSC_V] = 0; + + if(highlightsectorcnt == -1) + { + message("You didn't select any sectors!"); + return; + } + visval = (unsigned char)getnumber256("Visibility of selected sectors: ",sector[searchsector].visibility,255,0); + if(AskIfSure()) return; + + for (i = 0; i < highlightsectorcnt; i++) + { + currsector = highlightsector[i]; + sector[currsector].visibility = visval; + } + message("Visibility changed on all selected sectors"); + } + + + if (keystatus[0xd3] > 0) + { + if (searchstat == 3) + { + deletesprite(searchwall); + updatenumsprites(); + Bsprintf(tempbuf,"Sprite (%d) deleted",searchwall); + message(tempbuf); + asksave = 1; + } + keystatus[0xd3] = 0; + } + + if (keystatus[KEYSC_F6] > 0) //F6 + { + keystatus[KEYSC_F6] = 0; + autospritehelp=!autospritehelp; + Bsprintf(tempbuf,"Automatic SECTOREFFECTOR help: %d",autospritehelp); + message(tempbuf); + } + if (keystatus[KEYSC_F7] > 0) //F7 + { + keystatus[KEYSC_F7] = 0; + autosecthelp=!autosecthelp; + Bsprintf(tempbuf,"Automatic sector tag help: %d",autosecthelp); + message(tempbuf); + + } + + if ((searchstat == 3) && (sprite[searchwall].picnum==SECTOREFFECTOR)) + if (autospritehelp && helpon==0) Show3dText("sehelp.hlp"); + + if (searchstat == 1 || searchstat == 2) + if (autosecthelp && helpon==0) Show3dText("sthelp.hlp"); + + + + if (keystatus[0x33] > 0) // , Search & fix panning to the left (3D) + { + if (searchstat == 3) + { + i = searchwall; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048-1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048-128)&2047); + keystatus[0x33] = 0; + } + Bsprintf(tempbuf,"Sprite (%ld) angle: %d",i,sprite[i].ang); + message(tempbuf); + } + } + if (keystatus[0x34] > 0) // . Search & fix panning to the right (3D) + { + if ((searchstat == 0) || (searchstat == 4)) + { + AutoAlignWalls((long)searchwall,0L); + keystatus[0x34] = 0; + } + if (searchstat == 3) + { + i = searchwall; + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + sprite[i].ang = ((sprite[i].ang+2048+1)&2047); + else + { + sprite[i].ang = ((sprite[i].ang+2048+128)&2047); + keystatus[0x34] = 0; + } + Bsprintf(tempbuf,"Sprite (%ld) angle: %d",i,sprite[i].ang); + message(tempbuf); + } + } + + if ((keystatus[KEYSC_L] > 0) && (keystatus[KEYSC_QUOTE] > 0)) // ' L + { + switch (searchstat) + { + case 1: + strcpy(tempbuf,"Sector ceilingz: "); + sector[searchsector].ceilingz = getnumber256(tempbuf,sector[searchsector].ceilingz,8388608,1); + if (!(sector[searchsector].ceilingstat&2)) + sector[searchsector].ceilingheinum = 0; + + strcpy(tempbuf,"Sector ceiling slope: "); + sector[searchsector].ceilingheinum = getnumber256(tempbuf,sector[searchsector].ceilingheinum,8388608,1); + break; + case 2: + strcpy(tempbuf,"Sector floorz: "); + sector[searchsector].floorz = getnumber256(tempbuf,sector[searchsector].floorz,8388608,1); + if (!(sector[searchsector].floorstat&2)) + sector[searchsector].floorheinum = 0; + strcpy(tempbuf,"Sector floor slope: "); + sector[searchsector].floorheinum = getnumber256(tempbuf,sector[searchsector].floorheinum,8388608,1); + break; + case 3: + strcpy(tempbuf,"Sprite x: "); + sprite[searchwall].x = getnumber256(tempbuf,sprite[searchwall].x,131072,1); + strcpy(tempbuf,"Sprite y: "); + sprite[searchwall].y = getnumber256(tempbuf,sprite[searchwall].y,131072,1); + strcpy(tempbuf,"Sprite z: "); + sprite[searchwall].z = getnumber256(tempbuf,sprite[searchwall].z,8388608,1); + strcpy(tempbuf,"Sprite angle: "); + sprite[searchwall].ang = getnumber256(tempbuf,sprite[searchwall].ang,2048L,0); + break; + } + if (sector[searchsector].ceilingheinum == 0) + sector[searchsector].ceilingstat &= ~2; + else + sector[searchsector].ceilingstat |= 2; + + if (sector[searchsector].floorheinum == 0) + sector[searchsector].floorstat &= ~2; + else + sector[searchsector].floorstat |= 2; + asksave = 1; + keystatus[KEYSC_L] = 0; + } + + if ((keystatus[KEYSC_G] > 0)) // G + { + switch (searchstat) + { + case 0: + strcpy(tempbuf,"Wall picnum: "); + i = getnumber256(tempbuf,wall[searchwall].picnum,MAXTILES-1,0); + if(tilesizx[i] != 0) + wall[searchwall].picnum = i; + break; + case 1: + strcpy(tempbuf,"Sector ceiling picnum: "); + i = getnumber256(tempbuf,sector[searchsector].ceilingpicnum,MAXTILES-1,0); + if(tilesizx[i] != 0) + sector[searchsector].ceilingpicnum = i; + break; + case 2: + strcpy(tempbuf,"Sector floor picnum: "); + i = getnumber256(tempbuf,sector[searchsector].floorpicnum,MAXTILES-1,0); + if(tilesizx[i] != 0) + sector[searchsector].floorpicnum = i; + break; + case 3: + strcpy(tempbuf,"Sprite picnum: "); + i = getnumber256(tempbuf,sprite[searchwall].picnum,MAXTILES-1,0); + if(tilesizx[i] != 0) + sprite[searchwall].picnum = i; + break; + case 4: + strcpy(tempbuf,"Masked wall picnum: "); + i = getnumber256(tempbuf,wall[searchwall].overpicnum,MAXTILES-1,0); + if(tilesizx[i] != 0) + wall[searchwall].overpicnum = i; + break; + } + asksave = 1; + keystatus[KEYSC_G] = 0; + } + + getzrange(posx,posy,posz,cursectnum,&hiz,&hihit,&loz,&lohit,128L,CLIPMASK0); + + if (keystatus[KEYSC_CAPS] > 0) + { + zmode++; + if (zmode == 3) zmode = 0; + else if (zmode == 1) zlock = (loz-posz)&0xfffffc00; + if (zmode == 0) message("Zmode = Gravity"); + else if (zmode == 1) message("Zmode = Locked/Sector"); + else if (zmode == 2) message("Zmode = Locked/Free"); + keystatus[KEYSC_CAPS] = 0; + } + + + + if (keystatus[KEYSC_B] > 0) // B (clip Blocking xor) (3D) + { + if (searchstat == 3) + { + sprite[searchwall].cstat ^= 1; + // sprite[searchwall].cstat &= ~256; + // sprite[searchwall].cstat |= ((sprite[searchwall].cstat&1)<<8); + sprintf(getmessage,"Sprite (%d) blocking %s",searchwall,sprite[searchwall].cstat&1?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + else + { + wall[searchwall].cstat ^= 1; + // wall[searchwall].cstat &= ~64; + if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[searchwall].nextwall].cstat &= ~(1+64); + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&1); + } + sprintf(getmessage,"Wall (%d) blocking %s",searchwall,wall[searchwall].cstat&1?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + keystatus[KEYSC_B] = 0; + } + if (keystatus[KEYSC_T] > 0) // T (transluscence for sprites/masked walls) + { + if (searchstat == 1) //Set masked/transluscent ceilings/floors + { + i = (sector[searchsector].ceilingstat&(128+256)); + sector[searchsector].ceilingstat &= ~(128+256); + switch(i) + { + case 0: sector[searchsector].ceilingstat |= 128; break; + case 128: sector[searchsector].ceilingstat |= 256; break; + case 256: sector[searchsector].ceilingstat |= 384; break; + case 384: sector[searchsector].ceilingstat |= 0; break; + } + asksave = 1; + } + if (searchstat == 2) + { + i = (sector[searchsector].floorstat&(128+256)); + sector[searchsector].floorstat &= ~(128+256); + switch(i) + { + case 0: sector[searchsector].floorstat |= 128; break; + case 128: sector[searchsector].floorstat |= 256; break; + case 256: sector[searchsector].floorstat |= 384; break; + case 384: sector[searchsector].floorstat |= 0; break; + } + asksave = 1; + } + + if ((keystatus[KEYSC_QUOTE]) > 0) + { + switch (searchstat) + { + case 0: case 4: + strcpy(buffer,"Wall lotag: "); + wall[searchwall].lotag = getnumber256(buffer,(long)wall[searchwall].lotag,65536L,0); + break; + case 1: + strcpy(buffer,"Sector lotag: "); + sector[searchsector].lotag = getnumber256(buffer,(long)sector[searchsector].lotag,65536L,0); + break; + case 2: + strcpy(buffer,"Sector lotag: "); + sector[searchsector].lotag = getnumber256(buffer,(long)sector[searchsector].lotag,65536L,0); + break; + case 3: + strcpy(buffer,"Sprite lotag: "); + sprite[searchwall].lotag = getnumber256(buffer,(long)sprite[searchwall].lotag,65536L,0); + break; + } + } + else + { + if (searchstat == 3) + { + if ((sprite[searchwall].cstat&2) == 0) + sprite[searchwall].cstat |= 2; + else if ((sprite[searchwall].cstat&512) == 0) + sprite[searchwall].cstat |= 512; + else + sprite[searchwall].cstat &= ~(2+512); + asksave = 1; + } + if (searchstat == 4) + { + if ((wall[searchwall].cstat&128) == 0) + wall[searchwall].cstat |= 128; + else if ((wall[searchwall].cstat&512) == 0) + wall[searchwall].cstat |= 512; + else + wall[searchwall].cstat &= ~(128+512); + + if (wall[searchwall].nextwall >= 0) + { + wall[wall[searchwall].nextwall].cstat &= ~(128+512); + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&(128+512)); + } + asksave = 1; + } + } + keystatus[KEYSC_T] = 0; + } + + + if (keystatus[KEYSC_M] > 0 && (keystatus[KEYSC_QUOTE]) > 0) // M + { + switch (searchstat) + { + case 0: case 4: + strcpy(buffer,"Wall extra: "); + wall[searchwall].extra = getnumber256(buffer,(long)wall[searchwall].extra,65536L,1); + break; + case 1: + strcpy(buffer,"Sector extra: "); + sector[searchsector].extra = getnumber256(buffer,(long)sector[searchsector].extra,65536L,1); + break; + case 2: + strcpy(buffer,"Sector extra: "); + sector[searchsector].extra = getnumber256(buffer,(long)sector[searchsector].extra,65536L,1); + break; + case 3: + strcpy(buffer,"Sprite extra: "); + sprite[searchwall].extra = getnumber256(buffer,(long)sprite[searchwall].extra,65536L,1); + break; + } + asksave = 1; + keystatus[KEYSC_M] = 0; + } + + if (keystatus[KEYSC_1] > 0) // 1 (make 1-way wall) + { + if (searchstat != 3) + { + wall[searchwall].cstat ^= 32; + sprintf(getmessage,"Wall (%d) 1 side masking %s",searchwall,wall[searchwall].cstat&32?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + else + { + sprite[searchwall].cstat ^= 64; + i = sprite[searchwall].cstat; + if ((i&48) == 32) + { + sprite[searchwall].cstat &= ~8; + if ((i&64) > 0) + if (posz > sprite[searchwall].z) + sprite[searchwall].cstat |= 8; + } + asksave = 1; + sprintf(getmessage,"Sprite (%d) 1 sided %s",searchwall,sprite[searchwall].cstat&64?"ON":"OFF"); + message(getmessage); + + } + keystatus[KEYSC_1] = 0; + } + if (keystatus[KEYSC_2] > 0) // 2 (bottom wall swapping) + { + if (searchstat != 3) + { + wall[searchwall].cstat ^= 2; + sprintf(getmessage,"Wall (%d) bottom texture swap %s",searchwall,wall[searchwall].cstat&2?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + keystatus[KEYSC_2] = 0; + } + if (keystatus[KEYSC_O] > 0) // O (top/bottom orientation - for doors) + { + if ((searchstat == 0) || (searchstat == 4)) + { + wall[searchwall].cstat ^= 4; + asksave = 1; + } + if (searchstat == 3) // O (ornament onto wall) (2D) + { + asksave = 1; + i = searchwall; + + hitscan(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum, + sintable[(sprite[i].ang+2560+1024)&2047], + sintable[(sprite[i].ang+2048+1024)&2047], + 0, + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + sprite[i].x = hitx; + sprite[i].y = hity; + sprite[i].z = hitz; + changespritesect(i,hitsect); + if (hitwall >= 0) + sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047); + + //Make sure sprite's in right sector + if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0) + { + j = wall[hitwall].point2; + sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y); + sprite[i].y += ksgn(wall[j].x-wall[hitwall].x); + } + } + keystatus[KEYSC_O] = 0; + } + if (keystatus[KEYSC_M] > 0) // M (masking walls) + { + if (searchstat != 3) + { + i = wall[searchwall].nextwall; + templong = (keystatus[0x2a]|keystatus[0x36]); + if (i >= 0) + { + wall[searchwall].cstat ^= 16; + sprintf(getmessage,"Wall (%d) masking %s",searchwall,wall[searchwall].cstat&16?"ON":"OFF"); + message(getmessage); + if ((wall[searchwall].cstat&16) > 0) + { + wall[searchwall].cstat &= ~8; + if (templong == 0) + { + wall[i].cstat |= 8; //auto other-side flip + wall[i].cstat |= 16; + wall[i].overpicnum = wall[searchwall].overpicnum; + } + } + else + { + wall[searchwall].cstat &= ~8; + if (templong == 0) + { + wall[i].cstat &= ~8; //auto other-side unflip + wall[i].cstat &= ~16; + } + } + wall[searchwall].cstat &= ~32; + if (templong == 0) wall[i].cstat &= ~32; + asksave = 1; + } + } + keystatus[KEYSC_M] = 0; + } + + if (keystatus[KEYSC_H] > 0) // H (hitscan sensitivity) + { + if ((keystatus[KEYSC_QUOTE]) > 0) + { + switch (searchstat) + { + case 0: case 4: + strcpy(buffer,"Wall hitag: "); + wall[searchwall].hitag = getnumber256(buffer,(long)wall[searchwall].hitag,65536L,0); + break; + case 1: + strcpy(buffer,"Sector hitag: "); + sector[searchsector].hitag = getnumber256(buffer,(long)sector[searchsector].hitag,65536L,0); + break; + case 2: + strcpy(buffer,"Sector hitag: "); + sector[searchsector].hitag = getnumber256(buffer,(long)sector[searchsector].hitag,65536L,0); + break; + case 3: + strcpy(buffer,"Sprite hitag: "); + sprite[searchwall].hitag = getnumber256(buffer,(long)sprite[searchwall].hitag,65536L,0); + break; + } + } + + else + { + + if (searchstat == 3) + { + sprite[searchwall].cstat ^= 256; + sprintf(getmessage,"Sprite (%d) hitscan sensitivity %s",searchwall,sprite[searchwall].cstat&256?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + else + { + wall[searchwall].cstat ^= 64; + + if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0)) + { + wall[wall[searchwall].nextwall].cstat &= ~64; + wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&64); + } + sprintf(getmessage,"Wall (%d) hitscan sensitivity %s",searchwall,wall[searchwall].cstat&64?"ON":"OFF"); + message(getmessage); + + asksave = 1; + } + } + keystatus[KEYSC_H] = 0; + } + + smooshyalign = keystatus[0x4c]; + repeatpanalign = (keystatus[0x2a]|keystatus[0x36]|(bstatus&2)); + + if(bstatus&4) + { + if(bstatus&1) + { + searchit = 0; + if (searchx != osearchx) + { + if ((repeatcountx == 0) || (repeatcountx > 16)) + { + changedir = 0; + if (osearchx > searchx) changedir = -1; + if (searchx > osearchx) changedir = 1; + + if ((searchstat == 0) || (searchstat == 4)) + { + if(!(wall[searchwall].cstat&8)) changedir = -changedir; + if (repeatpanalign == 0) + wall[searchwall].xrepeat = changechar(wall[searchwall].xrepeat,changedir,smooshyalign,1); + else + wall[searchwall].xpanning = changechar(wall[searchwall].xpanning,changedir,smooshyalign,0); + } + if ((searchstat == 1) || (searchstat == 2)) + { + if (searchstat == 1) + sector[searchsector].ceilingxpanning = changechar(sector[searchsector].ceilingxpanning,changedir,smooshyalign,0); + else + sector[searchsector].floorxpanning = changechar(sector[searchsector].floorxpanning,changedir,smooshyalign,0); + } + if (searchstat == 3) + { + sprite[searchwall].xrepeat = changechar(sprite[searchwall].xrepeat,changedir,smooshyalign,1); + if (sprite[searchwall].xrepeat < 4) + sprite[searchwall].xrepeat = 4; + } + asksave = 1; + repeatcountx = max(1,repeatcountx); + } + repeatcountx += (synctics>>1); + searchx = osearchx; + } + else + repeatcountx = 0; + + if (searchy != osearchy) + { + if ((repeatcounty == 0) || (repeatcounty > 16)) + { + changedir = 0; + if (osearchy < searchy) changedir = -1; + if (searchy < osearchy) changedir = 1; + + if ((searchstat == 0) || (searchstat == 4)) + { + if(wall[searchwall].cstat&4) changedir = -changedir; + if (repeatpanalign == 0) + wall[searchwall].yrepeat = changechar(wall[searchwall].yrepeat,changedir,smooshyalign,1); + else + wall[searchwall].ypanning = changechar(wall[searchwall].ypanning,changedir,smooshyalign,0); + } + if ((searchstat == 1) || (searchstat == 2)) + { + if (searchstat == 1) + sector[searchsector].ceilingypanning = changechar(sector[searchsector].ceilingypanning,changedir,smooshyalign,0); + else + sector[searchsector].floorypanning = changechar(sector[searchsector].floorypanning,changedir,smooshyalign,0); + } + if (searchstat == 3) + { + sprite[searchwall].yrepeat = changechar(sprite[searchwall].yrepeat,changedir,smooshyalign,1); + if (sprite[searchwall].yrepeat < 4) + sprite[searchwall].yrepeat = 4; + } + asksave = 1; + repeatcounty = max(1,repeatcounty); + } + searchy = osearchy; + repeatcounty += (synctics>>1); + //} + } + else + repeatcounty = 0; + } + if (bstatus&16) // - + { + mouseb &= ~16; + bstatus &= ~16; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL + { + if (visibility < 16384) visibility += visibility; + } + else + { + if ((keystatus[0x2a]|keystatus[0x36]) == 0) + k = 16; else k = 1; + + if (highlightsectorcnt >= 0) + for(i=0;i 0) + { + for(i=0;i 0) + { + sector[searchsector].visibility++; + if (sector[searchsector].visibility == 240) + sector[searchsector].visibility = 239; + k--; + } + asksave = 1; + } + } + else + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) //ALT + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL + { + if (visibility > 32) visibility >>= 1; + } + else + { + if ((keystatus[0x2a]|keystatus[0x36]) == 0) + k = 16; else k = 1; + + if (highlightsectorcnt >= 0) + for(i=0;i 0) + { + for(i=0;i 0) + { + sector[searchsector].visibility--; + if (sector[searchsector].visibility == 239) + sector[searchsector].visibility = 240; + k--; + } + asksave = 1; + } + } + else + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) // mousewheel, -, and +, cycle picnum + { + j = i = (keystatus[KEYSC_EQUAL]|(bstatus&32))?1:-1; + switch (searchstat) + { + case 0: + while(!tilesizx[wall[searchwall].picnum]||!tilesizy[wall[searchwall].picnum]||j) { + if(wall[searchwall].picnum+i >= MAXTILES) wall[searchwall].picnum = 0; + else if(wall[searchwall].picnum+i < 0) wall[searchwall].picnum = MAXTILES-1; + else wall[searchwall].picnum += i; + j = 0; + } + break; + case 1: + while(!tilesizx[sector[searchsector].ceilingpicnum]||!tilesizy[sector[searchsector].ceilingpicnum]||j) { + if(sector[searchsector].ceilingpicnum+i >= MAXTILES) sector[searchsector].ceilingpicnum = 0; + else if(sector[searchsector].ceilingpicnum+i < 0) sector[searchsector].ceilingpicnum = MAXTILES-1; + else sector[searchsector].ceilingpicnum += i; + j = 0; + } + break; + case 2: + while(!tilesizx[sector[searchsector].floorpicnum]||!tilesizy[sector[searchsector].floorpicnum]||j) { + if(sector[searchsector].floorpicnum+i >= MAXTILES) sector[searchsector].floorpicnum = 0; + else if(sector[searchsector].floorpicnum+i < 0) sector[searchsector].floorpicnum = MAXTILES-1; + else sector[searchsector].floorpicnum += i; + j = 0; + } + break; + case 3: + while(!tilesizx[sprite[searchwall].picnum]||!tilesizy[sprite[searchwall].picnum]||j) { + if(sprite[searchwall].picnum+i >= MAXTILES) sprite[searchwall].picnum = 0; + else if(sprite[searchwall].picnum+i < 0) sprite[searchwall].picnum = MAXTILES-1; + else sprite[searchwall].picnum += i; + j = 0; + } + break; + case 4: + while(!tilesizx[wall[searchwall].overpicnum]||!tilesizy[wall[searchwall].overpicnum]||j) { + if(wall[searchwall].overpicnum+i >= MAXTILES) wall[searchwall].overpicnum = 0; + else if(wall[searchwall].overpicnum+i < 0) wall[searchwall].overpicnum = MAXTILES-1; + else wall[searchwall].overpicnum += i; + j = 0; + } + break; + } + asksave = 1; + keystatus[KEYSC_DASH] = keystatus[KEYSC_EQUAL] = 0; + mouseb &= ~(16|32); + } + + if (keystatus[KEYSC_E] > 0) // E (expand) + { + if (searchstat == 1) + { + sector[searchsector].ceilingstat ^= 8; + sprintf(getmessage,"Sector (%d) ceiling texture expansion %s",searchsector,sector[searchsector].ceilingstat&8?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + if (searchstat == 2) + { + sector[searchsector].floorstat ^= 8; + sprintf(getmessage,"Sector (%d) floor texture expansion %s",searchsector,sector[searchsector].floorstat&8?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + keystatus[KEYSC_E] = 0; + } + if (keystatus[KEYSC_R] > 0) // R (relative alignment, rotation) + { + + if (keystatus[KEYSC_QUOTE] > 0) // FRAMERATE TOGGLE + { + + framerateon = !framerateon; + if(framerateon) message("Show framerate ON"); + else message("Show framerate OFF"); + + } + + else + + { + if (searchstat == 1) + { + sector[searchsector].ceilingstat ^= 64; + sprintf(getmessage,"Sector (%d) ceiling texture relativity %s",searchsector,sector[searchsector].ceilingstat&64?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + if (searchstat == 2) + { + sector[searchsector].floorstat ^= 64; + sprintf(getmessage,"Sector (%d) ceiling texture relativity %s",searchsector,sector[searchsector].floorstat&64?"ON":"OFF"); + message(getmessage); + asksave = 1; + } + if (searchstat == 3) + { + i = sprite[searchwall].cstat; + if ((i&48) < 32) i += 16; + + else i &= ~48; + sprite[searchwall].cstat = i; + + if (sprite[searchwall].cstat&16) + sprintf(getmessage,"Sprite (%d) wall aligned",searchwall); + else if (sprite[searchwall].cstat&32) + sprintf(getmessage,"Sprite (%d) floor aligned",searchwall); + else + sprintf(getmessage,"Sprite (%d) un-aligned",searchwall); + message(getmessage); + asksave = 1; + } + } + keystatus[KEYSC_R] = 0; + } + if (keystatus[KEYSC_F] > 0) //F (Flip) + { + keystatus[KEYSC_F] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT-F (relative alignmment flip) + { + if (searchstat != 3) + { + setfirstwall(searchsector,searchwall); + asksave = 1; + } + } + else + { + if ((searchstat == 0) || (searchstat == 4)) + { + i = wall[searchwall].cstat; + i = ((i>>3)&1)+((i>>7)&2); //3-x,8-y + switch(i) + { + case 0: i = 1; break; + case 1: i = 3; break; + case 2: i = 0; break; + case 3: i = 2; break; + } + i = ((i&1)<<3)+((i&2)<<7); + wall[searchwall].cstat &= ~0x0108; + wall[searchwall].cstat |= i; + asksave = 1; + } + if (searchstat == 1) //8-way ceiling flipping (bits 2,4,5) + { + i = sector[searchsector].ceilingstat; + i = (i&0x4)+((i>>4)&3); + switch(i) + { + case 0: i = 6; break; + case 6: i = 3; break; + case 3: i = 5; break; + case 5: i = 1; break; + case 1: i = 7; break; + case 7: i = 2; break; + case 2: i = 4; break; + case 4: i = 0; break; + } + i = (i&0x4)+((i&3)<<4); + sector[searchsector].ceilingstat &= ~0x34; + sector[searchsector].ceilingstat |= i; + asksave = 1; + } + if (searchstat == 2) //8-way floor flipping (bits 2,4,5) + { + i = sector[searchsector].floorstat; + i = (i&0x4)+((i>>4)&3); + switch(i) + { + case 0: i = 6; break; + case 6: i = 3; break; + case 3: i = 5; break; + case 5: i = 1; break; + case 1: i = 7; break; + case 7: i = 2; break; + case 2: i = 4; break; + case 4: i = 0; break; + } + i = (i&0x4)+((i&3)<<4); + sector[searchsector].floorstat &= ~0x34; + sector[searchsector].floorstat |= i; + asksave = 1; + } + if (searchstat == 3) + { + i = sprite[searchwall].cstat; + if (((i&48) == 32) && ((i&64) == 0)) + { + sprite[searchwall].cstat &= ~0xc; + sprite[searchwall].cstat |= ((i&4)^4); + } + else + { + i = ((i>>2)&3); + switch(i) + { + case 0: i = 1; break; + case 1: i = 3; break; + case 2: i = 0; break; + case 3: i = 2; break; + } + i <<= 2; + sprite[searchwall].cstat &= ~0xc; + sprite[searchwall].cstat |= i; + } + asksave = 1; + } + } + } + + if (keystatus[0xc7] > 0) // HOME + updownunits = 256; + else if (keystatus[0xcf] > 0) // END + updownunits = 512; + else + updownunits = 1024; + + if ((keystatus[0xc9] > 0) || ((bstatus&2) && (bstatus&32))) // PGUP + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i 0) //CTRL - put sprite on ceiling + { + sprite[searchwall].z = getceilzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y); + if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1); + if ((sprite[searchwall].cstat&48) != 32) + sprite[searchwall].z += ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<2); + } + else + { + k = 0; + if (highlightcnt >= 0) + for(i=0;i 0) || ((bstatus&2) && (bstatus&16))) // PGDN + { + k = 0; + if (highlightsectorcnt >= 0) + { + for(i=0;i sector[searchsector].floorz) + sector[searchsector].ceilingz = sector[searchsector].floorz; + if (searchstat == 3) + { + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL - put sprite on ground + { + sprite[searchwall].z = getflorzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y); + if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1); + } + else + { + k = 0; + if (highlightcnt >= 0) + for(i=0;i 640)); + enddrawing(); + } + } + } + clockval[clockcnt] = i; + clockcnt = ((clockcnt+1)&15); + + tempbuf[0] = 0; + if((bstatus&4) && (bstatus&2)) + Bsprintf(tempbuf,"PAN"); + else if(bstatus&4) + Bsprintf(tempbuf,"SHADE/SIZE"); + else if(bstatus&2) + Bsprintf(tempbuf,"Z"); + else if(bstatus&1) + Bsprintf(tempbuf,"LOCK"); + if(tempbuf[0] != 0) + { + printext256(searchx+4+2,searchy+4+2,0,-1,tempbuf,!(xdimgame > 640)); + printext256(searchx+4,searchy+4,whitecol,-1,tempbuf,!(xdimgame > 640)); + } + if(helpon==1) + { + for(i=0;i 640)))+2,0,-1,Help3d[i],!(xdimgame > 640)); + printext256(0*8,8+(i*(8+(xdimgame > 640))),whitecol,-1,Help3d[i],!(xdimgame > 640)); + enddrawing(); + switch(i) + { + case 8: Bsprintf(tempbuf,"%d",autosave); break; + case 9: Bsprintf(tempbuf,"%s",SKILLMODE[skill]); break; + case 10: Bsprintf(tempbuf,"%d",tabgraphic); break; + case 11: Bsprintf(tempbuf,"%d",framerateon); break; + case 12: Bsprintf(tempbuf,"%s",SPRDSPMODE[nosprites]); break; + case 13: Bsprintf(tempbuf,"%d",shadepreview); break; + case 14: Bsprintf(tempbuf,"%d",purpleon); break; + default : sprintf(tempbuf," "); break; + } + begindrawing(); + if(!strcmp(tempbuf,"0")) + Bsprintf(tempbuf,"OFF"); + else if(!strcmp(tempbuf,"1")) + Bsprintf(tempbuf,"ON"); + else if(!strcmp(tempbuf,"2")) + Bsprintf(tempbuf,"ON (2)"); + + printext256((20+((xdimgame > 640) * 20))*8+2,8+(i*8+(xdimgame > 640))+2,0,-1,tempbuf,!(xdimgame > 640)); + printext256((20+((xdimgame > 640) * 20))*8,8+(i*8+(xdimgame > 640)),whitecol,-1,tempbuf,!(xdimgame > 640)); + enddrawing(); + } + } + + /* if(purpleon) { + begindrawing(); + // printext256(1*4,1*8,whitecol,-1,"Purple ON",0); + sprintf(getmessage,"Purple ON"); + message(getmessage); + enddrawing(); + } + */ + if(sector[cursectnum].lotag==2) + { + if(sector[cursectnum].floorpal==8) SetBOSS1Palette(); + else SetWATERPalette(); + } + else SetGAMEPalette(); + + + //Stick this in 3D part of ExtCheckKeys + //Also choose your own key scan codes + + + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x20]==1) // ' d + /* + { + ShowHelpText("SectorEffector"); + } */ + + { + keystatus[0x20] = 0; + skill++; if(skill>MAXSKILL-1) skill=0; + sprintf(tempbuf,"%s",SKILLMODE[skill]); + // printext256(1*4,1*8,11,-1,tempbuf,0); + message(tempbuf); + } + + begindrawing(); + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x22]==1) // ' g + { + keystatus[0x22] = 0; + tabgraphic++; + if (tabgraphic > 2) tabgraphic = 0; + if(tabgraphic) message("Graphics ON"); + else message("Graphics OFF"); + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x2d]==1) // ' x + { + keystatus[0x2d] = 0; + shadepreview=!shadepreview; + if(shadepreview) message("Sprite shade preview ON"); + else message("Sprite shade preview OFF"); + } + + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x13]==1) // ' r + { + keystatus[0x13] = 0; + framerateon=!framerateon; + if(framerateon) message("Framerate ON"); + else message("Framerate OFF"); + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x11]==1) // ' w + { + keystatus[0x11] = 0; + nosprites++; if(nosprites>3) nosprites=0; + Bsprintf(tempbuf,"%s",SPRDSPMODE[nosprites]); + // printext256(1*4,1*8,whitecol,-1,tempbuf,0); + message(tempbuf); + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x15]==1) // ' y + { + keystatus[0x15] = 0; + purpleon=!purpleon; if(nosprites>3) nosprites=0; + if(purpleon) message("Purple ON"); + else message("Purple OFF"); + } + enddrawing(); + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x2e]==1) // ' C + { + keystatus[0x2e] = 0; + switch (searchstat) + { + case 0: + case 4: + for(i=0;i0) // F2 + { + usedcount=!usedcount; + keystatus[0x3c] = 0; + } + if(keystatus[0x0f]>0) // TAB : USED + { + // usedcount=!usedcount; + + count=0; + for(i=0;i= 256*/ && sprite[i].sectnum != MAXSECTORS) + { + radius = mulscale15(sprite[i].hitag,zoom); + col = 6; + if (i+16384 == pointhighlight) + if (totalclock & 32) col += (2<<2); + drawlinepat = 0xf0f0f0f0; + drawcircle16(halfxdim16+xp1, midydim16+yp1, radius, col); + drawlinepat = 0xffffffff; + } + } + enddrawing(); + + if(keystatus[0x3b]==1 || (keystatus[KEYSC_QUOTE]==1 && keystatus[0x29]==1)) //F1 or ' ~ + { + keystatus[0x3b]=0; + clearmidstatbar16(); + begindrawing(); + for(i=0;i 9) + { + j = 256; + k = 90; + } + printext16(j,ydim16+32+(i*9)-k,11,-1,Help2d[i],0); + } + enddrawing(); + } + + if((keystatus[KEYSC_QUOTE]==1 && keystatus[KEYSC_D]==1)) // ' D delete all sprites of a certain type + { + keystatus[KEYSC_D]=0; + Bsprintf(tempbuf,"Delete all sprites of picnum: "); + i = getnumber16(tempbuf,-1,MAXSPRITES-1,1); + if (i >= 0) + { + for(j=0;j 0) // M (tag) + { + keystatus[0x32] = 0; + if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT + { + if (pointhighlight >= 16384) + { + i = pointhighlight-16384; + Bsprintf(tempbuf,"Sprite (%d) Extra: ",i); + sprite[i].extra = getnumber16(tempbuf,sprite[i].extra,65536L,1); + clearmidstatbar16(); + showspritedata((short)i); + } + else if (linehighlight >= 0) + { + i = linehighlight; + Bsprintf(tempbuf,"Wall (%d) Extra: ",i); + wall[i].extra = getnumber16(tempbuf,wall[i].extra,65536L,1); + clearmidstatbar16(); + showwalldata((short)i); + } + printmessage16(""); + } + else + { + for (i=0;i 0) // /? Reset panning&repeat to 0 + { + if ((ppointhighlight&0xc000) == 16384) + { + if ((keystatus[0x2a]|keystatus[0x36]) > 0) + { + sprite[cursprite].xrepeat = sprite[cursprite].yrepeat; + } + else + { + sprite[cursprite].xrepeat = 64; + sprite[cursprite].yrepeat = 64; + } + } + keystatus[0x35] = 0; + asksave = 1; + } + + if ((keystatus[0x4b]|keystatus[0x4d]) > 0) // 4 & 6 (keypad) + { + smooshyalign = keystatus[0x4c]; + if ((repeatcountx == 0) || (repeatcountx > 16)) + { + changedir = 0; + if (keystatus[0x4b] > 0) changedir = -1; + if (keystatus[0x4d] > 0) changedir = 1; + + if ((ppointhighlight&0xc000) == 16384) + { + sprite[cursprite].xrepeat = changechar(sprite[cursprite].xrepeat,changedir,smooshyalign,1); + if (sprite[cursprite].xrepeat < 4) + sprite[cursprite].xrepeat = 4; + } + asksave = 1; + repeatcountx = max(1,repeatcountx); + } + repeatcountx += synctics; + } + else + repeatcountx = 0; + + if ((keystatus[0x48]|keystatus[0x50]) > 0) // 2 & 8 (keypad) + { + smooshyalign = keystatus[0x4c]; + if ((repeatcounty == 0) || (repeatcounty > 16)) + { + changedir = 0; + if (keystatus[0x48] > 0) changedir = -1; + if (keystatus[0x50] > 0) changedir = 1; + + if ((ppointhighlight&0xc000) == 16384) + { + sprite[cursprite].yrepeat = changechar(sprite[cursprite].yrepeat,changedir,smooshyalign,1); + if (sprite[cursprite].yrepeat < 4) + sprite[cursprite].yrepeat = 4; + } + asksave = 1; + repeatcounty = max(1,repeatcounty); + } + repeatcounty += synctics; + //} + } + else + repeatcounty = 0; + + if (keystatus[0x13] > 0) // R (relative alignment, rotation) + { + if (pointhighlight >= 16384) + { + i = sprite[cursprite].cstat; + if ((i&48) < 32) i += 16; + + else i &= ~48; + sprite[cursprite].cstat = i; + + if (sprite[cursprite].cstat&16) + sprintf(getmessage,"Sprite (%d) is wall aligned",cursprite); + else if (sprite[cursprite].cstat&32) + sprintf(getmessage,"Sprite (%d) is floor aligned",cursprite); + else + sprintf(getmessage,"Sprite (%d) is un-aligned",cursprite); + message(getmessage); + asksave = 1; + + } + keystatus[0x13] = 0; + } + + + if(keystatus[KEYSC_QUOTE] && keystatus[KEYSC_S]) // ' S + { + if (pointhighlight >= 16384) + { + keystatus[0x1f] = 0; + Bsprintf(tempbuf,"Sprite (%d) xrepeat: ",cursprite); + sprite[cursprite].xrepeat=getnumber16(tempbuf, sprite[cursprite].xrepeat, 256,0); + Bsprintf(tempbuf,"Sprite (%d) yrepeat: ",cursprite); + sprite[cursprite].yrepeat=getnumber16(tempbuf, sprite[cursprite].yrepeat, 256,0); + Bsprintf(tempbuf,"Sprite (%d) updated",i); + printmessage16(tempbuf); + } + } + + if(keystatus[KEYSC_QUOTE] && keystatus[KEYSC_F]) // ' F + { + keystatus[KEYSC_F] = 0; + j = 0; + for(i=0;i0) // [ search backward + { + keystatus[0x1a]=0; + if(wallsprite==0) + { + SearchSectorsBackward(); + } + else + + if(wallsprite==1) + { + if(curwallnum>0) curwallnum--; + for(i=curwallnum;i>=0;i--) + { + if( + (wall[i].picnum==wall[curwall].picnum) + &&((search_lotag==0)|| + (search_lotag!=0 && search_lotag==wall[i].lotag)) + &&((search_hitag==0)|| + (search_hitag!=0 && search_hitag==wall[i].hitag)) + ) + { + posx=(wall[i].x)-(( (wall[i].x)-(wall[wall[i].point2].x) )/2); + posy=(wall[i].y)-(( (wall[i].y)-(wall[wall[i].point2].y) )/2); + printmessage16("< Wall search: found"); + // curwallnum--; + keystatus[0x1a]=0; + return; + } + curwallnum--; + } + printmessage16("< Wall search: none found"); + } + else + + if(wallsprite==2) + { + if(cursearchspritenum>0) cursearchspritenum--; + for(i=cursearchspritenum;i>=0;i--) + { + + if( + (sprite[i].picnum==sprite[cursearchsprite].picnum && + sprite[i].statnum==0 ) + &&((search_lotag==0)|| + (search_lotag!=0 && search_lotag==sprite[i].lotag)) + &&((search_hitag==0)|| + (search_hitag!=0 && search_hitag==sprite[i].hitag)) + ) + { + posx=sprite[i].x; + posy=sprite[i].y; + ang= sprite[i].ang; + printmessage16("< Sprite search: found"); + // curspritenum--; + keystatus[0x1a]=0; + return; + } + cursearchspritenum--; + } + printmessage16("< Sprite search: none found"); + } + } + + + if(keystatus[0x1b]>0) // ] search forward + { + keystatus[0x1b]=0; + if(wallsprite==0) + { + SearchSectorsForward(); + } + else + + if(wallsprite==1) + { + if(curwallnum Wall search: found"); + // curwallnum++; + keystatus[0x1b]=0; + return; + } + curwallnum++; + } + printmessage16("> Wall search: none found"); + } + else + + if(wallsprite==2) + { + if(cursearchspritenum Sprite search: found"); + // curspritenum++; + keystatus[0x1b]=0; + return; + } + cursearchspritenum++; + } + printmessage16("> Sprite search: none found"); + } + } + + if (keystatus[0x22] > 0) // G (grid on/off) + { + grid += ((keystatus[0x2a]|keystatus[0x36]) > 0?-1:1); + if (grid == -1 || grid == 9) { + switch(grid) { + case -1: + grid = 8; + break; + case 9: + grid = 0; + break; + } + } + if(!grid) sprintf(tempbuf,"Grid off"); + else sprintf(tempbuf,"Grid size: %d (%d units)",grid,2048>>grid); + printmessage16(tempbuf); + keystatus[0x22] = 0; + } + + if ((totalclock > getmessagetimeoff) && (totalclock > (lastpm16time + 120*3))) + { + long olinehighlight, opointhighlight, ocursectornum; + + updatesector(mousxplc,mousyplc,&cursectornum); + if (pointhighlight >= 16384) + { + char tmpbuf[2048]; + i = pointhighlight-16384; + if (strlen(names[sprite[i].picnum]) > 0) { + if (sprite[i].picnum==SECTOREFFECTOR) + Bsprintf(tmpbuf,"Sprite %d %s: lo:%d hi:%d",i,SectorEffectorText(i),sprite[i].lotag,sprite[i].hitag); + else Bsprintf(tmpbuf,"Sprite %d %s: lo:%d hi:%d ex:%d",i,names[sprite[i].picnum],sprite[i].lotag,sprite[i].hitag,sprite[i].extra); + } + else Bsprintf(tmpbuf,"Sprite %d picnum %d: lo:%d hi:%d ex:%d",i,sprite[i].picnum,sprite[i].lotag,sprite[i].hitag,sprite[i].extra); + _printmessage16(tmpbuf); + } + else if ((linehighlight >= 0) && (sectorofwall(linehighlight) == cursectornum)) + { + long dax, day, dist; + dax = wall[linehighlight].x-wall[wall[linehighlight].point2].x; + day = wall[linehighlight].y-wall[wall[linehighlight].point2].y; + dist = ksqrt(dax*dax+day*day); + Bsprintf(tempbuf,"Wall %d: length:%ld lo:%d hi:%d",linehighlight,dist,wall[linehighlight].lotag,wall[linehighlight].hitag); + _printmessage16(tempbuf); + } + else if (cursectornum >= 0) + { + Bsprintf(tempbuf,"Sector %d: lo:%d hi:%d",cursectornum,sector[cursectornum].lotag,sector[cursectornum].hitag); + _printmessage16(tempbuf); + } + else _printmessage16(""); + } + + if ((keystatus[0x26] > 0) && (keystatus[KEYSC_QUOTE] > 0)) // ' L + { + if (pointhighlight >= 16384) + { + i = pointhighlight - 16384; + Bsprintf(tempbuf,"Sprite %d x: ",i); + sprite[i].x = getnumber16(tempbuf,sprite[i].x,131072,1); + Bsprintf(tempbuf,"Sprite %d y: ",i); + sprite[i].y = getnumber16(tempbuf,sprite[i].y,131072,1); + Bsprintf(tempbuf,"Sprite %d z: ",i); + sprite[i].z = getnumber16(tempbuf,sprite[i].z,8388608,1); + Bsprintf(tempbuf,"Sprite %d angle: ",i); + sprite[i].ang = getnumber16(tempbuf,sprite[i].ang,2048L,0); + Bsprintf(tempbuf,"Sprite %d updated",i); + printmessage16(tempbuf); + } + + else if (pointhighlight <= 16383) + { + i = linehighlight; + Bsprintf(tempbuf,"Wall %d x: ",i); + wall[i].x = getnumber16(tempbuf,wall[i].x,131072,1); + Bsprintf(tempbuf,"Wall %d y: ",i); + wall[i].y = getnumber16(tempbuf,wall[i].y,131072,1); + Bsprintf(tempbuf,"Wall %d updated",i); + printmessage16(tempbuf); + } + + keystatus[0x26] = 0; + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x06]==1) // ' 5 + { + signed char shade; + keystatus[0x06]=0; + + shade=getnumber16("Global parallaxed sky shade: ",0,128,1); + + for(i=0;i>1,255); + } + for(i=0;i>= 1; + sector[i].floorz >>= 1; + } + for(i=0;i>= 1; + wall[i].y >>= 1; + wall[i].yrepeat = min(wall[i].yrepeat<<1,255); + } + for(i=0;i>= 1; + sprite[i].y >>= 1; + sprite[i].z >>= 1; + sprite[i].xrepeat = max(sprite[i].xrepeat>>1,1); + sprite[i].yrepeat = max(sprite[i].yrepeat>>1,1); + } + printmessage16("Map scaled"); + } + + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x04]==1) // ' 3 + { + onnames++; if(onnames>8) onnames=0; + keystatus[0x04]=0; + Bsprintf(tempbuf,"Mode %d %s",onnames,SpriteMode[onnames]); + printmessage16(tempbuf); + // clearmidstatbar16(); + // for(i=0;i=20 && sprite[i].picnum<=59) + { + sprite[i].xrepeat = 32; + sprite[i].yrepeat = 32; + } + } + + } + */ + + // What the fuck is this supposed to do? + + /* Motorcycle ha ha ha + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x06]==1) // ' 5 + { + keystatus[0x06]=0; + sidemode++; if (sidemode > 2) sidemode = 0; + if (sidemode == 1) + { + editstatus = 0; + zmode = 2; + posz = ((sector[cursectnum].ceilingz+sector[cursectnum].floorz)>>1); + } + else + { + editstatus = 1; + zmode = 1; + } + } + */ + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x08]==1) // ' 7 : swap hilo + { + keystatus[0x08]=0; + + if (pointhighlight >= 16384) + { + temp=sprite[cursprite].lotag; + sprite[cursprite].lotag=sprite[cursprite].hitag; + sprite[cursprite].hitag=temp; + Bsprintf(tempbuf,"Sprite %d tags swapped",cursprite); + printmessage16(tempbuf); + } + else if (linehighlight >= 0) + { + temp=wall[linehighlight].lotag; + wall[linehighlight].lotag=wall[linehighlight].hitag; + wall[linehighlight].hitag=temp; + Bsprintf(tempbuf,"Wall %d tags swapped",linehighlight); + printmessage16(tempbuf); + } + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x24]==1) // ' J + { + posx=getnumber16("X-coordinate: ",posx,131072L,1); + posy=getnumber16("Y-coordinate: ",posy,131072L,1); + Bsprintf(tempbuf,"Current pos now (%ld, %ld)",posx,posy); + printmessage16(tempbuf); + keystatus[0x24]=0; + } + +}// end key2d + +void ExtSetupSpecialSpriteCols(void) +{ + short i; + for (i=0;i=0;i--) + sector[i].wallnum = sector[i+1].wallptr-sector[i].wallptr; + sector[numsectors-1].wallnum = numwalls-sector[numsectors-1].wallptr; + + for(i=0;ipicnum<11) tspr->xrepeat=0; + + if(nosprites==1||nosprites==3) + switch(tspr->picnum) + { + case SEENINE : + tspr->xrepeat=0; + } + + if(shadepreview && !(tspr->cstat & 16)) + { + if (sector[tspr->sectnum].ceilingstat&1) + l = sector[tspr->sectnum].ceilingshade; + else + { + l = sector[tspr->sectnum].floorshade; + if (sector[tspr->sectnum].floorpal != 0 && sector[tspr->sectnum].floorpal < num_tables) + tspr->pal=sector[tspr->sectnum].floorpal; + } + if(l < -127) l = -127; + if(l > 126) l = 127; + + tspr->shade = l; + + } + + switch(tspr->picnum) + { + // 5-frame walk + case 1550 : // Shark + frames=5; + // 2-frame walk + case 1445 : // duke kick + case LIZTROOPDUCKING : + case 2030 : // pig shot + case OCTABRAIN : + case PIGCOPDIVE : + case 2190 : // liz capt shot + case BOSS1SHOOT : + case BOSS1LOB : + case LIZTROOPSHOOT : + if(frames==0) frames=2; + + // 4-frame walk + case 1491 : // duke crawl + case LIZTROOP : + case LIZTROOPRUNNING : + case PIGCOP : + case LIZMAN : + case BOSS1 : + case BOSS2 : + case BOSS3 : + case BOSS4 : + case NEWBEAST: + if(frames==0) frames=4; + case LIZTROOPJETPACK : + case DRONE : + case COMMANDER : + case TANK : + case RECON : + if(frames==0) frames = 10; + case CAMERA1: + case APLAYER : + if(frames==0) frames=1; + case GREENSLIME : + case EGG : + case PIGCOPSTAYPUT : + case LIZMANSTAYPUT: + case LIZTROOPSTAYPUT : + case LIZMANSPITTING : + case LIZMANFEEDING : + case LIZMANJUMP : + if(skill!=4) + { + if(tspr->lotag>skill+1) + { + tspr->xrepeat=0; break; + } + } + if(nosprites==2||nosprites==3) + { + tspr->xrepeat=0; + // tspr->cstat|=32768; + } + // else tspr->cstat&=32767; + + if (bpp > 8 && usemodels && md_tilehasmodel(tspr->picnum)) { + tspr->cstat &= ~4; + break; + } + + if(frames!=0) + { + if(frames==10) frames=0; + k = getangle(tspr->x-posx,tspr->y-posy); + k = (((tspr->ang+3072+128-k)&2047)>>8)&7; + //This guy has only 5 pictures for 8 angles (3 are x-flipped) + if (k <= 4) + { + tspr->picnum += k; + tspr->cstat &= ~4; //clear x-flipping bit + } + else + { + tspr->picnum += 8-k; + tspr->cstat |= 4; //set x-flipping bit + } + } + + if(frames==2) tspr->picnum+=((((4-(totalclock>>5)))&1)*5); + if(frames==4) tspr->picnum+=((((4-(totalclock>>5)))&3)*5); + if(frames==5) tspr->picnum+=(((totalclock>>5)%5))*5; + + if(tilesizx[tspr->picnum] == 0) + tspr->picnum -= 5; //Hack, for actors + + break; + default: + break; + + } + } +} + +void Keys2d3d(void) +{ + int i, j; + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x1e]==1) // ' a + { + keystatus[0x1e] = 0; + autosave=!autosave; + if(autosave) message("Autosave ON"); + else message("Autosave OFF"); + } + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[KEYSC_N]==1) // ' n + { + keystatus[KEYSC_N] = 0; + noclip=!noclip; + if(noclip) message("Clipping disabled"); + else message("Clipping enabled"); + } + + if ((totalclock > autosavetimer) && (autosave)) + { + if (asksave) + { + fixspritesectors(); //Do this before saving! + // updatesector(startposx,startposy,&startsectnum); + ExtPreSaveMap(); + saveboard("autosave.map",&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap("autosave.map"); + message("Board autosaved to AUTOSAVE.MAP"); + } + autosavetimer = totalclock+120*180; + } + + if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL + if (keystatus[0x1f] > 0) // S + { + if (levelname) + { + fixspritesectors(); //Do this before saving! + updatesector(startposx,startposy,&startsectnum); + ExtPreSaveMap(); + saveboard(levelname,&startposx,&startposy,&startposz,&startang,&startsectnum); + ExtSaveMap(levelname); + message("Board saved"); + asksave = 0; + keystatus[0x1f] = 0; + } + } + + if (keystatus[buildkeys[14]] > 0) // Enter + { + getmessageleng = 0; + getmessagetimeoff = 0; + } + + if (getmessageleng > 0) + { + charsperline = 64; + //if (dimensionmode[snum] == 2) charsperline = 80; + if (qsetmode == 200) + { + for(i=0;i<=getmessageleng;i+=charsperline) + { + for(j=0;j>6)+2,((i/charsperline)<<3)+(ydimgame-(ydimgame>>5))-(((getmessageleng-1)/charsperline)<<3)+2,0,-1,tempbuf,xdimgame>640?0:1); + printext256((xdimgame>>6),((i/charsperline)<<3)+(ydimgame-(ydimgame>>5))-(((getmessageleng-1)/charsperline)<<3),whitecol,-1,tempbuf,xdimgame>640?0:1); + } + enddrawing(); + } + } + else printmessage16(getmessage); + if (totalclock > getmessagetimeoff) + getmessageleng = 0; + } + +} + +void ExtCheckKeys(void) +{ + readmousebstatus(&bstatus); + Keys2d3d(); + if (qsetmode == 200) //In 3D mode + { + Keys3d(); + m32_showmouse(); + if (sidemode != 1) editinput(); + } + else + { + Keys2d(); + } +} + +void faketimerhandler(void) +{ + long i, j, dax, day, dist; + long hiz, hihit, loz, lohit, oposx, oposy; + short hitwall, daang; + + counter++; if(counter>=5) counter=0; + + sampletimer(); + if (totalclock < ototalclock+TICSPERFRAME) + return; + if (qsetmode != 200) + return; + if (sidemode != 1) + return; + ototalclock = totalclock; + + oposx = posx; oposy = posy; + hitwall = clipmove(&posx,&posy,&posz,&cursectnum,xvel,yvel,128L,4L<<8,4L<<8,0); + xvel = ((posx-oposx)<<14); yvel = ((posy-oposy)<<14); + + yvel += 80000; + if ((hitwall&0xc000) == 32768) + { + hitwall &= (MAXWALLS-1); + i = wall[hitwall].point2; + daang = getangle(wall[i].x-wall[hitwall].x,wall[i].y-wall[hitwall].y); + + xvel -= (xvel>>4); + if (xvel < 0) xvel++; + if (xvel > 0) xvel--; + + yvel -= (yvel>>4); + if (yvel < 0) yvel++; + if (yvel > 0) yvel--; + + i = 4-keystatus[buildkeys[4]]; + xvel += mulscale(vel,(long)sintable[(ang+512)&2047],i); + yvel += mulscale(vel,(long)sintable[ang&2047],i); + + if (((daang-ang)&2047) < 1024) + ang = ((ang+((((daang-ang)&2047)+24)>>4))&2047); + else + ang = ((ang-((((ang-daang)&2047)+24)>>4))&2047); + + timoff = ototalclock; + } + else + { + if (ototalclock > timoff+32) + ang = ((ang+((timoff+32-ototalclock)>>4))&2047); + } + + getzrange(posx,posy,posz,cursectnum,&hiz,&hihit,&loz,&lohit,128L,0); + + oposx -= posx; oposy -= posy; + + dist = ksqrt(oposx*oposx+oposy*oposy); + if (ototalclock > timoff+32) dist = 0; + + daang = mulscale(dist,angvel,9); + posz += (daang<<6); + if (posz > loz-(4<<8)) posz = loz-(4<<8), hvel = 0; + if (posz < hiz+(4<<8)) posz = hiz+(4<<8), hvel = 0; + + horiz = ((horiz*7+(100-(daang>>1)))>>3); + if (horiz < 100) horiz++; + if (horiz > 100) horiz--; + + if(keystatus[KEYSC_QUOTE]==1 && keystatus[0x06]==1) // ' 5 + { + keystatus[0x06]=0; + editstatus = 1; + sidemode = 2; + } +} + +void SetBOSS1Palette() +{int x; + if(acurpalette==3) return; + acurpalette=3; + kensetpalette(BOSS1palette); +} + + +void SetSLIMEPalette() +{int x; + if(acurpalette==2) return; + acurpalette=2; + kensetpalette(SLIMEpalette); +} + +void SetWATERPalette() +{int x; + if(acurpalette==1) return; + acurpalette=1; + kensetpalette(WATERpalette); +} + + +void SetGAMEPalette() +{int x; + if(acurpalette==0) return; + acurpalette=0; + kensetpalette(GAMEpalette); +} + +void kensetpalette(char *vgapal) +{ + long i; + char vesapal[1024]; + + for(i=0;i<256;i++) + { + vesapal[i*4+0] = vgapal[i*3+2]; + vesapal[i*4+1] = vgapal[i*3+1]; + vesapal[i*4+2] = vgapal[i*3+0]; + vesapal[i*4+3] = 0; + } + setpalette(0L,256L,vesapal); +} + +void SearchSectorsForward() +{ + long ii=0; + if(cursector_lotag!=0) + { + if(cursectornum Sector search: found"); + // cursectornum++; + keystatus[0x1b]=0; // ] + return; + } + cursectornum++; + } + } + printmessage16("> Sector search: none found"); +} + +void SearchSectorsBackward() +{ + long ii=0; + if(cursector_lotag!=0) + { + if(cursectornum>0) cursectornum--; + for(ii=cursectornum;ii>=0;ii--) + { + if(sector[ii].lotag==cursector_lotag) + { + posx=wall[sector[ii].wallptr].x; + posy=wall[sector[ii].wallptr].y; + printmessage16("< Sector search: found"); + // cursectornum--; + keystatus[0x1a]=0; // [ + return; + } + cursectornum--; + } + } + printmessage16("< Sector search: none found"); +} + +// Build edit originally by Ed Coolidge +void EditSectorData(short sectnum) +{ + char disptext[80]; + char edittext[80]; + char snotbuf[80]; + char col=1, row=0, rowmax = 6, dispwidth = 24; + long xpos = 200, ypos = ydim-STATUS2DSIZ+48; + int i = -1; + char editval = 0; + disptext[dispwidth] = 0; + clearmidstatbar16(); + showsectordata(sectnum); + + begindrawing(); + while(keystatus[1] == 0) + { + if (handleevents()) { + if (quitevent) quitevent = 0; + } + printmessage16("Edit mode, press to exit"); + if (keystatus[0xd0] > 0) + { + if (row < rowmax) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row++; + } + keystatus[0xd0] = 0; + } + if (keystatus[0xc8] > 0) + { + if (row > 0) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row--; + } + keystatus[0xc8] = 0; + } + if (keystatus[0xcb] > 0) + { + if (col == 2) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 1; + xpos = 200; + rowmax = 6; + dispwidth = 24; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + keystatus[0xcb] = 0; + } + if (keystatus[0xcd] > 0) + { + if (col == 1) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 2; + xpos = 400; + rowmax = 6; + dispwidth = 24; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + keystatus[0xcd] = 0; + } + if (keystatus[0x1c] > 0) + { + keystatus[0x1c] = 0; + editval = 1; + } + + if (col == 1) + { + switch (row) + { + case 0: + for (i=Bsprintf(disptext,"Flags (hex): %x",sector[sectnum].ceilingstat); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Flags: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingstat = (short)getnumber16(edittext,(long)sector[sectnum].ceilingstat,32768L,0); + } + break; + case 1: + for (i=Bsprintf(disptext,"(X,Y)pan: %d, %d",sector[sectnum].ceilingxpanning,sector[sectnum].ceilingypanning); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Sector (%d) Ceiling X Pan: ",sectnum); + printmessage16(edittext); + sector[sectnum].ceilingxpanning = (char)getnumber16(edittext,(long)sector[sectnum].ceilingxpanning,256L,0); + Bsprintf(edittext,"Sector (%d) Ceiling Y Pan: ",sectnum); + printmessage16(edittext); + sector[sectnum].ceilingypanning = (char)getnumber16(edittext,(long)sector[sectnum].ceilingypanning,256L,0); + } + break; + case 2: + for (i=Bsprintf(disptext,"Shade byte: %d",sector[sectnum].ceilingshade); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Shade: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingshade = (char)getnumber16(edittext,(long)sector[sectnum].ceilingshade,128L,1); + } + break; + + case 3: + for (i=Bsprintf(disptext,"Z-coordinate: %ld",sector[sectnum].ceilingz); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Z-coordinate: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingz = getnumber16(edittext,sector[sectnum].ceilingz,8388608,1); //2147483647L,-2147483648L + } + break; + + case 4: + for (i=Bsprintf(disptext,"Tile number: %d",sector[sectnum].ceilingpicnum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Tile Number: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingpicnum = (short)getnumber16(edittext,(long)sector[sectnum].ceilingpicnum,MAXTILES,0); + } + break; + + case 5: + for (i=Bsprintf(disptext,"Ceiling heinum: %d",sector[sectnum].ceilingheinum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Heinum: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingheinum = (short)getnumber16(edittext,(long)sector[sectnum].ceilingheinum,32768L,1); + } + break; + + case 6: + for (i=Bsprintf(disptext,"Palookup number: %d",sector[sectnum].ceilingpal); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Ceiling Palookup Number: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].ceilingpal = (char)getnumber16(edittext,(long)sector[sectnum].ceilingpal,MAXPALOOKUPS,0); + } + break; + } + } + if (col == 2) + { + switch (row) + { + case 0: + for (i=Bsprintf(disptext,"Flags (hex): %x",sector[sectnum].floorstat); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Floor Flags: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorstat = (short)getnumber16(edittext,(long)sector[sectnum].floorstat,1024L,0); + } + break; + + case 1: + for (i=Bsprintf(disptext,"(X,Y)pan: %d, %d",sector[sectnum].floorxpanning,sector[sectnum].floorypanning); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Sector (%d) Floor X Pan: ",sectnum); + printmessage16(edittext); + sector[sectnum].floorxpanning = (char)getnumber16(edittext,(long)sector[sectnum].floorxpanning,256L,0); + Bsprintf(edittext,"Sector (%d) Floor Y Pan: ",sectnum); + printmessage16(edittext); + sector[sectnum].floorypanning = (char)getnumber16(edittext,(long)sector[sectnum].floorypanning,256L,0); + } + break; + + case 2: + for (i=Bsprintf(disptext,"Shade byte: %d",sector[sectnum].floorshade); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Floor Shade: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorshade = (char)getnumber16(edittext,(long)sector[sectnum].floorshade,65536L,1L); + } + break; + + case 3: + for (i=Bsprintf(disptext,"Z-coordinate: %ld",sector[sectnum].floorz); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Floor Z-coordinate: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorz = getnumber16(edittext,sector[sectnum].floorz,8388608L,1); //2147483647L,-2147483648L + } + break; + + case 4: + for (i=Bsprintf(disptext,"Tile number: %d",sector[sectnum].floorpicnum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Floor Tile Number: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorpicnum = (short)getnumber16(edittext,(long)sector[sectnum].floorpicnum,MAXTILES,0); + } + break; + case 5: + for (i=Bsprintf(disptext,"Floor heinum: %d",sector[sectnum].floorheinum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Flooring Heinum: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorheinum = (short)getnumber16(edittext,(long)sector[sectnum].floorheinum,32768L,1); + } + break; + case 6: + for (i=Bsprintf(disptext,"Palookup number: %d",sector[sectnum].floorpal); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sector (%d) Floor Palookup Number: ",sectnum); + if (editval) + { + printmessage16(edittext); + sector[sectnum].floorpal = (char)getnumber16(edittext,(long)sector[sectnum].floorpal,MAXPALOOKUPS,0); + } + break; + } + } + printext16(xpos,ypos+row*8,11,1,disptext,0); + if (editval) + { + editval = 0; + } + showframe(1); + } + printext16(xpos,ypos+row*8,11,0,disptext,0); + printmessage16(""); + enddrawing(); + showframe(1); + keystatus[1] = 0; +} + +void EditWallData(short wallnum) +{ + char disptext[80]; + char edittext[80]; + char snotbuf[80]; + char col=1, row=0, dispwidth = 24; + long xpos = 200, ypos = ydim-STATUS2DSIZ+48; + int i = -1; + char editval = 0; + disptext[dispwidth] = 0; + clearmidstatbar16(); + showwalldata(wallnum); + begindrawing(); + while(keystatus[1] == 0) + { + if (handleevents()) { + if (quitevent) quitevent = 0; + } + printmessage16("Edit mode, press to exit"); + if (keystatus[0xd0] > 0) + { + if (row < 6) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row++; + } + keystatus[0xd0] = 0; + } + if (keystatus[0xc8] > 0) + { + if (row > 0) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row--; + } + keystatus[0xc8] = 0; + } + if (keystatus[0x1c] > 0) + { + keystatus[0x1c] = 0; + editval = 1; + } + switch (row) + { + case 0: + for (i=Bsprintf(disptext,"Flags (hex): %x",wall[wallnum].cstat); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Wall (%d) Flags: ",wallnum); + if (editval) + { + printmessage16(edittext); + wall[wallnum].cstat = (short)getnumber16(edittext,(long)wall[wallnum].cstat,1024L,0); + } + break; + case 1: + for (i=Bsprintf(disptext,"Shade: %d",wall[wallnum].shade); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Wall (%d) Shade: ",wallnum); + if (editval) + { + printmessage16(edittext); + wall[wallnum].shade = (char)getnumber16(edittext,(long)wall[wallnum].shade,127,1); + } + break; + case 2: + for (i=Bsprintf(disptext,"Pal: %d",wall[wallnum].pal); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Wall (%d) Pal: ",wallnum); + if (editval) + { + printmessage16(edittext); + wall[wallnum].pal = (char)getnumber16(edittext,(long)wall[wallnum].pal,MAXPALOOKUPS,0); + } + break; + case 3: + for (i=Bsprintf(disptext,"(X,Y)repeat: %d, %d",wall[wallnum].xrepeat,wall[wallnum].yrepeat); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Wall (%d) X Repeat: ",wallnum); + printmessage16(edittext); + wall[wallnum].xrepeat = (char)getnumber16(edittext,(long)wall[wallnum].xrepeat,256L,0); + Bsprintf(edittext,"Wall (%d) Y Repeat: ",wallnum); + printmessage16(edittext); + wall[wallnum].yrepeat = (char)getnumber16(edittext,(long)wall[wallnum].yrepeat,256L,0); + } + break; + case 4: + for (i=Bsprintf(disptext,"(X,Y)pan: %d, %d",wall[wallnum].xpanning,wall[wallnum].ypanning); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Wall (%d) X Pan: ",wallnum); + printmessage16(edittext); + wall[wallnum].xpanning = (char)getnumber16(edittext,(long)wall[wallnum].xpanning,256L,0); + Bsprintf(edittext,"Wall (%d) Y Pan: ",wallnum); + printmessage16(edittext); + wall[wallnum].ypanning = (char)getnumber16(edittext,(long)wall[wallnum].ypanning,256L,0); + } + break; + case 5: + for (i=Bsprintf(disptext,"Tile number: %d",wall[wallnum].picnum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Wall (%d) Tile number: ",wallnum); + if (editval) + { + printmessage16(edittext); + wall[wallnum].picnum = (short)getnumber16(edittext,(long)wall[wallnum].picnum,MAXTILES,0); + } + break; + + case 6: + for (i=Bsprintf(disptext,"OverTile number: %d",wall[wallnum].overpicnum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Wall (%d) OverTile number: ",wallnum); + if (editval) + { + printmessage16(edittext); + wall[wallnum].overpicnum = (short)getnumber16(edittext,(long)wall[wallnum].overpicnum,MAXTILES,0); + } + break; + } + printext16(xpos,ypos+row*8,11,1,disptext,0); + if (editval) + { + editval = 0; + //showwalldata(wallnum); + //printmessage16(""); + } + //enddrawing(); + showframe(1); + } + //begindrawing(); + printext16(xpos,ypos+row*8,11,0,disptext,0); + printmessage16(""); + enddrawing(); + showframe(1); + keystatus[1] = 0; +} + +void EditSpriteData(short spritenum) +{ + char disptext[80]; + char edittext[80]; + char snotbuf[80]; + char col=1, row=0, rowmax=5, dispwidth = 24; + long xpos = 200, ypos = ydim-STATUS2DSIZ+48; + int i = -1; + char editval = 0; + disptext[dispwidth] = 0; + clearmidstatbar16(); + showspritedata(spritenum); + + while(keystatus[1] == 0) + { + begindrawing(); + if (handleevents()) { + if (quitevent) quitevent = 0; + } + printmessage16("Edit mode, press to exit"); + if (keystatus[0xd0] > 0) + { + if (row < rowmax) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row++; + } + keystatus[0xd0] = 0; + } + if (keystatus[0xc8] > 0) + { + if (row > 0) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + row--; + } + keystatus[0xc8] = 0; + } + if (keystatus[0xcb] > 0) + { + if (col == 2) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 1; + xpos = 200; + rowmax = 5; + dispwidth = 24; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + else if (col == 1) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 0; + xpos = 8; + rowmax = 2; + dispwidth = 23; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + keystatus[0xcb] = 0; + } + if (keystatus[0xcd] > 0) + { + if (col == 0) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 1; + xpos = 200; + rowmax = 5; + dispwidth = 24; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + else if (col == 1) + { + printext16(xpos,ypos+row*8,11,0,disptext,0); + col = 2; + xpos = 400; + rowmax = 6; + dispwidth = 26; + disptext[dispwidth] = 0; + if (row > rowmax) row = rowmax; + } + keystatus[0xcd] = 0; + } + if (keystatus[0x1c] > 0) + { + keystatus[0x1c] = 0; + editval = 1; + } + switch (row) + { + case 0: + if (col == 0) + { + for (i=Bsprintf(disptext,"X-coordinate: %ld",sprite[spritenum].x); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) X-coordinate: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].x = getnumber16(edittext,sprite[spritenum].x,131072,1); + } + } + else if (col == 1) + { + for (i=Bsprintf(disptext,"Flags (hex): %x",sprite[spritenum].cstat); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Flags: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].cstat = (short)getnumber16(edittext,(long)sprite[spritenum].cstat,32768L,0); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"Angle (2048 degrees): %d",sprite[spritenum].ang); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Angle: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].ang = (short)getnumber16(edittext,(long)sprite[spritenum].ang,2048L,0); + } + } + break; + case 1: + if (col == 0) + { + for (i=Bsprintf(disptext,"Y-coordinate: %ld",sprite[spritenum].y); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Y-coordinate: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].y = getnumber16(edittext,sprite[spritenum].y,131072,1); + } + } + else if (col == 1) + { + for (i=Bsprintf(disptext,"Shade: %d",sprite[spritenum].shade); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Shade: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].shade = (char)getnumber16(edittext,(long)sprite[spritenum].shade,127,1); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"X-Velocity: %d",sprite[spritenum].xvel); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) X-Velocity: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].xvel = getnumber16(edittext,(long)sprite[spritenum].xvel,32767,1); + } + } + break; + case 2: + if (col == 0) + { + for (i=Bsprintf(disptext,"Z-coordinate: %ld",sprite[spritenum].z); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Z-coordinate: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].z = getnumber16(edittext,sprite[spritenum].z,8388608,1); //2147483647L,-2147483648L + } + } + else if (col == 1) + { + for (i=Bsprintf(disptext,"Pal: %d",sprite[spritenum].pal); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Pal: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].pal = (char)getnumber16(edittext,(long)sprite[spritenum].pal,MAXPALOOKUPS,0); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"Y-Velocity: %d",sprite[spritenum].yvel); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Y-Velocity: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].yvel = getnumber16(edittext,(long)sprite[spritenum].yvel,32767,1); + } + } + + break; + case 3: + if (col == 1) + { + for (i=Bsprintf(disptext,"(X,Y)repeat: %d, %d",sprite[spritenum].xrepeat,sprite[spritenum].yrepeat); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Sprite (%d) X Repeat: ",spritenum); + printmessage16(edittext); + sprite[spritenum].xrepeat = (char)getnumber16(edittext,(long)sprite[spritenum].xrepeat,256L,0); + Bsprintf(edittext,"Sprite (%d) Y Repeat: ",spritenum); + printmessage16(edittext); + sprite[spritenum].yrepeat = (char)getnumber16(edittext,(long)sprite[spritenum].yrepeat,256L,0); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"Z-Velocity: %d",sprite[spritenum].zvel); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Z-Velocity: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].zvel = getnumber16(edittext,(long)sprite[spritenum].zvel,32767,1); + } + } + + break; + case 4: + if (col == 1) + { + for (i=Bsprintf(disptext,"(X,Y)offset: %d, %d",sprite[spritenum].xoffset,sprite[spritenum].yoffset); i < dispwidth; i++) disptext[i] = ' '; + if (editval) + { + Bsprintf(edittext,"Sprite (%d) X Offset: ",spritenum); + printmessage16(edittext); + sprite[spritenum].xoffset = (char)getnumber16(edittext,(long)sprite[spritenum].xoffset,128L,1); + Bsprintf(edittext,"Sprite (%d) Y Offset: ",spritenum); + printmessage16(edittext); + sprite[spritenum].yoffset = (char)getnumber16(edittext,(long)sprite[spritenum].yoffset,128L,1); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"Owner: %d",sprite[spritenum].owner); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Owner: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].owner = getnumber16(edittext,(long)sprite[spritenum].owner,MAXSPRITES,0); + } + } + + break; + case 5: + if (col == 1) + { + for (i=Bsprintf(disptext,"Tile number: %d",sprite[spritenum].picnum); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Tile number: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].picnum = (short)getnumber16(edittext,(long)sprite[spritenum].picnum,MAXTILES,0); + } + } + else if (col == 2) + { + for (i=Bsprintf(disptext,"Clipdist: %d",sprite[spritenum].clipdist); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Clipdist: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].clipdist = (char)getnumber16(edittext,(long)sprite[spritenum].clipdist,255,0); + } + } + + break; + case 6: + if (col == 2) + { + for (i=Bsprintf(disptext,"Extra: %d",sprite[spritenum].extra); i < dispwidth; i++) disptext[i] = ' '; + Bsprintf(edittext,"Sprite (%d) Extra: ",spritenum); + if (editval) + { + printmessage16(edittext); + sprite[spritenum].extra = getnumber16(edittext,(long)sprite[spritenum].extra,32767,1); + } + } + + break; + } + printext16(xpos,ypos+row*8,11,1,disptext,0); + if (editval) + { + editval = 0; + } + enddrawing(); + showframe(1); + } + begindrawing(); + printext16(xpos,ypos+row*8,11,0,disptext,0); + printmessage16(""); + enddrawing(); + showframe(1); + keystatus[1] = 0; +} + +// Build edit + +#define M_RED 12 +#define M_BLUE 9 + +void ResetKeys(void) +{ + int i; + + for (i = 0; i < MAXKEYBOARDSCAN; i++) + { + keystatus[i] = 0; + } +} + +void Msg(char *string, char color) +{ + clearmidstatbar16(); + + printext16(1*4,ydim16+4*8,color,-1,string,0); + +} + +long GetAToken(char *name, char *tc, long length) +{ + int i,x=0; + char t,*tmp,tokenfound=0; + char *token; + long count=0; + + if(!(token = (char *)malloc(9))) + { + Msg("Out of heap space!",M_RED); + return(tokenfound); + } + + + do{ + + // Find the token symbol + do { + t = *tc; + tc++; + count++; + } while(t!='@' && count < length); + + + if(t=='@') + { + tmp = token; + x=1; + + do { + // Read in the token + *tmp = t; + tmp++; + t = *tc; + tc++; + x++; + count++; + } while((t>=48 && t<=127) && t!='@' && x < 9 && count < length); + + *tmp = 0; + + if(!strcmp(name,Bstrupr(token))) + tokenfound = 1; + } + } while(!tokenfound && count < length); + + + if(!tokenfound) count=0; + return(count); + +} +/* +void ContextHelp(short spritenum) +{ + int i,fp; + char t,*tc; + char x=0,y=4; + char *name,*hightag; + char *filebuffer; + spritetype *sp; + short lotag=0; + long size=0,tokresult=0; + + + sp = &sprite[spritenum]; + + clearmidstatbar16(); + + if((fp=kopen4load("sehelp.hp2",0)) == -1) + { + Msg("ERROR: Help file not found.",M_RED); + return; + } + + // Read in whole file + size = kfilelength(fp); + filebuffer = (char *)malloc(size); + if (filebuffer == NULL) + { + Msg("Not enough memory to load sehelp.hp2",M_RED); + return; + } + + if (kread(fp, filebuffer, size) != size) + { + Msg("Unexpected end of file while reading sehelp.hp2",M_RED); + kclose(fp); + return; + } + + // close the file + kclose(fp); + + // Conver filebuffer to all upper case + //strupr(filebuffer); + + // Assign a token name to search for based on the sprite being pointed to. + name = (char *)malloc(20); + hightag = (char *)malloc(sizeof(short)); + + // Make the token + strcpy(name,"@TAG"); + // Make sure 500-600 SOBJ bounding tags all say the same thing. + lotag = sp->lotag; + if(lotag > 500 && lotag <= 600 ) lotag = 500; + // Give help summary for unknown sprites. + if((lotag == 0 || lotag > 1006) && sp->lotag == 0) lotag = 999; + + sprintf(hightag,"%d",lotag); + //itoa(lotag,hightag,10); + strcat(name,hightag); + + tc = filebuffer; + + if(!(tokresult = GetAToken(name,tc,size))) + { + // This message should never happen unless something is real wrong! + Msg("No help available.",M_RED); + return; + } + + tc += tokresult; + + do { + tc++; + t = *tc; + while(t!='\n' && t!='@' && t!='#' && x<128) + { + tempbuf[x]=t; + tc++; + t = *tc; + x++; + if(x >= 128) break; + } + tempbuf[x]=0; + x=0; + printext16(x*4,ydim16+(y*6)+2,11,-1,tempbuf,1); + y++; + + if(y>16) + { + y=18; + printext16(x*4,ydim16+(y*6)+2,11,-1,"Hit any key to continue or Q to quit....",1); + while (bgetchar() == NULL); + if (keystatus[KEYSC_Q]) + { + clearmidstatbar16(); + return; + } + ResetKeys(); + clearmidstatbar16(); + + y=6; + } + + } while(t!='@' && t!='#'); +} +*/ diff --git a/polymer/eduke32/source/config.c b/polymer/eduke32/source/config.c new file mode 100644 index 000000000..9fa4b081c --- /dev/null +++ b/polymer/eduke32/source/config.c @@ -0,0 +1,794 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +/* +#include +#include +#include +#include +#include +*/ + +#include "duke3d.h" +#include "scriplib.h" +#include "osd.h" + +#include "baselayer.h" + +// we load this in to get default button and key assignments +// as well as setting up function mappings + +#define __SETUP__ // JBF 20031211 +#include "_functio.h" + +// +// Sound variables +// +int32 FXDevice; +int32 MusicDevice; +int32 FXVolume; +int32 MusicVolume; +int32 SoundToggle; +int32 MusicToggle; +int32 VoiceToggle; +int32 AmbienceToggle; +//fx_blaster_config BlasterConfig; +int32 NumVoices; +int32 NumChannels; +int32 NumBits; +int32 MixRate; +//int32 MidiPort; +int32 ReverseStereo; + +int32 ControllerType; +int32 RunMode; +int32 AutoAim; // JBF 20031125 +int32 ShowOpponentWeapons; + +// JBF 20031211: Store the input settings because +// (currently) jmact can't regurgitate them +byte KeyboardKeys[NUMGAMEFUNCTIONS][2]; +int32 MouseFunctions[MAXMOUSEBUTTONS][2]; +int32 MouseDigitalFunctions[MAXMOUSEAXES][2]; +int32 MouseAnalogueAxes[MAXMOUSEAXES]; +int32 MouseAnalogueScale[MAXMOUSEAXES]; +int32 JoystickFunctions[MAXJOYBUTTONS][2]; +int32 JoystickDigitalFunctions[MAXJOYAXES][2]; +int32 JoystickAnalogueAxes[MAXJOYAXES]; +int32 JoystickAnalogueScale[MAXJOYAXES]; +int32 JoystickAnalogueDead[MAXJOYAXES]; +int32 JoystickAnalogueSaturate[MAXJOYAXES]; + +// +// Screen variables +// + +int32 ScreenMode = 1; +int32 ScreenWidth = 640; +int32 ScreenHeight = 480; +int32 ScreenBPP = 8; + +static char setupfilename[256]={SETUPFILENAME}; +int32 scripthandle = -1; +static int32 setupread=0; + +/* +=================== += += CONFIG_FunctionNameToNum += +=================== +*/ + +int32 CONFIG_FunctionNameToNum( char * func ) +{ + int32 i; + + for (i=0;i= (unsigned)NUMGAMEFUNCTIONS) + { + return NULL; + } + else + { + return gamefunctions[func]; + } +} + +/* +=================== += += CONFIG_AnalogNameToNum += +=================== +*/ + + +int32 CONFIG_AnalogNameToNum( char * func ) +{ + + if (!Bstrcasecmp(func,"analog_turning")) + { + return analog_turning; + } + if (!Bstrcasecmp(func,"analog_strafing")) + { + return analog_strafing; + } + if (!Bstrcasecmp(func,"analog_moving")) + { + return analog_moving; + } + if (!Bstrcasecmp(func,"analog_lookingupanddown")) + { + return analog_lookingupanddown; + } + + return -1; +} + + +char * CONFIG_AnalogNumToName( int32 func ) +{ + switch (func) { + case analog_turning: + return "analog_turning"; + case analog_strafing: + return "analog_strafing"; + case analog_moving: + return "analog_moving"; + case analog_lookingupanddown: + return "analog_lookingupanddown"; + } + + return NULL; +} + + +/* +=================== += += CONFIG_SetDefaults += +=================== +*/ + +void CONFIG_SetDefaults( void ) +{ + // JBF 20031211 + int32 i,f; + byte k1,k2; + + FXDevice = -1; + MusicDevice = -1; + NumVoices = 8; + NumChannels = 2; + NumBits = 8; + MixRate = 22050; + SoundToggle = 1; + MusicToggle = 1; + VoiceToggle = 1; + AmbienceToggle = 1; + FXVolume = 220; + MusicVolume = 200; + ReverseStereo = 0; + myaimmode = ps[0].aim_mode = 0; + ud.mouseaiming = 0; + ud.weaponswitch = 3; // new+empty + AutoAim = 1; + ControllerType = 1; + ud.mouseflip = 0; + ud.runkey_mode = 0; + ud.statusbarscale = 100; + ud.screen_size = 8; + ud.screen_tilting = 1; + ud.shadows = 1; + ud.detail = 1; + ud.lockout = 0; + ud.pwlockout[0] = '\0'; + ud.crosshair = 0; + ud.m_marker = 1; + ud.m_ffire = 1; + ud.levelstats = 0; + ud.drawweapon = 1; + ShowOpponentWeapons = 0; + Bstrcpy(ud.rtsname, "DUKE.RTS"); + Bstrcpy(myname, "Duke"); + + Bstrcpy(ud.ridecule[0], "An inspiration for birth control."); + Bstrcpy(ud.ridecule[1], "You're gonna die for that!"); + Bstrcpy(ud.ridecule[2], "It hurts to be you."); + Bstrcpy(ud.ridecule[3], "Lucky Son of a Bitch."); + Bstrcpy(ud.ridecule[4], "Hmmm....Payback time."); + Bstrcpy(ud.ridecule[5], "You bottom dwelling scum sucker."); + Bstrcpy(ud.ridecule[6], "Damn, you're ugly."); + Bstrcpy(ud.ridecule[7], "Ha ha ha...Wasted!"); + Bstrcpy(ud.ridecule[8], "You suck!"); + Bstrcpy(ud.ridecule[9], "AARRRGHHHHH!!!"); + + // JBF 20031211 + memset(KeyboardKeys, 0xff, sizeof(KeyboardKeys)); + for (i=0; i < (int32)(sizeof(keydefaults)/sizeof(keydefaults[0]))/3; i++) { + f = CONFIG_FunctionNameToNum( keydefaults[3*i+0] ); + if (f == -1) continue; + k1 = KB_StringToScanCode( keydefaults[3*i+1] ); + k2 = KB_StringToScanCode( keydefaults[3*i+2] ); + + KeyboardKeys[f][0] = k1; + KeyboardKeys[f][1] = k2; + } + + memset(MouseFunctions, -1, sizeof(MouseFunctions)); + for (i=0; i= 0) + { + for(dummy = 0;dummy < 10;dummy++) + { + commmacro[13] = dummy+'0'; + SCRIPT_GetString( scripthandle, "Comm Setup",commmacro,&ud.ridecule[dummy][0]); + } + + SCRIPT_GetString( scripthandle, "Comm Setup","PlayerName",&myname[0]); + + SCRIPT_GetString( scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]); + + SCRIPT_GetNumber( scripthandle, "Screen Setup", "Shadows",&ud.shadows); + SCRIPT_GetString( scripthandle, "Screen Setup","Password",&ud.pwlockout[0]); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "Detail",&ud.detail); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "Tilt",&ud.screen_tilting); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "Messages",&ud.fta_on); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenWidth",&ScreenWidth); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenHeight",&ScreenHeight); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenMode",&ScreenMode); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenGamma",&ud.brightness); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenSize",&ud.screen_size); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "Out",&ud.lockout); + + SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenBPP", &ScreenBPP); + if (ScreenBPP < 8) ScreenBPP = 8; + +#ifdef RENDERTYPEWIN + SCRIPT_GetNumber( scripthandle, "Screen Setup", "MaxRefreshFreq", (int32*)&maxrefreshfreq); +#endif + + SCRIPT_GetNumber( scripthandle, "Screen Setup", "GLTextureMode", &gltexfiltermode); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "GLAnisotropy", &glanisotropy); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "GLUseTextureCompr", &glusetexcompr); + dummy = usemodels; SCRIPT_GetNumber( scripthandle, "Screen Setup", "UseModels",&dummy); usemodels = dummy != 0; + dummy = usehightile; SCRIPT_GetNumber( scripthandle, "Screen Setup", "UseHightile",&dummy); usehightile = dummy != 0; + + SCRIPT_GetNumber( scripthandle, "Misc", "Executions",&ud.executions); + ud.executions++; + SCRIPT_GetNumber( scripthandle, "Misc", "RunMode",&RunMode); + SCRIPT_GetNumber( scripthandle, "Misc", "Crosshairs",&ud.crosshair); + SCRIPT_GetNumber( scripthandle, "Misc", "StatusBarScale",&ud.statusbarscale); + SCRIPT_GetNumber( scripthandle, "Misc", "ShowLevelStats",&ud.levelstats); + SCRIPT_GetNumber( scripthandle, "Misc", "ShowOpponentWeapons",&ShowOpponentWeapons); + SCRIPT_GetNumber( scripthandle, "Misc", "ShowViewWeapon",&ud.drawweapon); + SCRIPT_GetNumber( scripthandle, "Misc", "ShowFPS",&ud.tickrate); + dummy = useprecache; SCRIPT_GetNumber( scripthandle, "Misc", "UsePrecache",&dummy); useprecache = dummy != 0; + if(ud.wchoice[0][0] == 0 && ud.wchoice[0][1] == 0) + { + ud.wchoice[0][0] = 3; + ud.wchoice[0][1] = 4; + ud.wchoice[0][2] = 5; + ud.wchoice[0][3] = 7; + ud.wchoice[0][4] = 8; + ud.wchoice[0][5] = 6; + ud.wchoice[0][6] = 0; + ud.wchoice[0][7] = 2; + ud.wchoice[0][8] = 9; + ud.wchoice[0][9] = 1; + + for(dummy=0;dummy<10;dummy++) + { + Bsprintf(buf,"WeaponChoice%ld",dummy); + SCRIPT_GetNumber( scripthandle, "Misc", buf, &ud.wchoice[0][dummy]); + } + } + + SCRIPT_GetNumber( scripthandle, "Sound Setup", "FXDevice",&FXDevice); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicDevice",&MusicDevice); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "FXVolume",&FXVolume); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicVolume",&MusicVolume); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "SoundToggle",&SoundToggle); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicToggle",&MusicToggle); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "VoiceToggle",&VoiceToggle); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "AmbienceToggle",&AmbienceToggle); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumVoices",&NumVoices); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumChannels",&NumChannels); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumBits",&NumBits); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "MixRate",&MixRate); + SCRIPT_GetNumber( scripthandle, "Sound Setup", "ReverseStereo",&ReverseStereo); + + SCRIPT_GetNumber( scripthandle, "Controls","ControllerType",&ControllerType); + SCRIPT_GetNumber( scripthandle, "Controls","MouseAimingFlipped",&ud.mouseflip); // mouse aiming inverted + SCRIPT_GetNumber( scripthandle, "Controls","MouseAiming",&ud.mouseaiming); // 1=momentary/0=toggle + //SCRIPT_GetNumber( scripthandle, "Controls","GameMouseAiming",(int32 *)&ps[0].aim_mode); // dupe of below (?) + ps[0].aim_mode = ud.mouseaiming; + SCRIPT_GetNumber( scripthandle, "Controls","AimingFlag",(int32 *)&myaimmode); // (if toggle mode) gives state + SCRIPT_GetNumber( scripthandle, "Controls","RunKeyBehaviour",&ud.runkey_mode); // JBF 20031125 + SCRIPT_GetNumber( scripthandle, "Controls","AutoAim",&AutoAim); // JBF 20031125 + ps[0].auto_aim = AutoAim; + SCRIPT_GetNumber( scripthandle, "Controls","WeaponSwitchMode",&ud.weaponswitch); + glusetexcache = glusetexcachecompression = -1; + SCRIPT_GetNumber( scripthandle, "Screen Setup", "GLUseCompressedTextureCache", &glusetexcache); + SCRIPT_GetNumber( scripthandle, "Screen Setup", "GLUseTextureCacheCompression", &glusetexcachecompression); + if(glusetexcache == -1 && glusetexcachecompression == -1) + { + i=wm_ynbox("Texture caching", + "Would you like to enable the on-disk texture cache? " + "This feature may use up to 200 megabytes of disk " + "space if you have a great deal of high resolution " + "textures and skins, but textures will load exponentially " + "faster after the first time they are loaded."); + if (i) i = 'y'; + if(i == 'y' || i == 'Y' ) + useprecache = glusetexcompr = glusetexcache = glusetexcachecompression = 1; + else glusetexcache = glusetexcachecompression = 0; + } + + } + + CONFIG_ReadKeys(); + + //CONFIG_SetupMouse(scripthandle); + //CONFIG_SetupJoystick(scripthandle); + + setupread = 1; +} + +/* +=================== += += CONFIG_WriteSetup += +=================== +*/ + +void CONFIG_WriteSetup( void ) +{ + int32 dummy; + + //if (!setupread) return; + if (scripthandle < 0) + scripthandle = SCRIPT_Init(setupfilename); + + SCRIPT_PutNumber( scripthandle, "Screen Setup", "Shadows",ud.shadows,false,false); + SCRIPT_PutString( scripthandle, "Screen Setup", "Password",ud.pwlockout); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "Detail",ud.detail,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "Tilt",ud.screen_tilting,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "Messages",ud.fta_on,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "Out",ud.lockout,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenWidth",ScreenWidth,false,false); // JBF 20031206 + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenHeight",ScreenHeight,false,false); // JBF 20031206 + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenMode",ScreenMode,false,false); // JBF 20031206 + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenBPP",ScreenBPP,false,false); // JBF 20040523 +#ifdef RENDERTYPEWIN + SCRIPT_PutNumber( scripthandle, "Screen Setup", "MaxRefreshFreq",maxrefreshfreq,false,false); +#endif + SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLTextureMode",gltexfiltermode,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLAnisotropy",glanisotropy,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLUseTextureCompr",glusetexcompr,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLUseCompressedTextureCache", glusetexcache,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLUseTextureCacheCompression", glusetexcachecompression,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "UseModels",usemodels,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "UseHightile",usehightile,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXVolume",FXVolume,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicVolume",MusicVolume,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "SoundToggle",SoundToggle,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "VoiceToggle",VoiceToggle,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "AmbienceToggle",AmbienceToggle,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicToggle",MusicToggle,false,false); + SCRIPT_PutNumber( scripthandle, "Sound Setup", "ReverseStereo",ReverseStereo,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenSize",ud.screen_size,false,false); + SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenGamma",ud.brightness,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "Executions",ud.executions,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "RunMode",RunMode,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "Crosshairs",ud.crosshair,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "ShowLevelStats",ud.levelstats,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "StatusBarScale",ud.statusbarscale,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "ShowOpponentWeapons",ShowOpponentWeapons,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "UsePrecache",useprecache,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "ShowViewWeapon",ud.drawweapon,false,false); + SCRIPT_PutNumber( scripthandle, "Misc", "ShowFPS",ud.tickrate,false,false); + SCRIPT_PutNumber( scripthandle, "Controls", "MouseAimingFlipped",ud.mouseflip,false,false); + SCRIPT_PutNumber( scripthandle, "Controls","MouseAiming",ud.mouseaiming,false,false); + //SCRIPT_PutNumber( scripthandle, "Controls","GameMouseAiming",(int32) ps[myconnectindex].aim_mode,false,false); + SCRIPT_PutNumber( scripthandle, "Controls","AimingFlag",(long) myaimmode,false,false); + SCRIPT_PutNumber( scripthandle, "Controls","RunKeyBehaviour",ud.runkey_mode,false,false); + SCRIPT_PutNumber( scripthandle, "Controls","AutoAim",AutoAim,false,false); + SCRIPT_PutNumber( scripthandle, "Controls","WeaponSwitchMode",ud.weaponswitch,false,false); + + // JBF 20031211 + for(dummy=0;dummy= (MAXMOUSEBUTTONS-2)) continue; + + Bsprintf(buf,"MouseButtonClicked%ld",dummy); + SCRIPT_PutString( scripthandle,"Controls", buf, CONFIG_FunctionNumToName( MouseFunctions[dummy][1] )); + } + for (dummy=0;dummysectnum,s->x+(TRAND&255)-128,s->y+(TRAND&255)-128,s->z-(8<<8)-(TRAND&8191),SCRAP6+(TRAND&15),-8,48,48,TRAND&2047,(TRAND&63)+64,-512-(TRAND&2047),i,5) + +#define PHEIGHT (38<<8) + +// #define P(X) printf("%ld\n",X); + +#define WAIT(X) ototalclock=totalclock+(X);while(totalclock=(B) && (PN)<=(E)) +#define KILLIT(KX) {ResetActorGameVars(KX);deletesprite(KX);goto BOLT;} + + +#define IFMOVING if(ssp(i,CLIPMASK0)) +#define IFHIT j=ifhitbyweapon(i);if(j >= 0) +#define IFHITSECT j=ifhitsectors(s->sectnum);if(j >= 0) + +#define AFLAMABLE(X) (X==BOX||X==TREE1||X==TREE2||X==TIRE||X==CONE) + + +#define IFSKILL1 if(player_skill<1) +#define IFSKILL2 if(player_skill<2) +#define IFSKILL3 if(player_skill<3) +#define IFSKILL4 if(player_skill<4) + +#define rnd(X) ((TRAND>>8)>=(255-(X))) + +typedef struct { + short i; + int voice; +} SOUNDOWNER; + +#define __USRHOOKS_H + +enum USRHOOKS_Errors { + USRHOOKS_Warning = -2, + USRHOOKS_Error = -1, + USRHOOKS_Ok = 0 +}; + +typedef struct { + signed char avel, horz; + short fvel, svel; + unsigned long bits, bits2; +} input; + +#define sync dsync // JBF 20040604: sync is a function on some platforms +extern input inputfifo[MOVEFIFOSIZ][MAXPLAYERS], sync[MAXPLAYERS]; +extern input recsync[RECSYNCBUFSIZ]; + +extern long movefifosendplc; + +typedef struct { + char *ptr; + volatile char lock; +int length, num; +} SAMPLE; + +struct animwalltype { + short wallnum; + long tag; +}; + +extern struct animwalltype animwall[MAXANIMWALLS]; +extern short numanimwalls,probey,lastprobey; + +extern char typebuflen,typebuf[41]; +extern char MusicPtr[72000*2]; +extern long msx[2048],msy[2048]; +extern short cyclers[MAXCYCLERS][6],numcyclers; +extern char myname[32]; + +struct savehead { + char name[19]; + int32 numplr,volnum,levnum,plrskl; + char boardfn[BMAX_PATH]; +}; + +struct user_defs { + char god,warp_on,cashman,eog,showallmap; + char show_help,scrollmode,clipping; + char user_name[MAXPLAYERS][32]; + char ridecule[10][40]; + char savegame[10][22]; + char pwlockout[128],rtsname[128]; + char overhead_on,last_overhead,showweapons; + + short pause_on,from_bonus; + short camerasprite,last_camsprite; + short last_level,secretlevel; + + long const_visibility,uw_framerate; + long camera_time,folfvel,folavel,folx,foly,fola; + long reccnt; + + int32 runkey_mode,statusbarscale,mouseaiming,weaponswitch,drawweapon; // JBF 20031125 + + int32 entered_name,screen_tilting,shadows,fta_on,executions,auto_run; + int32 coords,tickrate,levelstats,m_coop,coop,screen_size,lockout,crosshair; + int32 wchoice[MAXPLAYERS][MAX_WEAPONS],playerai; + + int32 respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness; + int32 m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off,detail; + int32 m_ffire,ffire,m_player_skill,m_level_number,m_volume_number,multimode; + int32 player_skill,level_number,volume_number,m_marker,marker,mouseflip; +}; + +struct player_orig { + long ox,oy,oz; + short oa,os; +}; + + +extern char numplayersprites; +extern char picsiz[MAXTILES]; + +extern long fricxv,fricyv; + +struct player_struct { + long zoom,exitx,exity,loogiex[64],loogiey[64],numloogs,loogcnt; + long posx, posy, posz, horiz, ohoriz, ohorizoff, invdisptime; + long bobposx,bobposy,oposx,oposy,oposz,pyoff,opyoff; + long posxv,posyv,poszv,last_pissed_time,truefz,truecz; + long player_par,visibility; + long bobcounter,weapon_sway; + long pals_time,randomflamex,crack_time; + + char aim_mode,auto_aim,weaponswitch; + + short ang,oang,angvel,cursectnum,look_ang,last_extra,subweapon; + short ammo_amount[MAX_WEAPONS],wackedbyactor,frag,fraggedself; + + short curr_weapon, last_weapon, tipincs, horizoff, wantweaponfire; + short holoduke_amount,newowner,hurt_delay,hbomb_hold_delay; + short jumping_counter,airleft,knee_incs,access_incs; + short fta,ftq,access_wallnum,access_spritenum; + short kickback_pic,got_access,weapon_ang,firstaid_amount; + short somethingonplayer,on_crane,i,one_parallax_sectnum; + short over_shoulder_on,random_club_frame,fist_incs; + short one_eighty_count,cheat_phase; + short dummyplayersprite,extra_extra8,quick_kick; + short heat_amount,actorsqu,timebeforeexit,customexitsound; + + short weaprecs[16],weapreccnt; + unsigned long interface_toggle_flag; + + short orotscrnang,rotscrnang,dead_flag,show_empty_weapon; // JBF 20031220: added orotscrnang + short scuba_amount,jetpack_amount,steroids_amount,shield_amount; + short holoduke_on,pycount,weapon_pos,frag_ps; + short transporter_hold,last_full_weapon,footprintshade,boot_amount; + + int scream_voice; + + char gm,on_warping_sector,footprintcount; + char hbomb_on,jumping_toggle,rapid_fire_hold,on_ground; + char name[32],inven_icon,buttonpalette; + + char jetpack_on,spritebridge,lastrandomspot; + char scuba_on,footprintpal,heat_on; + + char holster_weapon,falling_counter; + char gotweapon[MAX_WEAPONS],refresh_inventory,*palette; + + char toggle_key_flag,knuckle_incs; // ,select_dir; + char walking_snd_toggle, palookup, hard_landing; + char /*fire_flag,*/pals[3]; + char return_to_center, reloading, movement_lock[4]; + + long max_secret_rooms,secret_rooms,max_actors_killed,actors_killed; + long runspeed; + short sbs, sound_pitch; +}; + +extern char tempbuf[2048], packbuf[576]; + +extern long gc,max_player_health,max_armour_amount,max_ammo_amount[MAX_WEAPONS]; + +extern long impact_damage,respawnactortime,respawnitemtime; + +#define MOVFIFOSIZ 256 + +extern short spriteq[1024],spriteqloc,spriteqamount; +extern struct player_struct ps[MAXPLAYERS]; +extern struct player_orig po[MAXPLAYERS]; +extern struct user_defs ud; +extern short int moustat; +extern short int global_random; +extern long scaredfallz; +extern char buf[1024]; //My own generic input buffer + +extern char fta_quotes[NUMOFFIRSTTIMEACTIVE][64]; +extern char scantoasc[128],ready2send; +extern char scantoascwithshift[128]; + +//extern fx_device device; +extern SAMPLE Sound[ NUM_SOUNDS ]; +extern int32 VoiceToggle,AmbienceToggle; +extern SOUNDOWNER SoundOwner[NUM_SOUNDS][4]; + +extern char playerreadyflag[MAXPLAYERS],playerquitflag[MAXPLAYERS]; +extern char sounds[NUM_SOUNDS][BMAX_PATH]; + +// JBF 20040531: adding 16 extra to the script so we have some leeway +// to (hopefully) safely abort when hitting the limit +extern long script[MAXSCRIPTSIZE+16],*scriptptr,*insptr,*labelcode,labelcnt,defaultlabelcnt,*labeltype; +extern char *label,*textptr,error,warning,killit_flag; +extern long *actorscrptr[MAXTILES],*parsing_actor; +extern long *actorLoadEventScrptr[MAXTILES]; +extern char actortype[MAXTILES]; +extern char *music_pointer; + +extern char ipath[80],opath[80]; + +extern char music_fn[8][11][13],music_select; +extern char env_music_fn[8][13]; +extern short camsprite; + +// extern char gotz; +extern char inspace(short sectnum); + +struct weaponhit { + char cgg; + short picnum,ang,extra,owner,movflag; + short tempang,actorstayput,dispicnum; + short timetosleep; + long floorz,ceilingz,lastvx,lastvy,bposx,bposy,bposz; + long temp_data[10]; +}; + +extern struct weaponhit hittype[MAXSPRITES]; + +extern input loc; +extern input recsync[RECSYNCBUFSIZ]; +extern long avgfvel, avgsvel, avgavel, avghorz, avgbits, avgbits2; + +extern long numplayers, myconnectindex; +extern long connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers) +extern short screenpeek; + +extern int current_menu; +extern long tempwallptr,animatecnt; +extern long lockclock,frameplace; +extern char display_mirror,loadfromgrouponly,rtsplaying; + +extern long movefifoend[MAXPLAYERS], groupfile; +extern long ototalclock; + +extern long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; +extern long animatevel[MAXANIMATES]; +// extern long oanimateval[MAXANIMATES]; +extern short neartagsector, neartagwall, neartagsprite; +extern long neartaghitdist; +extern short animatesect[MAXANIMATES]; +extern long movefifoplc, vel,svel,angvel,horiz; + +extern short mirrorwall[64], mirrorsector[64], mirrorcnt; + +#define NUMKEYS 19 + +extern long frameplace, chainplace, chainnumpages; + +#include "funct.h" + +extern char screencapt; +extern short soundps[NUM_SOUNDS],soundpe[NUM_SOUNDS],soundvo[NUM_SOUNDS]; +extern char soundpr[NUM_SOUNDS],soundm[NUM_SOUNDS]; +extern long soundsiz[NUM_SOUNDS]; +extern char level_names[77][33]; +extern long partime[77],designertime[77]; +extern char volume_names[7][33]; +extern char skill_names[5][33]; + +#define MAXGAMETYPES 32 +extern char gametype_names[MAXGAMETYPES][33]; +extern int gametype_flags[MAXGAMETYPES]; +extern char num_gametypes; + +enum gametypeflags { + GAMETYPE_FLAG_COOP = 1, + GAMETYPE_FLAG_WEAPSTAY = 2, + GAMETYPE_FLAG_FRAGBAR = 4, + GAMETYPE_FLAG_SCORESHEET = 8, + GAMETYPE_FLAG_DMSWITCHES = 16, + GAMETYPE_FLAG_COOPSPAWN = 32, + GAMETYPE_FLAG_ACCESSCARDSPRITES = 64, + GAMETYPE_FLAG_COOPVIEW = 128, + GAMETYPE_FLAG_COOPSOUND = 256, + GAMETYPE_FLAG_OTHERPLAYERSINMAP = 512, + GAMETYPE_FLAG_ITEMRESPAWN = 1024, + GAMETYPE_FLAG_MARKEROPTION = 2048, + GAMETYPE_FLAG_PLAYERSFRIENDLY = 4096, + GAMETYPE_FLAG_FIXEDRESPAWN = 8192, + GAMETYPE_FLAG_ACCESSATSTART = 16384, + GAMETYPE_FLAG_PRESERVEINVENTORYDEATH = 32768 +}; + +extern char level_file_names[77][BMAX_PATH]; +extern char num_volumes; + +extern int32 SoundToggle,MusicToggle; +extern short last_threehundred,lastsavedpos; +extern char restorepalette; + +extern short buttonstat; +extern long cachecount; +extern char boardfilename[BMAX_PATH],waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768]; +extern char betaname[80]; +extern char cachedebug,earthquaketime; +extern char networkmode; +extern char lumplockbyte[11]; + +//DUKE3D.H - replace the end "my's" with this +extern long myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; +extern short myhoriz, omyhoriz, myhorizoff, omyhorizoff, globalskillsound; +extern short myang, omyang, mycursectnum, myjumpingcounter; +extern char myjumpingtoggle, myonground, myhardlanding,myreturntocenter; +extern long fakemovefifoplc; +extern long myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; +extern long myhorizbak[MOVEFIFOSIZ]; +extern short myangbak[MOVEFIFOSIZ]; + +extern short weaponsandammosprites[15]; + +//DUKE3D.H: +typedef struct { + short frag[MAXPLAYERS], got_access, last_extra, shield_amount, curr_weapon; + short ammo_amount[MAX_WEAPONS], holoduke_on; + char gotweapon[MAX_WEAPONS], inven_icon, jetpack_on, heat_on; + short firstaid_amount, steroids_amount, holoduke_amount, jetpack_amount; + short heat_amount, scuba_amount, boot_amount; + short last_weapon, weapon_pos, kickback_pic; +} STATUSBARTYPE; + +extern STATUSBARTYPE sbar; +extern short frags[MAXPLAYERS][MAXPLAYERS]; +extern long cameradist, cameraclock, dukefriction,show_shareware; +extern char networkmode, movesperpacket; +extern char gamequit; + +extern char pus,pub,camerashitable,freezerhurtowner,lasermode; +extern char syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ]; +extern signed char multiwho, multipos, multiwhat, multiflag; +extern long syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail; +extern long numfreezebounces,rpgblastradius,pipebombblastradius,tripbombblastradius,shrinkerblastradius,morterblastradius,bouncemineblastradius,seenineblastradius; +extern char stereo,playerswhenstarted,everyothertime; +extern long myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter; + +extern long numinterpolations, startofdynamicinterpolations; +extern long oldipos[MAXINTERPOLATIONS]; +extern long bakipos[MAXINTERPOLATIONS]; +extern long *curipos[MAXINTERPOLATIONS]; + +extern short numclouds,clouds[128],cloudx[128],cloudy[128]; +extern long cloudtotalclock,totalmemory; + +extern long stereomode, stereowidth, stereopixelwidth; + +extern long myaimmode, myaimstat, omyaimstat; + +#define IFISGLMODE if (getrendermode() >= 3) +#define IFISSOFTMODE if (getrendermode() < 3) + +#define TILE_SAVESHOT (MAXTILES-1) +#define TILE_LOADSHOT (MAXTILES-3) +#define TILE_TILT (MAXTILES-2) +#define TILE_ANIM (MAXTILES-4) +#define TILE_VIEWSCR (MAXTILES-5) + +extern char useprecache; + +enum events { + EVENT_INIT, + EVENT_ENTERLEVEL, + EVENT_RESETWEAPONS, + EVENT_RESETINVENTORY, + EVENT_HOLSTER, + EVENT_LOOKLEFT, + EVENT_LOOKRIGHT, + EVENT_SOARUP, + EVENT_SOARDOWN, + EVENT_CROUCH, + EVENT_JUMP, + EVENT_RETURNTOCENTER, + EVENT_LOOKUP, + EVENT_LOOKDOWN, + EVENT_AIMUP, + EVENT_FIRE, + EVENT_CHANGEWEAPON, + EVENT_GETSHOTRANGE, + EVENT_GETAUTOAIMANGLE, + EVENT_GETLOADTILE, + EVENT_CHEATGETSTEROIDS, + EVENT_CHEATGETHEAT, + EVENT_CHEATGETBOOT, + EVENT_CHEATGETSHIELD, + EVENT_CHEATGETSCUBA, + EVENT_CHEATGETHOLODUKE, + EVENT_CHEATGETJETPACK, + EVENT_CHEATGETFIRSTAID, + EVENT_QUICKKICK, + EVENT_INVENTORY, + EVENT_USENIGHTVISION, + EVENT_USESTEROIDS, + EVENT_INVENTORYLEFT, + EVENT_INVENTORYRIGHT, + EVENT_HOLODUKEON, + EVENT_HOLODUKEOFF, + EVENT_USEMEDKIT, + EVENT_USEJETPACK, + EVENT_TURNAROUND, + EVENT_DISPLAYWEAPON, + EVENT_FIREWEAPON, + EVENT_SELECTWEAPON, + EVENT_MOVEFORWARD, + EVENT_MOVEBACKWARD, + EVENT_TURNLEFT, + EVENT_TURNRIGHT, + EVENT_STRAFELEFT, + EVENT_STRAFERIGHT, + EVENT_WEAPKEY1, + EVENT_WEAPKEY2, + EVENT_WEAPKEY3, + EVENT_WEAPKEY4, + EVENT_WEAPKEY5, + EVENT_WEAPKEY6, + EVENT_WEAPKEY7, + EVENT_WEAPKEY8, + EVENT_WEAPKEY9, + EVENT_WEAPKEY10, + EVENT_DRAWWEAPON, + EVENT_DISPLAYCROSSHAIR, + EVENT_DISPLAYREST, + EVENT_RESETPLAYER, + EVENT_INCURDAMAGE, + EVENT_AIMDOWN, + EVENT_GAME, + EVENT_PREVIOUSWEAPON, + EVENT_NEXTWEAPON, + EVENT_SWIMUP, + EVENT_SWIMDOWN, + EVENT_GETMENUTILE, + EVENT_SPAWN, + EVENT_LOGO, + EVENT_EGS, + EVENT_DOFIRE, + EVENT_PRESSEDFIRE, + EVENT_USE, + EVENT_PROCESSINPUT +}; + +// store global game definitions + +enum gamevarflags { + MAXGAMEVARS = 1024, + MAXVARLABEL = 26, + GAMEVAR_FLAG_NORMAL = 0, // normal + GAMEVAR_FLAG_PERPLAYER = 1, // per-player variable + GAMEVAR_FLAG_PERACTOR = 2, // per-actor variable + GAMEVAR_FLAG_USER_MASK = 3, + GAMEVAR_FLAG_DEFAULT = 256, // allow override + GAMEVAR_FLAG_SECRET = 512, // don't dump... + GAMEVAR_FLAG_NODEFAULT = 1024, // don't add to 'default' array. + GAMEVAR_FLAG_SYSTEM = 2048, // cannot change mode flags...(only default value) + GAMEVAR_FLAG_READONLY = 4096, // values are read-only (no setvar allowed) + GAMEVAR_FLAG_PLONG = 8192, // plValue is a pointer to a long + GAMEVAR_FLAG_SYNCCHECK = 16384 // check event sync when translating +}; + +typedef struct { + long lValue; + char szLabel[MAXVARLABEL]; + unsigned long dwFlags; + + long *plValues; // array of values when 'per-player', or 'per-actor' +} MATTGAMEVAR; + +extern MATTGAMEVAR aGameVars[MAXGAMEVARS]; +extern MATTGAMEVAR aDefaultGameVars[MAXGAMEVARS]; +extern int iGameVarCount; + +extern int spriteflags[MAXTILES], actorspriteflags[MAXSPRITES]; +extern inline int checkspriteflags(short sActor, int iType); +extern inline int checkspriteflagsp(short sPicnum, int iType); + +enum spriteflags { + SPRITE_FLAG_SHADOW = 1, + SPRITE_FLAG_NVG = 2, + SPRITE_FLAG_NOSHADE = 4, + SPRITE_FLAG_PROJECTILE = 8, + SPRITE_FLAG_DECAL = 16, + SPRITE_FLAG_BADGUY = 32 +}; + +extern short spritecache[MAXTILES][3]; + +extern int g_iReturnVarID; +extern int g_iWeaponVarID; +extern int g_iWorksLikeVarID; +extern int g_iZRangeVarID; +extern int g_iAngRangeVarID; +extern int g_iAimAngleVarID; +extern int g_iLoTagID; // var ID of "LOTAG" +extern int g_iHiTagID; // ver ID of "HITAG" +extern int g_iTextureID; // ver ID of "TEXTURE" + +extern char g_bEnhanced; // are we 'enhanced' (more minerals, etc) + +extern char g_szBuf[1024]; + +#define NAM_GRENADE_LIFETIME 120 +#define NAM_GRENADE_LIFETIME_VAR 30 + +extern long *aplWeaponClip[MAX_WEAPONS]; // number of items in clip +extern long *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire) +extern long *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire +extern long *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none) +extern long *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire. +extern long *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon +extern long *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots +extern long *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item +extern long *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn +extern long *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst' +extern long *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like +extern long *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when initialy firing. zero for no sound +extern long *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic) +extern long *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time +extern long *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID +extern long *aplWeaponRenderSize[MAX_WEAPONS]; // Rendering size +extern long *aplWeaponReloadSound1[MAX_WEAPONS]; // Sound of magazine being removed +extern long *aplWeaponReloadSound2[MAX_WEAPONS]; // Sound of magazine being inserted + +extern short timer; + +enum weaponflags { + WEAPON_FLAG_HOLSTER_CLEARS_CLIP = 1, // 'holstering' clears the current clip + WEAPON_FLAG_GLOWS = 2, // weapon 'glows' (shrinker and grower) + WEAPON_FLAG_AUTOMATIC = 4, // automatic fire (continues while 'fire' is held down + WEAPON_FLAG_FIREEVERYOTHER = 8, // during 'hold time' fire every frame + WEAPON_FLAG_FIREEVERYTHIRD = 16, // during 'hold time' fire every third frame + WEAPON_FLAG_RANDOMRESTART = 32, // restart for automatic is 'randomized' by RND 3 + WEAPON_FLAG_AMMOPERSHOT = 64, // uses ammo for each shot (for automatic) + WEAPON_FLAG_BOMB_TRIGGER = 128, // weapon is the 'bomb' trigger + WEAPON_FLAG_NOVISIBLE = 256, // weapon use does not cause user to become 'visible' + WEAPON_FLAG_THROWIT = 512, // weapon 'throws' the 'shoots' item... + WEAPON_FLAG_CHECKATRELOAD = 1024, // check weapon availability at 'reload' time + WEAPON_FLAG_STANDSTILL = 2048, // player stops jumping before actual fire (like tripbomb in duke) + WEAPON_FLAG_SPAWNTYPE1 = 0, // just spawn + WEAPON_FLAG_SPAWNTYPE2 = 4096, // spawn like shotgun shells + WEAPON_FLAG_SPAWNTYPE3 = 8192, // spawn like chaingun shells + WEAPON_FLAG_SEMIAUTO = 16384, // cancel button press after each shot + WEAPON_FLAG_RELOAD_TIMING = 32768 // special casing for pistol reload sounds +}; + +#define TRIPBOMB_TRIPWIRE 1 +#define TRIPBOMB_TIMER 2 + +#define PIPEBOMB_REMOTE 1 +#define PIPEBOMB_TIMER 2 + +// custom projectiles + +enum projectileflags { + PROJECTILE_FLAG_BULLET = 1, + PROJECTILE_FLAG_RPG = 2, + PROJECTILE_FLAG_BOUNCESOFFWALLS = 4, + PROJECTILE_FLAG_BOUNCESOFFMIRRORS = 8, + PROJECTILE_FLAG_KNEE = 16, + PROJECTILE_FLAG_WATERBUBBLES = 32, + PROJECTILE_FLAG_TIMED = 64, + PROJECTILE_FLAG_NOENEMYHITS = 128, + PROJECTILE_FLAG_SPIT = 256, + PROJECTILE_FLAG_COOLEXPLOSION1 = 512, + PROJECTILE_FLAG_BLOOD = 1024, + PROJECTILE_FLAG_LOSESVELOCITY = 2048, + PROJECTILE_FLAG_NOAIM = 4096, + PROJECTILE_FLAG_RANDDECALSIZE = 8192, + PROJECTILE_FLAG_EXPLODEONTIMER = 16384, + PROJECTILE_FLAG_RPG_IMPACT = 32768 +}; + +typedef struct { + int workslike, extra, cstat, extra_rand, hitradius, range; + short spawns, sound, isound, vel, decal, trail, tnum, drop, clipdist, offset, bounces, bsound, toffset; + signed char sxrepeat, syrepeat, txrepeat, tyrepeat, shade, xrepeat, yrepeat, pal, velmult; +} proj_struct; + +proj_struct projectile[MAXTILES], thisprojectile[MAXSPRITES], defaultprojectile[MAXTILES]; + +// logo control + +enum logoflags { + LOGO_FLAG_ENABLED = 1, + LOGO_FLAG_PLAYANIM = 2, + LOGO_FLAG_PLAYMUSIC = 4, + LOGO_FLAG_3DRSCREEN = 8, + LOGO_FLAG_TITLESCREEN = 16, + LOGO_FLAG_DUKENUKEM = 32, + LOGO_FLAG_THREEDEE = 64, + LOGO_FLAG_PLUTOPAKSPRITE = 128 +}; + +extern char numl, condebug; + +extern char cheatkey[2]; + +#define MAXCHEATLEN 20 + +extern short weapon_sprites[MAX_WEAPONS]; + +#ifdef __cplusplus +} +#endif diff --git a/polymer/eduke32/source/funct.h b/polymer/eduke32/source/funct.h new file mode 100644 index 000000000..423d161a1 --- /dev/null +++ b/polymer/eduke32/source/funct.h @@ -0,0 +1,355 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef __funct_h__ +#define __funct_h__ + +struct player_struct; // JBF: duke3d.h defines this later + +extern void sendscore(char *s); +extern void SoundStartup(void ); +extern void SoundShutdown(void ); +extern void MusicStartup(void ); +extern void MusicShutdown(void ); +extern int USRHOOKS_GetMem(char **ptr,unsigned long size); +extern int USRHOOKS_FreeMem(char *ptr); +extern void intomenusounds(void ); +extern void playmusic(char *fn); +extern char loadsound(unsigned short num); +extern int xyzsound(short num,short i,long x,long y,long z); +extern void sound(short num); +extern int spritesound(unsigned short num,short i); +extern void stopsound(short num); +extern void stopenvsound(short num,short i); +extern void pan3dsound(void ); +extern void testcallback(unsigned long num); +extern void clearsoundlocks(void); +extern short callsound(short sn,short whatsprite); +extern short check_activator_motion(short lotag); +extern char isadoorwall(short dapic); +extern char isanunderoperator(short lotag); +extern char isanearoperator(short lotag); +extern short checkcursectnums(short sect); +extern long ldist(spritetype *s1,spritetype *s2); +extern long dist(spritetype *s1,spritetype *s2); +extern short findplayer(spritetype *s,long *d); +extern short findotherplayer(short p,long *d); +extern void doanimations(void ); +extern int getanimationgoal(long *animptr); +extern int setanimation(short animsect,long *animptr,long thegoal,long thevel); +extern void animatecamsprite(void ); +extern void animatewalls(void ); +extern char activatewarpelevators(short s,short d); +extern void operatesectors(short sn,short ii); +extern void operaterespawns(short low); +extern void operateactivators(short low,short snum); +extern void operatemasterswitches(short low); +extern void operateforcefields(short s,short low); +extern char checkhitswitch(short snum,long w,char switchtype); +extern void activatebysector(short sect,short j); +extern void checkhitwall(short spr,short dawallnum,long x,long y,long z,short atwith); +extern void checkplayerhurt(struct player_struct *p,short j); +extern char checkhitceiling(short sn); +extern void checkhitsprite(short i,short sn); +extern void allignwarpelevators(void ); +extern void cheatkeys(short snum); +extern void checksectors(short snum); +extern int32 RTS_AddFile(char *filename); +extern void RTS_Init(char *filename); +extern int32 RTS_NumSounds(void ); +extern int32 RTS_SoundLength(int32 lump); +extern char *RTS_GetSoundName(int32 i); +extern void RTS_ReadLump(int32 lump,void *dest); +extern void *RTS_GetSound(int32 lump); +extern void docacheit(void); +extern void xyzmirror(short i,short wn); +extern void vscrn(void ); +extern void pickrandomspot(short snum); +extern void resetplayerstats(short snum); +extern void resetweapons(short snum); +extern void resetinventory(short snum); +extern void resetprestat(short snum,char g); +extern void setupbackdrop(short backpicnum); +extern void cachespritenum(short i); +extern void cachegoodsprites(void ); +extern void prelevel(char g); +extern void newgame(char vn,char ln,char sk); +extern void resetpspritevars(char g); +extern void resettimevars(void ); +extern void genspriteremaps(void ); +extern void waitforeverybody(void); +extern char checksum(long sum); +extern char getsound(unsigned short num); +extern void precachenecessarysounds(void ); +extern void cacheit(void ); +extern void dofrontscreens(char *); +extern void clearfifo(void); +extern void resetmys(void); +extern int enterlevel(char g); +extern void backtomenu(void); +extern void setpal(struct player_struct *p); +extern void incur_damage(short snum); +extern void quickkill(struct player_struct *p); +extern void forceplayerangle(struct player_struct *p); +extern void tracers(long x1,long y1,long z1,long x2,long y2,long z2,long n); +extern long hits(short i); +extern long hitasprite(short i,short *hitsp); +extern long hitawall(struct player_struct *p,short *hitw); +extern short aim(spritetype *s,short aang); +extern short shoot(short i,short atwith); +extern void displayloogie(short snum); +extern char animatefist(short gs,short snum); +extern char animateknee(short gs,short snum); +extern char animateknuckles(short gs,short snum); +extern void displaymasks(short snum); +extern char animatetip(short gs,short snum); +extern char animateaccess(short gs,short snum); +extern void displayweapon(short snum); +extern void getinput(short snum); +extern char doincrements(struct player_struct *p); +extern void checkweapons(struct player_struct *p); +extern void processinput(short snum); +extern void cmenu(short cm); +extern void savetemp(char *fn,long daptr,long dasiz); +extern void getangplayers(short snum); +// extern int loadpheader(char spot,int32 *vn,int32 *ln,int32 *psk,int32 *numplr); +extern int loadplayer(signed char spot); +extern int saveplayer(signed char spot); +extern void sendgameinfo(void ); +extern int probe(int x,int y,int i,int n); +extern int menutext(int x,int y,short s,short p,char *t); +extern void bar(int x,int y,short *p,short dainc,char damodify,short s,short pa); +extern void barsm(int x,int y,short *p,short dainc,char damodify,short s,short pa); +extern void dispnames(void ); +extern int getfilenames(char *path, char kind[]); +extern void sortfilenames(void); +extern void menus(void ); +extern void palto(char r,char g,char b,long e); +extern void drawoverheadmap(long cposx,long cposy,long czoom,short cang); +extern void playanm(char *fn,char); +extern short getincangle(short a,short na); +extern char ispecial(char c); +extern char isaltok(char c); +extern void getglobalz(short sActor); +extern void makeitfall(short sActor); +extern void getlabel(void ); +extern long keyword(void ); +extern long transword(void ); +extern long transnum(long type); +extern char parsecommand(void ); +extern void passone(void ); +extern void loadefs(char *fn); +extern char dodge(spritetype *s); +extern short furthestangle(short sActor,short angs); +extern short furthestcanseepoint(short sActor,spritetype *ts,long *dax,long *day); +extern void alterang(short a); +extern void move(void); +extern void parseifelse(long condition); +extern char parse(void ); +extern void execute(short sActor,short sPlayer,long lDist); +extern void overwritesprite(long thex,long they,short tilenum,signed char shade,char stat,char dapalnum); +extern void timerhandler(void); +extern int gametext(int x,int y,char *t,char s,short dabits); +extern int gametextpal(int x,int y,char *t,char s,char p); +extern int minitext(int x,int y,char *t,char p,short sb); +extern void gamenumber(long x,long y,long n,char s); +extern void Shutdown(void ); +extern void allowtimetocorrecterrorswhenquitting(void ); +extern void getpackets(void ); +extern void faketimerhandler(void); +extern void checksync(void ); +extern void check_fta_sounds(short i); +extern inline short inventory(spritetype *s); +extern short badguy(spritetype *s); +extern short badguypic(short pn); +extern void myos(long x,long y,short tilenum,signed char shade,char orientation); +extern void myospal(long x,long y,short tilenum,signed char shade,char orientation,char p); +extern void invennum(long x,long y,char num1,char ha,char sbits); +extern void weaponnum(short ind,long x,long y,long num1,long num2,char ha); +extern void weaponnum999(char ind,long x,long y,long num1,long num2,char ha); +extern void weapon_amounts(struct player_struct *p,long x,long y,long u); +extern void digitalnumber(long x,long y,long n,char s,char cs); +extern void scratchmarks(long x,long y,long n,char s,char p); +extern void displayinventory(struct player_struct *p); +extern void displayfragbar(void ); +extern void coolgaugetext(short snum); +extern void tics(void ); +extern void clocks(void ); +extern void coords(short snum); +extern void operatefta(void); +extern void FTA(short q,struct player_struct *p); +extern void showtwoscreens(void ); +extern void binscreen(void ); +extern void gameexit(char *t); +extern short strget(short x,short y,char *t,short dalen,short c); +extern void displayrest(long smoothratio); +extern void updatesectorz(long x,long y,long z,short *sectnum); +extern void view(struct player_struct *pp,long *vx,long *vy,long *vz,short *vsectnum,short ang,short horiz); +extern void drawbackground(void ); +extern void displayrooms(short snum,long smoothratio); +extern short LocateTheLocator(short n,short sn); +extern short EGS(short whatsect,long s_x,long s_y,long s_z,short s_pn,signed char s_s,signed char s_xr,signed char s_yr,short s_a,short s_ve,long s_zv,short s_ow,signed char s_ss); +extern char wallswitchcheck(short i); +extern short spawn(short j,short pn); +extern void animatesprites(long x,long y,short a,long smoothratio); +extern void cheats(void ); +extern void nonsharedkeys(void ); +extern void comlinehelp(char **argv); +extern void checkcommandline(int argc,char **argv); +extern void printstr(short x,short y,char string[],char attribute); +extern void Logo(void ); +extern void loadtmb(void ); +extern void compilecons(void ); +extern void Startup(void ); +extern void getnames(void ); +extern int main(int argc,char **argv); +extern char opendemoread(char which_demo); +extern void opendemowrite(void ); +extern void record(void ); +extern void closedemowrite(void ); +extern long playback(void ); +extern char moveloop(void); +extern void fakedomovethingscorrect(void); +extern void fakedomovethings(void ); +extern char domovethings(void ); +extern void displaybonuspics(short x,short y,short p); +extern void doorders(void ); +extern void dobonus(char bonusonly); +extern void cameratext(short i); +extern void vglass(long x,long y,short a,short wn,short n); +extern void lotsofglass(short i,short wallnum,short n); +extern void spriteglass(short i,short n); +extern void ceilingglass(short i,short sectnum,short n); +extern void lotsofcolourglass(short i,short wallnum,short n); +extern void SetupGameButtons(void ); +extern long GetTime(void ); +extern void CenterCenter(void ); +extern void UpperLeft(void ); +extern void LowerRight(void ); +extern void CenterThrottle(void ); +extern void CenterRudder(void ); +extern void CONFIG_GetSetupFilename(void ); +extern int32 CONFIG_FunctionNameToNum(char *func); +extern char *CONFIG_FunctionNumToName(int32 func); +extern int32 CONFIG_AnalogNameToNum(char *func); +extern char *CONFIG_AnalogNumToName(int32 func); +extern void CONFIG_SetDefaults(void ); +extern void CONFIG_ReadKeys(void ); +extern void readsavenames(void ); +extern void CONFIG_ReadSetup(void ); +extern void CONFIG_WriteSetup(void ); +extern void CheckAnimStarted(char *funcname); +extern uint16 findpage(uint16 framenumber); +extern void loadpage(uint16 pagenumber,uint16 *pagepointer); +extern void CPlayRunSkipDump(char *srcP,char *dstP); +extern void renderframe(uint16 framenumber,uint16 *pagepointer); +extern void drawframe(uint16 framenumber); +extern void updateinterpolations(void); +extern void setinterpolation(long *posptr); +extern void stopinterpolation(long *posptr); +extern void dointerpolations(long smoothratio); +extern void restoreinterpolations(void); +extern long ceilingspace(short sectnum); +extern long floorspace(short sectnum); +extern void addammo(short weapon,struct player_struct *p,short amount); +extern void addweaponnoswitch(struct player_struct *p,short weapon); +extern void addweapon(struct player_struct *p,short weapon); +extern void checkavailinven(struct player_struct *p); +extern void checkavailweapon(struct player_struct *p); +extern long ifsquished(short i,short p); +extern void hitradius(short i,long r,long hp1,long hp2,long hp3,long hp4); +extern int movesprite(short spritenum,long xchange,long ychange,long zchange,unsigned long cliptype); +extern short ssp(short i,unsigned long cliptype); +extern void insertspriteq(short i); +extern void lotsofmoney(spritetype *s,short n); +extern void lotsofmail(spritetype *s, short n); +extern void lotsofpaper(spritetype *s, short n); +extern void guts(spritetype *s,short gtype,short n,short p); +extern void setsectinterpolate(short i); +extern void clearsectinterpolate(short i); +extern void ms(short i); +extern void movefta(void ); +extern short ifhitsectors(short sectnum); +extern short ifhitbyweapon(short sn); +extern void movecyclers(void ); +extern void movedummyplayers(void ); +extern void moveplayers(void ); +extern void movefx(void ); +extern void movefallers(void ); +extern void movestandables(void ); +extern void bounce(short i); +extern void moveweapons(void ); +extern void movetransports(void ); +extern void moveeffectors(void ); +extern void moveactors(void ); +extern void moveexplosions(void ); + +// game.c +extern void setstatusbarscale(long sc); + +extern void setgamepalette(struct player_struct *player, char *pal, int set); +extern void fadepal(int r, int g, int b, int start, int end, int step); + +extern int minitextshade(int x,int y,char *t,char s,char p,short sb); +extern int txgametext(int starttile, int x,int y,char *t,char s,char p,short orientation,long x1, long y1, long x2, long y2); +extern void txdigitalnumber(short starttile, long x,long y,long n,char s,char pal,char cs,long x1, long y1, long x2, long y2); +extern long txdist(spritetype *s1,spritetype *s2); +extern void myosx(long x,long y,short tilenum,signed char shade,char orientation); +extern void myospalx(long x,long y,short tilenum,signed char shade,char orientation,char p); +extern void ResetGameVars(void); +extern void ResetActorGameVars(short sActor); + +extern void sanitizegametype(); +// extern void readnames(); +extern void setupdynamictostatic(); +extern void processnames(char *szLabel, long lValue); + +extern void LoadActor(short sActor, short sPlayer, long lDist); + +extern long GetGameVar(char *szGameLabel, long lDefault, short sActor, short sPlayer); +extern void DumpGameVars(FILE *fp); +extern void AddLog(char *psz); + +extern void ResetSystemDefaults(void); +extern void InitGameVarPointers(void); +extern void InitGameVars(void); +extern void SaveGameVars(FILE *fil); +extern void ReadGameVars(long fil); + +extern int GetGameID(char *szGameLabel); +extern long GetGameVarID(int id, short sActor, short sPlayer); +extern void SetGameVarID(int id, long lValue, short sActor, short sPlayer); + +extern void onvideomodechange(int newmode); + +extern void OnEvent(int iEventID, short sActor,short sPlayer,long lDist); + +extern int isspritemakingsound(short i, int num); +extern int issoundplaying(int num); +extern void stopspritesound(short num, short i); + +#endif // __funct_h__ diff --git a/polymer/eduke32/source/function.h b/polymer/eduke32/source/function.h new file mode 100644 index 000000000..4eef07153 --- /dev/null +++ b/polymer/eduke32/source/function.h @@ -0,0 +1,105 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +// function.h + +// file created by makehead.exe +// these headers contain default key assignments, as well as +// default button assignments and game function names +// axis defaults are also included + + +#ifndef _function_public_ +#define _function_public_ +#ifdef __cplusplus +extern "C" { +#endif + +#define NUMGAMEFUNCTIONS 53 + +extern char * gamefunctions[]; + +enum + { + gamefunc_Move_Forward, + gamefunc_Move_Backward, + gamefunc_Turn_Left, + gamefunc_Turn_Right, + gamefunc_Strafe, + gamefunc_Fire, + gamefunc_Open, + gamefunc_Run, + gamefunc_AutoRun, + gamefunc_Jump, + gamefunc_Crouch, + gamefunc_Look_Up, + gamefunc_Look_Down, + gamefunc_Look_Left, + gamefunc_Look_Right, + gamefunc_Strafe_Left, + gamefunc_Strafe_Right, + gamefunc_Aim_Up, + gamefunc_Aim_Down, + gamefunc_Weapon_1, + gamefunc_Weapon_2, + gamefunc_Weapon_3, + gamefunc_Weapon_4, + gamefunc_Weapon_5, + gamefunc_Weapon_6, + gamefunc_Weapon_7, + gamefunc_Weapon_8, + gamefunc_Weapon_9, + gamefunc_Weapon_10, + gamefunc_Inventory, + gamefunc_Inventory_Left, + gamefunc_Inventory_Right, + gamefunc_Holo_Duke, + gamefunc_Jetpack, + gamefunc_NightVision, + gamefunc_MedKit, + gamefunc_TurnAround, + gamefunc_SendMessage, + gamefunc_Map, + gamefunc_Shrink_Screen, + gamefunc_Enlarge_Screen, + gamefunc_Center_View, + gamefunc_Holster_Weapon, + gamefunc_Show_Opponents_Weapon, + gamefunc_Map_Follow_Mode, + gamefunc_See_Coop_View, + gamefunc_Mouse_Aiming, + gamefunc_Toggle_Crosshair, + gamefunc_Steroids, + gamefunc_Quick_Kick, + gamefunc_Next_Weapon, + gamefunc_Previous_Weapon, + gamefunc_Show_Console + }; +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c new file mode 100644 index 000000000..f9ac23dd8 --- /dev/null +++ b/polymer/eduke32/source/game.c @@ -0,0 +1,10479 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "types.h" +#include "develop.h" +#include "scriplib.h" +#include "file_lib.h" +#include "mathutil.h" +#include "gamedefs.h" +#include "keyboard.h" +#include "mouse.h" // JBF 20030809 +#include "function.h" +#include "control.h" +#include "fx_man.h" +#include "sounds.h" +#include "config.h" + +#include "osd.h" +#include "osdfuncs.h" +#include "osdcmds.h" + +//#include "crc32.h" + +#include "duke3d.h" + +#include "util_lib.h" + +#define VERSION " 1.3.1-2" + +#define HEAD "EDuke32"VERSION" (shareware mode)" +#define HEAD2 "EDuke32"VERSION + +#define IDFSIZE 479985668 +#define IDFILENAME "DUKE3D.IDF" + +#define TIMERUPDATESIZ 32 + +long cameradist = 0, cameraclock = 0; +char playerswhenstarted; +char qe,cp; + +static int32 CommandSoundToggleOff = 0; +static int32 CommandMusicToggleOff = 0; +static char *CommandMap = NULL; +static char *CommandName = NULL; + +char confilename[BMAX_PATH] = {"EDUKE.CON"}, boardfilename[BMAX_PATH] = {0}; +char waterpal[768], slimepal[768], titlepal[768], drealms[768], endingpal[768]; +char firstdemofile[80] = { '\0' }; +int display_bonus_screen = 1, userconfiles = 0; + +static int netparamcount = 0; +static char **netparam = NULL; + +void setstatusbarscale(long sc) +{ + ud.statusbarscale = min(100,max(10,sc)); + vscrn(); +} + +static inline long sbarx(long x) +{ + if (ud.screen_size == 4) return scale(x<<16,ud.statusbarscale,100); + return (((320l<<16) - scale(320l<<16,ud.statusbarscale,100)) >> 1) + scale(x<<16,ud.statusbarscale,100); +} + +static inline long sbary(long y) +{ + return ((200l<<16) - scale(200l<<16,ud.statusbarscale,100) + scale(y<<16,ud.statusbarscale,100)); +} + +static inline long sbarsc(long sc) +{ + return scale(sc,ud.statusbarscale,100); +} + +void patchstatusbar(long x1, long y1, long x2, long y2) +{ + long scl, tx, ty; + long clx1,cly1,clx2,cly2,clofx,clofy; + + scl = sbarsc(65536); + tx = sbarx(0); ty = sbary(200-tilesizy[BOTTOMSTATUSBAR]); + + clx1 = scale(scale(x1,xdim,320),ud.statusbarscale,100); + cly1 = scale(scale(y1,ydim,200),ud.statusbarscale,100); + clx2 = scale(scale(x2,xdim,320),ud.statusbarscale,100); + cly2 = scale(scale(y2,ydim,200),ud.statusbarscale,100); + clofx = (xdim - scale(xdim,ud.statusbarscale,100)) >> 1; + clofy = (ydim - scale(ydim,ud.statusbarscale,100)); + + rotatesprite(tx,ty,scl,0,BOTTOMSTATUSBAR,4,0,10+16+64,clx1+clofx,cly1+clofy,clx2+clofx-1,cly2+clofy-1); +} + +int recfilep,totalreccnt; +char debug_on = 0,actor_tog = 0,*rtsptr,memorycheckoveride=0; + +extern char syncstate; +extern int32 numlumps; + +FILE *frecfilep = (FILE *)NULL; +void pitch_test( void ); + +char restorepalette,screencapt,nomorelogohack; +int sendmessagecommand = -1; + +static char *duke3dgrp = "duke3d.grp"; // JBF 20030925 +static char *duke3ddef = "duke3d.def"; + +extern long lastvisinc; + +// JBF 20031221: These ought to disappear when things mature +extern int showmultidiags; +extern int netmode, nethostplayers; +extern char netjoinhost[64]; +int startupnetworkgame(void); +int processnetworkrequests(void); + +void setgamepalette(struct player_struct *player, char *pal, int set) +{ + if (player != &ps[screenpeek]) { + // another head + player->palette = pal; + return; + } + + if (getrendermode() < 3) { + // 8-bit mode + player->palette = pal; + setbrightness(ud.brightness>>2, pal, set); + //pub = pus = NUMPAGES; + return; + } + + if (pal == palette || pal == waterpal || pal == slimepal) { + if (player->palette != palette && player->palette != waterpal && player->palette != slimepal) + setbrightness(ud.brightness>>2, palette, set); + else setpalettefade(0,0,0,0); + } else { + setbrightness(ud.brightness>>2, pal, set); + } + player->palette = pal; +} + +int txgametext(int starttile, int x,int y,char *t,char s,char p,short orientation,long x1, long y1, long x2, long y2) +{ + short ac,newx; + char centre, *oldt; + + centre = ( x == (320>>1) ); + newx = 0; + oldt = t; + + if(centre) + { + while(*t) + { + if(*t == 32) {newx+=5;t++;continue;} + else ac = *t - '!' + starttile; + + if( ac < starttile || ac > (starttile + 93) ) break; + + if(*t >= '0' && *t <= '9') + newx += 8; + else newx += tilesizx[ac]; + t++; + } + + t = oldt; + x = (320>>1)-(newx>>1); + } + + while(*t) + { + if(*t == 32) {x+=5;t++;continue;} + else ac = *t - '!' + starttile; + + if( ac < starttile || ac > (starttile + 93) ) + break; + + rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,2|orientation,x1,y1,x2,y2); + if(*t >= '0' && *t <= '9') + x += 8; + else x += tilesizx[ac]; + + t++; + } + + return (x); +} + +inline int gametext(int x,int y,char *t,char s,short dabits) +{ + return(txgametext(STARTALPHANUM, x,y,t,s,0,dabits,0, 0, xdim-1, ydim-1)); +} + +inline int gametextpal(int x,int y,char *t,char s,char p) +{ + return(txgametext(STARTALPHANUM, x,y,t,s,p,26,0, 0, xdim-1, ydim-1)); +} + +int minitextshade(int x,int y,char *t,char s,char p,short sb) +{ + short ac; + char ch,cmode; + + cmode = (sb&256)!=0; + sb &= 255; + + while(*t) + { + ch = Btoupper(*t); + if(ch == 32) {x+=5;t++;continue;} + else ac = ch - '!' + MINIFONT; + + if (cmode) rotatesprite(sbarx(x),sbary(y),sbarsc(65536L),0,ac,s,p,sb,0,0,xdim-1,ydim-1); + else rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,sb,0,0,xdim-1,ydim-1); + x += 4; // tilesizx[ac]+1; + + t++; + } + return (x); +} + +inline int minitext(int x,int y,char *t,char p,short sb) +{ + return (minitextshade(x,y,t,0,p,sb)); +} + +void gamenumber(long x,long y,long n,char s) +{ + char b[10]; + //ltoa(n,b,10); + Bsnprintf(b,10,"%ld",n); + gametext(x,y,b,s,2+8+16); +} + +char recbuf[80]; +void allowtimetocorrecterrorswhenquitting(void) +{ + long i, j, oldtotalclock; + + ready2send = 0; + + for(j=0;j<8;j++) + { + oldtotalclock = totalclock; + + while (totalclock < oldtotalclock+TICSPERFRAME) { + handleevents(); + getpackets(); + } + if(KB_KeyPressed(sc_Escape)) return; + + packbuf[0] = 127; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) sendpacket(i,packbuf,1); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + } +} + +#define MAXUSERQUOTES 4 +long quotebot, quotebotgoal; +short user_quote_time[MAXUSERQUOTES]; +char user_quote[MAXUSERQUOTES][128]; +// char typebuflen,typebuf[41]; + +void adduserquote(char *daquote) +{ + long i; + + for(i=MAXUSERQUOTES-1;i>0;i--) + { + strcpy(user_quote[i],user_quote[i-1]); + user_quote_time[i] = user_quote_time[i-1]; + } + strcpy(user_quote[0],daquote); + OSD_Printf("%s\n", daquote); + user_quote_time[0] = 180; + pub = NUMPAGES; +} + +void getpackets(void) +{ + long i, j, k, l; + FILE *fp; + long other, packbufleng; + input *osyn, *nsyn; + + sampletimer(); + AudioUpdate(); + + // only dispatch commands here when not in a game + if( !(ps[myconnectindex].gm&MODE_GAME) ) { OSD_DispatchQueued(); } + + if(qe == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && KB_KeyPressed(sc_Delete)) + { + qe = 1; + gameexit("Quick Exit."); + } + + if (numplayers < 2) return; + while ((packbufleng = getpacket(&other,packbuf)) > 0) + { + switch(packbuf[0]) + { + case 126: + //Slaves in M/S mode only send to master + //Master re-transmits message to all others + if ((!networkmode) && (myconnectindex == connecthead)) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (i != other) sendpacket(i,packbuf,packbufleng); + + multiflag = 2; + multiwhat = 0; + multiwho = packbuf[2]; //other: need to send in m/s mode because of possible re-transmit + multipos = packbuf[1]; + loadplayer( multipos ); + multiflag = 0; + break; + case 0: //[0] (receive master sync buffer) + j = 1; + + if ((movefifoend[other]&(TIMERUPDATESIZ-1)) == 0) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + { + if (playerquitflag[i] == 0) continue; + if (i == myconnectindex) + otherminlag = (long)((signed char)packbuf[j]); + j++; + } + + osyn = (input *)&inputfifo[(movefifoend[connecthead]-1)&(MOVEFIFOSIZ-1)][0]; + nsyn = (input *)&inputfifo[(movefifoend[connecthead])&(MOVEFIFOSIZ-1)][0]; + + k = j; + for(i=connecthead;i>=0;i=connectpoint2[i]) + j += playerquitflag[i] + playerquitflag[i]; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerquitflag[i] == 0) continue; + + l = packbuf[k++]; + l |= (long)packbuf[k++] << 8; + + if (i == myconnectindex) + { j += ((l&1)<<1)+(l&2)+((l&4)>>2)+((l&8)>>3)+((l&16)>>4)+((l&32)>>5)+((l&64)>>6)+((l&128)>>7)+((l&256)>>8)+((l&512)>>9)+((l&1024)>>10)+((l&2048)>>11); continue; } + + copybufbyte(&osyn[i],&nsyn[i],sizeof(input)); + if (l&1) nsyn[i].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; + if (l&2) nsyn[i].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; + if (l&4) nsyn[i].avel = (signed char)packbuf[j++]; + if (l&8) nsyn[i].bits = ((nsyn[i].bits&0xffffff00)|((long)packbuf[j++])); + if (l&16) nsyn[i].bits = ((nsyn[i].bits&0xffff00ff)|((long)packbuf[j++])<<8); + if (l&32) nsyn[i].bits = ((nsyn[i].bits&0xff00ffff)|((long)packbuf[j++])<<16); + if (l&64) nsyn[i].bits = ((nsyn[i].bits&0x00ffffff)|((long)packbuf[j++])<<24); + if (l&128) nsyn[i].horz = (signed char)packbuf[j++]; + if (l&256) nsyn[i].bits2 = ((nsyn[i].bits2&0xffffff00)|((long)packbuf[j++])); + if (l&512) nsyn[i].bits2 = ((nsyn[i].bits2&0xffff00ff)|((long)packbuf[j++])<<8); + if (l&1024) nsyn[i].bits2 = ((nsyn[i].bits2&0xff00ffff)|((long)packbuf[j++])<<16); + if (l&2048) nsyn[i].bits2 = ((nsyn[i].bits2&0x00ffffff)|((long)packbuf[j++])<<24); + + if (nsyn[i].bits&(1<<26)) playerquitflag[i] = 0; + movefifoend[i]++; + } + + while (j != packbufleng) + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if(i != myconnectindex) + { + syncval[i][syncvalhead[i]&(MOVEFIFOSIZ-1)] = packbuf[j]; + syncvalhead[i]++; + } + j++; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + for(j=1;j=0;i=connectpoint2[i]) + if (i != other) + sendpacket(i,packbuf,packbufleng); + } + else if (((long)packbuf[1]) != myconnectindex) + { + //Master re-transmits message not intended for master + sendpacket((long)packbuf[1],packbuf,packbufleng); + break; + } + } + + strcpy(recbuf,packbuf+2); + recbuf[packbufleng-2] = 0; + + adduserquote(recbuf); + sound(EXITMENUSOUND); + + pus = NUMPAGES; + pub = NUMPAGES; + + break; + + case 5: + //Slaves in M/S mode only send to master + //Master re-transmits message to all others + if ((!networkmode) && (myconnectindex == connecthead)) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (i != other) sendpacket(i,packbuf,packbufleng); + + ud.m_level_number = ud.level_number = packbuf[1]; + ud.m_volume_number = ud.volume_number = packbuf[2]; + ud.m_player_skill = ud.player_skill = packbuf[3]; + ud.m_monsters_off = ud.monsters_off = packbuf[4]; + ud.m_respawn_monsters = ud.respawn_monsters = packbuf[5]; + ud.m_respawn_items = ud.respawn_items = packbuf[6]; + ud.m_respawn_inventory = ud.respawn_inventory = packbuf[7]; + ud.m_coop = packbuf[8]; + ud.m_marker = ud.marker = packbuf[9]; + ud.m_ffire = ud.ffire = packbuf[10]; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + resetweapons(i); + resetinventory(i); + } + + newgame(ud.volume_number,ud.level_number,ud.player_skill); + ud.coop = ud.m_coop; + + if (enterlevel(MODE_GAME)) backtomenu(); + + break; + case 6: + //slaves in M/S mode only send to master + //Master re-transmits message to all others + if ((!networkmode) && (myconnectindex == connecthead)) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (i != other) sendpacket(i,packbuf,packbufleng); + + if (packbuf[2] != BYTEVERSION) + gameexit("\nYou cannot play Duke with different versions."); + + other = packbuf[1]; + + for (i=3;packbuf[i];i++) + ud.user_name[other][i-3] = packbuf[i]; + ud.user_name[other][i-3] = 0; + i++; + + j = i; //This used to be Duke packet #9... now concatenated with Duke packet #6 + for (;i-j<10;i++) ud.wchoice[other][i-j] = packbuf[i]; + + ps[other].aim_mode = packbuf[i++]; + ps[other].auto_aim = packbuf[i++]; + ps[other].weaponswitch = packbuf[i++]; + + break; + case 7: + //slaves in M/S mode only send to master + //Master re-transmits message to all others + if ((!networkmode) && (myconnectindex == connecthead)) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (i != other) sendpacket(i,packbuf,packbufleng); + + if(numlumps == 0) break; + + if (SoundToggle == 0 || ud.lockout == 1 || FXDevice < 0 ) + break; + rtsptr = (char *)RTS_GetSound(packbuf[1]-1); + if (*rtsptr == 'C') + FX_PlayVOC3D(rtsptr,0,0,0,255,-packbuf[1]); + else + FX_PlayWAV3D(rtsptr,0,0,0,255,-packbuf[1]); + rtsplaying = 7; + break; + case 8: + //Slaves in M/S mode only send to master + //Master re-transmits message to all others + if ((!networkmode) && (myconnectindex == connecthead)) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (i != other) sendpacket(i,packbuf,packbufleng); + + ud.m_level_number = ud.level_number = packbuf[1]; + ud.m_volume_number = ud.volume_number = packbuf[2]; + ud.m_player_skill = ud.player_skill = packbuf[3]; + ud.m_monsters_off = ud.monsters_off = packbuf[4]; + ud.m_respawn_monsters = ud.respawn_monsters = packbuf[5]; + ud.m_respawn_items = ud.respawn_items = packbuf[6]; + ud.m_respawn_inventory = ud.respawn_inventory = packbuf[7]; + ud.m_coop = ud.coop = packbuf[8]; + ud.m_marker = ud.marker = packbuf[9]; + ud.m_ffire = ud.ffire = packbuf[10]; + + copybufbyte(packbuf+10,boardfilename,packbufleng-11); + boardfilename[packbufleng-11] = 0; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + resetweapons(i); + resetinventory(i); + } + + newgame(ud.volume_number,ud.level_number,ud.player_skill); + if (enterlevel(MODE_GAME)) backtomenu(); + break; + + case 16: + movefifoend[other] = movefifoplc = movefifosendplc = fakemovefifoplc = 0; + syncvalhead[other] = syncvaltottail = 0L; + case 17: + j = 1; + + if ((movefifoend[other]&(TIMERUPDATESIZ-1)) == 0) + if (other == connecthead) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + { + if (i == myconnectindex) + otherminlag = (long)((signed char)packbuf[j]); + j++; + } + + osyn = (input *)&inputfifo[(movefifoend[other]-1)&(MOVEFIFOSIZ-1)][0]; + nsyn = (input *)&inputfifo[(movefifoend[other])&(MOVEFIFOSIZ-1)][0]; + + copybufbyte(&osyn[other],&nsyn[other],sizeof(input)); + k = packbuf[j++]; + k |= (long)packbuf[j++] << 8; + if (k&1) nsyn[other].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; + if (k&2) nsyn[other].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; + if (k&4) nsyn[other].avel = (signed char)packbuf[j++]; + if (k&8) nsyn[other].bits = ((nsyn[other].bits&0xffffff00)|((long)packbuf[j++])); + if (k&16) nsyn[other].bits = ((nsyn[other].bits&0xffff00ff)|((long)packbuf[j++])<<8); + if (k&32) nsyn[other].bits = ((nsyn[other].bits&0xff00ffff)|((long)packbuf[j++])<<16); + if (k&64) nsyn[other].bits = ((nsyn[other].bits&0x00ffffff)|((long)packbuf[j++])<<24); + if (k&128) nsyn[other].horz = (signed char)packbuf[j++]; + if (k&256) nsyn[other].bits2 = ((nsyn[other].bits2&0xffffff00)|((long)packbuf[j++])); + if (k&512) nsyn[other].bits2 = ((nsyn[other].bits2&0xffff00ff)|((long)packbuf[j++])<<8); + if (k&1024) nsyn[other].bits2 = ((nsyn[other].bits2&0xff00ffff)|((long)packbuf[j++])<<16); + if (k&2048) nsyn[other].bits2 = ((nsyn[other].bits2&0x00ffffff)|((long)packbuf[j++])<<24); + movefifoend[other]++; + + for(i=1;i packbufleng) + initprintf("INVALID GAME PACKET!!! (%ld too many bytes)\n",j-packbufleng); + + while (j != packbufleng) + { + syncval[other][syncvalhead[other]&(MOVEFIFOSIZ-1)] = packbuf[j++]; + syncvalhead[other]++; + } + + break; + case 127: + break; + + case 250: + playerreadyflag[other]++; + break; + case 255: + gameexit(" "); + break; + } + } +} + +extern void computergetinput(long snum, input *syn); + +void faketimerhandler() +{ + long i, j, k, l; + long momx, momy; + // short who; + input *osyn, *nsyn; + + if(qe == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && KB_KeyPressed(sc_Delete)) + { + qe = 1; + gameexit("Quick Exit."); + } + + sampletimer(); + AudioUpdate(); + if ((totalclock < ototalclock+TICSPERFRAME) || (ready2send == 0)) return; + ototalclock += TICSPERFRAME; + + getpackets(); if (getoutputcirclesize() >= 16) return; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + if (movefifoend[i] < movefifoend[myconnectindex]-200) return; + + getinput(myconnectindex); + + avgfvel += loc.fvel; + avgsvel += loc.svel; + avgavel += loc.avel; + avghorz += loc.horz; + avgbits |= loc.bits; + avgbits2 |= loc.bits2; + if (movefifoend[myconnectindex]&(movesperpacket-1)) + { + copybufbyte(&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex], + &inputfifo[movefifoend[myconnectindex]&(MOVEFIFOSIZ-1)][myconnectindex],sizeof(input)); + movefifoend[myconnectindex]++; + return; + } + nsyn = &inputfifo[movefifoend[myconnectindex]&(MOVEFIFOSIZ-1)][myconnectindex]; + nsyn[0].fvel = avgfvel/movesperpacket; + nsyn[0].svel = avgsvel/movesperpacket; + nsyn[0].avel = avgavel/movesperpacket; + nsyn[0].horz = avghorz/movesperpacket; + nsyn[0].bits = avgbits; + nsyn[0].bits2 = avgbits2; + avgfvel = avgsvel = avgavel = avghorz = avgbits = avgbits2 = 0; + movefifoend[myconnectindex]++; + + if (numplayers < 2) + { + if (ud.multimode > 1) for(i=connecthead;i>=0;i=connectpoint2[i]) + if(i != myconnectindex) + { + //clearbufbyte(&inputfifo[movefifoend[i]&(MOVEFIFOSIZ-1)][i],sizeof(input),0L); + if(ud.playerai) + computergetinput(i,&inputfifo[movefifoend[i]&(MOVEFIFOSIZ-1)][i]); + movefifoend[i]++; + } + return; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + { + k = (movefifoend[myconnectindex]-1)-movefifoend[i]; + myminlag[i] = min(myminlag[i],k); + mymaxlag = max(mymaxlag,k); + } + + if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) + { + i = mymaxlag-bufferjitter; mymaxlag = 0; + if (i > 0) bufferjitter += ((3+i)>>2); + else if (i < 0) bufferjitter -= ((1-i)>>2); + } + + if (networkmode == 1) + { + packbuf[0] = 17; + if ((movefifoend[myconnectindex]-1) == 0) packbuf[0] = 16; + j = 1; + + //Fix timers and buffer/jitter value + if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) + { + if (myconnectindex != connecthead) + { + i = myminlag[connecthead]-otherminlag; + if (klabs(i) > 8) i >>= 1; + else if (klabs(i) > 2) i = ksgn(i); + else i = 0; + + totalclock -= TICSPERFRAME*i; + myminlag[connecthead] -= i; otherminlag += i; + } + + if (myconnectindex == connecthead) + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + packbuf[j++] = min(max(myminlag[i],-128),127); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + myminlag[i] = 0x7fffffff; + } + + osyn = (input *)&inputfifo[(movefifoend[myconnectindex]-2)&(MOVEFIFOSIZ-1)][myconnectindex]; + nsyn = (input *)&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex]; + + k = j; + packbuf[j++] = 0; + packbuf[j++] = 0; + + if (nsyn[0].fvel != osyn[0].fvel) + { + packbuf[j++] = (char)nsyn[0].fvel; + packbuf[j++] = (char)(nsyn[0].fvel>>8); + packbuf[k] |= 1; + } + if (nsyn[0].svel != osyn[0].svel) + { + packbuf[j++] = (char)nsyn[0].svel; + packbuf[j++] = (char)(nsyn[0].svel>>8); + packbuf[k] |= 2; + } + if (nsyn[0].avel != osyn[0].avel) + { + packbuf[j++] = (signed char)nsyn[0].avel; + packbuf[k] |= 4; + } + if ((nsyn[0].bits^osyn[0].bits)&0x000000ff) packbuf[j++] = (nsyn[0].bits&255), packbuf[k] |= 8; + if ((nsyn[0].bits^osyn[0].bits)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits>>8)&255), packbuf[k] |= 16; + if ((nsyn[0].bits^osyn[0].bits)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits>>16)&255), packbuf[k] |= 32; + if ((nsyn[0].bits^osyn[0].bits)&0xff000000) packbuf[j++] = ((nsyn[0].bits>>24)&255), packbuf[k] |= 64; + if (nsyn[0].horz != osyn[0].horz) + { + packbuf[j++] = (char)nsyn[0].horz; + packbuf[k] |= 128; + } + k++; + packbuf[k] = 0; + if ((nsyn[0].bits2^osyn[0].bits2)&0x000000ff) packbuf[j++] = (nsyn[0].bits2&255), packbuf[k] |= 1; + if ((nsyn[0].bits2^osyn[0].bits2)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits2>>8)&255), packbuf[k] |= 2; + if ((nsyn[0].bits2^osyn[0].bits2)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits2>>16)&255), packbuf[k] |= 4; + if ((nsyn[0].bits2^osyn[0].bits2)&0xff000000) packbuf[j++] = ((nsyn[0].bits2>>24)&255), packbuf[k] |= 8; + + while (syncvalhead[myconnectindex] != syncvaltail) + { + packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)]; + syncvaltail++; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + sendpacket(i,packbuf,j); + + return; + } + if (myconnectindex != connecthead) //Slave + { + //Fix timers and buffer/jitter value + if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) + { + i = myminlag[connecthead]-otherminlag; + if (klabs(i) > 8) i >>= 1; + else if (klabs(i) > 2) i = ksgn(i); + else i = 0; + + totalclock -= TICSPERFRAME*i; + myminlag[connecthead] -= i; otherminlag += i; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + myminlag[i] = 0x7fffffff; + } + + packbuf[0] = 1; packbuf[1] = 0; packbuf[2] = 0; j = 3; + + osyn = (input *)&inputfifo[(movefifoend[myconnectindex]-2)&(MOVEFIFOSIZ-1)][myconnectindex]; + nsyn = (input *)&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex]; + + if (nsyn[0].fvel != osyn[0].fvel) + { + packbuf[j++] = (char)nsyn[0].fvel; + packbuf[j++] = (char)(nsyn[0].fvel>>8); + packbuf[1] |= 1; + } + if (nsyn[0].svel != osyn[0].svel) + { + packbuf[j++] = (char)nsyn[0].svel; + packbuf[j++] = (char)(nsyn[0].svel>>8); + packbuf[1] |= 2; + } + if (nsyn[0].avel != osyn[0].avel) + { + packbuf[j++] = (signed char)nsyn[0].avel; + packbuf[1] |= 4; + } + if ((nsyn[0].bits^osyn[0].bits)&0x000000ff) packbuf[j++] = (nsyn[0].bits&255), packbuf[1] |= 8; + if ((nsyn[0].bits^osyn[0].bits)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits>>8)&255), packbuf[1] |= 16; + if ((nsyn[0].bits^osyn[0].bits)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits>>16)&255), packbuf[1] |= 32; + if ((nsyn[0].bits^osyn[0].bits)&0xff000000) packbuf[j++] = ((nsyn[0].bits>>24)&255), packbuf[1] |= 64; + if (nsyn[0].horz != osyn[0].horz) + { + packbuf[j++] = (char)nsyn[0].horz; + packbuf[1] |= 128; + } + packbuf[2] = 0; + if ((nsyn[0].bits2^osyn[0].bits2)&0x000000ff) packbuf[j++] = (nsyn[0].bits2&255), packbuf[2] |= 1; + if ((nsyn[0].bits2^osyn[0].bits2)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits2>>8)&255), packbuf[2] |= 2; + if ((nsyn[0].bits2^osyn[0].bits2)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits2>>16)&255), packbuf[2] |= 4; + if ((nsyn[0].bits2^osyn[0].bits2)&0xff000000) packbuf[j++] = ((nsyn[0].bits2>>24)&255), packbuf[2] |= 8; + + while (syncvalhead[myconnectindex] != syncvaltail) + { + packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)]; + syncvaltail++; + } + + sendpacket(connecthead,packbuf,j); + return; + } + + //This allows allow packet resends + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (movefifoend[i] <= movefifosendplc) + { + packbuf[0] = 127; + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + sendpacket(i,packbuf,1); + return; + } + + while (1) //Master + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (playerquitflag[i] && (movefifoend[i] <= movefifosendplc)) return; + + osyn = (input *)&inputfifo[(movefifosendplc-1)&(MOVEFIFOSIZ-1)][0]; + nsyn = (input *)&inputfifo[(movefifosendplc )&(MOVEFIFOSIZ-1)][0]; + + //MASTER -> SLAVE packet + packbuf[0] = 0; j = 1; + + //Fix timers and buffer/jitter value + if ((movefifosendplc&(TIMERUPDATESIZ-1)) == 0) + { + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (playerquitflag[i]) + packbuf[j++] = min(max(myminlag[i],-128),127); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + myminlag[i] = 0x7fffffff; + } + + k = j; + for(i=connecthead;i>=0;i=connectpoint2[i]) + j += playerquitflag[i] + playerquitflag[i]; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerquitflag[i] == 0) continue; + + packbuf[k] = 0; + if (nsyn[i].fvel != osyn[i].fvel) + { + packbuf[j++] = (char)nsyn[i].fvel; + packbuf[j++] = (char)(nsyn[i].fvel>>8); + packbuf[k] |= 1; + } + if (nsyn[i].svel != osyn[i].svel) + { + packbuf[j++] = (char)nsyn[i].svel; + packbuf[j++] = (char)(nsyn[i].svel>>8); + packbuf[k] |= 2; + } + if (nsyn[i].avel != osyn[i].avel) + { + packbuf[j++] = (signed char)nsyn[i].avel; + packbuf[k] |= 4; + } + if ((nsyn[i].bits^osyn[i].bits)&0x000000ff) packbuf[j++] = (nsyn[i].bits&255), packbuf[k] |= 8; + if ((nsyn[i].bits^osyn[i].bits)&0x0000ff00) packbuf[j++] = ((nsyn[i].bits>>8)&255), packbuf[k] |= 16; + if ((nsyn[i].bits^osyn[i].bits)&0x00ff0000) packbuf[j++] = ((nsyn[i].bits>>16)&255), packbuf[k] |= 32; + if ((nsyn[i].bits^osyn[i].bits)&0xff000000) packbuf[j++] = ((nsyn[i].bits>>24)&255), packbuf[k] |= 64; + if (nsyn[i].horz != osyn[i].horz) + { + packbuf[j++] = (char)nsyn[i].horz; + packbuf[k] |= 128; + } + k++; + packbuf[k] = 0; + if ((nsyn[i].bits2^osyn[i].bits2)&0x000000ff) packbuf[j++] = (nsyn[i].bits2&255), packbuf[k] |= 1; + if ((nsyn[i].bits2^osyn[i].bits2)&0x0000ff00) packbuf[j++] = ((nsyn[i].bits2>>8)&255), packbuf[k] |= 2; + if ((nsyn[i].bits2^osyn[i].bits2)&0x00ff0000) packbuf[j++] = ((nsyn[i].bits2>>16)&255), packbuf[k] |= 4; + if ((nsyn[i].bits2^osyn[i].bits2)&0xff000000) packbuf[j++] = ((nsyn[i].bits2>>24)&255), packbuf[k] |= 8; + k++; + } + + while (syncvalhead[myconnectindex] != syncvaltail) + { + packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)]; + syncvaltail++; + } + + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (playerquitflag[i]) + { + sendpacket(i,packbuf,j); + if (nsyn[i].bits&(1<<26)) + playerquitflag[i] = 0; + } + + movefifosendplc += movesperpacket; + } +} + +extern long cacnum; +typedef struct { long *hand, leng; char *lock; } cactype; +extern cactype cac[]; + +void caches(void) +{ + short i,k; + + k = 0; + for(i=0;i= 200) + { + Bsprintf(tempbuf,"Locked- %d: Leng:%ld, Lock:%d",i,cac[i].leng,*cac[i].lock); + printext256(0L,k,31,-1,tempbuf,1); k += 6; + } + + k += 6; + + for(i=1;i<11;i++) + if (lumplockbyte[i] >= 200) + { + Bsprintf(tempbuf,"RTS Locked %d:",i); + printext256(0L,k,31,-1,tempbuf,1); k += 6; + } + + +} + +void checksync(void) +{ + long i, k; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (syncvalhead[i] == syncvaltottail) break; + if (i < 0) + { + syncstat = 0; + do + { + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (syncval[i][syncvaltottail&(MOVEFIFOSIZ-1)] != + syncval[connecthead][syncvaltottail&(MOVEFIFOSIZ-1)]) + syncstat = 1; + + syncvaltottail++; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (syncvalhead[i] == syncvaltottail) break; + } while (i < 0); + } + if (connectpoint2[connecthead] < 0) syncstat = 0; + + if (syncstat) + { + printext256(4L,130L,31,0,"Out Of Sync - Please restart game",0); + printext256(4L,138L,31,0,"RUN DN3DHELP.EXE for information.",0); + } + if (syncstate) + { + printext256(4L,160L,31,0,"Missed Network packet!",0); + printext256(4L,138L,31,0,"RUN DN3DHELP.EXE for information.",0); + } +} + +void check_fta_sounds(short i) +{ + if(sprite[i].extra > 0) + switch(dynamictostatic[PN]) + { + case LIZTROOPONTOILET__STATIC: + case LIZTROOPJUSTSIT__STATIC: + case LIZTROOPSHOOT__STATIC: + case LIZTROOPJETPACK__STATIC: + case LIZTROOPDUCKING__STATIC: + case LIZTROOPRUNNING__STATIC: + case LIZTROOP__STATIC: + spritesound(PRED_RECOG,i); + break; + case LIZMAN__STATIC: + case LIZMANSPITTING__STATIC: + case LIZMANFEEDING__STATIC: + case LIZMANJUMP__STATIC: + spritesound(CAPT_RECOG,i); + break; + case PIGCOP__STATIC: + case PIGCOPDIVE__STATIC: + spritesound(PIG_RECOG,i); + break; + case RECON__STATIC: + spritesound(RECO_RECOG,i); + break; + case DRONE__STATIC: + spritesound(DRON_RECOG,i); + break; + case COMMANDER__STATIC: + case COMMANDERSTAYPUT__STATIC: + spritesound(COMM_RECOG,i); + break; + case ORGANTIC__STATIC: + spritesound(TURR_RECOG,i); + break; + case OCTABRAIN__STATIC: + case OCTABRAINSTAYPUT__STATIC: + spritesound(OCTA_RECOG,i); + break; + case BOSS1__STATIC: + sound(BOS1_RECOG); + break; + case BOSS2__STATIC: + if(sprite[i].pal == 1) + sound(BOS2_RECOG); + else sound(WHIPYOURASS); + break; + case BOSS3__STATIC: + if(sprite[i].pal == 1) + sound(BOS3_RECOG); + else sound(RIPHEADNECK); + break; + case BOSS4__STATIC: + case BOSS4STAYPUT__STATIC: + if(sprite[i].pal == 1) + sound(BOS4_RECOG); + sound(BOSS4_FIRSTSEE); + break; + case GREENSLIME__STATIC: + spritesound(SLIM_RECOG,i); + break; + } +} + +inline short inventory(spritetype *s) +{ + switch(dynamictostatic[s->picnum]) + { + case FIRSTAID__STATIC: + case STEROIDS__STATIC: + case HEATSENSOR__STATIC: + case BOOTS__STATIC: + case JETPACK__STATIC: + case HOLODUKE__STATIC: + case AIRTANK__STATIC: + return 1; + } + return 0; +} + +inline int checkspriteflags(short sActor, int iType) +{ + int i; + + i = spriteflags[sprite[sActor].picnum]; i ^= actorspriteflags[sActor]; + if(i & iType) return 1; + else return 0; +} + +inline int checkspriteflagsp(short sPicnum, int iType) +{ + if(spriteflags[sPicnum] & iType) return 1; + else return 0; +} + +inline short badguypic(short pn) +{ + //this case can't be handled by the dynamictostatic system because it adds + //stuff to the value from names.h so handling separately + if ((pn >= GREENSLIME) && (pn <= GREENSLIME+7)) return 1; + + if(checkspriteflagsp(pn,SPRITE_FLAG_BADGUY)) return 1; + + if( actortype[pn] ) return 1; + + switch(dynamictostatic[pn]) + { + case SHARK__STATIC: + case RECON__STATIC: + case DRONE__STATIC: + case LIZTROOPONTOILET__STATIC: + case LIZTROOPJUSTSIT__STATIC: + case LIZTROOPSTAYPUT__STATIC: + case LIZTROOPSHOOT__STATIC: + case LIZTROOPJETPACK__STATIC: + case LIZTROOPDUCKING__STATIC: + case LIZTROOPRUNNING__STATIC: + case LIZTROOP__STATIC: + case OCTABRAIN__STATIC: + case COMMANDER__STATIC: + case COMMANDERSTAYPUT__STATIC: + case PIGCOP__STATIC: + case EGG__STATIC: + case PIGCOPSTAYPUT__STATIC: + case PIGCOPDIVE__STATIC: + case LIZMAN__STATIC: + case LIZMANSPITTING__STATIC: + case LIZMANFEEDING__STATIC: + case LIZMANJUMP__STATIC: + case ORGANTIC__STATIC: + case BOSS1__STATIC: + case BOSS2__STATIC: + case BOSS3__STATIC: + case BOSS4__STATIC: + //case GREENSLIME: + //case GREENSLIME+1: + //case GREENSLIME+2: + //case GREENSLIME+3: + //case GREENSLIME+4: + //case GREENSLIME+5: + //case GREENSLIME+6: + //case GREENSLIME+7: + case RAT__STATIC: + case ROTATEGUN__STATIC: + return 1; + } + return 0; +} + +inline short badguy(spritetype *s) +{ + return(badguypic(s->picnum)); +} + +void myos(long x, long y, short tilenum, signed char shade, char orientation) +{ + char p; + short a; + + if(orientation&4) + a = 1024; + else a = 0; + + p = sector[ps[screenpeek].cursectnum].floorpal; + rotatesprite(x<<16,y<<16,65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2); +} + +void myospal(long x, long y, short tilenum, signed char shade, char orientation, char p) +{ + short a; + + if(orientation&4) + a = 1024; + else a = 0; + + rotatesprite(x<<16,y<<16,65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2); +} + +void myosx(long x, long y, short tilenum, signed char shade, char orientation) +{ + char p; + short a; + + if(orientation&4) + a = 1024; + else a = 0; + + p = sector[ps[screenpeek].cursectnum].floorpal; + rotatesprite(x<<16,y<<16,32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2); +} + +void myospalx(long x, long y, short tilenum, signed char shade, char orientation, char p) +{ + short a; + + if(orientation&4) + a = 1024; + else a = 0; + + rotatesprite(x<<16,y<<16,32768L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2); +} + +void invennum(long x,long y,char num1,char ha,char sbits) +{ + char dabuf[80] = {0}; + Bsprintf(dabuf,"%d",num1); + if(num1 > 99) + { + rotatesprite(sbarx(x-4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[2]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); + } + else if(num1 > 9) + { + rotatesprite(sbarx(x),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); + } + else + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1); +} + +void orderweaponnum(short ind,long x,long y,long num1, long num2,char ha) +{ + rotatesprite(sbarx(x-7),sbary(y),sbarsc(65536L),0,THREEBYFIVE+ind+1,ha-10,7,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x-3),sbary(y),sbarsc(65536L),0,THREEBYFIVE+10,ha,0,10,0,0,xdim-1,ydim-1); + + minitextshade(x+1,y-4,"ORDER",26,6,2+8+16+128 + 256); +} + +void weaponnum(short ind,long x,long y,long num1, long num2,char ha) +{ + char dabuf[80] = {0}; + + rotatesprite(sbarx(x-7),sbary(y),sbarsc(65536L),0,THREEBYFIVE+ind+1,ha-10,7,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x-3),sbary(y),sbarsc(65536L),0,THREEBYFIVE+10,ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+9),sbary(y),sbarsc(65536L),0,THREEBYFIVE+11,ha,0,10,0,0,xdim-1,ydim-1); + + if(num1 > 99) num1 = 99; + if(num2 > 99) num2 = 99; + + Bsprintf(dabuf,"%ld",num1); + if(num1 > 9) + { + rotatesprite(sbarx(x),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + + Bsprintf(dabuf,"%ld",num2); + if(num2 > 9) + { + rotatesprite(sbarx(x+13),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+17),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else rotatesprite(sbarx(x+13),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); +} + +void weaponnum999(char ind,long x,long y,long num1, long num2,char ha) +{ + char dabuf[80] = {0}; + + rotatesprite(sbarx(x-7),sbary(y),sbarsc(65536L),0,THREEBYFIVE+ind+1,ha-10,7,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x-4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+10,ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+13),sbary(y),sbarsc(65536L),0,THREEBYFIVE+11,ha,0,10,0,0,xdim-1,ydim-1); + + Bsprintf(dabuf,"%ld",num1); + if(num1 > 99) + { + rotatesprite(sbarx(x),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+8),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[2]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else if(num1 > 9) + { + rotatesprite(sbarx(x+4),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+8),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else rotatesprite(sbarx(x+8),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + + Bsprintf(dabuf,"%ld",num2); + if(num2 > 99) + { + rotatesprite(sbarx(x+17),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+21),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+25),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[2]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else if(num2 > 9) + { + rotatesprite(sbarx(x+17),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); + rotatesprite(sbarx(x+21),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[1]-'0',ha,0,10,0,0,xdim-1,ydim-1); + } + else rotatesprite(sbarx(x+25),sbary(y),sbarsc(65536L),0,THREEBYFIVE+dabuf[0]-'0',ha,0,10,0,0,xdim-1,ydim-1); +} + +void weapon_amounts(struct player_struct *p,long x,long y,long u) +{ + int cw; + + cw = p->curr_weapon; + + if (u&4) + { + if (u != -1) patchstatusbar(88,178,88+37,178+6); //original code: (96,178,96+12,178+6); + weaponnum999(PISTOL_WEAPON,x,y, + p->ammo_amount[PISTOL_WEAPON],max_ammo_amount[PISTOL_WEAPON], + 12-20*(cw == PISTOL_WEAPON) ); + } + if (u&8) + { + if (u != -1) patchstatusbar(88,184,88+37,184+6); //original code: (96,184,96+12,184+6); + weaponnum999(SHOTGUN_WEAPON,x,y+6, + p->ammo_amount[SHOTGUN_WEAPON],max_ammo_amount[SHOTGUN_WEAPON], + (!p->gotweapon[SHOTGUN_WEAPON]*9)+12-18* + (cw == SHOTGUN_WEAPON) ); + } + if (u&16) + { + if (u != -1) patchstatusbar(88,190,88+37,190+6); //original code: (96,190,96+12,190+6); + weaponnum999(CHAINGUN_WEAPON,x,y+12, + p->ammo_amount[CHAINGUN_WEAPON],max_ammo_amount[CHAINGUN_WEAPON], + (!p->gotweapon[CHAINGUN_WEAPON]*9)+12-18* + (cw == CHAINGUN_WEAPON) ); + } + if (u&32) + { + if (u != -1) patchstatusbar(127,178,127+29,178+6); //original code: (135,178,135+8,178+6); + weaponnum(RPG_WEAPON,x+39,y, + p->ammo_amount[RPG_WEAPON],max_ammo_amount[RPG_WEAPON], + (!p->gotweapon[RPG_WEAPON]*9)+12-19* + (cw == RPG_WEAPON) ); + } + if (u&64) + { + if (u != -1) patchstatusbar(127,184,127+29,184+6); //original code: (135,184,135+8,184+6); + weaponnum(HANDBOMB_WEAPON,x+39,y+6, + p->ammo_amount[HANDBOMB_WEAPON],max_ammo_amount[HANDBOMB_WEAPON], + (((!p->ammo_amount[HANDBOMB_WEAPON])|(!p->gotweapon[HANDBOMB_WEAPON]))*9)+12-19* + ((cw == HANDBOMB_WEAPON) || (cw == HANDREMOTE_WEAPON))); + } + if (u&128) + { + if (u != -1) patchstatusbar(127,190,127+29,190+6); //original code: (135,190,135+8,190+6); + + if (VOLUMEONE) { + orderweaponnum(SHRINKER_WEAPON,x+39,y+12, + p->ammo_amount[SHRINKER_WEAPON],max_ammo_amount[SHRINKER_WEAPON], + (!p->gotweapon[SHRINKER_WEAPON]*9)+12-18* + (cw == SHRINKER_WEAPON) ); + } else { + if(p->subweapon&(1<ammo_amount[GROW_WEAPON],max_ammo_amount[GROW_WEAPON], + (!p->gotweapon[GROW_WEAPON]*9)+12-18* + (cw == GROW_WEAPON) ); + else + weaponnum(SHRINKER_WEAPON,x+39,y+12, + p->ammo_amount[SHRINKER_WEAPON],max_ammo_amount[SHRINKER_WEAPON], + (!p->gotweapon[SHRINKER_WEAPON]*9)+12-18* + (cw == SHRINKER_WEAPON) ); + } + } + if (u&256) + { + if (u != -1) patchstatusbar(158,178,162+29,178+6); //original code: (166,178,166+8,178+6); + + if (VOLUMEONE) { + orderweaponnum(DEVISTATOR_WEAPON,x+70,y, + p->ammo_amount[DEVISTATOR_WEAPON],max_ammo_amount[DEVISTATOR_WEAPON], + (!p->gotweapon[DEVISTATOR_WEAPON]*9)+12-18* + (cw == DEVISTATOR_WEAPON) ); + } else { + weaponnum(DEVISTATOR_WEAPON,x+70,y, + p->ammo_amount[DEVISTATOR_WEAPON],max_ammo_amount[DEVISTATOR_WEAPON], + (!p->gotweapon[DEVISTATOR_WEAPON]*9)+12-18* + (cw == DEVISTATOR_WEAPON) ); + } + } + if (u&512) + { + if (u != -1) patchstatusbar(158,184,162+29,184+6); //original code: (166,184,166+8,184+6); + if (VOLUMEONE) { + orderweaponnum(TRIPBOMB_WEAPON,x+70,y+6, + p->ammo_amount[TRIPBOMB_WEAPON],max_ammo_amount[TRIPBOMB_WEAPON], + (!p->gotweapon[TRIPBOMB_WEAPON]*9)+12-18* + (cw == TRIPBOMB_WEAPON) ); + } else { + weaponnum(TRIPBOMB_WEAPON,x+70,y+6, + p->ammo_amount[TRIPBOMB_WEAPON],max_ammo_amount[TRIPBOMB_WEAPON], + (!p->gotweapon[TRIPBOMB_WEAPON]*9)+12-18* + (cw == TRIPBOMB_WEAPON) ); + } + } + + if (u&65536L) + { + if (u != -1) patchstatusbar(158,190,162+29,190+6); //original code: (166,190,166+8,190+6); + if (VOLUMEONE) { + orderweaponnum(-1,x+70,y+12, + p->ammo_amount[FREEZE_WEAPON],max_ammo_amount[FREEZE_WEAPON], + (!p->gotweapon[FREEZE_WEAPON]*9)+12-18* + (cw == FREEZE_WEAPON) ); + } else { + weaponnum(-1,x+70,y+12, + p->ammo_amount[FREEZE_WEAPON],max_ammo_amount[FREEZE_WEAPON], + (!p->gotweapon[FREEZE_WEAPON]*9)+12-18* + (cw == FREEZE_WEAPON) ); + } + } +} + +void digitalnumber(long x,long y,long n,char s,char cs) +{ + + short i, j, k, p, c; + char b[10]; + + //ltoa(n,b,10); + Bsnprintf(b,10,"%ld",n); + i = strlen(b); + j = 0; + + for(k=0;k>1); + + j = 0; + for(k=0;k>1); + + j = 0; + for(k=0;k= 0;i--) + { + overwritesprite(x-2,y,SCRATCH+4,s,0,0); + x += tilesizx[SCRATCH+4]-1; + } + + ni = n%5; + if(ni) overwritesprite(x,y,SCRATCH+ni-1,s,p,0); +} + */ +void displayinventory(struct player_struct *p) +{ + short n, j, xoff, y; + + j = xoff = 0; + + n = (p->jetpack_amount > 0)<<3; if(n&8) j++; + n |= ( p->scuba_amount > 0 )<<5; if(n&32) j++; + n |= (p->steroids_amount > 0)<<1; if(n&2) j++; + n |= ( p->holoduke_amount > 0)<<2; if(n&4) j++; + n |= (p->firstaid_amount > 0); if(n&1) j++; + n |= (p->heat_amount > 0)<<4; if(n&16) j++; + n |= (p->boot_amount > 0)<<6; if(n&64) j++; + + xoff = 160-(j*11); + + j = 0; + + if(ud.screen_size > 4) + y = 154; + else y = 172; + + if(ud.screen_size == 4) + { + if(ud.multimode > 1) + xoff += 56; + else xoff += 65; + } + + while( j <= 9 ) + { + if( n&(1<inven_icon == j+1) + rotatesprite((xoff-2)<<16,(y+19)<<16,65536L,1024,ARROW,-32,0,2+16,windowx1,windowy1,windowx2,windowy2); + } + + j++; + } +} + +void displayfragbar(void) +{ + short i, j; + + j = 0; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if(i > j) j = i; + + rotatesprite(0,0,65600L,0,FRAGBAR,0,0,2+8+16+64,0,0,xdim-1,ydim-1); + if(j >= 4) rotatesprite(319,(8)<<16,65600L,0,FRAGBAR,0,0,10+16+64,0,0,xdim-1,ydim-1); + if(j >= 8) rotatesprite(319,(16)<<16,65600L,0,FRAGBAR,0,0,10+16+64,0,0,xdim-1,ydim-1); + if(j >= 12) rotatesprite(319,(24)<<16,65600L,0,FRAGBAR,0,0,10+16+64,0,0,xdim-1,ydim-1); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + minitext(21+(73*(i&3)),2+((i&28)<<1),&ud.user_name[i][0],sprite[ps[i].i].pal,2+8+16); + Bsprintf(tempbuf,"%d",ps[i].frag-ps[i].fraggedself); + minitext(17+50+(73*(i&3)),2+((i&28)<<1),tempbuf,sprite[ps[i].i].pal,2+8+16); + } +} + +void coolgaugetext(short snum) +{ + struct player_struct *p; + long i, j, o, ss, u; + char c, permbit; + + p = &ps[snum]; + + if (p->invdisptime > 0) displayinventory(p); + + + if(ps[snum].gm&MODE_MENU) + if( (current_menu >= 400 && current_menu <= 405) ) + return; + + ss = ud.screen_size; if (ss < 4) return; + + if (getrendermode() >= 3) pus = NUMPAGES; // JBF 20040101: always redraw in GL + + if ( ud.multimode > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + { + if (pus) + { displayfragbar(); } + else + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (ps[i].frag != sbar.frag[i]) { displayfragbar(); break; } + } + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + sbar.frag[i] = ps[i].frag; + } + + if (ss == 4) //DRAW MINI STATUS BAR: + { + rotatesprite(sbarx(5),sbary(200-28),sbarsc(65536L),0,HEALTHBOX,0,21,10+16,0,0,xdim-1,ydim-1); + if (p->inven_icon) + rotatesprite(sbarx(69),sbary(200-30),sbarsc(65536L),0,INVENTORYBOX,0,21,10+16,0,0,xdim-1,ydim-1); + + if(sprite[p->i].pal == 1 && p->last_extra < 2) + digitalnumber(20,200-17,1,-16,10+16); + else digitalnumber(20,200-17,p->last_extra,-16,10+16); + + rotatesprite(sbarx(37),sbary(200-28),sbarsc(65536L),0,AMMOBOX,0,21,10+16,0,0,xdim-1,ydim-1); + + if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON; else i = p->curr_weapon; + digitalnumber(53,200-17,p->ammo_amount[i],-16,10+16); + + o = 158; permbit = 0; + if (p->inven_icon) + { + switch(p->inven_icon) + { + case 1: i = FIRSTAID_ICON; break; + case 2: i = STEROIDS_ICON; break; + case 3: i = HOLODUKE_ICON; break; + case 4: i = JETPACK_ICON; break; + case 5: i = HEAT_ICON; break; + case 6: i = AIRTANK_ICON; break; + case 7: i = BOOT_ICON; break; + default: i = -1; + } + if (i >= 0) rotatesprite(sbarx(231-o),sbary(200-21),sbarsc(65536L),0,i,0,0,10+16+permbit,0,0,xdim-1,ydim-1); + + minitext(292-30-o,190,"%",6,10+16+permbit + 256); + + j = 0x80000000; + switch(p->inven_icon) + { + case 1: i = p->firstaid_amount; break; + case 2: i = ((p->steroids_amount+3)>>2); break; + case 3: i = ((p->holoduke_amount+15)/24); j = p->holoduke_on; break; + case 4: i = ((p->jetpack_amount+15)>>4); j = p->jetpack_on; break; + case 5: i = p->heat_amount/12; j = p->heat_on; break; + case 6: i = ((p->scuba_amount+63)>>6); break; + case 7: i = (p->boot_amount>>1); break; + } + invennum(284-30-o,200-6,(char)i,0,10+permbit); + if (p->inven_icon >= 6) minitext(284-35-o,180,"AUTO",2,10+16+permbit + 256); + } + return; + } + + //DRAW/UPDATE FULL STATUS BAR: + +if (pus) { pus = 0; u = -1; } else u = 0; + +if (sbar.frag[myconnectindex] != p->frag) { sbar.frag[myconnectindex] = p->frag; u |= 32768; } + if (sbar.got_access != p->got_access) { sbar.got_access = p->got_access; u |= 16384; } + if (sbar.last_extra != p->last_extra) { sbar.last_extra = p->last_extra; u |= 1; } + { + long lAmount=GetGameVar("PLR_MORALE",-1, p->i, snum); + if(lAmount == -1) + { + if (sbar.shield_amount != p->shield_amount) { sbar.shield_amount = p->shield_amount; u |= 2; } + } + else + { + if (sbar.shield_amount != lAmount) { sbar.shield_amount = lAmount; u |= 2; } + } + } + if (sbar.curr_weapon != p->curr_weapon) { sbar.curr_weapon = p->curr_weapon; u |= (4+8+16+32+64+128+256+512+1024+65536L); } + for(i=1;i < MAX_WEAPONS;i++) + { + if (sbar.ammo_amount[i] != p->ammo_amount[i]) + { + sbar.ammo_amount[i] = p->ammo_amount[i]; + if(i < 9) + u |= ((2<gotweapon[i]) + { + sbar.gotweapon[i] = p->gotweapon[i]; + if(i < 9 ) + u |= ((2<inven_icon) { sbar.inven_icon = p->inven_icon; u |= (2048+4096+8192); } + if (sbar.holoduke_on != p->holoduke_on) { sbar.holoduke_on = p->holoduke_on; u |= (4096+8192); } + if (sbar.jetpack_on != p->jetpack_on) { sbar.jetpack_on = p->jetpack_on; u |= (4096+8192); } + if (sbar.heat_on != p->heat_on) { sbar.heat_on = p->heat_on; u |= (4096+8192); } + if (sbar.firstaid_amount != p->firstaid_amount) { sbar.firstaid_amount = p->firstaid_amount; u |= 8192; } + if (sbar.steroids_amount != p->steroids_amount) { sbar.steroids_amount = p->steroids_amount; u |= 8192; } + if (sbar.holoduke_amount != p->holoduke_amount) { sbar.holoduke_amount = p->holoduke_amount; u |= 8192; } + if (sbar.jetpack_amount != p->jetpack_amount) { sbar.jetpack_amount = p->jetpack_amount; u |= 8192; } + if (sbar.heat_amount != p->heat_amount) { sbar.heat_amount = p->heat_amount; u |= 8192; } + if (sbar.scuba_amount != p->scuba_amount) { sbar.scuba_amount = p->scuba_amount; u |= 8192; } + if (sbar.boot_amount != p->boot_amount) { sbar.boot_amount = p->boot_amount; u |= 8192; } + if (u == 0) return; + + //0 - update health + //1 - update armor + //2 - update PISTOL_WEAPON ammo + //3 - update SHOTGUN_WEAPON ammo + //4 - update CHAINGUN_WEAPON ammo + //5 - update RPG_WEAPON ammo + //6 - update HANDBOMB_WEAPON ammo + //7 - update SHRINKER_WEAPON ammo + //8 - update DEVISTATOR_WEAPON ammo + //9 - update TRIPBOMB_WEAPON ammo + //10 - update ammo display + //11 - update inventory icon + //12 - update inventory on/off + //13 - update inventory % + //14 - update keys + //15 - update kills + //16 - update FREEZE_WEAPON ammo + if (u == -1) + { + patchstatusbar(0,0,320,200); + if (ud.multimode > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + rotatesprite(sbarx(277+1),sbary(200-27-1),sbarsc(65536L),0,KILLSICON,0,0,10+16,0,0,xdim-1,ydim-1); + } + if (ud.multimode > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + { + if (u&32768) + { + if (u != -1) patchstatusbar(276,183,299,193); + digitalnumber(287,200-17,max(p->frag-p->fraggedself,0),-16,10+16); + } + } + else + { + if (u&16384) + { + if (u != -1) patchstatusbar(275,182,299,194); + if (p->got_access&4) rotatesprite(sbarx(275),sbary(182),sbarsc(65536L),0,ACCESS_ICON,0,23,10+16,0,0,xdim-1,ydim-1); + if (p->got_access&2) rotatesprite(sbarx(288),sbary(182),sbarsc(65536L),0,ACCESS_ICON,0,21,10+16,0,0,xdim-1,ydim-1); + if (p->got_access&1) rotatesprite(sbarx(281),sbary(189),sbarsc(65536L),0,ACCESS_ICON,0,0,10+16,0,0,xdim-1,ydim-1); + } + } + if (u&(4+8+16+32+64+128+256+512+65536L)) weapon_amounts(p,96,182,u); + + if (u&1) + { + if (u != -1) patchstatusbar(20,183,43,194); //Original code:(20,183,43,193); + if (sprite[p->i].pal == 1 && p->last_extra < 2) + digitalnumber(32,200-17,1,-16,10+16); + else digitalnumber(32,200-17,p->last_extra,-16,10+16); + } + if (u&2) + { + long lAmount=GetGameVar("PLR_MORALE",-1, p->i, snum); + if (u != -1) patchstatusbar(52,183,75,193); + if(lAmount == -1) + { + digitalnumber(64,200-17,p->shield_amount,-16,10+16); + } + else + { + digitalnumber(64,200-17,lAmount,-16,10+16); + } + } + + if (u&1024) + { + if (u != -1) patchstatusbar(196,183,219,194); //Original code:(196,183,219,193); + if (p->curr_weapon != KNEE_WEAPON) + { + if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON; else i = p->curr_weapon; + digitalnumber(230-22,200-17,p->ammo_amount[i],-16,10+16); + } + } + + if (u&(2048+4096+8192)) + { + if (u != -1) + { + if (u&(2048+4096)) { patchstatusbar(231,179,265,197); } + else { patchstatusbar(250,190,261,196); } //Original code:(250,190,261,195); + } + if (p->inven_icon) + { + o = 0; permbit = 0; + + if (u&(2048+4096)) + { + switch(p->inven_icon) + { + case 1: i = FIRSTAID_ICON; break; + case 2: i = STEROIDS_ICON; break; + case 3: i = HOLODUKE_ICON; break; + case 4: i = JETPACK_ICON; break; + case 5: i = HEAT_ICON; break; + case 6: i = AIRTANK_ICON; break; + case 7: i = BOOT_ICON; break; + } + + rotatesprite(sbarx(231-o),sbary(200-21),sbarsc(65536L),0,i,0,0,10+16+permbit,0,0,xdim-1,ydim-1); + minitext(292-30-o,190,"%",6,10+16+permbit + 256); + if (p->inven_icon >= 6) minitext(284-35-o,180,"AUTO",2,10+16+permbit + 256); + } + if (u&(2048+4096)) + { + switch(p->inven_icon) + { + case 3: j = p->holoduke_on; break; + case 4: j = p->jetpack_on; break; + case 5: j = p->heat_on; break; + default: j = 0x80000000; + } + if (j > 0) minitext(288-30-o,180,"ON",0,10+16+permbit + 256); + else if ((unsigned long)j != 0x80000000) minitext(284-30-o,180,"OFF",2,10+16+permbit + 256); + } + if (u&8192) + { + switch(p->inven_icon) + { + case 1: i = p->firstaid_amount; break; + case 2: i = ((p->steroids_amount+3)>>2); break; + case 3: i = ((p->holoduke_amount+15)/24); break; + case 4: i = ((p->jetpack_amount+15)>>4); break; + case 5: i = p->heat_amount/12; break; + case 6: i = ((p->scuba_amount+63)>>6); break; + case 7: i = (p->boot_amount>>1); break; + } + invennum(284-30-o,200-6,(char)i,0,10+permbit); + } + } + } +} + +#define AVERAGEFRAMES 16 +static long frameval[AVERAGEFRAMES], framecnt = 0; + +void tics(void) +{ + long i,j; + char b[10]; + + i = totalclock; + if (i != frameval[framecnt]) + { + j=(TICRATE*AVERAGEFRAMES)/(i-frameval[framecnt]); + Bsprintf(b,"%ld",j>0?j:0); + /* printext256(windowx1,windowy1,31,-21,b,1); */ + minitext(320-strlen(b)*4,ud.multimode>1&&ud.multimode<5?9:ud.multimode>4?17:1,b,(TICRATE*AVERAGEFRAMES)/(i-frameval[framecnt]) < 40?2:0,26); + frameval[framecnt] = i; + } + + framecnt = ((framecnt+1)&(AVERAGEFRAMES-1)); +} + +void coords(short snum) +{ + short y = 8; + + if((gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + { + if(ud.multimode > 1 && ud.multimode < 5) + y = 16; + else if(ud.multimode > 4) + y = 24; + } + sprintf(tempbuf,"X= %ld",ps[snum].posx); + printext256(250L,y,31,-1,tempbuf,0); + sprintf(tempbuf,"Y= %ld",ps[snum].posy); + printext256(250L,y+9L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"Z= %ld",ps[snum].posz); + printext256(250L,y+18L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"A= %d",ps[snum].ang); + printext256(250L,y+27L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"ZV= %ld",ps[snum].poszv); + printext256(250L,y+36L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"OG= %d",ps[snum].on_ground); + printext256(250L,y+45L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"AM= %d",ps[snum].ammo_amount[GROW_WEAPON]); + printext256(250L,y+54L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"LFW= %d",ps[snum].last_full_weapon); + printext256(250L,y+63L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"SECTL= %d",sector[ps[snum].cursectnum].lotag); + printext256(250L,y+72L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"SEED= %ld",randomseed); + printext256(250L,y+81L,31,-1,tempbuf,0); + Bsprintf(tempbuf,"THOLD= %d",ps[snum].transporter_hold); + printext256(250L,y+90L+7,31,-1,tempbuf,0); +} + +void operatefta(void) +{ + long i, j, k; + + if(ud.screen_size > 0) j = 200-45; else j = 200-8; + quotebot = min(quotebot,j); + quotebotgoal = min(quotebotgoal,j); + if(ps[myconnectindex].gm&MODE_TYPE) j -= 8; + quotebotgoal = j; j = quotebot; + for(i=0;i 4) + gametext(320>>1,j,user_quote[i],0,2+8+16); + else if (k > 2) gametext(320>>1,j,user_quote[i],0,2+8+16+1); + else gametext(320>>1,j,user_quote[i],0,2+8+16+1+32); + j -= 8; + } + + if (ps[screenpeek].fta <= 1) return; + + if ((gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR) && ud.screen_size > 0 && ud.multimode > 1) + { + j = 0; k = 8; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i > j) j = i; + + if (j >= 4 && j <= 8) k += 8; + else if (j > 8 && j <= 12) k += 16; + else if (j > 12) k += 24; + } + else k = 0; + + if (ps[screenpeek].ftq == 115 || ps[screenpeek].ftq == 116) + { + k = quotebot; + for(i=0;i 4) + gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16); + else + if (j > 2) gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16+1); + else + gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16+1+32); +} + +void FTA(short q,struct player_struct *p) +{ + if( ud.fta_on == 1) + { + if( p->fta > 0 && q != 115 && q != 116 ) + if( p->ftq == 115 || p->ftq == 116 ) return; + + p->fta = 100; + + if( p->ftq != q || q == 26 ) + // || q == 26 || q == 115 || q ==116 || q == 117 || q == 122 ) + { + p->ftq = q; + pub = NUMPAGES; + pus = NUMPAGES; + if (p == &ps[screenpeek]) OSD_Printf("%s\n",fta_quotes[q]); + } + } +} + +void showtwoscreens(void) +{ + short i; + + if (!VOLUMEALL) { + setview(0,0,xdim-1,ydim-1); + flushperms(); + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 1); // JBF 20040308 + fadepal(0,0,0, 0,64,7); + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,3291,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + IFISSOFTMODE fadepal(0,0,0, 63,0,-7); else nextpage(); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + + fadepal(0,0,0, 0,64,7); + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,3290,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + IFISSOFTMODE fadepal(0,0,0, 63,0,-7); else nextpage(); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + } +} +/* +void binscreen(void) +{ + long fil; +#ifdef VOLUMEONE + fil = kopen4load("dukesw.bin",1); +#else + fil = kopen4load("duke3d.bin",1); +#endif + if(fil == -1) return; + kread(fil,(char *)0xb8000,4000); + kclose(fil); +} +*/ + +extern long qsetmode; + +void gameexit(char *t) +{ + short i; + + if(*t != 0) ps[myconnectindex].palette = (char *) &palette[0]; + + if(numplayers > 1) + { + allowtimetocorrecterrorswhenquitting(); + uninitmultiplayers(); + } + + if(ud.recstat == 1) closedemowrite(); +else if(ud.recstat == 2) { if (frecfilep) fclose(frecfilep); } // JBF: fixes crash on demo playback + + if(qe || cp) + goto GOTOHERE; + + if(playerswhenstarted > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_SCORESHEET) && *t == ' ') + { + dobonus(1); + setgamemode(ScreenMode,ScreenWidth,ScreenHeight,ScreenBPP); + } + + if( *t != 0 && *(t+1) != 'V' && *(t+1) != 'Y') + showtwoscreens(); + +GOTOHERE: + + if (qsetmode == 200) + Shutdown(); + + if(*t != 0) + { + //setvmode(0x3); // JBF + //binscreen(); + // if(*t == ' ' && *(t+1) == 0) *t = 0; + //printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + if (!(t[0] == ' ' && t[1] == 0)) { + wm_msgbox(HEAD2, t); + } + } + + uninitgroupfile(); + + //unlink("duke3d.tmp"); + + exit(0); +} + +short inputloc = 0; +short strget(short x,short y,char *t,short dalen,short c) +{ + short ch; + + while((ch = KB_Getch()) != 0) + { + if(ch == asc_BackSpace) + { + if( inputloc > 0 ) + { + inputloc--; + *(t+inputloc) = 0; + } + } + else + { + if(ch == asc_Enter) + { + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + return (1); + } + else if(ch == asc_Escape) + { + KB_ClearKeyDown(sc_Escape); + return (-1); + } + else if ( ch >= 32 && inputloc < dalen && ch < 127) + { + ch = Btoupper(ch); + if (c != 997 || (ch >= '0' && ch <= '9')) { // JBF 20040508: so we can have numeric only if we want + *(t+inputloc) = ch; + *(t+inputloc+1) = 0; + inputloc++; + } + } + } + } + + if( c == 999 ) return(0); + if( c == 998 ) + { + char b[41],ii; + for(ii=0;ii>11); + rotatesprite((x+8)<<16,(y+4)<<16,32768L,0,SPINNINGNUKEICON+((totalclock>>3)%7),c,0,2+8,0,0,xdim-1,ydim-1); + + return (0); +} + +void typemode(void) +{ + short ch, hitstate, i, j; + + if( ps[myconnectindex].gm&MODE_SENDTOWHOM ) + { + if(sendmessagecommand != -1 || ud.multimode < 3 || movesperpacket == 4) + { + tempbuf[0] = 4; + tempbuf[2] = 0; + recbuf[0] = 0; + + if(ud.multimode < 3) + sendmessagecommand = 2; + + strcat(recbuf,ud.user_name[myconnectindex]); + strcat(recbuf,": "); + strcat(recbuf,typebuf); + j = strlen(recbuf); + recbuf[j] = 0; + strcat(tempbuf+2,recbuf); + + if(sendmessagecommand >= ud.multimode || movesperpacket == 4) + { + tempbuf[1] = 255; + for(ch=connecthead;ch >= 0;ch=connectpoint2[ch]) + { + if (ch != myconnectindex) sendpacket(ch,tempbuf,j+2); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + adduserquote(recbuf); + quotebot += 8; + quotebotgoal = quotebot; + } + else if(sendmessagecommand >= 0) + { + tempbuf[1] = (char)sendmessagecommand; + if ((!networkmode) && (myconnectindex != connecthead)) + sendmessagecommand = connecthead; + sendpacket(sendmessagecommand,tempbuf,j+2); + } + + sendmessagecommand = -1; + ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM); + } + else if(sendmessagecommand == -1) + { + j = 50; + gametext(320>>1,j,"SEND MESSAGE TO...",0,2+8+16); j += 8; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i == myconnectindex) + { + minitextshade((320>>1)-40+1,j+1,"A/ENTER - ALL",26,0,2+8+16); + minitext((320>>1)-40,j,"A/ENTER - ALL",0,2+8+16); j += 7; + } + else + { + Bsprintf(buf," %d - %s",i+1,ud.user_name[i]); + minitextshade((320>>1)-40-6+1,j+1,buf,26,0,2+8+16); + minitext((320>>1)-40-6,j,buf,0,2+8+16); j += 7; + } + } + minitextshade((320>>1)-40-4+1,j+1," ESC - Abort",26,0,2+8+16); + minitext((320>>1)-40-4,j," ESC - Abort",0,2+8+16); j += 7; + + if (ud.screen_size > 0) j = 200-45; else j = 200-8; + gametext(320>>1,j,typebuf,0,2+8+16); + + if( KB_KeyWaiting() ) + { + i = KB_GetCh(); + + if(i == 'A' || i == 'a' || i == 13) + sendmessagecommand = ud.multimode; + else if(i >= '1' || i <= (ud.multimode + '1') ) + sendmessagecommand = i - '1'; + else + { + sendmessagecommand = ud.multimode; + if(i == 27) + { + ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM); + sendmessagecommand = -1; + } + else + typebuf[0] = 0; + } + + KB_ClearKeyDown(sc_1); + KB_ClearKeyDown(sc_2); + KB_ClearKeyDown(sc_3); + KB_ClearKeyDown(sc_4); + KB_ClearKeyDown(sc_5); + KB_ClearKeyDown(sc_6); + KB_ClearKeyDown(sc_7); + KB_ClearKeyDown(sc_8); + KB_ClearKeyDown(sc_A); + KB_ClearKeyDown(sc_Escape); + KB_ClearKeyDown(sc_Enter); + } + } + } + else + { + if(ud.screen_size > 0) j = 200-45; else j = 200-8; + hitstate = strget(320>>1,j,typebuf,30,1); + + if(hitstate == 1) + { + KB_ClearKeyDown(sc_Enter); + ps[myconnectindex].gm |= MODE_SENDTOWHOM; + } + else if(hitstate == -1) + ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM); + else pub = NUMPAGES; + } +} + +void moveclouds(void) +{ + if( totalclock > cloudtotalclock || totalclock < (cloudtotalclock-7)) + { + short i; + + cloudtotalclock = totalclock+6; + + for(i=0;i>9); + cloudy[i] += (sintable[ps[screenpeek].ang&2047]>>9); + + sector[clouds[i]].ceilingxpanning = cloudx[i]>>6; + sector[clouds[i]].ceilingypanning = cloudy[i]>>6; + } + } +} + +void drawoverheadmap(long cposx, long cposy, long czoom, short cang) +{ + long i, j, k, l, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; + long dax, day, cosang, sinang, xspan, yspan, sprx, spry; + long xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; + long xvect, yvect, xvect2, yvect2; + short p; + char col; + walltype *wal, *wal2; + spritetype *spr; + + xvect = sintable[(-cang)&2047] * czoom; + yvect = sintable[(1536-cang)&2047] * czoom; + xvect2 = mulscale16(xvect,yxaspect); + yvect2 = mulscale16(yvect,yxaspect); + + //Draw red lines + for(i=0;i>3]&(1<<(i&7)))) continue; + + startwall = sector[i].wallptr; + endwall = sector[i].wallptr + sector[i].wallnum; + + z1 = sector[i].ceilingz; z2 = sector[i].floorz; + + for(j=startwall,wal=&wall[startwall];jnextwall; if (k < 0) continue; + + //if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + //if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue; + + if (sector[wal->nextsector].ceilingz == z1) + if (sector[wal->nextsector].floorz == z2) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; + + col = 139; //red + if ((wal->cstat|wall[wal->nextwall].cstat)&1) col = 234; //magenta + + if (!(show2dsector[wal->nextsector>>3]&(1<<(wal->nextsector&7)))) + col = 24; + else continue; + + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + wal2 = &wall[wal->point2]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,col); + } + } + + //Draw sprites + k = ps[screenpeek].i; + for(i=0;i>3]&(1<<(i&7)))) continue; + for(j=headspritesect[i];j>=0;j=nextspritesect[j]) + //if ((show2dsprite[j>>3]&(1<<(j&7))) > 0) + { + spr = &sprite[j]; + + if (j == k || (spr->cstat&0x8000) || spr->cstat == 257 || spr->xrepeat == 0) continue; + + col = 71; //cyan + if (spr->cstat&1) col = 234; //magenta + + sprx = spr->x; + spry = spr->y; + + if( (spr->cstat&257) != 0) switch (spr->cstat&48) + { + case 0: break; + + ox = sprx-cposx; oy = spry-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = (sintable[(spr->ang+512)&2047]>>7); + oy = (sintable[(spr->ang)&2047]>>7); + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect,ox,yvect); + + x3 = mulscale16(x2,yxaspect); + y3 = mulscale16(y2,yxaspect); + + drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + break; + + case 16: + if( spr->picnum == LASERLINE ) + { + x1 = sprx; y1 = spry; + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + } + + break; + + case 32: + + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + if ((spr->cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; sinang = sintable[k]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + x1 = sprx + dmulscale16(sinang,dax,cosang,day); + y1 = spry + dmulscale16(sinang,day,-cosang,dax); + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang,l); + y2 = y1 + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; + k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x3-cposx; oy = y3-cposy; + x3 = dmulscale16(ox,xvect,-oy,yvect); + y3 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x4-cposx; oy = y4-cposy; + x4 = dmulscale16(ox,xvect,-oy,yvect); + y4 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + + drawline256(x2+(xdim<<11),y2+(ydim<<11), + x3+(xdim<<11),y3+(ydim<<11),col); + + drawline256(x3+(xdim<<11),y3+(ydim<<11), + x4+(xdim<<11),y4+(ydim<<11),col); + + drawline256(x4+(xdim<<11),y4+(ydim<<11), + x1+(xdim<<11),y1+(ydim<<11),col); + + break; + } + } + } + + //Draw white lines + for(i=0;i>3]&(1<<(i&7)))) continue; + + startwall = sector[i].wallptr; + endwall = sector[i].wallptr + sector[i].wallnum; + + k = -1; + for(j=startwall,wal=&wall[startwall];jnextwall >= 0) continue; + + //if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + + if (tilesizx[wal->picnum] == 0) continue; + if (tilesizy[wal->picnum] == 0) continue; + + if (j == k) + { x1 = x2; y1 = y2; } + else + { + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + } + + k = wal->point2; wal2 = &wall[k]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,24); + } + } + + for(p=connecthead;p >= 0;p=connectpoint2[p]) + { + if(ud.scrollmode && p == screenpeek) continue; + + ox = sprite[ps[p].i].x-cposx; oy = sprite[ps[p].i].y-cposy; + daang = (sprite[ps[p].i].ang-cang)&2047; + if (p == screenpeek) { ox = 0; oy = 0; daang = 0; } + x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16); + y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16); + + if(p == screenpeek || (gametype_flags[ud.coop] & GAMETYPE_FLAG_OTHERPLAYERSINMAP ) ) + { + if(sprite[ps[p].i].xvel > 16 && ps[p].on_ground) + i = APLAYERTOP+((totalclock>>4)&3); + else + i = APLAYERTOP; + + j = klabs(ps[p].truefz-ps[p].posz)>>8; + j = mulscale(czoom*(sprite[ps[p].i].yrepeat+j),yxaspect,16); + + if(j < 22000) j = 22000; + else if(j > (65536<<1)) j = (65536<<1); + + rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),j, + daang,i,sprite[ps[p].i].shade,sprite[ps[p].i].pal, + (sprite[ps[p].i].cstat&2)>>1,windowx1,windowy1,windowx2,windowy2); + } + } +} + +void palto(char r,char g,char b,long e) +{ + int i; + char temparray[768]; + long tc; +/* + for(i=0;i<768;i+=3) + { + temparray[i ] = + ps[myconnectindex].palette[i+0]+((((long)r-(long)ps[myconnectindex].palette[i+0])*(long)(e&127))>>6); + temparray[i+1] = + ps[myconnectindex].palette[i+1]+((((long)g-(long)ps[myconnectindex].palette[i+1])*(long)(e&127))>>6); + temparray[i+2] = + ps[myconnectindex].palette[i+2]+((((long)b-(long)ps[myconnectindex].palette[i+2])*(long)(e&127))>>6); + } +*/ + + //setbrightness(ud.brightness>>2,temparray); + setpalettefade(r,g,b,e&127); + if (getrendermode() >= 3) pus = pub = NUMPAGES; // JBF 20040110: redraw the status bar next time + if ((e&128) == 0) { + nextpage(); + for (tc = totalclock; totalclock < tc + 4; handleevents(), getpackets() ); + } +} + +void displayrest(long smoothratio) +{ + long a, i, j; + char fader=0,fadeg=0,fadeb=0,fadef=0,tintr=0,tintg=0,tintb=0,tintf=0,dotint=0; + + struct player_struct *pp; + walltype *wal; + long cposx,cposy,cang; + + pp = &ps[screenpeek]; + + // this takes care of fullscreen tint for OpenGL + if (getrendermode() >= 3) { + if (pp->palette == waterpal) tintr=0,tintg=0,tintb=63,tintf=8; + else if (pp->palette == slimepal) tintr=0,tintg=63,tintb=0,tintf=8; + } + + // this does pain tinting etc from the CON + if( pp->pals_time >= 0 && pp->loogcnt == 0) // JBF 20040101: pals_time > 0 now >= 0 + { + fader = pp->pals[0]; + fadeg = pp->pals[1]; + fadeb = pp->pals[2]; + fadef = pp->pals_time; + restorepalette = 1; // JBF 20040101 + dotint = 1; + } + // reset a normal palette + else if( restorepalette ) + { + //setbrightness(ud.brightness>>2,&pp->palette[0],0); + setgamepalette(pp,pp->palette,0); + restorepalette = 0; + } + // loogies courtesy of being snotted on + else if(pp->loogcnt > 0) { + //palto(0,64,0,(pp->loogcnt>>1)+128); + fader = 0; + fadeg = 64; + fadeb = 0; + fadef = pp->loogcnt>>1; + dotint = 1; + } + if (fadef > tintf) { + tintr = fader; + tintg = fadeg; + tintb = fadeb; + tintf = fadef; + } + + if(ud.show_help) + { + switch(ud.show_help) + { + case 1: + rotatesprite(0,0,65536L,0,TEXTSTORY,0,0,10+16+64, 0,0,xdim-1,ydim-1); + break; + case 2: + rotatesprite(0,0,65536L,0,F1HELP,0,0,10+16+64, 0,0,xdim-1,ydim-1); + break; + } + + if ( KB_KeyPressed(sc_Escape ) ) + { + KB_ClearKeyDown(sc_Escape); + ud.show_help = 0; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + vscrn(); + } + if (tintf > 0 || dotint) palto(tintr,tintg,tintb,tintf|128); + return; + } + + i = pp->cursectnum; + + show2dsector[i>>3] |= (1<<(i&7)); + wal = &wall[sector[i].wallptr]; + for(j=sector[i].wallnum;j>0;j--,wal++) + { + i = wal->nextsector; + if (i < 0) continue; + if (wal->cstat&0x0071) continue; + if (wall[wal->nextwall].cstat&0x0071) continue; + if (sector[i].lotag == 32767) continue; + if (sector[i].ceilingz >= sector[i].floorz) continue; + show2dsector[i>>3] |= (1<<(i&7)); + } + + if(ud.camerasprite == -1) + { + if( ud.overhead_on != 2 ) + { + if(pp->newowner >= 0) + cameratext(pp->newowner); + else + { + displayweapon(screenpeek); + if(pp->over_shoulder_on == 0 ) + displaymasks(screenpeek); + } + moveclouds(); + } + + if( ud.overhead_on > 0 ) + { + smoothratio = min(max(smoothratio,0),65536); + dointerpolations(smoothratio); + if( ud.scrollmode == 0 ) + { + if(pp->newowner == -1) + { + if (screenpeek == myconnectindex && numplayers > 1) + { + cposx = omyx+mulscale16((long)(myx-omyx),smoothratio); + cposy = omyy+mulscale16((long)(myy-omyy),smoothratio); + cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); + } + else + { + cposx = pp->oposx+mulscale16((long)(pp->posx-pp->oposx),smoothratio); + cposy = pp->oposy+mulscale16((long)(pp->posy-pp->oposy),smoothratio); + cang = pp->oang+mulscale16((long)(((pp->ang+1024-pp->oang)&2047)-1024),smoothratio); + } + } + else + { + cposx = pp->oposx; + cposy = pp->oposy; + cang = pp->oang; + } + } + else + { + + ud.fola += ud.folavel>>3; + ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14; + ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14; + + cposx = ud.folx; + cposy = ud.foly; + cang = ud.fola; + } + + if(ud.overhead_on == 2) + { + clearview(0L); + drawmapview(cposx,cposy,pp->zoom,cang); + } + drawoverheadmap( cposx,cposy,pp->zoom,cang); + + restoreinterpolations(); + + if(ud.overhead_on == 2) + { + if(ud.screen_size > 0) a = 147; + else a = 182; + + minitext(1,a+6,volume_names[ud.volume_number],0,2+8+16); + minitext(1,a+12,level_names[ud.volume_number*11 + ud.level_number],0,2+8+16); + } + } + } + + coolgaugetext(screenpeek); + operatefta(); + + if( KB_KeyPressed(sc_Escape) && ud.overhead_on == 0 + && ud.show_help == 0 + && ps[myconnectindex].newowner == -1) + { + if( (ps[myconnectindex].gm&MODE_MENU) == MODE_MENU && current_menu < 51) + { + KB_ClearKeyDown(sc_Escape); + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + cameraclock = totalclock; + cameradist = 65536L; + } + walock[TILE_SAVESHOT] = 199; + vscrn(); + } + else if( (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU && + ps[myconnectindex].newowner == -1 && + (ps[myconnectindex].gm&MODE_TYPE) != MODE_TYPE) + { + KB_ClearKeyDown(sc_Escape); + FX_StopAllSounds(); + clearsoundlocks(); + + intomenusounds(); + + ps[myconnectindex].gm |= MODE_MENU; + + if(ud.multimode < 2 && ud.recstat != 2) ready2send = 0; + + if(ps[myconnectindex].gm&MODE_GAME) cmenu(50); + else cmenu(0); + screenpeek = myconnectindex; + } + } + + OnEvent(EVENT_DISPLAYREST, ps[screenpeek].i, screenpeek, -1); + + if(ps[myconnectindex].newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1) + { + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DISPLAYCROSSHAIR, ps[screenpeek].i, screenpeek, -1); + + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0) + rotatesprite((160L-(ps[myconnectindex].look_ang>>1))<<16,100L<<16,65536L,0,CROSSHAIR,0,0,2+1,windowx1,windowy1,windowx2,windowy2); + } + if(ps[myconnectindex].gm&MODE_TYPE) + typemode(); + else + menus(); + + if( ud.pause_on==1 && (ps[myconnectindex].gm&MODE_MENU) == 0 ) + menutext(160,100,0,0,"GAME PAUSED"); + + if(ud.coords) + coords(screenpeek); + if(ud.tickrate&&!(ps[myconnectindex].gm&MODE_MENU)) + tics(); + + // JBF 20040124: display level stats in screen corner + if(ud.levelstats && (ps[myconnectindex].gm&MODE_MENU) == 0) { + i = (ud.screen_size <= 4)?0:scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100); + + Bsprintf(tempbuf,"Time: %ld:%02ld", + (ps[myconnectindex].player_par/(26*60)), + (ps[myconnectindex].player_par/26)%60); + minitext(320-5*12,200-i-6-6-6,tempbuf,0,26); + + if(ud.player_skill > 3 ) + Bsprintf(tempbuf,"Kills: %ld",ps[myconnectindex].actors_killed); + else + Bsprintf(tempbuf,"Kills: %ld/%ld",ps[myconnectindex].actors_killed, + ps[myconnectindex].max_actors_killed>ps[myconnectindex].actors_killed? + ps[myconnectindex].max_actors_killed:ps[myconnectindex].actors_killed); + minitext(320-5*12,200-i-6-6,tempbuf,0,26); + + Bsprintf(tempbuf,"Secrets: %ld/%ld", ps[myconnectindex].secret_rooms,ps[myconnectindex].max_secret_rooms); + minitext(320-5*12,200-i-6,tempbuf,0,26); + } + if (tintf > 0 || dotint) palto(tintr,tintg,tintb,tintf|128); +} + +void view(struct player_struct *pp, long *vx, long *vy,long *vz,short *vsectnum, short ang, short horiz) +{ + spritetype *sp; + long i, nx, ny, nz, hx, hy, hz, hitx, hity, hitz; + short bakcstat, hitsect, hitwall, hitsprite, daang; + + nx = (sintable[(ang+1536)&2047]>>4); + ny = (sintable[(ang+1024)&2047]>>4); + nz = (horiz-100)*128; + + sp = &sprite[pp->i]; + + bakcstat = sp->cstat; + sp->cstat &= (short)~0x101; + + updatesectorz(*vx,*vy,*vz,vsectnum); + hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + if(*vsectnum < 0) + { + sp->cstat = bakcstat; + return; + } + + hx = hitx-(*vx); hy = hity-(*vy); + if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy)) + { + *vsectnum = hitsect; + if (hitwall >= 0) + { + daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x, + wall[wall[hitwall].point2].y-wall[hitwall].y); + + i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047]; + if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i); + else hy -= mulscale28(ny,i); + } + else if (hitsprite < 0) + { + if (klabs(nx) > klabs(ny)) hx -= (nx>>5); + else hy -= (ny>>5); + } + if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx); + else i = divscale16(hy,ny); + if (i < cameradist) cameradist = i; + } + *vx = (*vx)+mulscale16(nx,cameradist); + *vy = (*vy)+mulscale16(ny,cameradist); + *vz = (*vz)+mulscale16(nz,cameradist); + + cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536); + cameraclock = totalclock; + + updatesectorz(*vx,*vy,*vz,vsectnum); + + sp->cstat = bakcstat; +} + +//REPLACE FULLY +void drawbackground(void) +{ + short dapicnum; + long x,y,x1,y1,x2,y2,rx; + + flushperms(); + + switch(ud.m_volume_number) + { + default:dapicnum = BIGHOLE;break; + case 1:dapicnum = BIGHOLE;break; + case 2:dapicnum = BIGHOLE;break; + } + + if (tilesizx[dapicnum] == 0 || tilesizy[dapicnum] == 0) { + pus = pub = NUMPAGES; + return; + } + + y1 = 0; y2 = ydim; + if( (ready2send && ps[myconnectindex].gm == MODE_GAME) || ud.recstat == 2 ) + //if (ud.recstat == 0 || ud.recstat == 1 || (ud.recstat == 2 && ud.reccnt > 0)) // JBF 20040717 + { + if (ud.screen_size == 8) + y1 = scale(ydim,200-scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100),200); + else if((gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + { + if (ud.multimode > 1) y1 += scale(ydim,8,200); + if (ud.multimode > 4) y1 += scale(ydim,8,200); + } + } else { + // when not rendering a game, fullscreen wipe + SetGameVarID(g_iReturnVarID,BIGHOLE, -1, -1); + OnEvent(EVENT_GETMENUTILE, -1, -1, -1); + if (GetGameVar("MENU_TILE", 1, -1, -1)) + { + for(y=y1;y 8) { + // across top + for (y=0; y> 1; + x1 = xdim-x2; x1 -= x1%tilesizx[dapicnum]; + for(y=y1-y1%tilesizy[dapicnum]; y 8 && ( ready2send || ud.recstat == 2 )) + { + y = 0; + if((gametype_flags[ud.coop] & GAMETYPE_FLAG_FRAGBAR)) + { + if (ud.multimode > 1) y += 8; + if (ud.multimode > 4) y += 8; + } + + x1 = max(windowx1-4,0); + y1 = max(windowy1-4,y); + x2 = min(windowx2+4,xdim-1); + y2 = min(windowy2+4,scale(ydim,200-scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100),200)-1); + + for(y=y1+4;y=0;j=nextspritestat[j]) + { + if( sprite[j].picnum==1 && sprite[j].lotag==fofmode && sprite[j].hitag==sprite[floor1].hitag ) + { + floor1=j; + fofmode=sprite[j].lotag; + ok++; + break; + } + } + // if(ok==1) { Message("no floor1",RED); return; } + + if(fofmode==40) k=41; else k=40; + + for(j=headspritestat[15];j>=0;j=nextspritestat[j]) + { + if( sprite[j].picnum==1 && sprite[j].lotag==k && sprite[j].hitag==sprite[floor1].hitag ) + { + floor2=j; ok++; break; + } + } + + i=floor1; + offx=sprite[floor2].x-sprite[floor1].x; + offy=sprite[floor2].y-sprite[floor1].y; + offz=0; + + if (sprite[floor2].ang >= 1024) + offz = sprite[floor2].z; + else if (fofmode==41) + offz = sector[sprite[floor2].sectnum].floorz; + else + offz = sector[sprite[floor2].sectnum].ceilingz; + + if (sprite[floor1].ang >= 1024) + offz -= sprite[floor1].z; + else if (fofmode==40) + offz -= sector[sprite[floor1].sectnum].floorz; + else + offz -= sector[sprite[floor1].sectnum].ceilingz; + + + // if(ok==2) { Message("no floor2",RED); return; } + + for(j=headspritestat[15];j>=0;j=nextspritestat[j]) // raise ceiling or floor + { + if(sprite[j].picnum==1 && sprite[j].lotag==k+2 && sprite[j].hitag==sprite[floor1].hitag ) + { + if(k==40) + { + tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].floorz; + sector[sprite[j].sectnum].floorz+=(((z-sector[sprite[j].sectnum].floorz)/32768)+1)*32768; + tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].floorpicnum; + sector[sprite[j].sectnum].floorpicnum=562; + } + else + { + tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingz; + sector[sprite[j].sectnum].ceilingz+=(((z-sector[sprite[j].sectnum].ceilingz)/32768)-1)*32768; + tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingpicnum; + sector[sprite[j].sectnum].ceilingpicnum=562; + } + draw_both = 1; + } + } + + drawrooms(x+offx,y+offy,z+offz,a,h,sprite[floor2].sectnum); + animatesprites(x,y,a,smoothratio); + drawmasks(); + + if (draw_both) + { + for(j=headspritestat[15];j>=0;j=nextspritestat[j]) // restore ceiling or floor for the draw both sectors + { + if(sprite[j].picnum==1 && + sprite[j].lotag==k+2 && + sprite[j].hitag==sprite[floor1].hitag) + { + if(k==40) + { + sector[sprite[j].sectnum].floorz=tempsectorz[sprite[j].sectnum]; + sector[sprite[j].sectnum].floorpicnum=tempsectorpicnum[sprite[j].sectnum]; + } + else + { + sector[sprite[j].sectnum].ceilingz=tempsectorz[sprite[j].sectnum]; + sector[sprite[j].sectnum].ceilingpicnum=tempsectorpicnum[sprite[j].sectnum]; + } + }// end if + }// end for + + // Now re-draw + drawrooms(x+offx,y+offy,z+offz,a,h,sprite[floor2].sectnum); + animatesprites(x,y,a,smoothratio); + drawmasks(); + } +} // end SE40 + +static void se40code(long x,long y,long z,long a,long h, long smoothratio) +{ + int i; + + i = headspritestat[15]; + while(i >= 0) + { + int t = sprite[i].lotag; + switch(t) + { + // case 40: + // case 41: + // SE40_Draw(i,x,y,a,smoothratio); + // break; + case 42: + case 43: + case 44: + case 45: + if(ps[screenpeek].cursectnum == sprite[i].sectnum) + SE40_Draw(i,x,y,z,a,h,smoothratio); + break; + } + i = nextspritestat[i]; + } +} +#endif + +static long oyrepeat=-1; + +void displayrooms(short snum,long smoothratio) +{ + long cposx,cposy,cposz,dst,j,fz,cz,hz,lz; + short sect, cang, k, choriz,tsect; + struct player_struct *p; + long tposx,tposy,tposz,dx,dy,thoriz,i; + short tang; + long tiltcx,tiltcy,tiltcs=0; // JBF 20030807 + + p = &ps[snum]; + + if(pub > 0 || getrendermode() >= 3) // JBF 20040101: redraw background always + { + if(ud.screen_size > 8 || (ud.screen_size == 8 && ud.statusbarscale<100)) drawbackground(); + pub = 0; + } + + if( ud.overhead_on == 2 || ud.show_help || p->cursectnum == -1) + return; + + smoothratio = min(max(smoothratio,0),65536); + + visibility = p->visibility; + + if(ud.pause_on || ps[snum].on_crane > -1) smoothratio = 65536; + + sect = p->cursectnum; + if(sect < 0 || sect >= MAXSECTORS) return; + + dointerpolations(smoothratio); + + animatecamsprite(); + + if(ud.camerasprite >= 0) + { + spritetype *s; + + s = &sprite[ud.camerasprite]; + + if(s->yvel < 0) s->yvel = -100; + else if(s->yvel > 199) s->yvel = 300; + + cang = hittype[ud.camerasprite].tempang+mulscale16((long)(((s->ang+1024-hittype[ud.camerasprite].tempang)&2047)-1024),smoothratio); +#ifdef SE40 + se40code(s->x,s->y,s->z,cang,s->yvel,smoothratio); +#endif + drawrooms(s->x,s->y,s->z-(4<<8),cang,s->yvel,s->sectnum); + animatesprites(s->x,s->y,cang,smoothratio); + drawmasks(); + } + else + { + i = divscale22(1,sprite[p->i].yrepeat+28); + if (i != oyrepeat) + { + oyrepeat = i; + setaspect(oyrepeat,yxaspect); + } + + if(screencapt) + { + walock[TILE_SAVESHOT] = 199; + if (waloff[TILE_SAVESHOT] == 0) + allocache((long *)&waloff[TILE_SAVESHOT],200*320,&walock[TILE_SAVESHOT]); + setviewtotile(TILE_SAVESHOT,200L,320L); + } + else if( getrendermode() == 0 && ( ( ud.screen_tilting && p->rotscrnang ) || ud.detail==0 ) ) + { + if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0; + + if (xres <= 320 && yres <= 240) { // JBF 20030807: Increased tilted-screen quality + tiltcs = 1; + tiltcx = 320; + tiltcy = 200; + } else { + tiltcs = 2; + tiltcx = 640; + tiltcy = 480; + } + + walock[TILE_TILT] = 255; + if (waloff[TILE_TILT] == 0) + allocache(&waloff[TILE_TILT],tiltcx*tiltcx,&walock[TILE_TILT]); + if ((tang&1023) == 0) + setviewtotile(TILE_TILT,tiltcy>>(1-ud.detail),tiltcx>>(1-ud.detail)); + else + setviewtotile(TILE_TILT,tiltcx>>(1-ud.detail),tiltcx>>(1-ud.detail)); + if ((tang&1023) == 512) + { //Block off unscreen section of 90ø tilted screen + j = ((tiltcx-(60*tiltcs))>>(1-ud.detail)); + for(i=((60*tiltcs)>>(1-ud.detail))-1;i>=0;i--) + { + startumost[i] = 1; startumost[i+j] = 1; + startdmost[i] = 0; startdmost[i+j] = 0; + } + } + + i = (tang&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + setaspect(i>>1,yxaspect); + } else if (getrendermode() > 0 /*&& (p->rotscrnang || p->orotscrnang)*/) { + setrollangle(p->orotscrnang + mulscale16(((p->rotscrnang - p->orotscrnang + 1024)&2047)-1024,smoothratio)); + p->orotscrnang = p->rotscrnang; // JBF: save it for next time + } + + if ( (snum == myconnectindex) && (numplayers > 1) ) + { + cposx = omyx+mulscale16((long)(myx-omyx),smoothratio); + cposy = omyy+mulscale16((long)(myy-omyy),smoothratio); + cposz = omyz+mulscale16((long)(myz-omyz),smoothratio); + cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); + choriz = omyhoriz+omyhorizoff+mulscale16((long)(myhoriz+myhorizoff-omyhoriz-omyhorizoff),smoothratio); + sect = mycursectnum; + } + else + { + cposx = p->oposx+mulscale16((long)(p->posx-p->oposx),smoothratio); + cposy = p->oposy+mulscale16((long)(p->posy-p->oposy),smoothratio); + cposz = p->oposz+mulscale16((long)(p->posz-p->oposz),smoothratio); + cang = p->oang+mulscale16((long)(((p->ang+1024-p->oang)&2047)-1024),smoothratio); + choriz = p->ohoriz+p->ohorizoff+mulscale16((long)(p->horiz+p->horizoff-p->ohoriz-p->ohorizoff),smoothratio); + } + cang += p->look_ang; + + if (p->newowner >= 0) + { + cang = p->ang+p->look_ang; + choriz = p->horiz+p->horizoff; + cposx = p->posx; + cposy = p->posy; + cposz = p->posz; + sect = sprite[p->newowner].sectnum; + smoothratio = 65536L; + } + + else if( p->over_shoulder_on == 0 ) + cposz += p->opyoff+mulscale16((long)(p->pyoff-p->opyoff),smoothratio); + else view(p,&cposx,&cposy,&cposz,§,cang,choriz); + + cz = hittype[p->i].ceilingz; + fz = hittype[p->i].floorz; + + if(earthquaketime > 0 && p->on_ground == 1) + { + cposz += 256-(((earthquaketime)&1)<<9); + cang += (2-((earthquaketime)&2))<<2; + } + + if(sprite[p->i].pal == 1) cposz -= (18<<8); + + if(p->newowner >= 0) + choriz = 100+sprite[p->newowner].shade; + else if(p->spritebridge == 0) + { + if( cposz < ( p->truecz + (4<<8) ) ) cposz = cz + (4<<8); + else if( cposz > ( p->truefz - (4<<8) ) ) cposz = fz - (4<<8); + } + + if (sect >= 0) + { + getzsofslope(sect,cposx,cposy,&cz,&fz); + if (cposz < cz+(4<<8)) cposz = cz+(4<<8); + if (cposz > fz-(4<<8)) cposz = fz-(4<<8); + } + + if(choriz > 299) choriz = 299; + else if(choriz < -99) choriz = -99; +#ifdef SE40 + se40code(cposx,cposy,cposz,cang,choriz,smoothratio); +#endif + if ((gotpic[MIRROR>>3]&(1<<(MIRROR&7))) > 0) + { + dst = 0x7fffffff; i = 0; + for(k=0;k>1) + (j>>2); + + drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]+MAXSECTORS); + + display_mirror = 1; + animatesprites(tposx,tposy,tang,smoothratio); + display_mirror = 0; + + drawmasks(); + completemirror(); //Reverse screen x-wise in this function + visibility = j; + } + gotpic[MIRROR>>3] &= ~(1<<(MIRROR&7)); + } + + drawrooms(cposx,cposy,cposz,cang,choriz,sect); + animatesprites(cposx,cposy,cang,smoothratio); + drawmasks(); + + if(screencapt == 1) + { + setviewback(); + screencapt = 0; + // walock[TILE_SAVESHOT] = 1; + } + else if( getrendermode() == 0 && ( ( ud.screen_tilting && p->rotscrnang) || ud.detail==0 ) ) + { + if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0; + + if (getrendermode() == 0) { + setviewback(); + picanm[TILE_TILT] &= 0xff0000ff; + i = (tang&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + if ((1-ud.detail) == 0) i >>= 1; + i>>=(tiltcs-1); // JBF 20030807 + rotatesprite(160<<16,100<<16,i,tang+512,TILE_TILT,0,0,4+2+64,windowx1,windowy1,windowx2,windowy2); + walock[TILE_TILT] = 199; + } + } + } + + restoreinterpolations(); + + if (totalclock < lastvisinc) + { + if (klabs(p->visibility-ud.const_visibility) > 8) + p->visibility += (ud.const_visibility-p->visibility)>>2; + } + else p->visibility = ud.const_visibility; +} + +short LocateTheLocator(short n,short sn) +{ + short i; + + i = headspritestat[7]; + while(i >= 0) + { + if( (sn == -1 || sn == SECT) && n == SLT ) + return i; + i = nextspritestat[i]; + } + return -1; +} + +short EGS(short whatsect,long s_x,long s_y,long s_z,short s_pn,signed char s_s,signed char s_xr,signed char s_yr,short s_a,short s_ve,long s_zv,short s_ow,signed char s_ss) +{ + short i; + long p; + spritetype *s; + + i = insertsprite(whatsect,s_ss); + + if( i < 0 ) + gameexit(" Too many sprites spawned."); + + hittype[i].bposx = s_x; + hittype[i].bposy = s_y; + hittype[i].bposz = s_z; + + s = &sprite[i]; + + s->x = s_x; + s->y = s_y; + s->z = s_z; + s->cstat = 0; + s->picnum = s_pn; + s->shade = s_s; + s->xrepeat = s_xr; + s->yrepeat = s_yr; + s->pal = 0; + + s->ang = s_a; + s->xvel = s_ve; + s->zvel = s_zv; + s->owner = s_ow; + s->xoffset = 0; + s->yoffset = 0; + s->yvel = 0; + s->clipdist = 0; + s->pal = 0; + s->lotag = 0; + + hittype[i].picnum = sprite[s_ow].picnum; + + hittype[i].lastvx = 0; + hittype[i].lastvy = 0; + + hittype[i].timetosleep = 0; + hittype[i].actorstayput = -1; + hittype[i].extra = -1; + hittype[i].owner = s_ow; + hittype[i].cgg = 0; + hittype[i].movflag = 0; + hittype[i].tempang = 0; + hittype[i].dispicnum = 0; + hittype[i].floorz = hittype[s_ow].floorz; + hittype[i].ceilingz = hittype[s_ow].ceilingz; + + T1=T3=T4=T6=T7=T8=T9=0; + + actorspriteflags[i] = 0; + + if( actorscrptr[s_pn] ) + { + s->extra = *actorscrptr[s_pn]; + T5 = *(actorscrptr[s_pn]+1); + T2 = *(actorscrptr[s_pn]+2); + s->hitag = *(actorscrptr[s_pn]+3); + } + else + { + T2=T5=0; + s->extra = 0; + s->hitag = 0; + } + + if (show2dsector[SECT>>3]&(1<<(SECT&7))) show2dsprite[i>>3] |= (1<<(i&7)); + else show2dsprite[i>>3] &= ~(1<<(i&7)); + + clearbufbyte(&spriteext[i], sizeof(spriteexttype), 0); + + /* + if(s->sectnum < 0) + { + s->xrepeat = s->yrepeat = 0; + changespritestat(i,5); + } + */ + ResetActorGameVars(i); + actorspriteflags[i] = 0; + OnEvent(EVENT_EGS,i, findplayer(&sprite[i],&p), p); + return(i); +} + +char wallswitchcheck(short i) +{ + int j; + //MULTISWITCH has 4 states so deal with it separately + if ((PN >= MULTISWITCH) && (PN <=MULTISWITCH+3)) return 1; + // ACCESSSWITCH and ACCESSSWITCH2 are only active in 1 state so deal with them separately + if ((PN == ACCESSSWITCH) || (PN == ACCESSSWITCH2)) return 1; + //loop to catch both states of switches + for (j=0;j<=1;j++) { + switch(dynamictostatic[PN-j]) + { + case HANDPRINTSWITCH__STATIC: + //case HANDPRINTSWITCH+1: + case ALIENSWITCH__STATIC: + //case ALIENSWITCH+1: + case MULTISWITCH__STATIC: + //case MULTISWITCH+1: + //case MULTISWITCH+2: + //case MULTISWITCH+3: + //case ACCESSSWITCH: + //case ACCESSSWITCH2: + case PULLSWITCH__STATIC: + //case PULLSWITCH+1: + case HANDSWITCH__STATIC: + //case HANDSWITCH+1: + case SLOTDOOR__STATIC: + //case SLOTDOOR+1: + case LIGHTSWITCH__STATIC: + //case LIGHTSWITCH+1: + case SPACELIGHTSWITCH__STATIC: + //case SPACELIGHTSWITCH+1: + case SPACEDOORSWITCH__STATIC: + //case SPACEDOORSWITCH+1: + case FRANKENSTINESWITCH__STATIC: + //case FRANKENSTINESWITCH+1: + case LIGHTSWITCH2__STATIC: + //case LIGHTSWITCH2+1: + case POWERSWITCH1__STATIC: + //case POWERSWITCH1+1: + case LOCKSWITCH1__STATIC: + //case LOCKSWITCH1+1: + case POWERSWITCH2__STATIC: + //case POWERSWITCH2+1: + case DIPSWITCH__STATIC: + //case DIPSWITCH+1: + case DIPSWITCH2__STATIC: + //case DIPSWITCH2+1: + case TECHSWITCH__STATIC: + //case TECHSWITCH+1: + case DIPSWITCH3__STATIC: + //case DIPSWITCH3+1: + return 1; + } + } + return 0; +} + +long tempwallptr; +short spawn( short j, short pn ) +{ + short i, s, startwall, endwall, sect, clostest=0; + long x, y, d, p; + spritetype *sp; + + if(j >= 0) + { + i = EGS(sprite[j].sectnum,sprite[j].x,sprite[j].y,sprite[j].z + ,pn,0,0,0,0,0,0,j,0); + hittype[i].picnum = sprite[j].picnum; + } + else + { + i = pn; + + hittype[i].picnum = PN; + hittype[i].timetosleep = 0; + hittype[i].extra = -1; + + hittype[i].bposx = SX; + hittype[i].bposy = SY; + hittype[i].bposz = SZ; + + OW = hittype[i].owner = i; + hittype[i].cgg = 0; + hittype[i].movflag = 0; + hittype[i].tempang = 0; + hittype[i].dispicnum = 0; + hittype[i].floorz = sector[SECT].floorz; + hittype[i].ceilingz = sector[SECT].ceilingz; + + hittype[i].lastvx = 0; + hittype[i].lastvy = 0; + hittype[i].actorstayput = -1; + + T1 = T2 = T3 = T4 = T5 = T6 = T7 = T8 = T9 = 0; + + actorspriteflags[i] = 0; + + if( PN != SPEAKER && PN != LETTER && PN != DUCK && PN != TARGET && PN != TRIPBOMB && PN != VIEWSCREEN && PN != VIEWSCREEN2 && (CS&48) ) + if( !(PN >= CRACK1 && PN <= CRACK4) ) + { + if(SS == 127) return i; + if( wallswitchcheck(i) == 1 && (CS&16) ) + { + if( PN != ACCESSSWITCH && PN != ACCESSSWITCH2 && sprite[i].pal) + { + if( (ud.multimode < 2) || (ud.multimode > 1 && !(gametype_flags[ud.coop] & GAMETYPE_FLAG_DMSWITCHES)) ) + { + sprite[i].xrepeat = sprite[i].yrepeat = 0; + sprite[i].cstat = SLT = SHT = 0; + return i; + } + } + CS |= 257; + if( sprite[i].pal && PN != ACCESSSWITCH && PN != ACCESSSWITCH2) + sprite[i].pal = 0; + return i; + } + + if( SHT ) + { + changespritestat(i,12); + CS |= 257; + SH = impact_damage; + return i; + } + } + + s = PN; + + if( CS&1 ) CS |= 256; + + if( actorscrptr[s] ) + { + SH = *(actorscrptr[s]); + T5 = *(actorscrptr[s]+1); + T2 = *(actorscrptr[s]+2); + if( *(actorscrptr[s]+3) && SHT == 0 ) + SHT = *(actorscrptr[s]+3); + } + else T2 = T5 = 0; + } + + sp = &sprite[i]; + sect = sp->sectnum; + + //some special cases that can't be handled through the dynamictostatic system. + if (((sp->picnum >= BOLT1)&&(sp->picnum <= BOLT1+3))||((sp->picnum >= SIDEBOLT1)&&(sp->picnum <= SIDEBOLT1+3))) + { + T1 = sp->xrepeat; + T2 = sp->yrepeat; + sp->yvel = 0; + changespritestat(i,6); + } + else if (((sp->picnum >= CAMERA1)&&(sp->picnum <= CAMERA1+3))||(sp->picnum==CAMERAPOLE)||(sp->picnum==GENERICPOLE)) + { + if (sp->picnum != GENERICPOLE) { + sp->extra = 1; + + if(camerashitable) sp->cstat = 257; + else sp->cstat = 0; + } + if( ud.multimode < 2 && sp->pal != 0 ) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + + } + else { + sp->pal = 0; + if (!(sp->picnum == CAMERAPOLE || sp->picnum == GENERICPOLE)) { + sp->picnum = CAMERA1; + changespritestat(i,1); + } + } + } + else switch(dynamictostatic[sp->picnum]) + { + default: + + if( actorscrptr[sp->picnum] ) + { + if( j == -1 && sp->lotag > ud.player_skill ) + { + sp->xrepeat=sp->yrepeat=0; + changespritestat(i,5); + break; + } + + // Init the size + if(sp->xrepeat == 0 || sp->yrepeat == 0) + sp->xrepeat = sp->yrepeat = 1; + + if( actortype[sp->picnum] & 3) + { + if( ud.monsters_off == 1 ) + { + sp->xrepeat=sp->yrepeat=0; + changespritestat(i,5); + break; + } + + makeitfall(i); + + if( actortype[sp->picnum] & 2) + hittype[i].actorstayput = sp->sectnum; + + ps[myconnectindex].max_actors_killed++; + sp->clipdist = 80; + if(j >= 0) + { + if(sprite[j].picnum == RESPAWN) + hittype[i].tempang = sprite[i].pal = sprite[j].pal; + changespritestat(i,1); + } + else changespritestat(i,2); + } + else + { + sp->clipdist = 40; + sp->owner = i; + changespritestat(i,1); + } + + hittype[i].timetosleep = 0; + + if(j >= 0) + sp->ang = sprite[j].ang; + } + break; + case FOF__STATIC: + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + case WATERSPLASH2__STATIC: + if(j >= 0) + { + setsprite(i,sprite[j].x,sprite[j].y,sprite[j].z); + sp->xrepeat = sp->yrepeat = 8+(TRAND&7); + } + else sp->xrepeat = sp->yrepeat = 16+(TRAND&15); + + sp->shade = -16; + sp->cstat |= 128; + if(j >= 0) + { + if(sector[sprite[j].sectnum].lotag == 2) + { + sp->z = getceilzofslope(SECT,SX,SY)+(16<<8); + sp->cstat |= 8; + } + else if( sector[sprite[j].sectnum].lotag == 1) + sp->z = getflorzofslope(SECT,SX,SY); + } + + if(sector[sect].floorpicnum == FLOORSLIME || + sector[sect].ceilingpicnum == FLOORSLIME) + sp->pal = 7; + case NEON1__STATIC: + case NEON2__STATIC: + case NEON3__STATIC: + case NEON4__STATIC: + case NEON5__STATIC: + case NEON6__STATIC: + case DOMELITE__STATIC: + if(sp->picnum != WATERSPLASH2) + sp->cstat |= 257; + case NUKEBUTTON__STATIC: + if(sp->picnum == DOMELITE) + sp->cstat |= 257; + case JIBS1__STATIC: + case JIBS2__STATIC: + case JIBS3__STATIC: + case JIBS4__STATIC: + case JIBS5__STATIC: + case JIBS6__STATIC: + case HEADJIB1__STATIC: + case ARMJIB1__STATIC: + case LEGJIB1__STATIC: + case LIZMANHEAD1__STATIC: + case LIZMANARM1__STATIC: + case LIZMANLEG1__STATIC: + case DUKETORSO__STATIC: + case DUKEGUN__STATIC: + case DUKELEG__STATIC: + changespritestat(i,5); + break; + case TONGUE__STATIC: + if(j >= 0) + sp->ang = sprite[j].ang; + sp->z -= 38<<8; + sp->zvel = 256-(TRAND&511); + sp->xvel = 64-(TRAND&127); + changespritestat(i,4); + break; + case NATURALLIGHTNING__STATIC: + sp->cstat &= ~257; + sp->cstat |= 32768; + break; + case TRANSPORTERSTAR__STATIC: + case TRANSPORTERBEAM__STATIC: + if(j == -1) break; + if(sp->picnum == TRANSPORTERBEAM) + { + sp->xrepeat = 31; + sp->yrepeat = 1; + sp->z = sector[sprite[j].sectnum].floorz-(40<<8); + } + else + { + if(sprite[j].statnum == 4) + { + sp->xrepeat = 8; + sp->yrepeat = 8; + } + else + { + sp->xrepeat = 48; + sp->yrepeat = 64; + if(sprite[j].statnum == 10 || badguy(&sprite[j]) ) + sp->z -= (32<<8); + } + } + + sp->shade = -127; + sp->cstat = 128|2; + sp->ang = sprite[j].ang; + + sp->xvel = 128; + changespritestat(i,5); + ssp(i,CLIPMASK0); + setsprite(i,sp->x,sp->y,sp->z); + break; + + case FRAMEEFFECT1_13__STATIC: + if (PLUTOPAK) break; + case FRAMEEFFECT1__STATIC: + if(j >= 0) + { + sp->xrepeat = sprite[j].xrepeat; + sp->yrepeat = sprite[j].yrepeat; + T2 = sprite[j].picnum; + } + else sp->xrepeat = sp->yrepeat = 0; + + changespritestat(i,5); + + break; + + case LASERLINE__STATIC: + sp->yrepeat = 6; + sp->xrepeat = 32; + + if(lasermode == 1) + sp->cstat = 16 + 2; + else if(lasermode == 0 || lasermode == 2) + sp->cstat = 16; + else + { + sp->xrepeat = 0; + sp->yrepeat = 0; + } + + if(j >= 0) sp->ang = hittype[j].temp_data[5]+512; + changespritestat(i,5); + break; + + case FORCESPHERE__STATIC: + if(j == -1 ) + { + sp->cstat = (short) 32768; + changespritestat(i,2); + } + else + { + sp->xrepeat = sp->yrepeat = 1; + changespritestat(i,5); + } + break; + + case BLOOD__STATIC: + sp->xrepeat = sp->yrepeat = 16; + sp->z -= (26<<8); + if( j >= 0 && sprite[j].pal == 6 ) + sp->pal = 6; + changespritestat(i,5); + break; + case BLOODPOOL__STATIC: + case PUKE__STATIC: + { + short s1; + s1 = sp->sectnum; + + updatesector(sp->x+108,sp->y+108,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x-108,sp->y-108,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x+108,sp->y-108,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x-108,sp->y+108,&s1); + if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz) + { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;} + } + else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;} + } + else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;} + } + else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;} + } + + if( sector[SECT].lotag == 1 ) + { + changespritestat(i,5); + break; + } + + if(j >= 0 && sp->picnum != PUKE) + { + if( sprite[j].pal == 1) + sp->pal = 1; + else if( sprite[j].pal != 6 && sprite[j].picnum != NUKEBARREL && sprite[j].picnum != TIRE ) + { + if(sprite[j].picnum == FECES) + sp->pal = 7; // Brown + else sp->pal = 2; // Red + } + else sp->pal = 0; // green + + if(sprite[j].picnum == TIRE) + sp->shade = 127; + } + sp->cstat |= 32; + case FECES__STATIC: + if( j >= 0) + sp->xrepeat = sp->yrepeat = 1; + changespritestat(i,5); + break; + + case BLOODSPLAT1__STATIC: + case BLOODSPLAT2__STATIC: + case BLOODSPLAT3__STATIC: + case BLOODSPLAT4__STATIC: + sp->cstat |= 16; + sp->xrepeat = 7+(TRAND&7); + sp->yrepeat = 7+(TRAND&7); + sp->z -= (16<<8); + if(j >= 0 && sprite[j].pal == 6) + sp->pal = 6; + insertspriteq(i); + changespritestat(i,5); + break; + + case TRIPBOMB__STATIC: + if( sp->lotag > ud.player_skill ) + { + sp->xrepeat=sp->yrepeat=0; + changespritestat(i,5); + break; + } + + sp->xrepeat=4; + sp->yrepeat=5; + + sp->owner = i; + sp->hitag = i; + + sp->xvel = 16; + ssp(i,CLIPMASK0); + hittype[i].temp_data[0] = 17; + hittype[i].temp_data[2] = 0; + hittype[i].temp_data[5] = sp->ang; + + case SPACEMARINE__STATIC: + if(sp->picnum == SPACEMARINE) + { + sp->extra = 20; + sp->cstat |= 257; + } + changespritestat(i,2); + break; + + case HYDRENT__STATIC: + case PANNEL1__STATIC: + case PANNEL2__STATIC: + case SATELITE__STATIC: + case FUELPOD__STATIC: + case SOLARPANNEL__STATIC: + case ANTENNA__STATIC: + case GRATE1__STATIC: + case CHAIR1__STATIC: + case CHAIR2__STATIC: + case CHAIR3__STATIC: + case BOTTLE1__STATIC: + case BOTTLE2__STATIC: + case BOTTLE3__STATIC: + case BOTTLE4__STATIC: + case BOTTLE5__STATIC: + case BOTTLE6__STATIC: + case BOTTLE7__STATIC: + case BOTTLE8__STATIC: + case BOTTLE10__STATIC: + case BOTTLE11__STATIC: + case BOTTLE12__STATIC: + case BOTTLE13__STATIC: + case BOTTLE14__STATIC: + case BOTTLE15__STATIC: + case BOTTLE16__STATIC: + case BOTTLE17__STATIC: + case BOTTLE18__STATIC: + case BOTTLE19__STATIC: + case OCEANSPRITE1__STATIC: + case OCEANSPRITE2__STATIC: + case OCEANSPRITE3__STATIC: + case OCEANSPRITE5__STATIC: + case MONK__STATIC: + case INDY__STATIC: + case LUKE__STATIC: + case JURYGUY__STATIC: + case SCALE__STATIC: + case VACUUM__STATIC: + case FANSPRITE__STATIC: + case CACTUS__STATIC: + case CACTUSBROKE__STATIC: + case HANGLIGHT__STATIC: + case FETUS__STATIC: + case FETUSBROKE__STATIC: + case CAMERALIGHT__STATIC: + case MOVIECAMERA__STATIC: + case IVUNIT__STATIC: + case POT1__STATIC: + case POT2__STATIC: + case POT3__STATIC: + case TRIPODCAMERA__STATIC: + case SUSHIPLATE1__STATIC: + case SUSHIPLATE2__STATIC: + case SUSHIPLATE3__STATIC: + case SUSHIPLATE4__STATIC: + case SUSHIPLATE5__STATIC: + case WAITTOBESEATED__STATIC: + case VASE__STATIC: + case PIPE1__STATIC: + case PIPE2__STATIC: + case PIPE3__STATIC: + case PIPE4__STATIC: + case PIPE5__STATIC: + case PIPE6__STATIC: + sp->clipdist = 32; + sp->cstat |= 257; + case OCEANSPRITE4__STATIC: + changespritestat(i,0); + break; + case FEMMAG1__STATIC: + case FEMMAG2__STATIC: + sp->cstat &= ~257; + changespritestat(i,0); + break; + case DUKETAG__STATIC: + case SIGN1__STATIC: + case SIGN2__STATIC: + if(ud.multimode < 2 && sp->pal) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + } + else sp->pal = 0; + break; + case MASKWALL1__STATIC: + case MASKWALL2__STATIC: + case MASKWALL3__STATIC: + case MASKWALL4__STATIC: + case MASKWALL5__STATIC: + case MASKWALL6__STATIC: + case MASKWALL7__STATIC: + case MASKWALL8__STATIC: + case MASKWALL9__STATIC: + case MASKWALL10__STATIC: + case MASKWALL11__STATIC: + case MASKWALL12__STATIC: + case MASKWALL13__STATIC: + case MASKWALL14__STATIC: + case MASKWALL15__STATIC: + j = sp->cstat&60; + sp->cstat = j|1; + changespritestat(i,0); + break; + case FOOTPRINTS__STATIC: + case FOOTPRINTS2__STATIC: + case FOOTPRINTS3__STATIC: + case FOOTPRINTS4__STATIC: + if(j >= 0) + { + short s1; + s1 = sp->sectnum; + + updatesector(sp->x+84,sp->y+84,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x-84,sp->y-84,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x+84,sp->y-84,&s1); + if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz) + { + updatesector(sp->x-84,sp->y+84,&s1); + if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz) + { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;} + } + else { sp->xrepeat = sp->yrepeat = 0;break;} + } + else { sp->xrepeat = sp->yrepeat = 0;break;} + } + else { sp->xrepeat = sp->yrepeat = 0;break;} + + sp->cstat = 32+((ps[sprite[j].yvel].footprintcount&1)<<2); + sp->ang = sprite[j].ang; + } + + sp->z = sector[sect].floorz; + if(sector[sect].lotag != 1 && sector[sect].lotag != 2) + sp->xrepeat = sp->yrepeat = 32; + + insertspriteq(i); + changespritestat(i,5); + break; + + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case PODFEM1__STATIC: + case NAKED1__STATIC: + case STATUE__STATIC: + case TOUGHGAL__STATIC: + sp->yvel = sp->hitag; + sp->hitag = -1; + if(sp->picnum == PODFEM1) sp->extra <<= 1; + case BLOODYPOLE__STATIC: + + case QUEBALL__STATIC: + case STRIPEBALL__STATIC: + + if(sp->picnum == QUEBALL || sp->picnum == STRIPEBALL) + { + sp->cstat = 256; + sp->clipdist = 8; + } + else + { + sp->cstat |= 257; + sp->clipdist = 32; + } + + changespritestat(i,2); + break; + + case DUKELYINGDEAD__STATIC: + if(j >= 0 && sprite[j].picnum == APLAYER) + { + sp->xrepeat = sprite[j].xrepeat; + sp->yrepeat = sprite[j].yrepeat; + sp->shade = sprite[j].shade; + sp->pal = ps[sprite[j].yvel].palookup; + } + case DUKECAR__STATIC: + case HELECOPT__STATIC: + // if(sp->picnum == HELECOPT || sp->picnum == DUKECAR) sp->xvel = 1024; + sp->cstat = 0; + sp->extra = 1; + sp->xvel = 292; + sp->zvel = 360; + case RESPAWNMARKERRED__STATIC: + case BLIMP__STATIC: + + if(sp->picnum == RESPAWNMARKERRED) + { + sp->xrepeat = sp->yrepeat = 24; + if(j >= 0) sp->z = hittype[j].floorz; // -(1<<4); + } + else + { + sp->cstat |= 257; + sp->clipdist = 128; + } + case MIKE__STATIC: + if(sp->picnum == MIKE) + { + sp->yvel = sp->hitag; + sp->hitag = 0; + } + case WEATHERWARN__STATIC: + changespritestat(i,1); + break; + + case SPOTLITE__STATIC: + T1 = sp->x; + T2 = sp->y; + break; + case BULLETHOLE__STATIC: + sp->xrepeat = sp->yrepeat = 3; + sp->cstat = 16+(krand()&12); + insertspriteq(i); + case MONEY__STATIC: + case MAIL__STATIC: + case PAPER__STATIC: + if( sp->picnum == MONEY || sp->picnum == MAIL || sp->picnum == PAPER ) + { + hittype[i].temp_data[0] = TRAND&2047; + sp->cstat = TRAND&12; + sp->xrepeat = sp->yrepeat = 8; + sp->ang = TRAND&2047; + } + changespritestat(i,5); + break; + + case VIEWSCREEN__STATIC: + case VIEWSCREEN2__STATIC: + sp->owner = i; + sp->lotag = 1; + sp->extra = 1; + changespritestat(i,6); + break; + + case SHELL__STATIC: //From the player + case SHOTGUNSHELL__STATIC: + if( j >= 0 ) + { + short snum,a; + + if(sprite[j].picnum == APLAYER) + { + snum = sprite[j].yvel; + a = ps[snum].ang-(TRAND&63)+8; //Fine tune + + T1 = TRAND&1; + if(sp->picnum == SHOTGUNSHELL) + sp->z = (6<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4); + else sp->z = (3<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4); + sp->zvel = -(TRAND&255); + } + else + { + a = sp->ang; + sp->z = sprite[j].z-PHEIGHT+(3<<8); + } + + sp->x = sprite[j].x+(sintable[(a+512)&2047]>>7); + sp->y = sprite[j].y+(sintable[a&2047]>>7); + + sp->shade = -8; + + if (sp->yvel == 1) + { + sp->ang = a+512; + sp->xvel = 30; + } + else + { + sp->ang = a-512; + sp->xvel = 20; + } + sp->xrepeat=sp->yrepeat=4; + + changespritestat(i,5); + } + break; + + case RESPAWN__STATIC: + sp->extra = 66-13; + case MUSICANDSFX__STATIC: + if( ud.multimode < 2 && sp->pal == 1) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + sp->cstat = (short)32768; + changespritestat(i,11); + break; + + case EXPLOSION2__STATIC: + case EXPLOSION2BOT__STATIC: + case BURNING__STATIC: + case BURNING2__STATIC: + case SMALLSMOKE__STATIC: + case SHRINKEREXPLOSION__STATIC: + case COOLEXPLOSION1__STATIC: + + if(j >= 0) + { + sp->ang = sprite[j].ang; + sp->shade = -64; + sp->cstat = 128|(TRAND&4); + } + + if(sp->picnum == EXPLOSION2 || sp->picnum == EXPLOSION2BOT) + { + sp->xrepeat = 48; + sp->yrepeat = 48; + sp->shade = -127; + sp->cstat |= 128; + } + else if(sp->picnum == SHRINKEREXPLOSION ) + { + sp->xrepeat = 32; + sp->yrepeat = 32; + } + else if( sp->picnum == SMALLSMOKE ) + { + // 64 "money" + sp->xrepeat = 24; + sp->yrepeat = 24; + } + else if(sp->picnum == BURNING || sp->picnum == BURNING2) + { + sp->xrepeat = 4; + sp->yrepeat = 4; + } + + if(j >= 0) + { + x = getflorzofslope(sp->sectnum,sp->x,sp->y); + if(sp->z > x-(12<<8) ) + sp->z = x-(12<<8); + } + + changespritestat(i,5); + + break; + + case PLAYERONWATER__STATIC: + if(j >= 0) + { + sp->xrepeat = sprite[j].xrepeat; + sp->yrepeat = sprite[j].yrepeat; + sp->zvel = 128; + if(sector[sp->sectnum].lotag != 2) + sp->cstat |= 32768; + } + changespritestat(i,13); + break; + + case APLAYER__STATIC: + sp->xrepeat = sp->yrepeat = 0; + //j = ud.coop; + //if(j == 2) j = 0; + j=(gametype_flags[ud.coop] & GAMETYPE_FLAG_COOPSPAWN ) / GAMETYPE_FLAG_COOPSPAWN ; + if( ud.multimode < 2 || (ud.multimode > 1 && j != sp->lotag) ) + changespritestat(i,5); + else + changespritestat(i,10); + break; + case WATERBUBBLE__STATIC: + if(j >= 0 && sprite[j].picnum == APLAYER) + sp->z -= (16<<8); + if( sp->picnum == WATERBUBBLE) + { + if( j >= 0 ) + sp->ang = sprite[j].ang; + sp->xrepeat = sp->yrepeat = 4; + } + else sp->xrepeat = sp->yrepeat = 32; + + changespritestat(i,5); + break; + + case CRANE__STATIC: + + sp->cstat |= 64|257; + + sp->picnum += 2; + sp->z = sector[sect].ceilingz+(48<<8); + T5 = tempwallptr; + + msx[tempwallptr] = sp->x; + msy[tempwallptr] = sp->y; + msx[tempwallptr+2] = sp->z; + + s = headspritestat[0]; + while(s >= 0) + { + if( sprite[s].picnum == CRANEPOLE && SHT == (sprite[s].hitag) ) + { + msy[tempwallptr+2] = s; + + T2 = sprite[s].sectnum; + + sprite[s].xrepeat = 48; + sprite[s].yrepeat = 128; + + msx[tempwallptr+1] = sprite[s].x; + msy[tempwallptr+1] = sprite[s].y; + + sprite[s].x = sp->x; + sprite[s].y = sp->y; + sprite[s].z = sp->z; + sprite[s].shade = sp->shade; + + setsprite(s,sprite[s].x,sprite[s].y,sprite[s].z); + break; + } + s = nextspritestat[s]; + } + + tempwallptr += 3; + sp->owner = -1; + sp->extra = 8; + changespritestat(i,6); + break; + + case WATERDRIP__STATIC: + if((j >= 0 && sprite[j].statnum == 10) || sprite[j].statnum == 1) + { + sp->shade = 32; + if(sprite[j].pal != 1) + { + sp->pal = 2; + sp->z -= (18<<8); + } + else sp->z -= (13<<8); + sp->ang = getangle(ps[connecthead].posx-sp->x,ps[connecthead].posy-sp->y); + sp->xvel = 48-(TRAND&31); + ssp(i,CLIPMASK0); + } + else if(j == -1) + { + sp->z += (4<<8); + T1 = sp->z; + T2 = TRAND&127; + } + case TRASH__STATIC: + + if(sp->picnum != WATERDRIP) + sp->ang = TRAND&2047; + + case WATERDRIPSPLASH__STATIC: + + sp->xrepeat = 24; + sp->yrepeat = 24; + + + changespritestat(i,6); + break; + + case PLUG__STATIC: + sp->lotag = 9999; + changespritestat(i,6); + break; + case TOUCHPLATE__STATIC: + T3 = sector[sect].floorz; + if(sector[sect].lotag != 1 && sector[sect].lotag != 2) + sector[sect].floorz = sp->z; + if(sp->pal && ud.multimode > 1) + { + sp->xrepeat=sp->yrepeat=0; + changespritestat(i,5); + break; + } + case WATERBUBBLEMAKER__STATIC: + if (sp->hitag && sp->picnum == WATERBUBBLEMAKER) { // JBF 20030913: Pisses off move(), eg. in bobsp2 + OSD_Printf("WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n", + i,sp->x,sp->y); + sp->hitag = 0; + } + sp->cstat |= 32768; + changespritestat(i,6); + break; + //case BOLT1: + //case BOLT1+1: + //case BOLT1+2: + //case BOLT1+3: + //case SIDEBOLT1: + //case SIDEBOLT1+1: + //case SIDEBOLT1+2: + //case SIDEBOLT1+3: + // T1 = sp->xrepeat; + // T2 = sp->yrepeat; + case MASTERSWITCH__STATIC: + if(sp->picnum == MASTERSWITCH) + sp->cstat |= 32768; + sp->yvel = 0; + changespritestat(i,6); + break; + case TARGET__STATIC: + case DUCK__STATIC: + case LETTER__STATIC: + sp->extra = 1; + sp->cstat |= 257; + changespritestat(i,1); + break; + case OCTABRAINSTAYPUT__STATIC: + case LIZTROOPSTAYPUT__STATIC: + case PIGCOPSTAYPUT__STATIC: + case LIZMANSTAYPUT__STATIC: + case BOSS1STAYPUT__STATIC: + case PIGCOPDIVE__STATIC: + case COMMANDERSTAYPUT__STATIC: + case BOSS4STAYPUT__STATIC: + hittype[i].actorstayput = sp->sectnum; + case BOSS1__STATIC: + case BOSS2__STATIC: + case BOSS3__STATIC: + case BOSS4__STATIC: + case ROTATEGUN__STATIC: + case GREENSLIME__STATIC: + if(sp->picnum == GREENSLIME) + sp->extra = 1; + case DRONE__STATIC: + case LIZTROOPONTOILET__STATIC: + case LIZTROOPJUSTSIT__STATIC: + case LIZTROOPSHOOT__STATIC: + case LIZTROOPJETPACK__STATIC: + case LIZTROOPDUCKING__STATIC: + case LIZTROOPRUNNING__STATIC: + case LIZTROOP__STATIC: + case OCTABRAIN__STATIC: + case COMMANDER__STATIC: + case PIGCOP__STATIC: + case LIZMAN__STATIC: + case LIZMANSPITTING__STATIC: + case LIZMANFEEDING__STATIC: + case LIZMANJUMP__STATIC: + case ORGANTIC__STATIC: + case RAT__STATIC: + case SHARK__STATIC: + + if(sp->pal == 0) + { + switch(dynamictostatic[sp->picnum]) + { + case LIZTROOPONTOILET__STATIC: + case LIZTROOPSHOOT__STATIC: + case LIZTROOPJETPACK__STATIC: + case LIZTROOPDUCKING__STATIC: + case LIZTROOPRUNNING__STATIC: + case LIZTROOPSTAYPUT__STATIC: + case LIZTROOPJUSTSIT__STATIC: + case LIZTROOP__STATIC: + sp->pal = 22; + break; + } + } + + if( sp->picnum == BOSS4STAYPUT || sp->picnum == BOSS1 || sp->picnum == BOSS2 || sp->picnum == BOSS1STAYPUT || sp->picnum == BOSS3 || sp->picnum == BOSS4 ) + { + if(j >= 0 && sprite[j].picnum == RESPAWN) + sp->pal = sprite[j].pal; + if(sp->pal) + { + sp->clipdist = 80; + sp->xrepeat = 40; + sp->yrepeat = 40; + } + else + { + sp->xrepeat = 80; + sp->yrepeat = 80; + sp->clipdist = 164; + } + } + else + { + if(sp->picnum != SHARK) + { + sp->xrepeat = 40; + sp->yrepeat = 40; + sp->clipdist = 80; + } + else + { + sp->xrepeat = 60; + sp->yrepeat = 60; + sp->clipdist = 40; + } + } + + if(j >= 0) sp->lotag = 0; + + if( ( sp->lotag > ud.player_skill ) || ud.monsters_off == 1 ) + { + sp->xrepeat=sp->yrepeat=0; + changespritestat(i,5); + break; + } + else + { + makeitfall(i); + + if(sp->picnum == RAT) + { + sp->ang = TRAND&2047; + sp->xrepeat = sp->yrepeat = 48; + sp->cstat = 0; + } + else + { + sp->cstat |= 257; + + if(sp->picnum != SHARK) + ps[myconnectindex].max_actors_killed++; + } + + if(sp->picnum == ORGANTIC) sp->cstat |= 128; + + if(j >= 0) + { + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i,1); + } + else changespritestat(i,2); + } + + if(sp->picnum == ROTATEGUN) + sp->zvel = 0; + + break; + + case LOCATORS__STATIC: + sp->cstat |= 32768; + changespritestat(i,7); + break; + + case ACTIVATORLOCKED__STATIC: + case ACTIVATOR__STATIC: + sp->cstat = (short) 32768; + if(sp->picnum == ACTIVATORLOCKED) + sector[sp->sectnum].lotag |= 16384; + changespritestat(i,8); + break; + + case DOORSHOCK__STATIC: + sp->cstat |= 1+256; + sp->shade = -12; + changespritestat(i,6); + break; + + case OOZ__STATIC: + case OOZ2__STATIC: + sp->shade = -12; + + if(j >= 0) + { + if( sprite[j].picnum == NUKEBARREL ) + sp->pal = 8; + insertspriteq(i); + } + + changespritestat(i,1); + + getglobalz(i); + + j = (hittype[i].floorz-hittype[i].ceilingz)>>9; + + sp->yrepeat = j; + sp->xrepeat = 25-(j>>1); + sp->cstat |= (TRAND&4); + + break; + + case HEAVYHBOMB__STATIC: + if(j >= 0) + sp->owner = j; + else sp->owner = i; + sp->xrepeat = sp->yrepeat = 9; + sp->yvel = 4; + case REACTOR2__STATIC: + case REACTOR__STATIC: + case RECON__STATIC: + + if(sp->picnum == RECON) + { + if( sp->lotag > ud.player_skill ) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + return i; + } + ps[myconnectindex].max_actors_killed++; + hittype[i].temp_data[5] = 0; + if(ud.monsters_off == 1) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + sp->extra = 130; + } + + if(sp->picnum == REACTOR || sp->picnum == REACTOR2) + sp->extra = impact_damage; + + CS |= 257; // Make it hitable + + if( ud.multimode < 2 && sp->pal != 0) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + sp->pal = 0; + SS = -17; + + changespritestat(i,2); + break; + + case ATOMICHEALTH__STATIC: + case STEROIDS__STATIC: + case HEATSENSOR__STATIC: + case SHIELD__STATIC: + case AIRTANK__STATIC: + case TRIPBOMBSPRITE__STATIC: + case JETPACK__STATIC: + case HOLODUKE__STATIC: + + case FIRSTGUNSPRITE__STATIC: + case CHAINGUNSPRITE__STATIC: + case SHOTGUNSPRITE__STATIC: + case RPGSPRITE__STATIC: + case SHRINKERSPRITE__STATIC: + case FREEZESPRITE__STATIC: + case DEVISTATORSPRITE__STATIC: + + case SHOTGUNAMMO__STATIC: + case FREEZEAMMO__STATIC: + case HBOMBAMMO__STATIC: + case CRYSTALAMMO__STATIC: + case GROWAMMO__STATIC: + case BATTERYAMMO__STATIC: + case DEVISTATORAMMO__STATIC: + case RPGAMMO__STATIC: + case BOOTS__STATIC: + case AMMO__STATIC: + case AMMOLOTS__STATIC: + case COLA__STATIC: + case FIRSTAID__STATIC: + case SIXPAK__STATIC: + + if(j >= 0) + { + sp->lotag = 0; + sp->z -= (32<<8); + sp->zvel = -1024; + ssp(i,CLIPMASK0); + sp->cstat = TRAND&4; + } + else + { + sp->owner = i; + sp->cstat = 0; + } + + if( ( ud.multimode < 2 && sp->pal != 0) || (sp->lotag > ud.player_skill) ) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + + sp->pal = 0; + + case ACCESSCARD__STATIC: + + if(sp->picnum == ATOMICHEALTH) + sp->cstat |= 128; + + if(ud.multimode > 1 && !(gametype_flags[ud.coop]&GAMETYPE_FLAG_ACCESSCARDSPRITES) && sp->picnum == ACCESSCARD) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + else + { + if(sp->picnum == AMMO) + sp->xrepeat = sp->yrepeat = 16; + else sp->xrepeat = sp->yrepeat = 32; + } + + sp->shade = -17; + + if(j >= 0) changespritestat(i,1); + else + { + changespritestat(i,2); + makeitfall(i); + } + break; + + case WATERFOUNTAIN__STATIC: + SLT = 1; + + case TREE1__STATIC: + case TREE2__STATIC: + case TIRE__STATIC: + case CONE__STATIC: + case BOX__STATIC: + CS = 257; // Make it hitable + sprite[i].extra = 1; + changespritestat(i,6); + break; + + case FLOORFLAME__STATIC: + sp->shade = -127; + changespritestat(i,6); + break; + + case BOUNCEMINE__STATIC: + sp->owner = i; + sp->cstat |= 1+256; //Make it hitable + sp->xrepeat = sp->yrepeat = 24; + sp->shade = -127; + sp->extra = impact_damage<<2; + changespritestat(i,2); + break; + + + + case STEAM__STATIC: + if(j >= 0) + { + sp->ang = sprite[j].ang; + sp->cstat = 16+128+2; + sp->xrepeat=sp->yrepeat=1; + sp->xvel = -8; + ssp(i,CLIPMASK0); + } + case CEILINGSTEAM__STATIC: + changespritestat(i,6); + break; + + case SECTOREFFECTOR__STATIC: + sp->yvel = sector[sect].extra; + sp->cstat |= 32768; + sp->xrepeat = sp->yrepeat = 0; + + switch(sp->lotag) + { + case 28: + T6 = 65;// Delay for lightning + break; + case 7: // Transporters!!!! + case 23:// XPTR END + if(sp->lotag != 23) + { + for(j=0;jcstat = 0; + changespritestat(i,9); + return i; + case 1: + sp->owner = -1; + T1 = 1; + break; + case 18: + + if(sp->ang == 512) + { + T2 = sector[sect].ceilingz; + if(sp->pal) + sector[sect].ceilingz = sp->z; + } + else + { + T2 = sector[sect].floorz; + if(sp->pal) + sector[sect].floorz = sp->z; + } + + sp->hitag <<= 2; + break; + + case 19: + sp->owner = -1; + break; + case 25: // Pistons + T4 = sector[sect].ceilingz; + T5 = 1; + sector[sect].ceilingz = sp->z; + setinterpolation(§or[sect].ceilingz); + break; + case 35: + sector[sect].ceilingz = sp->z; + break; + case 27: + if(ud.recstat == 1) + { + sp->xrepeat=sp->yrepeat=64; + sp->cstat &= 32767; + } + break; + case 12: + + T2 = sector[sect].floorshade; + T3 = sector[sect].ceilingshade; + break; + + case 13: + + T1 = sector[sect].ceilingz; + T2 = sector[sect].floorz; + + if( klabs(T1-sp->z) < klabs(T2-sp->z) ) + sp->owner = 1; + else sp->owner = 0; + + if(sp->ang == 512) + { + if(sp->owner) + sector[sect].ceilingz = sp->z; + else + sector[sect].floorz = sp->z; + } + else + sector[sect].ceilingz = sector[sect].floorz = sp->z; + + if( sector[sect].ceilingstat&1 ) + { + sector[sect].ceilingstat ^= 1; + T4 = 1; + + if(!sp->owner && sp->ang==512) + { + sector[sect].ceilingstat ^= 1; + T4 = 0; + } + + sector[sect].ceilingshade = + sector[sect].floorshade; + + if(sp->ang==512) + { + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + for(j=startwall;j= 0) + if( !(sector[x].ceilingstat&1) ) + { + sector[sect].ceilingpicnum = + sector[x].ceilingpicnum; + sector[sect].ceilingshade = + sector[x].ceilingshade; + break; //Leave earily + } + } + } + } + + break; + + case 17: + + T3 = sector[sect].floorz; //Stopping loc + + j = nextsectorneighborz(sect,sector[sect].floorz,-1,-1); + T4 = sector[j].ceilingz; + + j = nextsectorneighborz(sect,sector[sect].ceilingz,1,1); + T5 = sector[j].floorz; + + if(numplayers < 2) + { + setinterpolation(§or[sect].floorz); + setinterpolation(§or[sect].ceilingz); + } + + break; + + case 24: + sp->yvel <<= 1; + case 36: + break; + + case 20: + { + long q; + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + //find the two most clostest wall x's and y's + q = 0x7fffffff; + + for(s=startwall;sx-x,sp->y-y); + if( d < q ) + { + q = d; + clostest = s; + } + } + + T2 = clostest; + + q = 0x7fffffff; + + for(s=startwall;sx-x,sp->y-y); + if(d < q && s != T2) + { + q = d; + clostest = s; + } + } + + T3 = clostest; + } + + break; + + case 3: + + T4=sector[sect].floorshade; + + sector[sect].floorshade = sp->shade; + sector[sect].ceilingshade = sp->shade; + + sp->owner = sector[sect].ceilingpal<<8; + sp->owner |= sector[sect].floorpal; + + //fix all the walls; + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + for(s=startwall;sshade; + if( (wall[s].cstat&2) && wall[s].nextwall >= 0) + wall[wall[s].nextwall].shade = sp->shade; + } + break; + + case 31: + T2 = sector[sect].floorz; + // T3 = sp->hitag; + if(sp->ang != 1536) sector[sect].floorz = sp->z; + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + for(s=startwall;shitag; + if(sp->ang != 1536) sector[sect].ceilingz = sp->z; + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + for(s=startwall;sowner = sector[sect].ceilingpal<<8; + sp->owner |= sector[sect].floorpal; + + for(s=startwall;s T4) + T4 = wall[s].shade; + + break; + + case 9: + if( sector[sect].lotag && + labs(sector[sect].ceilingz-sp->z) > 1024) + sector[sect].lotag |= 32768; //If its open + case 8: + //First, get the ceiling-floor shade + + T1 = sector[sect].floorshade; + T2 = sector[sect].ceilingshade; + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + for(s=startwall;s T3) + T3 = wall[s].shade; + + T4 = 1; //Take Out; + + break; + + case 11://Pivitor rotater + if(sp->ang>1024) T4 = 2; + else T4 = -2; + case 0: + case 2://Earthquakemakers + case 5://Boss Creature + case 6://Subway + case 14://Caboos + case 15://Subwaytype sliding door + case 16://That rotating blocker reactor thing + case 26://ESCELATOR + case 30://No rotational subways + + if(sp->lotag == 0) + { + if( sector[sect].lotag == 30 ) + { + if(sp->pal) sprite[i].clipdist = 1; + else sprite[i].clipdist = 0; + T4 = sector[sect].floorz; + sector[sect].hitag = i; + } + + for(j = 0;j < MAXSPRITES;j++) + { + if( sprite[j].statnum < MAXSTATUS ) + if( sprite[j].picnum == SECTOREFFECTOR && + sprite[j].lotag == 1 && + sprite[j].hitag == sp->hitag) + { + if( sp->ang == 512 ) + { + sp->x = sprite[j].x; + sp->y = sprite[j].y; + } + break; + } + } + if(j == MAXSPRITES) + { + Bsprintf(tempbuf,"Found lonely Sector Effector (lotag 0) at (%ld,%ld)\n",sp->x,sp->y); + gameexit(tempbuf); + } + sp->owner = j; + } + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + T2 = tempwallptr; + for(s=startwall;sx; + msy[tempwallptr] = wall[s].y-sp->y; + tempwallptr++; + if(tempwallptr > 2047) + { + Bsprintf(tempbuf,"Too many moving sectors at (%ld,%ld).\n",wall[s].x,wall[s].y); + gameexit(tempbuf); + } + } + if( sp->lotag == 30 || sp->lotag == 6 || sp->lotag == 14 || sp->lotag == 5 ) + { + + startwall = sector[sect].wallptr; + endwall = startwall+sector[sect].wallnum; + + if(sector[sect].hitag == -1) + sp->extra = 0; + else sp->extra = 1; + + sector[sect].hitag = i; + + j = 0; + + for(s=startwall;s= 0 && + sector[ wall[ s ].nextsector].hitag == 0 && + sector[ wall[ s ].nextsector].lotag < 3 ) + { + s = wall[s].nextsector; + j = 1; + break; + } + } + + if(j == 0) + { + Bsprintf(tempbuf,"Subway found no zero'd sectors with locators\nat (%ld,%ld).\n",sp->x,sp->y); + gameexit(tempbuf); + } + + sp->owner = -1; + T1 = s; + + if(sp->lotag != 30) + T4 = sp->hitag; + } + + else if(sp->lotag == 16) + T4 = sector[sect].ceilingz; + + else if( sp->lotag == 26 ) + { + T4 = sp->x; + T5 = sp->y; + if(sp->shade==sector[sect].floorshade) //UP + sp->zvel = -256; + else + sp->zvel = 256; + + sp->shade = 0; + } + else if( sp->lotag == 2) + { + T6 = sector[sp->sectnum].floorheinum; + sector[sp->sectnum].floorheinum = 0; + } + } + + switch(sp->lotag) + { + case 6: + case 14: + j = callsound(sect,i); + if(j == -1) j = SUBWAY; + hittype[i].lastvx = j; + case 30: + if(numplayers > 1) break; + case 0: + case 1: + case 5: + case 11: + case 15: + case 16: + case 26: + setsectinterpolate(i); + break; + } + + switch(sprite[i].lotag) + { + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + changespritestat(i,15); + break; + default: + changespritestat(i,3); + break; + } + + break; + + + case SEENINE__STATIC: + case OOZFILTER__STATIC: + + sp->shade = -16; + if(sp->xrepeat <= 8) + { + sp->cstat = (short)32768; + sp->xrepeat=sp->yrepeat=0; + } + else sp->cstat = 1+256; + sp->extra = impact_damage<<2; + sp->owner = i; + + changespritestat(i,6); + break; + + case CRACK1__STATIC: + case CRACK2__STATIC: + case CRACK3__STATIC: + case CRACK4__STATIC: + case FIREEXT__STATIC: + if(sp->picnum == FIREEXT) + { + sp->cstat = 257; + sp->extra = impact_damage<<2; + } + else + { + sp->cstat |= (sp->cstat & 48) ? 1 : 17; + sp->extra = 1; + } + + if( ud.multimode < 2 && sp->pal != 0) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + break; + } + + sp->pal = 0; + sp->owner = i; + changespritestat(i,6); + sp->xvel = 8; + ssp(i,CLIPMASK0); + break; + + case TOILET__STATIC: + case STALL__STATIC: + sp->lotag = 1; + sp->cstat |= 257; + sp->clipdist = 8; + sp->owner = i; + break; + case CANWITHSOMETHING__STATIC: + case CANWITHSOMETHING2__STATIC: + case CANWITHSOMETHING3__STATIC: + case CANWITHSOMETHING4__STATIC: + case RUBBERCAN__STATIC: + sp->extra = 0; + case EXPLODINGBARREL__STATIC: + case HORSEONSIDE__STATIC: + case FIREBARREL__STATIC: + case NUKEBARREL__STATIC: + case FIREVASE__STATIC: + case NUKEBARRELDENTED__STATIC: + case NUKEBARRELLEAKED__STATIC: + case WOODENHORSE__STATIC: + + if(j >= 0) + sp->xrepeat = sp->yrepeat = 32; + sp->clipdist = 72; + makeitfall(i); + if(j >= 0) + sp->owner = j; + else sp->owner = i; + case EGG__STATIC: + if( ud.monsters_off == 1 && sp->picnum == EGG ) + { + sp->xrepeat = sp->yrepeat = 0; + changespritestat(i,5); + } + else + { + if(sp->picnum == EGG) + sp->clipdist = 24; + sp->cstat = 257|(TRAND&4); + changespritestat(i,2); + } + break; + case TOILETWATER__STATIC: + sp->shade = -16; + changespritestat(i,6); + break; + } + + OnEvent(EVENT_SPAWN,i, findplayer(&sprite[i],&p), p); + return i; +} + +#ifdef _MSC_VER +// Visual C thought this was a bit too hard to optimise so we'd better +// tell it not to try... such a pussy it is. +//#pragma auto_inline( off ) +#pragma optimize("g",off) +#endif +void animatesprites(long x,long y,short a,long smoothratio) +{ + short i, j, k, p, sect; + long l, t1,t3,t4; + spritetype *s,*t; + int switchpic; + + for(j=0;j < spritesortcnt; j++) + { + t = &tsprite[j]; + i = t->owner; + s = &sprite[t->owner]; + //greenslime can't be handled through the dynamictostatic system due to addition on constant + if ((t->picnum >= GREENSLIME)&&(t->picnum <= GREENSLIME+7)) { + } else switch(dynamictostatic[t->picnum]) + { + case BLOODPOOL__STATIC: + case PUKE__STATIC: + case FOOTPRINTS__STATIC: + case FOOTPRINTS2__STATIC: + case FOOTPRINTS3__STATIC: + case FOOTPRINTS4__STATIC: + if(t->shade == 127) continue; + break; + case RESPAWNMARKERRED__STATIC: + case RESPAWNMARKERYELLOW__STATIC: + case RESPAWNMARKERGREEN__STATIC: + if(ud.marker == 0) + t->xrepeat = t->yrepeat = 0; + continue; + case CHAIR3__STATIC: + if (bpp > 8 && usemodels && md_tilehasmodel(t->picnum) >= 0) { + t->cstat &= ~4; + break; + } + + k = (((t->ang+3072+128-a)&2047)>>8)&7; + if(k>4) + { + k = 8-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + t->picnum = s->picnum+k; + break; + case BLOODSPLAT1__STATIC: + case BLOODSPLAT2__STATIC: + case BLOODSPLAT3__STATIC: + case BLOODSPLAT4__STATIC: + if(ud.lockout) t->xrepeat = t->yrepeat = 0; + else if(t->pal == 6) + { + t->shade = -127; + continue; + } + case BULLETHOLE__STATIC: + case CRACK1__STATIC: + case CRACK2__STATIC: + case CRACK3__STATIC: + case CRACK4__STATIC: + t->shade = 16; + continue; + case NEON1__STATIC: + case NEON2__STATIC: + case NEON3__STATIC: + case NEON4__STATIC: + case NEON5__STATIC: + case NEON6__STATIC: + continue; + //case GREENSLIME: + //case GREENSLIME+1: + //case GREENSLIME+2: + //case GREENSLIME+3: + //case GREENSLIME+4: + //case GREENSLIME+5: + //case GREENSLIME+6: + //case GREENSLIME+7: + // break; + default: + if( ( (t->cstat&16) ) || ( badguy(t) && t->extra > 0) || t->statnum == 10) + continue; + } + + if (checkspriteflags(i,SPRITE_FLAG_NOSHADE)) + l = sprite[j].shade; + else + { + if (sector[t->sectnum].ceilingstat&1) + l = sector[t->sectnum].ceilingshade; + else + l = sector[t->sectnum].floorshade; + if(l < -127) l = -127; + if(l > 128) l = 127; + } + t->shade = l; + } + + + for(j=0;j < spritesortcnt; j++ ) //Between drawrooms() and drawmasks() + { //is the perfect time to animate sprites + t = &tsprite[j]; + i = t->owner; + s = &sprite[i]; + + switch(dynamictostatic[s->picnum]) + { + case SECTOREFFECTOR__STATIC: + if(t->lotag == 27 && ud.recstat == 1) + { + t->picnum = 11+((totalclock>>3)&1); + t->cstat |= 128; + } + else + t->xrepeat = t->yrepeat = 0; + break; + case NATURALLIGHTNING__STATIC: + t->shade = -127; + break; + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case MAN__STATIC: + case MAN2__STATIC: + case WOMAN__STATIC: + case NAKED1__STATIC: + case PODFEM1__STATIC: + case FEMMAG1__STATIC: + case FEMMAG2__STATIC: + case FEMPIC1__STATIC: + case FEMPIC2__STATIC: + case FEMPIC3__STATIC: + case FEMPIC4__STATIC: + case FEMPIC5__STATIC: + case FEMPIC6__STATIC: + case FEMPIC7__STATIC: + case BLOODYPOLE__STATIC: + case FEM6PAD__STATIC: + case STATUE__STATIC: + case STATUEFLASH__STATIC: + case OOZ__STATIC: + case OOZ2__STATIC: + case WALLBLOOD1__STATIC: + case WALLBLOOD2__STATIC: + case WALLBLOOD3__STATIC: + case WALLBLOOD4__STATIC: + case WALLBLOOD5__STATIC: + case WALLBLOOD7__STATIC: + case WALLBLOOD8__STATIC: + case SUSHIPLATE1__STATIC: + case SUSHIPLATE2__STATIC: + case SUSHIPLATE3__STATIC: + case SUSHIPLATE4__STATIC: + case FETUS__STATIC: + case FETUSJIB__STATIC: + case FETUSBROKE__STATIC: + case HOTMEAT__STATIC: + case FOODOBJECT16__STATIC: + case DOLPHIN1__STATIC: + case DOLPHIN2__STATIC: + case TOUGHGAL__STATIC: + case TAMPON__STATIC: + case XXXSTACY__STATIC: + if(ud.lockout) + { + t->xrepeat = t->yrepeat = 0; + continue; + } + } + switch(s->picnum) + { + + case 4946: + case 4947: + case 693: + case 2254: + case 4560: + case 4561: + case 4562: + case 4498: + case 4957: + if(ud.lockout) + { + t->xrepeat = t->yrepeat = 0; + continue; + } + } + + if( t->statnum == 99 ) continue; + if( s->statnum != 1 && s->picnum == APLAYER && ps[s->yvel].newowner == -1 && s->owner >= 0 ) + { + t->x -= mulscale16(65536-smoothratio,ps[s->yvel].posx-ps[s->yvel].oposx); + t->y -= mulscale16(65536-smoothratio,ps[s->yvel].posy-ps[s->yvel].oposy); + t->z = ps[s->yvel].oposz + mulscale16(smoothratio,ps[s->yvel].posz-ps[s->yvel].oposz); + t->z += (40<<8); + } + else if( ( s->statnum == 0 && s->picnum != CRANEPOLE) || s->statnum == 10 || s->statnum == 6 || s->statnum == 4 || s->statnum == 5 || s->statnum == 1 ) + { + t->x -= mulscale16(65536-smoothratio,s->x-hittype[i].bposx); + t->y -= mulscale16(65536-smoothratio,s->y-hittype[i].bposy); + t->z -= mulscale16(65536-smoothratio,s->z-hittype[i].bposz); + } + + sect = s->sectnum; + t1 = T2;t3 = T4;t4 = T5; + switchpic = s->picnum; + //some special cases because dynamictostatic system can't handle addition to constants + if ((s->picnum >= SCRAP6)&&(s->picnum<=SCRAP6+7)) + switchpic = SCRAP5; + else if ((s->picnum==MONEY+1)||(s->picnum==MAIL+1)||(s->picnum==PAPER+1)) + switchpic--; + + switch(dynamictostatic[switchpic]) + { + case DUKELYINGDEAD__STATIC: + t->z += (24<<8); + break; + case BLOODPOOL__STATIC: + case FOOTPRINTS__STATIC: + case FOOTPRINTS2__STATIC: + case FOOTPRINTS3__STATIC: + case FOOTPRINTS4__STATIC: + if(t->pal == 6) + t->shade = -127; + case PUKE__STATIC: + case MONEY__STATIC: + //case MONEY+1__STATIC: + case MAIL__STATIC: + //case MAIL+1__STATIC: + case PAPER__STATIC: + //case PAPER+1__STATIC: + if(ud.lockout && s->pal == 2) + { + t->xrepeat = t->yrepeat = 0; + continue; + } + break; + case TRIPBOMB__STATIC: + continue; + case FORCESPHERE__STATIC: + if(t->statnum == 5) + { + short sqa,sqb; + + sqa = + getangle( + sprite[s->owner].x-ps[screenpeek].posx, + sprite[s->owner].y-ps[screenpeek].posy); + sqb = + getangle( + sprite[s->owner].x-t->x, + sprite[s->owner].y-t->y); + + if( klabs(getincangle(sqa,sqb)) > 512 ) + if( ldist(&sprite[s->owner],t) < ldist(&sprite[ps[screenpeek].i],&sprite[s->owner]) ) + t->xrepeat = t->yrepeat = 0; + } + continue; + case BURNING__STATIC: + case BURNING2__STATIC: + if( sprite[s->owner].statnum == 10 ) + { + if( display_mirror == 0 && sprite[s->owner].yvel == screenpeek && ps[sprite[s->owner].yvel].over_shoulder_on == 0 ) + t->xrepeat = 0; + else + { + t->ang = getangle(x-t->x,y-t->y); + t->x = sprite[s->owner].x; + t->y = sprite[s->owner].y; + t->x += sintable[(t->ang+512)&2047]>>10; + t->y += sintable[t->ang&2047]>>10; + } + } + break; + + case ATOMICHEALTH__STATIC: + t->z -= (4<<8); + break; + case CRYSTALAMMO__STATIC: + t->shade = (sintable[(totalclock<<4)&2047]>>10); + continue; + case VIEWSCREEN__STATIC: + case VIEWSCREEN2__STATIC: + if(camsprite >= 0 && hittype[OW].temp_data[0] == 1) + { + t->picnum = STATIC; + t->cstat |= (rand()&12); + t->xrepeat += 8; + t->yrepeat += 8; + } else if (camsprite >= 0 && waloff[TILE_VIEWSCR] && walock[TILE_VIEWSCR] > 200) { + t->picnum = TILE_VIEWSCR; + } + break; + + case SHRINKSPARK__STATIC: + t->picnum = SHRINKSPARK+( (totalclock>>4)&3 ); + break; + case GROWSPARK__STATIC: + t->picnum = GROWSPARK+( (totalclock>>4)&3 ); + break; + case RPG__STATIC: + if (bpp > 8 && usemodels && md_tilehasmodel(t->picnum) >= 0) { + t->cstat &= ~4; + break; + } + + k = getangle(s->x-x,s->y-y); + k = (((s->ang+3072+128-k)&2047)/170); + if(k > 6) + { + k = 12-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + t->picnum = RPG+k; + break; + + case RECON__STATIC: + if (bpp > 8 && usemodels && md_tilehasmodel(t->picnum) >= 0) { + t->cstat &= ~4; + break; + } + + k = getangle(s->x-x,s->y-y); + if( T1 < 4 ) + k = (((s->ang+3072+128-k)&2047)/170); + else k = (((s->ang+3072+128-k)&2047)/170); + + if(k>6) + { + k = 12-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + + if( klabs(t3) > 64 ) k += 7; + t->picnum = RECON+k; + + break; + + case APLAYER__STATIC: + + p = s->yvel; + + if(t->pal == 1) t->z -= (18<<8); + + if(ps[p].over_shoulder_on > 0 && ps[p].newowner < 0 ) + { + t->cstat |= 2; + if ( screenpeek == myconnectindex && numplayers >= 2 ) + { + t->x = omyx+mulscale16((long)(myx-omyx),smoothratio); + t->y = omyy+mulscale16((long)(myy-omyy),smoothratio); + t->z = omyz+mulscale16((long)(myz-omyz),smoothratio)+(40<<8); + t->ang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); + t->sectnum = mycursectnum; + } + } + + if( ( display_mirror == 1 || screenpeek != p || s->owner == -1 ) && ud.multimode > 1 && ud.showweapons && sprite[ps[p].i].extra > 0 && ps[p].curr_weapon > 0 ) + { + memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype)); + + tsprite[spritesortcnt].statnum = 99; + + tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 ); + if(t->yrepeat < 4) t->yrepeat = 4; + + tsprite[spritesortcnt].shade = t->shade; + tsprite[spritesortcnt].cstat = 0; + + switch(ps[p].curr_weapon) + { + case PISTOL_WEAPON: tsprite[spritesortcnt].picnum = FIRSTGUNSPRITE; break; + case SHOTGUN_WEAPON: tsprite[spritesortcnt].picnum = SHOTGUNSPRITE; break; + case CHAINGUN_WEAPON: tsprite[spritesortcnt].picnum = CHAINGUNSPRITE; break; + case RPG_WEAPON: tsprite[spritesortcnt].picnum = RPGSPRITE; break; + case HANDREMOTE_WEAPON: + case HANDBOMB_WEAPON: tsprite[spritesortcnt].picnum = HEAVYHBOMB; break; + case TRIPBOMB_WEAPON: tsprite[spritesortcnt].picnum = TRIPBOMBSPRITE; break; + case GROW_WEAPON: tsprite[spritesortcnt].picnum = GROWSPRITEICON; break; + case SHRINKER_WEAPON: tsprite[spritesortcnt].picnum = SHRINKERSPRITE; break; + case FREEZE_WEAPON: tsprite[spritesortcnt].picnum = FREEZESPRITE; break; + case DEVISTATOR_WEAPON: tsprite[spritesortcnt].picnum = DEVISTATORSPRITE; break; + } + + if(s->owner >= 0) + tsprite[spritesortcnt].z = ps[p].posz-(12<<8); + else tsprite[spritesortcnt].z = s->z-(51<<8); + if(ps[p].curr_weapon == HANDBOMB_WEAPON) + { + tsprite[spritesortcnt].xrepeat = 10; + tsprite[spritesortcnt].yrepeat = 10; + } + else + { + tsprite[spritesortcnt].xrepeat = 16; + tsprite[spritesortcnt].yrepeat = 16; + } + tsprite[spritesortcnt].pal = 0; + spritesortcnt++; + } + + if(s->owner == -1) + { + if (bpp > 8 && usemodels && md_tilehasmodel(s->picnum) >= 0) { + k = 0; + t->cstat &= ~4; + } else { + k = (((s->ang+3072+128-a)&2047)>>8)&7; + if(k>4) + { + k = 8-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + } + + if(sector[t->sectnum].lotag == 2) k += 1795-1405; + else if( (hittype[i].floorz-s->z) > (64<<8) ) k += 60; + + t->picnum += k; + t->pal = ps[p].palookup; + + goto PALONLY; + } + + if( ps[p].on_crane == -1 && (sector[s->sectnum].lotag&0x7ff) != 1 ) + { + l = s->z-hittype[ps[p].i].floorz+(3<<8); + if( l > 1024 && s->yrepeat > 32 && s->extra > 0 ) + s->yoffset = (signed char)(l/(s->yrepeat<<2)); + else s->yoffset=0; + } + + if(ps[p].newowner > -1) + { + t4 = *(actorscrptr[APLAYER]+1); + t3 = 0; + t1 = *(actorscrptr[APLAYER]+2); + } + + if(ud.camerasprite == -1 && ps[p].newowner == -1) + if(s->owner >= 0 && display_mirror == 0 && ps[p].over_shoulder_on == 0 ) + if( ud.multimode < 2 || ( ud.multimode > 1 && p == screenpeek ) ) + { + t->owner = -1; + t->xrepeat = t->yrepeat = 0; + continue; + } + +PALONLY: + + if( sector[sect].floorpal && sector[sect].floorpal < numl) + t->pal = sector[sect].floorpal; + + if(s->owner == -1) continue; + + if( t->z > hittype[i].floorz && t->xrepeat < 32 ) + t->z = hittype[i].floorz; + + break; + + case JIBS1__STATIC: + case JIBS2__STATIC: + case JIBS3__STATIC: + case JIBS4__STATIC: + case JIBS5__STATIC: + case JIBS6__STATIC: + case HEADJIB1__STATIC: + case LEGJIB1__STATIC: + case ARMJIB1__STATIC: + case LIZMANHEAD1__STATIC: + case LIZMANARM1__STATIC: + case LIZMANLEG1__STATIC: + case DUKELEG__STATIC: + case DUKEGUN__STATIC: + case DUKETORSO__STATIC: + if(ud.lockout) + { + t->xrepeat = t->yrepeat = 0; + continue; + } + if(t->pal == 6) t->shade = -120; + case SCRAP1__STATIC: + case SCRAP2__STATIC: + case SCRAP3__STATIC: + case SCRAP4__STATIC: + case SCRAP5__STATIC: + + + + if(hittype[i].picnum == BLIMP && t->picnum == SCRAP1 && s->yvel >= 0) + t->picnum = s->yvel; + else t->picnum += T1; + t->shade -= 6; + + if( sector[sect].floorpal && sector[sect].floorpal < numl ) + t->pal = sector[sect].floorpal; + break; + + case WATERBUBBLE__STATIC: + if(sector[t->sectnum].floorpicnum == FLOORSLIME) + { + t->pal = 7; + break; + } + default: + + if( sector[sect].floorpal && sector[sect].floorpal < numl ) + t->pal = sector[sect].floorpal; + break; + } + + if( actorscrptr[s->picnum] ) + { + if(t4) + { + l = *(long *)(t4+8); + + if (bpp > 8 && usemodels && md_tilehasmodel(s->picnum) >= 0) { + k = 0; + t->cstat &= ~4; + } + else switch( l ) + { + case 2: + k = (((s->ang+3072+128-a)&2047)>>8)&1; + break; + + case 3: + case 4: + k = (((s->ang+3072+128-a)&2047)>>7)&7; + if(k > 3) + { + t->cstat |= 4; + k = 7-k; + } + else t->cstat &= ~4; + break; + + case 5: + k = getangle(s->x-x,s->y-y); + k = (((s->ang+3072+128-k)&2047)>>8)&7; + if(k>4) + { + k = 8-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + break; + case 7: + k = getangle(s->x-x,s->y-y); + k = (((s->ang+3072+128-k)&2047)/170); + if(k>6) + { + k = 12-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + break; + case 8: + k = (((s->ang+3072+128-a)&2047)>>8)&7; + t->cstat &= ~4; + break; + default: + k = 0; + break; + } + + t->picnum += k + ( *(long *)t4 ) + l * t3; + + if(l > 0) while(tilesizx[t->picnum] == 0 && t->picnum > 0 ) + t->picnum -= l; //Hack, for actors + + if( hittype[i].dispicnum >= 0) + hittype[i].dispicnum = t->picnum; + } + else if(display_mirror == 1) + t->cstat |= 4; + } + + if( s->statnum == 13 || badguy(s) || checkspriteflags(i,SPRITE_FLAG_SHADOW) || (s->picnum == APLAYER && s->owner >= 0) ) + if(t->statnum != 99 && s->picnum != EXPLOSION2 && s->picnum != HANGLIGHT && s->picnum != DOMELITE) + if(s->picnum != HOTMEAT) + { + if( hittype[i].dispicnum < 0 ) + { + hittype[i].dispicnum++; + continue; + } + else if( ud.shadows && spritesortcnt < (MAXSPRITESONSCREEN-2)) + { + long daz,xrep,yrep; + + if( (sector[sect].lotag&0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE || s->picnum == COMMANDER ) + daz = sector[sect].floorz; + else + daz = hittype[i].floorz; + + if( (s->z-daz) < (8<<8) ) + if( ps[screenpeek].posz < daz ) + { + memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype)); + + tsprite[spritesortcnt].statnum = 99; + + tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 ); + if(t->yrepeat < 4) t->yrepeat = 4; + + tsprite[spritesortcnt].shade = 127; + tsprite[spritesortcnt].cstat |= 2; + + tsprite[spritesortcnt].z = daz; + xrep = tsprite[spritesortcnt].xrepeat;// - (klabs(daz-t->z)>>11); + tsprite[spritesortcnt].xrepeat = xrep; + tsprite[spritesortcnt].pal = 4; + + yrep = tsprite[spritesortcnt].yrepeat;// - (klabs(daz-t->z)>>11); + tsprite[spritesortcnt].yrepeat = yrep; + + if (bpp > 8 && usemodels && md_tilehasmodel(t->picnum) >= 0) + { + tsprite[spritesortcnt].yrepeat = 0; + // 512:trans reverse + //1024:tell MD2SPRITE.C to use Z-buffer hacks to hide overdraw issues + tsprite[spritesortcnt].cstat |= (512+1024); + } + + spritesortcnt++; + } + } + + if( ps[screenpeek].heat_amount > 0 && ps[screenpeek].heat_on && (badguy(s) || checkspriteflags(i,SPRITE_FLAG_NVG) || s->picnum == APLAYER || s->statnum == 13)) + { + t->pal = 6; + t->shade = 0; + } + } + + switch(dynamictostatic[s->picnum]) + { + case LASERLINE__STATIC: + if(sector[t->sectnum].lotag == 2) t->pal = 8; + t->z = sprite[s->owner].z-(3<<8); + if(lasermode == 2 && ps[screenpeek].heat_on == 0 ) + t->yrepeat = 0; + case EXPLOSION2__STATIC: + case EXPLOSION2BOT__STATIC: + case FREEZEBLAST__STATIC: + case ATOMICHEALTH__STATIC: + case FIRELASER__STATIC: + case SHRINKSPARK__STATIC: + case GROWSPARK__STATIC: + case CHAINGUN__STATIC: + case SHRINKEREXPLOSION__STATIC: + case RPG__STATIC: + case FLOORFLAME__STATIC: + if(t->picnum == EXPLOSION2) + { + ps[screenpeek].visibility = -127; + lastvisinc = totalclock+32; + //restorepalette = 1; // JBF 20040101: why? + } + t->shade = -127; + break; + case FIRE__STATIC: + case FIRE2__STATIC: + case BURNING__STATIC: + case BURNING2__STATIC: + if( sprite[s->owner].picnum != TREE1 && sprite[s->owner].picnum != TREE2 ) + t->z = sector[t->sectnum].floorz; + t->shade = -127; + break; + case COOLEXPLOSION1__STATIC: + t->shade = -127; + t->picnum += (s->shade>>1); + break; + case PLAYERONWATER__STATIC: + if (bpp > 8 && usemodels && md_tilehasmodel(s->picnum) >= 0) { + k = 0; + t->cstat &= ~4; + } else { + k = (((t->ang+3072+128-a)&2047)>>8)&7; + if(k>4) + { + k = 8-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + } + + t->picnum = s->picnum+k+((T1<4)*5); + t->shade = sprite[s->owner].shade; + + break; + + case WATERSPLASH2__STATIC: + t->picnum = WATERSPLASH2+t1; + break; + case REACTOR2__STATIC: + t->picnum = s->picnum + T3; + break; + case SHELL__STATIC: + t->picnum = s->picnum+(T1&1); + case SHOTGUNSHELL__STATIC: + t->cstat |= 12; + if(T1 > 1) t->cstat &= ~4; + if(T1 > 2) t->cstat &= ~12; + break; + case FRAMEEFFECT1_13__STATIC: + if (PLUTOPAK) break; + case FRAMEEFFECT1__STATIC: + if(s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) + { + if(sprite[s->owner].picnum == APLAYER) + if(ud.camerasprite == -1) + if(screenpeek == sprite[s->owner].yvel && display_mirror == 0) + { + t->owner = -1; + break; + } + if( (sprite[s->owner].cstat&32768) == 0 ) + { + t->picnum = hittype[s->owner].dispicnum; + t->pal = sprite[s->owner].pal; + t->shade = sprite[s->owner].shade; + t->ang = sprite[s->owner].ang; + t->cstat = 2|sprite[s->owner].cstat; + } + } + break; + + case CAMERA1__STATIC: + case RAT__STATIC: + + if (bpp > 8 && usemodels && md_tilehasmodel(s->picnum) >= 0) { + t->cstat &= ~4; + break; + } + + k = (((t->ang+3072+128-a)&2047)>>8)&7; + if(k>4) + { + k = 8-k; + t->cstat |= 4; + } + else t->cstat &= ~4; + t->picnum = s->picnum+k; + break; + } + + hittype[i].dispicnum = t->picnum; + if(sector[t->sectnum].floorpicnum == MIRROR) + t->xrepeat = t->yrepeat = 0; + } +} +#ifdef _MSC_VER +//#pragma auto_inline( ) +#pragma optimize("",on) +#endif + +static char terminx[64] = { "Undead TC still sucks." }; + +// #define NUMCHEATCODES 26 +// #define NUMCHEATCODES (signed int)(sizeof(cheatquotes)/sizeof(cheatquotes[14])) +#define NUMCHEATCODES (signed int)(sizeof(cheatquotes)/sizeof(cheatquotes[MAXCHEATLEN])) +char cheatquotes[][MAXCHEATLEN] = { + "cornholio", // 0 + "stuff", // 1 + "scotty###", // 2 + "coords", // 3 + "view", // 4 + "time", // 5 + "unlock", // 6 + "cashman", // 7 + "items", // 8 + "rate", // 9 + "skill#", // 10 + "beta", // 11 + "hyper", // 12 + "monsters", // 13 + "", // 14 + "", // 15 + "todd", // 16 + "showmap", // 17 + "kroz", // 18 + "allen", // 19 + "clip", // 20 + "weapons", // 21 + "inventory", // 22 + "keys", // 23 + "debug", // 24 + "", // 25 + "txisgod", // 26 + }; + +enum cheats { + CHEAT_CORNHOLIO, + CHEAT_STUFF, + CHEAT_SCOTTY, + CHEAT_COORDS, + CHEAT_VIEW, + CHEAT_TIME, + CHEAT_UNLOCK, + CHEAT_CASHMAN, + CHEAT_ITEMS, + CHEAT_RATE, + CHEAT_SKILL, + CHEAT_BETA, + CHEAT_HYPER, + CHEAT_MONSTERS, + CHEAT_RESERVED, + CHEAT_RESERVED2, + CHEAT_TODD, + CHEAT_SHOWMAP, + CHEAT_KROZ, + CHEAT_ALLEN, + CHEAT_CLIP, + CHEAT_WEAPONS, + CHEAT_INVENTORY, + CHEAT_KEYS, + CHEAT_DEBUG, + CHEAT_RESERVED3, + CHEAT_TXISGOD, +}; + +void CheatGetInventory(void) +{ + SetGameVarID(g_iReturnVarID, 400, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETSTEROIDS, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].steroids_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 1200, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETHEAT, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].heat_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 200, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETBOOT, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].boot_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 100, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETSHIELD, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].shield_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 6400, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETSCUBA, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].scuba_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 2400, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETHOLODUKE, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].holoduke_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, 1600, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETJETPACK, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].jetpack_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } + + SetGameVarID(g_iReturnVarID, max_player_health, ps[myconnectindex].i, myconnectindex); + OnEvent(EVENT_CHEATGETFIRSTAID, ps[myconnectindex].i, myconnectindex, -1); + if( GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex) >=0) + { + ps[myconnectindex].firstaid_amount = + GetGameVarID(g_iReturnVarID, ps[myconnectindex].i, myconnectindex); + } +} + +char cheatbuf[MAXCHEATLEN],cheatbuflen; + +void cheats(void) +{ + short ch, i, j, k=0,x,y, keystate, weapon; + static char z=0; + char consolecheat = 0; // JBF 20030914 + + if (osdcmd_cheatsinfo_stat.cheatnum != -1) { // JBF 20030914 + k = osdcmd_cheatsinfo_stat.cheatnum; + osdcmd_cheatsinfo_stat.cheatnum = -1; + consolecheat = 1; + } + + if( (ps[myconnectindex].gm&MODE_TYPE) || (ps[myconnectindex].gm&MODE_MENU)) + return; + + if (VOLUMEONE && !z) { + strcpy(cheatquotes[2],"scotty##"); + strcpy(cheatquotes[6],""); + z=1; + } + + if (consolecheat && numplayers < 2 && ud.recstat == 0) + goto FOUNDCHEAT; + + if ( ps[myconnectindex].cheat_phase == 1) + { + while (KB_KeyWaiting()) + { + ch = Btolower(KB_Getch()); + + if( !( (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ) ) + { + ps[myconnectindex].cheat_phase = 0; + // FTA(46,&ps[myconnectindex]); + return; + } + + cheatbuf[cheatbuflen++] = ch; + cheatbuf[cheatbuflen] = 0; + KB_ClearKeysDown(); + + if(cheatbuflen > MAXCHEATLEN) + { + ps[myconnectindex].cheat_phase = 0; + return; + } + + for(k=0;k < NUMCHEATCODES;k++) + { + for(j = 0;j= '0' && ch <= '9') ) + { + if( cheatquotes[k][j+1] == 0 ) goto FOUNDCHEAT; + if(j == cheatbuflen-1) return; + } + else break; + } + } + + ps[myconnectindex].cheat_phase = 0; + return; + +FOUNDCHEAT: + { + switch(k) + { + case CHEAT_WEAPONS: + if (VOLUMEONE) { + j = 6; + } else { + j = 0; + } + + for ( weapon = PISTOL_WEAPON;weapon < MAX_WEAPONS-j;weapon++ ) + { + addammo( weapon, &ps[myconnectindex], max_ammo_amount[weapon] ); + ps[myconnectindex].gotweapon[weapon] = 1; + } + + KB_FlushKeyBoardQueue(); + ps[myconnectindex].cheat_phase = 0; + FTA(119,&ps[myconnectindex]); + return; + + case CHEAT_INVENTORY: + KB_FlushKeyBoardQueue(); + ps[myconnectindex].cheat_phase = 0; + CheatGetInventory(); + FTA(120,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + return; + + case CHEAT_KEYS: + ps[myconnectindex].got_access = 7; + KB_FlushKeyBoardQueue(); + ps[myconnectindex].cheat_phase = 0; + FTA(121,&ps[myconnectindex]); + return; + + case CHEAT_DEBUG: + debug_on = 1-debug_on; + KB_FlushKeyBoardQueue(); + ps[myconnectindex].cheat_phase = 0; + + { + int i,j; + FILE * fp=fopen("debug.con","w"); + for(i=0;i= 0) + { + fprintf(fp,"Sprite %d (%ld,%ld,%ld) (picnum: %d)\n",j,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].picnum); + for(i=0;i 0 ) + { + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + } + else if(volnume > num_volumes-1) + { + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + } + else if(volnume == 0) + { + if(levnume > 5) + { + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + } + } + else + { + if(levnume >= 11) + { + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + } + } + + ud.m_volume_number = ud.volume_number = volnume; + ud.m_level_number = ud.level_number = levnume; + } else { // JBF 20030914 + ud.m_volume_number = ud.volume_number = osdcmd_cheatsinfo_stat.volume; + ud.m_level_number = ud.level_number = osdcmd_cheatsinfo_stat.level; + } + + } + else + { + i = strlen(cheatquotes[k])-1; + ud.m_player_skill = ud.player_skill = cheatbuf[i] - '1'; + } + if(numplayers > 1 && myconnectindex == connecthead) + { + tempbuf[0] = 5; + tempbuf[1] = ud.m_level_number; + tempbuf[2] = ud.m_volume_number; + tempbuf[3] = ud.m_player_skill; + tempbuf[4] = ud.m_monsters_off; + tempbuf[5] = ud.m_respawn_monsters; + tempbuf[6] = ud.m_respawn_items; + tempbuf[7] = ud.m_respawn_inventory; + tempbuf[8] = ud.m_coop; + tempbuf[9] = ud.m_marker; + tempbuf[10] = ud.m_ffire; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + sendpacket(i,tempbuf,11); + } + else ps[myconnectindex].gm |= MODE_RESTART; + + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_COORDS: + ps[myconnectindex].cheat_phase = 0; + ud.coords = 1-ud.coords; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_VIEW: + if( ps[myconnectindex].over_shoulder_on ) + ps[myconnectindex].over_shoulder_on = 0; + else + { + ps[myconnectindex].over_shoulder_on = 1; + cameradist = 0; + cameraclock = totalclock; + } + FTA(22,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_TIME: + + FTA(21,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_UNLOCK: + if (VOLUMEONE) return; + + for(i=numsectors-1;i>=0;i--) //Unlock + { + j = sector[i].lotag; + if(j == -1 || j == 32767) continue; + if( (j & 0x7fff) > 2 ) + { + if( j&(0xffff-16384) ) + sector[i].lotag &= (0xffff-16384); + operatesectors(i,ps[myconnectindex].i); + } + } + operateforcefields(ps[myconnectindex].i,-1); + + FTA(100,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_CASHMAN: + ud.cashman = 1-ud.cashman; + KB_ClearKeyDown(sc_N); + ps[myconnectindex].cheat_phase = 0; + return; + + case CHEAT_ITEMS: + CheatGetInventory(); + ps[myconnectindex].got_access = 7; + FTA(5,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_SHOWMAP: // SHOW ALL OF THE MAP TOGGLE; + ud.showallmap = 1-ud.showallmap; + if(ud.showallmap) + { + for(i=0;i<(MAXSECTORS>>3);i++) + show2dsector[i] = 255; + for(i=0;i<(MAXWALLS>>3);i++) + show2dwall[i] = 255; + FTA(111,&ps[myconnectindex]); + } + else + { + for(i=0;i<(MAXSECTORS>>3);i++) + show2dsector[i] = 0; + for(i=0;i<(MAXWALLS>>3);i++) + show2dwall[i] = 0; + FTA(1,&ps[myconnectindex]); + } + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_TODD: + FTA(99,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_RATE: + ud.tickrate = !ud.tickrate; + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_BETA: + FTA(105,&ps[myconnectindex]); + KB_ClearKeyDown(sc_H); + ps[myconnectindex].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_HYPER: + ps[myconnectindex].steroids_amount = 399; + ps[myconnectindex].heat_amount = 1200; + ps[myconnectindex].cheat_phase = 0; + FTA(37,&ps[myconnectindex]); + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_MONSTERS: + if(actor_tog == 3) actor_tog = 0; + actor_tog++; + ps[screenpeek].cheat_phase = 0; + KB_FlushKeyBoardQueue(); + return; + + case CHEAT_RESERVED: + case CHEAT_RESERVED3: + ud.eog = 1; + ps[myconnectindex].gm |= MODE_EOL; + KB_FlushKeyBoardQueue(); + return; + } + } + } + } + else + { + if( KB_KeyPressed(cheatkey[0]) ) + { + if( ps[myconnectindex].cheat_phase >= 0 && numplayers < 2 && ud.recstat == 0) + ps[myconnectindex].cheat_phase = -1; + } + + if( KB_KeyPressed(cheatkey[1]) ) + { + if( ps[myconnectindex].cheat_phase == -1 ) + { + if(ud.player_skill == 4) + { + FTA(22,&ps[myconnectindex]); + ps[myconnectindex].cheat_phase = 0; + } + else + { + ps[myconnectindex].cheat_phase = 1; + // FTA(25,&ps[myconnectindex]); + cheatbuflen = 0; + } + KB_FlushKeyboardQueue(); + } + else if(ps[myconnectindex].cheat_phase != 0) + { + ps[myconnectindex].cheat_phase = 0; + KB_ClearKeyDown(cheatkey[0]); + KB_ClearKeyDown(cheatkey[1]); + } + } + } +} + +long nonsharedtimer; +void nonsharedkeys(void) +{ + short i,ch, weapon; + long j; + + if(ud.recstat == 2) + { + ControlInfo noshareinfo; + CONTROL_GetInput( &noshareinfo ); + } + + if( KB_KeyPressed( sc_F12 ) ) + { + KB_ClearKeyDown( sc_F12 ); + screencapture("duke0000.tga",0); + FTA(103,&ps[myconnectindex]); + } + + if( !ALT_IS_PRESSED && ud.overhead_on == 0) + { + if( BUTTON( gamefunc_Enlarge_Screen ) ) + { + CONTROL_ClearButton( gamefunc_Enlarge_Screen ); + if(ud.screen_size > 0) + sound(THUD); + ud.screen_size -= 4; + vscrn(); + } + if( BUTTON( gamefunc_Shrink_Screen ) ) + { + CONTROL_ClearButton( gamefunc_Shrink_Screen ); + if(ud.screen_size < 64) sound(THUD); + ud.screen_size += 4; + vscrn(); + } + } + + if( ps[myconnectindex].cheat_phase == 1 || (ps[myconnectindex].gm&(MODE_MENU|MODE_TYPE))) return; + + if( BUTTON(gamefunc_See_Coop_View) && ( (gametype_flags[ud.coop] & GAMETYPE_FLAG_COOPVIEW) || ud.recstat == 2) ) + { + CONTROL_ClearButton( gamefunc_See_Coop_View ); + screenpeek = connectpoint2[screenpeek]; + if(screenpeek == -1) screenpeek = connecthead; + restorepalette = 1; + } + + if( ud.multimode > 1 && BUTTON(gamefunc_Show_Opponents_Weapon) ) + { + CONTROL_ClearButton(gamefunc_Show_Opponents_Weapon); + ud.showweapons = 1-ud.showweapons; + ShowOpponentWeapons = ud.showweapons; + FTA(82-ud.showweapons,&ps[screenpeek]); + } + + if( BUTTON(gamefunc_Toggle_Crosshair) ) + { + CONTROL_ClearButton(gamefunc_Toggle_Crosshair); + ud.crosshair = 1-ud.crosshair; + FTA(21-ud.crosshair,&ps[screenpeek]); + } + + if(ud.overhead_on && BUTTON(gamefunc_Map_Follow_Mode) ) + { + CONTROL_ClearButton(gamefunc_Map_Follow_Mode); + ud.scrollmode = 1-ud.scrollmode; + if(ud.scrollmode) + { + ud.folx = ps[screenpeek].oposx; + ud.foly = ps[screenpeek].oposy; + ud.fola = ps[screenpeek].oang; + } + FTA(83+ud.scrollmode,&ps[myconnectindex]); + } + + if( SHIFTS_IS_PRESSED || ALT_IS_PRESSED ) + { + i = 0; + if( KB_KeyPressed( sc_F1) ) { KB_ClearKeyDown(sc_F1);i = 1; } + if( KB_KeyPressed( sc_F2) ) { KB_ClearKeyDown(sc_F2);i = 2; } + if( KB_KeyPressed( sc_F3) ) { KB_ClearKeyDown(sc_F3);i = 3; } + if( KB_KeyPressed( sc_F4) ) { KB_ClearKeyDown(sc_F4);i = 4; } + if( KB_KeyPressed( sc_F5) ) { KB_ClearKeyDown(sc_F5);i = 5; } + if( KB_KeyPressed( sc_F6) ) { KB_ClearKeyDown(sc_F6);i = 6; } + if( KB_KeyPressed( sc_F7) ) { KB_ClearKeyDown(sc_F7);i = 7; } + if( KB_KeyPressed( sc_F8) ) { KB_ClearKeyDown(sc_F8);i = 8; } + if( KB_KeyPressed( sc_F9) ) { KB_ClearKeyDown(sc_F9);i = 9; } + if( KB_KeyPressed( sc_F10) ) {KB_ClearKeyDown(sc_F10);i = 10; } + + if(i) + { + if(SHIFTS_IS_PRESSED) + { + if(i == 5 && ps[myconnectindex].fta > 0 && ps[myconnectindex].ftq == 26) + { + music_select++; + if (VOLUMEALL) { + if(music_select == 44) music_select = 0; + } else { + if(music_select == 6) music_select = 0; + } + strcpy(&tempbuf[0],"PLAYING "); + strcat(&tempbuf[0],&music_fn[0][music_select][0]); + playmusic(&music_fn[0][music_select][0]); + strcpy(&fta_quotes[26][0],&tempbuf[0]); + FTA(26,&ps[myconnectindex]); + return; + } + + adduserquote(ud.ridecule[i-1]); + + ch = 0; + + tempbuf[ch] = 4; + tempbuf[ch+1] = 255; + tempbuf[ch+2] = 0; + strcat(tempbuf+2,ud.ridecule[i-1]); + + i = 2+strlen(ud.ridecule[i-1]); + + if(ud.multimode > 1) + for(ch=connecthead;ch>=0;ch=connectpoint2[ch]) + { + if (ch != myconnectindex) sendpacket(ch,tempbuf,i); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + + pus = NUMPAGES; + pub = NUMPAGES; + + return; + + } + + if(ud.lockout == 0) + if(SoundToggle && ALT_IS_PRESSED && ( RTS_NumSounds() > 0 ) && rtsplaying == 0 && VoiceToggle ) + { + rtsptr = (char *)RTS_GetSound (i-1); + if(*rtsptr == 'C') + FX_PlayVOC3D( rtsptr,0,0,0,255,-i); + else FX_PlayWAV3D( rtsptr,0,0,0,255,-i); + + rtsplaying = 7; + + if(ud.multimode > 1) + { + tempbuf[0] = 7; + tempbuf[1] = i; + + for(ch=connecthead;ch>=0;ch=connectpoint2[ch]) + { + if(ch != myconnectindex) sendpacket(ch,tempbuf,2); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + } + + pus = NUMPAGES; + pub = NUMPAGES; + + return; + } + } + } + + if(!ALT_IS_PRESSED && !SHIFTS_IS_PRESSED) + { + + if( ud.multimode > 1 && BUTTON(gamefunc_SendMessage) ) + { + KB_FlushKeyboardQueue(); + CONTROL_ClearButton( gamefunc_SendMessage ); + ps[myconnectindex].gm |= MODE_TYPE; + typebuf[0] = 0; + inputloc = 0; + } + + if( KB_KeyPressed(sc_F1) || ( ud.show_help && ( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) ) ) ) + { + KB_ClearKeyDown(sc_F1); + KB_ClearKeyDown(sc_Space); + KB_ClearKeyDown(sc_kpad_Enter); + KB_ClearKeyDown(sc_Enter); + ud.show_help ++; + + if( ud.show_help > 2 ) + { + ud.show_help = 0; + if(ud.multimode < 2 && ud.recstat != 2) ready2send = 1; + vscrn(); + } + else + { + setview(0,0,xdim-1,ydim-1); + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 0; + totalclock = ototalclock; + } + } + } + + // if(ud.multimode < 2) + { + if(ud.recstat != 2 && KB_KeyPressed( sc_F2 ) ) + { + KB_ClearKeyDown( sc_F2 ); + + if(movesperpacket == 4 && connecthead != myconnectindex) + return; + +FAKE_F2: + if(sprite[ps[myconnectindex].i].extra <= 0) + { + FTA(118,&ps[myconnectindex]); + return; + } + cmenu(350); + screencapt = 1; + displayrooms(myconnectindex,65536); + //savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100); + screencapt = 0; + FX_StopAllSounds(); + clearsoundlocks(); + + // setview(0,0,xdim-1,ydim-1); + ps[myconnectindex].gm |= MODE_MENU; + + if(ud.multimode < 2) + { + ready2send = 0; + totalclock = ototalclock; + screenpeek = myconnectindex; + } + } + + if(KB_KeyPressed( sc_F3 )) + { + KB_ClearKeyDown( sc_F3 ); + + if(movesperpacket == 4 && connecthead != myconnectindex) + return; +FAKE_F3: + cmenu(300); + FX_StopAllSounds(); + clearsoundlocks(); + + // setview(0,0,xdim-1,ydim-1); + ps[myconnectindex].gm |= MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 0; + totalclock = ototalclock; + } + screenpeek = myconnectindex; + } + } + + if(KB_KeyPressed( sc_F4 ) && FXDevice >= 0 ) + { + KB_ClearKeyDown( sc_F4 ); + FX_StopAllSounds(); + clearsoundlocks(); + + ps[myconnectindex].gm |= MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 0; + totalclock = ototalclock; + } + cmenu(701); + + } + + if( KB_KeyPressed( sc_F6 ) && (ps[myconnectindex].gm&MODE_GAME)) + { + KB_ClearKeyDown( sc_F6 ); + + if(movesperpacket == 4 && connecthead != myconnectindex) + return; + + if(lastsavedpos == -1) goto FAKE_F2; + + KB_FlushKeyboardQueue(); + + if(sprite[ps[myconnectindex].i].extra <= 0) + { + FTA(118,&ps[myconnectindex]); + return; + } + screencapt = 1; + displayrooms(myconnectindex,65536); + //savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100); + screencapt = 0; + if( lastsavedpos >= 0 ) + { +/* inputloc = strlen(&ud.savegame[lastsavedpos][0]); + current_menu = 360+lastsavedpos; + probey = lastsavedpos; */ + if(ud.multimode > 1) + saveplayer(-1-(lastsavedpos)); + else saveplayer(lastsavedpos); + } + } + + if(KB_KeyPressed( sc_F7 ) ) + { + KB_ClearKeyDown(sc_F7); + if( ps[myconnectindex].over_shoulder_on ) + ps[myconnectindex].over_shoulder_on = 0; + else + { + ps[myconnectindex].over_shoulder_on = 1; + cameradist = 0; + cameraclock = totalclock; + } + FTA(109+ps[myconnectindex].over_shoulder_on,&ps[myconnectindex]); + } + + if( KB_KeyPressed( sc_F5 ) && MusicDevice >= 0 ) + { + KB_ClearKeyDown( sc_F5 ); + strcpy(&tempbuf[0],&music_fn[0][music_select][0]); + strcat(&tempbuf[0],". USE SHIFT-F5 TO CHANGE."); + strcpy(&fta_quotes[26][0],&tempbuf[0]); + FTA(26,&ps[myconnectindex]); + + } + + if(KB_KeyPressed( sc_F8 )) + { + KB_ClearKeyDown( sc_F8 ); + ud.fta_on = !ud.fta_on; + if(ud.fta_on) FTA(23,&ps[myconnectindex]); + else + { + ud.fta_on = 1; + FTA(24,&ps[myconnectindex]); + ud.fta_on = 0; + } + } + + if(KB_KeyPressed( sc_F9 ) && (ps[myconnectindex].gm&MODE_GAME) ) + { + KB_ClearKeyDown( sc_F9 ); + + if(movesperpacket == 4 && myconnectindex != connecthead) + return; + + if(lastsavedpos == -1) goto FAKE_F3; + + if( lastsavedpos >= 0 ) + { + KB_FlushKeyboardQueue(); + KB_ClearKeysDown(); + FX_StopAllSounds(); + + if(ud.multimode > 1) + { + loadplayer(-1-lastsavedpos); + ps[myconnectindex].gm = MODE_GAME; + } + else + { + i = loadplayer(lastsavedpos); + if(i == 0) + ps[myconnectindex].gm = MODE_GAME; + } + } + } + + if(KB_KeyPressed( sc_F10 )) + { + KB_ClearKeyDown( sc_F10 ); + cmenu(500); + FX_StopAllSounds(); + clearsoundlocks(); + ps[myconnectindex].gm |= MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 0; + totalclock = ototalclock; + } + } + + if( ud.overhead_on != 0) + { + + j = totalclock-nonsharedtimer; nonsharedtimer += j; + if ( BUTTON( gamefunc_Enlarge_Screen ) ) + ps[myconnectindex].zoom += mulscale6(j,max(ps[myconnectindex].zoom,256)); + if ( BUTTON( gamefunc_Shrink_Screen ) ) + ps[myconnectindex].zoom -= mulscale6(j,max(ps[myconnectindex].zoom,256)); + + if( (ps[myconnectindex].zoom > 2048) ) + ps[myconnectindex].zoom = 2048; + if( (ps[myconnectindex].zoom < 48) ) + ps[myconnectindex].zoom = 48; + + } + } + + if( KB_KeyPressed(sc_Escape) && ud.overhead_on && ps[myconnectindex].newowner == -1 ) + { + KB_ClearKeyDown( sc_Escape ); + ud.last_overhead = ud.overhead_on; + ud.overhead_on = 0; + ud.scrollmode = 0; + vscrn(); + } + + if( BUTTON(gamefunc_AutoRun) ) + { + CONTROL_ClearButton(gamefunc_AutoRun); + ud.auto_run = 1-ud.auto_run; + RunMode = ud.auto_run; + FTA(85+ud.auto_run,&ps[myconnectindex]); + } + + if( BUTTON(gamefunc_Map) ) + { + CONTROL_ClearButton( gamefunc_Map ); + if( ud.last_overhead != ud.overhead_on && ud.last_overhead) + { + ud.overhead_on = ud.last_overhead; + ud.last_overhead = 0; + } + else + { + ud.overhead_on++; + if(ud.overhead_on == 3 ) ud.overhead_on = 0; + ud.last_overhead = ud.overhead_on; + } + restorepalette = 1; + vscrn(); + } + + if(KB_KeyPressed( sc_F11 )) + { + KB_ClearKeyDown( sc_F11 ); + if(SHIFTS_IS_PRESSED) ud.brightness-=4; + else ud.brightness+=4; + + if (ud.brightness > (7<<2) ) + ud.brightness = 0; + else if(ud.brightness < 0) + ud.brightness = (7<<2); + + setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0],0); + if(ud.brightness < 20) FTA( 29 + (ud.brightness>>2) ,&ps[myconnectindex]); + else if(ud.brightness < 40) FTA( 96 + (ud.brightness>>2) - 5,&ps[myconnectindex]); + } +} + +void comlinehelp(char **argv) +{ + char *s = "Command line help.\n" + "?, -?\t\tThis help message\n" + "-l##\t\tLevel (1-11)\n" + "-v#\t\tVolume (1-4)\n" + "-s#\t\tSkill (1-4)\n" + "-r\t\tRecord demo\n" + "-dFILE\t\tStart to play demo FILE\n" + "-m\t\tNo monsters\n" + "-ns\t\tNo sound\n" + "-nm\t\tNo music\n" + "-t#\t\tRespawn, 1 = Monsters, 2 = Items, 3 = Inventory, x = All\n" + "-c#\t\tMP mode, 1 = DukeMatch(spawn), 2 = Coop, 3 = Dukematch(no spawn)\n" + "-q#\t\tFake multiplayer (2-8 players)\n" + "-a\t\tUse player AI (fake multiplayer only)\n" + "-i#\t\tNetwork mode (1/0) (multiplayer only) (default == 1)\n" + "-f#\t\tSend fewer packets (1, 2, 4) (multiplayer only)\n" + "-gFILE\t\tUse multiple group files (must be last on command line)\n" + "-hFILE\t\tUse FILE instead of DUKE3D.DEF\n" + "-xFILE\t\tUse specified CON file (default EDUKE.CON/GAME.CON)\n" + "-u#########\tUser's favorite weapon order (default: 3425689071)\n" + "-#\t\tLoad and run a game (slot 0-9)\n" + "-map FILE\tUse a map FILE\n" + "-name NAME\tFoward NAME\n" + "-net\t\tNet mode game\n" + "-nD\t\tDump game definitions to gamevars.txt\n" + "-condebug, -z#\tLine-by-line CON compilation debugging"; + wm_msgbox(apptitle,s); +} + +void checkcommandline(int argc,char **argv) +{ + short i, j; + char *c; + int firstnet = 0; + + i = 1; + + ud.fta_on = 1; + ud.god = 0; + ud.m_respawn_items = 0; + ud.m_respawn_monsters = 0; + ud.m_respawn_inventory = 0; + ud.warp_on = 0; + ud.cashman = 0; + ud.m_player_skill = ud.player_skill = 2; + + if(argc > 1) + { + while(i < argc) + { + c = argv[i]; + if (((*c == '/') || (*c == '-')) && (!firstnet)) + { + if (!Bstrcasecmp(c+1,"net")) { + firstnet = i; + netparamcount = argc - i - 1; + netparam = (char **)calloc(netparamcount, sizeof(char**)); + i++; + continue; + } + if (!Bstrcasecmp(c+1,"name")) { + if (argc > i+1) { + CommandName = argv[i+1]; + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1,"map")) { + if (argc > i+1) { + CommandMap = argv[i+1]; + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1,"condebug")) { + condebug = 1; + i++; + continue; + } + } + + if (firstnet > 0) { + if (*c == '-' || *c == '/') { + c++; + if (((c[0] == 'n') || (c[0] == 'N')) && (c[1] == '0')) + { networkmode = 0; initprintf("Network mode: master/slave\n"); } + else if (((c[0] == 'n') || (c[0] == 'N')) && (c[1] == '1')) + { networkmode = 1; initprintf("Network mode: peer-to-peer\n"); } + } + netparam[i-firstnet-1] = argv[i]; + i++; + continue; + } + + + if(*c == '?') + { + comlinehelp(argv); + exit(-1); + } + + if((*c == '/') || (*c == '-')) + { + c++; + switch(*c) + { + default: + // printf("Unknown command line parameter '%s'\n",argv[i]); + case '?': + comlinehelp(argv); + exit(0); + case 'x': + case 'X': + c++; + if(*c) + { + strcpy(confilename,c); + userconfiles = 1; + /* if(SafeFileExists(c) == 0) + { + initprintf("Could not find CON file '%s'.\n",confilename ); + exit(-1); + } + else */ initprintf("Using CON file: '%s'\n",confilename); + } + break; + case 'g': + case 'G': + c++; + if(*c) + { + strcpy(tempbuf,c); + if( strchr(tempbuf,'.') == 0) + strcat(tempbuf,".grp"); + + j = initgroupfile(tempbuf); + if( j == -1 ) + initprintf("Could not find GRP file %s.\n",tempbuf); + else + { + groupfile = j; + initprintf("Using GRP file %s.\n",tempbuf); + } + } + + break; + case 'h': + case 'H': + c++; + if (*c) { + duke3ddef = c; + initprintf("Using DEF file %s.\n",duke3ddef); + } + break; + + case 'a': + case 'A': + ud.playerai = 1; + initprintf("Other player AI.\n"); + break; + case 'n': + case 'N': + c++; + if(*c == 's' || *c == 'S') + { + CommandSoundToggleOff = 2; + initprintf("Sound off.\n"); + } + else if(*c == 'm' || *c == 'M') + { + CommandMusicToggleOff = 1; + initprintf("Music off.\n"); + } + + else if( *c == 'D') + { + FILE * fp=fopenfrompath("gamevars.txt","w"); + InitGameVars(); + DumpGameVars(fp); + fclose(fp); + initprintf("Game variables saved to gamevars.txt.\n"); + } + + else + { + comlinehelp(argv); + exit(-1); + } + break; + case 'i': + case 'I': + c++; + if(*c == '0') networkmode = 0; + if(*c == '1') networkmode = 1; + initprintf("Network Mode %d\n",networkmode); + break; + case 'c': + case 'C': + + c++; + //if(*c == '1' || *c == '2' || *c == '3' ) + // ud.m_coop = *c - '0' - 1; + //else ud.m_coop = 0; + + ud.m_coop = 0; + while ((*c >= '0')&&(*c <= '9')) { + ud.m_coop *= 10; + ud.m_coop += *c - '0'; + c++; + } + ud.m_coop--; + //switch(ud.m_coop) + //{ + //case 0: + // initprintf("Dukematch (spawn).\n"); + // break; + //case 1: + // initprintf("Cooperative play.\n"); + // break; + //case 2: + // initprintf("Dukematch (no spawn).\n"); + // break; + //} + break; + case 'f': + case 'F': + c++; + if(*c == '1') + movesperpacket = 1; + if(*c == '2') + movesperpacket = 2; + if(*c == '4') + { + movesperpacket = 4; + setpackettimeout(0x3fffffff,0x3fffffff); + } + break; + case 't': + case 'T': + c++; + if(*c == '1') ud.m_respawn_monsters = 1; + else if(*c == '2') ud.m_respawn_items = 1; + else if(*c == '3') ud.m_respawn_inventory = 1; + else + { + ud.m_respawn_monsters = 1; + ud.m_respawn_items = 1; + ud.m_respawn_inventory = 1; + } + initprintf("Respawn on.\n"); + break; + case 'm': + case 'M': + if( *(c+1) != 'a' && *(c+1) != 'A' ) + { + ud.m_monsters_off = 1; + ud.m_player_skill = ud.player_skill = 0; + initprintf("Monsters off.\n"); + } + break; + case 'w': + case 'W': + ud.coords = 1; + break; + case 'q': + case 'Q': + initprintf("Fake multiplayer mode.\n"); + if( *(++c) == 0) ud.multimode = 1; + else ud.multimode = atol(c)%17; + ud.m_coop = ud.coop = 0; + ud.m_marker = ud.marker = 1; + ud.m_respawn_monsters = ud.respawn_monsters = 1; + ud.m_respawn_items = ud.respawn_items = 1; + ud.m_respawn_inventory = ud.respawn_inventory = 1; + + break; + case 'r': + case 'R': + ud.m_recstat = 1; + initprintf("Demo record mode on.\n"); + break; + case 'd': + case 'D': + c++; + if( strchr(c,'.') == 0) + strcat(c,".dmo"); + initprintf("Play demo %s.\n",c); + strcpy(firstdemofile,c); + break; + case 'l': + case 'L': + ud.warp_on = 1; + c++; + ud.m_level_number = ud.level_number = (atol(c)-1)%11; + break; + case 'j': + case 'J': + initprintf(HEAD2); + exit(0); + + case 'v': + case 'V': + c++; + ud.warp_on = 1; + ud.m_volume_number = ud.volume_number = atol(c)-1; + break; + case 's': + case 'S': + c++; + ud.m_player_skill = ud.player_skill = (atol(c)%5); + if(ud.m_player_skill == 4) + ud.m_respawn_monsters = ud.respawn_monsters = 1; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ud.warp_on = 2 + (*c) - '0'; + break; + case 'u': + case 'U': + c++; + j = 0; + if(*c) + { + initprintf("Using favorite weapon order(s).\n"); + while(*c) + { + ud.wchoice[0][j] = *c-'0'; + c++; + j++; + } + while(j < 10) + { + if(j == 9) + ud.wchoice[0][9] = 1; + else + ud.wchoice[0][j] = 2; + + j++; + } + } + else + { + initprintf("Using default weapon orders.\n"); + ud.wchoice[0][0] = 3; + ud.wchoice[0][1] = 4; + ud.wchoice[0][2] = 5; + ud.wchoice[0][3] = 7; + ud.wchoice[0][4] = 8; + ud.wchoice[0][5] = 6; + ud.wchoice[0][6] = 0; + ud.wchoice[0][7] = 2; + ud.wchoice[0][8] = 9; + ud.wchoice[0][9] = 1; + } + + break; + case 'z': + case 'Z': + c++; + condebug = atol(c); + if(!condebug) + condebug = 1; + break; + } + } + i++; + } + } +} + +void printstr(short x, short y, char string[81], char attribute) +{ + char character; + short i, pos; + /* + pos = (y*80+x)<<1; + i = 0; + while (string[i] != 0) + { + character = string[i]; + printchrasm(0xb8000+(long)pos,1L,((long)attribute<<8)+(long)character); + i++; + pos+=2; + } + */ +} + +/* +void cacheicon(void) +{ + if(cachecount > 0) + { + if( (ps[myconnectindex].gm&MODE_MENU) == 0 ) + rotatesprite((320-7)<<16,(200-23)<<16,32768L,0,SPINNINGNUKEICON,0,0,2,windowx1,windowy1,windowx2,windowy2); + cachecount = 0; + } +} + */ + +void Logo(void) +{ + short i,j,soundanm; + long logoflags=GetGameVar("LOGO_FLAGS",255, -1, -1); + soundanm = 0; + + ready2send = 0; + + KB_FlushKeyboardQueue(); + KB_ClearKeysDown(); // JBF + + setview(0,0,xdim-1,ydim-1); + clearview(0L); + IFISSOFTMODE palto(0,0,0,63); + + flushperms(); + nextpage(); + + MUSIC_StopSong(); + FX_StopAllSounds(); // JBF 20031228 + clearsoundlocks(); // JBF 20031228 + if (ud.multimode < 2 && (logoflags & LOGO_FLAG_ENABLED)) + { + if (VOLUMEALL && (logoflags & LOGO_FLAG_PLAYANIM)) { + + if(!KB_KeyWaiting() && nomorelogohack == 0) + { + getpackets(); + playanm("logo.anm",5); + IFISSOFTMODE palto(0,0,0,63); + KB_FlushKeyboardQueue(); + KB_ClearKeysDown(); // JBF + } + + clearview(0L); + nextpage(); + } + if (logoflags & LOGO_FLAG_PLAYMUSIC) + playmusic(&env_music_fn[0][0]); + + fadepal(0,0,0, 0,64,7); + //ps[myconnectindex].palette = drealms; + //palto(0,0,0,63); + if (logoflags & LOGO_FLAG_3DRSCREEN) + { + setgamepalette(&ps[myconnectindex], drealms, 3); // JBF 20040308 + rotatesprite(0,0,65536L,0,DREALMS,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + nextpage(); + fadepal(0,0,0, 63,0,-7); + totalclock = 0; + while( totalclock < (120*7) && !KB_KeyWaiting() ) { + handleevents(); + getpackets(); + } + } + KB_ClearKeysDown(); // JBF + + fadepal(0,0,0, 0,64,7); + clearview(0L); + nextpage(); + if (logoflags & LOGO_FLAG_TITLESCREEN) + { + //ps[myconnectindex].palette = titlepal; + setgamepalette(&ps[myconnectindex], titlepal, 3); // JBF 20040308 + flushperms(); + rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1); + KB_FlushKeyboardQueue(); + fadepal(0,0,0, 63,0,-7); + totalclock = 0; + + while(totalclock < (860+120) && !KB_KeyWaiting()) + { + rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1); + if (logoflags & LOGO_FLAG_DUKENUKEM) + { + if( totalclock > 120 && totalclock < (120+60) ) + { + if(soundanm == 0) + { + soundanm = 1; + sound(PIPEBOMB_EXPLODE); + } + rotatesprite(160<<16,104<<16,(totalclock-120)<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1); + } + else if( totalclock >= (120+60) ) + rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1); + } else soundanm = 1; + if (logoflags & LOGO_FLAG_THREEDEE) + { + if( totalclock > 220 && totalclock < (220+30) ) + { + if( soundanm == 1) + { + soundanm = 2; + sound(PIPEBOMB_EXPLODE); + } + + rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1); + rotatesprite(160<<16,(129)<<16,(totalclock - 220 )<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1); + } + else if( totalclock >= (220+30) ) + rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1); + } else soundanm = 2; + if (PLUTOPAK && (logoflags & LOGO_FLAG_PLUTOPAKSPRITE)) { // JBF 20030804 + if( totalclock >= 280 && totalclock < 395 ) + { + rotatesprite(160<<16,(151)<<16,(410-totalclock)<<12,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1); + if(soundanm == 2) + { + soundanm = 3; + sound(FLY_BY); + } + } + else if( totalclock >= 395 ) + { + if(soundanm == 3) + { + soundanm = 4; + sound(PIPEBOMB_EXPLODE); + } + rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1); + } + } + OnEvent(EVENT_LOGO, -1, screenpeek, -1); + handleevents(); + getpackets(); + nextpage(); + } + } + KB_ClearKeysDown(); // JBF + } + + if(ud.multimode > 1) + { + setgamepalette(&ps[myconnectindex], titlepal, 3); + rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1); + + rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1); + rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1); + if (PLUTOPAK) // JBF 20030804 + rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1); + + gametext(160,190,"WAITING FOR PLAYERS",14,2); + nextpage(); + } + + waitforeverybody(); + + flushperms(); + clearview(0L); + nextpage(); + + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 0); // JBF 20040308 + sound(NITEVISION_ONOFF); + + //palto(0,0,0,0); + clearview(0L); +} + +void loadtmb(void) +{ + char tmb[8000]; + long fil, l; + + fil = kopen4load("d3dtimbr.tmb",0); + if(fil == -1) return; + l = kfilelength(fil); + kread(fil,(char *)tmb,l); + MUSIC_RegisterTimbreBank(tmb); + kclose(fil); +} + +/* +=================== += += ShutDown += +=================== +*/ + +void Shutdown( void ) +{ + SoundShutdown(); + MusicShutdown(); + uninittimer(); + uninitengine(); + CONTROL_Shutdown(); + CONFIG_WriteSetup(); + KB_Shutdown(); +} + +/* +=================== += += Startup += +=================== +*/ + +void compilecons(void) +{ + char *tempname; + int i; + label = (char *)&sprite[0]; // V8: 16384*44/64 = 11264 V7: 4096*44/64 = 2816 + labelcode = (long *)§or[0]; // V8: 4096*40/4 = 40960 V7: 1024*40/4 = 10240 + labeltype = (long *)&wall[0]; // V8: 16384*32/4 = 131072 V7: 8192*32/4 = 65536 + // if we compile for a V7 engine wall[] should be used for label names since it's bigger + + if(userconfiles == 0) + { + i = kopen4load(confilename,0); + if (i!=-1) + kclose(i); + else Bsprintf(confilename,"GAME.CON"); + } + loadefs(confilename); + + if( loadfromgrouponly ) + { + if(userconfiles == 0) + { + i = kopen4load("EDUKE.CON",1); + if (i!=-1) + { + Bsprintf(confilename,"EDUKE.CON"); + kclose(i); + } + else Bsprintf(confilename,"GAME.CON"); + } + loadefs(confilename); + } + + if ((unsigned long)labelcnt > sizeof(sprite)/64 ) // see the arithmetic above for why + gameexit("Error: too many labels defined!"); + else + { + char *newlabel; + long *newlabelcode; + + newlabel = (char *)malloc(labelcnt<<6); + newlabelcode = (long *)malloc(labelcnt*sizeof(long)); + + if (!newlabel || !newlabelcode) + { + gameexit("Error: out of memory retaining labels\n"); + } + + copybuf(label, newlabel, (labelcnt*64)/4); + copybuf(labelcode, newlabelcode, (labelcnt*sizeof(long))/4); + + label = newlabel; + labelcode = newlabelcode; + } + clearbufbyte(&sprite[0], sizeof(sprite), 0); + clearbufbyte(§or[0], sizeof(sector), 0); + clearbufbyte(&wall[0], sizeof(wall), 0); + + OnEvent(EVENT_INIT, -1, -1, -1); +} + +void sanitizegametype() +{ + // initprintf("ud.m_coop=%i before sanitization\n",ud.m_coop); + if (ud.m_coop >= num_gametypes || ud.m_coop < 0) { + ud.m_coop = 0; + } + Bsprintf(tempbuf,"%s\n",gametype_names[ud.m_coop]); + initprintf(tempbuf); + if(gametype_flags[ud.m_coop] & GAMETYPE_FLAG_ITEMRESPAWN) ud.m_respawn_items = 1; + else ud.m_respawn_items = 0; + // initprintf("ud.m_coop=%i after sanitisation\n",ud.m_coop); +} + +void Startup(void) +{ + int i; + + CONFIG_ReadSetup(); + + // readnames(); + + compilecons(); // JBF 20040116: Moved to below setup reading, because otherwise blown + + setupdynamictostatic(); + + if (ud.multimode > 1) sanitizegametype(); + + if (CommandSoundToggleOff) SoundToggle = 0; + if (CommandMusicToggleOff) MusicToggle = 0; + if (CommandName) strcpy(myname,CommandName); + if (CommandMap) { + if (VOLUMEONE) { + initprintf("The -map option is available in the registered version only!\n"); + boardfilename[0] = 0; + } else { + char *dot, *slash; + + Bstrcpy(boardfilename, CommandMap); + + dot = Bstrrchr(boardfilename,'.'); + slash = Bstrrchr(boardfilename,'/'); + if (!slash) slash = Bstrrchr(boardfilename,'\\'); + + if ((!slash && !dot) || (slash && dot < slash)) + Bstrcat(boardfilename,".map"); + + i = kopen4load(boardfilename,0); + if (i!=-1) { + initprintf("Using level: '%s'.\n",boardfilename); + kclose(i); + } + else + { + initprintf("Level '%s' not found.\n",boardfilename); + boardfilename[0] = 0; + } + } + } + + if (VOLUMEONE) { + initprintf("*** You have run Duke Nukem 3D %ld times. ***\n\n",ud.executions); + if(ud.executions >= 50) initprintf("IT IS NOW TIME TO UPGRADE TO THE COMPLETE VERSION!!!\n"); + } + + if (initengine()) { + wm_msgbox("Build Engine Initialisation Error", + "There was a problem initialising the Build engine: %s", engineerrstr); + exit(1); + } + + if (CONTROL_Startup( ControllerType, &GetTime, TICRATE )) { + uninitengine(); + exit(1); + } + SetupGameButtons(); + CONFIG_SetupMouse(); + CONFIG_SetupJoystick(); + + // JBF 20040215: evil and nasty place to do this, but joysticks are evil and nasty too + if (ControllerType == controltype_keyboardandjoystick) { + for (i=0;i 1) + initprintf("Multiplayer initialized.\n"); + + screenpeek = myconnectindex; + ps[myconnectindex].palette = (char *) &palette[0]; + + if(networkmode == 255) + networkmode = 1; + + getnames(); +} + +void sendscore(char *s) +{ + if(numplayers > 1) + genericmultifunction(-1,s,strlen(s)+1,5); +} + +void getnames(void) +{ + int i,l; + + for(l=0;myname[l];l++) + ud.user_name[myconnectindex][l] = Btoupper(myname[l]); + + if(numplayers > 1) + { + buf[0] = 6; + buf[1] = myconnectindex; + buf[2] = BYTEVERSION; + l = 3; + + //null terminated player name to send + for(i=0;myname[i];i++) buf[l++] = Btoupper(myname[i]); + buf[l++] = 0; + + for(i=0;i<10;i++) + { + ud.wchoice[myconnectindex][i] = ud.wchoice[0][i]; + buf[l++] = (char)ud.wchoice[0][i]; + } + + buf[l++] = ps[myconnectindex].aim_mode = ud.mouseaiming; + buf[l++] = ps[myconnectindex].auto_aim = AutoAim; + buf[l++] = ps[myconnectindex].weaponswitch = ud.weaponswitch; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) sendpacket(i,&buf[0],l); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + + getpackets(); + + waitforeverybody(); + } + + if(cp == 1 && numplayers < 2) + gameexit("Please put the Duke Nukem 3D Atomic Edition CD in the CD-ROM drive."); +} + +void writestring(long a1,long a2,long a3,short a4,long vx,long vy,long vz) +{ + + FILE *fp; + + fp = (FILE *)fopenfrompath("debug.txt","rt+"); + + fprintf(fp,"%ld %ld %ld %d %ld %ld %ld\n",a1,a2,a3,a4,vx,vy,vz); + + fclose(fp); + +} + +char testcd(char *fn, long testsiz); + +// JBF: various hacks here +void copyprotect(void) +{ + // FILE *fp; + // char idfile[256]; + + cp = 0; + +#ifdef NOCOPYPROTECT + return; +#endif + if (VOLUMEONE) return; + + if( testcd(IDFILENAME, IDFSIZE) ) + { + cp = 1; + return; + } +} + +void backtomenu(void) +{ + boardfilename[0] = 0; + if (ud.recstat == 1) closedemowrite(); + ud.warp_on = 0; + ps[myconnectindex].gm = MODE_MENU; + cmenu(0); + KB_FlushKeyboardQueue(); +} + +int shareware = 0; + +char *startwin_labeltext = "Starting EDuke32..."; + +int load_script(char *szScript) +{ + FILE* fp = fopenfrompath(szScript, "r"); + + if(fp != NULL) + { + char line[255]; + OSD_Printf("Executing \"%s\"\n", szScript); + while(fgets(line ,sizeof(line)-1, fp) != NULL) + OSD_Dispatch(strtok(line,"\r\n")); + fclose(fp); + return 0; + } + return 1; +} + +void app_main(int argc,char **argv) +{ + long i, j, k, l; +#ifdef RENDERTYPEWIN + if (win_checkinstance()) { + if (!wm_ynbox("EDuke32","Another Build game is currently running. " + "Do you wish to continue starting this copy?")) + return; + } +#endif + + OSD_SetLogFile("eduke32.log"); + +#if 1 // defined(_WIN32) + if (!access("user_profiles_enabled", F_OK)) +#endif + { + char cwd[BMAX_PATH]; + char *homedir; + int asperr; + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + addsearchpath("/usr/share/games/eduke32"); + addsearchpath("/usr/local/share/games/eduke32"); +#elif defined(__APPLE__) + addsearchpath("/Library/Application Support/EDuke32"); +#endif + if (getcwd(cwd,BMAX_PATH)) addsearchpath(cwd); + if ((homedir = Bgethomedir())) { + Bsnprintf(cwd,sizeof(cwd),"%s/" +#if defined(_WIN32) + "EDuke32 Settings" +#elif defined(__APPLE__) + "Library/Application Support/EDuke32" +#else + ".eduke32" +#endif + ,homedir); + asperr = addsearchpath(cwd); + if (asperr == -2) { + if (Bmkdir(cwd,S_IRWXU) == 0) asperr = addsearchpath(cwd); + else asperr = -1; + } + if ((asperr == 0)) + chdir(cwd); + Bfree(homedir); + } + } + + // JBF 20030925: Because it's annoying renaming GRP files whenever I want to test different game data + if (getenv("DUKE3DGRP")) { + duke3dgrp = getenv("DUKE3DGRP"); + initprintf("Using `%s' as main GRP file\n", duke3dgrp); + } + initgroupfile(duke3dgrp); + i = kopen4load("DUKESW.BIN",1); // JBF 20030810 + if (i!=-1) { + initprintf("Using Shareware GRP file.\n"); + shareware = 1; + kclose(i); + } + copyprotect(); + if (cp) return; + + // gotta set the proper title after we compile the CONs if this is the full version + + if (VOLUMEALL) wm_setapptitle(HEAD2); + else wm_setapptitle(HEAD); + + initprintf("%s%s\n",apptitle," ("__DATE__" "__TIME__")"); + initprintf("Copyright (c) 1996, 2003 3D Realms Entertainment\n"); + initprintf("Copyright (c) 2006 EDuke32 team\n\n"); + + ud.multimode = 1; + + checkcommandline(argc,argv); + if (!loaddefinitionsfile(duke3ddef)) initprintf("Definitions file loaded.\n"); + if (condebug) + initprintf("CON debugging activated (%d).\n\n",condebug); + + if (netparamcount > 0) _buildargc = (argc -= netparamcount+1); // crop off the net parameters + + RegisterShutdownFunction( Shutdown ); + + if (VOLUMEONE) { + initprintf("Distribution of shareware Duke Nukem 3D is restricted in certain ways.\n"); + initprintf("Please read LICENSE.DOC for more details.\n"); + } + + Startup(); // a bunch of stuff including compiling cons + + if (quitevent) return; + + // initprintf("numplayers=%i\n",numplayers); + + if(numplayers > 1) + { + ud.multimode = numplayers; + sendlogon(); + } + else if(boardfilename[0] != 0) + { + ud.m_level_number = 7; + ud.m_volume_number = 0; + ud.warp_on = 1; + } + + getnames(); + + if(ud.multimode > 1) + { + playerswhenstarted = ud.multimode; + + if(ud.warp_on == 0) + { + ud.m_monsters_off = 1; + ud.m_player_skill = 0; + } + } + + ud.last_level = -1; + + RTS_Init(ud.rtsname); + if(numlumps) initprintf("Using .RTS file: %s\n",ud.rtsname); + + if (CONTROL_JoystickEnabled) + CONTROL_CenterJoystick + ( + CenterCenter, + UpperLeft, + LowerRight, + CenterThrottle, + CenterRudder + ); + + if( setgamemode(ScreenMode,ScreenWidth,ScreenHeight,ScreenBPP) < 0 ) + { + initprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...", + ScreenWidth,ScreenHeight,ScreenBPP,ScreenMode?"fullscreen":"windowed"); + ScreenMode = 0; // JBF: was 2 + ScreenWidth = 320; + ScreenHeight = 240; // JBF: was 200 + ScreenBPP = 8; + setgamemode(ScreenMode,ScreenWidth,ScreenHeight,ScreenBPP); + } + + initprintf("Initializing OSD...\n"); + + OSD_SetFunctions( + GAME_drawosdchar, + GAME_drawosdstr, + GAME_drawosdcursor, + GAME_getcolumnwidth, + GAME_getrowheight, + GAME_clearbackground, + (int(*)(void))GetTime, + GAME_onshowosd + ); + OSD_SetParameters(0,2, 0,0, 4,0); + registerosdcommands(); + + initprintf("Checking music inits...\n"); + MusicStartup(); + initprintf("Checking sound inits...\n"); + SoundStartup(); + loadtmb(); + + if (VOLUMEONE) { + if(numplayers > 4 || ud.multimode > 4) + gameexit(" The full version of Duke Nukem 3D supports 5 or more players."); + } + + setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0],0); + + // ESCESCAPE; + + FX_StopAllSounds(); + clearsoundlocks(); + + load_script("autoexec.cfg"); + + if(ud.warp_on > 1 && ud.multimode < 2) + { + clearview(0L); + //ps[myconnectindex].palette = palette; + //palto(0,0,0,0); + setgamepalette(&ps[myconnectindex], palette, 0); // JBF 20040308 + rotatesprite(320<<15,200<<15,65536L,0,LOADSCREEN,0,0,2+8+64,0,0,xdim-1,ydim-1); + menutext(160,105,0,0,"LOADING SAVED GAME..."); + nextpage(); + + j = loadplayer(ud.warp_on-2); + if(j) + ud.warp_on = 0; + } + + // getpackets(); + +MAIN_LOOP_RESTART: + + if(ud.warp_on == 0) + Logo(); + else if(ud.warp_on == 1) + { + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill); + + if (enterlevel(MODE_GAME)) backtomenu(); + } + else vscrn(); + /* + if(ud.warp_on == 0) + Logo(); + + MAIN_LOOP_RESTART: + + if(ud.warp_on == 1) + { + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill); + + if (enterlevel(MODE_GAME)) backtomenu(); + } + else if(ud.warp_on != 0) vscrn(); + */ + if( ud.warp_on == 0 && playback() ) + { + FX_StopAllSounds(); + clearsoundlocks(); + nomorelogohack = 1; + goto MAIN_LOOP_RESTART; + } + + ud.auto_run = RunMode; + ud.showweapons = ShowOpponentWeapons; + ps[myconnectindex].aim_mode = ud.mouseaiming; + ps[myconnectindex].auto_aim = AutoAim; + ps[myconnectindex].weaponswitch = ud.weaponswitch; + + ud.warp_on = 0; + KB_KeyDown[sc_Pause] = 0; // JBF: I hate the pause key + + while ( !(ps[myconnectindex].gm&MODE_END) ) //The whole loop!!!!!!!!!!!!!!!!!! + { + if (handleevents()) { // JBF + if (quitevent) { + KB_KeyDown[sc_Escape] = 1; + quitevent = 0; + } + } + + AudioUpdate(); + + OSD_DispatchQueued(); + + if( ud.recstat == 2 || ud.multimode > 1 || ( ud.show_help == 0 && (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU ) ) + if( ps[myconnectindex].gm&MODE_GAME ) + if( moveloop() ) continue; + + if( ps[myconnectindex].gm&MODE_EOL || ps[myconnectindex].gm&MODE_RESTART ) + { + if( ps[myconnectindex].gm&MODE_EOL && display_bonus_screen == 1) + { + closedemowrite(); + + ready2send = 0; + + i = ud.screen_size; + ud.screen_size = 0; + vscrn(); + ud.screen_size = i; + dobonus(0); + + if(ud.eog) + { + ud.eog = 0; + if(ud.multimode < 2) + { + if (!VOLUMEALL) { + doorders(); + } + ps[myconnectindex].gm = MODE_MENU; + cmenu(0); + probey = 0; + goto MAIN_LOOP_RESTART; + } + else + { + ud.m_level_number = 0; + ud.level_number = 0; + } + } + } + display_bonus_screen = 1; + ready2send = 0; + if(numplayers > 1) ps[myconnectindex].gm = MODE_GAME; + if (enterlevel(ps[myconnectindex].gm)) { + backtomenu(); + goto MAIN_LOOP_RESTART; + } + continue; + } + + cheats(); + nonsharedkeys(); + + if( (ud.show_help == 0 && ud.multimode < 2 && !(ps[myconnectindex].gm&MODE_MENU) ) || ud.multimode > 1 || ud.recstat == 2) + i = min(max((totalclock-ototalclock)*(65536L/TICSPERFRAME),0),65536); + else + i = 65536; + + displayrooms(screenpeek,i); + displayrest(i); + + // if( KB_KeyPressed(sc_F) ) + // { + // KB_ClearKeyDown(sc_F); + // addplayer(); + // } + + if(ps[myconnectindex].gm&MODE_DEMO) + goto MAIN_LOOP_RESTART; + + if(debug_on) caches(); + + checksync(); + + if (VOLUMEONE) { + if(ud.show_help == 0 && show_shareware > 0 && (ps[myconnectindex].gm&MODE_MENU) == 0 ) + rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1); + } + + nextpage(); + + while (!(ps[myconnectindex].gm&MODE_MENU) && ready2send && totalclock >= ototalclock+TICSPERFRAME) + faketimerhandler(); + } + + gameexit(" "); +} + +char opendemoread(char which_demo) // 0 = mine +{ + char d[13]; + char ver; + short i; + + strcpy(d, "demo_.dmo"); + + if(which_demo == 10) + d[4] = 'x'; + else + d[4] = '0' + which_demo; + + ud.reccnt = 0; + + if(which_demo == 1 && firstdemofile[0] != 0) + { + if ((recfilep = kopen4load(firstdemofile,loadfromgrouponly)) == -1) return(0); + } + else + if ((recfilep = kopen4load(d,loadfromgrouponly)) == -1) return(0); + + if (kread(recfilep,&ud.reccnt,sizeof(long)) != sizeof(long)) goto corrupt; + if (kread(recfilep,&ver,sizeof(char)) != sizeof(char)) goto corrupt; + if( (ver != BYTEVERSION) ) // || (ud.reccnt < 512) ) + { + if (ver == BYTEVERSION_JF) initprintf("Demo %s is for Regular edition.\n", d); + else if (ver == BYTEVERSION_JF+1) initprintf("Demo %s is for Atomic edition.\n", d); + else if (ver == BYTEVERSION_JF+2) initprintf("Demo %s is for Shareware version.\n", d); + else OSD_Printf("Demo %s is of an incompatible version (%d).\n", d, ver); + kclose(recfilep); + ud.reccnt=0; + return 0; + } + + if (kread(recfilep,(char *)&ud.volume_number,sizeof(char)) != sizeof(char)) goto corrupt; + if (kread(recfilep,(char *)&ud.level_number,sizeof(char)) != sizeof(char)) goto corrupt; + if (kread(recfilep,(char *)&ud.player_skill,sizeof(char)) != sizeof(char)) goto corrupt; + if (kread(recfilep,(char *)&ud.m_coop,sizeof(char)) != sizeof(char)) goto corrupt; + if (kread(recfilep,(char *)&ud.m_ffire,sizeof(char)) != sizeof(char)) goto corrupt; + if (kread(recfilep,(short *)&ud.multimode,sizeof(short)) != sizeof(short)) goto corrupt; + if (kread(recfilep,(short *)&ud.m_monsters_off,sizeof(short)) != sizeof(short)) goto corrupt; + if (kread(recfilep,(int32 *)&ud.m_respawn_monsters,sizeof(int32)) != sizeof(int32)) goto corrupt; + if (kread(recfilep,(int32 *)&ud.m_respawn_items,sizeof(int32)) != sizeof(int32)) goto corrupt; + if (kread(recfilep,(int32 *)&ud.m_respawn_inventory,sizeof(int32)) != sizeof(int32)) goto corrupt; + if (kread(recfilep,(int32 *)&ud.playerai,sizeof(int32)) != sizeof(int32)) goto corrupt; + if (kread(recfilep,(char *)&ud.user_name[0][0],sizeof(ud.user_name)) != sizeof(ud.user_name)) goto corrupt; + if (kread(recfilep,(int32 *)&ud.auto_run,sizeof(int32)) != sizeof(int32)) goto corrupt; + if (kread(recfilep,(char *)boardfilename,sizeof(boardfilename)) != sizeof(boardfilename)) goto corrupt; + if( boardfilename[0] != 0 ) + { + ud.m_level_number = 7; + ud.m_volume_number = 0; + } + + for(i=0;i=0;i=connectpoint2[i]) + { + copybufbyte(&sync[i],&recsync[ud.reccnt],sizeof(input)); + ud.reccnt++; + totalreccnt++; + if (ud.reccnt >= RECSYNCBUFSIZ) + { + dfwrite(recsync,sizeof(input)*ud.multimode,ud.reccnt/ud.multimode,frecfilep); + ud.reccnt = 0; + } + } +} + +void closedemowrite(void) +{ + if (ud.recstat == 1) + { + if (ud.reccnt > 0) + { + dfwrite(recsync,sizeof(input)*ud.multimode,ud.reccnt/ud.multimode,frecfilep); + + fseek(frecfilep,SEEK_SET,0L); + fwrite(&totalreccnt,sizeof(long),1,frecfilep); + ud.recstat = ud.m_recstat = 0; + } + fclose(frecfilep); + } +} + +char which_demo = 1; +char in_menu = 0; + +// extern long syncs[]; +long playback(void) +{ + long i,j,k,l,t,tc; + short p; + char foundemo; + + if( ready2send ) return 0; + + foundemo = 0; + +RECHECK: + + in_menu = ps[myconnectindex].gm&MODE_MENU; + + pub = NUMPAGES; + pus = NUMPAGES; + + flushperms(); + + if(numplayers < 2) foundemo = opendemoread(which_demo); + + if(foundemo == 0) + { + if(which_demo > 1) + { + which_demo = 1; + goto RECHECK; + } + fadepal(0,0,0, 0,63,7); + setgamepalette(&ps[myconnectindex], palette, 1); // JBF 20040308 + drawbackground(); + menus(); + //ps[myconnectindex].palette = palette; + nextpage(); + fadepal(0,0,0, 63,0,-7); + ud.reccnt = 0; + } + else + { + ud.recstat = 2; + which_demo++; + if(which_demo == 10) which_demo = 1; + if (enterlevel(MODE_DEMO)) return 1; + } + + if(foundemo == 0 || in_menu || KB_KeyWaiting() || numplayers > 1) + { + FX_StopAllSounds(); + clearsoundlocks(); + ps[myconnectindex].gm |= MODE_MENU; + } + + ready2send = 0; + i = 0; + + KB_FlushKeyboardQueue(); + + k = 0; + + while (ud.reccnt > 0 || foundemo == 0) + { + if(foundemo) while ( totalclock >= (lockclock+TICSPERFRAME) ) + { + if ((i == 0) || (i >= RECSYNCBUFSIZ)) + { + i = 0; + l = min(ud.reccnt,RECSYNCBUFSIZ); + if (kdfread(recsync,sizeof(input)*ud.multimode,l/ud.multimode,recfilep) != l/ud.multimode) { + OSD_Printf("Demo %d is corrupt.\n", which_demo-1); + foundemo = 0; + ud.reccnt = 0; + kclose(recfilep); + ps[myconnectindex].gm |= MODE_MENU; + break; + } + } + + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + copybufbyte(&recsync[i],&inputfifo[movefifoend[j]&(MOVEFIFOSIZ-1)][j],sizeof(input)); + movefifoend[j]++; + i++; + ud.reccnt--; + } + domovethings(); + } + + if(foundemo == 0) + drawbackground(); + else + { + nonsharedkeys(); + + j = min(max((totalclock-lockclock)*(65536/TICSPERFRAME),0),65536); + displayrooms(screenpeek,j); + displayrest(j); + + if(ud.multimode > 1 && ps[myconnectindex].gm ) + getpackets(); + } + + if( (ps[myconnectindex].gm&MODE_MENU) && (ps[myconnectindex].gm&MODE_EOL) ) + goto RECHECK; + + if (KB_KeyPressed(sc_Escape)) + { + KB_ClearKeyDown(sc_Escape); + FX_StopAllSounds(); + clearsoundlocks(); + ps[myconnectindex].gm |= MODE_MENU; + cmenu(0); + intomenusounds(); + } + + if(ps[myconnectindex].gm&MODE_TYPE) + { + typemode(); + if((ps[myconnectindex].gm&MODE_TYPE) != MODE_TYPE) + ps[myconnectindex].gm = MODE_MENU; + } + else + { + menus(); + if( ud.multimode > 1 ) + { + ControlInfo noshareinfo; + CONTROL_GetInput( &noshareinfo ); + if( BUTTON(gamefunc_SendMessage) ) + { + KB_FlushKeyboardQueue(); + CONTROL_ClearButton( gamefunc_SendMessage ); + ps[myconnectindex].gm = MODE_TYPE; + typebuf[0] = 0; + inputloc = 0; + } + } + } + + operatefta(); + + if(ud.last_camsprite != ud.camerasprite) + { + ud.last_camsprite = ud.camerasprite; + ud.camera_time = totalclock+(TICRATE*2); + } + + if (VOLUMEONE) { + if( ud.show_help == 0 && (ps[myconnectindex].gm&MODE_MENU) == 0 ) + rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1); + } + handleevents(); + getpackets(); + nextpage(); + + if( ps[myconnectindex].gm==MODE_END || ps[myconnectindex].gm==MODE_GAME ) + { + if(foundemo) + kclose(recfilep); + return 0; + } + } + kclose(recfilep); + +#if 0 + { + unsigned long crcv; + // sync checker + + initcrc32table(); + crc32init(&crcv); + crc32block(&crcv, (unsigned char *)wall, sizeof(wall)); + crc32block(&crcv, (unsigned char *)sector, sizeof(sector)); + crc32block(&crcv, (unsigned char *)sprite, sizeof(sprite)); + crc32finish(&crcv); + initprintf("Checksum = %08X\n",crcv); + } +#endif + + if(ps[myconnectindex].gm&MODE_MENU) goto RECHECK; + return 1; +} + +char moveloop() +{ + long i; + + if (numplayers > 1) + while (fakemovefifoplc < movefifoend[myconnectindex]) fakedomovethings(); + + getpackets(); + + if (numplayers < 2) bufferjitter = 0; + while (movefifoend[myconnectindex]-movefifoplc > bufferjitter) + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (movefifoplc == movefifoend[i]) break; + if (i >= 0) break; + if( domovethings() ) return 1; + } + return 0; +} + +void fakedomovethingscorrect(void) +{ + long i; + struct player_struct *p; + + if (numplayers < 2) return; + + i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); + p = &ps[myconnectindex]; + + if (p->posx == myxbak[i] && p->posy == myybak[i] && p->posz == myzbak[i] + && p->horiz == myhorizbak[i] && p->ang == myangbak[i]) return; + + myx = p->posx; omyx = p->oposx; myxvel = p->posxv; + myy = p->posy; omyy = p->oposy; myyvel = p->posyv; + myz = p->posz; omyz = p->oposz; myzvel = p->poszv; + myang = p->ang; omyang = p->oang; + mycursectnum = p->cursectnum; + myhoriz = p->horiz; omyhoriz = p->ohoriz; + myhorizoff = p->horizoff; omyhorizoff = p->ohorizoff; + myjumpingcounter = p->jumping_counter; + myjumpingtoggle = p->jumping_toggle; + myonground = p->on_ground; + myhardlanding = p->hard_landing; + myreturntocenter = p->return_to_center; + + fakemovefifoplc = movefifoplc; + while (fakemovefifoplc < movefifoend[myconnectindex]) + fakedomovethings(); + +} + +void fakedomovethings(void) +{ + input *syn; + struct player_struct *p; + long i, j, k, doubvel, fz, cz, hz, lz, x, y; + unsigned long sb_snum; + short psect, psectlotag, tempsect, backcstat; + char shrunk, spritebridge; + + syn = (input *)&inputfifo[fakemovefifoplc&(MOVEFIFOSIZ-1)][myconnectindex]; + + p = &ps[myconnectindex]; + + backcstat = sprite[p->i].cstat; + sprite[p->i].cstat &= ~257; + + sb_snum = syn->bits; + + psect = mycursectnum; + psectlotag = sector[psect].lotag; + spritebridge = 0; + + shrunk = (sprite[p->i].yrepeat < 32); + + if( ud.clipping == 0 && ( sector[psect].floorpicnum == MIRROR || psect < 0 || psect >= MAXSECTORS) ) + { + myx = omyx; + myy = omyy; + } + else + { + omyx = myx; + omyy = myy; + } + + omyhoriz = myhoriz; + omyhorizoff = myhorizoff; + omyz = myz; + omyang = myang; + + getzrange(myx,myy,myz,psect,&cz,&hz,&fz,&lz,163L,CLIPMASK0); + + j = getflorzofslope(psect,myx,myy); + + if( (lz&49152) == 16384 && psectlotag == 1 && klabs(myz-j) > PHEIGHT+(16<<8) ) + psectlotag = 0; + + if( p->aim_mode == 0 && myonground && psectlotag != 2 && (sector[psect].floorstat&2) ) + { + x = myx+(sintable[(myang+512)&2047]>>5); + y = myy+(sintable[myang&2047]>>5); + tempsect = psect; + updatesector(x,y,&tempsect); + if (tempsect >= 0) + { + k = getflorzofslope(psect,x,y); + if (psect == tempsect) + myhorizoff += mulscale16(j-k,160); + else if (klabs(getflorzofslope(tempsect,x,y)-k) <= (4<<8)) + myhorizoff += mulscale16(j-k,160); + } + } + if (myhorizoff > 0) myhorizoff -= ((myhorizoff>>3)+1); + else if (myhorizoff < 0) myhorizoff += (((-myhorizoff)>>3)+1); + + if(hz >= 0 && (hz&49152) == 49152) + { + hz &= (MAXSPRITES-1); + if (sprite[hz].statnum == 1 && sprite[hz].extra >= 0) + { + hz = 0; + cz = getceilzofslope(psect,myx,myy); + } + } + + if(lz >= 0 && (lz&49152) == 49152) + { + j = lz&(MAXSPRITES-1); + if ((sprite[j].cstat&33) == 33) + { + psectlotag = 0; + spritebridge = 1; + } + if(badguy(&sprite[j]) && sprite[j].xrepeat > 24 && klabs(sprite[p->i].z-sprite[j].z) < (84<<8) ) + { + j = getangle( sprite[j].x-myx,sprite[j].y-myy); + myxvel -= sintable[(j+512)&2047]<<4; + myyvel -= sintable[j&2047]<<4; + } + } + + if( sprite[p->i].extra <= 0 ) + { + if( psectlotag == 2 ) + { + if(p->on_warping_sector == 0) + { + if( klabs(myz-fz) > (PHEIGHT>>1)) + myz += 348; + } + clipmove(&myx,&myy,&myz,&mycursectnum,0,0,164L,(4L<<8),(4L<<8),CLIPMASK0); + } + + updatesector(myx,myy,&mycursectnum); + pushmove(&myx,&myy,&myz,&mycursectnum,128L,(4L<<8),(20L<<8),CLIPMASK0); + + myhoriz = 100; + myhorizoff = 0; + + goto ENDFAKEPROCESSINPUT; + } + + doubvel = TICSPERFRAME; + + if(p->on_crane >= 0) goto FAKEHORIZONLY; + + if(p->one_eighty_count < 0) myang += 128; + + i = 40; + + if( psectlotag == 2) + { + myjumpingcounter = 0; + + if ( sb_snum&1 ) + { + if(myzvel > 0) myzvel = 0; + myzvel -= 348; + if(myzvel < -(256*6)) myzvel = -(256*6); + } + else if (sb_snum&(1<<1)) + { + if(myzvel < 0) myzvel = 0; + myzvel += 348; + if(myzvel > (256*6)) myzvel = (256*6); + } + else + { + if(myzvel < 0) + { + myzvel += 256; + if(myzvel > 0) + myzvel = 0; + } + if(myzvel > 0) + { + myzvel -= 256; + if(myzvel < 0) + myzvel = 0; + } + } + + if(myzvel > 2048) myzvel >>= 1; + + myz += myzvel; + + if(myz > (fz-(15<<8)) ) + myz += ((fz-(15<<8))-myz)>>1; + + if(myz < (cz+(4<<8)) ) + { + myz = cz+(4<<8); + myzvel = 0; + } + } + + else if(p->jetpack_on) + { + myonground = 0; + myjumpingcounter = 0; + myhardlanding = 0; + + if(p->jetpack_on < 11) + myz -= (p->jetpack_on<<7); //Goin up + + if(shrunk) j = 512; + else j = 2048; + + if (sb_snum&1) //A + myz -= j; + if (sb_snum&(1<<1)) //Z + myz += j; + + if(shrunk == 0 && ( psectlotag == 0 || psectlotag == 2 ) ) k = 32; + else k = 16; + + if(myz > (fz-(k<<8)) ) + myz += ((fz-(k<<8))-myz)>>1; + if(myz < (cz+(18<<8)) ) + myz = cz+(18<<8); + } + else if( psectlotag != 2 ) + { + if (psectlotag == 1 && p->spritebridge == 0) + { + if(shrunk == 0) i = 34; + else i = 12; + } + if(myz < (fz-(i<<8)) && (floorspace(psect)|ceilingspace(psect)) == 0 ) //falling + { + if( (sb_snum&3) == 0 && myonground && (sector[psect].floorstat&2) && myz >= (fz-(i<<8)-(16<<8) ) ) + myz = fz-(i<<8); + else + { + myonground = 0; + + myzvel += (gc+80); + + if(myzvel >= (4096+2048)) myzvel = (4096+2048); + } + } + + else + { + if(psectlotag != 1 && psectlotag != 2 && myonground == 0 && myzvel > (6144>>1)) + myhardlanding = myzvel>>10; + myonground = 1; + + if(i==40) + { + //Smooth on the ground + + k = ((fz-(i<<8))-myz)>>1; + if( klabs(k) < 256 ) k = 0; + myz += k; // ((fz-(i<<8))-myz)>>1; + myzvel -= 768; // 412; + if(myzvel < 0) myzvel = 0; + } + else if(myjumpingcounter == 0) + { + myz += ((fz-(i<<7))-myz)>>1; //Smooth on the water + if(p->on_warping_sector == 0 && myz > fz-(16<<8)) + { + myz = fz-(16<<8); + myzvel >>= 1; + } + } + + if( sb_snum&2 ) + myz += (2048+768); + + if( (sb_snum&1) == 0 && myjumpingtoggle == 1) + myjumpingtoggle = 0; + + else if( (sb_snum&1) && myjumpingtoggle == 0 ) + { + if( myjumpingcounter == 0 ) + if( (fz-cz) > (56<<8) ) + { + myjumpingcounter = 1; + myjumpingtoggle = 1; + } + } + if( myjumpingcounter && (sb_snum&1) == 0 ) + myjumpingcounter = 0; + } + + if(myjumpingcounter) + { + if( (sb_snum&1) == 0 && myjumpingtoggle == 1) + myjumpingtoggle = 0; + + if( myjumpingcounter < (1024+256) ) + { + if(psectlotag == 1 && myjumpingcounter > 768) + { + myjumpingcounter = 0; + myzvel = -512; + } + else + { + myzvel -= (sintable[(2048-128+myjumpingcounter)&2047])/12; + myjumpingcounter += 180; + + myonground = 0; + } + } + else + { + myjumpingcounter = 0; + myzvel = 0; + } + } + + myz += myzvel; + + if(myz < (cz+(4<<8)) ) + { + myjumpingcounter = 0; + if(myzvel < 0) myxvel = myyvel = 0; + myzvel = 128; + myz = cz+(4<<8); + } + + } + + if ( p->fist_incs || + p->transporter_hold > 2 || + myhardlanding || + p->access_incs > 0 || + p->knee_incs > 0 || + (p->curr_weapon == TRIPBOMB_WEAPON && + p->kickback_pic > 1 && + p->kickback_pic < 4 ) ) + { + doubvel = 0; + myxvel = 0; + myyvel = 0; + } + else if ( syn->avel ) //p->ang += syncangvel * constant + { //ENGINE calculates angvel for you + long tempang; + + tempang = syn->avel<<1; + + if(psectlotag == 2) + myang += (tempang-(tempang>>3))*ksgn(doubvel); + else myang += (tempang)*ksgn(doubvel); + myang &= 2047; + } + + if ( myxvel || myyvel || syn->fvel || syn->svel ) + { + if(p->steroids_amount > 0 && p->steroids_amount < 400) + doubvel <<= 1; + + myxvel += ((syn->fvel*doubvel)<<6); + myyvel += ((syn->svel*doubvel)<<6); + + if( ( p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && myonground ) || ( myonground && (sb_snum&2) ) ) + { + myxvel = mulscale16(myxvel,p->runspeed-0x2000); + myyvel = mulscale16(myyvel,p->runspeed-0x2000); + } + else + { + if(psectlotag == 2) + { + myxvel = mulscale16(myxvel,p->runspeed-0x1400); + myyvel = mulscale16(myyvel,p->runspeed-0x1400); + } + else + { + myxvel = mulscale16(myxvel,p->runspeed); + myyvel = mulscale16(myyvel,p->runspeed); + } + } + + if( abs(myxvel) < 2048 && abs(myyvel) < 2048 ) + myxvel = myyvel = 0; + + if( shrunk ) + { + myxvel = + mulscale16(myxvel,(p->runspeed)-(p->runspeed>>1)+(p->runspeed>>2)); + myyvel = + mulscale16(myyvel,(p->runspeed)-(p->runspeed>>1)+(p->runspeed>>2)); + } + } + +FAKEHORIZONLY: + if(psectlotag == 1 || spritebridge == 1) i = (4L<<8); else i = (20L<<8); + + clipmove(&myx,&myy,&myz,&mycursectnum,myxvel,myyvel,164L,4L<<8,i,CLIPMASK0); + pushmove(&myx,&myy,&myz,&mycursectnum,164L,4L<<8,4L<<8,CLIPMASK0); + + if( p->jetpack_on == 0 && psectlotag != 1 && psectlotag != 2 && shrunk) + myz += 30<<8; + + if ((sb_snum&(1<<18)) || myhardlanding) + myreturntocenter = 9; + + if (sb_snum&(1<<13)) + { + myreturntocenter = 9; + if (sb_snum&(1<<5)) myhoriz += 6; + myhoriz += 6; + } + else if (sb_snum&(1<<14)) + { + myreturntocenter = 9; + if (sb_snum&(1<<5)) myhoriz -= 6; + myhoriz -= 6; + } + else if (sb_snum&(1<<3)) + { + if (sb_snum&(1<<5)) myhoriz += 6; + myhoriz += 6; + } + else if (sb_snum&(1<<4)) + { + if (sb_snum&(1<<5)) myhoriz -= 6; + myhoriz -= 6; + } + + if (myreturntocenter > 0) + if ((sb_snum&(1<<13)) == 0 && (sb_snum&(1<<14)) == 0) + { + myreturntocenter--; + myhoriz += 33-(myhoriz/3); + } + + if(p->aim_mode) + myhoriz += syn->horz>>1; + else + { + if( myhoriz > 95 && myhoriz < 105) myhoriz = 100; + if( myhorizoff > -5 && myhorizoff < 5) myhorizoff = 0; + } + + if (myhardlanding > 0) + { + myhardlanding--; + myhoriz -= (myhardlanding<<4); + } + + if (myhoriz > 299) myhoriz = 299; + else if (myhoriz < -99) myhoriz = -99; + + if(p->knee_incs > 0) + { + myhoriz -= 48; + myreturntocenter = 9; + } + + +ENDFAKEPROCESSINPUT: + + myxbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myx; + myybak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myy; + myzbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myz; + myangbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myang; + myhorizbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myhoriz; + fakemovefifoplc++; + + sprite[p->i].cstat = backcstat; +} + +char domovethings(void) +{ + short i, j, k; + char ch; + + long p; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if( sync[i].bits&(1<<17) ) + { + multiflag = 2; + multiwhat = (sync[i].bits>>18)&1; + multipos = (unsigned) (sync[i].bits>>19)&15; + multiwho = i; + + if( multiwhat ) + { + saveplayer( multipos ); + multiflag = 0; + + if(multiwho != myconnectindex) + { + strcpy(fta_quotes[122],&ud.user_name[multiwho][0]); + strcat(fta_quotes[122]," SAVED A MULTIPLAYER GAME"); + FTA(122,&ps[myconnectindex]); + } + else + { + strcpy(fta_quotes[122],"MULTIPLAYER GAME SAVED"); + FTA(122,&ps[myconnectindex]); + } + break; + } + else + { + // waitforeverybody(); + + j = loadplayer( multipos ); + + multiflag = 0; + + if(j == 0) + { + if(multiwho != myconnectindex) + { + strcpy(fta_quotes[122],&ud.user_name[multiwho][0]); + strcat(fta_quotes[122]," LOADED A MULTIPLAYER GAME"); + FTA(122,&ps[myconnectindex]); + } + else + { + strcpy(fta_quotes[122],"MULTIPLAYER GAME LOADED"); + FTA(122,&ps[myconnectindex]); + } + return 1; + } + } + } + + ud.camerasprite = -1; + lockclock += TICSPERFRAME; + + if(earthquaketime > 0) earthquaketime--; + if(rtsplaying > 0) rtsplaying--; + + for(i=0;i 0 ) + { + show_shareware--; + if(show_shareware == 0) + { + pus = NUMPAGES; + pub = NUMPAGES; + } + } + + everyothertime++; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + copybufbyte(&inputfifo[movefifoplc&(MOVEFIFOSIZ-1)][i],&sync[i],sizeof(input)); + movefifoplc++; + + updateinterpolations(); + + j = -1; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if ((sync[i].bits&(1<<26)) == 0) { j = i; continue; } + + closedemowrite(); + + if (i == myconnectindex) gameexit(" "); + if (screenpeek == i) + { + screenpeek = connectpoint2[i]; + if (screenpeek < 0) screenpeek = connecthead; + } + + if (i == connecthead) connecthead = connectpoint2[connecthead]; + else connectpoint2[j] = connectpoint2[i]; + + numplayers--; + ud.multimode--; + + if (numplayers < 2) + sound(GENERIC_AMBIENCE17); + + pub = NUMPAGES; + pus = NUMPAGES; + vscrn(); + + Bsprintf(buf,"%s is history!",ud.user_name[i]); + + quickkill(&ps[i]); + deletesprite(ps[i].i); + + adduserquote(buf); + + if(j < 0 && networkmode == 0 ) + gameexit( " \nThe 'MASTER/First player' just quit the game. All\nplayers are returned from the game. This only happens in 5-8\nplayer mode as a different network scheme is used."); + } + + if ((numplayers >= 2) && ((movefifoplc&7) == 7)) + { + ch = (char)(randomseed&255); + for(i=connecthead;i>=0;i=connectpoint2[i]) + ch += ((ps[i].posx+ps[i].posy+ps[i].posz+ps[i].ang+ps[i].horiz)&255); + syncval[myconnectindex][syncvalhead[myconnectindex]&(MOVEFIFOSIZ-1)] = ch; + syncvalhead[myconnectindex]++; + } + + if(ud.recstat == 1) record(); + + if( ud.pause_on == 0 ) + { + global_random = TRAND; + movedummyplayers();//ST 13 + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + cheatkeys(i); + + if( ud.pause_on == 0 ) + { + processinput(i); + checksectors(i); + } + } + + if( ud.pause_on == 0 ) + { + + movefta(); //ST 2 + moveweapons(); //ST 5 (must be last) + movetransports(); //ST 9 + + moveplayers(); //ST 10 + movefallers(); //ST 12 + moveexplosions(); //ST 4 + + moveactors(); //ST 1 + moveeffectors(); //ST 3 + + movestandables(); //ST 6 + + for (k=0;k= 0) + { + j = nextspritestat[i]; + OnEvent(EVENT_GAME,i, findplayer(&sprite[i],&p), p); + i = j; + } + } + + doanimations(); + movefx(); //ST 11 + } + + fakedomovethingscorrect(); + + if( (everyothertime&1) == 0) + { + animatewalls(); + movecyclers(); + pan3dsound(); + } + return 0; +} + +void doorders(void) +{ + short i; + + setview(0,0,xdim-1,ydim-1); + + fadepal(0,0,0, 0,63,7); + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 1); // JBF 20040308 + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,ORDERING,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + fadepal(0,0,0, 63,0,-7); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + + fadepal(0,0,0, 0,63,7); + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,ORDERING+1,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + fadepal(0,0,0, 63,0,-7); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + + fadepal(0,0,0, 0,63,7); + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,ORDERING+2,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + fadepal(0,0,0, 63,0,-7); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + + fadepal(0,0,0, 0,63,7); + KB_FlushKeyboardQueue(); + rotatesprite(0,0,65536L,0,ORDERING+3,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + fadepal(0,0,0, 63,0,-7); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } +} + +void dobonus(char bonusonly) +{ + short t, r, tinc,gfx_offset; + long i, y,xfragtotal,yfragtotal; + short bonuscnt; + int clockpad = 2; + char *lastmapname; + long breathe[] = + { + 0, 30,VICTORY1+1,176,59, + 30, 60,VICTORY1+2,176,59, + 60, 90,VICTORY1+1,176,59, + 90, 120,0 ,176,59 + }; + + long bossmove[] = + { + 0, 120,VICTORY1+3,86,59, + 220, 260,VICTORY1+4,86,59, + 260, 290,VICTORY1+5,86,59, + 290, 320,VICTORY1+6,86,59, + 320, 350,VICTORY1+7,86,59, + 350, 380,VICTORY1+8,86,59 + }; + + if (ud.volume_number == 0 && ud.last_level == 8 && boardfilename[0]) { + lastmapname = Bstrrchr(boardfilename,'\\'); + if (!lastmapname) lastmapname = Bstrrchr(boardfilename,'/'); + if (!lastmapname) lastmapname = boardfilename; + } else lastmapname = level_names[(ud.volume_number*11)+ud.last_level-1]; + + bonuscnt = 0; + + fadepal(0,0,0, 0,64,7); + setview(0,0,xdim-1,ydim-1); + clearview(0L); + nextpage(); + flushperms(); + + FX_StopAllSounds(); + clearsoundlocks(); + FX_SetReverb(0L); + + if(bonusonly) goto FRAGBONUS; + + if(numplayers < 2 && ud.eog && ud.from_bonus == 0) + switch(ud.volume_number) + { + case 0: + if(ud.lockout == 0) + { + setgamepalette(&ps[myconnectindex], endingpal, 3); // JBF 20040308 + clearview(0L); + rotatesprite(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + nextpage(); + //ps[myconnectindex].palette = endingpal; + fadepal(0,0,0, 63,0,-1); + + KB_FlushKeyboardQueue(); + totalclock = 0; tinc = 0; + while( 1 ) + { + clearview(0L); + rotatesprite(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + + // boss + if( totalclock > 390 && totalclock < 780 ) + for(t=0;t<35;t+=5) if( bossmove[t+2] && (totalclock%390) > bossmove[t] && (totalclock%390) <= bossmove[t+1] ) + { + if(t==10 && bonuscnt == 1) { sound(SHOTGUN_FIRE);sound(SQUISHED); bonuscnt++; } + rotatesprite(bossmove[t+3]<<16,bossmove[t+4]<<16,65536L,0,bossmove[t+2],0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + } + + // Breathe + if( totalclock < 450 || totalclock >= 750 ) + { + if(totalclock >= 750) + { + rotatesprite(86<<16,59<<16,65536L,0,VICTORY1+8,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + if(totalclock >= 750 && bonuscnt == 2) { sound(DUKETALKTOBOSS); bonuscnt++; } + } + for(t=0;t<20;t+=5) + if( breathe[t+2] && (totalclock%120) > breathe[t] && (totalclock%120) <= breathe[t+1] ) + { + if(t==5 && bonuscnt == 0) + { + sound(BOSSTALKTODUKE); + bonuscnt++; + } + rotatesprite(breathe[t+3]<<16,breathe[t+4]<<16,65536L,0,breathe[t+2],0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + } + } + handleevents(); + getpackets(); + nextpage(); + if( KB_KeyWaiting() ) break; + } + } + + fadepal(0,0,0, 0,64,1); + + KB_FlushKeyboardQueue(); + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 3); // JBF 20040308 + + rotatesprite(0,0,65536L,0,3292,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + IFISSOFTMODE fadepal(0,0,0, 63,0,-1); else nextpage(); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + fadepal(0,0,0, 0,64,1); + MUSIC_StopSong(); + FX_StopAllSounds(); + clearsoundlocks(); + break; + case 1: + MUSIC_StopSong(); + clearview(0L); + nextpage(); + + if(ud.lockout == 0) + { + playanm("cineov2.anm",1); + KB_FlushKeyBoardQueue(); + clearview(0L); + nextpage(); + } + + sound(PIPEBOMB_EXPLODE); + + fadepal(0,0,0, 0,64,1); + setview(0,0,xdim-1,ydim-1); + KB_FlushKeyboardQueue(); + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 3); // JBF 20040308 + rotatesprite(0,0,65536L,0,3293,0,0,2+8+16+64, 0,0,xdim-1,ydim-1); + IFISSOFTMODE fadepal(0,0,0, 63,0,-1); else nextpage(); + while( !KB_KeyWaiting() ) { handleevents(); getpackets(); } + IFISSOFTMODE fadepal(0,0,0, 0,64,1); + + break; + + case 3: + + setview(0,0,xdim-1,ydim-1); + + MUSIC_StopSong(); + clearview(0L); + nextpage(); + + if(ud.lockout == 0) + { + KB_FlushKeyboardQueue(); + playanm("vol4e1.anm",8); + clearview(0L); + nextpage(); + playanm("vol4e2.anm",10); + clearview(0L); + nextpage(); + playanm("vol4e3.anm",11); + clearview(0L); + nextpage(); + } + + FX_StopAllSounds(); + clearsoundlocks(); + sound(ENDSEQVOL3SND4); + KB_FlushKeyBoardQueue(); + + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 3); // JBF 20040308 + IFISSOFTMODE palto(0,0,0,63); + clearview(0L); + menutext(160,60,0,0,"THANKS TO ALL OUR"); + menutext(160,60+16,0,0,"FANS FOR GIVING"); + menutext(160,60+16+16,0,0,"US BIG HEADS."); + menutext(160,70+16+16+16,0,0,"LOOK FOR A DUKE NUKEM 3D"); + menutext(160,70+16+16+16+16,0,0,"SEQUEL SOON."); + nextpage(); + + fadepal(0,0,0, 63,0,-3); + KB_FlushKeyboardQueue(); + while(!KB_KeyWaiting()) { handleevents(); getpackets(); } + fadepal(0,0,0, 0,64,3); + + clearview(0L); + nextpage(); + + playanm("DUKETEAM.ANM",4); + + KB_FlushKeyBoardQueue(); + while(!KB_KeyWaiting()) { handleevents(); getpackets(); } + + clearview(0L); + nextpage(); + IFISSOFTMODE palto(0,0,0,63); + + FX_StopAllSounds(); + clearsoundlocks(); + KB_FlushKeyBoardQueue(); + + break; + + case 2: + + MUSIC_StopSong(); + clearview(0L); + nextpage(); + if(ud.lockout == 0) + { + fadepal(0,0,0, 63,0,-1); + playanm("cineov3.anm",2); + KB_FlushKeyBoardQueue(); + ototalclock = totalclock+200; + while(totalclock < ototalclock) { handleevents(); getpackets(); } + clearview(0L); + nextpage(); + + FX_StopAllSounds(); + clearsoundlocks(); + } + + playanm("RADLOGO.ANM",3); + + if( ud.lockout == 0 && !KB_KeyWaiting() ) + { + sound(ENDSEQVOL3SND5); + while(issoundplaying(ENDSEQVOL3SND5)) { handleevents(); getpackets(); } + if(KB_KeyWaiting()) goto ENDANM; + sound(ENDSEQVOL3SND6); + while(issoundplaying(ENDSEQVOL3SND6)) { handleevents(); getpackets(); } + if(KB_KeyWaiting()) goto ENDANM; + sound(ENDSEQVOL3SND7); + while(issoundplaying(ENDSEQVOL3SND7)) { handleevents(); getpackets(); } + if(KB_KeyWaiting()) goto ENDANM; + sound(ENDSEQVOL3SND8); + while(issoundplaying(ENDSEQVOL3SND8)) { handleevents(); getpackets(); } + if(KB_KeyWaiting()) goto ENDANM; + sound(ENDSEQVOL3SND9); + while(issoundplaying(ENDSEQVOL3SND9)) { handleevents(); getpackets(); } + } + + KB_FlushKeyBoardQueue(); + totalclock = 0; + while(!KB_KeyWaiting() && totalclock < 120) { handleevents(); getpackets(); } + +ENDANM: + + FX_StopAllSounds(); + clearsoundlocks(); + + KB_FlushKeyBoardQueue(); + + clearview(0L); + + break; + } + +FRAGBONUS: + + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 3); // JBF 20040308 + IFISSOFTMODE palto(0,0,0,63); // JBF 20031228 + KB_FlushKeyboardQueue(); + totalclock = 0; tinc = 0; + bonuscnt = 0; + + MUSIC_StopSong(); + FX_StopAllSounds(); + clearsoundlocks(); + + if(playerswhenstarted > 1 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_SCORESHEET)) + { + if(!(MusicToggle == 0 || MusicDevice < 0)) + sound(BONUSMUSIC); + + rotatesprite(0,0,65536L,0,MENUSCREEN,16,0,2+8+16+64,0,0,xdim-1,ydim-1); + rotatesprite(160<<16,34<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1); + if (PLUTOPAK) // JBF 20030804 + rotatesprite((260)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,0,0,2+8,0,0,xdim-1,ydim-1); + gametext(160,58+2,"MULTIPLAYER TOTALS",0,2+8+16); + gametext(160,58+10,level_names[(ud.volume_number*11)+ud.last_level-1],0,2+8+16); + + gametext(160,165,"PRESS ANY KEY TO CONTINUE",0,2+8+16); + + + t = 0; + minitext(23,80," NAME KILLS",8,2+8+16+128); + for(i=0;i 1) return; + + fadepal(0,0,0, 0,64,7); + } + + if(bonusonly || ud.multimode > 1) return; + + switch(ud.volume_number) + { + case 1: + gfx_offset = 5; + break; + default: + gfx_offset = 0; + break; + } + + rotatesprite(0,0,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + + menutext(160,20-6,0,0,lastmapname); + menutext(160,36-6,0,0,"COMPLETED"); + + gametext(160,192,"PRESS ANY KEY TO CONTINUE",16,2+8+16); + + if(!(MusicToggle == 0 || MusicDevice < 0)) + sound(BONUSMUSIC); + + nextpage(); + KB_FlushKeyboardQueue(); + fadepal(0,0,0, 63,0,-1); + bonuscnt = 0; + totalclock = 0; tinc = 0; + + { + int ii, ij; + + for (ii=ps[myconnectindex].player_par/(26*60), ij=1; ii>9; ii/=10, ij++) ; + clockpad = max(clockpad,ij); + for (ii=partime[ud.volume_number*11+ud.last_level-1]/(26*60), ij=1; ii>9; ii/=10, ij++) ; + clockpad = max(clockpad,ij); + for (ii=designertime[ud.volume_number*11+ud.last_level-1]/(26*60), ij=1; ii>9; ii/=10, ij++) ; + clockpad = max(clockpad,ij); + } + + while( 1 ) + { + handleevents(); + AudioUpdate(); + + if(ps[myconnectindex].gm&MODE_EOL) + { + rotatesprite(0,0,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + + if( totalclock > (1000000000L) && totalclock < (1000000320L) ) + { + switch( (totalclock>>4)%15 ) + { + case 0: + if(bonuscnt == 6) + { + bonuscnt++; + sound(SHOTGUN_COCK); + switch(rand()&3) + { + case 0: + sound(BONUS_SPEECH1); + break; + case 1: + sound(BONUS_SPEECH2); + break; + case 2: + sound(BONUS_SPEECH3); + break; + case 3: + sound(BONUS_SPEECH4); + break; + } + } + case 1: + case 4: + case 5: + rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+3+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + break; + case 2: + case 3: + rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+4+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + break; + } + } + else if( totalclock > (10240+120L) ) break; + else + { + switch( (totalclock>>5)&3 ) + { + case 1: + case 3: + rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+1+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + break; + case 2: + rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+2+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1); + break; + } + } + + menutext(160,20-6,0,0,lastmapname); + menutext(160,36-6,0,0,"COMPLETED"); + + gametext(160,192,"PRESS ANY KEY TO CONTINUE",16,2+8+16); + + if( totalclock > (60*3) ) + { + gametext(10,59+9,"Your Time:",0,2+8+16); + gametext(10,69+9,"Par time:",0,2+8+16); + gametext(10,78+9,"3D Realms' Time:",0,2+8+16); + if(bonuscnt == 0) + bonuscnt++; + + if( totalclock > (60*4) ) + { + if(bonuscnt == 1) + { + bonuscnt++; + sound(PIPEBOMB_EXPLODE); + } + + Bsprintf(tempbuf,"%0*ld:%02ld",clockpad, + (ps[myconnectindex].player_par/(26*60)), + (ps[myconnectindex].player_par/26)%60); + gametext((320>>2)+71,60+9,tempbuf,0,2+8+16); + + Bsprintf(tempbuf,"%0*ld:%02ld",clockpad, + (partime[ud.volume_number*11+ud.last_level-1]/(26*60)), + (partime[ud.volume_number*11+ud.last_level-1]/26)%60); + gametext((320>>2)+71,69+9,tempbuf,0,2+8+16); + + Bsprintf(tempbuf,"%0*ld:%02ld",clockpad, + (designertime[ud.volume_number*11+ud.last_level-1]/(26*60)), + (designertime[ud.volume_number*11+ud.last_level-1]/26)%60); + gametext((320>>2)+71,78+9,tempbuf,0,2+8+16); + + } + } + if( totalclock > (60*6) ) + { + gametext(10,94+9,"Enemies Killed:",0,2+8+16); + gametext(10,99+4+9,"Enemies Left:",0,2+8+16); + + if(bonuscnt == 2) + { + bonuscnt++; + sound(FLY_BY); + } + + if( totalclock > (60*7) ) + { + if(bonuscnt == 3) + { + bonuscnt++; + sound(PIPEBOMB_EXPLODE); + } + Bsprintf(tempbuf,"%-3ld",ps[myconnectindex].actors_killed); + gametext((320>>2)+70,93+9,tempbuf,0,2+8+16); + if(ud.player_skill > 3 ) + { + Bsprintf(tempbuf,"N/A"); + gametext((320>>2)+70,99+4+9,tempbuf,0,2+8+16); + } + else + { + if( (ps[myconnectindex].max_actors_killed-ps[myconnectindex].actors_killed) < 0 ) + Bsprintf(tempbuf,"%-3d",0); + else Bsprintf(tempbuf,"%-3ld",ps[myconnectindex].max_actors_killed-ps[myconnectindex].actors_killed); + gametext((320>>2)+70,99+4+9,tempbuf,0,2+8+16); + } + } + } + if( totalclock > (60*9) ) + { + gametext(10,120+9,"Secrets Found:",0,2+8+16); + gametext(10,130+9,"Secrets Missed:",0,2+8+16); + if(bonuscnt == 4) bonuscnt++; + + if( totalclock > (60*10) ) + { + if(bonuscnt == 5) + { + bonuscnt++; + sound(PIPEBOMB_EXPLODE); + } + Bsprintf(tempbuf,"%-3ld",ps[myconnectindex].secret_rooms); + gametext((320>>2)+70,120+9,tempbuf,0,2+8+16); + if( ps[myconnectindex].secret_rooms > 0 ) + Bsprintf(tempbuf,"%-3ld%%",(100*ps[myconnectindex].secret_rooms/ps[myconnectindex].max_secret_rooms)); + Bsprintf(tempbuf,"%-3ld",ps[myconnectindex].max_secret_rooms-ps[myconnectindex].secret_rooms); + gametext((320>>2)+70,130+9,tempbuf,0,2+8+16); + } + } + + if(totalclock > 10240 && totalclock < 10240+10240) + totalclock = 1024; + + if( ( (MOUSE_GetButtons()&7) || KB_KeyWaiting() ) && totalclock > (60*2) ) // JBF 20030809 + { + MOUSE_ClearButton(7); + if( KB_KeyPressed( sc_F12 ) ) + { + KB_ClearKeyDown( sc_F12 ); + screencapture("eduke0000.tga",0); + } + + if( totalclock < (60*13) ) + { + KB_FlushKeyboardQueue(); + totalclock = (60*13); + } + else if( totalclock < (1000000000L)) + totalclock = (1000000000L); + } + } + else break; + nextpage(); + } +} + +void cameratext(short i) +{ + char flipbits; + long x , y; + + if(!T1) + { + rotatesprite(24<<16,33<<16,65536L,0,CAMCORNER,0,0,2,windowx1,windowy1,windowx2,windowy2); + rotatesprite((320-26)<<16,34<<16,65536L,0,CAMCORNER+1,0,0,2,windowx1,windowy1,windowx2,windowy2); + rotatesprite(22<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2+4,windowx1,windowy1,windowx2,windowy2); + rotatesprite((310-10)<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2,windowx1,windowy1,windowx2,windowy2); + if(totalclock&16) + rotatesprite(46<<16,32<<16,65536L,0,CAMLIGHT,0,0,2,windowx1,windowy1,windowx2,windowy2); + } + else + { + flipbits = (totalclock<<1)&48; + for(x=0;x<394;x+=64) + for(y=0;y<200;y+=64) + rotatesprite(x<<16,y<<16,65536L,0,STATIC,0,0,2+flipbits,windowx1,windowy1,windowx2,windowy2); + } +} + +void vglass(long x,long y,short a,short wn,short n) +{ + long z, zincs; + short sect; + + sect = wall[wn].nextsector; + if(sect == -1) return; + zincs = ( sector[sect].floorz-sector[sect].ceilingz ) / n; + + for(z = sector[sect].ceilingz;z < sector[sect].floorz; z += zincs ) + EGS(sect,x,y,z-(TRAND&8191),GLASSPIECES+(z&(TRAND%3)),-32,36,36,a+128-(TRAND&255),16+(TRAND&31),0,-1,5); +} + +void lotsofglass(short i,short wallnum,short n) +{ + long j, xv, yv, z, x1, y1; + short sect, a; + + sect = -1; + + if(wallnum < 0) + { + for(j=n-1; j >= 0 ;j--) + { + a = SA-256+(TRAND&511)+1024; + EGS(SECT,SX,SY,SZ,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),1024-(TRAND&1023),i,5); + } + return; + } + + j = n+1; + + x1 = wall[wallnum].x; + y1 = wall[wallnum].y; + + xv = wall[wall[wallnum].point2].x-x1; + yv = wall[wall[wallnum].point2].y-y1; + + x1 -= ksgn(yv); + y1 += ksgn(xv); + + xv /= j; + yv /= j; + + for(j=n;j>0;j--) + { + x1 += xv; + y1 += yv; + + updatesector(x1,y1,§); + if(sect >= 0) + { + z = sector[sect].floorz-(TRAND&(klabs(sector[sect].ceilingz-sector[sect].floorz))); + if( z < -(32<<8) || z > (32<<8) ) + z = SZ-(32<<8)+(TRAND&((64<<8)-1)); + a = SA-1024; + EGS(SECT,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),-(TRAND&1023),i,5); + } + } +} + +void spriteglass(short i,short n) +{ + long j, k, a, z; + + for(j=n;j>0;j--) + { + a = TRAND&2047; + z = SZ-((TRAND&16)<<8); + k = EGS(SECT,SX,SY,z,GLASSPIECES+(j%3),TRAND&15,36,36,a,32+(TRAND&63),-512-(TRAND&2047),i,5); + sprite[k].pal = sprite[i].pal; + } +} + +void ceilingglass(short i,short sectnum,short n) +{ + long j, xv, yv, z, x1, y1; + short a,s, startwall,endwall; + + startwall = sector[sectnum].wallptr; + endwall = startwall+sector[sectnum].wallnum; + + for(s=startwall;s<(endwall-1);s++) + { + x1 = wall[s].x; + y1 = wall[s].y; + + xv = (wall[s+1].x-x1)/(n+1); + yv = (wall[s+1].y-y1)/(n+1); + + for(j=n;j>0;j--) + { + x1 += xv; + y1 += yv; + a = TRAND&2047; + z = sector[sectnum].ceilingz+((TRAND&15)<<8); + EGS(sectnum,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,(TRAND&31),0,i,5); + } + } +} + + +void lotsofcolourglass(short i,short wallnum,short n) +{ + long j, xv, yv, z, x1, y1; + short sect = -1, a, k; + + if(wallnum < 0) + { + for(j=n-1; j >= 0 ;j--) + { + a = TRAND&2047; + k = EGS(SECT,SX,SY,SZ-(TRAND&(63<<8)),GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),1024-(TRAND&2047),i,5); + sprite[k].pal = TRAND&15; + } + return; + } + + j = n+1; + x1 = wall[wallnum].x; + y1 = wall[wallnum].y; + + xv = (wall[wall[wallnum].point2].x-wall[wallnum].x)/j; + yv = (wall[wall[wallnum].point2].y-wall[wallnum].y)/j; + + for(j=n;j>0;j--) + { + x1 += xv; + y1 += yv; + + updatesector(x1,y1,§); + z = sector[sect].floorz-(TRAND&(klabs(sector[sect].ceilingz-sector[sect].floorz))); + if( z < -(32<<8) || z > (32<<8) ) + z = SZ-(32<<8)+(TRAND&((64<<8)-1)); + a = SA-1024; + k = EGS(SECT,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),-(TRAND&2047),i,5); + sprite[k].pal = TRAND&7; + } +} + +void SetupGameButtons( void ) +{ + CONTROL_DefineFlag(gamefunc_Move_Forward,false); + CONTROL_DefineFlag(gamefunc_Move_Backward,false); + CONTROL_DefineFlag(gamefunc_Turn_Left,false); + CONTROL_DefineFlag(gamefunc_Turn_Right,false); + CONTROL_DefineFlag(gamefunc_Strafe,false); + CONTROL_DefineFlag(gamefunc_Fire,false); + CONTROL_DefineFlag(gamefunc_Open,false); + CONTROL_DefineFlag(gamefunc_Run,false); + CONTROL_DefineFlag(gamefunc_AutoRun,false); + CONTROL_DefineFlag(gamefunc_Jump,false); + CONTROL_DefineFlag(gamefunc_Crouch,false); + CONTROL_DefineFlag(gamefunc_Look_Up,false); + CONTROL_DefineFlag(gamefunc_Look_Down,false); + CONTROL_DefineFlag(gamefunc_Look_Left,false); + CONTROL_DefineFlag(gamefunc_Look_Right,false); + CONTROL_DefineFlag(gamefunc_Strafe_Left,false); + CONTROL_DefineFlag(gamefunc_Strafe_Right,false); + CONTROL_DefineFlag(gamefunc_Aim_Up,false); + CONTROL_DefineFlag(gamefunc_Aim_Down,false); + CONTROL_DefineFlag(gamefunc_Weapon_1,false); + CONTROL_DefineFlag(gamefunc_Weapon_2,false); + CONTROL_DefineFlag(gamefunc_Weapon_3,false); + CONTROL_DefineFlag(gamefunc_Weapon_4,false); + CONTROL_DefineFlag(gamefunc_Weapon_5,false); + CONTROL_DefineFlag(gamefunc_Weapon_6,false); + CONTROL_DefineFlag(gamefunc_Weapon_7,false); + CONTROL_DefineFlag(gamefunc_Weapon_8,false); + CONTROL_DefineFlag(gamefunc_Weapon_9,false); + CONTROL_DefineFlag(gamefunc_Weapon_10,false); + CONTROL_DefineFlag(gamefunc_Inventory,false); + CONTROL_DefineFlag(gamefunc_Inventory_Left,false); + CONTROL_DefineFlag(gamefunc_Inventory_Right,false); + CONTROL_DefineFlag(gamefunc_Holo_Duke,false); + CONTROL_DefineFlag(gamefunc_Jetpack,false); + CONTROL_DefineFlag(gamefunc_NightVision,false); + CONTROL_DefineFlag(gamefunc_MedKit,false); + CONTROL_DefineFlag(gamefunc_TurnAround,false); + CONTROL_DefineFlag(gamefunc_SendMessage,false); + CONTROL_DefineFlag(gamefunc_Map,false); + CONTROL_DefineFlag(gamefunc_Shrink_Screen,false); + CONTROL_DefineFlag(gamefunc_Enlarge_Screen,false); + CONTROL_DefineFlag(gamefunc_Center_View,false); + CONTROL_DefineFlag(gamefunc_Holster_Weapon,false); + CONTROL_DefineFlag(gamefunc_Show_Opponents_Weapon,false); + CONTROL_DefineFlag(gamefunc_Map_Follow_Mode,false); + CONTROL_DefineFlag(gamefunc_See_Coop_View,false); + CONTROL_DefineFlag(gamefunc_Mouse_Aiming,false); + CONTROL_DefineFlag(gamefunc_Toggle_Crosshair,false); + CONTROL_DefineFlag(gamefunc_Steroids,false); + CONTROL_DefineFlag(gamefunc_Quick_Kick,false); + CONTROL_DefineFlag(gamefunc_Next_Weapon,false); + CONTROL_DefineFlag(gamefunc_Previous_Weapon,false); +} + +/* +=================== += += GetTime += +=================== +*/ + +long GetTime(void) +{ + return totalclock; +} + +/* +=================== += += CenterCenter += +=================== +*/ + +void CenterCenter(void) +{ + initprintf("Center the joystick and press a button\n"); +} + +/* +=================== += += UpperLeft += +=================== +*/ + +void UpperLeft(void) +{ + initprintf("Move joystick to upper-left corner and press a button\n"); +} + +/* +=================== += += LowerRight += +=================== +*/ + +void LowerRight(void) +{ + initprintf("Move joystick to lower-right corner and press a button\n"); +} + +/* +=================== += += CenterThrottle += +=================== +*/ + +void CenterThrottle(void) +{ + initprintf("Center the throttle control and press a button\n"); +} + +/* +=================== += += CenterRudder += +=================== +*/ + +void CenterRudder(void) +{ + initprintf("Center the rudder control and press a button\n"); +} + diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c new file mode 100644 index 000000000..785e17f45 --- /dev/null +++ b/polymer/eduke32/source/gamedef.c @@ -0,0 +1,5992 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "gamedef.h" + +#include "osd.h" + +int conversion = 13; + +static char compilefile[BMAX_PATH] = "(none)"; // file we're currently compiling +static char parsing_item_name[MAXVARLABEL] = "(none)", previous_item_name[MAXVARLABEL] = "NULL"; + +static short total_lines,line_number; +static char checking_ifelse,parsing_state; +char g_szBuf[1024]; + +long *casescriptptr=NULL; // the pointer to the start of the case table in a switch statement +// first entry is 'default' code. +int casecount = 0; +signed char checking_switch = 0, current_event = -1; +char labelsonly = 0, nokeywordcheck = 0, dynamicremap = 0; +static short num_braces = 0; // init to some sensible defaults + +char redefined_fta_quotes[NUMOFFIRSTTIMEACTIVE][64]; +int redefined_quotes = 0; + +long *aplWeaponClip[MAX_WEAPONS]; // number of items in magazine +long *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire) +long *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire +long *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none) +long *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire. +long *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon +long *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots +long *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item +long *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn +long *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst' +long *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like +long *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when initialy firing. zero for no sound +long *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic) +long *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time +long *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID +long *aplWeaponRenderSize[MAX_WEAPONS]; // size of weapon sprite, 0 = normal, 1 = half size (RR style) +long *aplWeaponReloadSound1[MAX_WEAPONS]; // Sound of magazine being removed +long *aplWeaponReloadSound2[MAX_WEAPONS]; // Sound of magazine being inserted + +int g_iReturnVarID=-1; // var ID of "RETURN" +int g_iWeaponVarID=-1; // var ID of "WEAPON" +int g_iWorksLikeVarID=-1; // var ID of "WORKSLIKE" +int g_iZRangeVarID=-1; // var ID of "ZRANGE" +int g_iAngRangeVarID=-1; // var ID of "ANGRANGE" +int g_iAimAngleVarID=-1; // var ID of "AUTOAIMANGLE" +int g_iLoTagID=-1; // var ID of "LOTAG" +int g_iHiTagID=-1; // var ID of "HITAG" +int g_iTextureID=-1; // var ID of "TEXTURE" +int g_iThisActorID=-1; // var ID of "THISACTOR" + +long *actorLoadEventScrptr[MAXTILES]; + +long *apScriptGameEvent[MAXGAMEEVENTS]; +long *parsing_event=NULL; + +MATTGAMEVAR aGameVars[MAXGAMEVARS]; +int iGameVarCount=0; + +MATTGAMEVAR aDefaultGameVars[MAXGAMEVARS]; // the 'original' values +int iDefaultGameVarCount=0; + +void ReportError(int iError); +void FreeGameVars(void); + +extern long qsetmode; + +enum errors { + ERROR_CLOSEBRACKET, + ERROR_EVENTONLY, + ERROR_EXCEEDSMAXTILES, + ERROR_EXPECTEDKEYWORD, + ERROR_FOUNDWITHIN, + ERROR_ISAKEYWORD, + ERROR_NOENDSWITCH, + ERROR_NOTAGAMEDEF, + ERROR_NOTAGAMEVAR, + ERROR_OPENBRACKET, + ERROR_PARAMUNDEFINED, + ERROR_SYMBOLNOTRECOGNIZED, + ERROR_SYNTAXERROR, + ERROR_VARREADONLY, + ERROR_VARTYPEMISMATCH, + WARNING_DUPLICATEDEFINITION, + WARNING_EVENTSYNC, + WARNING_LABELSONLY, +}; + +enum labeltypes { + LABEL_ANY = -1, + LABEL_ACTION = 1, + LABEL_AI = 2, + LABEL_DEFINE = 4, + LABEL_MOVE = 8, + LABEL_STATE = 16, +}; + +static char *labeltypenames[] = { + "define", + "state", + "actor", + "action", + "ai", + "move" + }; + +static char *translatelabeltype(long type) +{ + int i; + char x[64]; + + x[0] = 0; + for (i=0;i<6;i++) { + if (!(type & (1<pals_time and p->pals[0-2] + "sound", // 15 plays a sound that was defined with definesound + "fall", // 16 causes actor to fall to sector floor height + "state", // 17 begins defining a state if used outside a state or actor, otherwise calls a state + "ends", // 18 ends defining a state + "define", // 19 defines a value + "", // 20 was previously used to define a comment + "ifai", // 21 checks if actor is currently performing a specific ai function + "killit", // 22 kills an actor + "addweapon", // 23 adds a weapon to the closest player + "ai", // 24 sets an ai function to be used by an actor + "addphealth", // 25 adds health to the player + "ifdead", // 26 checks if actor is dead + "ifsquished", // 27 checks if actor has been squished + "sizeto", // 28 gradually increases actor size until it matches parameters given + "{", // 29 used to indicate segments of code + "}", // 30 used to indicate segments of code + "spawn", // 31 spawns an actor + "move", // 32 + "ifwasweapon", // 33 + "ifaction", // 34 + "ifactioncount", // 35 + "resetactioncount", // 36 + "debris", // 37 + "pstomp", // 38 + "", // 39 was previously used to define the start of a comment block + "cstat", // 40 + "ifmove", // 41 + "resetplayer", // 42 + "ifonwater", // 43 + "ifinwater", // 44 + "ifcanshoottarget", // 45 + "ifcount", // 46 + "resetcount", // 47 + "addinventory", // 48 + "ifactornotstayput", // 49 + "hitradius", // 50 + "ifp", // 51 + "count", // 52 + "ifactor", // 53 + "music", // 54 + "include", // 55 + "ifstrength", // 56 + "definesound", // 57 + "guts", // 58 + "ifspawnedby", // 59 + "gamestartup", // 60 + "wackplayer", // 61 + "ifgapzl", // 62 + "ifhitspace", // 63 + "ifoutside", // 64 + "ifmultiplayer", // 65 + "operate", // 66 + "ifinspace", // 67 + "debug", // 68 + "endofgame", // 69 + "ifbulletnear", // 70 + "ifrespawn", // 71 + "iffloordistl", // 72 + "ifceilingdistl", // 73 + "spritepal", // 74 + "ifpinventory", // 75 + "betaname", // 76 + "cactor", // 77 + "ifphealthl", // 78 + "definequote", // 79 + "quote", // 80 + "ifinouterspace", // 81 + "ifnotmoving", // 82 + "respawnhitag", // 83 + "tip", // 84 + "ifspritepal", // 85 + "money", // 86 + "soundonce", // 87 + "addkills", // 88 + "stopsound", // 89 + "ifawayfromwall", // 90 + "ifcanseetarget", // 91 + "globalsound", // 92 + "lotsofglass", // 93 + "ifgotweaponce", // 94 + "getlastpal", // 95 + "pkick", // 96 + "mikesnd", // 97 + "useractor", // 98 + "sizeat", // 99 + "addstrength", // 100 [#] + "cstator", // 101 + "mail", // 102 + "paper", // 103 + "tossweapon", // 104 + "sleeptime", // 105 + "nullop", // 106 + "definevolumename", // 107 + "defineskillname", // 108 + "ifnosounds", // 109 + "clipdist", // 110 + "ifangdiffl", // 111 + "gamevar", // 112 + "ifvarl", // 113 + "ifvarg", // 114 + "setvarvar", // 115 + "setvar", // 116 + "addvarvar", // 117 + "addvar", // 118 + "ifvarvarl", // 119 + "ifvarvarg", // 120 + "addlogvar", // 121 + "addlog", // 122 + "onevent", // 123 + "endevent", // 124 + "ifvare", // 125 + "ifvarvare", // 126 + "spgetlotag", // 127 + "spgethitag", // 128 + "sectgetlotag", // 129 + "sectgethitag", // 130 + "ifsound", // 131 + "gettexturefloor", // 132 + "gettextureceiling", // 133 + "inittimer", // 134 + "starttrack", // 135 + "randvar", // 136 + "enhanced", // 137 + "getangletotarget", // 138 + "getactorangle", // 139 + "setactorangle", // 140 + "mulvar", // 141 + "mulvarvar", // 142 + "divvar", // 143 + "divvarvar", // 144 + "modvar", // 145 + "modvarvar", // 146 + "andvar", // 147 + "andvarvar", // 148 + "orvar", // 149 + "orvarvar", // 150 + "getplayerangle", // 151 + "setplayerangle", // 152 + "lockplayer", // 153 + "setsector", // 154 + "getsector", // 155 + "setactor", // 156 + "getactor", // 157 + "setwall", // 158 + "getwall", // 159 + "findnearactor", // 160 + "findnearactorvar", // 161 + "setactorvar", // 162 + "getactorvar", // 163 + "espawn", // 164 + "getplayer", // 165 + "setplayer", // 166 + "sqrt", // 167 + "eventloadactor", // 168 + "espawnvar", // 169 + "getuserdef", // 170 + "setuserdef", // 171 + "subvarvar", // 172 + "subvar", // 173 + "ifvarn", // 174 + "ifvarvarn", // 175 + "ifvarand", // 176 + "ifvarvarand", // 177 + "myos", // 178 + "myospal", // 179 + "displayrand", // 180 + "sin", // 181 + "xorvarvar", // 182 + "xorvar", // 183 + "randvarvar", // 184 + "myosx", // 185 + "myospalx", // 186 + "gmaxammo", // 187 + "smaxammo", // 188 + "startlevel", // 189 + "eshoot", // 190 + "qspawn", // 191 + "rotatesprite", // 192 + "defineprojectile", // 193 + "spriteshadow", // 194 + "cos", // 195 + "eshootvar", // 196 + "findnearactor3d", // 197 + "findnearactor3dvar", // 198 + "flash", // 199 + "qspawnvar", // 200 + "eqspawn", // 201 + "eqspawnvar", // 202 + "minitext", // 203 + "gametext", // 204 + "digitalnumber", // 205 + "addweaponvar", // 206 + "setprojectile", // 207 + "angoff", // 208 + "updatesector", // 209 + "insertspriteq", // 210 + "angoffvar", // 211 + "whilevarn", // 212 + "switch", // 213 + "case", // 214 + "default", // 215 + "endswitch", // 216 + "shootvar", // 217 + "soundvar", // 218 + "findplayer", // 219 + "findotherplayer", // 220 + "activatebysector", // 221 sectnum, spriteid + "operatesectors", // 222 sectnum, spriteid + "operaterespawns", // 223 lotag + "operateactivators", // 224 lotag, player index + "operatemasterswitches", // 225 lotag + "checkactivatormotion", // 226 lotag + "zshoot", // 227 zvar projnum + "dist", // 228 sprite1 sprite2 + "ldist", // 229 sprite1 sprite2 + "shiftvarl", // 230 + "shiftvarr", // 231 + "spritenvg", // 232 + "getangle", // 233 + "whilevarvarn", // 234 + "hitscan", // 235 + "time", // 236 + "getplayervar", // 237 + "setplayervar", // 238 + "mulscale", // 239 + "setaspect", // 240 + "txdist", // 241 + "spritenoshade", // 242 + "movesprite", // 243 + "checkavailweapon", // 244 + "soundoncevar", // 245 + "updatesectorz", // 246 + "stopallsounds", // 247 + "ssp", // 248 + "stopsoundvar", // 249 + "displayrandvar", // 250 + "displayrandvarvar", // 251 + "checkavailinven", // 252 + "globalsoundvar", // 253 + "guniqhudid", // 254 + "getprojectile", // 255 + "getthisprojectile", // 256 + "setthisprojectile", // 257 + "definecheat", // 258 + "cheatkeys", // 259 + "userquote", // 260 + "precache", // 261 + "projectile", // 262 + "redefinequote", // 263 + "dynquote", // 264 + "getpname", // 265 + "qstrcat", // 266 + "qstrcpy", // 267 + "setsprite", // 268 + "rotatepoint", // 269 + "dragpoint", // 270 + "getzrange", // 271 + "changespritestat", // 272 + "getceilzofslope", // 273 + "getflorzofslope", // 274 + "neartag", // 275 + "definegametype", // 276 + "changespritesect", // 277 + "spriteflags", // 278 + "savegamevar", // 279 + "readgamevar", // 280 + "findnearsprite", // 281 + "findnearspritevar", // 282 + "findnearsprite3d", // 283 + "findnearsprite3dvar", // 284 + "dynamicremap", // 285 + "setinput", // 286 + "getinput", // 287 + "save", // 288 + "" + }; + +LABELS sectorlabels[]= { + { "wallptr", SECTOR_WALLPTR, 0, 0 }, + { "wallnum", SECTOR_WALLNUM, 0, 0 }, + { "ceilingz", SECTOR_CEILINGZ, 0, 0 }, + { "floorz", SECTOR_FLOORZ, 0, 0 }, + { "ceilingstat", SECTOR_CEILINGSTAT, 0, 0 }, + { "floorstat", SECTOR_FLOORSTAT, 0, 0 }, + { "ceilingpicnum", SECTOR_CEILINGPICNUM, 0, 0 }, + { "ceilingslope", SECTOR_CEILINGSLOPE, 0, 0 }, + { "ceilingshade", SECTOR_CEILINGSHADE, 0, 0 }, + { "ceilingpal", SECTOR_CEILINGPAL, 0, 0 }, + { "ceilingxpanning", SECTOR_CEILINGXPANNING, 0, 0 }, + { "ceilingypanning", SECTOR_CEILINGYPANNING, 0, 0 }, + { "floorpicnum", SECTOR_FLOORPICNUM, 0, 0 }, + { "floorslope", SECTOR_FLOORSLOPE, 0, 0 }, + { "floorshade", SECTOR_FLOORSHADE, 0, 0 }, + { "floorpal", SECTOR_FLOORPAL, 0, 0 }, + { "floorxpanning", SECTOR_FLOORXPANNING, 0, 0 }, + { "floorypanning", SECTOR_FLOORYPANNING, 0, 0 }, + { "visibility", SECTOR_VISIBILITY, 0, 0 }, + { "alignto", SECTOR_ALIGNTO, 0, 0 }, + { "lotag", SECTOR_LOTAG, 0, 0 }, + { "hitag", SECTOR_HITAG, 0, 0 }, + { "extra", SECTOR_EXTRA, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS walllabels[]= { + { "x", WALL_X, 0, 0 }, + { "y", WALL_Y, 0, 0 }, + { "point2", WALL_POINT2, 0, 0 }, + { "nextwall", WALL_NEXTWALL, 0, 0 }, + { "nextsector", WALL_NEXTSECTOR, 0, 0 }, + { "cstat", WALL_CSTAT, 0, 0 }, + { "picnum", WALL_PICNUM, 0, 0 }, + { "overpicnum", WALL_OVERPICNUM, 0, 0 }, + { "shade", WALL_SHADE, 0, 0 }, + { "pal", WALL_PAL, 0, 0 }, + { "xrepeat", WALL_XREPEAT, 0, 0 }, + { "yrepeat", WALL_YREPEAT, 0, 0 }, + { "xpanning", WALL_XPANNING, 0, 0 }, + { "ypanning", WALL_YPANNING, 0, 0 }, + { "lotag", WALL_LOTAG, 0, 0 }, + { "hitag", WALL_HITAG, 0, 0 }, + { "extra", WALL_EXTRA, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS actorlabels[]= { + { "x", ACTOR_X, 0, 0 }, + { "y", ACTOR_Y, 0, 0 }, + { "z", ACTOR_Z, 0, 0 }, + { "cstat", ACTOR_CSTAT, 0, 0 }, + { "picnum", ACTOR_PICNUM, 0, 0 }, + { "shade", ACTOR_SHADE, 0, 0 }, + { "pal", ACTOR_PAL, 0, 0 }, + { "clipdist", ACTOR_CLIPDIST, 0, 0 }, + { "detail", ACTOR_DETAIL, 0, 0 }, + { "xrepeat", ACTOR_XREPEAT, 0, 0 }, + { "yrepeat", ACTOR_YREPEAT, 0, 0 }, + { "xoffset", ACTOR_XOFFSET, 0, 0 }, + { "yoffset", ACTOR_YOFFSET, 0, 0 }, + { "sectnum", ACTOR_SECTNUM, 0, 0 }, + { "statnum", ACTOR_STATNUM, 0, 0 }, + { "ang", ACTOR_ANG, 0, 0 }, + { "owner", ACTOR_OWNER, 0, 0 }, + { "xvel", ACTOR_XVEL, 0, 0 }, + { "yvel", ACTOR_YVEL, 0, 0 }, + { "zvel", ACTOR_ZVEL, 0, 0 }, + { "lotag", ACTOR_LOTAG, 0, 0 }, + { "hitag", ACTOR_HITAG, 0, 0 }, + { "extra", ACTOR_EXTRA, 0, 0 }, + + // hittype labels... + { "htcgg", ACTOR_HTCGG, 0, 0 }, + { "htpicnum", ACTOR_HTPICNUM, 0, 0 }, + { "htang", ACTOR_HTANG, 0, 0 }, + { "htextra", ACTOR_HTEXTRA, 0, 0 }, + { "htowner", ACTOR_HTOWNER, 0, 0 }, + { "htmovflag", ACTOR_HTMOVFLAG, 0, 0 }, + { "httempang", ACTOR_HTTEMPANG, 0, 0 }, + { "htactorstayput", ACTOR_HTACTORSTAYPUT, 0, 0 }, + { "htdispicnum", ACTOR_HTDISPICNUM, 0, 0 }, + { "httimetosleep", ACTOR_HTTIMETOSLEEP, 0, 0 }, + { "htfloorz", ACTOR_HTFLOORZ, 0, 0 }, + { "htceilingz", ACTOR_HTCEILINGZ, 0, 0 }, + { "htlastvx", ACTOR_HTLASTVX, 0, 0 }, + { "htlastvy", ACTOR_HTLASTVY, 0, 0 }, + { "htbposx", ACTOR_HTBPOSX, 0, 0 }, + { "htbposy", ACTOR_HTBPOSY, 0, 0 }, + { "htbposz", ACTOR_HTBPOSZ, 0, 0 }, + { "htg_t", ACTOR_HTG_T, LABEL_HASPARM2, 8 }, + + // model flags + + { "angoff", ACTOR_ANGOFF, 0, 0 }, + { "pitch", ACTOR_PITCH, 0, 0 }, + { "roll", ACTOR_ROLL, 0, 0 }, + { "mdxoff", ACTOR_MDXOFF, 0, 0 }, + { "mdyoff", ACTOR_MDYOFF, 0, 0 }, + { "mdzoff", ACTOR_MDZOFF, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS playerlabels[]= { + { "zoom", PLAYER_ZOOM, 0, 0 }, + { "exitx", PLAYER_EXITX, 0, 0 }, + { "exity", PLAYER_EXITY, 0, 0 }, + { "loogiex", PLAYER_LOOGIEX, LABEL_HASPARM2, 64 }, + { "loogiey", PLAYER_LOOGIEY, LABEL_HASPARM2, 64 }, + { "numloogs", PLAYER_NUMLOOGS, 0, 0 }, + { "loogcnt", PLAYER_LOOGCNT, 0, 0 }, + { "posx", PLAYER_POSX, 0, 0 }, + { "posy", PLAYER_POSY, 0, 0 }, + { "posz", PLAYER_POSZ, 0, 0 }, + { "horiz", PLAYER_HORIZ, 0, 0 }, + { "ohoriz", PLAYER_OHORIZ, 0, 0 }, + { "ohorizoff", PLAYER_OHORIZOFF, 0, 0 }, + { "invdisptime", PLAYER_INVDISPTIME, 0, 0 }, + { "bobposx", PLAYER_BOBPOSX, 0, 0 }, + { "bobposy", PLAYER_BOBPOSY, 0, 0 }, + { "oposx", PLAYER_OPOSX, 0, 0 }, + { "oposy", PLAYER_OPOSY, 0, 0 }, + { "oposz", PLAYER_OPOSZ, 0, 0 }, + { "pyoff", PLAYER_PYOFF, 0, 0 }, + { "opyoff", PLAYER_OPYOFF, 0, 0 }, + { "posxv", PLAYER_POSXV, 0, 0 }, + { "posyv", PLAYER_POSYV, 0, 0 }, + { "poszv", PLAYER_POSZV, 0, 0 }, + { "last_pissed_time", PLAYER_LAST_PISSED_TIME, 0, 0 }, + { "truefz", PLAYER_TRUEFZ, 0, 0 }, + { "truecz", PLAYER_TRUECZ, 0, 0 }, + { "player_par", PLAYER_PLAYER_PAR, 0, 0 }, + { "visibility", PLAYER_VISIBILITY, 0, 0 }, + { "bobcounter", PLAYER_BOBCOUNTER, 0, 0 }, + { "weapon_sway", PLAYER_WEAPON_SWAY, 0, 0 }, + { "pals_time", PLAYER_PALS_TIME, 0, 0 }, + { "randomflamex", PLAYER_RANDOMFLAMEX, 0, 0 }, + { "crack_time", PLAYER_CRACK_TIME, 0, 0 }, + { "aim_mode", PLAYER_AIM_MODE, 0, 0 }, + { "ang", PLAYER_ANG, 0, 0 }, + { "oang", PLAYER_OANG, 0, 0 }, + { "angvel", PLAYER_ANGVEL, 0, 0 }, + { "cursectnum", PLAYER_CURSECTNUM, 0, 0 }, + { "look_ang", PLAYER_LOOK_ANG, 0, 0 }, + { "last_extra", PLAYER_LAST_EXTRA, 0, 0 }, + { "subweapon", PLAYER_SUBWEAPON, 0, 0 }, + { "ammo_amount", PLAYER_AMMO_AMOUNT, LABEL_HASPARM2, MAX_WEAPONS }, + { "wackedbyactor", PLAYER_WACKEDBYACTOR, 0, 0 }, + { "frag", PLAYER_FRAG, 0, 0 }, + { "fraggedself", PLAYER_FRAGGEDSELF, 0, 0 }, + { "curr_weapon", PLAYER_CURR_WEAPON, 0, 0 }, + { "last_weapon", PLAYER_LAST_WEAPON, 0, 0 }, + { "tipincs", PLAYER_TIPINCS, 0, 0 }, + { "horizoff", PLAYER_HORIZOFF, 0, 0 }, + { "wantweaponfire", PLAYER_WANTWEAPONFIRE, 0, 0 }, + { "holoduke_amount", PLAYER_HOLODUKE_AMOUNT, 0, 0 }, + { "newowner", PLAYER_NEWOWNER, 0, 0 }, + { "hurt_delay", PLAYER_HURT_DELAY, 0, 0 }, + { "hbomb_hold_delay", PLAYER_HBOMB_HOLD_DELAY, 0, 0 }, + { "jumping_counter", PLAYER_JUMPING_COUNTER, 0, 0 }, + { "airleft", PLAYER_AIRLEFT, 0, 0 }, + { "knee_incs", PLAYER_KNEE_INCS, 0, 0 }, + { "access_incs", PLAYER_ACCESS_INCS, 0, 0 }, + { "fta", PLAYER_FTA, 0, 0 }, + { "ftq", PLAYER_FTQ, 0, 0 }, + { "access_wallnum", PLAYER_ACCESS_WALLNUM, 0, 0 }, + { "access_spritenum", PLAYER_ACCESS_SPRITENUM, 0, 0 }, + { "kickback_pic", PLAYER_KICKBACK_PIC, 0, 0 }, + { "got_access", PLAYER_GOT_ACCESS, 0, 0 }, + { "weapon_ang", PLAYER_WEAPON_ANG, 0, 0 }, + { "firstaid_amount", PLAYER_FIRSTAID_AMOUNT, 0, 0 }, + { "somethingonplayer", PLAYER_SOMETHINGONPLAYER, 0, 0 }, + { "on_crane", PLAYER_ON_CRANE, 0, 0 }, + { "i", PLAYER_I, 0, 0 }, + { "one_parallax_sectnum", PLAYER_ONE_PARALLAX_SECTNUM, 0, 0 }, + { "over_shoulder_on", PLAYER_OVER_SHOULDER_ON, 0, 0 }, + { "random_club_frame", PLAYER_RANDOM_CLUB_FRAME, 0, 0 }, + { "fist_incs", PLAYER_FIST_INCS, 0, 0 }, + { "one_eighty_count", PLAYER_ONE_EIGHTY_COUNT, 0, 0 }, + { "cheat_phase", PLAYER_CHEAT_PHASE, 0, 0 }, + { "dummyplayersprite", PLAYER_DUMMYPLAYERSPRITE, 0, 0 }, + { "extra_extra8", PLAYER_EXTRA_EXTRA8, 0, 0 }, + { "quick_kick", PLAYER_QUICK_KICK, 0, 0 }, + { "heat_amount", PLAYER_HEAT_AMOUNT, 0, 0 }, + { "actorsqu", PLAYER_ACTORSQU, 0, 0 }, + { "timebeforeexit", PLAYER_TIMEBEFOREEXIT, 0, 0 }, + { "customexitsound", PLAYER_CUSTOMEXITSOUND, 0, 0 }, + { "weaprecs[16]", PLAYER_WEAPRECS, 0, 0 }, + { "weapreccnt", PLAYER_WEAPRECCNT, 0, 0 }, + { "interface_toggle_flag", PLAYER_INTERFACE_TOGGLE_FLAG, 0, 0 }, + { "rotscrnang", PLAYER_ROTSCRNANG, 0, 0 }, + { "dead_flag", PLAYER_DEAD_FLAG, 0, 0 }, + { "show_empty_weapon", PLAYER_SHOW_EMPTY_WEAPON, 0, 0 }, + { "scuba_amount", PLAYER_SCUBA_AMOUNT, 0, 0 }, + { "jetpack_amount", PLAYER_JETPACK_AMOUNT, 0, 0 }, + { "steroids_amount", PLAYER_STEROIDS_AMOUNT, 0, 0 }, + { "shield_amount", PLAYER_SHIELD_AMOUNT, 0, 0 }, + { "holoduke_on", PLAYER_HOLODUKE_ON, 0, 0 }, + { "pycount", PLAYER_PYCOUNT, 0, 0 }, + { "weapon_pos", PLAYER_WEAPON_POS, 0, 0 }, + { "frag_ps", PLAYER_FRAG_PS, 0, 0 }, + { "transporter_hold", PLAYER_TRANSPORTER_HOLD, 0, 0 }, + { "last_full_weapon", PLAYER_LAST_FULL_WEAPON, 0, 0 }, + { "footprintshade", PLAYER_FOOTPRINTSHADE, 0, 0 }, + { "boot_amount", PLAYER_BOOT_AMOUNT, 0, 0 }, + { "scream_voice", PLAYER_SCREAM_VOICE, 0, 0 }, + { "gm", PLAYER_GM, 0, 0 }, + { "on_warping_sector", PLAYER_ON_WARPING_SECTOR, 0, 0 }, + { "footprintcount", PLAYER_FOOTPRINTCOUNT, 0, 0 }, + { "hbomb_on", PLAYER_HBOMB_ON, 0, 0 }, + { "jumping_toggle", PLAYER_JUMPING_TOGGLE, 0, 0 }, + { "rapid_fire_hold", PLAYER_RAPID_FIRE_HOLD, 0, 0 }, + { "on_ground", PLAYER_ON_GROUND, 0, 0 }, + { "name", PLAYER_NAME, LABEL_ISSTRING, 32 }, + { "inven_icon", PLAYER_INVEN_ICON, 0, 0 }, + { "buttonpalette", PLAYER_BUTTONPALETTE, 0, 0 }, + { "jetpack_on", PLAYER_JETPACK_ON, 0, 0 }, + { "spritebridge", PLAYER_SPRITEBRIDGE, 0, 0 }, + { "lastrandomspot", PLAYER_LASTRANDOMSPOT, 0, 0 }, + { "scuba_on", PLAYER_SCUBA_ON, 0, 0 }, + { "footprintpal", PLAYER_FOOTPRINTPAL, 0, 0 }, + { "heat_on", PLAYER_HEAT_ON, 0, 0 }, + { "holster_weapon", PLAYER_HOLSTER_WEAPON, 0, 0 }, + { "falling_counter", PLAYER_FALLING_COUNTER, 0, 0 }, + { "gotweapon", PLAYER_GOTWEAPON, LABEL_HASPARM2, MAX_WEAPONS }, + { "refresh_inventory", PLAYER_REFRESH_INVENTORY, 0, 0 }, + { "palette", PLAYER_PALETTE, 0, 0 }, + { "toggle_key_flag", PLAYER_TOGGLE_KEY_FLAG, 0, 0 }, + { "knuckle_incs", PLAYER_KNUCKLE_INCS, 0, 0 }, + { "walking_snd_toggle", PLAYER_WALKING_SND_TOGGLE, 0, 0 }, + { "palookup", PLAYER_PALOOKUP, 0, 0 }, + { "hard_landing", PLAYER_HARD_LANDING, 0, 0 }, + { "max_+_rooms", PLAYER_MAX_SECRET_ROOMS, 0, 0 }, + { "secret_rooms", PLAYER_SECRET_ROOMS, 0, 0 }, + { "pals", PLAYER_PALS, LABEL_HASPARM2, 2 }, + { "max_actors_killed", PLAYER_MAX_ACTORS_KILLED, 0, 0 }, + { "actors_killed", PLAYER_ACTORS_KILLED, 0, 0 }, + { "return_to_center", PLAYER_RETURN_TO_CENTER, 0, 0 }, + { "runspeed", PLAYER_RUNSPEED, 0, 0 }, + { "sbs", PLAYER_SBS, 0, 0 }, + { "reloading", PLAYER_RELOADING, 0, 0 }, + { "auto_aim", PLAYER_AUTO_AIM, 0, 0 }, + { "movement_lock", PLAYER_MOVEMENT_LOCK, LABEL_HASPARM2, 4 }, + { "sound_pitch", PLAYER_SOUND_PITCH, 0, 0 }, + { "weaponswitch", PLAYER_WEAPONSWITCH, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS projectilelabels[]= { + { "workslike", PROJ_WORKSLIKE, 0, 0 }, + { "spawns", PROJ_SPAWNS, 0, 0 }, + { "sxrepeat", PROJ_SXREPEAT, 0, 0 }, + { "syrepeat", PROJ_SYREPEAT, 0, 0 }, + { "sound", PROJ_SOUND, 0, 0 }, + { "isound", PROJ_ISOUND, 0, 0 }, + { "vel", PROJ_VEL, 0, 0 }, + { "extra", PROJ_EXTRA, 0, 0 }, + { "decal", PROJ_DECAL, 0, 0 }, + { "trail", PROJ_TRAIL, 0, 0 }, + { "txrepeat", PROJ_TXREPEAT, 0, 0 }, + { "tyrepeat", PROJ_TYREPEAT, 0, 0 }, + { "toffset", PROJ_TOFFSET, 0, 0 }, + { "tnum", PROJ_TNUM, 0, 0 }, + { "drop", PROJ_DROP, 0, 0 }, + { "cstat", PROJ_CSTAT, 0, 0 }, + { "clipdist", PROJ_CLIPDIST, 0, 0 }, + { "shade", PROJ_SHADE, 0, 0 }, + { "xrepeat", PROJ_XREPEAT, 0, 0 }, + { "yrepeat", PROJ_YREPEAT, 0, 0 }, + { "pal", PROJ_PAL, 0, 0 }, + { "extra_rand", PROJ_EXTRA_RAND, 0, 0 }, + { "hitradius", PROJ_HITRADIUS, 0, 0 }, + { "velmult", PROJ_VEL_MULT, 0, 0 }, + { "offset", PROJ_OFFSET, 0, 0 }, + { "bounces", PROJ_BOUNCES, 0, 0 }, + { "bsound", PROJ_BSOUND, 0, 0 }, + { "range", PROJ_RANGE, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS userdefslabels[]= { + // { "", 1, 0, 0 }, + { "god", USERDEFS_GOD, 0, 0 }, + { "warp_on", USERDEFS_WARP_ON, 0, 0 }, + { "cashman", USERDEFS_CASHMAN, 0, 0 }, + { "eog", USERDEFS_EOG, 0, 0 }, + { "showallmap", USERDEFS_SHOWALLMAP, 0, 0 }, + { "show_help", USERDEFS_SHOW_HELP, 0, 0 }, + { "scrollmode", USERDEFS_SCROLLMODE, 0, 0 }, + { "clipping", USERDEFS_CLIPPING, 0, 0 }, + { "user_name", USERDEFS_USER_NAME, LABEL_HASPARM2, MAXPLAYERS }, + { "ridecule", USERDEFS_RIDECULE, LABEL_HASPARM2 | LABEL_ISSTRING, 10 }, + { "savegame", USERDEFS_SAVEGAME, LABEL_HASPARM2 | LABEL_ISSTRING, 10 }, + { "pwlockout", USERDEFS_PWLOCKOUT, LABEL_ISSTRING, 128 }, + { "rtsname;", USERDEFS_RTSNAME, LABEL_ISSTRING, 128 }, + { "overhead_on", USERDEFS_OVERHEAD_ON, 0, 0 }, + { "last_overhead", USERDEFS_LAST_OVERHEAD, 0, 0 }, + { "showweapons", USERDEFS_SHOWWEAPONS, 0, 0 }, + + { "pause_on", USERDEFS_PAUSE_ON, 0, 0 }, + { "from_bonus", USERDEFS_FROM_BONUS, 0, 0 }, + { "camerasprite", USERDEFS_CAMERASPRITE, 0, 0 }, + { "last_camsprite", USERDEFS_LAST_CAMSPRITE, 0, 0 }, + { "last_level", USERDEFS_LAST_LEVEL, 0, 0 }, + { "secretlevel", USERDEFS_SECRETLEVEL, 0, 0 }, + + { "const_visibility", USERDEFS_CONST_VISIBILITY, 0, 0 }, + { "uw_framerate", USERDEFS_UW_FRAMERATE, 0, 0 }, + { "camera_time", USERDEFS_CAMERA_TIME, 0, 0 }, + { "folfvel", USERDEFS_FOLFVEL, 0, 0 }, + { "folavel", USERDEFS_FOLAVEL, 0, 0 }, + { "folx", USERDEFS_FOLX, 0, 0 }, + { "foly", USERDEFS_FOLY, 0, 0 }, + { "fola", USERDEFS_FOLA, 0, 0 }, + { "reccnt", USERDEFS_RECCNT, 0, 0 }, + + { "entered_name", USERDEFS_ENTERED_NAME, 0, 0 }, + { "screen_tilting", USERDEFS_SCREEN_TILTING, 0, 0 }, + { "shadows", USERDEFS_SHADOWS, 0, 0 }, + { "fta_on", USERDEFS_FTA_ON, 0, 0 }, + { "executions", USERDEFS_EXECUTIONS, 0, 0 }, + { "auto_run", USERDEFS_AUTO_RUN, 0, 0 }, + { "coords", USERDEFS_COORDS, 0, 0 }, + { "tickrate", USERDEFS_TICKRATE, 0, 0 }, + { "m_coop", USERDEFS_M_COOP, 0, 0 }, + { "coop", USERDEFS_COOP, 0, 0 }, + { "screen_size", USERDEFS_SCREEN_SIZE, 0, 0 }, + { "lockout", USERDEFS_LOCKOUT, 0, 0 }, + { "crosshair", USERDEFS_CROSSHAIR, 0, 0 }, + { "wchoice[MAXPLAYERS][MAX_WEAPONS]", USERDEFS_WCHOICE, 0, 0 }, + { "playerai", USERDEFS_PLAYERAI, 0, 0 }, + { "respawn_monsters", USERDEFS_RESPAWN_MONSTERS, 0, 0 }, + { "respawn_items", USERDEFS_RESPAWN_ITEMS, 0, 0 }, + { "respawn_inventory", USERDEFS_RESPAWN_INVENTORY, 0, 0 }, + { "recstat", USERDEFS_RECSTAT, 0, 0 }, + { "monsters_off", USERDEFS_MONSTERS_OFF, 0, 0 }, + { "brightness", USERDEFS_BRIGHTNESS, 0, 0 }, + { "m_respawn_items", USERDEFS_M_RESPAWN_ITEMS, 0, 0 }, + { "m_respawn_monsters", USERDEFS_M_RESPAWN_MONSTERS, 0, 0 }, + { "m_respawn_inventory", USERDEFS_M_RESPAWN_INVENTORY, 0, 0 }, + { "m_recstat", USERDEFS_M_RECSTAT, 0, 0 }, + { "m_monsters_off", USERDEFS_M_MONSTERS_OFF, 0, 0 }, + { "detail", USERDEFS_DETAIL, 0, 0 }, + { "m_ffire", USERDEFS_M_FFIRE, 0, 0 }, + { "ffire", USERDEFS_FFIRE, 0, 0 }, + { "m_player_skill", USERDEFS_M_PLAYER_SKILL, 0, 0 }, + { "m_level_number", USERDEFS_M_LEVEL_NUMBER, 0, 0 }, + { "m_volume_number", USERDEFS_M_VOLUME_NUMBER, 0, 0 }, + { "multimode", USERDEFS_MULTIMODE, 0, 0 }, + { "player_skill", USERDEFS_PLAYER_SKILL, 0, 0 }, + { "level_number", USERDEFS_LEVEL_NUMBER, 0, 0 }, + { "volume_number", USERDEFS_VOLUME_NUMBER, 0, 0 }, + { "m_marker", USERDEFS_M_MARKER, 0, 0 }, + { "marker", USERDEFS_MARKER, 0, 0 }, + { "mouseflip", USERDEFS_MOUSEFLIP, 0, 0 }, + { "statusbarscale", USERDEFS_STATUSBARSCALE, 0, 0 }, + { "drawweapon", USERDEFS_DRAWWEAPON, 0, 0 }, + { "mouseaiming", USERDEFS_MOUSEAIMING, 0, 0 }, + { "weaponswitch", USERDEFS_WEAPONSWITCH, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST + }; + +LABELS inputlabels[]= { + { "avel", INPUT_AVEL, 0, 0 }, + { "horz", INPUT_HORZ, 0, 0 }, + { "fvel", INPUT_FVEL, 0, 0 }, + { "svel", INPUT_SVEL, 0, 0 }, + { "bits", INPUT_BITS, 0, 0 }, + { "bits2", INPUT_BITS2, 0, 0 }, + { "", -1, 0, 0 } // END OF LIST +}; + +void skipcomments(void) +{ + char c; + while ((c = *textptr)) + { + if (c == ' ' || c == '\t' || c == '\r') + textptr++; + else if (c == '\n') { + line_number++; + textptr++; + } + else if (c == '/' && textptr[1] == '/') + { + if (!(error || warning) && condebug > 1) + initprintf("%s:%ld: debug: got comment.\n",compilefile,line_number); + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + textptr++; + } + else if (c == '/' && textptr[1] == '*') + { + if (!(error || warning) && condebug > 1) + initprintf("%s:%ld: debug: got start of comment block.\n",compilefile,line_number); + while (*textptr && !(textptr[0] == '*' && textptr[1] == '/')) + { + if (*textptr == '\n') + line_number++; + textptr++; + } + if ((!(error || warning) && condebug > 1) && (textptr[0] == '*' && textptr[1] == '/')) + initprintf("%s:%ld: debug: got end of comment block.\n",compilefile,line_number); + if (!*textptr) + { + if(!(error || warning) && condebug) + initprintf("%s:%ld: debug: EOF in comment!\n",compilefile,line_number); + ReportError(-1); + initprintf("%s:%ld: error: found `/*' with no `*/'.\n",compilefile,line_number); + parsing_state = num_braces = 0; + parsing_actor = 0; + error++; + break; + } + else textptr+=2; + } + else break; + } +} + +void DefineProjectile(long lVar1, long lLabelID, long lVar2) +{ + switch(lLabelID) + { + case PROJ_WORKSLIKE: + projectile[lVar1].workslike=lVar2; + break; + + case PROJ_SPAWNS: + projectile[lVar1].spawns=lVar2; + break; + + case PROJ_SXREPEAT: + projectile[lVar1].sxrepeat=lVar2; + break; + + case PROJ_SYREPEAT: + projectile[lVar1].syrepeat=lVar2; + break; + + case PROJ_SOUND: + projectile[lVar1].sound=lVar2; + break; + + case PROJ_ISOUND: + projectile[lVar1].isound=lVar2; + break; + + case PROJ_VEL: + projectile[lVar1].vel=lVar2; + break; + + case PROJ_EXTRA: + projectile[lVar1].extra=lVar2; + break; + + case PROJ_DECAL: + projectile[lVar1].decal=lVar2; + break; + + case PROJ_TRAIL: + projectile[lVar1].trail=lVar2; + break; + + case PROJ_TXREPEAT: + projectile[lVar1].txrepeat=lVar2; + break; + + case PROJ_TYREPEAT: + projectile[lVar1].tyrepeat=lVar2; + break; + + case PROJ_TOFFSET: + projectile[lVar1].toffset=lVar2; + break; + + case PROJ_TNUM: + projectile[lVar1].tnum=lVar2; + break; + + case PROJ_DROP: + projectile[lVar1].drop=lVar2; + break; + + case PROJ_CSTAT: + projectile[lVar1].cstat=lVar2; + break; + + case PROJ_CLIPDIST: + projectile[lVar1].clipdist=lVar2; + break; + + case PROJ_SHADE: + projectile[lVar1].shade=lVar2; + break; + + case PROJ_XREPEAT: + projectile[lVar1].xrepeat=lVar2; + break; + + case PROJ_YREPEAT: + projectile[lVar1].yrepeat=lVar2; + break; + + case PROJ_PAL: + projectile[lVar1].pal=lVar2; + break; + + case PROJ_EXTRA_RAND: + projectile[lVar1].extra_rand=lVar2; + break; + + case PROJ_HITRADIUS: + projectile[lVar1].hitradius=lVar2; + break; + + case PROJ_VEL_MULT: + projectile[lVar1].velmult=lVar2; + break; + + case PROJ_OFFSET: + projectile[lVar1].offset=lVar2; + break; + + case PROJ_BOUNCES: + projectile[lVar1].bounces=lVar2; + break; + + case PROJ_BSOUND: + projectile[lVar1].bsound=lVar2; + break; + + case PROJ_RANGE: + projectile[lVar1].range=lVar2; + break; + + default: + break; + } + + // defaultprojectile[lVar1] = projectile[lVar1]; + Bmemcpy(&defaultprojectile[lVar1], &projectile[lVar1], sizeof(projectile[lVar1])); + + return; +} + +char CheckEventSync(int iEventID) +{ + if(parsing_event || parsing_actor) + { + switch(iEventID) + { + case EVENT_CHEATGETSTEROIDS: + case EVENT_CHEATGETHEAT: + case EVENT_CHEATGETBOOT: + case EVENT_CHEATGETSHIELD: + case EVENT_CHEATGETSCUBA: + case EVENT_CHEATGETHOLODUKE: + case EVENT_CHEATGETJETPACK: + case EVENT_CHEATGETFIRSTAID: + case EVENT_DISPLAYWEAPON: + case EVENT_DRAWWEAPON: + case EVENT_DISPLAYCROSSHAIR: + case EVENT_DISPLAYREST: + case EVENT_ENTERLEVEL: + case EVENT_GETLOADTILE: + case EVENT_GETMENUTILE: + case EVENT_INIT: + case EVENT_LOGO: + return 0; + default: + return 1; + } + } + return 1; +} + +void AddLog(char *psz) +{ + Bstrcpy(tempbuf,psz); + if(tempbuf[Bstrlen(psz)] != '\n') + Bstrcat(tempbuf,"\n"); + if (qsetmode == 200) OSD_Printf(tempbuf); + else initprintf(tempbuf); +} + +char AddGameVar(char *pszLabel, long lValue, unsigned long dwFlags); + +void ReadGameVars(long fil) +{ + int i; + long l; + + // AddLog("Reading gamevars from savegame"); + + kdfread(&l,sizeof(l),1,fil); + kdfread(g_szBuf,l,1,fil); + g_szBuf[l]=0; + AddLog(g_szBuf); + + FreeGameVars(); // nuke 'em from orbit, it's the only way to be sure... + // Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__); + // AddLog(g_szBuf); + + kdfread(&iGameVarCount,sizeof(iGameVarCount),1,fil); + + for(i=0;i (MAXVARLABEL-1) ) + { + error++; + initprintf("%s:%ld: error: variable name `%s' exceeds limit of %d characters.\n",compilefile,line_number,pszLabel, MAXVARLABEL); + return 0; + } + for(i=0;i= iGameVarCount) + { + if(id==MAXGAMEVARS) + return(*insptr++); + else if(id&(MAXGAMEVARS<<1)) + { + m=1; + id ^= (MAXGAMEVARS<<1); + } + else + { + AddLog("GetGameVarID: Invalid Game ID"); + return -1; + } + } + if( id == g_iThisActorID ) + { + return sActor; + } + if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERPLAYER ) + { + // for the current player + if(sPlayer >=0 && sPlayer < MAXPLAYERS) + { + //Bsprintf(g_szBuf,"GetGameVarID( %d, %d, %d) returns %ld\n",id,sActor,sPlayer, aGameVars[id].plValues[sPlayer]); + //AddLog(g_szBuf); + if(m) return -aGameVars[id].plValues[sPlayer]; + else return aGameVars[id].plValues[sPlayer]; + } + else + { + if(m) return -aGameVars[id].lValue; + else return aGameVars[id].lValue; + } + } + else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERACTOR ) + { + // for the current actor + if(sActor >= 0 && sActor <=MAXSPRITES) + { + if(m) return -aGameVars[id].plValues[sActor]; + else return aGameVars[id].plValues[sActor]; + } + else + { + if(m) return -aGameVars[id].lValue; + else return aGameVars[id].lValue; + } + } + else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PLONG ) + { + if(m) return -(*((long*)aGameVars[id].lValue)); + else return (*((long*)aGameVars[id].lValue)); + } + else + { + if(m) return -aGameVars[id].lValue; + else return aGameVars[id].lValue; + } + +} + +void SetGameVarID(int id, long lValue, short sActor, short sPlayer) +{ + if(id<0 || id >= iGameVarCount) + { + AddLog("Invalid Game ID"); + return; + } + //Bsprintf(g_szBuf,"SGVI: %d ('%s') to %ld for %d %d",id,aGameVars[id].szLabel,lValue,sActor,sPlayer); + //AddLog(g_szBuf); + if((aGameVars[id].dwFlags & GAMEVAR_FLAG_PERPLAYER) && (sPlayer != -1)) + { + // for the current player + aGameVars[id].plValues[sPlayer]=lValue; + } + else if((aGameVars[id].dwFlags & GAMEVAR_FLAG_PERACTOR) && (sActor != -1)) + { + // for the current actor + aGameVars[id].plValues[sActor]=lValue; + } + else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PLONG ) + { + // set the value at pointer + *((long*)aGameVars[id].lValue)=lValue; + } + else + { + aGameVars[id].lValue=lValue; + } + +} + +long GetGameVar(char *szGameLabel, long lDefault, short sActor, short sPlayer) +{ + int i; + for(i=0;i=0 ; i++) + { + if(!Bstrcasecmp(pLabel[i].name,psz)) + { + l= pLabel[i].lId; + break; // stop for loop + } + } + return l; +} + +long getlabeloffset(LABELS *pLabel, char *psz) +{ + // find the label psz in the table pLabel. + // returns the offset in the array for the label, or -1 + long l=-1; + int i; + + for(i=0;pLabel[i].lId >=0 ; i++) + { + if(!Bstrcasecmp(pLabel[i].name,psz)) + { + // printf("Label has flags of %02X\n",pLabel[i].flags); + return i; + } + } + return -1; +} + +void getlabel(void) +{ + long i; + + skipcomments(); + + while( isalnum(*textptr) == 0 ) + { + if(*textptr == 0x0a) line_number++; + textptr++; + if( *textptr == 0) + return; + } + + i = 0; + while( ispecial(*textptr) == 0 && *textptr!=']' ) + label[(labelcnt<<6)+i++] = *(textptr++); + + label[(labelcnt<<6)+i] = 0; + if (!(error || warning) && condebug > 1) + initprintf("%s:%ld: debug: got label `%s'.\n",compilefile,line_number,label+(labelcnt<<6)); +} + +long keyword(void) +{ + long i; + char *temptextptr; + + skipcomments(); + + temptextptr = textptr; + + while( isaltok(*temptextptr) == 0 ) + { + temptextptr++; + if( *temptextptr == 0 ) + return 0; + } + + i = 0; + while( isaltok(*temptextptr) ) + { + tempbuf[i] = *(temptextptr++); + i++; + } + tempbuf[i] = 0; + for(i=0;i 1) + initprintf("%s:%ld: debug: accepted gamevar `%s'.\n",compilefile,line_number,label+(labelcnt<<6)); + i |= f; + *scriptptr++=i; +} + +inline void transvar(void) +{ + transvartype(0); +} + +inline void transmultvarstype(int type, char num) +{ + char i; + for(i=0;i 1) + { + gl = translatelabeltype(labeltype[i]); + initprintf("%s:%ld: debug: accepted %s label `%s'.\n",compilefile,line_number,gl,label+(i<<6)); + Bfree(gl); + } + *(scriptptr++) = labelcode[i]; + textptr += l; + return labeltype[i]; + } + *(scriptptr++) = 0; + textptr += l; + el = translatelabeltype(type); + gl = translatelabeltype(labeltype[i]); + ReportError(-1); + initprintf("%s:%ld: warning: expected a %s, found a %s.\n",compilefile,line_number,el,gl); + Bfree(el); + Bfree(gl); + return -1; // valid label name, but wrong type + } + } + + if( isdigit(*textptr) == 0 && *textptr != '-') + { + ReportError(ERROR_PARAMUNDEFINED); + error++; + textptr+=l; + return -1; // error! + } + + if( isdigit(*textptr) && labelsonly ) + { + ReportError(WARNING_LABELSONLY); + // warning++; + } + if (!(error || warning) && condebug > 1) + initprintf("%s:%ld: debug: accepted constant %ld.\n",compilefile,line_number,atol(textptr)); + *scriptptr = atol(textptr); + scriptptr++; + + textptr += l; + + return 0; // literal value +} + +long CountCaseStatements() +{ + long lCount; + char *temptextptr; + long *savescript; + long *savecase; + short temp_line_number; + + + temp_line_number=line_number; + + casecount=0; + temptextptr=textptr; + savescript=scriptptr; + savecase=casescriptptr; + casescriptptr=NULL; + //Bsprintf(g_szBuf,"CSS: %.12s",textptr); + //AddLog(g_szBuf); + while(parsecommand() == 0) + { + //Bsprintf(g_szBuf,"CSSL: %.20s",textptr); + //AddLog(g_szBuf); + ; + } + // since we processed the endswitch, we need to re-increment checking_switch + checking_switch++; + + textptr=temptextptr; + scriptptr=savescript; + + line_number = temp_line_number; + + lCount=casecount; + casecount=0; + casescriptptr=savecase; + return lCount; +} + +char parsecommand(void) +{ + long i, j=0, k=0, *tempscrptr; + char done, *temptextptr; + + long tw; + + if (((unsigned)(scriptptr-script) > MAXSCRIPTSIZE) && error == 0) { + /* Bsprintf(tempbuf,"fatal error: Size of compiled CON code exceeds maximum size! (%ud, %d)\n",(unsigned)(scriptptr-script),MAXSCRIPTSIZE); */ + ReportError(-1); + initprintf("%s:%ld: internal compiler error: Aborted (%ud)\n",compilefile,line_number,(unsigned)(scriptptr-script)); + initprintf(tempbuf); + error++; + } + + if( (error+warning) > 63 || ( *textptr == '\0' ) || ( *(textptr+1) == '\0' ) ) return 1; + + if (checking_switch > 0 ) + { + //Bsprintf(g_szBuf,"PC(): '%.25s'",textptr); + //AddLog(g_szBuf); + } + tw = transword(); + // Bsprintf(tempbuf,"%s",keyw[tw]); + // AddLog(tempbuf); + + skipcomments(); // yes? no? + + switch(tw) + { + default: + case -1: + return 0; //End + case CON_STATE: + if( parsing_actor == 0 && parsing_state == 0 ) + { + getlabel(); + scriptptr--; + labelcode[labelcnt] = (long) scriptptr; + labeltype[labelcnt] = LABEL_STATE; + + parsing_state = 1; + Bsprintf(parsing_item_name,"%s",label+(labelcnt<<6)); + labelcnt++; + return 0; + } + + getlabel(); + + for(i=0;i 1) + initprintf("%s:%ld: debug: accepted state label `%s'.\n",compilefile,line_number,label+(j<<6)); + *scriptptr = labelcode[j]; + break; + } + else + { + char *gl; + gl = translatelabeltype(labeltype[j]); + ReportError(-1); + initprintf("%s:%ld: warning: expected a state, found a %s.\n",compilefile,line_number,gl); + Bfree(gl); + *(scriptptr-1) = CON_NULLOP; // get rid of the state, leaving a nullop to satisfy if conditions + return 0; // valid label name, but wrong type + } + } + } + if(j==labelcnt) + { + ReportError(-1); + initprintf("%s:%ld: error: state `%s' not found.\n",compilefile,line_number,label+(labelcnt<<6)); + error++; + } + scriptptr++; + return 0; + + case CON_ENDS: + if( parsing_state == 0 ) + { + ReportError(-1); + initprintf("%s:%ld: error: found `ends' without open `state'.\n",compilefile,line_number); + error++; + } + // else + { + if( num_braces > 0 ) + { + ReportError(ERROR_OPENBRACKET); + error++; + } + if( num_braces < 0 ) + { + ReportError(ERROR_CLOSEBRACKET); + error++; + } + if( checking_switch > 0 ) + { + ReportError(ERROR_NOENDSWITCH); + error++; + + checking_switch = 0; // can't be checking anymore... + } + + parsing_state = 0; + Bsprintf(parsing_item_name,"(none)"); + } + return 0; + + case CON_SETTHISPROJECTILE: + case CON_SETPROJECTILE: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETTHISPROJECTILE: + case CON_GETPROJECTILE: + { + long lLabelID; + + // syntax getwall[].x + // gets the value of wall[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + if(tw == CON_SETTHISPROJECTILE) + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabeloffset(projectilelabels,label+(labelcnt<<6)); + //printf("LabelID is %ld\n",lLabelID); + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + + *scriptptr++=projectilelabels[lLabelID].lId; + + //printf("member's flags are: %02Xh\n",playerlabels[lLabelID].flags); + + // now at target VAR... + + // get the ID of the DEF + switch(tw) + { + case CON_SETPROJECTILE: + case CON_SETTHISPROJECTILE: + transvar(); + break; + default: + transvartype(GAMEVAR_FLAG_READONLY); + break; + } + break; + } + + case CON_GAMEVAR: + // syntax: gamevar + // defines var1 and sets initial value. + // flags are used to define usage + // (see top of this files for flags) + //printf("Got gamedef. Getting Label. '%.20s'\n",textptr); + + if(isdigit(*textptr) || (*textptr == '-')) + { + getlabel(); + error++; + ReportError(ERROR_SYNTAXERROR); + transnum(LABEL_DEFINE); + transnum(LABEL_DEFINE); + scriptptr -= 3; // we complete the process anyways just to skip past the fucked up section + return 0; + } + + getlabel(); + //printf("Got Label '%.20s'\n",textptr); + // Check to see it's already defined + + for(i=0;i= defaultlabelcnt) + { + warning++; + ReportError(WARNING_DUPLICATEDEFINITION); + } + break; + } + } + //printf("Translating. '%.20s'\n",textptr); + transnum(LABEL_DEFINE); + //printf("Translated. '%.20s'\n",textptr); + if(i == labelcnt) + { + // printf("Defining Definition '%s' to be '%d'\n",label+(labelcnt<<6),*(scriptptr-1)); + labeltype[labelcnt] = LABEL_DEFINE; + labelcode[labelcnt++] = *(scriptptr-1); + if (*(scriptptr-1) >= 0 && *(scriptptr-1) < MAXTILES && dynamicremap) + processnames(label+(i<<6),*(scriptptr-1)); + } + scriptptr -= 2; + return 0; + } + + case CON_PALFROM: + for(j=0;j<4;j++) + { + if( keyword() == -1 ) + transnum(LABEL_DEFINE); + else break; + } + + while(j<4) + { + *scriptptr = 0; + scriptptr++; + j++; + } + return 0; + + case CON_MOVE: + if( parsing_actor || parsing_state ) + { + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transnum(LABEL_MOVE); + + j = 0; + while(keyword() == -1) + { + transnum(LABEL_DEFINE); + scriptptr--; + j |= *scriptptr; + } + *scriptptr = j; + + scriptptr++; + } + else + { + scriptptr--; + getlabel(); + // Check to see it's already defined + + for(i=0;i= 0) break; + transnum(LABEL_DEFINE); + } + for(k=j;k<2;k++) + { + *scriptptr = 0; + scriptptr++; + } + } + return 0; + + case CON_MUSIC: + { + // NOTE: this doesn't get stored in the PCode... + + // music 1 stalker.mid dethtoll.mid streets.mid watrwld1.mid snake1.mid + // thecall.mid ahgeez.mid dethtoll.mid streets.mid watrwld1.mid snake1.mid + scriptptr--; + transnum(LABEL_DEFINE); // Volume Number (0/4) + scriptptr--; + + k = *scriptptr-1; + + if(k >= 0) // if it's background music + { + i = 0; + // get the file name... + while(keyword() == -1) + { + while( isaltok(*textptr) == 0 ) + { + if(*textptr == 0x0a) line_number++; + textptr++; + if( *textptr == 0 ) break; + } + j = 0; + while( isaltok(*(textptr+j)) ) + { + music_fn[k][i][j] = textptr[j]; + j++; + } + music_fn[k][i][j] = '\0'; + textptr += j; + if(i > 9) break; + i++; + } + } + else + { + i = 0; + while(keyword() == -1) + { + while( isaltok(*textptr) == 0 ) + { + if(*textptr == 0x0a) line_number++; + textptr++; + if( *textptr == 0 ) break; + } + j = 0; + while( isaltok(*(textptr+j)) ) + { + env_music_fn[i][j] = textptr[j]; + j++; + } + env_music_fn[i][j] = '\0'; + + textptr += j; + if(i > 9) break; + i++; + } + } + } + return 0; + + case CON_INCLUDE: + scriptptr--; + while( isaltok(*textptr) == 0 ) + { + if(*textptr == 0x0a) line_number++; + textptr++; + if( *textptr == 0 ) break; + } + j = 0; + while( isaltok(*textptr) ) + { + tempbuf[j] = *(textptr++); + j++; + } + tempbuf[j] = '\0'; + + { + short temp_line_number; + char temp_ifelse_check; + char *origtptr, *mptr; + char parentcompilefile[255]; + int fp; + + fp = kopen4load(tempbuf,loadfromgrouponly); + if(fp < 0) + { + error++; + initprintf("%s:%ld: error: could not find file `%s'.\n",compilefile,line_number,tempbuf); + return 0; + } + + j = kfilelength(fp); + + mptr = (char *)Bmalloc(j+1); + if (!mptr) + { + kclose(fp); + error++; + initprintf("%s:%ld: error: could not allocate %ld bytes to include `%s'.\n", + line_number,compilefile,j,tempbuf); + return 0; + } + + initprintf("Including: %s (%ld bytes)\n",tempbuf, j); + kread(fp, mptr, j); + kclose(fp); + mptr[j] = 0; + + if (*textptr == '"') // skip past the closing quote if it's there so we don't screw up the next line + textptr++; + origtptr = textptr; + + Bstrcpy(parentcompilefile, compilefile); + Bstrcpy(compilefile, tempbuf); + temp_line_number = line_number; + line_number = 1; + temp_ifelse_check = checking_ifelse; + checking_ifelse = 0; + + textptr = mptr; + do done = parsecommand(); while (!done); + + Bstrcpy(compilefile, parentcompilefile); + total_lines += line_number; + line_number = temp_line_number; + checking_ifelse = temp_ifelse_check; + + textptr = origtptr; + + Bfree(mptr); + } + return 0; + + case CON_AI: + if( parsing_actor || parsing_state ) + { + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transnum(LABEL_AI); + } + else + { + scriptptr--; + getlabel(); + + for(i=0;i= 0) break; + if(j == 1) + transnum(LABEL_ACTION); + else if(j == 2) + { + transnum(LABEL_MOVE); + k = 0; + while(keyword() == -1) + { + transnum(LABEL_DEFINE); + scriptptr--; + k |= *scriptptr; + } + *scriptptr = k; + scriptptr++; + return 0; + } + } + for(k=j;k<3;k++) + { + *scriptptr = 0; + scriptptr++; + } + } + return 0; + + case CON_ACTION: + if( parsing_actor || parsing_state ) + { + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transnum(LABEL_ACTION); + } + else + { + scriptptr--; + getlabel(); + // Check to see it's already defined + + for(i=0;i= 0) break; + transnum(LABEL_DEFINE); + } + for(k=j;k<5;k++) + { + *scriptptr = 0; + scriptptr++; + } + } + return 0; + + case CON_ACTOR: + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + num_braces = 0; + scriptptr--; + parsing_actor = scriptptr; + + skipcomments(); + j = 0; + while( isaltok(*(textptr+j)) ) + { + parsing_item_name[j] = textptr[j]; + j++; + } + parsing_item_name[j] = 0; + transnum(LABEL_DEFINE); + // Bsprintf(parsing_item_name,"%s",label+(labelcnt<<6)); + scriptptr--; + actorscrptr[*scriptptr] = parsing_actor; + + for(j=0;j<4;j++) + { + *(parsing_actor+j) = 0; + if(j == 3) + { + j = 0; + while(keyword() == -1) + { + transnum(LABEL_DEFINE); + scriptptr--; + j |= *scriptptr; + } + *scriptptr = j; + scriptptr++; + break; + } + else + { + if(keyword() >= 0) + { + scriptptr += (4-j); + break; + } + switch(j) + { + case 0: transnum(LABEL_DEFINE); break; + case 1: transnum(LABEL_ACTION); break; + case 2: transnum(LABEL_MOVE|LABEL_DEFINE); break; + } + *(parsing_actor+j) = *(scriptptr-1); + } + } + checking_ifelse = 0; + return 0; + + case CON_ONEVENT: + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + num_braces = 0; + scriptptr--; + parsing_event = scriptptr; + parsing_actor = scriptptr; + + skipcomments(); + j = 0; + while( isaltok(*(textptr+j)) ) + { + parsing_item_name[j] = textptr[j]; + j++; + } + parsing_item_name[j] = 0; + labelsonly = 1; + transnum(LABEL_DEFINE); + labelsonly = 0; + scriptptr--; + j= *scriptptr; // type of event + current_event = j; + //Bsprintf(g_szBuf,"Adding Event for %d at %lX",j, parsing_event); + //AddLog(g_szBuf); + if(j>=MAXGAMEEVENTS || j < 0) + { + initprintf("%s:%ld: error: invalid event ID.\n",compilefile,line_number); + error++; + return 0; + } + + if(apScriptGameEvent[j]) + { + tempscrptr = parsing_event; + parsing_event = parsing_actor = 0; + ReportError(-1); + parsing_event = parsing_actor = tempscrptr; + initprintf("%s:%ld: warning: duplicate event `%s'.\n",compilefile,line_number,parsing_item_name); + } + else apScriptGameEvent[j]=parsing_event; + + checking_ifelse = 0; + + return 0; + + case CON_EVENTLOADACTOR: + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + num_braces = 0; + scriptptr--; + parsing_actor = scriptptr; + + skipcomments(); + j = 0; + while( isaltok(*(textptr+j)) ) + { + parsing_item_name[j] = textptr[j]; + j++; + } + parsing_item_name[j] = 0; + transnum(LABEL_DEFINE); + scriptptr--; + actorLoadEventScrptr[*scriptptr] = parsing_actor; + + checking_ifelse = 0; + return 0; + + case CON_USERACTOR: + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + num_braces = 0; + scriptptr--; + parsing_actor = scriptptr; + + transnum(LABEL_DEFINE); + scriptptr--; + + skipcomments(); + j = 0; + while( isaltok(*(textptr+j)) ) + { + parsing_item_name[j] = textptr[j]; + j++; + } + parsing_item_name[j] = 0; + + j = *scriptptr; + transnum(LABEL_DEFINE); + scriptptr--; + actorscrptr[*scriptptr] = parsing_actor; + actortype[*scriptptr] = j; + + for(j=0;j<4;j++) + { + *(parsing_actor+j) = 0; + if(j == 3) + { + j = 0; + while(keyword() == -1) + { + transnum(LABEL_DEFINE); + scriptptr--; + j |= *scriptptr; + } + *scriptptr = j; + scriptptr++; + break; + } + else + { + if(keyword() >= 0) + { + for (i=4-j; i; i--) *(scriptptr++) = 0; + break; + } + switch(j) + { + case 0: transnum(LABEL_DEFINE); break; + case 1: transnum(LABEL_ACTION); break; + case 2: transnum(LABEL_MOVE|LABEL_DEFINE); break; + } + *(parsing_actor+j) = *(scriptptr-1); + } + } + checking_ifelse = 0; + return 0; + + case CON_INSERTSPRITEQ: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + return 0; + + case CON_DYNQUOTE: + transnum(LABEL_DEFINE); + for(j = 0;j < 4;j++) + { + if( keyword() == -1 ) + transvar(); + else break; + } + + while(j < 4) + { + *scriptptr = 0; + scriptptr++; + j++; + } + return 0; + + case CON_ESPAWN: + case CON_ESHOOT: + case CON_QSPAWN: + case CON_EQSPAWN: + case CON_STRENGTH: + case CON_SHOOT: + case CON_ADDPHEALTH: + case CON_SPAWN: + case CON_CSTAT: + case CON_COUNT: + case CON_ENDOFGAME: + case CON_SPRITEPAL: + case CON_CACTOR: + case CON_MONEY: + case CON_ADDKILLS: + case CON_DEBUG: + case CON_ADDSTRENGTH: + case CON_CSTATOR: + case CON_MAIL: + case CON_PAPER: + case CON_SLEEPTIME: + case CON_CLIPDIST: + case CON_LOTSOFGLASS: + case CON_SAVE: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_ANGOFF: + case CON_USERQUOTE: + case CON_QUOTE: + case CON_SOUND: + case CON_GLOBALSOUND: + case CON_SOUNDONCE: + case CON_STOPSOUND: + transnum(LABEL_DEFINE); + if (tw == CON_CSTAT) + { + if(*(scriptptr-1) == 32767) + { + ReportError(-1); + initprintf("%s:%ld: warning: tried to set cstat 32767, using 32768 instead.\n",compilefile,line_number); + *(scriptptr-1) = 32768; + } + else if((*(scriptptr-1) & 32) && (*(scriptptr-1) & 16)) + { + i = *(scriptptr-1); + *(scriptptr-1) ^= 48; + ReportError(-1); + initprintf("%s:%ld: warning: tried to set cstat %ld, using %ld instead.\n",compilefile,line_number,i,*(scriptptr-1)); + } + } + return 0; + + case CON_HITRADIUS: + transnum(LABEL_DEFINE); + transnum(LABEL_DEFINE); + transnum(LABEL_DEFINE); + case CON_ADDAMMO: + case CON_ADDWEAPON: + case CON_SIZETO: + case CON_SIZEAT: + case CON_DEBRIS: + case CON_ADDINVENTORY: + case CON_GUTS: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transnum(LABEL_DEFINE); + transnum(LABEL_DEFINE); + break; + + case CON_ELSE: + if( checking_ifelse ) + { + checking_ifelse--; + tempscrptr = scriptptr; + scriptptr++; //Leave a spot for the fail location + parsecommand(); + *tempscrptr = (long) scriptptr; + } + else + { + scriptptr--; + error++; + ReportError(-1); + initprintf("%s:%ld: error: found `else' with no `if'.\n",compilefile,line_number); + } + return 0; + + case CON_SETSECTOR: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETSECTOR: + { + long lLabelID; + + // syntax getsector[].x + // gets the value of sector[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabelid(sectorlabels,label+(labelcnt<<6)); + + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + *scriptptr++=lLabelID; + + // now at target VAR... + + // get the ID of the DEF + if (tw==CON_GETSECTOR) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_FINDNEARACTOR: + case CON_FINDNEARACTOR3D: + case CON_FINDNEARSPRITE: + case CON_FINDNEARSPRITE3D: + { + + // syntax findnearactor + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + + transnum(LABEL_DEFINE); // get + + transnum(LABEL_DEFINE); // get maxdist + + switch(tw) + { + case CON_FINDNEARACTOR3D: + case CON_FINDNEARSPRITE3D: + transnum(LABEL_DEFINE); + default: + break; + } + + // target var + // get the ID of the DEF + transvartype(GAMEVAR_FLAG_READONLY); + break; + } + + case CON_FINDNEARACTORVAR: + case CON_FINDNEARACTOR3DVAR: + case CON_FINDNEARSPRITEVAR: + case CON_FINDNEARSPRITE3DVAR: + { + + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + + transnum(LABEL_DEFINE); // get + + // get the ID of the DEF + transvar(); + switch(tw) + { + case CON_FINDNEARACTOR3DVAR: + case CON_FINDNEARSPRITE3DVAR: + transvar(); + default: + break; + } + // target var + // get the ID of the DEF + transvartype(GAMEVAR_FLAG_READONLY); + break; + } + + case CON_SQRT: + { + // syntax sqrt + // gets the sqrt of invar into outvar + + // get the ID of the DEF + transvar(); + // target var + // get the ID of the DEF + transvartype(GAMEVAR_FLAG_READONLY); + break; + } + + case CON_SETWALL: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETWALL: + { + long lLabelID; + + + // syntax getwall[].x + // gets the value of wall[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabelid(walllabels,label+(labelcnt<<6)); + + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + *scriptptr++=lLabelID; + + // now at target VAR... + + // get the ID of the DEF + if (tw == CON_GETWALL) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_SETPLAYER: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETPLAYER: + { + long lLabelID; + + + // syntax getwall[].x + // gets the value of wall[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabeloffset(playerlabels,label+(labelcnt<<6)); + //printf("LabelID is %ld\n",lLabelID); + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + + *scriptptr++=playerlabels[lLabelID].lId; + + //printf("member's flags are: %02Xh\n",playerlabels[lLabelID].flags); + if (playerlabels[lLabelID].flags & LABEL_HASPARM2) + { + //printf("Member has PARM2\n"); + // get parm2 + // get the ID of the DEF + transvar(); + } + else + { + //printf("Member does not have Parm2\n"); + } + + // now at target VAR... + + // get the ID of the DEF + if (tw==CON_GETPLAYER) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_SETINPUT: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETINPUT: + { + long lLabelID; + + + // syntax getwall[].x + // gets the value of wall[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabeloffset(inputlabels,label+(labelcnt<<6)); + //printf("LabelID is %ld\n",lLabelID); + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + + *scriptptr++=inputlabels[lLabelID].lId; + + // now at target VAR... + + // get the ID of the DEF + if (tw==CON_GETINPUT) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_SETUSERDEF: + case CON_GETUSERDEF: + { + long lLabelID; + + // syntax [gs]etuserdef.x + // gets the value of ud.xxx into + + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabelid(userdefslabels,label+(labelcnt<<6)); + + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + *scriptptr++=lLabelID; + + // now at target VAR... + + // get the ID of the DEF + if (tw==CON_GETUSERDEF) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_SETACTORVAR: + case CON_SETPLAYERVAR: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETACTORVAR: + case CON_GETPLAYERVAR: + { + // syntax [gs]etactorvar[]. + // gets the value of the per-actor variable varx into VAR + + // now get name of + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of . + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + + // get the ID of the DEF + getlabel(); + //printf("found label of '%s'\n", label+(labelcnt<<6)); + + // Check to see if it's a keyword + for(i=0;i].x + // gets the value of wall[].xxx into + + // now get name of .xxx + while((*textptr != '[')) + { + textptr++; + } + if(*textptr == '[') + textptr++; + + // get the ID of the DEF + labelsonly = 1; + transvar(); + labelsonly = 0; + // now get name of .xxx + while(*textptr != '.') + { + if(*textptr == 0xa) + break; + if(!*textptr) + break; + + textptr++; + } + if(*textptr!='.') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + textptr++; + /// now pointing at 'xxx' + getlabel(); + //printf("found xxx label of '%s'\n", label+(labelcnt<<6)); + + lLabelID=getlabeloffset(actorlabels,label+(labelcnt<<6)); + //printf("LabelID is %ld\n",lLabelID); + if(lLabelID == -1 ) + { + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + + *scriptptr++=actorlabels[lLabelID].lId; + + //printf("member's flags are: %02Xh\n",actorlabels[lLabelID].flags); + if (actorlabels[lLabelID].flags & LABEL_HASPARM2) + { + //printf("Member has PARM2\n"); + // get parm2 + // get the ID of the DEF + transvar(); + } + else + { + //printf("Member does not have Parm2\n"); + } + + // now at target VAR... + + // get the ID of the DEF + if(tw == CON_GETACTOR) + transvartype(GAMEVAR_FLAG_READONLY); + else + transvar(); + break; + } + + case CON_ESHOOTVAR: + case CON_ESPAWNVAR: + case CON_QSPAWNVAR: + case CON_EQSPAWNVAR: + case CON_OPERATERESPAWNS: + case CON_OPERATEMASTERSWITCHES: + case CON_CHECKACTIVATORMOTION: + case CON_TIME: + case CON_INITTIMER: + case CON_LOCKPLAYER: + case CON_SHOOTVAR: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_SOUNDVAR: + case CON_GLOBALSOUNDVAR: + case CON_STOPSOUNDVAR: + case CON_SOUNDONCEVAR: + case CON_ANGOFFVAR: + case CON_CHECKAVAILWEAPON: + case CON_CHECKAVAILINVEN: + case CON_GUNIQHUDID: + case CON_SAVEGAMEVAR: + case CON_READGAMEVAR: + transvar(); + return 0; + + case CON_ENHANCED: + { + // don't store in pCode... + scriptptr--; + //printf("We are enhanced, baby...\n"); + transnum(LABEL_DEFINE); + scriptptr--; + if(*scriptptr > BYTEVERSION_JF) + { + warning++; + initprintf("%s:%ld: warning: need build %ld, found build %ld\n",compilefile,line_number,k,BYTEVERSION_JF); + } + break; + } + + case CON_DYNAMICREMAP: + { + scriptptr--; + initprintf("Dynamic tile remapping enabled.\n"); + dynamicremap = 1; + break; + } + + case CON_RANDVAR: + case CON_ZSHOOT: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_SETVAR: + case CON_ADDVAR: + case CON_SUBVAR: + case CON_DISPLAYRANDVAR: + case CON_MULVAR: + case CON_DIVVAR: + case CON_MODVAR: + case CON_ANDVAR: + case CON_ORVAR: + case CON_XORVAR: + case CON_SHIFTVARL: + case CON_SHIFTVARR: + + // syntax: [rand|add|set]var + // sets var1 to const1 + // adds const1 to var1 (const1 can be negative...) + //printf("Found [add|set]var at line= %ld\n",line_number); + + // get the ID of the DEF + if(tw != CON_ZSHOOT) + transvartype(GAMEVAR_FLAG_READONLY); + else transvar(); + + transnum(LABEL_DEFINE); // the number to check against... + return 0; + case CON_RANDVARVAR: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_SETVARVAR: + case CON_ADDVARVAR: + case CON_SUBVARVAR: + case CON_MULVARVAR: + case CON_DIVVARVAR: + case CON_MODVARVAR: + case CON_ANDVARVAR: + case CON_ORVARVAR: + case CON_XORVARVAR: + case CON_DISPLAYRANDVARVAR: + case CON_SIN: + case CON_COS: + transvartype(GAMEVAR_FLAG_READONLY); + transvar(); + return 0; + + case CON_SMAXAMMO: + case CON_ADDWEAPONVAR: + case CON_ACTIVATEBYSECTOR: + case CON_OPERATESECTORS: + case CON_OPERATEACTIVATORS: + case CON_SSP: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GMAXAMMO: + case CON_DIST: + case CON_LDIST: + case CON_TXDIST: + case CON_GETANGLE: + case CON_MULSCALE: + case CON_SETASPECT: + // get the ID of the DEF + switch(tw) + { + case CON_DIST: + case CON_LDIST: + case CON_TXDIST: + case CON_GETANGLE: + transvartype(GAMEVAR_FLAG_READONLY); + break; + default: + transvar(); + break; + } + + // get the ID of the DEF + if (tw == CON_GMAXAMMO) + transvartype(GAMEVAR_FLAG_READONLY); + else transvar(); + + switch(tw) + { + case CON_DIST: + case CON_LDIST: + case CON_TXDIST: + case CON_GETANGLE: + transvartype(GAMEVAR_FLAG_READONLY); + break; + case CON_MULSCALE: + transmultvars(2); + break; + } + return 0; + + case CON_FLASH: + return 0; + + case CON_DRAGPOINT: + transmultvars(3); + return 0; + + case CON_GETFLORZOFSLOPE: + case CON_GETCEILZOFSLOPE: + transmultvars(3); + transvartype(GAMEVAR_FLAG_READONLY); + return 0; + + case CON_DEFINEPROJECTILE: + { + short y; + signed long z; + + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + scriptptr--; + + transnum(LABEL_DEFINE); + j = *(scriptptr-1); + + if(j>=MAXTILES) + { + ReportError(ERROR_EXCEEDSMAXTILES); + error++; + } + + transnum(LABEL_DEFINE); + y = *(scriptptr-1); + transnum(LABEL_DEFINE); + z = *(scriptptr-1); + + DefineProjectile(j,y,z); + spriteflags[j] |= SPRITE_FLAG_PROJECTILE; + return 0; + } + + case CON_PROJECTILE: + { + int y; + signed long z; + char *bracepos; + + scriptptr--; + + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + transnum(LABEL_DEFINE); + scriptptr--; + j = *(scriptptr); + if(j>=MAXTILES) + { + ReportError(ERROR_EXCEEDSMAXTILES); + error++; + } + + num_braces = 0; + skipcomments(); + if(textptr[0]!='{') + { + while(textptr[0] != '}') + { + textptr++; + if (textptr[0] == '\n' || textptr[0] == '\r') + line_number++; + } + if(textptr[0]=='}') + textptr++; + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + num_braces++; + temptextptr = ++textptr; + + while(textptr[0] != '}') + textptr++; + if(textptr[0]!='}') + { + error++; + ReportError(ERROR_SYNTAXERROR); + return 0; + } + + bracepos=textptr; + textptr=temptextptr; + + while(textptr < bracepos) + { + getlabel(); + initprintf("%s:%ld: debug: label is `%s'\n",compilefile,line_number,label+(labelcnt<<6)); + y=getlabeloffset(projectilelabels,label+(labelcnt<<6)); + if(y != -1 ) + { + nokeywordcheck = 1; + transnum(LABEL_DEFINE); + nokeywordcheck = 0; + scriptptr--; + z = *(scriptptr); + DefineProjectile(j,y,z); + skipcomments(); + continue; + } + error++; + ReportError(ERROR_SYMBOLNOTRECOGNIZED); + return 0; + } + textptr = bracepos; + if(textptr[0] != '}') + { + initprintf("%s:%ld: error: EOF in projectile definition!\n",compilefile,line_number); + error++; + return 0; + } + num_braces--; + textptr++; + spriteflags[j] |= SPRITE_FLAG_PROJECTILE; + return 0; + } + + case CON_SPRITEFLAGS: + { + if( parsing_actor == 0 && parsing_state == 0 ) + { + scriptptr--; + + transnum(LABEL_DEFINE); + scriptptr--; + j = *scriptptr; + + if(j>=MAXTILES) + { + ReportError(ERROR_EXCEEDSMAXTILES); + error++; + } + + transnum(LABEL_DEFINE); + scriptptr--; + spriteflags[j] = *scriptptr; + + return 0; + } + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transvar(); + return 0; + } + + case CON_SPRITESHADOW: + case CON_SPRITENVG: + case CON_SPRITENOSHADE: + case CON_PRECACHE: + { + if( parsing_state || parsing_actor ) + { + ReportError(ERROR_FOUNDWITHIN); + error++; + } + + scriptptr--; + + transnum(LABEL_DEFINE); + scriptptr--; + j = *scriptptr; + + if(j>=MAXTILES) + { + ReportError(ERROR_EXCEEDSMAXTILES); + error++; + } + + switch (tw) + { + case CON_SPRITESHADOW: + spriteflags[*scriptptr] |= SPRITE_FLAG_SHADOW; + break; + case CON_SPRITENVG: + spriteflags[*scriptptr] |= SPRITE_FLAG_NVG; + break; + case CON_SPRITENOSHADE: + spriteflags[*scriptptr] |= SPRITE_FLAG_NOSHADE; + break; + case CON_PRECACHE: + spritecache[*scriptptr][0] = j; + transnum(LABEL_DEFINE); + scriptptr--; + i = *scriptptr; + if(i>=MAXTILES) + { + ReportError(ERROR_EXCEEDSMAXTILES); + error++; + } + spritecache[j][1] = i; + transnum(LABEL_DEFINE); + scriptptr--; + i = *scriptptr; + spritecache[j][2] = i; + break; + } + return 0; + } + + case CON_IFVARVARG: + case CON_IFVARVARL: + case CON_IFVARVARE: + case CON_IFVARVARN: + case CON_IFVARVARAND: + case CON_WHILEVARVARN: + transmultvars(2); + tempscrptr = scriptptr; + scriptptr++; // Leave a spot for the fail location + + j = keyword(); + parsecommand(); + + *tempscrptr = (long) scriptptr; + + if(tw != CON_WHILEVARVARN) checking_ifelse++; + return 0; + + case CON_SPGETLOTAG: + case CON_SPGETHITAG: + case CON_SECTGETLOTAG: + case CON_SECTGETHITAG: + case CON_GETTEXTUREFLOOR: + case CON_GETTEXTURECEILING: + // no paramaters... + return 0; + + case CON_STARTTRACK: + // one parameter (track#) + transnum(LABEL_DEFINE); + return 0; + + case CON_IFVARL: + case CON_IFVARG: + case CON_IFVARE: + case CON_IFVARN: + case CON_IFVARAND: + case CON_WHILEVARN: + + // get the ID of the DEF + transvar(); + transnum(LABEL_DEFINE); // the number to check against... + + tempscrptr = scriptptr; + scriptptr++; //Leave a spot for the fail location + + j = keyword(); + parsecommand(); + + *tempscrptr = (long) scriptptr; + + if(tw != CON_WHILEVARN) checking_ifelse++; + return 0; + + case CON_ADDLOGVAR: + + // syntax: addlogvar + + // prints the line number in the log file. + *scriptptr=line_number; + scriptptr++; + + // get the ID of the DEF + transvar(); + return 0; + + case CON_ROTATESPRITE: + if( parsing_event == 0 && parsing_state == 0) + { + ReportError(ERROR_EVENTONLY); + error++; + } + + // syntax: + // long x, long y, long z, short a, short tilenum, signed char shade, char orientation, x1, y1, x2, y2 + // myospal adds char pal + + // get the ID of the DEFs + + transmultvars(12); + break; + + case CON_GETZRANGE: + transmultvars(4); + transmultvarstype(GAMEVAR_FLAG_READONLY,4); + transmultvars(2); + break; + + case CON_HITSCAN: + // get the ID of the DEF + transmultvars(7); + transmultvarstype(GAMEVAR_FLAG_READONLY,6); + transvar(); + break; + + case CON_ROTATEPOINT: + case CON_NEARTAG: + transmultvars(5); + transmultvarstype(GAMEVAR_FLAG_READONLY,2); + if (tw == CON_NEARTAG) + { + transmultvarstype(GAMEVAR_FLAG_READONLY,2); + transmultvars(2); + } + break; + + case CON_MOVESPRITE: + case CON_SETSPRITE: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + transmultvars(4); + if (tw == CON_MOVESPRITE) + transvar(); + break; + + case CON_MINITEXT: + case CON_GAMETEXT: + case CON_DIGITALNUMBER: + if( parsing_event == 0 && parsing_state == 0) + { + ReportError(ERROR_EVENTONLY); + error++; + } + + switch(tw) + { + case CON_GAMETEXT: + case CON_DIGITALNUMBER: + transmultvars(6); + default: + transmultvars(5); + break; + } + break; + + case CON_UPDATESECTOR: + case CON_UPDATESECTORZ: + transmultvars(2); + if (tw==CON_UPDATESECTORZ) + transvar(); + transvartype(GAMEVAR_FLAG_READONLY); + break; + + case CON_MYOS: + case CON_MYOSPAL: + case CON_MYOSX: + case CON_MYOSPALX: + if( parsing_event == 0 && parsing_state == 0) + { + ReportError(ERROR_EVENTONLY); + error++; + } + + // syntax: + // long x, long y, short tilenum, signed char shade, char orientation + // myospal adds char pal + + transmultvars(5); + if(tw==CON_MYOSPAL || tw==CON_MYOSPALX) + { + // Parse: pal + + // get the ID of the DEF + transvar(); + } + break; + + case CON_FINDPLAYER: + case CON_FINDOTHERPLAYER: + case CON_DISPLAYRAND: + + // syntax: displayrand + // gets rand (not game rand) into + + // Get The ID of the DEF + transvartype(GAMEVAR_FLAG_READONLY); + break; + + case CON_SWITCH: + //AddLog("Got Switch statement"); + if(checking_switch) + { + // Bsprintf(g_szBuf,"ERROR::%s %d: Checking_switch=",__FILE__,__LINE__, checking_switch); + // AddLog(g_szBuf); + } + checking_switch++; // allow nesting (if other things work) + // Get The ID of the DEF + transvar(); + + tempscrptr= scriptptr; + *scriptptr++=0; // leave spot for end location (for after processing) + *scriptptr++=0; // count of case statements + casescriptptr=scriptptr; // the first case's pointer. + + *scriptptr++=0; // leave spot for 'default' location (null if none) + + j = keyword(); + temptextptr=textptr; + // probably does not allow nesting... + + //AddLog("Counting Case Statements..."); + + j=CountCaseStatements(); + //Bsprintf(g_szBuf,"Done Counting Case Statements: found %d.", j); + //AddLog(g_szBuf); + if(checking_switch>1) + { + // Bsprintf(g_szBuf,"ERROR::%s %d: Checking_switch=",__FILE__,__LINE__, checking_switch); + // AddLog(g_szBuf); + } + if( j<0 ) + { + return 1; + } + if (tempscrptr) + { + tempscrptr[1]=(long)j; // save count of cases + } + else + { + //Bsprintf(g_szBuf,"ERROR::%s %d",__FILE__,__LINE__); + //AddLog(g_szBuf); + } + + while(j--) + { + // leave room for statements + *scriptptr++=0; // value check + *scriptptr++=0; // code offset + } + + //Bsprintf(g_szBuf,"SWITCH1: '%.22s'",textptr); + //AddLog(g_szBuf); + + casecount=0; + + while ( parsecommand() == 0 ) + { + //Bsprintf(g_szBuf,"SWITCH2: '%.22s'",textptr); + //AddLog(g_szBuf); + } + //Bsprintf(g_szBuf,"SWITCHXX: '%.22s'",textptr); + //AddLog(g_szBuf); + // done processing switch. clean up. + if(checking_switch!=1) + { + // Bsprintf(g_szBuf,"ERROR::%s %d: Checking_switch=%d",__FILE__,__LINE__, checking_switch); + // AddLog(g_szBuf); + } + casecount=0; + if (tempscrptr) + { + tempscrptr[0]= (long)scriptptr - (long)&script[0]; // save 'end' location + } + else + { + //Bsprintf(g_szBuf,"ERROR::%s %d",__FILE__,__LINE__); + //AddLog(g_szBuf); + } + casescriptptr=NULL; + // decremented in endswitch. Don't decrement here... + // checking_switch--; // allow nesting (maybe if other things work) + tempscrptr=NULL; + if(checking_switch) + { + //Bsprintf(g_szBuf,"ERROR::%s %d: Checking_switch=%d",__FILE__,__LINE__, checking_switch); + //AddLog(g_szBuf); + } + //AddLog("End of Switch statement"); + break; + + case CON_CASE: + //AddLog("Found Case"); +repeatcase: + scriptptr--; // don't save in code + if(checking_switch<1) + { + error++; + ReportError(-1); + initprintf("%s:%ld: error: found `case' statement when not in switch\n",compilefile,line_number); + return 1; + } + casecount++; + //Bsprintf(g_szBuf,"case1: %.12s",textptr); + //AddLog(g_szBuf); + transnum(LABEL_DEFINE); + if(*textptr == ':') + textptr++; + //Bsprintf(g_szBuf,"case2: %.12s",textptr); + //AddLog(g_szBuf); + + j=*(--scriptptr); // get value + //Bsprintf(g_szBuf,"case: Value of case %ld is %ld",(long)casecount,(long)j); + //AddLog(g_szBuf); + if( casescriptptr) + { + //AddLog("Adding value to script"); + casescriptptr[casecount++]=j; // save value + casescriptptr[casecount]=(long)((long*)scriptptr-&script[0]); // save offset + } + // j = keyword(); + //Bsprintf(g_szBuf,"case3: %.12s",textptr); + //AddLog(g_szBuf); + + j = keyword(); + if (j == CON_CASE) + { + //AddLog("Found Repeat Case"); + transword(); // eat 'case' + goto repeatcase; + } + //Bsprintf(g_szBuf,"case4: '%.12s'",textptr); + //AddLog(g_szBuf); + while(parsecommand() == 0) + { + //Bsprintf(g_szBuf,"case5 '%.25s'",textptr); + //AddLog(g_szBuf); + j = keyword(); + if (j == CON_CASE) + { + //AddLog("Found Repeat Case"); + transword(); // eat 'case' + goto repeatcase; + } + } + //AddLog("End Case"); + return 0; + // break; + case CON_DEFAULT: + scriptptr--; // don't save + if(checking_switch<1) + { + error++; + ReportError(-1); + initprintf("%s:%ld: error: found `default' statement when not in switch\n",compilefile,line_number); + return 1; + } + if(casescriptptr && casescriptptr[0]!=0) + { + // duplicate default statement + error++; + ReportError(-1); + initprintf("%s:%ld: error: multiple `default' statements found in switch\n",compilefile,line_number); + } + if (casescriptptr) + { + casescriptptr[0]=(long)(scriptptr-&script[0]); // save offset + } + //Bsprintf(g_szBuf,"default: '%.22s'",textptr); + //AddLog(g_szBuf); + while( parsecommand() == 0) + { + //Bsprintf(g_szBuf,"defaultParse: '%.22s'",textptr); + //AddLog(g_szBuf); + ; + } + break; + + case CON_ENDSWITCH: + //AddLog("End Switch"); + checking_switch--; + if(checking_switch < 0 ) + { + error++; + ReportError(-1); + initprintf("%s:%ld: error: found `endswitch' without matching `switch'\n",compilefile,line_number); + } + if (casescriptptr) + { + int i; + + //Bsprintf(g_szBuf,"Default Offset is %ld\n Total of %ld cases",casescriptptr[0],(long)casecount/2); + //AddLog(g_szBuf); + for(i=1;i<=casecount;i++) + { + if (i & 1) + { + //Bsprintf(g_szBuf,"Case Value %d is %ld",i/2+1,casescriptptr[i]); + //AddLog(g_szBuf); + } + else + { + //Bsprintf(g_szBuf,"Offset %d is %ld",i/2+1,casescriptptr[i]); + //AddLog(g_szBuf); + } + } + } + else + { + //AddLog("Not saving case value: just counting"); + } + return 1; // end of block + break; + + case CON_CHANGESPRITESTAT: + case CON_CHANGESPRITESECT: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETPNAME: + case CON_STARTLEVEL: + case CON_QSTRCAT: + case CON_QSTRCPY: + transmultvars(2); + return 0; + case CON_SETACTORANGLE: + case CON_SETPLAYERANGLE: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_GETANGLETOTARGET: + case CON_GETACTORANGLE: + case CON_GETPLAYERANGLE: + // Syntax: + + // get the ID of the DEF + transvar(); + return 0; + + case CON_ADDLOG: + // syntax: addlog + + // prints the line number in the log file. + *scriptptr=line_number; + scriptptr++; + return 0; + + case CON_IFPINVENTORY: + case CON_IFRND: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_IFPDISTL: + case CON_IFPDISTG: + case CON_IFWASWEAPON: + case CON_IFACTIONCOUNT: + case CON_IFCOUNT: + case CON_IFACTOR: + case CON_IFSTRENGTH: + case CON_IFSPAWNEDBY: + case CON_IFGAPZL: + case CON_IFFLOORDISTL: + case CON_IFCEILINGDISTL: + // case 74: + case CON_IFPHEALTHL: + case CON_IFSPRITEPAL: + case CON_IFGOTWEAPONCE: + case CON_IFANGDIFFL: + case CON_IFSOUND: + case CON_IFAI: + case CON_IFACTION: + case CON_IFMOVE: + switch(tw) + { + case CON_IFAI: + transnum(LABEL_AI); + break; + case CON_IFACTION: + transnum(LABEL_ACTION); + break; + case CON_IFMOVE: + transnum(LABEL_MOVE); + break; + case CON_IFPINVENTORY: + transnum(LABEL_DEFINE); + transnum(LABEL_DEFINE); + break; + default: + transnum(LABEL_DEFINE); + break; + } + case CON_IFONWATER: + case CON_IFINWATER: + case CON_IFACTORNOTSTAYPUT: + case CON_IFCANSEE: + case CON_IFHITWEAPON: + case CON_IFSQUISHED: + case CON_IFDEAD: + case CON_IFCANSHOOTTARGET: + case CON_IFP: + case CON_IFHITSPACE: + case CON_IFOUTSIDE: + case CON_IFMULTIPLAYER: + case CON_IFINSPACE: + case CON_IFBULLETNEAR: + case CON_IFRESPAWN: + case CON_IFINOUTERSPACE: + case CON_IFNOTMOVING: + case CON_IFAWAYFROMWALL: + case CON_IFCANSEETARGET: + case CON_IFNOSOUNDS: + if(tw == CON_IFP) + { + j = 0; + do + { + transnum(LABEL_DEFINE); + scriptptr--; + j |= *scriptptr; + } + while(keyword() == -1); + *scriptptr = j; + scriptptr++; + } + + tempscrptr = scriptptr; + scriptptr++; //Leave a spot for the fail location + + j = keyword(); + parsecommand(); + + *tempscrptr = (long) scriptptr; + + checking_ifelse++; + return 0; + + case CON_LEFTBRACE: + if(!(parsing_state || parsing_actor || parsing_event)) + { + error++; + ReportError(ERROR_SYNTAXERROR); + } + num_braces++; + do + done = parsecommand(); + while( done == 0 ); + return 0; + + case CON_RIGHTBRACE: + num_braces--; + if( num_braces < 0 ) + { + if(checking_switch) + { + ReportError(ERROR_NOENDSWITCH); + } + + ReportError(-1); + initprintf("%s:%ld: error: found more `}' than `{'.\n",compilefile,line_number); + error++; + } + return 1; + + case CON_BETANAME: + scriptptr--; + j = 0; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + betaname[j] = *textptr; + j++; textptr++; + } + betaname[j] = 0; + return 0; + + case CON_DEFINEVOLUMENAME: + scriptptr--; + transnum(LABEL_DEFINE); + scriptptr--; + j = *scriptptr; + while( *textptr == ' ' ) textptr++; + + if (j < 0 || j > 6) + { + initprintf("%s:%ld: error: volume number exceeds maximum volume count.\n",compilefile,line_number); + error++; + while( *textptr != 0x0a && *textptr != 0 ) textptr++; + break; + } + + + i = 0; + + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + volume_names[j][i] = toupper(*textptr); + textptr++,i++; + if(i >= (signed)sizeof(volume_names[j])-1) + { + initprintf("%s:%ld: error: volume name exceeds limit of %ld characters.\n",compilefile,line_number,sizeof(volume_names[j])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + } + num_volumes = j+1; + volume_names[j][i] = '\0'; + return 0; + + case CON_DEFINESKILLNAME: + scriptptr--; + transnum(LABEL_DEFINE); + scriptptr--; + j = *scriptptr; + while( *textptr == ' ' ) textptr++; + + if (j < 0 || j >= 5) + { + initprintf("%s:%ld: error: skill number exceeds maximum skill count.\n",compilefile,line_number); + error++; + while( *textptr != 0x0a && *textptr != 0 ) textptr++; + break; + } + + + i = 0; + + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + skill_names[j][i] = toupper(*textptr); + textptr++,i++; + if(i >= (signed)sizeof(skill_names[j])-1) + { + initprintf("%s:%ld: error: skill name exceeds limit of %ld characters.\n",compilefile,line_number,sizeof(skill_names[j])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + } + skill_names[j][i] = '\0'; + return 0; + + case CON_DEFINEGAMETYPE: + scriptptr--; //remove opcode from compiled code + transnum(LABEL_DEFINE); //translate number + scriptptr--; //remove it from compiled code + j = *scriptptr; //put it into j + + transnum(LABEL_DEFINE); //translate number + scriptptr--; //remove it from compiled code + gametype_flags[j] = *scriptptr; //put it into the flags + + while( *textptr == ' ' ) textptr++; + + if (j < 0 || j >= MAXGAMETYPES) + { + initprintf("%s:%ld: error: gametype number exceeds maximum gametype count.\n",compilefile,line_number); + error++; + while( *textptr != 0x0a && *textptr != 0 ) textptr++; + break; + } + num_gametypes = j+1; + + i = 0; + + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + gametype_names[j][i] = toupper(*textptr); + textptr++,i++; + if(i >= (signed)sizeof(gametype_names[j])-1) + { + initprintf("%s:%ld: error: gametype name exceeds limit of %ld characters.\n",compilefile,line_number,sizeof(gametype_names[j])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + } + gametype_names[j][i] = '\0'; + return 0; + + case CON_DEFINELEVELNAME: + scriptptr--; + transnum(LABEL_DEFINE); + scriptptr--; + j = *scriptptr; + transnum(LABEL_DEFINE); + scriptptr--; + k = *scriptptr; + while( *textptr == ' ' ) textptr++; + + if (j < 0 || j > 6) + { + initprintf("%s:%ld: error: volume number exceeds maximum volume count.\n",compilefile,line_number); + error++; + while( *textptr != 0x0a && *textptr != 0 ) textptr++; + break; + } + if (k < 0 || k >= 11) + { + initprintf("%s:%ld: error: level number exceeds maximum number of levels per episode.\n", + line_number,compilefile); + error++; + while( *textptr != 0x0a && *textptr != 0 ) textptr++; + break; + } + + i = 0; + while( *textptr != ' ' && *textptr != 0x0a ) + { + level_file_names[j*11+k][i] = *textptr; + textptr++,i++; + if(i > BMAX_PATH) + { + initprintf("%s:%ld: error: level file name exceeds limit of %d characters.\n",compilefile,line_number,BMAX_PATH); + error++; + while( *textptr != ' ') textptr++; + break; + } + } + level_names[j*11+k][i] = '\0'; + + while( *textptr == ' ' ) textptr++; + + partime[j*11+k] = + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*26*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*26); + + textptr += 5; + while( *textptr == ' ' ) textptr++; + + designertime[j*11+k] = + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*26*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*26); + + textptr += 5; + while( *textptr == ' ' ) textptr++; + + i = 0; + + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + level_names[j*11+k][i] = toupper(*textptr); + textptr++,i++; + if(i >= (signed)sizeof(level_names[j*11+k])-1) + { + initprintf("%s:%ld: error: level name exceeds limit of %ld characters.\n",compilefile,line_number,sizeof(level_names[j*11+k])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + } + level_names[j*11+k][i] = '\0'; + return 0; + + case CON_DEFINEQUOTE: + case CON_REDEFINEQUOTE: + if (tw == CON_DEFINEQUOTE) + scriptptr--; + + transnum(LABEL_DEFINE); + + k = *(scriptptr-1); + + if(k >= NUMOFFIRSTTIMEACTIVE) + { + initprintf("%s:%ld: error: quote number exceeds limit of %ld.\n",compilefile,line_number,NUMOFFIRSTTIMEACTIVE); + error++; + } + + if (tw == CON_DEFINEQUOTE) + scriptptr--; + + i = 0; + + while( *textptr == ' ' ) + textptr++; + + if (tw == CON_REDEFINEQUOTE) + redefined_quotes++; + + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) + { + if(*textptr == '%' && *(textptr+1) == 's') + { + initprintf("%s:%ld: error: quote text contains string identifier.\n",compilefile,line_number); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + if (tw == CON_DEFINEQUOTE) + fta_quotes[k][i] = *textptr; + else redefined_fta_quotes[redefined_quotes][i] = *textptr; + textptr++,i++; + if(i >= (signed)sizeof(fta_quotes[k])-1) + { + initprintf("%s:%ld: error: quote text exceeds limit of %ld characters.\n",compilefile,line_number,sizeof(fta_quotes[k])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 ) textptr++; + break; + } + } + if (tw == CON_DEFINEQUOTE) + fta_quotes[k][i] = '\0'; + else + { + redefined_fta_quotes[redefined_quotes][i] = '\0'; + *scriptptr++=redefined_quotes; + } + return 0; + + case CON_CHEATKEYS: + scriptptr--; + transnum(LABEL_DEFINE); + cheatkey[0] = *(scriptptr-1); + transnum(LABEL_DEFINE); + cheatkey[1] = *(scriptptr-1); + return 0; + + case CON_DEFINECHEAT: + scriptptr--; + transnum(LABEL_DEFINE); + k = *(scriptptr-1); + + if(k > 25) + { + initprintf("%s:%ld: error: cheat redefinition attempts to redefine nonexistant cheat.\n",compilefile,line_number); + error++; + } + scriptptr--; + i = 0; + while( *textptr == ' ' ) + textptr++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 && *textptr != ' ') + { + cheatquotes[k][i] = *textptr; + textptr++,i++; + if(i >= (signed)sizeof(cheatquotes[k])-1) + { + initprintf("%s:%ld: error: cheat exceeds limit of %ld characters.\n",compilefile,line_number,MAXCHEATLEN,sizeof(cheatquotes[k])-1); + error++; + while( *textptr != 0x0a && *textptr != 0x0d && *textptr != 0 && *textptr != ' ') textptr++; + break; + } + } + cheatquotes[k][i] = '\0'; + return 0; + + case CON_DEFINESOUND: + scriptptr--; + transnum(LABEL_DEFINE); + k = *(scriptptr-1); + if(k >= NUM_SOUNDS) + { + initprintf("%s:%ld: error: exceeded sound limit of %ld.\n",compilefile,line_number,NUM_SOUNDS); + error++; + } + scriptptr--; + i = 0; + while( *textptr == ' ') + textptr++; + + while( *textptr != ' ' ) + { + sounds[k][i] = *textptr; + textptr++,i++; + if(i >= BMAX_PATH) + { + puts(sounds[k]); + initprintf("%s:%ld: error: sound filename exceeds limit of %d characters.\n",compilefile,line_number,BMAX_PATH); + error++; + while( *textptr != ' ' ) textptr++; + break; + } + } + sounds[k][i] = '\0'; + + transnum(LABEL_DEFINE); + soundps[k] = *(scriptptr-1); + scriptptr--; + transnum(LABEL_DEFINE); + soundpe[k] = *(scriptptr-1); + scriptptr--; + transnum(LABEL_DEFINE); + soundpr[k] = *(scriptptr-1); + scriptptr--; + transnum(LABEL_DEFINE); + soundm[k] = *(scriptptr-1); + scriptptr--; + transnum(LABEL_DEFINE); + soundvo[k] = *(scriptptr-1); + scriptptr--; + return 0; + + case CON_ENDEVENT: + + if( parsing_event == 0) + { + ReportError(-1); + initprintf("%s:%ld: error: found `endevent' without open `onevent'.\n",compilefile,line_number); + error++; + } + if( num_braces > 0 ) + { + ReportError(ERROR_OPENBRACKET); + error++; + } + if( num_braces < 0 ) + { + ReportError(ERROR_CLOSEBRACKET); + error++; + } + parsing_event = 0; + parsing_actor = 0; + current_event = -1; + Bsprintf(parsing_item_name,"(none)"); + return 0; + + case CON_ENDA: + if( parsing_actor == 0 ) + { + ReportError(-1); + initprintf("%s:%ld: error: found `enda' without open `actor'.\n",compilefile,line_number); + error++; + } + if( num_braces > 0 ) + { + ReportError(ERROR_OPENBRACKET); + error++; + } + if( num_braces < 0 ) + { + ReportError(ERROR_CLOSEBRACKET); + error++; + } + parsing_actor = 0; + Bsprintf(parsing_item_name,"(none)"); + return 0; + + case CON_BREAK: + if(checking_switch) + { + //Bsprintf(g_szBuf," * (L%ld) case Break statement.\n",line_number); + //AddLog(g_szBuf); + return 1; + } + return 0; + + case CON_FALL: + case CON_TIP: + // case 21: + case CON_KILLIT: + case CON_RESETACTIONCOUNT: + case CON_PSTOMP: + case CON_RESETPLAYER: + case CON_RESETCOUNT: + case CON_WACKPLAYER: + case CON_OPERATE: + case CON_RESPAWNHITAG: + case CON_GETLASTPAL: + case CON_PKICK: + case CON_MIKESND: + case CON_TOSSWEAPON: + if(!CheckEventSync(current_event)) + ReportError(WARNING_EVENTSYNC); + case CON_NULLOP: + case CON_STOPALLSOUNDS: + return 0; + case CON_GAMESTARTUP: + { + long params[30]; + + scriptptr--; + for(j = 0; j < 30; j++) + { + transnum(LABEL_DEFINE); + scriptptr--; + params[j] = *scriptptr; + + if (j != 25) continue; + + if (keyword() != -1) { + initprintf("Version 1.3D CON files detected.\n"); + break; + } else { + conversion = 14; + initprintf("Version 1.4+ CON files detected.\n"); + } + + } + + /* + v1.3d v1.5 + DEFAULTVISIBILITY DEFAULTVISIBILITY + GENERICIMPACTDAMAGE GENERICIMPACTDAMAGE + MAXPLAYERHEALTH MAXPLAYERHEALTH + STARTARMORHEALTH STARTARMORHEALTH + RESPAWNACTORTIME RESPAWNACTORTIME + RESPAWNITEMTIME RESPAWNITEMTIME + RUNNINGSPEED RUNNINGSPEED + RPGBLASTRADIUS GRAVITATIONALCONSTANT + PIPEBOMBRADIUS RPGBLASTRADIUS + SHRINKERBLASTRADIUS PIPEBOMBRADIUS + TRIPBOMBBLASTRADIUS SHRINKERBLASTRADIUS + MORTERBLASTRADIUS TRIPBOMBBLASTRADIUS + BOUNCEMINEBLASTRADIUS MORTERBLASTRADIUS + SEENINEBLASTRADIUS BOUNCEMINEBLASTRADIUS + MAXPISTOLAMMO SEENINEBLASTRADIUS + MAXSHOTGUNAMMO MAXPISTOLAMMO + MAXCHAINGUNAMMO MAXSHOTGUNAMMO + MAXRPGAMMO MAXCHAINGUNAMMO + MAXHANDBOMBAMMO MAXRPGAMMO + MAXSHRINKERAMMO MAXHANDBOMBAMMO + MAXDEVISTATORAMMO MAXSHRINKERAMMO + MAXTRIPBOMBAMMO MAXDEVISTATORAMMO + MAXFREEZEAMMO MAXTRIPBOMBAMMO + CAMERASDESTRUCTABLE MAXFREEZEAMMO + NUMFREEZEBOUNCES MAXGROWAMMO + FREEZERHURTOWNER CAMERASDESTRUCTABLE + NUMFREEZEBOUNCES + FREEZERHURTOWNER + QSIZE + TRIPBOMBLASERMODE + */ + + j = 0; + ud.const_visibility = params[j++]; + impact_damage = params[j++]; + max_player_health = params[j++]; + max_armour_amount = params[j++]; + respawnactortime = params[j++]; + respawnitemtime = params[j++]; + dukefriction = params[j++]; + if (conversion == 14) gc = params[j++]; + rpgblastradius = params[j++]; + pipebombblastradius = params[j++]; + shrinkerblastradius = params[j++]; + tripbombblastradius = params[j++]; + morterblastradius = params[j++]; + bouncemineblastradius = params[j++]; + seenineblastradius = params[j++]; + max_ammo_amount[PISTOL_WEAPON] = params[j++]; + max_ammo_amount[SHOTGUN_WEAPON] = params[j++]; + max_ammo_amount[CHAINGUN_WEAPON] = params[j++]; + max_ammo_amount[RPG_WEAPON] = params[j++]; + max_ammo_amount[HANDBOMB_WEAPON] = params[j++]; + max_ammo_amount[SHRINKER_WEAPON] = params[j++]; + max_ammo_amount[DEVISTATOR_WEAPON] = params[j++]; + max_ammo_amount[TRIPBOMB_WEAPON] = params[j++]; + max_ammo_amount[FREEZE_WEAPON] = params[j++]; + if (conversion == 14) max_ammo_amount[GROW_WEAPON] = params[j++]; + camerashitable = params[j++]; + numfreezebounces = params[j++]; + freezerhurtowner = params[j++]; + if (conversion == 14) { + spriteqamount = params[j++]; + if(spriteqamount > 1024) spriteqamount = 1024; + else if(spriteqamount < 0) spriteqamount = 0; + + lasermode = params[j++]; + } + } + return 0; + } + return 0; +} + +void passone(void) +{ +#ifdef DEBUG + int i; +#endif + + while( parsecommand() == 0 ); + + if( (error+warning) > 63) + initprintf( "fatal error: too many warnings or errors: Aborted\n"); + +#ifdef DEBUG + initprintf("Game Definitions\n"); + for(i=0;i + +#include "duke3d.h" +#include "gamedef.h" +#include "scriplib.h" + +#include "osd.h" + +static short g_i,g_p; +static long g_x,*g_t; +static spritetype *g_sp; + +extern int32 scripthandle; + +void DoUserDef(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer, long lParm2) +{ + int iPlayer; + long lValue; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + if(sPlayer != myconnectindex) return; + + switch(lLabelID) + { + case USERDEFS_GOD: + if(bSet) + ud.god = lValue; + else + SetGameVarID((int)lVar2, ud.god, sActor, sPlayer); + break; + + case USERDEFS_WARP_ON: + if(bSet) + ud.warp_on = lValue; + else + SetGameVarID((int)lVar2, ud.warp_on, sActor, sPlayer); + break; + + case USERDEFS_CASHMAN: + if(bSet) + ud.cashman = lValue; + else + SetGameVarID((int)lVar2, ud.cashman, sActor, sPlayer); + break; + + case USERDEFS_EOG: + if(bSet) + ud.eog = lValue; + else + SetGameVarID((int)lVar2, ud.eog, sActor, sPlayer); + break; + + case USERDEFS_SHOWALLMAP: + if(bSet) + ud.showallmap = lValue; + else + SetGameVarID((int)lVar2, ud.showallmap, sActor, sPlayer); + break; + + case USERDEFS_SHOW_HELP: + if(bSet) + ud.show_help = lValue; + else + SetGameVarID((int)lVar2, ud.show_help, sActor, sPlayer); + break; + + case USERDEFS_SCROLLMODE: + if(bSet) + ud.scrollmode = lValue; + else + SetGameVarID((int)lVar2, ud.scrollmode, sActor, sPlayer); + break; + + case USERDEFS_CLIPPING: + if(bSet) + ud.clipping = lValue; + else + SetGameVarID((int)lVar2, ud.clipping, sActor, sPlayer); + break; + + // case USERDEFS_USER_NAME: + // if(bSet) + // { + // ud.user_name[MAXPLAYERS][32] = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.user_name[MAXPLAYERS][32], sActor, sPlayer); + // } + // break; + + // case USERDEFS_RIDECULE: + // if(bSet) + // { + // ud.ridecule = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.ridecule, sActor, sPlayer); + // } + // break; + + // case USERDEFS_SAVEGAME: + // if(bSet) + // { + // ud.savegame = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.savegame, sActor, sPlayer); + // } + // break; + + // case USERDEFS_PWLOCKOUT: + // if(bSet) + // { + // ud.pwlockout = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.pwlockout, sActor, sPlayer); + // } + // break; + + // case USERDEFS_RTSNAME: + // if(bSet) + // { + // ud.rtsname = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.rtsname, sActor, sPlayer); + // } + // break; + + case USERDEFS_OVERHEAD_ON: + if(bSet) + ud.overhead_on = lValue; + else + SetGameVarID((int)lVar2, ud.overhead_on, sActor, sPlayer); + break; + + case USERDEFS_LAST_OVERHEAD: + if(bSet) + ud.last_overhead = lValue; + else + SetGameVarID((int)lVar2, ud.last_overhead, sActor, sPlayer); + break; + + case USERDEFS_SHOWWEAPONS: + if(bSet) + ud.showweapons = lValue; + else + SetGameVarID((int)lVar2, ud.showweapons, sActor, sPlayer); + break; + + + case USERDEFS_PAUSE_ON: + if(bSet) + ud.pause_on = lValue; + else + SetGameVarID((int)lVar2, ud.pause_on, sActor, sPlayer); + break; + + case USERDEFS_FROM_BONUS: + if(bSet) + ud.from_bonus = lValue; + else + SetGameVarID((int)lVar2, ud.from_bonus, sActor, sPlayer); + break; + + case USERDEFS_CAMERASPRITE: + if(bSet) + ud.camerasprite = lValue; + else + SetGameVarID((int)lVar2, ud.camerasprite, sActor, sPlayer); + break; + + case USERDEFS_LAST_CAMSPRITE: + if(bSet) + ud.last_camsprite = lValue; + else + SetGameVarID((int)lVar2, ud.last_camsprite, sActor, sPlayer); + break; + + case USERDEFS_LAST_LEVEL: + if(bSet) + ud.last_level = lValue; + else + SetGameVarID((int)lVar2, ud.last_level, sActor, sPlayer); + break; + + case USERDEFS_SECRETLEVEL: + if(bSet) + ud.secretlevel = lValue; + else + SetGameVarID((int)lVar2, ud.secretlevel, sActor, sPlayer); + break; + + case USERDEFS_CONST_VISIBILITY: + if(bSet) + ud.const_visibility = lValue; + else + SetGameVarID((int)lVar2, ud.const_visibility, sActor, sPlayer); + break; + + case USERDEFS_UW_FRAMERATE: + if(bSet) + ud.uw_framerate = lValue; + else + SetGameVarID((int)lVar2, ud.uw_framerate, sActor, sPlayer); + break; + + case USERDEFS_CAMERA_TIME: + if(bSet) + ud.camera_time = lValue; + else + SetGameVarID((int)lVar2, ud.camera_time, sActor, sPlayer); + break; + + case USERDEFS_FOLFVEL: + if(bSet) + ud.folfvel = lValue; + else + SetGameVarID((int)lVar2, ud.folfvel, sActor, sPlayer); + break; + + case USERDEFS_FOLAVEL: + if(bSet) + ud.folavel = lValue; + else + SetGameVarID((int)lVar2, ud.folavel, sActor, sPlayer); + break; + + case USERDEFS_FOLX: + if(bSet) + ud.folx = lValue; + else + SetGameVarID((int)lVar2, ud.folx, sActor, sPlayer); + break; + + case USERDEFS_FOLY: + if(bSet) + ud.foly = lValue; + else + SetGameVarID((int)lVar2, ud.foly, sActor, sPlayer); + break; + + case USERDEFS_FOLA: + if(bSet) + ud.fola = lValue; + else + SetGameVarID((int)lVar2, ud.fola, sActor, sPlayer); + break; + + case USERDEFS_RECCNT: + if(bSet) + ud.reccnt = lValue; + else + SetGameVarID((int)lVar2, ud.reccnt, sActor, sPlayer); + break; + + case USERDEFS_ENTERED_NAME: + if(bSet) + ud.entered_name = lValue; + else + SetGameVarID((int)lVar2, ud.entered_name, sActor, sPlayer); + break; + + case USERDEFS_SCREEN_TILTING: + if(bSet) + ud.screen_tilting = lValue; + else + SetGameVarID((int)lVar2, ud.screen_tilting, sActor, sPlayer); + break; + + case USERDEFS_SHADOWS: + if(bSet) + ud.shadows = lValue; + else + SetGameVarID((int)lVar2, ud.shadows, sActor, sPlayer); + break; + + case USERDEFS_FTA_ON: + if(bSet) + ud.fta_on = lValue; + else + SetGameVarID((int)lVar2, ud.fta_on, sActor, sPlayer); + break; + + case USERDEFS_EXECUTIONS: + if(bSet) + ud.executions = lValue; + else + SetGameVarID((int)lVar2, ud.executions, sActor, sPlayer); + break; + + case USERDEFS_AUTO_RUN: + if(bSet) + ud.auto_run = lValue; + else + SetGameVarID((int)lVar2, ud.auto_run, sActor, sPlayer); + break; + + case USERDEFS_COORDS: + if(bSet) + ud.coords = lValue; + else + SetGameVarID((int)lVar2, ud.coords, sActor, sPlayer); + break; + + case USERDEFS_TICKRATE: + if(bSet) + ud.tickrate = lValue; + else + SetGameVarID((int)lVar2, ud.tickrate, sActor, sPlayer); + break; + + case USERDEFS_M_COOP: + if(bSet) + ud.m_coop = lValue; + else + SetGameVarID((int)lVar2, ud.m_coop, sActor, sPlayer); + break; + + case USERDEFS_COOP: + if(bSet) + ud.coop = lValue; + else + SetGameVarID((int)lVar2, ud.coop, sActor, sPlayer); + break; + + case USERDEFS_SCREEN_SIZE: + if(bSet) + ud.screen_size = lValue; + else + SetGameVarID((int)lVar2, ud.screen_size, sActor, sPlayer); + break; + + case USERDEFS_LOCKOUT: + if(bSet) + ud.lockout = lValue; + else + SetGameVarID((int)lVar2, ud.lockout, sActor, sPlayer); + break; + + case USERDEFS_CROSSHAIR: + if(bSet) + ud.crosshair = lValue; + else + SetGameVarID((int)lVar2, ud.crosshair, sActor, sPlayer); + break; + + // case USERDEFS_WCHOICE: + // if(bSet) + // { + // ud.wchoice = lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ud.wchoice, sActor, sPlayer); + // } + // break; + + case USERDEFS_PLAYERAI: + if(bSet) + ud.playerai = lValue; + else + SetGameVarID((int)lVar2, ud.playerai, sActor, sPlayer); + break; + + case USERDEFS_RESPAWN_MONSTERS: + if(bSet) + ud.respawn_monsters = lValue; + else + SetGameVarID((int)lVar2, ud.respawn_monsters, sActor, sPlayer); + break; + + case USERDEFS_RESPAWN_ITEMS: + if(bSet) + ud.respawn_items = lValue; + else + SetGameVarID((int)lVar2, ud.respawn_items, sActor, sPlayer); + break; + + case USERDEFS_RESPAWN_INVENTORY: + if(bSet) + ud.respawn_inventory = lValue; + else + SetGameVarID((int)lVar2, ud.respawn_inventory, sActor, sPlayer); + break; + + case USERDEFS_RECSTAT: + if(bSet) + ud.recstat = lValue; + else + SetGameVarID((int)lVar2, ud.recstat, sActor, sPlayer); + break; + + case USERDEFS_MONSTERS_OFF: + if(bSet) + ud.monsters_off = lValue; + else + SetGameVarID((int)lVar2, ud.monsters_off, sActor, sPlayer); + break; + + case USERDEFS_BRIGHTNESS: + if(bSet) + ud.brightness = lValue; + else + SetGameVarID((int)lVar2, ud.brightness, sActor, sPlayer); + break; + + case USERDEFS_M_RESPAWN_ITEMS: + if(bSet) + ud.m_respawn_items = lValue; + else + SetGameVarID((int)lVar2, ud.m_respawn_items, sActor, sPlayer); + break; + + case USERDEFS_M_RESPAWN_MONSTERS: + if(bSet) + ud.m_respawn_monsters = lValue; + else + SetGameVarID((int)lVar2, ud.m_respawn_monsters, sActor, sPlayer); + break; + + case USERDEFS_M_RESPAWN_INVENTORY: + if(bSet) + ud.m_respawn_inventory = lValue; + else + SetGameVarID((int)lVar2, ud.m_respawn_inventory, sActor, sPlayer); + break; + + case USERDEFS_M_RECSTAT: + if(bSet) + ud.m_recstat = lValue; + else + SetGameVarID((int)lVar2, ud.m_recstat, sActor, sPlayer); + break; + + case USERDEFS_M_MONSTERS_OFF: + if(bSet) + ud.m_monsters_off = lValue; + else + SetGameVarID((int)lVar2, ud.m_monsters_off, sActor, sPlayer); + break; + + case USERDEFS_DETAIL: + if(bSet) + ud.detail = lValue; + else + SetGameVarID((int)lVar2, ud.detail, sActor, sPlayer); + break; + + case USERDEFS_M_FFIRE: + if(bSet) + ud.m_ffire = lValue; + else + SetGameVarID((int)lVar2, ud.m_ffire, sActor, sPlayer); + break; + + case USERDEFS_FFIRE: + if(bSet) + ud.ffire = lValue; + else + SetGameVarID((int)lVar2, ud.ffire, sActor, sPlayer); + break; + + case USERDEFS_M_PLAYER_SKILL: + if(bSet) + ud.m_player_skill = lValue; + else + SetGameVarID((int)lVar2, ud.m_player_skill, sActor, sPlayer); + break; + + case USERDEFS_M_LEVEL_NUMBER: + if(bSet) + ud.m_level_number = lValue; + else + SetGameVarID((int)lVar2, ud.m_level_number, sActor, sPlayer); + break; + + case USERDEFS_M_VOLUME_NUMBER: + if(bSet) + ud.m_volume_number = lValue; + else + SetGameVarID((int)lVar2, ud.m_volume_number, sActor, sPlayer); + break; + + case USERDEFS_MULTIMODE: + if(bSet) + ud.multimode = lValue; + else + SetGameVarID((int)lVar2, ud.multimode, sActor, sPlayer); + break; + + case USERDEFS_PLAYER_SKILL: + if(bSet) + ud.player_skill = lValue; + else + SetGameVarID((int)lVar2, ud.player_skill, sActor, sPlayer); + break; + + case USERDEFS_LEVEL_NUMBER: + if(bSet) + ud.level_number = lValue; + else + SetGameVarID((int)lVar2, ud.level_number, sActor, sPlayer); + break; + + case USERDEFS_VOLUME_NUMBER: + if(bSet) + ud.volume_number = lValue; + else + SetGameVarID((int)lVar2, ud.volume_number, sActor, sPlayer); + break; + + case USERDEFS_M_MARKER: + if(bSet) + ud.m_marker = lValue; + else + SetGameVarID((int)lVar2, ud.m_marker, sActor, sPlayer); + break; + + case USERDEFS_MARKER: + if(bSet) + ud.marker = lValue; + else + SetGameVarID((int)lVar2, ud.marker, sActor, sPlayer); + break; + + case USERDEFS_MOUSEFLIP: + if(bSet) + ud.mouseflip = lValue; + else + SetGameVarID((int)lVar2, ud.mouseflip, sActor, sPlayer); + break; + + case USERDEFS_STATUSBARSCALE: + if(bSet) + ud.statusbarscale = lValue; + else + SetGameVarID((int)lVar2, ud.statusbarscale, sActor, sPlayer); + break; + + case USERDEFS_DRAWWEAPON: + if(bSet) + ud.drawweapon = lValue; + else + SetGameVarID((int)lVar2, ud.drawweapon, sActor, sPlayer); + break; + + case USERDEFS_MOUSEAIMING: + if(bSet) + ud.mouseaiming = lValue; + else + SetGameVarID((int)lVar2, ud.mouseaiming, sActor, sPlayer); + break; + + case USERDEFS_WEAPONSWITCH: + if(bSet) + ud.weaponswitch = lValue; + else + SetGameVarID((int)lVar2, ud.weaponswitch, sActor, sPlayer); + break; + + default: + break; + } + return; +} + +void DoThisProjectile(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer) +{ + long lValue,proj; + + if(lVar1 == g_iThisActorID ) + { + // if they've asked for 'this', then use 'this'... + proj=sActor; + } + else + { + if(sActor < 0 || sActor >= MAXSPRITES) + return; + proj=GetGameVarID((int)lVar1, sActor, sPlayer); + } + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + switch(lLabelID) + { + case PROJ_WORKSLIKE: + if(bSet) + thisprojectile[proj].workslike=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].workslike, sActor, sPlayer); + break; + + case PROJ_SPAWNS: + if(bSet) + thisprojectile[proj].spawns=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].spawns, sActor, sPlayer); + break; + + case PROJ_SXREPEAT: + if(bSet) + thisprojectile[proj].sxrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].sxrepeat, sActor, sPlayer); + break; + + case PROJ_SYREPEAT: + if(bSet) + thisprojectile[proj].syrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].syrepeat, sActor, sPlayer); + break; + + case PROJ_SOUND: + if(bSet) + thisprojectile[proj].sound=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].sound, sActor, sPlayer); + break; + + case PROJ_ISOUND: + if(bSet) + thisprojectile[proj].isound=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].isound, sActor, sPlayer); + break; + + case PROJ_VEL: + if(bSet) + thisprojectile[proj].vel=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].vel, sActor, sPlayer); + break; + + case PROJ_EXTRA: + if(bSet) + thisprojectile[proj].extra=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].extra, sActor, sPlayer); + break; + + case PROJ_DECAL: + if(bSet) + thisprojectile[proj].decal=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].decal, sActor, sPlayer); + break; + + case PROJ_TRAIL: + if(bSet) + thisprojectile[proj].trail=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].trail, sActor, sPlayer); + break; + + case PROJ_TXREPEAT: + if(bSet) + thisprojectile[proj].txrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].txrepeat, sActor, sPlayer); + break; + + case PROJ_TYREPEAT: + if(bSet) + thisprojectile[proj].tyrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].tyrepeat, sActor, sPlayer); + break; + + case PROJ_TOFFSET: + if(bSet) + thisprojectile[proj].toffset=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].toffset, sActor, sPlayer); + break; + + case PROJ_TNUM: + if(bSet) + thisprojectile[proj].tnum=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].tnum, sActor, sPlayer); + break; + + case PROJ_DROP: + if(bSet) + thisprojectile[proj].drop=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].drop, sActor, sPlayer); + break; + + case PROJ_CSTAT: + if(bSet) + thisprojectile[proj].cstat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].cstat, sActor, sPlayer); + break; + + case PROJ_CLIPDIST: + if(bSet) + thisprojectile[proj].clipdist=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].clipdist, sActor, sPlayer); + break; + + case PROJ_SHADE: + if(bSet) + thisprojectile[proj].shade=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].shade, sActor, sPlayer); + break; + + case PROJ_XREPEAT: + if(bSet) + thisprojectile[proj].xrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].xrepeat, sActor, sPlayer); + break; + + case PROJ_YREPEAT: + if(bSet) + thisprojectile[proj].yrepeat=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].yrepeat, sActor, sPlayer); + break; + + case PROJ_PAL: + if(bSet) + thisprojectile[proj].pal=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].pal, sActor, sPlayer); + break; + + case PROJ_EXTRA_RAND: + if(bSet) + thisprojectile[proj].extra_rand=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].extra_rand, sActor, sPlayer); + break; + + case PROJ_HITRADIUS: + if(bSet) + thisprojectile[proj].hitradius=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].hitradius, sActor, sPlayer); + break; + + case PROJ_VEL_MULT: + if(bSet) + thisprojectile[proj].velmult=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].velmult, sActor, sPlayer); + break; + + case PROJ_OFFSET: + if(bSet) + thisprojectile[proj].offset=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].offset, sActor, sPlayer); + break; + + case PROJ_BOUNCES: + if(bSet) + thisprojectile[proj].bounces=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].bounces, sActor, sPlayer); + break; + + case PROJ_BSOUND: + if(bSet) + thisprojectile[proj].bsound=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].bsound, sActor, sPlayer); + break; + + case PROJ_RANGE: + if(bSet) + thisprojectile[proj].range=lValue; + else + SetGameVarID((int)lVar2, thisprojectile[proj].range, sActor, sPlayer); + break; + + default: + break; + } + return; +} + +void DoPlayer(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer, long lParm2) +{ + int iPlayer; + long lValue; + long lTemp; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + if(lVar1 == g_iThisActorID ) + { + // if they've asked for 'this', then use 'this player'... + iPlayer=g_p; + } + else + { + if(sPlayer<0 || sPlayer >= MAXPLAYERS) + return; + iPlayer=GetGameVarID((int)lVar1, sActor, sPlayer); + } + + if(iPlayer<0 || iPlayer >= MAXPLAYERS) + return; + + switch(lLabelID) + { + case PLAYER_ZOOM: + if(bSet) + ps[iPlayer].zoom=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].zoom, sActor, sPlayer); + break; + + case PLAYER_EXITX: + if(bSet) + ps[iPlayer].exitx=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].exitx, sActor, sPlayer); + break; + + case PLAYER_EXITY: + if(bSet) + ps[iPlayer].exity=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].exity, sActor, sPlayer); + break; + + case PLAYER_LOOGIEX: + lTemp=lParm2; + if(bSet) + ps[iPlayer].loogiex[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].loogiex[lTemp], sActor, sPlayer); + break; + + case PLAYER_LOOGIEY: + lTemp=lParm2; + if(bSet) + ps[iPlayer].loogiey[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].loogiey[lTemp], sActor, sPlayer); + break; + + case PLAYER_NUMLOOGS: + if(bSet) + ps[iPlayer].numloogs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].numloogs, sActor, sPlayer); + break; + + case PLAYER_LOOGCNT: + if(bSet) + ps[iPlayer].loogcnt=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].loogcnt, sActor, sPlayer); + break; + + case PLAYER_POSX: + if(bSet) + ps[iPlayer].posx=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].posx, sActor, sPlayer); + break; + + case PLAYER_POSY: + if(bSet) + ps[iPlayer].posy=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].posy, sActor, sPlayer); + break; + + case PLAYER_POSZ: + if(bSet) + ps[iPlayer].posz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].posz, sActor, sPlayer); + break; + + case PLAYER_HORIZ: + if(bSet) + ps[iPlayer].horiz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].horiz, sActor, sPlayer); + break; + + case PLAYER_OHORIZ: + if(bSet) + ps[iPlayer].ohoriz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].ohoriz, sActor, sPlayer); + break; + + case PLAYER_OHORIZOFF: + if(bSet) + ps[iPlayer].ohorizoff=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].ohorizoff, sActor, sPlayer); + break; + + case PLAYER_INVDISPTIME: + if(bSet) + ps[iPlayer].invdisptime=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].invdisptime, sActor, sPlayer); + break; + + case PLAYER_BOBPOSX: + if(bSet) + ps[iPlayer].bobposx=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].bobposx, sActor, sPlayer); + break; + + case PLAYER_BOBPOSY: + if(bSet) + ps[iPlayer].bobposy=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].bobposy, sActor, sPlayer); + break; + + case PLAYER_OPOSX: + if(bSet) + ps[iPlayer].oposx=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].oposx, sActor, sPlayer); + break; + + case PLAYER_OPOSY: + if(bSet) + ps[iPlayer].oposy=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].oposy, sActor, sPlayer); + break; + + case PLAYER_OPOSZ: + if(bSet) + ps[iPlayer].oposz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].oposz, sActor, sPlayer); + break; + + case PLAYER_PYOFF: + if(bSet) + ps[iPlayer].pyoff=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].pyoff, sActor, sPlayer); + break; + + case PLAYER_OPYOFF: + if(bSet) + ps[iPlayer].opyoff=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].opyoff, sActor, sPlayer); + break; + + case PLAYER_POSXV: + if(bSet) + ps[iPlayer].posxv=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].posxv, sActor, sPlayer); + break; + + case PLAYER_POSYV: + if(bSet) + ps[iPlayer].posyv=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].posyv, sActor, sPlayer); + break; + + case PLAYER_POSZV: + if(bSet) + ps[iPlayer].poszv=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].poszv, sActor, sPlayer); + break; + + case PLAYER_LAST_PISSED_TIME: + if(bSet) + ps[iPlayer].last_pissed_time=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].last_pissed_time, sActor, sPlayer); + break; + + case PLAYER_TRUEFZ: + if(bSet) + ps[iPlayer].truefz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].truefz, sActor, sPlayer); + break; + + case PLAYER_TRUECZ: + if(bSet) + ps[iPlayer].truecz=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].truecz, sActor, sPlayer); + break; + + case PLAYER_PLAYER_PAR: + if(bSet) + ps[iPlayer].player_par=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].player_par, sActor, sPlayer); + break; + + case PLAYER_VISIBILITY: + if(bSet) + ps[iPlayer].visibility=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].visibility, sActor, sPlayer); + break; + + case PLAYER_BOBCOUNTER: + if(bSet) + ps[iPlayer].bobcounter=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].bobcounter, sActor, sPlayer); + break; + + case PLAYER_WEAPON_SWAY: + if(bSet) + ps[iPlayer].weapon_sway=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weapon_sway, sActor, sPlayer); + break; + + case PLAYER_PALS_TIME: + if(bSet) + ps[iPlayer].pals_time=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].pals_time, sActor, sPlayer); + break; + + case PLAYER_RANDOMFLAMEX: + if(bSet) + ps[iPlayer].randomflamex=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].randomflamex, sActor, sPlayer); + break; + + case PLAYER_CRACK_TIME: + if(bSet) + ps[iPlayer].crack_time=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].crack_time, sActor, sPlayer); + break; + + case PLAYER_AIM_MODE: + if(bSet) + ps[iPlayer].aim_mode=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].aim_mode, sActor, sPlayer); + break; + + case PLAYER_ANG: + if(bSet) + ps[iPlayer].ang=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].ang, sActor, sPlayer); + break; + + case PLAYER_OANG: + if(bSet) + ps[iPlayer].oang=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].oang, sActor, sPlayer); + break; + + case PLAYER_ANGVEL: + if(bSet) + ps[iPlayer].angvel=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].angvel, sActor, sPlayer); + break; + + case PLAYER_CURSECTNUM: + if(bSet) + ps[iPlayer].cursectnum=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].cursectnum, sActor, sPlayer); + break; + + case PLAYER_LOOK_ANG: + if(bSet) + ps[iPlayer].look_ang=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].look_ang, sActor, sPlayer); + break; + + case PLAYER_LAST_EXTRA: + if(bSet) + ps[iPlayer].last_extra=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].last_extra, sActor, sPlayer); + break; + + case PLAYER_SUBWEAPON: + if(bSet) + ps[iPlayer].subweapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].subweapon, sActor, sPlayer); + break; + + case PLAYER_AMMO_AMOUNT: + lTemp=lParm2; + if(bSet) + ps[iPlayer].ammo_amount[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].ammo_amount[lTemp], sActor, sPlayer); + break; + + case PLAYER_WACKEDBYACTOR: + if(bSet) + ps[iPlayer].wackedbyactor=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].wackedbyactor, sActor, sPlayer); + break; + + case PLAYER_FRAG: + if(bSet) + ps[iPlayer].frag=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].frag, sActor, sPlayer); + break; + + case PLAYER_FRAGGEDSELF: + if(bSet) + ps[iPlayer].fraggedself=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].fraggedself, sActor, sPlayer); + break; + + case PLAYER_CURR_WEAPON: + if(bSet) + ps[iPlayer].curr_weapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].curr_weapon, sActor, sPlayer); + break; + + case PLAYER_LAST_WEAPON: + if(bSet) + ps[iPlayer].last_weapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].last_weapon, sActor, sPlayer); + break; + + case PLAYER_TIPINCS: + if(bSet) + ps[iPlayer].tipincs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].tipincs, sActor, sPlayer); + break; + + case PLAYER_HORIZOFF: + if(bSet) + ps[iPlayer].horizoff=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].horizoff, sActor, sPlayer); + break; + + case PLAYER_WANTWEAPONFIRE: + if(bSet) + ps[iPlayer].wantweaponfire=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].wantweaponfire, sActor, sPlayer); + break; + + case PLAYER_HOLODUKE_AMOUNT: + if(bSet) + ps[iPlayer].holoduke_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].holoduke_amount, sActor, sPlayer); + break; + + case PLAYER_NEWOWNER: + if(bSet) + ps[iPlayer].newowner=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].newowner, sActor, sPlayer); + break; + + case PLAYER_HURT_DELAY: + if(bSet) + ps[iPlayer].hurt_delay=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].hurt_delay, sActor, sPlayer); + break; + + case PLAYER_HBOMB_HOLD_DELAY: + if(bSet) + ps[iPlayer].hbomb_hold_delay=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].hbomb_hold_delay, sActor, sPlayer); + break; + + case PLAYER_JUMPING_COUNTER: + if(bSet) + ps[iPlayer].jumping_counter=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].jumping_counter, sActor, sPlayer); + break; + + case PLAYER_AIRLEFT: + if(bSet) + ps[iPlayer].airleft=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].airleft, sActor, sPlayer); + break; + + case PLAYER_KNEE_INCS: + if(bSet) + ps[iPlayer].knee_incs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].knee_incs, sActor, sPlayer); + break; + + case PLAYER_ACCESS_INCS: + if(bSet) + ps[iPlayer].access_incs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].access_incs, sActor, sPlayer); + break; + + case PLAYER_FTA: + if(bSet) + ps[iPlayer].fta=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].fta, sActor, sPlayer); + break; + + case PLAYER_FTQ: + if(bSet) + ps[iPlayer].ftq=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].ftq, sActor, sPlayer); + break; + + case PLAYER_ACCESS_WALLNUM: + if(bSet) + ps[iPlayer].access_wallnum=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].access_wallnum, sActor, sPlayer); + break; + + case PLAYER_ACCESS_SPRITENUM: + if(bSet) + ps[iPlayer].access_spritenum=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].access_spritenum, sActor, sPlayer); + break; + + case PLAYER_KICKBACK_PIC: + if(bSet) + ps[iPlayer].kickback_pic=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].kickback_pic, sActor, sPlayer); + break; + + case PLAYER_GOT_ACCESS: + if(bSet) + ps[iPlayer].got_access=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].got_access, sActor, sPlayer); + break; + + case PLAYER_WEAPON_ANG: + if(bSet) + ps[iPlayer].weapon_ang=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weapon_ang, sActor, sPlayer); + break; + + case PLAYER_FIRSTAID_AMOUNT: + if(bSet) + ps[iPlayer].firstaid_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].firstaid_amount, sActor, sPlayer); + break; + + case PLAYER_SOMETHINGONPLAYER: + if(bSet) + ps[iPlayer].somethingonplayer=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].somethingonplayer, sActor, sPlayer); + break; + + case PLAYER_ON_CRANE: + if(bSet) + ps[iPlayer].on_crane=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].on_crane, sActor, sPlayer); + break; + + case PLAYER_I: + if(bSet) + ps[iPlayer].i=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].i, sActor, sPlayer); + break; + + case PLAYER_ONE_PARALLAX_SECTNUM: + if(bSet) + ps[iPlayer].one_parallax_sectnum=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].one_parallax_sectnum, sActor, sPlayer); + break; + + case PLAYER_OVER_SHOULDER_ON: + if(bSet) + ps[iPlayer].over_shoulder_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].over_shoulder_on, sActor, sPlayer); + break; + + case PLAYER_RANDOM_CLUB_FRAME: + if(bSet) + ps[iPlayer].random_club_frame=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].random_club_frame, sActor, sPlayer); + break; + + case PLAYER_FIST_INCS: + if(bSet) + ps[iPlayer].fist_incs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].fist_incs, sActor, sPlayer); + break; + + case PLAYER_ONE_EIGHTY_COUNT: + if(bSet) + ps[iPlayer].one_eighty_count=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].one_eighty_count, sActor, sPlayer); + break; + + case PLAYER_CHEAT_PHASE: + if(bSet) + ps[iPlayer].cheat_phase=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].cheat_phase, sActor, sPlayer); + break; + + case PLAYER_DUMMYPLAYERSPRITE: + if(bSet) + ps[iPlayer].dummyplayersprite=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].dummyplayersprite, sActor, sPlayer); + break; + + case PLAYER_EXTRA_EXTRA8: + if(bSet) + ps[iPlayer].extra_extra8=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].extra_extra8, sActor, sPlayer); + break; + + case PLAYER_QUICK_KICK: + if(bSet) + ps[iPlayer].quick_kick=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].quick_kick, sActor, sPlayer); + break; + + case PLAYER_HEAT_AMOUNT: + if(bSet) + ps[iPlayer].heat_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].heat_amount, sActor, sPlayer); + break; + + case PLAYER_ACTORSQU: + if(bSet) + ps[iPlayer].actorsqu=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].actorsqu, sActor, sPlayer); + break; + + case PLAYER_TIMEBEFOREEXIT: + if(bSet) + ps[iPlayer].timebeforeexit=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].timebeforeexit, sActor, sPlayer); + break; + + case PLAYER_CUSTOMEXITSOUND: + if(bSet) + ps[iPlayer].customexitsound=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].customexitsound, sActor, sPlayer); + break; + + case PLAYER_WEAPRECS: + if(bSet) + ps[iPlayer].weaprecs[16]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weaprecs[16], sActor, sPlayer); + break; + + case PLAYER_WEAPRECCNT: + if(bSet) + ps[iPlayer].weapreccnt=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weapreccnt, sActor, sPlayer); + break; + + case PLAYER_INTERFACE_TOGGLE_FLAG: + if(bSet) + ps[iPlayer].interface_toggle_flag=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].interface_toggle_flag, sActor, sPlayer); + break; + + case PLAYER_ROTSCRNANG: + if(bSet) + ps[iPlayer].rotscrnang=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].rotscrnang, sActor, sPlayer); + break; + + case PLAYER_DEAD_FLAG: + if(bSet) + ps[iPlayer].dead_flag=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].dead_flag, sActor, sPlayer); + break; + + case PLAYER_SHOW_EMPTY_WEAPON: + if(bSet) + ps[iPlayer].show_empty_weapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].show_empty_weapon, sActor, sPlayer); + break; + + case PLAYER_SCUBA_AMOUNT: + if(bSet) + ps[iPlayer].scuba_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].scuba_amount, sActor, sPlayer); + break; + + case PLAYER_JETPACK_AMOUNT: + if(bSet) + ps[iPlayer].jetpack_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].jetpack_amount, sActor, sPlayer); + break; + + case PLAYER_STEROIDS_AMOUNT: + if(bSet) + ps[iPlayer].steroids_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].steroids_amount, sActor, sPlayer); + break; + + case PLAYER_SHIELD_AMOUNT: + if(bSet) + ps[iPlayer].shield_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].shield_amount, sActor, sPlayer); + break; + + case PLAYER_HOLODUKE_ON: + if(bSet) + ps[iPlayer].holoduke_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].holoduke_on, sActor, sPlayer); + break; + + case PLAYER_PYCOUNT: + if(bSet) + ps[iPlayer].pycount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].pycount, sActor, sPlayer); + break; + + case PLAYER_WEAPON_POS: + if(bSet) + ps[iPlayer].weapon_pos=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weapon_pos, sActor, sPlayer); + break; + + case PLAYER_FRAG_PS: + if(bSet) + ps[iPlayer].frag_ps=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].frag_ps, sActor, sPlayer); + break; + + case PLAYER_TRANSPORTER_HOLD: + if(bSet) + ps[iPlayer].transporter_hold=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].transporter_hold, sActor, sPlayer); + break; + + case PLAYER_LAST_FULL_WEAPON: + if(bSet) + ps[iPlayer].last_full_weapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].last_full_weapon, sActor, sPlayer); + break; + + case PLAYER_FOOTPRINTSHADE: + if(bSet) + ps[iPlayer].footprintshade=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].footprintshade, sActor, sPlayer); + break; + + case PLAYER_BOOT_AMOUNT: + if(bSet) + ps[iPlayer].boot_amount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].boot_amount, sActor, sPlayer); + break; + + case PLAYER_SCREAM_VOICE: + if(bSet) + ps[iPlayer].scream_voice=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].scream_voice, sActor, sPlayer); + break; + + case PLAYER_GM: + if(bSet) + ps[iPlayer].gm=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].gm, sActor, sPlayer); + break; + + case PLAYER_ON_WARPING_SECTOR: + if(bSet) + ps[iPlayer].on_warping_sector=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].on_warping_sector, sActor, sPlayer); + break; + + case PLAYER_FOOTPRINTCOUNT: + if(bSet) + ps[iPlayer].footprintcount=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].footprintcount, sActor, sPlayer); + break; + + case PLAYER_HBOMB_ON: + if(bSet) + ps[iPlayer].hbomb_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].hbomb_on, sActor, sPlayer); + break; + + case PLAYER_JUMPING_TOGGLE: + if(bSet) + ps[iPlayer].jumping_toggle=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].jumping_toggle, sActor, sPlayer); + break; + + case PLAYER_RAPID_FIRE_HOLD: + if(bSet) + ps[iPlayer].rapid_fire_hold=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].rapid_fire_hold, sActor, sPlayer); + break; + + case PLAYER_ON_GROUND: + if(bSet) + ps[iPlayer].on_ground=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].on_ground, sActor, sPlayer); + break; + + case PLAYER_NAME: + if(bSet) + ps[iPlayer].name[32]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].name[32], sActor, sPlayer); + break; + + case PLAYER_INVEN_ICON: + if(bSet) + ps[iPlayer].inven_icon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].inven_icon, sActor, sPlayer); + break; + + case PLAYER_BUTTONPALETTE: + if(bSet) + ps[iPlayer].buttonpalette=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].buttonpalette, sActor, sPlayer); + break; + + case PLAYER_JETPACK_ON: + if(bSet) + ps[iPlayer].jetpack_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].jetpack_on, sActor, sPlayer); + break; + + case PLAYER_SPRITEBRIDGE: + if(bSet) + ps[iPlayer].spritebridge=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].spritebridge, sActor, sPlayer); + break; + + case PLAYER_LASTRANDOMSPOT: + if(bSet) + ps[iPlayer].lastrandomspot=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].lastrandomspot, sActor, sPlayer); + break; + + case PLAYER_SCUBA_ON: + if(bSet) + ps[iPlayer].scuba_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].scuba_on, sActor, sPlayer); + break; + + case PLAYER_FOOTPRINTPAL: + if(bSet) + ps[iPlayer].footprintpal=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].footprintpal, sActor, sPlayer); + break; + + case PLAYER_HEAT_ON: + if(bSet) + ps[iPlayer].heat_on=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].heat_on, sActor, sPlayer); + break; + + case PLAYER_HOLSTER_WEAPON: + if(bSet) + ps[iPlayer].holster_weapon=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].holster_weapon, sActor, sPlayer); + break; + + case PLAYER_FALLING_COUNTER: + if(bSet) + ps[iPlayer].falling_counter=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].falling_counter, sActor, sPlayer); + break; + + case PLAYER_GOTWEAPON: + lTemp=lParm2; + if(bSet) + ps[iPlayer].gotweapon[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].gotweapon[lTemp], sActor, sPlayer); + break; + + case PLAYER_REFRESH_INVENTORY: + if(bSet) + ps[iPlayer].refresh_inventory=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].refresh_inventory, sActor, sPlayer); + break; + + // case PLAYER_PALETTE: + // if(bSet) + // { + // ps[iPlayer].palette=lValue; + // } + // else + // { + // SetGameVarID((int)lVar2, ps[iPlayer].palette, sActor, sPlayer); + // } + // break; + + case PLAYER_TOGGLE_KEY_FLAG: + if(bSet) + ps[iPlayer].toggle_key_flag=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].toggle_key_flag, sActor, sPlayer); + break; + + case PLAYER_KNUCKLE_INCS: + if(bSet) + ps[iPlayer].knuckle_incs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].knuckle_incs, sActor, sPlayer); + break; + + case PLAYER_WALKING_SND_TOGGLE: + if(bSet) + ps[iPlayer].walking_snd_toggle=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].walking_snd_toggle, sActor, sPlayer); + break; + + case PLAYER_PALOOKUP: + if(bSet) + ps[iPlayer].palookup=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].palookup, sActor, sPlayer); + break; + + case PLAYER_HARD_LANDING: + if(bSet) + ps[iPlayer].hard_landing=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].hard_landing, sActor, sPlayer); + break; + + case PLAYER_MAX_SECRET_ROOMS: + if(bSet) + ps[iPlayer].max_secret_rooms=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].max_secret_rooms, sActor, sPlayer); + break; + + case PLAYER_SECRET_ROOMS: + if(bSet) + ps[iPlayer].secret_rooms=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].secret_rooms, sActor, sPlayer); + break; + + case PLAYER_PALS: + lTemp=lParm2; + if(bSet) + ps[iPlayer].pals[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].pals[lTemp], sActor, sPlayer); + break; + + case PLAYER_MAX_ACTORS_KILLED: + if(bSet) + ps[iPlayer].max_actors_killed=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].max_actors_killed, sActor, sPlayer); + break; + + case PLAYER_ACTORS_KILLED: + if(bSet) + ps[iPlayer].actors_killed=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].actors_killed, sActor, sPlayer); + break; + + case PLAYER_RETURN_TO_CENTER: + if(bSet) + ps[iPlayer].return_to_center=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].return_to_center, sActor, sPlayer); + break; + + case PLAYER_RUNSPEED: + if(bSet) + ps[iPlayer].runspeed=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].runspeed, sActor, sPlayer); + break; + + case PLAYER_SBS: + if(bSet) + ps[iPlayer].sbs=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].sbs, sActor, sPlayer); + break; + + case PLAYER_RELOADING: + if(bSet) + ps[iPlayer].reloading=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].reloading, sActor, sPlayer); + break; + + case PLAYER_AUTO_AIM: + if(bSet) + ps[iPlayer].auto_aim=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].auto_aim, sActor, sPlayer); + break; + + case PLAYER_MOVEMENT_LOCK: + lTemp=lParm2; + if(bSet) + ps[iPlayer].movement_lock[lTemp]=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].movement_lock[lTemp], sActor, sPlayer); + break; + + case PLAYER_SOUND_PITCH: + if(bSet) + ps[iPlayer].sound_pitch=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].sound_pitch, sActor, sPlayer); + break; + + case PLAYER_WEAPONSWITCH: + if(bSet) + ps[iPlayer].weaponswitch=lValue; + else + SetGameVarID((int)lVar2, ps[iPlayer].weaponswitch, sActor, sPlayer); + break; + + default: + break; + } + return; +} + +void DoInput(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer) +{ + int iPlayer; + long lValue; + long lTemp; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + if(lVar1 == g_iThisActorID ) + { + // if they've asked for 'this', then use 'this player'... + iPlayer=g_p; + } + else + { + if(sPlayer<0 || sPlayer >= MAXPLAYERS) + return; + iPlayer=GetGameVarID((int)lVar1, sActor, sPlayer); + } + + if(iPlayer<0 || iPlayer >= MAXPLAYERS) + return; + + switch(lLabelID) + { + case INPUT_AVEL: + if(bSet) + sync[iPlayer].avel=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].avel, sActor, sPlayer); + break; + case INPUT_HORZ: + if(bSet) + sync[iPlayer].horz=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].horz, sActor, sPlayer); + break; + case INPUT_FVEL: + if(bSet) + sync[iPlayer].fvel=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].fvel, sActor, sPlayer); + break; + case INPUT_SVEL: + if(bSet) + sync[iPlayer].svel=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].svel, sActor, sPlayer); + break; + case INPUT_BITS: + if(bSet) + sync[iPlayer].bits=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].bits, sActor, sPlayer); + break; + case INPUT_BITS2: + if(bSet) + sync[iPlayer].bits2=lValue; + else + SetGameVarID((int)lVar2, sync[iPlayer].bits2, sActor, sPlayer); + break; + default: + break; + } + return; +} + +void DoWall(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer) +{ + int iWall; + long lValue; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + iWall=GetGameVarID((int)lVar1, sActor, sPlayer); + + if(iWall<0 || iWall >= MAXWALLS) + return; + + switch(lLabelID) + { + case WALL_X: + if(bSet) + wall[iWall].x=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].x, sActor, sPlayer); + break; + case WALL_Y: + if(bSet) + wall[iWall].y=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].y, sActor, sPlayer); + break; + case WALL_POINT2: + if(bSet) + wall[iWall].point2=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].point2, sActor, sPlayer); + break; + case WALL_NEXTWALL: + if(bSet) + wall[iWall].nextwall=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].nextwall, sActor, sPlayer); + break; + case WALL_NEXTSECTOR: + if(bSet) + wall[iWall].nextsector=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].nextsector, sActor, sPlayer); + break; + case WALL_CSTAT: + if(bSet) + wall[iWall].cstat=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].cstat, sActor, sPlayer); + break; + case WALL_PICNUM: + if(bSet) + wall[iWall].picnum=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].picnum, sActor, sPlayer); + break; + case WALL_OVERPICNUM: + if(bSet) + wall[iWall].overpicnum=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].overpicnum, sActor, sPlayer); + break; + case WALL_SHADE: + if(bSet) + wall[iWall].shade=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].shade, sActor, sPlayer); + break; + case WALL_PAL: + if(bSet) + wall[iWall].pal=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].pal, sActor, sPlayer); + break; + case WALL_XREPEAT: + if(bSet) + wall[iWall].xrepeat=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].xrepeat, sActor, sPlayer); + break; + case WALL_YREPEAT: + if(bSet) + wall[iWall].yrepeat=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].yrepeat, sActor, sPlayer); + break; + case WALL_XPANNING: + if(bSet) + wall[iWall].xpanning=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].xpanning, sActor, sPlayer); + break; + case WALL_YPANNING: + if(bSet) + wall[iWall].ypanning=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].ypanning, sActor, sPlayer); + break; + case WALL_LOTAG: + if(bSet) + wall[iWall].lotag=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].lotag, sActor, sPlayer); + break; + case WALL_HITAG: + if(bSet) + wall[iWall].hitag=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].hitag, sActor, sPlayer); + break; + case WALL_EXTRA: + if(bSet) + wall[iWall].extra=lValue; + else + SetGameVarID((int)lVar2, wall[iWall].extra, sActor, sPlayer); + break; + default: + break; + } + return; +} + +void DoSector(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer) +{ + int iSector; + long lValue; + + + if(lVar1 == g_iThisActorID ) + { + // if they've asked for 'this', then use 'this'... + iSector=sprite[g_i].sectnum; + } + else + { + iSector=GetGameVarID((int)lVar1, sActor, sPlayer); + } + + if(iSector<0 || iSector >= MAXSECTORS) + return; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + switch(lLabelID) + { + case SECTOR_WALLPTR: + if(bSet) + sector[iSector].wallptr=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].wallptr,sActor,sPlayer); + break; + case SECTOR_WALLNUM: + if(bSet) + sector[iSector].wallnum=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].wallnum,sActor,sPlayer); + break; + case SECTOR_CEILINGZ: + if(bSet) + sector[iSector].ceilingz=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingz,sActor,sPlayer); + break; + case SECTOR_FLOORZ: + if(bSet) + sector[iSector].floorz=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorz,sActor,sPlayer); + break; + case SECTOR_CEILINGSTAT: + if(bSet) + sector[iSector].ceilingstat=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingstat,sActor,sPlayer); + break; + case SECTOR_FLOORSTAT: + if(bSet) + sector[iSector].floorstat=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorstat,sActor,sPlayer); + break; + case SECTOR_CEILINGPICNUM: + if(bSet) + sector[iSector].ceilingpicnum=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingpicnum,sActor,sPlayer); + break; + case SECTOR_CEILINGSLOPE: + if(bSet) + sector[iSector].ceilingheinum=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingheinum,sActor,sPlayer); + break; + case SECTOR_CEILINGSHADE: + if(bSet) + sector[iSector].ceilingshade=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingshade,sActor,sPlayer); + break; + case SECTOR_CEILINGPAL: + if(bSet) + sector[iSector].ceilingpal=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingpal,sActor,sPlayer); + break; + case SECTOR_CEILINGXPANNING: + if(bSet) + sector[iSector].ceilingxpanning=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].ceilingypanning,sActor,sPlayer); + break; + case SECTOR_FLOORPICNUM: + if(bSet) + sector[iSector].floorpicnum=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorpicnum,sActor,sPlayer); + break; + case SECTOR_FLOORSLOPE: + if(bSet) + sector[iSector].floorheinum=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorheinum,sActor,sPlayer); + break; + case SECTOR_FLOORSHADE: + if(bSet) + sector[iSector].floorshade=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorshade,sActor,sPlayer); + break; + case SECTOR_FLOORPAL: + if(bSet) + sector[iSector].floorpal=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorpal,sActor,sPlayer); + break; + case SECTOR_FLOORXPANNING: + if(bSet) + sector[iSector].floorxpanning=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorxpanning,sActor,sPlayer); + break; + case SECTOR_FLOORYPANNING: + if(bSet) + sector[iSector].floorypanning=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].floorypanning,sActor,sPlayer); + break; + case SECTOR_VISIBILITY: + if(bSet) + sector[iSector].visibility=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].visibility,sActor,sPlayer); + break; + case SECTOR_ALIGNTO: + if(bSet) + sector[iSector].filler=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].filler,sActor,sPlayer); + break; + case SECTOR_LOTAG: + if(bSet) + sector[iSector].lotag=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].lotag,sActor,sPlayer); + break; + case SECTOR_HITAG: + if(bSet) + sector[iSector].hitag=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].hitag,sActor,sPlayer); + break; + case SECTOR_EXTRA: + if(bSet) + sector[iSector].extra=lValue; + else + SetGameVarID((int)lVar2, sector[iSector].extra,sActor,sPlayer); + break; + default: + break; + } + return; +} + +void DoActor(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer, long lParm2) +{ + int iActor; + long lValue; + long lTemp; + + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + if(lVar1 == g_iThisActorID ) + { + // if they've asked for 'this', then use 'this'... + iActor=g_i; + } + else + { + if(sActor < 0 || sActor >= MAXSPRITES) + return; + iActor=GetGameVarID((int)lVar1, sActor, sPlayer); + } + + if(iActor < 0 || iActor >= MAXSPRITES) + return; + + switch(lLabelID) + { + case ACTOR_X: + if(bSet) + sprite[iActor].x=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].x,sActor,sPlayer); + break; + case ACTOR_Y: + if(bSet) + sprite[iActor].y=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].y,sActor,sPlayer); + break; + case ACTOR_Z: + if(bSet) + sprite[iActor].z=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].z,sActor,sPlayer); + break; + case ACTOR_CSTAT: + if(bSet) + sprite[iActor].cstat=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].cstat,sActor,sPlayer); + break; + case ACTOR_PICNUM: + if(bSet) + sprite[iActor].picnum=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].picnum,sActor,sPlayer); + break; + case ACTOR_SHADE: + if(bSet) + sprite[iActor].shade=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].shade,sActor,sPlayer); + break; + case ACTOR_PAL: + if(bSet) + sprite[iActor].pal=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].pal,sActor,sPlayer); + break; + case ACTOR_CLIPDIST: + if(bSet) + sprite[iActor].clipdist=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].clipdist,sActor,sPlayer); + break; + case ACTOR_DETAIL: + if(bSet) + sprite[iActor].filler=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].filler,sActor,sPlayer); + break; + case ACTOR_XREPEAT: + if(bSet) + sprite[iActor].xrepeat=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].xrepeat,sActor,sPlayer); + break; + case ACTOR_YREPEAT: + if(bSet) + sprite[iActor].yrepeat=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].yrepeat,sActor,sPlayer); + break; + case ACTOR_XOFFSET: + if(bSet) + sprite[iActor].xoffset=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].xoffset,sActor,sPlayer); + break; + case ACTOR_YOFFSET: + if(bSet) + sprite[iActor].yoffset=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].yoffset,sActor,sPlayer); + break; + case ACTOR_SECTNUM: + if(bSet) + changespritesect(iActor,lValue); + else + SetGameVarID((int)lVar2, sprite[iActor].sectnum,sActor,sPlayer); + break; + case ACTOR_STATNUM: + if(bSet) + changespritestat(iActor,lValue); + else + SetGameVarID((int)lVar2, sprite[iActor].statnum,sActor,sPlayer); + break; + case ACTOR_ANG: + if(bSet) + sprite[iActor].ang=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].ang,sActor,sPlayer); + break; + case ACTOR_OWNER: + if(bSet) + sprite[iActor].owner=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].owner,sActor,sPlayer); + break; + case ACTOR_XVEL: + if(bSet) + sprite[iActor].xvel=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].xvel,sActor,sPlayer); + break; + case ACTOR_YVEL: + if(bSet) + sprite[iActor].yvel=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].yvel,sActor,sPlayer); + break; + case ACTOR_ZVEL: + if(bSet) + sprite[iActor].zvel=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].zvel,sActor,sPlayer); + break; + case ACTOR_LOTAG: + if(bSet) + sprite[iActor].lotag=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].lotag,sActor,sPlayer); + break; + case ACTOR_HITAG: + if(bSet) + sprite[iActor].hitag=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].hitag,sActor,sPlayer); + break; + case ACTOR_EXTRA: + if(bSet) + sprite[iActor].extra=lValue; + else + SetGameVarID((int)lVar2, sprite[iActor].extra,sActor,sPlayer); + break; + case ACTOR_HTCGG: + if(bSet) + hittype[iActor].cgg=lValue; + else + SetGameVarID((int)lVar2, hittype[iActor].cgg, sActor, sPlayer); + break; + case ACTOR_HTPICNUM : + if(bSet) + hittype[iActor].picnum=lValue; + else + SetGameVarID((int)lVar2, hittype[iActor].picnum, sActor, sPlayer); + break; + case ACTOR_HTANG: + if(bSet) + hittype[iActor].ang=lValue; + else + SetGameVarID((int)lVar2, hittype[iActor].ang, sActor, sPlayer); + break; + case ACTOR_HTEXTRA: + if(bSet) + hittype[iActor].extra=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].extra, sActor, sPlayer); + break; + case ACTOR_HTOWNER: + if(bSet) + hittype[iActor].owner=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].owner, sActor, sPlayer); + break; + case ACTOR_HTMOVFLAG: + if(bSet) + hittype[iActor].movflag=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].movflag, sActor, sPlayer); + break; + case ACTOR_HTTEMPANG: + if(bSet) + hittype[iActor].tempang=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].tempang, sActor, sPlayer); + break; + case ACTOR_HTACTORSTAYPUT: + if(bSet) + hittype[iActor].actorstayput=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].actorstayput, sActor, sPlayer); + break; + case ACTOR_HTDISPICNUM: + if(bSet) + hittype[iActor].dispicnum=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].dispicnum, sActor, sPlayer); + break; + case ACTOR_HTTIMETOSLEEP: + if(bSet) + hittype[iActor].timetosleep=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].timetosleep, sActor, sPlayer); + break; + case ACTOR_HTFLOORZ: + if(bSet) + hittype[iActor].floorz=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].floorz, sActor, sPlayer); + break; + case ACTOR_HTCEILINGZ: + if(bSet) + hittype[iActor].ceilingz=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].ceilingz, sActor, sPlayer); + break; + case ACTOR_HTLASTVX: + if(bSet) + hittype[iActor].lastvx=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].lastvx, sActor, sPlayer); + break; + case ACTOR_HTLASTVY: + if(bSet) + hittype[iActor].lastvy=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].lastvy, sActor, sPlayer); + break; + case ACTOR_HTBPOSX: + if(bSet) + hittype[iActor].bposx=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].bposx, sActor, sPlayer); + break; + case ACTOR_HTBPOSY: + if(bSet) + hittype[iActor].bposy=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].bposy, sActor, sPlayer); + break; + case ACTOR_HTBPOSZ: + if(bSet) + hittype[iActor].bposz=lValue; + else + SetGameVarID((int)lVar2,hittype[iActor].bposz, sActor, sPlayer); + break; + case ACTOR_HTG_T: + lTemp=lParm2; + if(bSet) + hittype[iActor].temp_data[lTemp]=lValue; + else + SetGameVarID((int)lVar2, hittype[iActor].temp_data[lTemp], sActor, sPlayer); + break; + case ACTOR_ANGOFF: + if(bSet) + spriteext[iActor].angoff=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].angoff, sActor, sPlayer); + break; + case ACTOR_PITCH: + if(bSet) + spriteext[iActor].pitch=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].pitch, sActor, sPlayer); + break; + case ACTOR_ROLL: + if(bSet) + spriteext[iActor].roll=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].roll, sActor, sPlayer); + break; + case ACTOR_MDXOFF: + if(bSet) + spriteext[iActor].xoff=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].xoff, sActor, sPlayer); + break; + case ACTOR_MDYOFF: + if(bSet) + spriteext[iActor].yoff=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].yoff, sActor, sPlayer); + break; + case ACTOR_MDZOFF: + if(bSet) + spriteext[iActor].zoff=lValue; + else + SetGameVarID((int)lVar2,spriteext[iActor].zoff, sActor, sPlayer); + break; + + default: + break; + } + return; +} + +void DoProjectile(char bSet, long lVar1, long lLabelID, long lVar2, short sActor, short sPlayer) +{ + long lValue,proj; + + // proj=GetGameVarID((int)lVar1, sActor, sPlayer); + proj=lVar1; + lValue=GetGameVarID((int)lVar2, sActor, sPlayer); + + switch(lLabelID) + { + case PROJ_WORKSLIKE: + if(bSet) + projectile[proj].workslike=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].workslike, sActor, sPlayer); + break; + + case PROJ_SPAWNS: + if(bSet) + projectile[proj].spawns=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].spawns, sActor, sPlayer); + break; + + case PROJ_SXREPEAT: + if(bSet) + projectile[proj].sxrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].sxrepeat, sActor, sPlayer); + break; + + case PROJ_SYREPEAT: + if(bSet) + projectile[proj].syrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].syrepeat, sActor, sPlayer); + break; + + case PROJ_SOUND: + if(bSet) + projectile[proj].sound=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].sound, sActor, sPlayer); + break; + + case PROJ_ISOUND: + if(bSet) + projectile[proj].isound=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].isound, sActor, sPlayer); + break; + + case PROJ_VEL: + if(bSet) + projectile[proj].vel=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].vel, sActor, sPlayer); + break; + + case PROJ_EXTRA: + if(bSet) + projectile[proj].extra=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].extra, sActor, sPlayer); + break; + + case PROJ_DECAL: + if(bSet) + projectile[proj].decal=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].decal, sActor, sPlayer); + break; + + case PROJ_TRAIL: + if(bSet) + projectile[proj].trail=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].trail, sActor, sPlayer); + break; + + case PROJ_TXREPEAT: + if(bSet) + projectile[proj].txrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].txrepeat, sActor, sPlayer); + break; + + case PROJ_TYREPEAT: + if(bSet) + projectile[proj].tyrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].tyrepeat, sActor, sPlayer); + break; + + case PROJ_TOFFSET: + if(bSet) + projectile[proj].toffset=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].toffset, sActor, sPlayer); + break; + + case PROJ_TNUM: + if(bSet) + projectile[proj].tnum=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].tnum, sActor, sPlayer); + break; + + case PROJ_DROP: + if(bSet) + projectile[proj].drop=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].drop, sActor, sPlayer); + break; + + case PROJ_CSTAT: + if(bSet) + projectile[proj].cstat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].cstat, sActor, sPlayer); + break; + + case PROJ_CLIPDIST: + if(bSet) + projectile[proj].clipdist=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].clipdist, sActor, sPlayer); + break; + + case PROJ_SHADE: + if(bSet) + projectile[proj].shade=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].shade, sActor, sPlayer); + break; + + case PROJ_XREPEAT: + if(bSet) + projectile[proj].xrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].xrepeat, sActor, sPlayer); + break; + + case PROJ_YREPEAT: + if(bSet) + projectile[proj].yrepeat=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].yrepeat, sActor, sPlayer); + break; + + case PROJ_PAL: + if(bSet) + projectile[proj].pal=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].pal, sActor, sPlayer); + break; + + case PROJ_EXTRA_RAND: + if(bSet) + projectile[proj].extra_rand=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].extra_rand, sActor, sPlayer); + break; + + case PROJ_HITRADIUS: + if(bSet) + projectile[proj].hitradius=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].hitradius, sActor, sPlayer); + break; + + case PROJ_VEL_MULT: + if(bSet) + projectile[proj].velmult=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].velmult, sActor, sPlayer); + break; + + case PROJ_OFFSET: + if(bSet) + projectile[proj].offset=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].offset, sActor, sPlayer); + break; + + case PROJ_BOUNCES: + if(bSet) + projectile[proj].bounces=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].bounces, sActor, sPlayer); + break; + + case PROJ_BSOUND: + if(bSet) + projectile[proj].bsound=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].bsound, sActor, sPlayer); + break; + + case PROJ_RANGE: + if(bSet) + projectile[proj].range=lValue; + else + SetGameVarID((int)lVar2, projectile[proj].range, sActor, sPlayer); + break; + + default: + break; + } + return; +} + +void OnEvent(int iEventID, short sActor,short sPlayer,long lDist) +{ + short og_i,og_p; + long og_x; + long *og_t; + spritetype *og_sp; + char okillit_flag; + long *oinsptr; + + char done; + + if( iEventID >= MAXGAMEEVENTS) + { + AddLog("Invalid Event ID"); + return; + } + + if( apScriptGameEvent[iEventID] == 0 ) + { + //Bsprintf(g_szBuf,"No event found for %d",iEventID); + //AddLog(g_szBuf); + return; + } + + // save current values... + og_i=g_i; + og_p=g_p; + og_x=g_x; + og_sp=g_sp; + og_t=g_t; + okillit_flag=killit_flag; + oinsptr=insptr; + + g_i = sActor; // current sprite ID + g_p = sPlayer; // current player ID + g_x = lDist; // ? + g_sp = &sprite[g_i]; + g_t = &hittype[g_i].temp_data[0]; + + insptr = (apScriptGameEvent[iEventID]); + //Bsprintf(g_szBuf,"Executing event for %d at %lX",iEventID, insptr); + //AddLog(g_szBuf); + + killit_flag = 0; + do + done = parse(); + while( done == 0 ); + + // restore old values... + g_i=og_i; + g_p=og_p; + g_x=og_x; + g_sp=og_sp; + g_t=og_t; + killit_flag=okillit_flag; + insptr=oinsptr; + + //AddLog("End of Execution"); +} + +char dodge(spritetype *s) +{ + short i; + long bx,by,mx,my,bxvect,byvect,mxvect,myvect,d; + + mx = s->x; + my = s->y; + mxvect = sintable[(s->ang+512)&2047]; myvect = sintable[s->ang&2047]; + + for(i=headspritestat[4];i>=0;i=nextspritestat[i]) //weapons list + { + if( OW == i || SECT != s->sectnum) + continue; + + bx = SX-mx; + by = SY-my; + bxvect = sintable[(SA+512)&2047]; byvect = sintable[SA&2047]; + + if (mxvect*bx + myvect*by >= 0) + if (bxvect*bx + byvect*by < 0) + { + d = bxvect*by - byvect*bx; + if (klabs(d) < 65536*64) + { + s->ang -= 512+(TRAND&1024); + return 1; + } + } + } + return 0; +} + +short furthestangle(short sActor,short angs) +{ + short j, hitsect,hitwall,hitspr,furthest_angle=0, angincs; + long hx, hy, hz, d, greatestd; + spritetype *s = &sprite[sActor]; + + greatestd = -(1<<30); + angincs = 2048/angs; + + if(s->picnum != APLAYER) + if( (g_t[0]&63) > 2 ) return( s->ang + 1024 ); + + for(j=s->ang;j<(2048+s->ang);j+=angincs) + { + hitscan(s->x, s->y, s->z-(8<<8), s->sectnum, + sintable[(j+512)&2047], + sintable[j&2047],0, + &hitsect,&hitwall,&hitspr,&hx,&hy,&hz,CLIPMASK1); + + d = klabs(hx-s->x) + klabs(hy-s->y); + + if(d > greatestd) + { + greatestd = d; + furthest_angle = j; + } + } + return (furthest_angle&2047); +} + +short furthestcanseepoint(short sActor,spritetype *ts,long *dax,long *day) +{ + short j, hitsect,hitwall,hitspr, angincs, tempang; + long hx, hy, hz, d, da;//, d, cd, ca,tempx,tempy,cx,cy; + spritetype *s = &sprite[sActor]; + + if( (g_t[0]&63) ) return -1; + + if(ud.multimode < 2 && ud.player_skill < 3) + angincs = 2048/2; + else angincs = 2048/(1+(TRAND&1)); + + for(j=ts->ang;j<(2048+ts->ang);j+=(angincs-(TRAND&511))) + { + hitscan(ts->x, ts->y, ts->z-(16<<8), ts->sectnum, + sintable[(j+512)&2047], + sintable[j&2047],16384-(TRAND&32767), + &hitsect,&hitwall,&hitspr,&hx,&hy,&hz,CLIPMASK1); + + d = klabs(hx-ts->x)+klabs(hy-ts->y); + da = klabs(hx-s->x)+klabs(hy-s->y); + + if( d < da ) + if(cansee(hx,hy,hz,hitsect,s->x,s->y,s->z-(16<<8),s->sectnum)) + { + *dax = hx; + *day = hy; + return hitsect; + } + } + return -1; +} + +void getglobalz(short sActor) +{ + long hz,lz,zr; + + spritetype *s = &sprite[sActor]; + + if( s->statnum == 10 || s->statnum == 6 || s->statnum == 2 || s->statnum == 1 || s->statnum == 4) + { + if(s->statnum == 4) + zr = 4L; + else zr = 127L; + + getzrange(s->x,s->y,s->z-(FOURSLEIGHT),s->sectnum,&hittype[sActor].ceilingz,&hz,&hittype[sActor].floorz,&lz,zr,CLIPMASK0); + + if( (lz&49152) == 49152 && (sprite[lz&(MAXSPRITES-1)].cstat&48) == 0 ) + { + lz &= (MAXSPRITES-1); + if( badguy(&sprite[lz]) && sprite[lz].pal != 1) + { + if( s->statnum != 4 ) + { + hittype[sActor].dispicnum = -4; // No shadows on actors + s->xvel = -256; + ssp(sActor,CLIPMASK0); + } + } + else if(sprite[lz].picnum == APLAYER && badguy(s) ) + { + hittype[sActor].dispicnum = -4; // No shadows on actors + s->xvel = -256; + ssp(sActor,CLIPMASK0); + } + else if(s->statnum == 4 && sprite[lz].picnum == APLAYER) + if(s->owner == lz) + { + hittype[sActor].ceilingz = sector[s->sectnum].ceilingz; + hittype[sActor].floorz = sector[s->sectnum].floorz; + } + } + } + else + { + hittype[sActor].ceilingz = sector[s->sectnum].ceilingz; + hittype[sActor].floorz = sector[s->sectnum].floorz; + } +} + +void makeitfall(short sActor) +{ + spritetype *s = &sprite[sActor]; + long hz,lz,c; + + if( floorspace(s->sectnum) ) + c = 0; + else + { + if( ceilingspace(s->sectnum) || sector[s->sectnum].lotag == 2) + c = gc/6; + else c = gc; + } + + if( ( s->statnum == 1 || s->statnum == 10 || s->statnum == 2 || s->statnum == 6 ) ) + getzrange(s->x,s->y,s->z-(FOURSLEIGHT),s->sectnum,&hittype[sActor].ceilingz,&hz,&hittype[sActor].floorz,&lz,127L,CLIPMASK0); + else + { + hittype[sActor].ceilingz = sector[s->sectnum].ceilingz; + hittype[sActor].floorz = sector[s->sectnum].floorz; + } + + if( s->z < hittype[sActor].floorz-(FOURSLEIGHT) ) + { + if( sector[s->sectnum].lotag == 2 && s->zvel > 3122 ) + s->zvel = 3144; + if(s->zvel < 6144) + s->zvel += c; + else s->zvel = 6144; + s->z += s->zvel; + } + if( s->z >= hittype[sActor].floorz-(FOURSLEIGHT) ) + { + s->z = hittype[sActor].floorz - FOURSLEIGHT; + s->zvel = 0; + } +} + +short getincangle(short a,short na) +{ + a &= 2047; + na &= 2047; + + if(klabs(a-na) < 1024) + return (na-a); + else + { + if(na > 1024) na -= 2048; + if(a > 1024) a -= 2048; + + na -= 2048; + a -= 2048; + return (na-a); + } +} + +void alterang(short a) +{ + short aang, angdif, goalang,j; + long ticselapsed, *moveptr; + + moveptr = (long *)g_t[1]; + + ticselapsed = (g_t[0])&31; + + aang = g_sp->ang; + + g_sp->xvel += (*moveptr-g_sp->xvel)/5; + if(g_sp->zvel < 648) g_sp->zvel += ((*(moveptr+1)<<4)-g_sp->zvel)/5; + + if(a&seekplayer) + { + j = ps[g_p].holoduke_on; + + // NOTE: looks like 'owner' is set to target sprite ID... + + if(j >= 0 && cansee(sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum,g_sp->x,g_sp->y,g_sp->z,g_sp->sectnum) ) + g_sp->owner = j; + else g_sp->owner = ps[g_p].i; + + if(sprite[g_sp->owner].picnum == APLAYER) + goalang = getangle(hittype[g_i].lastvx-g_sp->x,hittype[g_i].lastvy-g_sp->y); + else + goalang = getangle(sprite[g_sp->owner].x-g_sp->x,sprite[g_sp->owner].y-g_sp->y); + + if(g_sp->xvel && g_sp->picnum != DRONE) + { + angdif = getincangle(aang,goalang); + + if(ticselapsed < 2) + { + if( klabs(angdif) < 256) + { + j = 128-(TRAND&256); + g_sp->ang += j; + if( hits(g_i) < 844 ) + g_sp->ang -= j; + } + } + else if(ticselapsed > 18 && ticselapsed < 26) // choose + { + if(klabs(angdif>>2) < 128) g_sp->ang = goalang; + else g_sp->ang += angdif>>2; + } + } + else g_sp->ang = goalang; + } + + if(ticselapsed < 1) + { + j = 2; + if(a&furthestdir) + { + goalang = furthestangle(g_i,j); + g_sp->ang = goalang; + g_sp->owner = ps[g_p].i; + } + + if(a&fleeenemy) + { + goalang = furthestangle(g_i,j); + g_sp->ang = goalang; // += angdif; // = getincangle(aang,goalang)>>1; + } + } +} + +void move() +{ + long l, *moveptr; + short j, a, goalang, angdif; + long daxvel; + + a = g_sp->hitag; + + if(a == -1) a = 0; + + g_t[0]++; + + if(a&face_player) + { + if(ps[g_p].newowner >= 0) + goalang = getangle(ps[g_p].oposx-g_sp->x,ps[g_p].oposy-g_sp->y); + else goalang = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y); + angdif = getincangle(g_sp->ang,goalang)>>2; + if(angdif > -8 && angdif < 0) angdif = 0; + g_sp->ang += angdif; + } + + if(a&spin) + g_sp->ang += sintable[ ((g_t[0]<<3)&2047) ]>>6; + + if(a&face_player_slow) + { + if(ps[g_p].newowner >= 0) + goalang = getangle(ps[g_p].oposx-g_sp->x,ps[g_p].oposy-g_sp->y); + else goalang = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y); + angdif = ksgn(getincangle(g_sp->ang,goalang))<<5; + if(angdif > -32 && angdif < 0) + { + angdif = 0; + g_sp->ang = goalang; + } + g_sp->ang += angdif; + } + + + if((a&jumptoplayer) == jumptoplayer) + { + if(g_t[0] < 16) + g_sp->zvel -= (sintable[(512+(g_t[0]<<4))&2047]>>5); + } + + if(a&face_player_smart) + { + long newx,newy; + + newx = ps[g_p].posx+(ps[g_p].posxv/768); + newy = ps[g_p].posy+(ps[g_p].posyv/768); + goalang = getangle(newx-g_sp->x,newy-g_sp->y); + angdif = getincangle(g_sp->ang,goalang)>>2; + if(angdif > -8 && angdif < 0) angdif = 0; + g_sp->ang += angdif; + } + + if( g_t[1] == 0 || a == 0 ) + { + if( ( badguy(g_sp) && g_sp->extra <= 0 ) || (hittype[g_i].bposx != g_sp->x) || (hittype[g_i].bposy != g_sp->y) ) + { + hittype[g_i].bposx = g_sp->x; + hittype[g_i].bposy = g_sp->y; + setsprite(g_i,g_sp->x,g_sp->y,g_sp->z); + } + return; + } + + moveptr = (long *)g_t[1]; + + if(a&geth) g_sp->xvel += (*moveptr-g_sp->xvel)>>1; + if(a&getv) g_sp->zvel += ((*(moveptr+1)<<4)-g_sp->zvel)>>1; + + if(a&dodgebullet) + dodge(g_sp); + + if(g_sp->picnum != APLAYER) + alterang(a); + + if(g_sp->xvel > -6 && g_sp->xvel < 6 ) g_sp->xvel = 0; + + a = badguy(g_sp); + + if(g_sp->xvel || g_sp->zvel) + { + if(a && g_sp->picnum != ROTATEGUN) + { + if( (g_sp->picnum == DRONE || g_sp->picnum == COMMANDER) && g_sp->extra > 0) + { + if(g_sp->picnum == COMMANDER) + { + hittype[g_i].floorz = l = getflorzofslope(g_sp->sectnum,g_sp->x,g_sp->y); + if( g_sp->z > (l-(8<<8)) ) + { + if( g_sp->z > (l-(8<<8)) ) g_sp->z = l-(8<<8); + g_sp->zvel = 0; + } + + hittype[g_i].ceilingz = l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y); + if( (g_sp->z-l) < (80<<8) ) + { + g_sp->z = l+(80<<8); + g_sp->zvel = 0; + } + } + else + { + if( g_sp->zvel > 0 ) + { + hittype[g_i].floorz = l = getflorzofslope(g_sp->sectnum,g_sp->x,g_sp->y); + if( g_sp->z > (l-(30<<8)) ) + g_sp->z = l-(30<<8); + } + else + { + hittype[g_i].ceilingz = l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y); + if( (g_sp->z-l) < (50<<8) ) + { + g_sp->z = l+(50<<8); + g_sp->zvel = 0; + } + } + } + } + else if(g_sp->picnum != ORGANTIC) + { + if(g_sp->zvel > 0 && hittype[g_i].floorz < g_sp->z) + g_sp->z = hittype[g_i].floorz; + if( g_sp->zvel < 0) + { + l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y); + if( (g_sp->z-l) < (66<<8) ) + { + g_sp->z = l+(66<<8); + g_sp->zvel >>= 1; + } + } + } + } + else if(g_sp->picnum == APLAYER) + if( (g_sp->z-hittype[g_i].ceilingz) < (32<<8) ) + g_sp->z = hittype[g_i].ceilingz+(32<<8); + + daxvel = g_sp->xvel; + angdif = g_sp->ang; + + if( a && g_sp->picnum != ROTATEGUN ) + { + if( g_x < 960 && g_sp->xrepeat > 16 ) + { + + daxvel = -(1024-g_x); + angdif = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y); + + if(g_x < 512) + { + ps[g_p].posxv = 0; + ps[g_p].posyv = 0; + } + else + { + ps[g_p].posxv = mulscale(ps[g_p].posxv,ps[g_p].runspeed-0x2000,16); + ps[g_p].posyv = mulscale(ps[g_p].posyv,ps[g_p].runspeed-0x2000,16); + } + } + else if(g_sp->picnum != DRONE && g_sp->picnum != SHARK && g_sp->picnum != COMMANDER) + { + if( hittype[g_i].bposz != g_sp->z || ( ud.multimode < 2 && ud.player_skill < 2 ) ) + { + if( (g_t[0]&1) || ps[g_p].actorsqu == g_i ) return; + else daxvel <<= 1; + } + else + { + if( (g_t[0]&3) || ps[g_p].actorsqu == g_i ) return; + else daxvel <<= 2; + } + } + } + + hittype[g_i].movflag = movesprite(g_i, + (daxvel*(sintable[(angdif+512)&2047]))>>14, + (daxvel*(sintable[angdif&2047]))>>14,g_sp->zvel,CLIPMASK0); + } + + if( a ) + { + if (sector[g_sp->sectnum].ceilingstat&1) + g_sp->shade += (sector[g_sp->sectnum].ceilingshade-g_sp->shade)>>1; + else g_sp->shade += (sector[g_sp->sectnum].floorshade-g_sp->shade)>>1; + + if( sector[g_sp->sectnum].floorpicnum == MIRROR ) + deletesprite(g_i); + } +} + +char parse(void); + +void parseifelse(long condition) +{ + if( condition ) + { + // skip 'else' pointer.. and... + insptr+=2; + parse(); + } + else + { + insptr = (long *) *(insptr+1); + if(*insptr == 10) + { + // else... + // skip 'else' and... + insptr+=2; + parse(); + } + } +} + +// long *it = 0x00589a04; + +char parse(void) +{ + long j, l, s, tw; + + if (!(error || warning) && condebug) + { + // Bsprintf(g_szBuf," * DEBUG! Executing: %s",keyw[*insptr]); + // AddLog(g_szBuf); + } + + if(killit_flag) return 1; + + // if(*it == 1668249134L) gameexit("\nERR"); + // Bsprintf(g_szBuf,"Parsing: %d",*insptr); + // AddLog(g_szBuf); + + tw = *insptr; + + switch(tw) + { + case CON_REDEFINEQUOTE: + { + int q, i; + insptr++; + q = *insptr++; + i = *insptr++; + Bstrcpy(fta_quotes[q],redefined_fta_quotes[i]); + break; + } + case CON_GETTHISPROJECTILE: + case CON_SETTHISPROJECTILE: + { + // syntax [gs]etplayer[].x + // + long lLabelID; + long lVar1, lVar2; + long lParm2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + lVar2=*insptr++; + DoThisProjectile(tw==CON_SETTHISPROJECTILE,lVar1,lLabelID,lVar2,g_i,g_p); + break; + } + case CON_IFRND: + insptr++; + parseifelse( rnd(*insptr)); + break; + case CON_IFCANSHOOTTARGET: + + if(g_x > 1024) + { + short temphit, sclip, angdif; + + if( badguy(g_sp) && g_sp->xrepeat > 56 ) + { + sclip = 3084; + angdif = 48; + } + else + { + sclip = 768; + angdif = 16; + } + + j = hitasprite(g_i,&temphit); + if(j == (1<<30)) + { + parseifelse(1); + break; + } + if(j > sclip) + { + if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum) + j = 0; + else + { + g_sp->ang += angdif;j = hitasprite(g_i,&temphit);g_sp->ang -= angdif; + if(j > sclip) + { + if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum) + j = 0; + else + { + g_sp->ang -= angdif;j = hitasprite(g_i,&temphit);g_sp->ang += angdif; + if( j > 768 ) + { + if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum) + j = 0; + else j = 1; + } + else j = 0; + } + } + else j = 0; + } + } + else j = 0; + } + else j = 1; + + parseifelse(j); + break; + case CON_IFCANSEETARGET: + j = cansee(g_sp->x,g_sp->y,g_sp->z-((TRAND&41)<<8),g_sp->sectnum,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz/*-((TRAND&41)<<8)*/,sprite[ps[g_p].i].sectnum); + parseifelse(j); + if( j ) hittype[g_i].timetosleep = SLEEPTIME; + break; + + case CON_IFACTORNOTSTAYPUT: + parseifelse(hittype[g_i].actorstayput == -1); + break; + case CON_IFCANSEE: + { + spritetype *s; + short sect; + + // select sprite for monster to target + // if holoduke is on, let them target holoduke first. + // + if(ps[g_p].holoduke_on >= 0) + { + s = &sprite[ps[g_p].holoduke_on]; + j = cansee(g_sp->x,g_sp->y,g_sp->z-(TRAND&((32<<8)-1)),g_sp->sectnum, + s->x,s->y,s->z,s->sectnum); + + if(j == 0) + { + // they can't see player's holoduke + // check for player... + s = &sprite[ps[g_p].i]; + } + } + else s = &sprite[ps[g_p].i]; // holoduke not on. look for player + + // can they see player, (or player's holoduke) + j = cansee(g_sp->x,g_sp->y,g_sp->z-(TRAND&((47<<8))),g_sp->sectnum, + s->x,s->y,s->z-(24<<8),s->sectnum); + + if(j == 0) + { + // they can't see it. + + // Huh?. This does nothing.... + // (the result is always j==0....) + if( ( klabs(hittype[g_i].lastvx-g_sp->x)+klabs(hittype[g_i].lastvy-g_sp->y) ) < + ( klabs(hittype[g_i].lastvx-s->x)+klabs(hittype[g_i].lastvy-s->y) ) ) + j = 0; + + // um yeah, this if() will always fire.... + if( j == 0 ) + { + // search around for target player + + // also modifies 'target' x&y if found.. + + j = furthestcanseepoint(g_i,s,&hittype[g_i].lastvx,&hittype[g_i].lastvy); + + if(j == -1) j = 0; + else j = 1; + } + } + else + { + // else, they did see it. + // save where we were looking... + hittype[g_i].lastvx = s->x; + hittype[g_i].lastvy = s->y; + } + + if( j == 1 && ( g_sp->statnum == 1 || g_sp->statnum == 6 ) ) + hittype[g_i].timetosleep = SLEEPTIME; + + parseifelse(j == 1); + break; + } + + case CON_IFHITWEAPON: + parseifelse(ifhitbyweapon(g_i) >= 0); + break; + case CON_IFSQUISHED: + parseifelse( ifsquished(g_i, g_p) == 1); + break; + case CON_IFDEAD: + { + j = g_sp->extra; + if(g_sp->picnum == APLAYER) + j--; + parseifelse(j < 0); + } + break; + case CON_AI: + insptr++; + g_t[5] = *insptr++; + g_t[4] = *(long *)(g_t[5]); // Action + g_t[1] = *(long *)(g_t[5]+4); // move + g_sp->hitag = *(long *)(g_t[5]+8); // Ai + g_t[0] = g_t[2] = g_t[3] = 0; + if(g_sp->hitag&random_angle) + g_sp->ang = TRAND&2047; + break; + case CON_ACTION: + insptr++; + g_t[2] = 0; + g_t[3] = 0; + g_t[4] = *insptr++; + break; + + case CON_IFPDISTL: + insptr++; + parseifelse(g_x < *insptr); + if(g_x > MAXSLEEPDIST && hittype[g_i].timetosleep == 0) + hittype[g_i].timetosleep = SLEEPTIME; + break; + case CON_IFPDISTG: + insptr++; + parseifelse(g_x > *insptr); + if(g_x > MAXSLEEPDIST && hittype[g_i].timetosleep == 0) + hittype[g_i].timetosleep = SLEEPTIME; + break; + case CON_ELSE: + insptr = (long *) *(insptr+1); + break; + case CON_ADDSTRENGTH: + insptr++; + g_sp->extra += *insptr++; + break; + case CON_STRENGTH: + insptr++; + g_sp->extra = *insptr++; + break; + case CON_IFGOTWEAPONCE: + insptr++; + + if((gametype_flags[ud.coop]&GAMETYPE_FLAG_WEAPSTAY) && ud.multimode > 1) + { + if(*insptr == 0) + { + for(j=0;j < ps[g_p].weapreccnt;j++) + if( ps[g_p].weaprecs[j] == g_sp->picnum ) + break; + + parseifelse(j < ps[g_p].weapreccnt && g_sp->owner == g_i); + } + else if(ps[g_p].weapreccnt < 16) + { + ps[g_p].weaprecs[ps[g_p].weapreccnt++] = g_sp->picnum; + parseifelse(g_sp->owner == g_i); + } + } + else parseifelse(0); + break; + case CON_GETLASTPAL: + insptr++; + if(g_sp->picnum == APLAYER) + g_sp->pal = ps[g_sp->yvel].palookup; + else g_sp->pal = hittype[g_i].tempang; + hittype[g_i].tempang = 0; + break; + case CON_TOSSWEAPON: + insptr++; + checkweapons(&ps[g_sp->yvel]); + break; + case CON_NULLOP: + insptr++; + break; + case CON_MIKESND: + insptr++; + if(!isspritemakingsound(g_i,g_sp->yvel)) + spritesound(g_sp->yvel,g_i); + break; + case CON_PKICK: + insptr++; + + if( ud.multimode > 1 && g_sp->picnum == APLAYER ) + { + if(ps[otherp].quick_kick == 0) + ps[otherp].quick_kick = 14; + } + else if(g_sp->picnum != APLAYER && ps[g_p].quick_kick == 0) + ps[g_p].quick_kick = 14; + break; + case CON_SIZETO: + insptr++; + + j = (*insptr++-g_sp->xrepeat)<<1; + g_sp->xrepeat += ksgn(j); + + if( ( g_sp->picnum == APLAYER && g_sp->yrepeat < 36 ) || *insptr < g_sp->yrepeat || ((g_sp->yrepeat*(tilesizy[g_sp->picnum]+8))<<2) < (hittype[g_i].floorz - hittype[g_i].ceilingz) ) + { + j = ((*insptr)-g_sp->yrepeat)<<1; + if( klabs(j) ) g_sp->yrepeat += ksgn(j); + } + + insptr++; + + break; + case CON_SIZEAT: + insptr++; + g_sp->xrepeat = (char) *insptr++; + g_sp->yrepeat = (char) *insptr++; + break; + case CON_SHOOT: + insptr++; + shoot(g_i,(short)*insptr++); + break; + case CON_SOUNDONCE: + insptr++; + if(!isspritemakingsound(g_i,*insptr)) + spritesound((short) *insptr,g_i); + insptr++; + break; + case CON_IFSOUND: + insptr++; + parseifelse( Sound[*insptr].num > 0 ); + // parseifelse(SoundOwner[*insptr][0].i == g_i); + break; + case CON_STOPSOUND: + insptr++; + if(isspritemakingsound(g_i,*insptr)) + stopspritesound((short)*insptr,g_i); + insptr++; + break; + case CON_GLOBALSOUND: + insptr++; + if(g_p == screenpeek || (gametype_flags[ud.coop]&GAMETYPE_FLAG_COOPSOUND)) + spritesound((short) *insptr,ps[screenpeek].i); + insptr++; + break; + case CON_SOUND: + insptr++; + spritesound((short) *insptr++,g_i); + break; + case CON_TIP: + insptr++; + ps[g_p].tipincs = 26; + break; + case CON_FALL: + insptr++; + g_sp->xoffset = 0; + g_sp->yoffset = 0; + // if(!gotz) + { + long c; + + if( floorspace(g_sp->sectnum) ) + c = 0; + else + { + if( ceilingspace(g_sp->sectnum) || sector[g_sp->sectnum].lotag == 2) + c = gc/6; + else c = gc; + } + + if( hittype[g_i].cgg <= 0 || (sector[g_sp->sectnum].floorstat&2) ) + { + getglobalz(g_i); + hittype[g_i].cgg = 6; + } + else hittype[g_i].cgg --; + + if( g_sp->z < (hittype[g_i].floorz-FOURSLEIGHT) ) + { + g_sp->zvel += c; + g_sp->z+=g_sp->zvel; + + if(g_sp->zvel > 6144) g_sp->zvel = 6144; + } + else + { + g_sp->z = hittype[g_i].floorz - FOURSLEIGHT; + + if( badguy(g_sp) || ( g_sp->picnum == APLAYER && g_sp->owner >= 0) ) + { + + if( g_sp->zvel > 3084 && g_sp->extra <= 1) + { + if(g_sp->pal != 1 && g_sp->picnum != DRONE) + { + if(g_sp->picnum == APLAYER && g_sp->extra > 0) + goto SKIPJIBS; + guts(g_sp,JIBS6,15,g_p); + spritesound(SQUISHED,g_i); + spawn(g_i,BLOODPOOL); + } + +SKIPJIBS: + + hittype[g_i].picnum = SHOTSPARK1; + hittype[g_i].extra = 1; + g_sp->zvel = 0; + } + else if(g_sp->zvel > 2048 && sector[g_sp->sectnum].lotag != 1) + { + + j = g_sp->sectnum; + pushmove(&g_sp->x,&g_sp->y,&g_sp->z,(short*)&j,128L,(4L<<8),(4L<<8),CLIPMASK0); + if(j != g_sp->sectnum && j >= 0 && j < MAXSECTORS) + changespritesect(g_i,j); + + spritesound(THUD,g_i); + } + } + if(sector[g_sp->sectnum].lotag == 1) + switch (dynamictostatic[g_sp->picnum]) + { + case OCTABRAIN__STATIC: + case COMMANDER__STATIC: + case DRONE__STATIC: + break; + default: + g_sp->z += (24<<8); + break; + } + else g_sp->zvel = 0; + } + } + + break; + case CON_ENDA: + case CON_BREAK: + case CON_ENDS: + return 1; + case CON_RIGHTBRACE: + insptr++; + return 1; + case CON_ADDAMMO: + insptr++; + if( ps[g_p].ammo_amount[*insptr] >= max_ammo_amount[*insptr] ) + { + killit_flag = 2; + break; + } + addammo( *insptr, &ps[g_p], *(insptr+1) ); + if(ps[g_p].curr_weapon == KNEE_WEAPON) + if( ps[g_p].gotweapon[*insptr]) { + if (!(ps[g_p].weaponswitch & 1)) addweaponnoswitch(&ps[g_p], *insptr); + else addweapon( &ps[g_p], *insptr ); + } + insptr += 2; + break; + case CON_MONEY: + insptr++; + lotsofmoney(g_sp,*insptr++); + break; + case CON_MAIL: + insptr++; + lotsofmail(g_sp,*insptr++); + break; + case CON_SLEEPTIME: + insptr++; + hittype[g_i].timetosleep = (short)*insptr++; + break; + case CON_PAPER: + insptr++; + lotsofpaper(g_sp,*insptr++); + break; + case CON_ADDKILLS: + insptr++; + ps[g_p].actors_killed += *insptr++; + hittype[g_i].actorstayput = -1; + break; + case CON_LOTSOFGLASS: + insptr++; + spriteglass(g_i,*insptr++); + break; + case CON_KILLIT: + insptr++; + killit_flag = 1; + break; + case CON_ADDWEAPON: + insptr++; + if( ps[g_p].gotweapon[*insptr] == 0 ) { + if (!(ps[g_p].weaponswitch & 1)) addweaponnoswitch(&ps[g_p], *insptr); + else addweapon( &ps[g_p], *insptr ); + } + else if( ps[g_p].ammo_amount[*insptr] >= max_ammo_amount[*insptr] ) + { + killit_flag = 2; + break; + } + addammo( *insptr, &ps[g_p], *(insptr+1) ); + if(ps[g_p].curr_weapon == KNEE_WEAPON) + if( ps[g_p].gotweapon[*insptr]) { + if (!(ps[g_p].weaponswitch & 1)) addweaponnoswitch(&ps[g_p], *insptr); + else addweapon( &ps[g_p], *insptr ); + } + insptr+=2; + break; + case CON_DEBUG: + insptr++; + printf("%ld\n",*insptr++); + break; + case CON_ENDOFGAME: + insptr++; + ps[g_p].timebeforeexit = *insptr++; + ps[g_p].customexitsound = -1; + ud.eog = 1; + break; + case CON_ADDPHEALTH: + insptr++; + + if(ps[g_p].newowner >= 0) + { + ps[g_p].newowner = -1; + ps[g_p].posx = ps[g_p].oposx; + ps[g_p].posy = ps[g_p].oposy; + ps[g_p].posz = ps[g_p].oposz; + ps[g_p].ang = ps[g_p].oang; + updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum); + setpal(&ps[g_p]); + + j = headspritestat[1]; + while(j >= 0) + { + if(sprite[j].picnum==CAMERA1) + sprite[j].yvel = 0; + j = nextspritestat[j]; + } + } + + j = sprite[ps[g_p].i].extra; + + if(g_sp->picnum != ATOMICHEALTH) + { + if( j > max_player_health && *insptr > 0 ) + { + insptr++; + break; + } + else + { + if(j > 0) + j += *insptr; + if ( j > max_player_health && *insptr > 0 ) + j = max_player_health; + } + } + else + { + if( j > 0 ) + j += *insptr; + if ( j > (max_player_health<<1) ) + j = (max_player_health<<1); + } + + if(j < 0) j = 0; + + if(ud.god == 0) + { + if(*insptr > 0) + { + if( ( j - *insptr ) < (max_player_health>>2) && + j >= (max_player_health>>2) ) + spritesound(DUKE_GOTHEALTHATLOW,ps[g_p].i); + + ps[g_p].last_extra = j; + } + + sprite[ps[g_p].i].extra = j; + } + + insptr++; + break; + case CON_STATE: + { + long *tempscrptr; + + tempscrptr = insptr+2; + + insptr = (long *) *(insptr+1); + while(1) if(parse()) break; + insptr = tempscrptr; + } + break; + case CON_LEFTBRACE: + insptr++; + while(1) if(parse()) break; + break; + case CON_MOVE: + insptr++; + g_t[0]=0; + g_t[1] = *insptr++; + g_sp->hitag = *insptr++; + if(g_sp->hitag&random_angle) + g_sp->ang = TRAND&2047; + break; + + case CON_ADDWEAPONVAR: + insptr++; + if( ps[g_p].gotweapon[GetGameVarID(*(insptr),g_i,g_p)] == 0 ) { + if (!(ps[g_p].weaponswitch & 1)) addweaponnoswitch(&ps[g_p], GetGameVarID(*(insptr),g_i,g_p)); + else addweapon( &ps[g_p], GetGameVarID(*(insptr),g_i,g_p) ); + } + else if( ps[g_p].ammo_amount[GetGameVarID(*(insptr),g_i,g_p)] >= max_ammo_amount[GetGameVarID(*(insptr),g_i,g_p)] ) + { + killit_flag = 2; + break; + } + addammo( GetGameVarID(*(insptr),g_i,g_p), &ps[g_p], GetGameVarID(*(insptr+1),g_i,g_p) ); + if(ps[g_p].curr_weapon == KNEE_WEAPON) + if( ps[g_p].gotweapon[GetGameVarID(*(insptr),g_i,g_p)] ) { + if (!(ps[g_p].weaponswitch & 1)) addweaponnoswitch(&ps[g_p], GetGameVarID(*(insptr),g_i,g_p)); + else addweapon( &ps[g_p], GetGameVarID(*(insptr),g_i,g_p) ); + } + insptr+=2; + break; + + case CON_ACTIVATEBYSECTOR: + case CON_OPERATESECTORS: + case CON_OPERATEACTIVATORS: + case CON_SETASPECT: + case CON_SSP: + { + long var1, var2; + + insptr++; + var1 = GetGameVarID(*insptr++,g_i,g_p); + var2 = GetGameVarID(*insptr++,g_i,g_p); + + switch(tw) + { + case CON_ACTIVATEBYSECTOR: + activatebysector(var1, var2); + break; + case CON_OPERATESECTORS: + operatesectors(var1, var2); + break; + case CON_OPERATEACTIVATORS: + operateactivators(var1, var2); + break; + case CON_SETASPECT: + setaspect(var1, var2); + break; + case CON_SSP: + ssp(var1, var2); + break; + } + break; + } + + case CON_OPERATERESPAWNS: + case CON_OPERATEMASTERSWITCHES: + case CON_CHECKACTIVATORMOTION: + { + long var1; + + insptr++; + var1 = GetGameVarID(*insptr++,g_i,g_p); + + switch(tw) + { + case CON_OPERATERESPAWNS: + operaterespawns(var1); + break; + case CON_OPERATEMASTERSWITCHES: + operatemasterswitches(var1); + break; + case CON_CHECKACTIVATORMOTION: + SetGameVarID(g_iReturnVarID, check_activator_motion(var1), g_i, g_p); + break; + } + break; + } + + + case CON_INSERTSPRITEQ: + insptr++; + insertspriteq(g_i); + break; + + case CON_GETPNAME: + case CON_QSTRCAT: + case CON_QSTRCPY: + case CON_CHANGESPRITESTAT: + case CON_CHANGESPRITESECT: + { + int i,j; + insptr++; + i = GetGameVarID(*insptr++, g_i, g_p); + j = GetGameVarID(*insptr++, g_i, g_p); + switch(tw) + { + case CON_GETPNAME: + if (ud.user_name[j][0] != 0) + Bsprintf(fta_quotes[i],ud.user_name[j]); + else Bsprintf(fta_quotes[i],"%d",j); + break; + case CON_QSTRCAT: + Bstrncat(fta_quotes[i],fta_quotes[j],63-Bstrlen(fta_quotes[i])); + break; + case CON_QSTRCPY: + Bstrcpy(fta_quotes[i],fta_quotes[j]); + break; + case CON_CHANGESPRITESTAT: + changespritestat(i,j); + break; + case CON_CHANGESPRITESECT: + changespritesect(i,j); + break; + } + break; + } + + case CON_STARTLEVEL: + { + // from 'level' cheat in game.c (about line 6250) + long volnume; + long levnume; + int i; + + insptr++; // skip command + volnume=GetGameVarID(*insptr++,g_i,g_p); + levnume=GetGameVarID(*insptr++,g_i,g_p); + + if(volnume > num_volumes || volnume < 0) + { + /* + if( g_cmddebug&CMDDEBUG_COMPILE) + { + Bsprintf(g_szBuf,"startlevel: Invalid Volume number: %ld. Command ignored.",volnume); + AddLog(g_szBuf); + } + */ + break; + } + + if(levnume >= 11 || levnume <0) + { + /* + if( g_cmddebug&CMDDEBUG_COMPILE) + { + Bsprintf(g_szBuf,"startlevel: Invalid Level number: %ld. Command ignored.",levnume); + AddLog(g_szBuf); + } + */ + break; + } + + ud.m_volume_number = ud.volume_number = volnume; + ud.m_level_number = ud.level_number = levnume; + if(numplayers > 1 && myconnectindex == connecthead) + { + tempbuf[0] = 5; + tempbuf[1] = ud.m_level_number; + tempbuf[2] = ud.m_volume_number; + tempbuf[3] = ud.m_player_skill; + tempbuf[4] = ud.m_monsters_off; + tempbuf[5] = ud.m_respawn_monsters; + tempbuf[6] = ud.m_respawn_items; + tempbuf[7] = ud.m_respawn_inventory; + tempbuf[8] = ud.m_coop; + tempbuf[9] = ud.m_marker; + tempbuf[10] = ud.m_ffire; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + sendpacket(i,tempbuf,11); + } + else { ps[myconnectindex].gm |= MODE_EOL; display_bonus_screen = 0; } // MODE_RESTART; + + break; + } + + case CON_MYOSX: + case CON_MYOSPALX: + case CON_MYOS: + case CON_MYOSPAL: + { + long x,y; + short tilenum; + signed char shade; + char orientation; + char pal; + + insptr++; + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + tilenum=GetGameVarID(*insptr++,g_i,g_p); + shade=GetGameVarID(*insptr++,g_i,g_p); + orientation=GetGameVarID(*insptr++,g_i,g_p); + + switch(tw) + { + case CON_MYOS: + myos(x,y,tilenum,shade,orientation); + break; + case CON_MYOSPAL: + pal=GetGameVarID(*insptr++,g_i,g_p); + myospal(x,y,tilenum,shade,orientation,pal); + break; + case CON_MYOSX: + myosx(x,y,tilenum,shade,orientation); + break; + case CON_MYOSPALX: + pal=GetGameVarID(*insptr++,g_i,g_p); + myospalx(x,y,tilenum,shade,orientation,pal); + break; + } + break; + } + + case CON_SWITCH: + { + long lVarID; + long lValue; + long *lpDefault; + long *lpCases; + long lCases; + long lEnd; + long lCheckCase; + char bMatched; + long *lTempInsPtr; + + // command format: + // variable ID to check + // script offset to 'end' + // count of case statements + // script offset to default case (null if none) + // For each case: value, ptr to code + //AddLog("Processing Switch..."); + insptr++; // p-code + lVarID=*insptr++; + lValue=GetGameVarID(lVarID, g_i, g_p); + lEnd=*insptr++; + lCases=*insptr++; + lpDefault=insptr++; + lpCases=insptr; + insptr+=lCases*2; + bMatched=0; + lTempInsPtr=insptr; + //Bsprintf(g_szBuf,"lEnd= %ld *lpDefault=%ld",lEnd,*lpDefault); + //AddLog(g_szBuf); + + //Bsprintf(g_szBuf,"Checking %ld cases for %ld",lCases, lValue); + //AddLog(g_szBuf); + for(lCheckCase=0; lCheckCasesectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i, lIn); + + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + insertspriteq(lReturn); + break; + } + + case CON_INITTIMER: + { + short i; + insptr++; + i = GetGameVarID(*insptr++, g_i, g_p); + if (timer != i) + { + uninittimer(); + inittimer(i); + timer = i; + } + break; + } + + case CON_TIME: + { + insptr += 2; + break; + } + + case CON_ESPAWNVAR: + { + long lIn, lReturn=-1; + + insptr++; + + lIn=*insptr++; + lIn=GetGameVarID(lIn, g_i, g_p); + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i, lIn); + + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + break; + } + + case CON_QSPAWNVAR: + { + long lIn, lReturn=-1; + + insptr++; + + lIn=*insptr++; + lIn=GetGameVarID(lIn, g_i, g_p); + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i, lIn); + + insertspriteq(lReturn); + break; + } + + case CON_ESPAWN: + { + long lReturn=-1; + + insptr++; + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i,*insptr); + insptr++; + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + break; + } + + case CON_EQSPAWN: + { + long lReturn=-1; + + insptr++; + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i,*insptr); + insptr++; + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + insertspriteq(lReturn); + break; + } + + case CON_QSPAWN: + { + long lReturn=-1; + + insptr++; + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = spawn(g_i,*insptr); + insptr++; + insertspriteq(lReturn); + break; + } + + case CON_ESHOOT: + { + long lReturn=-1; + + insptr++; + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = shoot(g_i,*insptr); + insptr++; + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + break; + } + + case CON_ZSHOOT: + { + insptr++; + hittype[g_i].temp_data[9] = GetGameVarID(*insptr++, g_i, g_p); + if (hittype[g_i].temp_data[9] == 0) + hittype[g_i].temp_data[9] = 1; + shoot(g_i,*insptr++); + hittype[g_i].temp_data[9]=0; + break; + } + + case CON_SHOOTVAR: + case CON_ESHOOTVAR: + { + long lIn, lReturn=-1; + + insptr++; + + lIn=GetGameVarID(*insptr++, g_i, g_p); + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + lReturn = shoot(g_i, lIn); + if (tw == CON_ESHOOTVAR) + SetGameVarID(g_iReturnVarID, lReturn, g_i, g_p); + break; + } + + case CON_SOUNDVAR: + case CON_STOPSOUNDVAR: + case CON_SOUNDONCEVAR: + case CON_GLOBALSOUNDVAR: + { + int sound; + + insptr++; + sound=GetGameVarID(*insptr++, g_i, g_p); + + switch(tw) + { + case CON_SOUNDONCEVAR: + if(!isspritemakingsound(g_i,sound)) + spritesound((short)sound,g_i); + break; + case CON_GLOBALSOUNDVAR: + spritesound((short)sound,ps[screenpeek].i); + break; + case CON_STOPSOUNDVAR: + if(isspritemakingsound(g_i,sound)) + stopspritesound((short)sound,g_i); + break; + case CON_SOUNDVAR: + spritesound((short)sound,g_i); + break; + } + break; + } + + case CON_GUNIQHUDID: + { + int i; + insptr++; + i=GetGameVarID(*insptr++, g_i, g_p); + if (i < MAXUNIQHUDID-1) + guniqhudid = i; + break; + } + + case CON_SAVEGAMEVAR: + case CON_READGAMEVAR: + { + int32 i=0; + insptr++; + if (scripthandle < 0) break; + switch(tw) + { + case CON_SAVEGAMEVAR: + i=GetGameVarID(*insptr, g_i, g_p); + SCRIPT_PutNumber( scripthandle, "Gamevars",aGameVars[*insptr++].szLabel,i,false,false); + break; + case CON_READGAMEVAR: + SCRIPT_GetNumber( scripthandle, "Gamevars",aGameVars[*insptr].szLabel,&i); + SetGameVarID(*insptr++, i, g_i, g_p); + break; + } + break; + } + + case CON_ROTATESPRITE: + { + long x,y,z; + short tilenum; + short a; + signed char shade; + char orientation; + char pal; + long x1, y1, x2, y2; + insptr++; + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + z=GetGameVarID(*insptr++,g_i,g_p); + a=GetGameVarID(*insptr++,g_i,g_p); + tilenum=GetGameVarID(*insptr++,g_i,g_p); + shade=GetGameVarID(*insptr++,g_i,g_p); + pal=GetGameVarID(*insptr++,g_i,g_p); + orientation=GetGameVarID(*insptr++,g_i,g_p); + x1=GetGameVarID(*insptr++,g_i,g_p); + y1=GetGameVarID(*insptr++,g_i,g_p); + x2=GetGameVarID(*insptr++,g_i,g_p); + y2=GetGameVarID(*insptr++,g_i,g_p); + + rotatesprite(x<<16,y<<16,z,a,tilenum,shade,pal,2|orientation,x1,y1,x2,y2); + break; + } + + case CON_MINITEXT: + case CON_GAMETEXT: + case CON_DIGITALNUMBER: + { + long x,y,z; + short tilenum=0; + short a; + signed char shade; + char orientation=0; + char pal; + long x1=0, y1=0, x2=0, y2=0; + long q; + insptr++; + + if (tw == CON_GAMETEXT || tw == CON_DIGITALNUMBER) + tilenum=GetGameVarID(*insptr++,g_i,g_p); + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + q=GetGameVarID(*insptr++,g_i,g_p); + shade=GetGameVarID(*insptr++,g_i,g_p); + pal=GetGameVarID(*insptr++,g_i,g_p); + if (tw == CON_GAMETEXT || tw == CON_DIGITALNUMBER) + { + orientation=GetGameVarID(*insptr++,g_i,g_p); + x1=GetGameVarID(*insptr++,g_i,g_p); + y1=GetGameVarID(*insptr++,g_i,g_p); + x2=GetGameVarID(*insptr++,g_i,g_p); + y2=GetGameVarID(*insptr++,g_i,g_p); + } + + if (tw == CON_MINITEXT) minitextshade(x,y,fta_quotes[q],shade,pal,26); + else if (tw == CON_GAMETEXT) txgametext(tilenum,x>>1,y,fta_quotes[q],shade,pal,orientation,x1,y1,x2,y2); + else if (tw == CON_DIGITALNUMBER) txdigitalnumber(tilenum,x,y,q,shade,pal,orientation,x1,y1,x2,y2); + break; + } + + case CON_ANGOFF: + insptr++; + spriteext[g_i].angoff=*insptr++; + break; + + case CON_GETZRANGE: + { + long x, y, z, ceilz, ceilhit, florz, florhit, walldist, clipmask; + long ceilzvar, ceilhitvar, florzvar, florhitvar; + short sectnum; + + insptr++; + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + z=GetGameVarID(*insptr++,g_i,g_p); + sectnum=GetGameVarID(*insptr++,g_i,g_p); + ceilzvar=*insptr++; + ceilhitvar=*insptr++; + florzvar=*insptr++; + florhitvar=*insptr++; + walldist=GetGameVarID(*insptr++,g_i,g_p); + clipmask=GetGameVarID(*insptr++,g_i,g_p); + + getzrange(x, y, z, sectnum, &ceilz, &ceilhit, &florz, &florhit, walldist, clipmask); + SetGameVarID(ceilzvar, ceilz, g_i, g_p); + SetGameVarID(ceilhitvar, ceilhit, g_i, g_p); + SetGameVarID(florzvar, florz, g_i, g_p); + SetGameVarID(florhitvar, florhit, g_i, g_p); + break; + } + + case CON_HITSCAN: + { + long xs, ys, zs, vx, vy, vz, hitx, hity, hitz; + short sectnum, hitsect, hitwall, hitsprite; + unsigned long cliptype; + + long hitxvar, hityvar, hitzvar; + short hitsectvar, hitwallvar, hitspritevar; + + insptr++; + xs=GetGameVarID(*insptr++,g_i,g_p); + ys=GetGameVarID(*insptr++,g_i,g_p); + zs=GetGameVarID(*insptr++,g_i,g_p); + sectnum=GetGameVarID(*insptr++,g_i,g_p); + vx=GetGameVarID(*insptr++,g_i,g_p); + vy=GetGameVarID(*insptr++,g_i,g_p); + vz=GetGameVarID(*insptr++,g_i,g_p); + hitsectvar=*insptr++; + hitwallvar=*insptr++; + hitspritevar=*insptr++; + hitxvar=*insptr++; + hityvar=*insptr++; + hitzvar=*insptr++; + cliptype=GetGameVarID(*insptr++,g_i,g_p); + hitscan(xs, ys, zs, sectnum, vx, vy, vz, &hitsect, &hitwall, &hitsprite, &hitx, &hity, &hitz, cliptype); + SetGameVarID(hitsectvar, hitsect, g_i, g_p); + SetGameVarID(hitwallvar, hitwall, g_i, g_p); + SetGameVarID(hitspritevar, hitsprite, g_i, g_p); + SetGameVarID(hitxvar, hitx, g_i, g_p); + SetGameVarID(hityvar, hity, g_i, g_p); + SetGameVarID(hitzvar, hitz, g_i, g_p); + break; + } + + case CON_ROTATEPOINT: + { + long xpivot, ypivot, x, y, x2, y2, x2var, y2var; + short daang; + + insptr++; + xpivot=GetGameVarID(*insptr++,g_i,g_p); + ypivot=GetGameVarID(*insptr++,g_i,g_p); + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + daang=GetGameVarID(*insptr++,g_i,g_p); + x2var=*insptr++; + y2var=*insptr++; + rotatepoint(xpivot,ypivot,x,y,daang,&x2,&y2); + SetGameVarID(x2var, x2, g_i, g_p); + SetGameVarID(y2var, y2, g_i, g_p); + break; + } + + case CON_NEARTAG: + { + // neartag(long x, long y, long z, short sectnum, short ang, //Starting position & angle + // short *neartagsector, //Returns near sector if sector[].tag != 0 + // short *neartagwall, //Returns near wall if wall[].tag != 0 + // short *neartagsprite, //Returns near sprite if sprite[].tag != 0 + // long *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) + // long neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size) + // char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag + + long x, y, z, neartaghitdist, neartagrange; + short sectnum, ang, neartagsector, neartagwall, neartagsprite; + long neartagsectorvar, neartagwallvar, neartagspritevar, neartaghitdistvar; + char tagsearch; + + insptr++; + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + z=GetGameVarID(*insptr++,g_i,g_p); + sectnum=GetGameVarID(*insptr++,g_i,g_p); + ang=GetGameVarID(*insptr++,g_i,g_p); + neartagsectorvar=*insptr++; + neartagwallvar=*insptr++; + neartagspritevar=*insptr++; + neartaghitdistvar=*insptr++; + neartagrange=GetGameVarID(*insptr++,g_i,g_p); + tagsearch=GetGameVarID(*insptr++,g_i,g_p); + neartag(x, y, z, sectnum, ang, &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, neartagrange, tagsearch); + SetGameVarID(neartagsectorvar, neartagsector, g_i, g_p); + SetGameVarID(neartagwallvar, neartagwall, g_i, g_p); + SetGameVarID(neartagspritevar, neartagsprite, g_i, g_p); + SetGameVarID(neartaghitdistvar, neartaghitdist, g_i, g_p); + break; + } + + case CON_MOVESPRITE: + case CON_SETSPRITE: + { + short spritenum; + long x, y, z; + unsigned long cliptype, returnvar; + insptr++; + spritenum = GetGameVarID(*insptr++,g_i,g_p); + x = GetGameVarID(*insptr++,g_i,g_p); + y = GetGameVarID(*insptr++,g_i,g_p); + z = GetGameVarID(*insptr++,g_i,g_p); + switch(tw) + { + case CON_MOVESPRITE: + cliptype = GetGameVarID(*insptr++,g_i,g_p); + returnvar = *insptr++; + SetGameVarID(returnvar, movesprite(spritenum, x, y, z, cliptype), g_i, g_p); + break; + case CON_SETSPRITE: + setsprite(spritenum, x, y, z); + break; + } + break; + } + + case CON_GETFLORZOFSLOPE: + case CON_GETCEILZOFSLOPE: + { + short sectnum; + long x, y; + unsigned long returnvar; + insptr++; + sectnum = GetGameVarID(*insptr++,g_i,g_p); + x = GetGameVarID(*insptr++,g_i,g_p); + y = GetGameVarID(*insptr++,g_i,g_p); + returnvar = *insptr++; + switch(tw) + { + case CON_GETFLORZOFSLOPE: + SetGameVarID(returnvar, getflorzofslope(sectnum,x,y), g_i, g_p); + break; + case CON_GETCEILZOFSLOPE: + SetGameVarID(returnvar, getceilzofslope(sectnum,x,y), g_i, g_p); + break; + } + break; + } + + case CON_UPDATESECTOR: + case CON_UPDATESECTORZ: + { + long x,y,z=0; + int var; + short w; + + w=sprite[g_i].sectnum; + + insptr++; + + x=GetGameVarID(*insptr++,g_i,g_p); + y=GetGameVarID(*insptr++,g_i,g_p); + if (tw==CON_UPDATESECTORZ) z=GetGameVarID(*insptr++,g_i,g_p); + var=*insptr++; + + if (tw==CON_UPDATESECTOR) updatesector(x,y,&w); + else if (tw==CON_UPDATESECTORZ) updatesectorz(x,y,z,&w); + + SetGameVarID(var, w, g_i, g_p); + break; + } + + case CON_SPAWN: + insptr++; + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + spawn(g_i,*insptr); + insptr++; + break; + case CON_IFWASWEAPON: + insptr++; + parseifelse( hittype[g_i].picnum == *insptr); + break; + case CON_IFAI: + insptr++; + parseifelse(g_t[5] == *insptr); + break; + case CON_IFACTION: + insptr++; + parseifelse(g_t[4] == *insptr); + break; + case CON_IFACTIONCOUNT: + insptr++; + parseifelse(g_t[2] >= *insptr); + break; + case CON_RESETACTIONCOUNT: + insptr++; + g_t[2] = 0; + break; + case CON_DEBRIS: + { + short dnum; + + insptr++; + dnum = *insptr++; + + if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS) + for(j=(*insptr)-1;j>=0;j--) + { + if(g_sp->picnum == BLIMP && dnum == SCRAP1) + s = 0; + else s = (TRAND%3); + + l = EGS(g_sp->sectnum, + g_sp->x+(TRAND&255)-128,g_sp->y+(TRAND&255)-128,g_sp->z-(8<<8)-(TRAND&8191), + dnum+s,g_sp->shade,32+(TRAND&15),32+(TRAND&15), + TRAND&2047,(TRAND&127)+32, + -(TRAND&2047),g_i,5); + if(g_sp->picnum == BLIMP && dnum == SCRAP1) + sprite[l].yvel = weaponsandammosprites[j%14]; + else sprite[l].yvel = -1; + sprite[l].pal = g_sp->pal; + } + insptr++; + } + break; + + case CON_COUNT: + insptr++; + g_t[0] = (short) *insptr++; + break; + case CON_CSTATOR: + insptr++; + g_sp->cstat |= (short) *insptr++; + break; + case CON_CLIPDIST: + insptr++; + g_sp->clipdist = (short) *insptr++; + break; + case CON_CSTAT: + insptr++; + g_sp->cstat = (short) *insptr++; + break; + case CON_SAVE: + { + int i; + time_t curtime; + + insptr++; + i = *insptr++; + if(movesperpacket == 4 && connecthead != myconnectindex) + break; + + lastsavedpos = i; + curtime = time(NULL); + Bstrcpy(tempbuf,asctime(localtime(&curtime))); + clearbuf(ud.savegame[lastsavedpos],sizeof(ud.savegame[lastsavedpos]),0); + Bsprintf(ud.savegame[lastsavedpos],"Auto"); + for(i=0;i<13;i++) + Bmemcpy(&ud.savegame[lastsavedpos][i+4],&tempbuf[i+3],sizeof(tempbuf[i+3])); + ud.savegame[lastsavedpos][Bstrlen(ud.savegame[lastsavedpos])] = '\0'; + OSD_Printf("Saving to slot %d\n",lastsavedpos); + + KB_FlushKeyboardQueue(); + + screencapt = 1; + displayrooms(myconnectindex,65536); + //savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100); + screencapt = 0; + if(ud.multimode > 1) + saveplayer(-1-(lastsavedpos)); + else saveplayer(lastsavedpos); + + break; + } + case CON_IFMOVE: + insptr++; + parseifelse(g_t[1] == *insptr); + break; + case CON_RESETPLAYER: + { + insptr++; + + //AddLog("resetplayer"); + if(ud.multimode < 2) + { + if( lastsavedpos >= 0 && ud.recstat != 2 ) + { + ps[g_p].gm = MODE_MENU; + KB_ClearKeyDown(sc_Space); + cmenu(15000); + } + else ps[g_p].gm = MODE_RESTART; + killit_flag = 2; + } + else + { + pickrandomspot(g_p); + g_sp->x = hittype[g_i].bposx = ps[g_p].bobposx = ps[g_p].oposx = ps[g_p].posx; + g_sp->y = hittype[g_i].bposy = ps[g_p].bobposy = ps[g_p].oposy =ps[g_p].posy; + g_sp->z = hittype[g_i].bposy = ps[g_p].oposz =ps[g_p].posz; + updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum); + setsprite(ps[g_p].i,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz+PHEIGHT); + g_sp->cstat = 257; + + g_sp->shade = -12; + g_sp->clipdist = 64; + g_sp->xrepeat = 42; + g_sp->yrepeat = 36; + g_sp->owner = g_i; + g_sp->xoffset = 0; + g_sp->pal = ps[g_p].palookup; + + ps[g_p].last_extra = g_sp->extra = max_player_health; + ps[g_p].wantweaponfire = -1; + ps[g_p].horiz = 100; + ps[g_p].on_crane = -1; + ps[g_p].frag_ps = g_p; + ps[g_p].horizoff = 0; + ps[g_p].opyoff = 0; + ps[g_p].wackedbyactor = -1; + ps[g_p].shield_amount = max_armour_amount; + ps[g_p].dead_flag = 0; + ps[g_p].pals_time = 0; + ps[g_p].footprintcount = 0; + ps[g_p].weapreccnt = 0; + ps[g_p].fta = 0; + ps[g_p].ftq = 0; + ps[g_p].posxv = ps[g_p].posyv = 0; + ps[g_p].rotscrnang = 0; + ps[g_p].runspeed = dukefriction; + ps[g_p].falling_counter = 0; + + hittype[g_i].extra = -1; + hittype[g_i].owner = g_i; + + hittype[g_i].cgg = 0; + hittype[g_i].movflag = 0; + hittype[g_i].tempang = 0; + hittype[g_i].actorstayput = -1; + hittype[g_i].dispicnum = 0; + hittype[g_i].owner = ps[g_p].i; + + resetinventory(g_p); + resetweapons(g_p); + + ps[g_p].reloading = 0; + + ps[g_p].movement_lock[1] = 0; + ps[g_p].movement_lock[2] = 0; + ps[g_p].movement_lock[3] = 0; + ps[g_p].movement_lock[4] = 0; + + OnEvent(EVENT_RESETPLAYER, ps[g_p].i, g_p, -1); + cameradist = 0; + cameraclock = totalclock; + } + setpal(&ps[g_p]); + //AddLog("EOF: resetplayer"); + } + break; + case CON_IFONWATER: + parseifelse( klabs(g_sp->z-sector[g_sp->sectnum].floorz) < (32<<8) && sector[g_sp->sectnum].lotag == 1); + break; + case CON_IFINWATER: + parseifelse( sector[g_sp->sectnum].lotag == 2); + break; + case CON_IFCOUNT: + insptr++; + parseifelse(g_t[0] >= *insptr); + break; + case CON_IFACTOR: + insptr++; + parseifelse(g_sp->picnum == *insptr); + break; + case CON_RESETCOUNT: + insptr++; + g_t[0] = 0; + break; + case CON_ADDINVENTORY: + insptr+=2; + switch(*(insptr-1)) + { + case GET_STEROIDS: + ps[g_p].steroids_amount = *insptr; + ps[g_p].inven_icon = 2; + break; + case GET_SHIELD: + ps[g_p].shield_amount += *insptr;// 100; + if(ps[g_p].shield_amount > max_player_health) + ps[g_p].shield_amount = max_player_health; + break; + case GET_SCUBA: + ps[g_p].scuba_amount = *insptr;// 1600; + ps[g_p].inven_icon = 6; + break; + case GET_HOLODUKE: + ps[g_p].holoduke_amount = *insptr;// 1600; + ps[g_p].inven_icon = 3; + break; + case GET_JETPACK: + ps[g_p].jetpack_amount = *insptr;// 1600; + ps[g_p].inven_icon = 4; + break; + case GET_ACCESS: + switch(g_sp->pal) + { + case 0: ps[g_p].got_access |= 1;break; + case 21: ps[g_p].got_access |= 2;break; + case 23: ps[g_p].got_access |= 4;break; + } + break; + case GET_HEATS: + ps[g_p].heat_amount = *insptr; + ps[g_p].inven_icon = 5; + break; + case GET_FIRSTAID: + ps[g_p].inven_icon = 1; + ps[g_p].firstaid_amount = *insptr; + break; + case GET_BOOTS: + ps[g_p].inven_icon = 7; + ps[g_p].boot_amount = *insptr; + break; + } + insptr++; + break; + case CON_HITRADIUS: + hitradius(g_i,*(insptr+1),*(insptr+2),*(insptr+3),*(insptr+4),*(insptr+5)); + insptr+=6; + break; + case CON_IFP: + { + insptr++; + + l = *insptr; + j = 0; + + s = g_sp->xvel; + + if( (l&8) && ps[g_p].on_ground && (sync[g_p].bits&2) ) + j = 1; + else if( (l&16) && ps[g_p].jumping_counter == 0 && !ps[g_p].on_ground && + ps[g_p].poszv > 2048 ) + j = 1; + else if( (l&32) && ps[g_p].jumping_counter > 348 ) + j = 1; + else if( (l&1) && s >= 0 && s < 8) + j = 1; + else if( (l&2) && s >= 8 && !(sync[g_p].bits&(1<<5)) ) + j = 1; + else if( (l&4) && s >= 8 && sync[g_p].bits&(1<<5) ) + j = 1; + else if( (l&64) && ps[g_p].posz < (g_sp->z-(48<<8)) ) + j = 1; + else if( (l&128) && s <= -8 && !(sync[g_p].bits&(1<<5)) ) + j = 1; + else if( (l&256) && s <= -8 && (sync[g_p].bits&(1<<5)) ) + j = 1; + else if( (l&512) && ( ps[g_p].quick_kick > 0 || ( ps[g_p].curr_weapon == KNEE_WEAPON && ps[g_p].kickback_pic > 0 ) ) ) + j = 1; + else if( (l&1024) && sprite[ps[g_p].i].xrepeat < 32 ) + j = 1; + else if( (l&2048) && ps[g_p].jetpack_on ) + j = 1; + else if( (l&4096) && ps[g_p].steroids_amount > 0 && ps[g_p].steroids_amount < 400 ) + j = 1; + else if( (l&8192) && ps[g_p].on_ground) + j = 1; + else if( (l&16384) && sprite[ps[g_p].i].xrepeat > 32 && sprite[ps[g_p].i].extra > 0 && ps[g_p].timebeforeexit == 0 ) + j = 1; + else if( (l&32768) && sprite[ps[g_p].i].extra <= 0) + j = 1; + else if( (l&65536L) ) + { + if(g_sp->picnum == APLAYER && ud.multimode > 1) + j = getincangle(ps[otherp].ang,getangle(ps[g_p].posx-ps[otherp].posx,ps[g_p].posy-ps[otherp].posy)); + else + j = getincangle(ps[g_p].ang,getangle(g_sp->x-ps[g_p].posx,g_sp->y-ps[g_p].posy)); + + if( j > -128 && j < 128 ) + j = 1; + else + j = 0; + } + + parseifelse((long) j); + + } + break; + case CON_IFSTRENGTH: + insptr++; + parseifelse(g_sp->extra <= *insptr); + break; + case CON_GUTS: + insptr += 2; + guts(g_sp,*(insptr-1),*insptr,g_p); + insptr++; + break; + case CON_IFSPAWNEDBY: + insptr++; + // if(g_sp->owner >= 0 && sprite[g_sp->owner].picnum == *insptr) + // parseifelse(1); + // else + parseifelse( hittype[g_i].picnum == *insptr); + break; + case CON_WACKPLAYER: + insptr++; + forceplayerangle(&ps[g_p]); + return 0; + case CON_FLASH: + insptr++; + sprite[g_i].shade = -127; + ps[g_p].visibility = -127; + lastvisinc = totalclock+32; + return 0; + case CON_STOPALLSOUNDS: + insptr++; + if (screenpeek == g_p) + FX_StopAllSounds(); + return 0; + case CON_IFGAPZL: + insptr++; + parseifelse( (( hittype[g_i].floorz - hittype[g_i].ceilingz ) >> 8 ) < *insptr); + break; + case CON_IFHITSPACE: + parseifelse( sync[g_p].bits&(1<<29)); + break; + case CON_IFOUTSIDE: + parseifelse(sector[g_sp->sectnum].ceilingstat&1); + break; + case CON_IFMULTIPLAYER: + parseifelse(ud.multimode > 1); + break; + case CON_OPERATE: + insptr++; + if( sector[g_sp->sectnum].lotag == 0 ) + { + neartag(g_sp->x,g_sp->y,g_sp->z-(32<<8),g_sp->sectnum,g_sp->ang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,768L,1); + if( neartagsector >= 0 && isanearoperator(sector[neartagsector].lotag) ) + if( (sector[neartagsector].lotag&0xff) == 23 || sector[neartagsector].floorz == sector[neartagsector].ceilingz ) + if( (sector[neartagsector].lotag&16384) == 0 ) + if( (sector[neartagsector].lotag&32768) == 0 ) + { + j = headspritesect[neartagsector]; + while(j >= 0) + { + if(sprite[j].picnum == ACTIVATOR) + break; + j = nextspritesect[j]; + } + if(j == -1) + operatesectors(neartagsector,g_i); + } + } + break; + case CON_IFINSPACE: + parseifelse(ceilingspace(g_sp->sectnum)); + break; + case CON_SPRITEPAL: + insptr++; + if(g_sp->picnum != APLAYER) + hittype[g_i].tempang = g_sp->pal; + g_sp->pal = *insptr++; + break; + case CON_CACTOR: + insptr++; + g_sp->picnum = *insptr++; + break; + case CON_IFBULLETNEAR: + parseifelse( dodge(g_sp) == 1); + break; + case CON_IFRESPAWN: + if( badguy(g_sp) ) + parseifelse( ud.respawn_monsters ); + else if( inventory(g_sp) ) + parseifelse( ud.respawn_inventory ); + else + parseifelse( ud.respawn_items ); + break; + case CON_IFFLOORDISTL: + insptr++; + // getglobalz(g_i); + parseifelse( (hittype[g_i].floorz - g_sp->z) <= ((*insptr)<<8)); + break; + case CON_IFCEILINGDISTL: + insptr++; + // getglobalz(g_i); + parseifelse( ( g_sp->z - hittype[g_i].ceilingz ) <= ((*insptr)<<8)); + break; + case CON_PALFROM: + insptr++; + ps[g_p].pals_time = *insptr++; + for(j=0;j<3;j++) + { + ps[g_p].pals[j] = *insptr++; + } + break; + + case CON_DYNQUOTE: + { + long var1, var2, var3, var4; + insptr++; + Bstrcpy(tempbuf,fta_quotes[*insptr++]); + var1 = GetGameVarID(*insptr++, g_i, g_p); + var2 = GetGameVarID(*insptr++, g_i, g_p); + var3 = GetGameVarID(*insptr++, g_i, g_p); + var4 = GetGameVarID(*insptr++, g_i, g_p); + Bsprintf(fta_quotes[122],tempbuf,var1,var2,var3,var4); + FTA(122,&ps[g_p]); + break; + } + + /* case 74: + insptr++; + getglobalz(g_i); + parseifelse( (( hittype[g_i].floorz - hittype[g_i].ceilingz ) >> 8 ) >= *insptr); + break; + */ + + + case CON_ADDLOG: + { + long l; + insptr++; + l=*insptr++; // var + Bsprintf(g_szBuf,"CONLOG: L=%ld",l); + AddLog(g_szBuf); + break; + } + case CON_ADDLOGVAR: + { + long l,m=1,lVarID; + char szBuf[256]; + insptr++; + l=*insptr++; // l=Line number, *instpr=varID + + lVarID = *insptr; + if( (lVarID >= iGameVarCount) || lVarID < 0) + { + if(*insptr==MAXGAMEVARS) // addlogvar for a constant? Har. + insptr++; + else if(*insptr&(MAXGAMEVARS<<1)) + { + m = -1; + lVarID ^= (MAXGAMEVARS<<1); + goto good; + } + // invalid varID + insptr++; + Bsprintf(g_szBuf,"CONLOGVAR: L=%ld INVALID VARIABLE",l); + AddLog(g_szBuf); + break; // out of switch + } +good: + Bsprintf(szBuf,"CONLOGVAR: L=%ld %s ",l, aGameVars[lVarID].szLabel); + strcpy(g_szBuf,szBuf); + + if( aGameVars[lVarID].dwFlags & GAMEVAR_FLAG_READONLY) + { + Bsprintf(szBuf," (read-only)"); + strcat(g_szBuf,szBuf); + } + if( aGameVars[lVarID].dwFlags & GAMEVAR_FLAG_PERPLAYER) + { + Bsprintf(szBuf," (Per Player. Player=%d)",g_p); + } + else if( aGameVars[lVarID].dwFlags & GAMEVAR_FLAG_PERACTOR) + { + Bsprintf(szBuf," (Per Actor. Actor=%d)",g_i); + } + else + { + Bsprintf(szBuf," (Global)"); + } + strcat(g_szBuf,szBuf); + Bsprintf(szBuf," =%ld", GetGameVarID(lVarID, g_i, g_p)*m); + strcat(g_szBuf,szBuf); + AddLog(g_szBuf); + insptr++; + break; + } + + case CON_SETSECTOR: + case CON_GETSECTOR: + { + // syntax [gs]etsector[].x + // + long lLabelID; + long lVar1, lVar2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + lVar2=*insptr++; + DoSector(tw==CON_SETSECTOR, lVar1, lLabelID, lVar2, g_i, g_p); + break; + } + case CON_SQRT: + { + // syntax sqrt + + long lInVarID; + long lOutVarID; + long lIn; + + insptr++; + lInVarID=*insptr++; + lOutVarID=*insptr++; + lIn=GetGameVarID(lInVarID, g_i, g_p); + SetGameVarID(lOutVarID, ksqrt(lIn), g_i, g_p); + break; + } + case CON_FINDNEARACTOR: + case CON_FINDNEARSPRITE: + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + long lType; + long lMaxDist; + long lVarID; + long lTemp; + long lFound; + long lDist; + short j, k; + + insptr++; + + lType=*insptr++; + lMaxDist=*insptr++; + lVarID=*insptr++; + + lFound=-1; + lDist=32767; // big number + + for (k=0;k=0) + { + if(sprite[j].picnum == lType && j != g_i) + { + lTemp=ldist(&sprite[g_i], &sprite[j]); + if( lTemp < lMaxDist ) + { + if (lTemp < lDist) + { + lFound=j; + j = MAXSPRITES; + break; + } + } + } + j = nextspritestat[j]; + } + if(tw==CON_FINDNEARACTOR || j == MAXSPRITES) + break; + } + SetGameVarID(lVarID, lFound, g_i, g_p); + break; + } + + case CON_FINDNEARACTORVAR: + case CON_FINDNEARSPRITEVAR: + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + long lType; + long lMaxDistVar; + long lMaxDist; + long lVarID; + long lTemp; + long lFound; + long lDist; + short j, k; + + insptr++; + + lType=*insptr++; + lMaxDistVar=*insptr++; + lVarID=*insptr++; + lMaxDist=GetGameVarID(lMaxDistVar, g_i, g_p); + lFound=-1; + lDist=32767; // big number + + for (k=0;k=0) + { + if(sprite[j].picnum == lType && j != g_i) + { + lTemp=ldist(&sprite[g_i], &sprite[j]); + if( lTemp < lMaxDist ) + { + if (lTemp < lDist) + { + lFound=j; + j = MAXSPRITES; + break; + } + } + } + j = nextspritestat[j]; + } + if(tw==CON_FINDNEARACTORVAR || j == MAXSPRITES) + break; + } + SetGameVarID(lVarID, lFound, g_i, g_p); + break; + } + + case CON_FINDPLAYER: + case CON_FINDOTHERPLAYER: + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + short j=0; + long var1, d; + + insptr++; + var1 = *insptr++; + + if (tw == CON_FINDPLAYER) j=findplayer(&sprite[g_i],&d); + else if (tw == CON_FINDOTHERPLAYER) j=findotherplayer(g_i,&d); + + SetGameVarID(g_iReturnVarID, j, g_i, g_p); + SetGameVarID(var1, d, g_i, g_p); + + break; + } + + + case CON_FINDNEARACTOR3DVAR: + case CON_FINDNEARSPRITE3DVAR: + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + long lType; + long lMaxDistVar; + long lMaxZDistVar; + long lMaxDist; + long lMaxZDist; + long lVarID; + long lTemp; + long lTemp2; + long lFound; + long lDist; + short j, k; + + insptr++; + + lType=*insptr++; + lMaxDistVar=*insptr++; + lMaxZDistVar=*insptr++; + lVarID=*insptr++; + lMaxDist=GetGameVarID(lMaxDistVar, g_i, g_p); + lMaxZDist=GetGameVarID(lMaxZDistVar, g_i, g_p); + lFound=-1; + lDist=32767; // big number + + for (k=0;k=0) + { + if(sprite[j].picnum == lType && j != g_i) + { + lTemp=ldist(&sprite[g_i], &sprite[j]); + lTemp2=txdist(&sprite[g_i], &sprite[j]); + if( (lTemp < lMaxDist) && (lTemp2 < lMaxZDist) ) + { + if (lTemp < lDist) + { + lFound=j; + j = MAXSPRITES; + break; + } + } + } + j = nextspritestat[j]; + } + if(tw==CON_FINDNEARACTOR3DVAR || j == MAXSPRITES) + break; + } + SetGameVarID(lVarID, lFound, g_i, g_p); + + break; + } + + case CON_FINDNEARACTOR3D: + case CON_FINDNEARSPRITE3D: + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + long lType; + long lMaxDist; + long lMaxZDist; + long lVarID; + long lTemp; + long lTemp2; + long lFound; + long lDist; + short j, k; + + insptr++; + + lType=*insptr++; + lMaxDist=*insptr++; + lMaxZDist=*insptr++; + lVarID=*insptr++; + + lFound=-1; + lDist=32767; // big number + + for (k=0;k=0) + { + if(sprite[j].picnum == lType && j != g_i) + { + lTemp=ldist(&sprite[g_i], &sprite[j]); + lTemp2=txdist(&sprite[g_i], &sprite[j]); + if( (lTemp < lMaxDist) && (lTemp2 < lMaxZDist) ) + { + if (lTemp < lDist) + { + lFound=j; + j = MAXSPRITES; + break; + } + } + } + j = nextspritestat[j]; + } + if(tw==CON_FINDNEARACTOR3DVAR || j == MAXSPRITES) + break; + } + SetGameVarID(lVarID, lFound, g_i, g_p); + break; + } + + case CON_SETPLAYER: + case CON_GETPLAYER: + { + // syntax [gs]etplayer[].x + // + long lLabelID; + long lVar1, lVar2; + long lParm2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + // HACK: need to have access to labels structure at run-time... + + switch(lLabelID) + { + case PLAYER_AMMO_AMOUNT: + case PLAYER_GOTWEAPON: + case PLAYER_PALS: + case PLAYER_MOVEMENT_LOCK: + case PLAYER_LOOGIEX: + case PLAYER_LOOGIEY: + lParm2=GetGameVarID(*insptr++, g_i, g_p); + break; + default: + lParm2=0; + break; + } + lVar2=*insptr++; + + DoPlayer(tw==CON_SETPLAYER, lVar1, lLabelID, lVar2, g_i, g_p, lParm2); + break; + } + + case CON_SETINPUT: + case CON_GETINPUT: + { + // syntax [gs]etplayer[].x + // + long lLabelID; + long lVar1, lVar2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + + lVar2=*insptr++; + + DoInput(tw==CON_SETINPUT, lVar1, lLabelID, lVar2, g_i, g_p); + break; + } + + case CON_GETUSERDEF: + case CON_SETUSERDEF: + { + // syntax [gs]etuserdef.xxx + // + long lLabelID; + long lVar1, lVar2; + long lParm2=0; + + insptr++; + lVar1=-1; + lLabelID=*insptr++; + lVar2=*insptr++; + + DoUserDef(tw==CON_SETUSERDEF, lVar1, lLabelID, lVar2, g_i, g_p, lParm2); + break; + } + case CON_GETPROJECTILE: + case CON_SETPROJECTILE: + { + // syntax [gs]etplayer[].x + // + long lLabelID; + long lVar1, lVar2; + long lParm2; + + insptr++; + lVar1=GetGameVarID(*insptr++, g_i, g_p); + lLabelID=*insptr++; + lVar2=*insptr++; + DoProjectile(tw==CON_SETPROJECTILE,lVar1,lLabelID,lVar2,g_i,g_p); + + break; + } + + + case CON_SETWALL: + case CON_GETWALL: + { + // syntax [gs]etwall[].x + // + long lLabelID; + long lVar1, lVar2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + lVar2=*insptr++; + + DoWall(tw==CON_SETWALL, lVar1, lLabelID, lVar2, g_i, g_p); + break; + } + case CON_SETACTORVAR: + case CON_GETACTORVAR: + { + // syntax [gs]etactorvar[]. + // gets the value of the per-actor variable varx into VAR + // + long lVar1, lVar2, lVar3; + long lTemp,lSprite; + + insptr++; + + lVar1=*insptr++; + lVar2=*insptr++; + lVar3=*insptr++; + + lSprite=GetGameVarID(lVar1, g_i, g_p); + if(lSprite >= 0) + { + switch(tw) + { + case CON_SETACTORVAR: + lTemp=GetGameVarID(lVar3, g_i, g_p); + SetGameVarID(lVar2, lTemp, lSprite, g_p); + break; + case CON_GETACTORVAR: + lTemp=GetGameVarID(lVar2, lSprite, g_p); + SetGameVarID(lVar3, lTemp, g_i, g_p); + break; + } + } + break; + } + + case CON_SETPLAYERVAR: + case CON_GETPLAYERVAR: + { + // syntax [gs]etactorvar[]. + // gets the value of the per-actor variable varx into VAR + // + long lVar1, lVar2, lVar3; + long lTemp,lSprite; + + insptr++; + + lVar1=*insptr++; + lVar2=*insptr++; + lVar3=*insptr++; + + lSprite=GetGameVarID(lVar1, g_i, g_p); + if(lSprite >= 0) + { + switch(tw) + { + case CON_SETPLAYERVAR: + lTemp=GetGameVarID(lVar3, g_i, g_p); + SetGameVarID(lVar2, lTemp, g_i, lSprite); + break; + case CON_GETPLAYERVAR: + lTemp=GetGameVarID(lVar2, g_i, lSprite); + SetGameVarID(lVar3, lTemp, g_i, g_p); + break; + } + } + break; + } + + case CON_SETACTOR: + case CON_GETACTOR: + { + // syntax [gs]etactor[].x + // + long lLabelID; + long lVar1, lVar2; + long lParm2; + + insptr++; + lVar1=*insptr++; + lLabelID=*insptr++; + + switch(lLabelID) + { + case ACTOR_HTG_T: + lParm2=GetGameVarID(*insptr++, g_i, g_p); + break; + default: + lParm2=0; + break; + } + lVar2=*insptr++; + + DoActor(tw==CON_SETACTOR, lVar1, lLabelID, lVar2, g_i, g_p, lParm2); + break; + } + case CON_GETANGLETOTARGET: + { + int i; + short ang; + + insptr++; + i=*insptr++; // ID of def + + // hittype[g_i].lastvx and lastvy are last known location of target. + ang=getangle(hittype[g_i].lastvx-g_sp->x,hittype[g_i].lastvy-g_sp->y); + SetGameVarID(i, ang, g_i, g_p ); + break; + } + case CON_ANGOFFVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + spriteext[g_i].angoff=GetGameVarID(i, g_i, g_p); + break; + } + case CON_LOCKPLAYER: + { + int i; + insptr++; + i=*insptr++; // ID of def + ps[g_p].transporter_hold=GetGameVarID(i, g_i, g_p); + break; + } + case CON_CHECKAVAILWEAPON: + case CON_CHECKAVAILINVEN: + { + int i; + + insptr++; + + if (*insptr == g_iThisActorID) + { + i = g_p; + insptr++; + } + else + i=GetGameVarID(*insptr++, g_i, g_p); + if (i < MAXPLAYERS) + { + if (tw == CON_CHECKAVAILWEAPON) + checkavailweapon(&ps[i]); + else checkavailinven(&ps[i]); + } + break; + } + case CON_GETPLAYERANGLE: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, ps[g_p].ang, g_i, g_p ); + break; + } + case CON_SETPLAYERANGLE: + { + int i; + insptr++; + i=*insptr++; // ID of def + ps[g_p].ang=GetGameVarID(i, g_i, g_p); + ps[g_p].ang &= 2047; + break; + } + case CON_GETACTORANGLE: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, g_sp->ang, g_i, g_p ); + break; + } + case CON_SETACTORANGLE: + { + int i; + insptr++; + i=*insptr++; // ID of def + g_sp->ang=GetGameVarID(i, g_i, g_p); + g_sp->ang &= 2047; + break; + } + case CON_SETVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, *insptr++, g_i, g_p ); + break; + } + case CON_SETVARVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, GetGameVarID(*insptr++, g_i, g_p), g_i, g_p ); + break; + } + + case CON_RANDVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, mulscale(krand(), *insptr++, 16), g_i, g_p ); + break; + } + case CON_DISPLAYRANDVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, mulscale(rand(), *insptr++, 15), g_i, g_p ); + break; + } + case CON_MULVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, GetGameVarID(i, g_i, g_p) * *insptr++, g_i, g_p ); + break; + } + + case CON_DIVVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + if( (*insptr) == 0 ) + { + gameexit("CON_DIVVAR: Divide by zero."); + } + SetGameVarID(i, GetGameVarID(i, g_i, g_p) / *insptr++, g_i, g_p ); + break; + } + case CON_MODVAR: + { + int i; + long l; + long lResult; + insptr++; + i=*insptr++; // ID of def + l=*insptr++; + if( l == 0 ) + { + gameexit("CON_MODVAR: Mod by zero."); + } + lResult=GetGameVarID(i, g_i, g_p) % l; + SetGameVarID(i, lResult, g_i, g_p ); + break; + } + case CON_ANDVAR: + { + int i; + long l; + long lResult; + insptr++; + i=*insptr++; // ID of def + l=*insptr++; + lResult=GetGameVarID(i, g_i, g_p) & l; + SetGameVarID(i, lResult, g_i, g_p ); + break; + } + case CON_ORVAR: + { + int i; + long l; + long lResult; + insptr++; + i=*insptr++; // ID of def + l=*insptr++; + lResult=GetGameVarID(i, g_i, g_p) | l; + SetGameVarID(i, lResult, g_i, g_p ); + break; + } + case CON_XORVAR: + { + int i; + long l; + long lResult; + insptr++; + i=*insptr++; // ID of def + l=*insptr++; + lResult=GetGameVarID(i, g_i, g_p) ^ l; + SetGameVarID(i, lResult, g_i, g_p ); + break; + } + + case CON_RANDVARVAR: + { + int i; + long l1; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(*insptr++, g_i, g_p); + lResult=mulscale(krand(), l1+1, 16); + SetGameVarID(i, lResult , g_i, g_p ); + break; + } + + case CON_DISPLAYRANDVARVAR: + { + int i; + long l1; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(*insptr++, g_i, g_p); + lResult=mulscale(rand(), l1+1, 15); + SetGameVarID(i, lResult , g_i, g_p ); + break; + } + + case CON_GMAXAMMO: + { + int i; + long l1; // l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + lResult=max_ammo_amount[l1]; + SetGameVarID(*insptr++, lResult , g_i, g_p ); + break; + } + + case CON_SMAXAMMO: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr++, g_i, g_p); + max_ammo_amount[l1]=l2; + break; + } + + case CON_MULVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr++, g_i, g_p); + lResult=l1*l2; + SetGameVarID(i, lResult , g_i, g_p ); + break; + } + case CON_DIVVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr++, g_i, g_p); + if(l2==0) + { + gameexit("CON_DIVVARVAR: Divide by zero."); + } + lResult=l1/l2; + SetGameVarID(i, lResult , g_i, g_p ); + break; + } + case CON_MODVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr, g_i, g_p); + if(l2==0) + { + gameexit("CON_MODVARVAR: Mod by zero."); + } + lResult=l1 % l2; + SetGameVarID(i, lResult , g_i, g_p ); + insptr++; + break; + } + case CON_ANDVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr, g_i, g_p); + lResult=l1 & l2; + SetGameVarID(i, lResult , g_i, g_p ); + insptr++; + break; + } + case CON_XORVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr, g_i, g_p); + lResult=l1 ^ l2; + SetGameVarID(i, lResult , g_i, g_p ); + insptr++; + break; + } + case CON_ORVARVAR: + { + int i; + long l1,l2; + long lResult; + insptr++; + i=*insptr++; // ID of def + l1=GetGameVarID(i, g_i, g_p); + l2=GetGameVarID(*insptr, g_i, g_p); + lResult=l1 | l2; + SetGameVarID(i, lResult , g_i, g_p ); + insptr++; + break; + } + case CON_SUBVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, GetGameVarID(i, g_i, g_p) - *insptr, g_i, g_p ); + insptr++; + break; + } + case CON_SUBVARVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, GetGameVarID(i, g_i, g_p) - GetGameVarID(*insptr, g_i, g_p), g_i, g_p ); + insptr++; + break; + } + case CON_ADDVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + //Bsprintf(g_szBuf,"AddVar %d to Var ID=%d, g_i=%d, g_p=%d\n",*insptr, i, g_i, g_p); + //AddLog(g_szBuf); + SetGameVarID(i, GetGameVarID(i, g_i, g_p) + *insptr, g_i, g_p ); + insptr++; + break; + } + case CON_SHIFTVARL: + { + int i; + insptr++; + i=*insptr++; // ID of def + //Bsprintf(g_szBuf,"AddVar %d to Var ID=%d, g_i=%d, g_p=%d\n",*insptr, i, g_i, g_p); + //AddLog(g_szBuf); + SetGameVarID(i, GetGameVarID(i, g_i, g_p) << *insptr, g_i, g_p ); + insptr++; + break; + } + + case CON_SHIFTVARR: + { + int i; + insptr++; + i=*insptr++; // ID of def + //Bsprintf(g_szBuf,"AddVar %d to Var ID=%d, g_i=%d, g_p=%d\n",*insptr, i, g_i, g_p); + //AddLog(g_szBuf); + SetGameVarID(i, GetGameVarID(i, g_i, g_p) >> *insptr, g_i, g_p ); + insptr++; + break; + } + + + case CON_SIN: + { + int i; + long lValue; + insptr++; + i=*insptr++; // ID of def + lValue=GetGameVarID(*insptr, g_i, g_p); + lValue=sintable[lValue&2047]; + SetGameVarID(i, lValue , g_i, g_p ); + insptr++; + break; + } + case CON_COS: + { + int i; + long lValue; + insptr++; + i=*insptr++; // ID of def + lValue=GetGameVarID(*insptr, g_i, g_p); + // propiedad trigonometrica con el seno para hallar coseno: cos = sqrt(1-sen^2) + // I don't know anything about sin/cos, and I don't know anything about foreign languages, either. :( + lValue=sintable[(lValue+512)&2047]; + SetGameVarID(i, lValue , g_i, g_p ); + insptr++; + break; + } + case CON_ADDVARVAR: + { + int i; + insptr++; + i=*insptr++; // ID of def + SetGameVarID(i, GetGameVarID(i, g_i, g_p) + GetGameVarID(*insptr, g_i, g_p), g_i, g_p ); + insptr++; + break; + } + case CON_SPGETLOTAG: + { + insptr++; + SetGameVarID(g_iLoTagID, g_sp->lotag, g_i, g_p); + break; + } + case CON_SPGETHITAG: + { + insptr++; + SetGameVarID(g_iHiTagID, g_sp->hitag, g_i, g_p); + break; + } + case CON_SECTGETLOTAG: + { + insptr++; + SetGameVarID(g_iLoTagID, sector[g_sp->sectnum].lotag, g_i, g_p); + break; + } + case CON_SECTGETHITAG: + { + insptr++; + SetGameVarID(g_iHiTagID, sector[g_sp->sectnum].hitag, g_i, g_p); + break; + } + case CON_GETTEXTUREFLOOR: + { + insptr++; + SetGameVarID(g_iTextureID, sector[g_sp->sectnum].floorpicnum, g_i, g_p); + break; + } + case CON_STARTTRACK: + { + insptr++; + music_select=*insptr++; + playmusic(&music_fn[ud.volume_number][music_select][0]); + break; + } + case CON_GETTEXTURECEILING: + { + insptr++; + SetGameVarID(g_iTextureID, sector[g_sp->sectnum].ceilingpicnum, g_i, g_p); + break; + } + case CON_IFVARVARAND: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) & GetGameVarID(*(insptr), g_i, g_p) ) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARVARN: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) != GetGameVarID(*(insptr), g_i, g_p) ) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARVARE: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) == GetGameVarID(*(insptr), g_i, g_p) ) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARVARG: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) > GetGameVarID(*(insptr), g_i, g_p) ) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARVARL: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) < GetGameVarID(*(insptr), g_i, g_p) ) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARE: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) == *insptr) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARN: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) != *insptr) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_WHILEVARN: + { + int i; + long *savedinsptr; + savedinsptr=insptr; + j=1; + while (j) + { + insptr=savedinsptr; + insptr++; + i=*insptr++; // ID of def + j=0; + + if(GetGameVarID(i, g_i, g_p) != *insptr) + { + j=1; + } + parseifelse( j ); + } + break; + } + case CON_WHILEVARVARN: + { + int i,k; + long *savedinsptr; + savedinsptr=insptr; + j=1; + while (j) + { + insptr=savedinsptr; + insptr++; + i=*insptr++; // ID of def + k=*(insptr); // ID of def + j=0; + + if(GetGameVarID(i, g_i, g_p) != GetGameVarID(k, g_i, g_p)) + { + j=1; + } + parseifelse( j ); + } + break; + } + case CON_IFVARAND: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) & *insptr) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARG: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) > *insptr) + { + j=1; + } + parseifelse( j ); + break; + } + case CON_IFVARL: + { + int i; + insptr++; + i=*insptr++; // ID of def + j=0; + if(GetGameVarID(i, g_i, g_p) < *insptr) + { + j=1; + } + parseifelse( j ); + break; + } + + case CON_IFPHEALTHL: + insptr++; + parseifelse( sprite[ps[g_p].i].extra < *insptr); + break; + + case CON_IFPINVENTORY: + { + insptr++; + j = 0; + switch(*insptr++) + { + case GET_STEROIDS:if( ps[g_p].steroids_amount != *insptr) + j = 1; + break; + case GET_SHIELD:if(ps[g_p].shield_amount != max_player_health ) + j = 1; + break; + case GET_SCUBA:if(ps[g_p].scuba_amount != *insptr) j = 1;break; + case GET_HOLODUKE:if(ps[g_p].holoduke_amount != *insptr) j = 1;break; + case GET_JETPACK:if(ps[g_p].jetpack_amount != *insptr) j = 1;break; + case GET_ACCESS: + switch(g_sp->pal) + { + case 0: if(ps[g_p].got_access&1) j = 1;break; + case 21: if(ps[g_p].got_access&2) j = 1;break; + case 23: if(ps[g_p].got_access&4) j = 1;break; + } + break; + case GET_HEATS:if(ps[g_p].heat_amount != *insptr) j = 1;break; + case GET_FIRSTAID: + if(ps[g_p].firstaid_amount != *insptr) j = 1;break; + case GET_BOOTS: + if(ps[g_p].boot_amount != *insptr) j = 1;break; + } + + parseifelse(j); + break; + } + case CON_PSTOMP: + insptr++; + if( ps[g_p].knee_incs == 0 && sprite[ps[g_p].i].xrepeat >= 40 ) + if( cansee(g_sp->x,g_sp->y,g_sp->z-(4<<8),g_sp->sectnum,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz+(16<<8),sprite[ps[g_p].i].sectnum) ) + { + ps[g_p].knee_incs = 1; + if(ps[g_p].weapon_pos == 0) + ps[g_p].weapon_pos = -1; + ps[g_p].actorsqu = g_i; + } + break; + case CON_IFAWAYFROMWALL: + { + short s1; + + s1 = g_sp->sectnum; + + j = 0; + + updatesector(g_sp->x+108,g_sp->y+108,&s1); + if( s1 == g_sp->sectnum ) + { + updatesector(g_sp->x-108,g_sp->y-108,&s1); + if( s1 == g_sp->sectnum ) + { + updatesector(g_sp->x+108,g_sp->y-108,&s1); + if( s1 == g_sp->sectnum ) + { + updatesector(g_sp->x-108,g_sp->y+108,&s1); + if( s1 == g_sp->sectnum ) + j = 1; + } + } + } + parseifelse( j ); + } + + break; + case CON_QUOTE: + insptr++; + FTA(*insptr,&ps[g_p]); + insptr++; + break; + case CON_USERQUOTE: + insptr++; + adduserquote(fta_quotes[*insptr]); + insptr++; + break; + case CON_IFINOUTERSPACE: + parseifelse( floorspace(g_sp->sectnum)); + break; + case CON_IFNOTMOVING: + parseifelse( (hittype[g_i].movflag&49152) > 16384 ); + break; + case CON_RESPAWNHITAG: + insptr++; + switch(dynamictostatic[g_sp->picnum]) + { + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case PODFEM1__STATIC: + case NAKED1__STATIC: + case STATUE__STATIC: + if(g_sp->yvel) operaterespawns(g_sp->yvel); + break; + default: + if(g_sp->hitag >= 0) operaterespawns(g_sp->hitag); + break; + } + break; + case CON_IFSPRITEPAL: + insptr++; + parseifelse( g_sp->pal == *insptr); + break; + + case CON_IFANGDIFFL: + insptr++; + j = klabs(getincangle(ps[g_p].ang,g_sp->ang)); + parseifelse( j <= *insptr); + break; + + case CON_IFNOSOUNDS: + for(j=1;jpicnum] == 0 ) return; + + insptr = actorLoadEventScrptr[g_sp->picnum]; + + killit_flag = 0; + + if(g_sp->sectnum < 0 || g_sp->sectnum >= MAXSECTORS) + { + // if(badguy(g_sp)) + // ps[g_p].actors_killed++; + deletesprite(g_i); + return; + } + do + done = parse(); + while( done == 0 ); + + if(killit_flag == 1) + { + // if player was set to squish, first stop that... + if (g_p >= 0 ) + { + if(ps[g_p].actorsqu == g_i) + ps[g_p].actorsqu = -1; + } + deletesprite(g_i); + } +} + +void execute(short sActor,short sPlayer,long lDist) +{ + char done; + + g_i = sActor; // Sprite ID + g_p = sPlayer; // Player ID + g_x = lDist; // ?? + g_sp = &sprite[g_i]; // Pointer to sprite structure + g_t = &hittype[g_i].temp_data[0]; // Sprite's 'extra' data + + if( actorscrptr[g_sp->picnum] == 0 ) return; + + insptr = 4 + (actorscrptr[g_sp->picnum]); + + killit_flag = 0; + + if(g_sp->sectnum < 0 || g_sp->sectnum >= MAXSECTORS) + { + if(badguy(g_sp)) + ps[g_p].actors_killed++; + deletesprite(g_i); + return; + } + + if(g_t[4]) + { + g_sp->lotag += TICSPERFRAME; + + if(g_sp->lotag > *(long *)(g_t[4]+16) ) + { + g_t[2]++; + g_sp->lotag = 0; + g_t[3] += *(long *)( g_t[4]+12 ); + } + + if( klabs(g_t[3]) >= klabs( *(long *)(g_t[4]+4) * *(long *)(g_t[4]+12) ) ) + g_t[3] = 0; + } + + do + done = parse(); + while( done == 0 ); + + if(killit_flag == 1) + { + // if player was set to squish, first stop that... + if(ps[g_p].actorsqu == g_i) + ps[g_p].actorsqu = -1; + deletesprite(g_i); + } + else + { + move(); + + if( g_sp->statnum == 1) + { + if( badguy(g_sp) ) + { + if( g_sp->xrepeat > 60 ) return; + if( ud.respawn_monsters == 1 && g_sp->extra <= 0 ) return; + } + else if( ud.respawn_items == 1 && (g_sp->cstat&32768) ) return; + + if(hittype[g_i].timetosleep > 1) + hittype[g_i].timetosleep--; + else if(hittype[g_i].timetosleep == 1) + changespritestat(g_i,2); + } + + else if(g_sp->statnum == 6) + switch(dynamictostatic[g_sp->picnum]) + { + case RUBBERCAN__STATIC: + case EXPLODINGBARREL__STATIC: + case WOODENHORSE__STATIC: + case HORSEONSIDE__STATIC: + case CANWITHSOMETHING__STATIC: + case FIREBARREL__STATIC: + case NUKEBARREL__STATIC: + case NUKEBARRELDENTED__STATIC: + case NUKEBARRELLEAKED__STATIC: + case TRIPBOMB__STATIC: + case EGG__STATIC: + if(hittype[g_i].timetosleep > 1) + hittype[g_i].timetosleep--; + else if(hittype[g_i].timetosleep == 1) + changespritestat(g_i,2); + break; + } + } +} diff --git a/polymer/eduke32/source/global.c b/polymer/eduke32/source/global.c new file mode 100644 index 000000000..5f71cc9ca --- /dev/null +++ b/polymer/eduke32/source/global.c @@ -0,0 +1,180 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" + +char MusicPtr[72000*2]; + +short global_random; +short neartagsector, neartagwall, neartagsprite; + +long neartaghitdist,lockclock,max_player_health,max_armour_amount,max_ammo_amount[MAX_WEAPONS]; +// JBF: gc modified to default to Atomic ed. default when using 1.3d CONs +long gc=176; + +// long temp_data[MAXSPRITES][6]; +struct weaponhit hittype[MAXSPRITES]; +short spriteq[1024],spriteqloc,spriteqamount=64; +struct animwalltype animwall[MAXANIMWALLS]; +short numanimwalls; +long *animateptr[MAXANIMATES], animategoal[MAXANIMATES], animatevel[MAXANIMATES], animatecnt; +// long oanimateval[MAXANIMATES]; +short animatesect[MAXANIMATES]; +long msx[2048],msy[2048]; +short cyclers[MAXCYCLERS][6],numcyclers; + +char fta_quotes[NUMOFFIRSTTIMEACTIVE][64]; + +char tempbuf[2048], packbuf[576]; + +char buf[1024]; + +short camsprite; +short mirrorwall[64], mirrorsector[64], mirrorcnt; + +int current_menu; + +char betaname[80]; + +char level_names[77][33],level_file_names[77][BMAX_PATH]; +long partime[77],designertime[77]; +char volume_names[7][33] = { "L.A. MELTDOWN", "LUNAR APOCALYPSE", "SHRAPNEL CITY" }; +char skill_names[5][33] = { "PIECE OF CAKE", "LET'S ROCK", "COME GET SOME", "DAMN I'M GOOD" }; + +char gametype_names[MAXGAMETYPES][33] = { "DUKEMATCH (SPAWN)","COOPERATIVE PLAY","DUKEMATCH (NO SPAWN)"}; +int gametype_flags[MAXGAMETYPES] = {4+8+16+1024+2048+16384,1+2+32+64+128+256+512+4096+8192+32768,2+4+8+16+16384}; +char num_gametypes = 3; + +long soundsiz[NUM_SOUNDS]; + +short soundps[NUM_SOUNDS],soundpe[NUM_SOUNDS],soundvo[NUM_SOUNDS]; +char soundm[NUM_SOUNDS],soundpr[NUM_SOUNDS]; +char sounds[NUM_SOUNDS][BMAX_PATH]; + +short title_zoom; + +char num_volumes = 3; + +short timer=120; +//fx_device device; + +SAMPLE Sound[ NUM_SOUNDS ]; +SOUNDOWNER SoundOwner[NUM_SOUNDS][4]; + +char numplayersprites,loadfromgrouponly=0,earthquaketime; + +long fricxv,fricyv; +struct player_orig po[MAXPLAYERS]; +struct player_struct ps[MAXPLAYERS]; +struct user_defs ud; + +char pus, pub; +char syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ]; +long syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail; + +input sync[MAXPLAYERS], loc; +input recsync[RECSYNCBUFSIZ]; +long avgfvel, avgsvel, avgavel, avghorz, avgbits, avgbits2; + + +input inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; +input recsync[RECSYNCBUFSIZ]; + +long movefifosendplc; + +//Multiplayer syncing variables +short screenpeek; +long movefifoend[MAXPLAYERS]; + + +//Game recording variables + +char playerreadyflag[MAXPLAYERS],ready2send; +char playerquitflag[MAXPLAYERS]; +long vel, svel, angvel, horiz, ototalclock, respawnactortime=768, respawnitemtime=768, groupfile; + +long *scriptptr,*insptr,*labelcode,labelcnt,defaultlabelcnt,*labeltype; +long *actorscrptr[MAXTILES],*parsing_actor; +char *label,*textptr,error,warning,killit_flag; +char *music_pointer; +char actortype[MAXTILES]; +long script[MAXSCRIPTSIZE+16]; + +char display_mirror,typebuflen,typebuf[41]; + +char music_fn[8][11][13],music_select; +char env_music_fn[8][13]; +char rtsplaying; + + +short weaponsandammosprites[15] = { + RPGSPRITE__STATIC, + CHAINGUNSPRITE__STATIC, + DEVISTATORAMMO__STATIC, + RPGAMMO__STATIC, + RPGAMMO__STATIC, + JETPACK__STATIC, + SHIELD__STATIC, + FIRSTAID__STATIC, + STEROIDS__STATIC, + RPGAMMO__STATIC, + RPGAMMO__STATIC, + RPGSPRITE__STATIC, + RPGAMMO__STATIC, + FREEZESPRITE__STATIC, + FREEZEAMMO__STATIC + }; + +long impact_damage; +char condebug; + +//GLOBAL.C - replace the end "my's" with this +long myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; +short myhoriz, omyhoriz, myhorizoff, omyhorizoff; +short myang, omyang, mycursectnum, myjumpingcounter,frags[MAXPLAYERS][MAXPLAYERS]; + +char myjumpingtoggle, myonground, myhardlanding, myreturntocenter; +signed char multiwho, multipos, multiwhat, multiflag; + +long fakemovefifoplc,movefifoplc; +long myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; +long myhorizbak[MOVEFIFOSIZ],dukefriction = 0xcc00, show_shareware; + +short myangbak[MOVEFIFOSIZ]; +char myname[32],camerashitable,freezerhurtowner=0,lasermode=0; +char networkmode = 255, movesperpacket = 1,gamequit = 0,everyothertime; +long numfreezebounces=3,rpgblastradius,pipebombblastradius,tripbombblastradius,shrinkerblastradius,morterblastradius,bouncemineblastradius,seenineblastradius; +STATUSBARTYPE sbar; + +long myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; +short numclouds,clouds[128],cloudx[128],cloudy[128]; +long cloudtotalclock = 0,totalmemory = 0; +long numinterpolations = 0, startofdynamicinterpolations = 0; +long oldipos[MAXINTERPOLATIONS]; +long bakipos[MAXINTERPOLATIONS]; +long *curipos[MAXINTERPOLATIONS]; + +int nextvoxid = 0; + +int spriteflags[MAXTILES], actorspriteflags[MAXSPRITES]; + +char cheatkey[2] = { sc_D, sc_N }; diff --git a/polymer/eduke32/source/jaudiolib/_midi.h b/polymer/eduke32/source/jaudiolib/_midi.h new file mode 100644 index 000000000..b28edd216 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/_midi.h @@ -0,0 +1,281 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) + +*/ +/********************************************************************** + module: _MIDI.H + + author: James R. Dose + date: May 25, 1994 + + Private header for MIDI.C. Midi song file playback routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef ___MIDI_H +#define ___MIDI_H + +#define RELATIVE_BEAT( measure, beat, tick ) \ + ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) ) + +//Bobby Prince thinks this may be 100 +//#define GENMIDI_DefaultVolume 100 +#define GENMIDI_DefaultVolume 90 + +#define MAX_FORMAT 1 + +#define NUM_MIDI_CHANNELS 16 + +#define TIME_PRECISION 16 + +#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd" +#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk" + +#define MIDI_VOLUME 7 +#define MIDI_PAN 10 +#define MIDI_DETUNE 94 +#define MIDI_RHYTHM_CHANNEL 9 +#define MIDI_RPN_MSB 100 +#define MIDI_RPN_LSB 101 +#define MIDI_DATAENTRY_MSB 6 +#define MIDI_DATAENTRY_LSB 38 +#define MIDI_PITCHBEND_MSB 0 +#define MIDI_PITCHBEND_LSB 0 +#define MIDI_RUNNING_STATUS 0x80 +#define MIDI_NOTE_OFF 0x8 +#define MIDI_NOTE_ON 0x9 +#define MIDI_POLY_AFTER_TCH 0xA +#define MIDI_CONTROL_CHANGE 0xB +#define MIDI_PROGRAM_CHANGE 0xC +#define MIDI_AFTER_TOUCH 0xD +#define MIDI_PITCH_BEND 0xE +#define MIDI_SPECIAL 0xF +#define MIDI_SYSEX 0xF0 +#define MIDI_SYSEX_CONTINUE 0xF7 +#define MIDI_META_EVENT 0xFF +#define MIDI_END_OF_TRACK 0x2F +#define MIDI_TEMPO_CHANGE 0x51 +#define MIDI_TIME_SIGNATURE 0x58 +#define MIDI_RESET_ALL_CONTROLLERS 0x79 +#define MIDI_ALL_NOTES_OFF 0x7b +#define MIDI_MONO_MODE_ON 0x7E +#define MIDI_SYSTEM_RESET 0xFF + +#define GET_NEXT_EVENT( track, data ) \ + ( data ) = *( track )->pos; \ + ( track )->pos += 1 + +#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf ) +#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 ) + +#define EMIDI_INFINITE -1 +#define EMIDI_END_LOOP_VALUE 127 +#define EMIDI_ALL_CARDS 127 +#define EMIDI_INCLUDE_TRACK 110 +#define EMIDI_EXCLUDE_TRACK 111 +#define EMIDI_PROGRAM_CHANGE 112 +#define EMIDI_VOLUME_CHANGE 113 +#define EMIDI_CONTEXT_START 114 +#define EMIDI_CONTEXT_END 115 +#define EMIDI_LOOP_START 116 +#define EMIDI_LOOP_END 117 +#define EMIDI_SONG_LOOP_START 118 +#define EMIDI_SONG_LOOP_END 119 + +#define EMIDI_GeneralMIDI 0 + +#define EMIDI_AffectsCurrentCard( c, type ) \ + ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) ) + + +#define EMIDI_NUM_CONTEXTS 7 +typedef struct + { + unsigned char *pos; + unsigned char *loopstart; + short loopcount; + short RunningStatus; + unsigned time; + long FPSecondsPerTick; + short tick; + short beat; + short measure; + short BeatsPerMeasure; + short TicksPerBeat; + short TimeBase; + long delay; + short active; + } songcontext; + +typedef struct + { + unsigned char *start; + unsigned char *pos; + + long delay; + short active; + short RunningStatus; + + short currentcontext; + songcontext context[ EMIDI_NUM_CONTEXTS ]; + + char EMIDI_IncludeTrack; + char EMIDI_ProgramChange; + char EMIDI_VolumeChange; + } track; + +static long _MIDI_ReadNumber( void *from, size_t size ); +static long _MIDI_ReadDelta( track *ptr ); +static void _MIDI_ResetTracks( void ); +static void _MIDI_AdvanceTick( void ); +static void _MIDI_MetaEvent( track *Track ); +static void _MIDI_SysEx( track *Track ); +static int _MIDI_InterpretControllerInfo( track *Track, int TimeSet, + int channel, int c1, int c2 ); +static int _MIDI_SendControlChange( int channel, int c1, int c2 ); +static void _MIDI_SetChannelVolume( int channel, int volume ); +static void _MIDI_SendChannelVolumes( void ); +static int _MIDI_ProcessNextTick( void ); +static void _MIDI_InitEMIDI( void ); + +/* + if ( c1 == EMIDI_LOOP_START ) + { + if ( c2 == 0 ) + { + Track->context[ 0 ].loopcount = EMIDI_INFINITE; + } + else + { + Track->context[ 0 ].loopcount = c2; + } + + Track->context[ 0 ].pos = Track->pos; + Track->context[ 0 ].loopstart = Track->pos; + Track->context[ 0 ].RunningStatus = Track->RunningStatus; + Track->context[ 0 ].time = _MIDI_Time; + Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; + Track->context[ 0 ].tick = _MIDI_Tick; + Track->context[ 0 ].beat = _MIDI_Beat; + Track->context[ 0 ].measure = _MIDI_Measure; + Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; + Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; + Track->context[ 0 ].TimeBase = _MIDI_TimeBase; + break; + } + + if ( ( c1 == EMIDI_LOOP_END ) && + ( c2 == EMIDI_END_LOOP_VALUE ) ) + { + if ( ( Track->context[ 0 ].loopstart != NULL ) && + ( Track->context[ 0 ].loopcount != 0 ) ) + { + if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE ) + { + Track->context[ 0 ].loopcount--; + } + + Track->pos = Track->context[ 0 ].loopstart; + Track->RunningStatus = Track->context[ 0 ].RunningStatus; + + if ( !TimeSet ) + { + _MIDI_Time = Track->context[ 0 ].time; + _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick; + _MIDI_Tick = Track->context[ 0 ].tick; + _MIDI_Beat = Track->context[ 0 ].beat; + _MIDI_Measure = Track->context[ 0 ].measure; + _MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure; + _MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat; + _MIDI_TimeBase = Track->context[ 0 ].TimeBase; + TimeSet = TRUE; + } + } + break; + } + + if ( c1 == MIDI_MONO_MODE_ON ) + { + Track->pos++; + } + + if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) ) + { + _MIDI_SetChannelVolume( channel, c2 ); + break; + } + else if ( ( c1 == EMIDI_VOLUME_CHANGE ) && + ( Track->EMIDI_VolumeChange ) ) + { + _MIDI_SetChannelVolume( channel, c2 ); + break; + } + + if ( ( c1 == EMIDI_PROGRAM_CHANGE ) && + ( Track->EMIDI_ProgramChange ) ) + { + _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] ); + break; + } + + if ( c1 == EMIDI_CONTEXT_START ) + { + break; + } + + if ( c1 == EMIDI_CONTEXT_END ) + { + if ( ( Track->currentcontext != _MIDI_Context ) || + ( Track->context[ _MIDI_Context ].pos == NULL ) + { + break; + } + + Track->currentcontext = _MIDI_Context; + Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; + Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; + Track->pos = Track->context[ _MIDI_Context ].pos; + Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; + + if ( TimeSet ) + { + break; + } + + _MIDI_Time = Track->context[ _MIDI_Context ].time; + _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; + _MIDI_Tick = Track->context[ _MIDI_Context ].tick; + _MIDI_Beat = Track->context[ _MIDI_Context ].beat; + _MIDI_Measure = Track->context[ _MIDI_Context ].measure; + _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; + _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; + _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; + TimeSet = TRUE; + break; + } + + if ( _MIDI_Funcs->ControlChange ) + { + _MIDI_Funcs->ControlChange( channel, c1, c2 ); + } + */ + +#endif diff --git a/polymer/eduke32/source/jaudiolib/_multivc.h b/polymer/eduke32/source/jaudiolib/_multivc.h new file mode 100644 index 000000000..78025d88e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/_multivc.h @@ -0,0 +1,310 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + file: _MULTIVC.H + + author: James R. Dose + date: December 20, 1993 + + Private header for MULTIVOC.C + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef ___MULTIVC_H +#define ___MULTIVC_H + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + +#define VOC_8BIT 0x0 +#define VOC_CT4_ADPCM 0x1 +#define VOC_CT3_ADPCM 0x2 +#define VOC_CT2_ADPCM 0x3 +#define VOC_16BIT 0x4 +#define VOC_ALAW 0x6 +#define VOC_MULAW 0x7 +#define VOC_CREATIVE_ADPCM 0x200 + +#define T_SIXTEENBIT_STEREO 0 +#define T_8BITS 1 +#define T_MONO 2 +#define T_16BITSOURCE 4 +#define T_LEFTQUIET 8 +#define T_RIGHTQUIET 16 +#define T_DEFAULT T_SIXTEENBIT_STEREO + +#define MV_MaxPanPosition 31 +#define MV_NumPanPositions ( MV_MaxPanPosition + 1 ) +#define MV_MaxTotalVolume 255 +//#define MV_MaxVolume 63 +#define MV_NumVoices 8 + +#define MIX_VOLUME( volume ) \ + ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 ) +// ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 ) + +//#define SILENCE_16BIT 0x80008000 +#define SILENCE_16BIT 0 +#define SILENCE_8BIT 0x80808080 +//#define SILENCE_16BIT_PAS 0 + +//#define MixBufferSize 256 +#define MixBufferSize (MV_GetBufferSize(MV_RequestedMixRate)) + +#define NumberOfBuffers 16 +#define TotalBufferSize ( MixBufferSize * NumberOfBuffers ) + +#define PI 3.1415926536 + +typedef enum + { + Raw, + VOC, + DemandFeed, + WAV + } wavedata; + +typedef enum + { + NoMoreData, + KeepPlaying + } playbackstatus; + + +typedef struct VoiceNode + { + struct VoiceNode *next; + struct VoiceNode *prev; + + wavedata wavetype; + char bits; + + playbackstatus ( *GetSound )( struct VoiceNode *voice ); + + void ( *mix )( unsigned long position, unsigned long rate, + char *start, unsigned long length ); + + char *NextBlock; + char *LoopStart; + char *LoopEnd; + unsigned LoopCount; + unsigned long LoopSize; + unsigned long BlockLength; + + unsigned long PitchScale; + unsigned long FixedPointBufferSize; + + char *sound; + unsigned long length; + unsigned long SamplingRate; + unsigned long RateScale; + unsigned long position; + int Playing; + + int handle; + int priority; + + void ( *DemandFeed )( char **ptr, unsigned long *length ); + + short *LeftVolume; + short *RightVolume; + + unsigned long callbackval; + + } VoiceNode; + +typedef struct + { + VoiceNode *start; + VoiceNode *end; + } VList; + +typedef struct + { + char left; + char right; + } Pan; + +typedef signed short MONO16; +typedef signed char MONO8; + +typedef struct + { + MONO16 left; + MONO16 right; +// unsigned short left; +// unsigned short right; + } STEREO16; + +typedef struct + { + MONO16 left; + MONO16 right; + } SIGNEDSTEREO16; + +typedef struct + { +// MONO8 left; +// MONO8 right; + char left; + char right; + } STEREO8; + +typedef struct + { + char RIFF[ 4 ]; + unsigned long file_size; + char WAVE[ 4 ]; + char fmt[ 4 ]; + unsigned long format_size; + } riff_header; + +typedef struct + { + unsigned short wFormatTag; + unsigned short nChannels; + unsigned long nSamplesPerSec; + unsigned long nAvgBytesPerSec; + unsigned short nBlockAlign; + unsigned short nBitsPerSample; + } format_header; + +typedef struct + { + unsigned char DATA[ 4 ]; + unsigned long size; + } data_header; + +typedef MONO8 VOLUME8[ 256 ]; +typedef MONO16 VOLUME16[ 256 ]; + +typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ]; + +static unsigned MV_GetBufferSize(unsigned); + +static void MV_Mix( VoiceNode *voice, int buffer ); +static void MV_PlayVoice( VoiceNode *voice ); +static void MV_StopVoice( VoiceNode *voice ); +static int MV_ServiceVoc( int ); + +static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextRawBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice ); + +static void MV_ServiceRecord( void ); +static VoiceNode *MV_GetVoice( int handle ); +static VoiceNode *MV_AllocVoice( int priority ); + +static short *MV_GetVolumeTable( int vol ); + +static void MV_SetVoiceMixMode( VoiceNode *voice ); + +static void MV_SetVoicePitch( VoiceNode *voice, unsigned long rate, int pitchoffset ); +static void MV_CalcVolume( int MaxLevel ); +static void MV_CalcPanTable( void ); + +void ClearBuffer_DW(void *ptr, long data, long length) +{ + long *pptr = ptr; + for (; length>0; length--) *(pptr++) = data; +} + +/* +#define ClearBuffer_DW( ptr, data, length ) \ + ({ void *__ptr=(ptr); unsigned __data=(data); int __length=(length); \ + __asm__ __volatile__ ("rep; stosl" \ + : "+c" (__length), "+D" (__ptr) : "a" (__data) : "memory", "cc"); \ + 0; }) +*/ +/* +#pragma aux ClearBuffer_DW = \ + "cld", \ + "push es", \ + "push ds", \ + "pop es", \ + "rep stosd", \ + "pop es", \ +parm [ edi ] [ eax ] [ ecx ] modify exact [ ecx edi ]; +*/ + +#if defined(__WATCOMC__) + +#pragma aux MV_Mix8BitMono parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix8BitStereo parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix16BitMono parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix16BitStereo parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix16BitMono16 parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix8BitMono16 parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix8BitStereo16 parm [eax] [edx] [ebx] [ecx] +#pragma aux MV_Mix16BitStereo16 parm [eax] [edx] [ebx] [ecx] + +#pragma aux MV_16BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi] +#pragma aux MV_8BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi] +#pragma aux MV_16BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi] +#pragma aux MV_8BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi] + +#define CDEC + +#elif defined(_MSC_VER) + +#define CDEC _cdecl + +#else + +#define CDEC __cdecl + +#endif + + +void CDEC MV_Mix8BitMono( unsigned long position, unsigned long rate, + char *start, unsigned long length ); + +void CDEC MV_Mix8BitStereo( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_Mix16BitMono( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_Mix16BitStereo( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_Mix16BitMono16( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_Mix8BitMono16( unsigned long position, unsigned long rate, + char *start, unsigned long length ); + +void CDEC MV_Mix8BitStereo16( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_Mix16BitStereo16( unsigned long position, + unsigned long rate, char *start, unsigned long length ); + +void CDEC MV_16BitReverb( char *src, char *dest, VOLUME16 *volume, int count ); +void CDEC MV_8BitReverb( signed char *src, signed char *dest, VOLUME16 *volume, int count ); +void CDEC MV_16BitReverbFast( char *src, char *dest, int count, int shift ); +void CDEC MV_8BitReverbFast( signed char *src, signed char *dest, int count, int shift ); + +#undef CDEC + +#endif diff --git a/polymer/eduke32/source/jaudiolib/audiolib_fx_fmod.c b/polymer/eduke32/source/jaudiolib/audiolib_fx_fmod.c new file mode 100644 index 000000000..e2e7b1fd3 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/audiolib_fx_fmod.c @@ -0,0 +1,737 @@ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + FMOD AudioLib implementation by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#include "fx_man_fmod.h" +#include "duke3d.h" + +#include "fmod.h" + +#define TRUE (1==1) +#define FALSE (1==0) + +#define dprintOSD(...) + +#ifdef WINDOWS +extern long hWindow; +#endif + + +void (*FX_CallBackFunc)(unsigned long) = NULL; +int FX_ErrorCode = FX_Ok; + +#define FX_SetErrorCode( status ) \ + FX_ErrorCode = ( status ); + +FSOUND_SAMPLE * FX_Samples[NUM_SOUNDS + 11]; // 11 remote ridicules + +int FX_NumVoices = 0; +static char chtoggle=0; +static char *chstates=NULL, *chstatesa, *chstatesb; +static long *chcallvals=NULL; + +int FX_ReadVOCInfo(char *data, long size, int *samplerate, int *channels, int *samplesize, long *datalen); +int FX_ReadVOCData(char *data, char *buf, int bufferlen, char eightbit); + +int FX_SimulateCallbacks(void); + + +/*--------------------------------------------------------------------- + Function: FX_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *FX_ErrorString(int ErrorNumber) +{ + char *ErrorString; + + switch( ErrorNumber ) + { + case FX_Warning : + case FX_Error : + ErrorString = FX_ErrorString( FX_ErrorCode ); + break; + + case FX_Ok : + ErrorString = "Fx ok."; + break; + + case FX_ASSVersion : + ErrorString = "Apogee Sound System Version WinMM " + "Programmed by Jim Dose, Ported by Jonathon Fowler\n" + "(c) Copyright 1995 James R. Dose. All Rights Reserved.\n"; + break; + + case FX_FMODInit : + ErrorString = "Failed initializing FMOD."; + break; + + default : + ErrorString = "Unknown Fx error code."; + break; + } + + return( ErrorString ); +} + + +/*--------------------------------------------------------------------- + Function: FX_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +static char *OutputType(int a) +{ + switch (a) { + case FSOUND_OUTPUT_NOSOUND: return "no-sound"; + case FSOUND_OUTPUT_WINMM: return "WinMM"; + case FSOUND_OUTPUT_DSOUND: return "DirectSound"; + case FSOUND_OUTPUT_A3D: return "Aureal3D"; + case FSOUND_OUTPUT_OSS: return "OSS"; + case FSOUND_OUTPUT_ESD: return "ESD"; + case FSOUND_OUTPUT_ALSA: return "ALSA"; + case FSOUND_OUTPUT_ASIO: return "ASIO"; + case FSOUND_OUTPUT_XBOX: return "Xbox"; + case FSOUND_OUTPUT_PS2: return "Playstation2"; + case FSOUND_OUTPUT_MAC: return "Macintosh Sound Manager"; + default: return "unknown"; + } +} + +int FX_Init(int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate) +{ + FSOUND_Close(); + + memset(FX_Samples, 0, sizeof(FX_Samples)); + +#ifdef WINDOWS + if (hWindow) { + //FSOUND_SetHWND(&hWindow); + } +#endif + if (!FSOUND_Init(mixrate, numvoices, FSOUND_INIT_GLOBALFOCUS)) { + FX_SetErrorCode( FX_FMODInit ); + return FX_Error; + } + + printOSD("FX_Init(): %d voices, %d channels, %dHz samplerate\n", numvoices,numchannels,FSOUND_GetOutputRate()); + printOSD("FX_Init(): FMOD is using the %s output driver\n", OutputType(FSOUND_GetOutput())); + + chtoggle=0; + if (chstates) free(chstates); + chstates = (char*)malloc(numvoices*2 + sizeof(long)*numvoices); + memset(chstates,0,numvoices*2 + sizeof(long)*numvoices); + + chcallvals = (long*)(chstates + numvoices*2); + chstatesa = chstates; + chstatesb = chstates + numvoices; + + FX_NumVoices = numvoices; + + FX_SetErrorCode(FX_Ok); + return FX_Ok; +} + + +/*--------------------------------------------------------------------- + Function: FX_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int FX_Shutdown(void) +{ + unsigned int curalloced, maxalloced; + + if (chstates) { + FSOUND_GetMemoryStats(&curalloced, &maxalloced); + printOSD("FX_Shutdown(): allocation stats - currently %d bytes, maximum %d bytes\n",curalloced,maxalloced); + } + + FSOUND_Close(); + + if (chstates) free(chstates); + chstates=chstatesa=chstatesb=0; + + FX_SetErrorCode(FX_Ok); + return FX_Ok; +} + + +/*--------------------------------------------------------------------- + Function: FX_SetCallback + + Sets the function to call when a voice is done. +---------------------------------------------------------------------*/ + +int FX_SetCallBack(void ( *function )( unsigned long )) +{ + FX_CallBackFunc = function; + FX_SetErrorCode(FX_Ok); + return FX_Ok; +} + + +/*--------------------------------------------------------------------- + Function: FX_SetVolume + + Sets the volume of the current sound device. +---------------------------------------------------------------------*/ + +void FX_SetVolume(int volume) +{ + FSOUND_SetSFXMasterVolume(volume); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void FX_SetReverseStereo(int setting) +{ +} + + +/*--------------------------------------------------------------------- + Function: FX_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int FX_GetReverseStereo(void) +{ + return 0; +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetReverb(int reverb) +{ +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void FX_SetReverbDelay(int delay) +{ +} + + +/*--------------------------------------------------------------------- + Function: FX_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int FX_VoiceAvailable(int priority) +{ + FX_SimulateCallbacks(); + return 1; +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedVOC + + Begin playback of sound data with the given volume and priority. + JBF: As a hack, since Duke3D passes the sound/sample number as the + callbackval parameter, we can use this as an index into the + FX_Samples array to access samples if they've already been loaded. + RemoteRidicule sounds have negative callback values, so they + take up residence at the end of FX_Samples. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedVOC + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) +{ + return FX_PlayLoopedSound(pitchoffset, vol, callbackval); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedWAV + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) +{ + return FX_PlayLoopedSound(pitchoffset, vol, callbackval); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayVOC3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) +{ + return FX_PlayPositionedSound(pitchoffset, angle, distance, callbackval); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayWAV3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) +{ + return FX_PlayPositionedSound(pitchoffset, angle, distance, callbackval); +} + + +/*--------------------------------------------------------------------- + Function: FX_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int FX_Pan3D + ( + int handle, + int angle, + int distance + ) +{ + return FX_Ok; +} + + +/*--------------------------------------------------------------------- + Function: FX_StopSound + + Halts playback of a specific voice +---------------------------------------------------------------------*/ + +int FX_StopSound(int handle) +{ + FX_SimulateCallbacks(); + FSOUND_StopSound(handle); + + if (handle>=0 && handle> (channels-1)) / (samplesize>>3), flags, samplerate, -1, -1, priority); + if (samp) { + if (FSOUND_Sample_Lock(samp,0,datalen,&ptr1,&ptr2,&ptr1len,&ptr2len)) { + if (FX_ReadVOCData(ptr,ptr1,datalen,(samplesize==8))) ; + FSOUND_Sample_Unlock(samp,ptr1,ptr2,ptr1len,ptr2len); + } + } + } + } else { + samp = FSOUND_Sample_Load(number, ptr, FSOUND_LOADMEMORY, size); + } + + dprintOSD("FX_LoadSample(): loaded sound %d\n",number); + if (samp) FSOUND_Sample_SetDefaults(samp, -1, -1, -1, priority); + FX_Samples[number] = samp; + + return (samp != NULL); +} + + +int FX_SampleLoaded(unsigned long number) +{ + return (FX_Samples[number] != NULL); +} + + +#define REGRESSTC(tc) (256000000/(65536-(tc))) +#define REGRESSSR(sr) (1000000/(256-(sr))) + +int FX_ReadVOCInfo(char *data, long size, int *samplerate, int *channels, int *samplesize, long *datalen) +{ + short version,version2; + char blocktype=0; + int blocklen=0; + char *ptr=data; + + if (memcmp(ptr, "Creative Voice File\x1A", 0x14)) return -1; + ptr += 0x14; + + ptr += 2; + version = ((short*)ptr)[0]; + version2 = ((short*)ptr)[1]; + + if (~version + 0x1234 != version2) return -1; + + ptr += 4; + + while (1) { + blocktype = *(ptr++); + if ((ptr-data)>size) return -1; // truncated + + if (blocktype == 0) + break; + + blocklen = *(ptr++); + blocklen |= *(ptr++) << 8; + blocklen |= *(ptr++) << 16; + + switch (blocktype) { + case 1: /* sound data begin block */ + if (!*samplerate) + *samplerate = REGRESSSR(ptr[0]); + if (ptr[1] != 0) { + /* only 8-bit files please */ + return -1; + } + if (!*channels) *channels = 1; + *samplesize = 8; + *datalen += blocklen-2; + ptr += blocklen; + break; + + case 2: /* sound continue */ + *datalen += blocklen; + ptr += blocklen; + break; + +#if 0 + case 3: /* silence */ + kread(fh, blockprop, 3); + /* + length = blockprop[0] | (blockprop[1] << 8) + sample rate = REGRESSSR(blockprop[2])) + */ + break; + + case 4: /* marker */ + kread(fh, &blockprop, 2); + /* + id = blockprop[0] | (blockprop[1] << 8)) + */ + break; + + case 5: /* ASCII data */ + klseek(fh, blocklen, SEEK_CUR); + /* + asciiz string + */ + break; + + case 6: /* repeat */ + kread(fh, blockprop, 2); + /* + num repetitions = (blockprop[0] | (blockprop[1] << 8)) - 1 + */ + break; + + case 7: /* end repeat */ + break; +#endif + + case 8: /* sound attribute extension block */ + *samplerate = REGRESSTC(ptr[0] | (ptr[1] << 8)); + *samplesize = 8; + if (ptr[3] == 1) { + *samplerate >>= 1; + *channels = 2; + } else + *channels = 1; + if (ptr[2] != 0) { + /* only 8-bit files please */ + return -1; + } + ptr += 4; + /* a block 1 follows */ + break; + + case 9: /* sound data format 3 */ + *samplerate = *((long*)(ptr)); + *samplesize = ptr[4]; + *channels = ptr[5]; + if ((ptr[6] | (ptr[7] << 8)) != 0 && + (ptr[6] | (ptr[7] << 8)) != 4) { + /* only PCM please */ + return -1; + } + *datalen += blocklen-12; + ptr += blocklen; + break; + + default: + ptr += blocklen; + break; + } + } + + return 0; +} + + +int FX_ReadVOCData(char *data, char *buf, int bufferlen, char eightbit) +{ + short offset; + char blocktype=0; + int blocklen=0, br; + + data += 0x14 + 2 + 4; + + while (bufferlen>0) { + blocktype = *(data++); + + if (blocktype == 0) + break; + + blocklen = *(data++); + blocklen |= *(data++) << 8; + blocklen |= *(data++) << 16; + + switch (blocktype) { + case 1: /* sound data */ + data += 2; + + br = min(blocklen-2, bufferlen); + goto convertdata; + + case 2: /* sound continue */ + br = min(blocklen, bufferlen); + goto convertdata; + + case 9: /* sound data format 3 */ + data += 12; + + br = min(blocklen-12, bufferlen); + goto convertdata; + + default: + data += blocklen; + continue; + } +convertdata: + bufferlen -= br; + if (eightbit) { + // FMOD wants signed data + for (; br>0; br--) + *(buf++) = (char)((short)(*(data++)) - 0x80); + } else { + memcpy(buf,data,br); + buf += br; + data += br; + } + } + + return 0; +} + + +int FX_SimulateCallbacks(void) +{ + int i; + + if (!FX_CallBackFunc || !chstates) return 0; + + chstatesa = chstates + (FX_NumVoices * chtoggle); + chstatesb = chstates + (FX_NumVoices * (chtoggle^1)); + + for (i=0;i chstatesb[i]) continue; // channel has begun playing + + // channel has ended playing + FX_CallBackFunc(chcallvals[i]); + dprintOSD("FX_SimulateCallbacks(): channel %d ended sound %d\n",i,chcallvals[i]); + } + + chtoggle ^= 1; + + return 0; +} + diff --git a/polymer/eduke32/source/jaudiolib/audiolib_fxstub.c b/polymer/eduke32/source/jaudiolib/audiolib_fxstub.c new file mode 100644 index 000000000..a0bfcc4a2 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/audiolib_fxstub.c @@ -0,0 +1,368 @@ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Dummy AudioLib stub implementation by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#include "fx_man.h" + + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + + +int FX_ErrorCode = FX_Ok; + +#define FX_SetErrorCode( status ) \ + FX_ErrorCode = ( status ); + + + +/*--------------------------------------------------------------------- + Function: FX_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *FX_ErrorString + ( + int ErrorNumber + ) + + { + char *ErrorString; + + switch( ErrorNumber ) + { + case FX_Warning : + case FX_Error : + ErrorString = FX_ErrorString( FX_ErrorCode ); + break; + + case FX_Ok : + ErrorString = "Fx ok."; + break; + + case FX_ASSVersion : + ErrorString = "Apogee Sound System Version 0 " + "Programmed by Jim Dose\n" + "(c) Copyright 1995 James R. Dose. All Rights Reserved.\n"; + break; + + default : + ErrorString = "Unknown Fx error code."; + break; + } + + return( ErrorString ); + } + + +/*--------------------------------------------------------------------- + Function: FX_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +int FX_Init + ( + int SoundCard, + int numvoices, + int numchannels, + int samplebits, + unsigned mixrate + ) + + { + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int FX_Shutdown + ( + void + ) + + { + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetCallback + + Sets the function to call when a voice is done. +---------------------------------------------------------------------*/ + +int FX_SetCallBack + ( + void ( *function )( unsigned long ) + ) + + { + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetVolume + + Sets the volume of the current sound device. +---------------------------------------------------------------------*/ + +void FX_SetVolume + ( + int volume + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void FX_SetReverseStereo + ( + int setting + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: FX_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int FX_GetReverseStereo + ( + void + ) + + { + return 0; + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetReverb + ( + int reverb + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void FX_SetReverbDelay + ( + int delay + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: FX_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int FX_VoiceAvailable + ( + int priority + ) + + { + return 0; + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedVOC + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedVOC + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedWAV + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayVOC3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayWAV3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: FX_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int FX_Pan3D + ( + int handle, + int angle, + int distance + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: FX_StopSound + + Halts playback of a specific voice +---------------------------------------------------------------------*/ + +int FX_StopSound + ( + int handle + ) + + { + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_StopAllSounds + + Halts playback of all sounds. +---------------------------------------------------------------------*/ + +int FX_StopAllSounds + ( + void + ) + + { + return( FX_Ok ); + } + + +void AudioUpdate(void) { } diff --git a/polymer/eduke32/source/jaudiolib/audiolib_musicstub.c b/polymer/eduke32/source/jaudiolib/audiolib_musicstub.c new file mode 100644 index 000000000..a8e2e1a2e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/audiolib_musicstub.c @@ -0,0 +1,510 @@ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Dummy AudioLib stub implementation by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#include "music.h" + + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + + +int MUSIC_ErrorCode = MUSIC_Ok; + + +/*--------------------------------------------------------------------- + Function: MUSIC_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *MUSIC_ErrorString + ( + int ErrorNumber + ) + + { + char *ErrorString; + + switch( ErrorNumber ) + { + case MUSIC_Warning : + case MUSIC_Error : + ErrorString = MUSIC_ErrorString( MUSIC_ErrorCode ); + break; + + case MUSIC_Ok : + ErrorString = "Music ok."; + break; + + case MUSIC_ASSVersion : + ErrorString = "Apogee Sound System Version " + "Programmed by Jim Dose\n" + "(c) Copyright 1996 James R. Dose. All Rights Reserved.\n"; + break; + + case MUSIC_SoundCardError : + break; + + case MUSIC_MPU401Error : + ErrorString = "Could not detect MPU-401."; + break; + + case MUSIC_InvalidCard : + ErrorString = "Invalid Music device."; + break; + + case MUSIC_MidiError : + ErrorString = "Error playing MIDI file."; + break; + + case MUSIC_TaskManError : + ErrorString = "TaskMan error."; + break; + + case MUSIC_DPMI_Error : + ErrorString = "DPMI Error in MUSIC."; + break; + + default : + ErrorString = "Unknown Music error code."; + break; + } + + return( ErrorString ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +int MUSIC_Init + ( + int SoundCard, + int Address + ) + + { + int i; + int status; + + status = MUSIC_Ok; + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int MUSIC_Shutdown + ( + void + ) + + { + int status; + + status = MUSIC_Ok; + + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetMaxFMMidiChannel + + Sets the maximum MIDI channel that FM cards respond to. +---------------------------------------------------------------------*/ + +void MUSIC_SetMaxFMMidiChannel + ( + int channel + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetVolume + + Sets the volume of music playback. +---------------------------------------------------------------------*/ + +void MUSIC_SetVolume + ( + int volume + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetMidiChannelVolume + + Sets the volume of music playback on the specified MIDI channel. +---------------------------------------------------------------------*/ + +void MUSIC_SetMidiChannelVolume + ( + int channel, + int volume + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_ResetMidiChannelVolumes + + Sets the volume of music playback on all MIDI channels to full volume. +---------------------------------------------------------------------*/ + +void MUSIC_ResetMidiChannelVolumes + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetVolume + + Returns the volume of music playback. +---------------------------------------------------------------------*/ + +int MUSIC_GetVolume + ( + void + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetLoopFlag + + Set whether the music will loop or end when it reaches the end of + the song. +---------------------------------------------------------------------*/ + +void MUSIC_SetLoopFlag + ( + int loopflag + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SongPlaying + + Returns whether there is a song playing. +---------------------------------------------------------------------*/ + +int MUSIC_SongPlaying + ( + void + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Continue + + Continues playback of a paused song. +---------------------------------------------------------------------*/ + +void MUSIC_Continue + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Pause + + Pauses playback of a song. +---------------------------------------------------------------------*/ + +void MUSIC_Pause + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_StopSong + + Stops playback of current song. +---------------------------------------------------------------------*/ + +int MUSIC_StopSong + ( + void + ) + + { + return( MUSIC_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_PlaySong + + Begins playback of MIDI song. +---------------------------------------------------------------------*/ + +int MUSIC_PlaySong + ( + unsigned char *song, + int loopflag + ) + + { + return( MUSIC_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetContext + + Sets the song context. +---------------------------------------------------------------------*/ + +void MUSIC_SetContext + ( + int context + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetContext + + Returns the current song context. +---------------------------------------------------------------------*/ + +int MUSIC_GetContext + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongTick + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongTick + ( + unsigned long PositionInTicks + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongTime + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongTime + ( + unsigned long milliseconds + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongPosition + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongPosition + ( + int measure, + int beat, + int tick + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetSongPosition + + Returns the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_GetSongPosition + ( + songposition *pos + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetSongLength + + Returns the length of the song. +---------------------------------------------------------------------*/ + +void MUSIC_GetSongLength + ( + songposition *pos + ) + + { + } + + + + + + +/*--------------------------------------------------------------------- + Function: MUSIC_FadeVolume + + Fades music volume from current level to another over a specified + period of time. +---------------------------------------------------------------------*/ + +int MUSIC_FadeVolume + ( + int tovolume, + int milliseconds + ) + + { + return( MUSIC_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_FadeActive + + Returns whether the fade routine is active. +---------------------------------------------------------------------*/ + +int MUSIC_FadeActive + ( + void + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_StopFade + + Stops fading the music. +---------------------------------------------------------------------*/ + +void MUSIC_StopFade + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_RerouteMidiChannel + + Sets callback function to reroute MIDI commands from specified + function. +---------------------------------------------------------------------*/ + +void MUSIC_RerouteMidiChannel + ( + int channel, + int ( *function )( int event, int c1, int c2 ) + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_RegisterTimbreBank + + Halts playback of all sounds. +---------------------------------------------------------------------*/ + +void MUSIC_RegisterTimbreBank + ( + unsigned char *timbres + ) + + { + } + + +void MUSIC_Update(void) +{ +} + diff --git a/polymer/eduke32/source/jaudiolib/dsoundout.c b/polymer/eduke32/source/jaudiolib/dsoundout.c new file mode 100644 index 000000000..0ab98202c --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/dsoundout.c @@ -0,0 +1,585 @@ +/* + * DirectSound output code for MultiVoc + * by Jonathon Fowler (jonof@edgenetwk.com) + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "dsoundout.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include "dsound.h" +#include "osd.h" + +#include "winlayer.h" + +#if defined(__WATCOMC__) || defined(_MSC_VER) +#include +#endif + + +#ifndef RENDERTYPEWIN +#error The DirectSound output module for AudioLib only works with the Windows interface. +#endif + +static CRITICAL_SECTION mutex; +static int _DSOUND_CriticalSectionAlloced = FALSE; +static HANDLE isrthread = NULL; +static HANDLE isrfinish = NULL; + +static HMODULE hDSoundDLL = NULL; +static LPDIRECTSOUND lpDS = NULL; +static LPDIRECTSOUNDBUFFER lpDSBPrimary = NULL; +static LPDIRECTSOUNDBUFFER lpDSBSecondary = NULL; +static LPDIRECTSOUNDNOTIFY lpDSNotify = NULL; +static HANDLE *hPosNotify = NULL; + +static int (*_DSOUND_CallBack)(int) = NULL; +static int _DSOUND_BufferLength = 0; +static int _DSOUND_NumBuffers = 0; +static char *_DSOUND_MixBuffer = NULL; + +static int DSOUND_Installed = FALSE; + +int DSOUND_ErrorCode = DSOUND_Ok; + +#define DSOUND_SetErrorCode( status ) \ + DSOUND_ErrorCode = ( status ); + + + +/* + * DisableInterrupts + * Enter the critical section. + */ +int DisableInterrupts(void) +{ + if (!_DSOUND_CriticalSectionAlloced) return -1; + + EnterCriticalSection(&mutex); + + return 0; +} + + +/* + * RestoreInterrupts + * Leave the critical section. + */ +int RestoreInterrupts(int a) +{ + if (!_DSOUND_CriticalSectionAlloced) return -1; + + LeaveCriticalSection(&mutex); + + return 0; + a=a; +} + + +/* + * DSOUND_ErrorString + * Returns a description of an error code. + */ +char *DSOUND_ErrorString(int errorcode) +{ + switch (errorcode) { + case DSOUND_Warning: + case DSOUND_Error: + return DSOUND_ErrorString(DSOUND_ErrorCode); + + case DSOUND_Ok: + return "DirectSound ok."; + + case DSOUND_NoDLL: + return "Failed loading DSOUND.DLL."; + + case DSOUND_NoDirectSoundCreate: + return "Failed getting DirectSoundCreate entry point."; + + case DSOUND_FailedDSC: + return "DirectSoundCreate failed."; + + case DSOUND_FailedSetCoopLevel: + return "Failed setting cooperative level."; + + case DSOUND_FailedCreatePrimary: + return "Failed creating primary buffer."; + + case DSOUND_FailedSetFormat: + return "Failed setting primary buffer format."; + + case DSOUND_FailedCreateSecondary: + return "Failed creating secondary buffer."; + + case DSOUND_FailedCreateNotifyEvent: + return "Failed creating notification event object."; + + case DSOUND_FailedQueryNotify: + return "Failed querying notification interface."; + + case DSOUND_FailedSetNotify: + return "Failed setting notification positions."; + + case DSOUND_FailedCreateFinishEvent: + return "Failed creating finish event object."; + + case DSOUND_FailedCreateThread: + return "Failed creating playback thread."; + + case DSOUND_FailedPlaySecondary: + return "Failed playing secondary buffer."; + + case DSOUND_FailedGetExitCode: + return "GetExitCodeThread failed."; + + default: + return "Unknown DirectSound error code."; + } +} + + +/* + * DSOUND_Init + * Initializes the DirectSound objects. + */ +int DSOUND_Init(int soundcard, int mixrate, int numchannels, int samplebits, int buffersize) +{ + HRESULT (WINAPI *aDirectSoundCreate)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); + HRESULT hr; + DSBUFFERDESC dsbuf; + WAVEFORMATEX wfex; + DSBPOSITIONNOTIFY posn; + + if (DSOUND_Installed) { + DSOUND_Shutdown(); + } + + printOSD("Initializing DirectSound...\n"); + + if (!_DSOUND_CriticalSectionAlloced) { + // initialize the critical section object we'll use to + // simulate (dis|en)abling interrupts + InitializeCriticalSection(&mutex); + _DSOUND_CriticalSectionAlloced = TRUE; + } + + printOSD(" - Loading DSOUND.DLL\n"); + hDSoundDLL = LoadLibrary("DSOUND.DLL"); + if (!hDSoundDLL) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_NoDLL); + return DSOUND_Error; + } + + aDirectSoundCreate = (void *)GetProcAddress(hDSoundDLL, "DirectSoundCreate"); + if (!aDirectSoundCreate) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_NoDirectSoundCreate); + return DSOUND_Error; + } + + printOSD(" - Creating DirectSound object\n"); + hr = aDirectSoundCreate(NULL, &lpDS, NULL); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedDSC); + return DSOUND_Error; + } + + hr = IDirectSound_SetCooperativeLevel(lpDS, (HWND)win_gethwnd(), DSSCL_EXCLUSIVE); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedSetCoopLevel); + return DSOUND_Error; + } + + printOSD(" - Creating primary buffer\n"); + ZeroMemory(&dsbuf, sizeof(dsbuf)); + dsbuf.dwSize = sizeof(DSBUFFERDESC); + dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; + hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBPrimary, NULL); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedCreatePrimary); + return DSOUND_Error; + } + + printOSD(" - Setting primary buffer format\n" + " Channels: %d\n" + " Sample rate: %dHz\n" + " Sample size: %d bits\n", + numchannels, mixrate, samplebits); + ZeroMemory(&wfex, sizeof(wfex)); + wfex.wFormatTag = WAVE_FORMAT_PCM; + wfex.nChannels = numchannels; + wfex.nSamplesPerSec = mixrate; + wfex.wBitsPerSample = samplebits; + wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels; + wfex.nAvgBytesPerSec = wfex.nBlockAlign * wfex.nSamplesPerSec; + hr = IDirectSoundBuffer_SetFormat(lpDSBPrimary, &wfex); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedSetFormat); + return DSOUND_Error; + } + + printOSD(" - Creating secondary buffer\n"); + ZeroMemory(&dsbuf, sizeof(dsbuf)); + dsbuf.dwSize = sizeof(DSBUFFERDESC); + dsbuf.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE; + dsbuf.dwBufferBytes = buffersize; + dsbuf.lpwfxFormat = &wfex; + hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBSecondary, NULL); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedCreateSecondary); + return DSOUND_Error; + } + + hr = IDirectSoundBuffer_QueryInterface(lpDSBSecondary, &IID_IDirectSoundNotify, &lpDSNotify); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedQueryNotify); + return DSOUND_Error; + } + + hPosNotify = (HANDLE *)malloc(sizeof(HANDLE)); + if (!hPosNotify) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedSetNotify); + return DSOUND_Error; + } + + hPosNotify[0] = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!hPosNotify) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedCreateNotifyEvent); + return DSOUND_Error; + } + + _DSOUND_BufferLength = 0; + _DSOUND_NumBuffers = 1; + posn.dwOffset = 0; + posn.hEventNotify = hPosNotify[0]; + + hr = IDirectSoundNotify_SetNotificationPositions(lpDSNotify, 1, &posn); + if (hr != DS_OK) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedSetNotify); + return DSOUND_Error; + } + + DSOUND_Installed = TRUE; + + DSOUND_SetErrorCode(DSOUND_Ok); + return DSOUND_Ok; +} + + +/* + * DSOUND_Shutdown + * Shuts down DirectSound and it's associates. + */ +int DSOUND_Shutdown(void) +{ + int i; + + if (DSOUND_Installed) printOSD("Uninitializing DirectSound...\n"); + + DSOUND_Installed = FALSE; + + DSOUND_StopPlayback(); + + if (lpDSNotify) { + IDirectSoundNotify_Release(lpDSNotify); + lpDSNotify = NULL; + } + + if (hPosNotify) { + for (i=0; i<_DSOUND_NumBuffers; i++) { + if (hPosNotify[i]) CloseHandle(hPosNotify[i]); + } + free(hPosNotify); + hPosNotify = NULL; + } + + if (lpDSBSecondary) { + printOSD(" - Releasing secondary buffer\n"); + IDirectSoundBuffer_Stop(lpDSBSecondary); + IDirectSoundBuffer_Release(lpDSBSecondary); + lpDSBSecondary = NULL; + } + + if (lpDSBPrimary) { + printOSD(" - Releasing primary buffer\n"); + IDirectSoundBuffer_Release(lpDSBPrimary); + lpDSBPrimary = NULL; + } + + if (lpDS) { + printOSD(" - Releasing DirectSound object\n"); + IDirectSound_Release(lpDS); + lpDS = NULL; + } + + if (hDSoundDLL) { + printOSD(" - Unloading DSOUND.DLL\n"); + FreeLibrary(hDSoundDLL); + hDSoundDLL = NULL; + } + + DSOUND_SetErrorCode(DSOUND_Ok); + return DSOUND_Ok; +} + + +/* + * DSOUND_SetMixMode + * Bit of filler for the future. + */ +int DSOUND_SetMixMode(int mode) +{ + return mode; +} + + +//#define DEBUGAUDIO + +#ifdef DEBUGAUDIO +#include +#endif +static DWORD WINAPI isr(LPVOID parm) +{ + HANDLE *handles; + HRESULT hr; + DWORD rv; +#ifdef DEBUGAUDIO + int h; +#endif + int p; + LPVOID lockptr; DWORD lockbytes; + LPVOID lockptr2; DWORD lockbytes2; + + handles = (HANDLE *)malloc(sizeof(HANDLE)*(1+_DSOUND_NumBuffers)); + if (!handles) return 1; + + handles[0] = isrfinish; + for (p=0; p<_DSOUND_NumBuffers; p++) + handles[p+1] = hPosNotify[p]; + +#ifdef DEBUGAUDIO + h = creat("audio.raw",S_IREAD|S_IWRITE); +#endif + + while (1) { + rv = WaitForMultipleObjects(1+_DSOUND_NumBuffers, handles, FALSE, INFINITE); + + if (!(rv >= WAIT_OBJECT_0 && rv <= WAIT_OBJECT_0+1+_DSOUND_NumBuffers)) return -1; + + if (rv == WAIT_OBJECT_0) { + // we've been asked to finish up + break; + } + + // otherwise we just service the interrupt + if (_DSOUND_CallBack) { + DisableInterrupts(); + + p = _DSOUND_CallBack(rv-WAIT_OBJECT_0-1); +#ifdef DEBUGAUDIO + write(h, _DSOUND_MixBuffer + p*_DSOUND_BufferLength, _DSOUND_BufferLength); +#endif + + hr = IDirectSoundBuffer_Lock(lpDSBSecondary, p*_DSOUND_BufferLength, _DSOUND_BufferLength, + &lockptr, &lockbytes, &lockptr2, &lockbytes2, 0); + if (hr == DSERR_BUFFERLOST) { + hr = IDirectSoundBuffer_Restore(lpDSBSecondary); + } + if (hr == DS_OK) { + /* +#define copybuf(S,D,c) \ + ({ void *__S=(S), *__D=(D); long __c=(c); \ + __asm__ __volatile__ ("rep; movsl" \ + : "+S" (__S), "+D" (__D), "+c" (__c) : : "memory", "cc"); \ + 0; }) +*/ + //copybuf(_DSOUND_MixBuffer + p * _DSOUND_BufferLength, lockptr, _DSOUND_BufferLength >> 2); + memcpy(lockptr, _DSOUND_MixBuffer + p * _DSOUND_BufferLength, _DSOUND_BufferLength); + IDirectSoundBuffer_Unlock(lpDSBSecondary, lockptr, lockbytes, lockptr2, lockbytes2); + } + + RestoreInterrupts(0); + } + } + +#ifdef DEBUGAUDIO + close(h); +#endif + + return 0; +} + + +/* + * DSOUND_BeginBufferedPlayback + * Spins off a thread that behaves somewhat like the SoundBlaster DMA ISR did. + */ +int DSOUND_BeginBufferedPlayback(char *BufferStart, int (*CallBackFunc)(int), int buffersize, int numdivisions) +{ + DWORD threadid; + HRESULT hr; + DSBPOSITIONNOTIFY *posns; + int i; + + _DSOUND_CallBack = CallBackFunc; + _DSOUND_MixBuffer = BufferStart; + + if (!lpDSBSecondary) return DSOUND_Error; + + if (isrthread) { + DSOUND_StopPlayback(); + } + + isrfinish = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!isrfinish) { + DSOUND_SetErrorCode(DSOUND_FailedCreateFinishEvent); + return DSOUND_Error; + } + + isrthread = CreateThread(NULL, 0, isr, NULL, CREATE_SUSPENDED, &threadid); + if (!isrthread) { + DSOUND_SetErrorCode(DSOUND_FailedCreateThread); + return DSOUND_Error; + } + + hPosNotify = (HANDLE *)malloc(sizeof(HANDLE)*numdivisions); + if (!hPosNotify) { + DSOUND_Shutdown(); + DSOUND_SetErrorCode(DSOUND_FailedSetNotify); + return DSOUND_Error; + } + + memset(hPosNotify, 0, sizeof(HANDLE)*numdivisions); + for (i=0; i +#include +#include "multivoc.h" +#include "ll_man.h" +#include "fx_man.h" + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + +static unsigned FX_MixRate; + +int FX_SoundDevice = -1; +int FX_ErrorCode = FX_Ok; +int FX_Installed = FALSE; + +#define FX_SetErrorCode( status ) \ + FX_ErrorCode = ( status ); + +/*--------------------------------------------------------------------- + Function: FX_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *FX_ErrorString + ( + int ErrorNumber + ) + + { + char *ErrorString; + + switch( ErrorNumber ) + { + case FX_Warning : + case FX_Error : + ErrorString = FX_ErrorString( FX_ErrorCode ); + break; + + case FX_Ok : + ErrorString = "Fx ok."; + break; + + case FX_ASSVersion : + ErrorString = "Apogee Sound System Version 0 " + "Programmed by Jim Dose\n" + "(c) Copyright 1995 James R. Dose. All Rights Reserved.\n"; + break; + + case FX_BlasterError : + case FX_SoundCardError : + ErrorString = "Sound device error."; + break; + + case FX_InvalidCard : + ErrorString = "Invalid Sound Fx device."; + break; + + case FX_MultiVocError : + ErrorString = MV_ErrorString( MV_Error ); + break; + + case FX_DPMI_Error : + ErrorString = "DPMI Error in FX_MAN."; + break; + + default : + ErrorString = "Unknown Fx error code."; + break; + } + + return( ErrorString ); + } + + +#if 0 +/*--------------------------------------------------------------------- + Function: FX_SetupCard + + Sets the configuration of a sound device. +---------------------------------------------------------------------*/ + +int FX_SetupCard + ( + int SoundCard, + fx_device *device + ) + + { + int status; + int DeviceStatus; + + FX_SoundDevice = SoundCard; + + status = FX_Ok; + FX_SetErrorCode( FX_Ok ); + + switch( SoundCard ) + { + case SoundBlaster : + DeviceStatus = BLASTER_Init(); + if ( DeviceStatus != BLASTER_Ok ) + { + FX_SetErrorCode( FX_SoundCardError ); + status = FX_Error; + break; + } + + device->MaxVoices = 32; + BLASTER_GetCardInfo( &device->MaxSampleBits, &device->MaxChannels ); + break; + + default : + FX_SetErrorCode( FX_InvalidCard ); + status = FX_Error; + } + return( status ); + } +#endif + + +#if 0 +/*--------------------------------------------------------------------- + Function: FX_GetBlasterSettings + + Returns the current BLASTER environment variable settings. +---------------------------------------------------------------------*/ + +int FX_GetBlasterSettings + ( + fx_blaster_config *blaster + ) + + { + int status; + BLASTER_CONFIG Blaster; + + FX_SetErrorCode( FX_Ok ); + + status = BLASTER_GetEnv( &Blaster ); + if ( status != BLASTER_Ok ) + { + FX_SetErrorCode( FX_BlasterError ); + return( FX_Error ); + } + + blaster->Type = Blaster.Type; + blaster->Address = Blaster.Address; + blaster->Interrupt = Blaster.Interrupt; + blaster->Dma8 = Blaster.Dma8; + blaster->Dma16 = Blaster.Dma16; + blaster->Midi = Blaster.Midi; + blaster->Emu = Blaster.Emu; + + return( FX_Ok ); + } +#endif + + +#if 0 +/*--------------------------------------------------------------------- + Function: FX_SetupSoundBlaster + + Handles manual setup of the Sound Blaster information. +---------------------------------------------------------------------*/ + +int FX_SetupSoundBlaster + ( + fx_blaster_config blaster, + int *MaxVoices, + int *MaxSampleBits, + int *MaxChannels + ) + + { + int DeviceStatus; + BLASTER_CONFIG Blaster; + + FX_SetErrorCode( FX_Ok ); + + FX_SoundDevice = SoundBlaster; + + Blaster.Type = blaster.Type; + Blaster.Address = blaster.Address; + Blaster.Interrupt = blaster.Interrupt; + Blaster.Dma8 = blaster.Dma8; + Blaster.Dma16 = blaster.Dma16; + Blaster.Midi = blaster.Midi; + Blaster.Emu = blaster.Emu; + + BLASTER_SetCardSettings( Blaster ); + + DeviceStatus = BLASTER_Init(); + if ( DeviceStatus != BLASTER_Ok ) + { + FX_SetErrorCode( FX_SoundCardError ); + return( FX_Error ); + } + + *MaxVoices = 8; + BLASTER_GetCardInfo( MaxSampleBits, MaxChannels ); + + return( FX_Ok ); + } +#endif + + +/*--------------------------------------------------------------------- + Function: FX_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +int FX_Init + ( + int SoundCard, + int numvoices, + int numchannels, + int samplebits, + unsigned mixrate + ) + + { + int status; + int devicestatus; + + if ( FX_Installed ) + { + FX_Shutdown(); + } + + FX_MixRate = mixrate; + + status = FX_Ok; + FX_SoundDevice = SoundCard; + + devicestatus = MV_Init( SoundCard, FX_MixRate, numvoices, + numchannels, samplebits ); + if ( devicestatus != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Error; + } + + if ( status == FX_Ok ) + { + FX_Installed = TRUE; + } + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int FX_Shutdown + ( + void + ) + + { + int status; + + if ( !FX_Installed ) + { + return( FX_Ok ); + } + + status = MV_Shutdown(); + if ( status != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Error; + } + + FX_Installed = FALSE; + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetCallback + + Sets the function to call when a voice is done. +---------------------------------------------------------------------*/ + +int FX_SetCallBack + ( + void ( *function )( unsigned long ) + ) + + { + MV_SetCallBack( function ); + + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetVolume + + Sets the volume of the current sound device. +---------------------------------------------------------------------*/ + +void FX_SetVolume + ( + int volume + ) + + { + MV_SetVolume( volume ); + } + + +/*--------------------------------------------------------------------- + Function: FX_GetVolume + + Returns the volume of the current sound device. +---------------------------------------------------------------------*/ + +int FX_GetVolume + ( + void + ) + + { + return MV_GetVolume(); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void FX_SetReverseStereo + ( + int setting + ) + + { + MV_SetReverseStereo( setting ); + } + + +/*--------------------------------------------------------------------- + Function: FX_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int FX_GetReverseStereo + ( + void + ) + + { + return MV_GetReverseStereo(); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetReverb + ( + int reverb + ) + + { + MV_SetReverb( reverb ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetFastReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetFastReverb + ( + int reverb + ) + + { + MV_SetFastReverb( reverb ); + } + + +/*--------------------------------------------------------------------- + Function: FX_GetMaxReverbDelay + + Returns the maximum delay time for reverb. +---------------------------------------------------------------------*/ + +int FX_GetMaxReverbDelay + ( + void + ) + + { + return MV_GetMaxReverbDelay(); + } + + +/*--------------------------------------------------------------------- + Function: FX_GetReverbDelay + + Returns the current delay time for reverb. +---------------------------------------------------------------------*/ + +int FX_GetReverbDelay + ( + void + ) + + { + return MV_GetReverbDelay(); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void FX_SetReverbDelay + ( + int delay + ) + + { + MV_SetReverbDelay( delay ); + } + + +/*--------------------------------------------------------------------- + Function: FX_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int FX_VoiceAvailable + ( + int priority + ) + + { + return MV_VoiceAvailable( priority ); + } + +/*--------------------------------------------------------------------- + Function: FX_EndLooping + + Stops the voice associated with the specified handle from looping + without stoping the sound. +---------------------------------------------------------------------*/ + +int FX_EndLooping + ( + int handle + ) + + { + int status; + + status = MV_EndLooping( handle ); + if ( status == MV_Error ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + + return( status ); + } + +/*--------------------------------------------------------------------- + Function: FX_SetPan + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int FX_SetPan + ( + int handle, + int vol, + int left, + int right + ) + + { + int status; + + status = MV_SetPan( handle, vol, left, right ); + if ( status == MV_Error ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetPitch + + Sets the pitch of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int FX_SetPitch + ( + int handle, + int pitchoffset + ) + + { + int status; + + status = MV_SetPitch( handle, pitchoffset ); + if ( status == MV_Error ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SetFrequency + + Sets the frequency of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int FX_SetFrequency + ( + int handle, + int frequency + ) + + { + int status; + + status = MV_SetFrequency( handle, frequency ); + if ( status == MV_Error ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayVOC + ( + char *ptr, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayVOC( ptr, pitchoffset, vol, left, right, + priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedVOC + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedVOC + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayLoopedVOC( ptr, loopstart, loopend, pitchoffset, + vol, left, right, priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayWAV + ( + char *ptr, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayWAV( ptr, pitchoffset, vol, left, right, + priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedWAV + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayLoopedWAV( ptr, loopstart, loopend, + pitchoffset, vol, left, right, priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayVOC3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayVOC3D( ptr, pitchoffset, angle, distance, + priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int FX_PlayWAV3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayWAV3D( ptr, pitchoffset, angle, distance, + priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayRaw + + Begin playback of raw sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayRaw + ( + char *ptr, + unsigned long length, + unsigned rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayRaw( ptr, length, rate, pitchoffset, + vol, left, right, priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedRaw + + Begin playback of raw sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int FX_PlayLoopedRaw + ( + char *ptr, + unsigned long length, + char *loopstart, + char *loopend, + unsigned rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_PlayLoopedRaw( ptr, length, loopstart, loopend, + rate, pitchoffset, vol, left, right, priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + + +/*--------------------------------------------------------------------- + Function: FX_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int FX_Pan3D + ( + int handle, + int angle, + int distance + ) + + { + int status; + + status = MV_Pan3D( handle, angle, distance ); + if ( status != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SoundActive + + Tests if the specified sound is currently playing. +---------------------------------------------------------------------*/ + +int FX_SoundActive + ( + int handle + ) + + { + return( MV_VoicePlaying( handle ) ); + } + + +/*--------------------------------------------------------------------- + Function: FX_SoundsPlaying + + Reports the number of voices playing. +---------------------------------------------------------------------*/ + +int FX_SoundsPlaying + ( + void + ) + + { + return( MV_VoicesPlaying() ); + } + + +/*--------------------------------------------------------------------- + Function: FX_StopSound + + Halts playback of a specific voice +---------------------------------------------------------------------*/ + +int FX_StopSound + ( + int handle + ) + + { + int status; + + status = MV_Kill( handle ); + if ( status != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + return( FX_Warning ); + } + + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_StopAllSounds + + Halts playback of all sounds. +---------------------------------------------------------------------*/ + +int FX_StopAllSounds + ( + void + ) + + { + int status; + + status = MV_KillAllVoices(); + if ( status != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + return( FX_Warning ); + } + + return( FX_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: FX_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int FX_StartDemandFeedPlayback + ( + void ( *function )( char **ptr, unsigned long *length ), + int rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int handle; + + handle = MV_StartDemandFeedPlayback( function, rate, + pitchoffset, vol, left, right, priority, callbackval ); + if ( handle < MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + handle = FX_Warning; + } + + return( handle ); + } + +#if 0 +/*--------------------------------------------------------------------- + Function: FX_StartRecording + + Starts the sound recording engine. +---------------------------------------------------------------------*/ + +int FX_StartRecording + ( + int MixRate, + void ( *function )( char *ptr, int length ) + ) + + { + int status; + + switch( FX_SoundDevice ) + { + case SoundBlaster : + status = MV_StartRecording( MixRate, function ); + if ( status != MV_Ok ) + { + FX_SetErrorCode( FX_MultiVocError ); + status = FX_Warning; + } + else + { + status = FX_Ok; + } + break; + + default : + FX_SetErrorCode( FX_InvalidCard ); + status = FX_Warning; + break; + } + + return( status ); + } +#endif + +#if 0 +/*--------------------------------------------------------------------- + Function: FX_StopRecord + + Stops the sound record engine. +---------------------------------------------------------------------*/ + +void FX_StopRecord + ( + void + ) + + { + // Stop sound playback + switch( FX_SoundDevice ) + { + case SoundBlaster : + MV_StopRecord(); + break; + } + } +#endif + +extern void MUSIC_Update(void); +void AudioUpdate(void) { MUSIC_Update(); } diff --git a/polymer/eduke32/source/jaudiolib/fx_man.h b/polymer/eduke32/source/jaudiolib/fx_man.h new file mode 100644 index 000000000..f2fa2429d --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/fx_man.h @@ -0,0 +1,137 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: FX_MAN.H + + author: James R. Dose + date: March 17, 1994 + + Public header for FX_MAN.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __FX_MAN_H +#define __FX_MAN_H + +typedef struct + { + int MaxVoices; + int MaxSampleBits; + int MaxChannels; + } fx_device; + +#define MonoFx 1 +#define StereoFx 2 + +typedef struct + { + unsigned long Address; + unsigned long Type; + unsigned long Interrupt; + unsigned long Dma8; + unsigned long Dma16; + unsigned long Midi; + unsigned long Emu; + } fx_blaster_config; + +enum FX_ERRORS + { + FX_Warning = -2, + FX_Error = -1, + FX_Ok = 0, + FX_ASSVersion, + FX_BlasterError, + FX_SoundCardError, + FX_InvalidCard, + FX_MultiVocError, + FX_DPMI_Error + }; + +/* +enum fx_BLASTER_Types + { + fx_SB = 1, + fx_SBPro = 2, + fx_SB20 = 3, + fx_SBPro2 = 4, + fx_SB16 = 6 + }; +*/ + +char *FX_ErrorString( int ErrorNumber ); +//int FX_SetupCard( int SoundCard, fx_device *device ); +//int FX_GetBlasterSettings( fx_blaster_config *blaster ); +//int FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels ); +int FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate ); +int FX_Shutdown( void ); +int FX_SetCallBack( void ( *function )( unsigned long ) ); +void FX_SetVolume( int volume ); +int FX_GetVolume( void ); + +void FX_SetReverseStereo( int setting ); +int FX_GetReverseStereo( void ); +void FX_SetReverb( int reverb ); +void FX_SetFastReverb( int reverb ); +int FX_GetMaxReverbDelay( void ); +int FX_GetReverbDelay( void ); +void FX_SetReverbDelay( int delay ); + +int FX_VoiceAvailable( int priority ); +int FX_EndLooping( int handle ); +int FX_SetPan( int handle, int vol, int left, int right ); +int FX_SetPitch( int handle, int pitchoffset ); +int FX_SetFrequency( int handle, int frequency ); + +int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right, + int priority, unsigned long callbackval ); +int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right, + int priority, unsigned long callbackval ); +int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); +int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); +int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart, + char *loopend, unsigned rate, int pitchoffset, int vol, int left, + int right, int priority, unsigned long callbackval ); +int FX_Pan3D( int handle, int angle, int distance ); +int FX_SoundActive( int handle ); +int FX_SoundsPlaying( void ); +int FX_StopSound( int handle ); +int FX_StopAllSounds( void ); +int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ), + int rate, int pitchoffset, int vol, int left, int right, + int priority, unsigned long callbackval ); +int FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) ); +void FX_StopRecord( void ); + +void FX_Update(void); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/fx_man_fmod.h b/polymer/eduke32/source/jaudiolib/fx_man_fmod.h new file mode 100644 index 000000000..e1b92ae3a --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/fx_man_fmod.h @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1994 - Jim Dose +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef __FX_MAN_H +#define __FX_MAN_H + + +enum FX_ERRORS + { + FX_Warning = -2, + FX_Error = -1, + FX_Ok = 0, + FX_ASSVersion, + FX_FMODInit + }; + + +char *FX_ErrorString( int ErrorNumber ); +int FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate ); +int FX_Shutdown( void ); +int FX_SetCallBack( void ( *function )( unsigned long ) ); +void FX_SetVolume( int volume ); + +void FX_SetReverseStereo( int setting ); +int FX_GetReverseStereo( void ); +void FX_SetReverb( int reverb ); +void FX_SetReverbDelay( int delay ); + +int FX_VoiceAvailable( int priority ); + +int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); +int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); + +int FX_Pan3D( int handle, int angle, int distance ); +int FX_StopSound( int handle ); +int FX_StopAllSounds( void ); + +int FX_LoadSample(char *ptr, long size, unsigned long number, int priority); +int FX_SampleLoaded(unsigned long number); + +int FX_PlayLoopedSound(int,int,unsigned long); +int FX_PlayPositionedSound(int,int,int,unsigned long); + +int FX_SimulateCallbacks(void); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/linklist.h b/polymer/eduke32/source/jaudiolib/linklist.h new file mode 100644 index 000000000..70a7d9622 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/linklist.h @@ -0,0 +1,119 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +#ifndef __linklist_h +#define __linklist_h +#ifdef __cplusplus +extern "C" { +#endif + + +#define NewNode(type) ((type*)SafeMalloc(sizeof(type))) + + +#define LL_CreateNewLinkedList(rootnode,type,next,prev) \ + { \ + (rootnode) = NewNode(type); \ + (rootnode)->prev = (rootnode); \ + (rootnode)->next = (rootnode); \ + } + + + +#define LL_AddNode(rootnode, newnode, next, prev) \ + { \ + (newnode)->next = (rootnode); \ + (newnode)->prev = (rootnode)->prev; \ + (rootnode)->prev->next = (newnode); \ + (rootnode)->prev = (newnode); \ + } + +#define LL_TransferList(oldroot,newroot,next,prev) \ + { \ + if ((oldroot)->prev != (oldroot)) \ + { \ + (oldroot)->prev->next = (newroot); \ + (oldroot)->next->prev = (newroot)->prev; \ + (newroot)->prev->next = (oldroot)->next; \ + (newroot)->prev = (oldroot)->prev; \ + (oldroot)->next = (oldroot); \ + (oldroot)->prev = (oldroot); \ + } \ + } + +#define LL_ReverseList(root,type,next,prev) \ + { \ + type *newend,*trav,*tprev; \ + \ + newend = (root)->next; \ + for(trav = (root)->prev; trav != newend; trav = tprev) \ + { \ + tprev = trav->prev; \ + LL_MoveNode(trav,newend,next,prev); \ + } \ + } + + +#define LL_RemoveNode(node,next,prev) \ + { \ + (node)->prev->next = (node)->next; \ + (node)->next->prev = (node)->prev; \ + (node)->next = (node); \ + (node)->prev = (node); \ + } + + +#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \ + { \ + type *hoya; \ + \ + hoya = (rootnode)->next; \ + while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \ + { \ + hoya = hoya->next; \ + } \ + LL_AddNode(hoya,(insertnode),next,prev); \ + } + +#define LL_MoveNode(node,newroot,next,prev) \ + { \ + LL_RemoveNode((node),next,prev); \ + LL_AddNode((newroot),(node),next,prev); \ + } + +#define LL_ListEmpty(list,next,prev) \ + ( \ + ((list)->next == (list)) && \ + ((list)->prev == (list)) \ + ) + +#define LL_Free(list) SafeFree(list) +#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list) +#define LL_New LL_CreateNewLinkedList +#define LL_Remove LL_RemoveNode +#define LL_Add LL_AddNode +#define LL_Empty LL_ListEmpty +#define LL_Move LL_MoveNode + + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jaudiolib/ll_man.c b/polymer/eduke32/source/jaudiolib/ll_man.c new file mode 100644 index 000000000..9c169d042 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/ll_man.c @@ -0,0 +1,103 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: LL_MAN.C + + author: James R. Dose + date: January 1, 1994 + + Linked list management routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +#include "ll_man.h" + +#define OFFSET( structure, offset ) \ + ( *( ( char ** )&( structure )[ offset ] ) ) + + +/********************************************************************** + + Memory locked functions: + +**********************************************************************/ + + +void LL_AddNode + ( + char *item, + char **head, + char **tail, + int next, + int prev + ) + + { + OFFSET( item, prev ) = NULL; + OFFSET( item, next ) = *head; + + if ( *head ) + { + OFFSET( *head, prev ) = item; + } + else + { + *tail = item; + } + + *head = item; + } + +void LL_RemoveNode + ( + char *item, + char **head, + char **tail, + int next, + int prev + ) + + { + if ( OFFSET( item, prev ) == NULL ) + { + *head = OFFSET( item, next ); + } + else + { + OFFSET( OFFSET( item, prev ), next ) = OFFSET( item, next ); + } + + if ( OFFSET( item, next ) == NULL ) + { + *tail = OFFSET( item, prev ); + } + else + { + OFFSET( OFFSET( item, next ), prev ) = OFFSET( item, prev ); + } + + OFFSET( item, next ) = NULL; + OFFSET( item, prev ) = NULL; + } + + diff --git a/polymer/eduke32/source/jaudiolib/ll_man.h b/polymer/eduke32/source/jaudiolib/ll_man.h new file mode 100644 index 000000000..39f1f422e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/ll_man.h @@ -0,0 +1,75 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: LL_MAN.H + + author: James R. Dose + date: February 4, 1994 + + Public header for LL_MAN.C. Linked list management routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __LL_MAN_H +#define __LL_MAN_H + +enum LL_Errors + { + LL_Warning = -2, + LL_Error = -1, + LL_Ok = 0 + }; + +typedef struct list + { + void *start; + void *end; + } list; + +void LL_AddNode( char *node, char **head, char **tail, int next, int prev ); +void LL_RemoveNode( char *node, char **head, char **tail, int next, int prev ); + +#define LL_AddToHead( type, listhead, node ) \ + LL_AddNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->start ), \ + ( char ** )&( ( listhead )->end ), \ + ( int )&( ( type * ) 0 )->next, \ + ( int )&( ( type * ) 0 )->prev ) + +#define LL_AddToTail( type, listhead, node ) \ + LL_AddNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->end ), \ + ( char ** )&( ( listhead )->start ), \ + ( int )&( ( type * ) 0 )->prev, \ + ( int )&( ( type * ) 0 )->next ) + +#define LL_Remove( type, listhead, node ) \ + LL_RemoveNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->start ), \ + ( char ** )&( ( listhead )->end ), \ + ( int )&( ( type * ) 0 )->next, \ + ( int )&( ( type * ) 0 )->prev ) + +#define LL_NextNode( node ) ( ( node )->next ) +#define LL_PreviousNode( node ) ( ( node )->prev ) + +#endif diff --git a/polymer/eduke32/source/jaudiolib/midi.c b/polymer/eduke32/source/jaudiolib/midi.c new file mode 100644 index 000000000..2e144587c --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/midi.c @@ -0,0 +1,2048 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: MIDI.C + + author: James R. Dose + date: May 25, 1994 + + Midi song file playback routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +#include +#include "standard.h" +#include "usrhooks.h" +#include "music.h" +#include "_midi.h" +#include "midi.h" +#include "mpu401.h" + +#define WIN32_LEAN_AND_MEAN +#include + +static __int64 nexttick, tickdelta; + +extern int MUSIC_SoundDevice; + +static const int _MIDI_CommandLengths[ NUM_MIDI_CHANNELS ] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 + }; + +static int ( *_MIDI_RerouteFunctions[ NUM_MIDI_CHANNELS ] ) + ( + int event, + int c1, + int c2 + ) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + +static track *_MIDI_TrackPtr = NULL; +static int _MIDI_TrackMemSize; +static int _MIDI_NumTracks; + +static int _MIDI_SongActive = FALSE; +static int _MIDI_SongLoaded = FALSE; +static int _MIDI_Loop = FALSE; + +static int _MIDI_Division; +static int _MIDI_Tick = 0; +static int _MIDI_Beat = 1; +static int _MIDI_Measure = 1; +static unsigned _MIDI_Time; +static int _MIDI_BeatsPerMeasure; +static int _MIDI_TicksPerBeat; +static int _MIDI_TimeBase; +static long _MIDI_FPSecondsPerTick; +static unsigned _MIDI_TotalTime; +static int _MIDI_TotalTicks; +static int _MIDI_TotalBeats; +static int _MIDI_TotalMeasures; + + unsigned long _MIDI_PositionInTicks; + unsigned long _MIDI_GlobalPositionInTicks; + +static int _MIDI_Context; + +static int _MIDI_ActiveTracks; +static int _MIDI_TotalVolume = MIDI_MaxVolume; + +static int _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ]; +static int _MIDI_UserChannelVolume[ NUM_MIDI_CHANNELS ] = + { + 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256 + }; + +static midifuncs *_MIDI_Funcs = NULL; + +static int Reset = FALSE; + +int MIDI_Tempo = 120; + +char MIDI_PatchMap[ 128 ]; + + +/********************************************************************** + + Memory locked functions: + +**********************************************************************/ + + +/*--------------------------------------------------------------------- + Function: _MIDI_ReadNumber + + Reads a variable length number from a MIDI track. +---------------------------------------------------------------------*/ + +static long _MIDI_ReadNumber + ( + void *from, + size_t size + ) + + { + unsigned char *FromPtr; + long value; + + if ( size > 4 ) + { + size = 4; + } + + FromPtr = ( unsigned char * )from; + + value = 0; + while( size-- ) + { + value <<= 8; + value += *FromPtr++; + } + + return( value ); + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_ReadDelta + + Reads a variable length encoded delta delay time from the MIDI data. +---------------------------------------------------------------------*/ + +static long _MIDI_ReadDelta + ( + track *ptr + ) + + { + long value; + unsigned char c; + + GET_NEXT_EVENT( ptr, value ); + + if ( value & 0x80 ) + { + value &= 0x7f; + do + { + GET_NEXT_EVENT( ptr, c ); + value = ( value << 7 ) + ( c & 0x7f ); + } + while ( c & 0x80 ); + } + + return( value ); + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_ResetTracks + + Sets the track pointers to the beginning of the song. +---------------------------------------------------------------------*/ + +static void _MIDI_ResetTracks + ( + void + ) + + { + int i; + track *ptr; + + _MIDI_Tick = 0; + _MIDI_Beat = 1; + _MIDI_Measure = 1; + _MIDI_Time = 0; + _MIDI_BeatsPerMeasure = 4; + _MIDI_TicksPerBeat = _MIDI_Division; + _MIDI_TimeBase = 4; + + _MIDI_PositionInTicks = 0; + //_MIDI_GlobalPositionInTicks = 0; + _MIDI_ActiveTracks = 0; + _MIDI_Context = 0; + + ptr = _MIDI_TrackPtr; + for( i = 0; i < _MIDI_NumTracks; i++ ) + { + ptr->pos = ptr->start; + ptr->delay = _MIDI_ReadDelta( ptr ); + ptr->active = ptr->EMIDI_IncludeTrack; + ptr->RunningStatus = 0; + ptr->currentcontext = 0; + ptr->context[ 0 ].loopstart = ptr->start; + ptr->context[ 0 ].loopcount = 0; + + if ( ptr->active ) + { + _MIDI_ActiveTracks++; + } + + ptr++; + } + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_AdvanceTick + + Increment tick counters. +---------------------------------------------------------------------*/ + +static void _MIDI_AdvanceTick + ( + void + ) + + { + _MIDI_PositionInTicks++; + _MIDI_Time += _MIDI_FPSecondsPerTick; + + _MIDI_Tick++; + while( _MIDI_Tick > _MIDI_TicksPerBeat ) + { + _MIDI_Tick -= _MIDI_TicksPerBeat; + _MIDI_Beat++; + } + while( _MIDI_Beat > _MIDI_BeatsPerMeasure ) + { + _MIDI_Beat -= _MIDI_BeatsPerMeasure; + _MIDI_Measure++; + } + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_SysEx + + Interpret SysEx Event. +---------------------------------------------------------------------*/ + +static void _MIDI_SysEx + ( + track *Track + ) + + { + int length; + + length = _MIDI_ReadDelta( Track ); + Track->pos += length; + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_MetaEvent + + Interpret Meta Event. +---------------------------------------------------------------------*/ + +static void _MIDI_MetaEvent + ( + track *Track + ) + + { + int command; + int length; + int denominator; + long tempo; + + GET_NEXT_EVENT( Track, command ); + GET_NEXT_EVENT( Track, length ); + + switch( command ) + { + case MIDI_END_OF_TRACK : + Track->active = FALSE; + + _MIDI_ActiveTracks--; + break; + + case MIDI_TEMPO_CHANGE : + tempo = 60000000L / _MIDI_ReadNumber( Track->pos, 3 ); + MIDI_SetTempo( tempo ); + break; + + case MIDI_TIME_SIGNATURE : + if ( ( _MIDI_Tick > 0 ) || ( _MIDI_Beat > 1 ) ) + { + _MIDI_Measure++; + } + + _MIDI_Tick = 0; + _MIDI_Beat = 1; + + _MIDI_BeatsPerMeasure = (int)*Track->pos; + denominator = (int)*( Track->pos + 1 ); + _MIDI_TimeBase = 1; + while( denominator > 0 ) + { + _MIDI_TimeBase += _MIDI_TimeBase; + denominator--; + } + _MIDI_TicksPerBeat = ( _MIDI_Division * 4 ) / _MIDI_TimeBase; + break; + } + + Track->pos += length; + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_InterpretControllerInfo + + Interprets the MIDI controller info. +---------------------------------------------------------------------*/ + +static int _MIDI_InterpretControllerInfo + ( + track *Track, + int TimeSet, + int channel, + int c1, + int c2 + ) + + { + track *trackptr; + int tracknum; + int loopcount; + + switch( c1 ) + { + case MIDI_MONO_MODE_ON : + Track->pos++; + break; + + case MIDI_VOLUME : + if ( !Track->EMIDI_VolumeChange ) + { + _MIDI_SetChannelVolume( channel, c2 ); + } + break; + + case EMIDI_INCLUDE_TRACK : + case EMIDI_EXCLUDE_TRACK : + break; + + case EMIDI_PROGRAM_CHANGE : + if ( Track->EMIDI_ProgramChange ) + { + _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] ); + } + break; + + case EMIDI_VOLUME_CHANGE : + if ( Track->EMIDI_VolumeChange ) + { + _MIDI_SetChannelVolume( channel, c2 ); + } + break; + + case EMIDI_CONTEXT_START : + break; + + case EMIDI_CONTEXT_END : + if ( ( Track->currentcontext == _MIDI_Context ) || + ( _MIDI_Context < 0 ) || + ( Track->context[ _MIDI_Context ].pos == NULL ) ) + { + break; + } + + Track->currentcontext = _MIDI_Context; + Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; + Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; + Track->pos = Track->context[ _MIDI_Context ].pos; + Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; + + if ( TimeSet ) + { + break; + } + + _MIDI_Time = Track->context[ _MIDI_Context ].time; + _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; + _MIDI_Tick = Track->context[ _MIDI_Context ].tick; + _MIDI_Beat = Track->context[ _MIDI_Context ].beat; + _MIDI_Measure = Track->context[ _MIDI_Context ].measure; + _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; + _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; + _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; + TimeSet = TRUE; + break; + + case EMIDI_LOOP_START : + case EMIDI_SONG_LOOP_START : + if ( c2 == 0 ) + { + loopcount = EMIDI_INFINITE; + } + else + { + loopcount = c2; + } + + if ( c1 == EMIDI_SONG_LOOP_START ) + { + trackptr = _MIDI_TrackPtr; + tracknum = _MIDI_NumTracks; + } + else + { + trackptr = Track; + tracknum = 1; + } + + while( tracknum > 0 ) + { + trackptr->context[ 0 ].loopcount = loopcount; + trackptr->context[ 0 ].pos = trackptr->pos; + trackptr->context[ 0 ].loopstart = trackptr->pos; + trackptr->context[ 0 ].RunningStatus = trackptr->RunningStatus; + trackptr->context[ 0 ].active = trackptr->active; + trackptr->context[ 0 ].delay = trackptr->delay; + trackptr->context[ 0 ].time = _MIDI_Time; + trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; + trackptr->context[ 0 ].tick = _MIDI_Tick; + trackptr->context[ 0 ].beat = _MIDI_Beat; + trackptr->context[ 0 ].measure = _MIDI_Measure; + trackptr->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; + trackptr->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; + trackptr->context[ 0 ].TimeBase = _MIDI_TimeBase; + trackptr++; + tracknum--; + } + break; + + case EMIDI_LOOP_END : + case EMIDI_SONG_LOOP_END : + if ( ( c2 != EMIDI_END_LOOP_VALUE ) || + ( Track->context[ 0 ].loopstart == NULL ) || + ( Track->context[ 0 ].loopcount == 0 ) ) + { + break; + } + + if ( c1 == EMIDI_SONG_LOOP_END ) + { + trackptr = _MIDI_TrackPtr; + tracknum = _MIDI_NumTracks; + _MIDI_ActiveTracks = 0; + } + else + { + trackptr = Track; + tracknum = 1; + _MIDI_ActiveTracks--; + } + + while( tracknum > 0 ) + { + if ( trackptr->context[ 0 ].loopcount != EMIDI_INFINITE ) + { + trackptr->context[ 0 ].loopcount--; + } + + trackptr->pos = trackptr->context[ 0 ].loopstart; + trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus; + trackptr->delay = trackptr->context[ 0 ].delay; + trackptr->active = trackptr->context[ 0 ].active; + if ( trackptr->active ) + { + _MIDI_ActiveTracks++; + } + + if ( !TimeSet ) + { + _MIDI_Time = trackptr->context[ 0 ].time; + _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick; + _MIDI_Tick = trackptr->context[ 0 ].tick; + _MIDI_Beat = trackptr->context[ 0 ].beat; + _MIDI_Measure = trackptr->context[ 0 ].measure; + _MIDI_BeatsPerMeasure = trackptr->context[ 0 ].BeatsPerMeasure; + _MIDI_TicksPerBeat = trackptr->context[ 0 ].TicksPerBeat; + _MIDI_TimeBase = trackptr->context[ 0 ].TimeBase; + TimeSet = TRUE; + } + + trackptr++; + tracknum--; + } + break; + + default : + if ( _MIDI_Funcs->ControlChange ) + { + _MIDI_Funcs->ControlChange( channel, c1, c2 ); + } + } + + return TimeSet; + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_ServiceRoutine + + Task that interperates the MIDI data. +---------------------------------------------------------------------*/ + +static int _MIDI_ServiceRoutine ( void ) +{ + int event; + int channel; + int command; + track *Track; + int tracknum; + int status; + int c1; + int c2; + int TimeSet = FALSE; + + if ( _MIDI_SongActive ) { + Track = _MIDI_TrackPtr; + tracknum = 0; + while( tracknum < _MIDI_NumTracks ) { + while ( ( Track->active ) && ( Track->delay == 0 ) ) { + GET_NEXT_EVENT( Track, event ); + + if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL ) { + switch( event ) { + case MIDI_SYSEX : + case MIDI_SYSEX_CONTINUE : + _MIDI_SysEx( Track ); + break; + + case MIDI_META_EVENT : + _MIDI_MetaEvent( Track ); + break; + } + + if ( Track->active ) { + Track->delay = _MIDI_ReadDelta( Track ); + } + continue; + } + + if ( event & MIDI_RUNNING_STATUS ) { + Track->RunningStatus = event; + } else { + event = Track->RunningStatus; + Track->pos--; + } + + channel = GET_MIDI_CHANNEL( event ); + command = GET_MIDI_COMMAND( event ); + + if ( _MIDI_CommandLengths[ command ] > 0 ) { + GET_NEXT_EVENT( Track, c1 ); + if ( _MIDI_CommandLengths[ command ] > 1 ) { + GET_NEXT_EVENT( Track, c2 ); + } + } + + if ( _MIDI_RerouteFunctions[ channel ] != NULL ) { + status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 ); + + if ( status == MIDI_DONT_PLAY ) { + Track->delay = _MIDI_ReadDelta( Track ); + continue; + } + } + + switch ( command ) { + case MIDI_NOTE_OFF : + if ( _MIDI_Funcs->NoteOff ) { + _MIDI_Funcs->NoteOff( channel, c1, c2 ); + } + break; + + case MIDI_NOTE_ON : + if ( _MIDI_Funcs->NoteOn ) { + _MIDI_Funcs->NoteOn( channel, c1, c2 ); + } + break; + + case MIDI_POLY_AFTER_TCH : + if ( _MIDI_Funcs->PolyAftertouch ) { + _MIDI_Funcs->PolyAftertouch( channel, c1, c2 ); + } + break; + + case MIDI_CONTROL_CHANGE : + TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet, channel, c1, c2 ); + break; + + case MIDI_PROGRAM_CHANGE : + if ( ( _MIDI_Funcs->ProgramChange ) && ( !Track->EMIDI_ProgramChange ) ) { + _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c1 & 0x7f ] ); + } + break; + + case MIDI_AFTER_TOUCH : + if ( _MIDI_Funcs->ChannelAftertouch ) { + _MIDI_Funcs->ChannelAftertouch( channel, c1 ); + } + break; + + case MIDI_PITCH_BEND : + if ( _MIDI_Funcs->PitchBend ) { + _MIDI_Funcs->PitchBend( channel, c1, c2 ); + } + break; + + default : + break; + } + + Track->delay = _MIDI_ReadDelta( Track ); + } + + Track->delay--; + Track++; + tracknum++; + + if ( _MIDI_ActiveTracks == 0 ) { + _MIDI_ResetTracks(); + if ( _MIDI_Loop ) { + tracknum = 0; + Track = _MIDI_TrackPtr; + } else { + _MIDI_SongActive = FALSE; + break; + } + } + } + + _MIDI_AdvanceTick(); + _MIDI_GlobalPositionInTicks++; + } + return 0; +} + + +/*--------------------------------------------------------------------- + Function: _MIDI_SendControlChange + + Sends a control change to the proper device +---------------------------------------------------------------------*/ + +static int _MIDI_SendControlChange + ( + int channel, + int c1, + int c2 + ) + + { + int status; + + if ( _MIDI_RerouteFunctions[ channel ] != NULL ) + { + status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel, + c1, c2 ); + if ( status == MIDI_DONT_PLAY ) + { + return( MIDI_Ok ); + } + } + + if ( _MIDI_Funcs == NULL ) + { + return( MIDI_Error ); + } + + if ( _MIDI_Funcs->ControlChange == NULL ) + { + return( MIDI_Error ); + } + + _MIDI_Funcs->ControlChange( channel, c1, c2 ); + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_RerouteMidiChannel + + Sets callback function to reroute MIDI commands from specified + function. +---------------------------------------------------------------------*/ + +void MIDI_RerouteMidiChannel + ( + int channel, + int ( *function )( int event, int c1, int c2 ) + ) + + { + if ( ( channel >= 1 ) && ( channel <= 16 ) ) + { + _MIDI_RerouteFunctions[ channel - 1 ] = function; + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_AllNotesOff + + Sends all notes off commands on all midi channels. +---------------------------------------------------------------------*/ + +int MIDI_AllNotesOff + ( + void + ) + + { + int channel; + + for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ ) + { + _MIDI_SendControlChange( channel, 0x40, 0 ); + _MIDI_SendControlChange( channel, MIDI_ALL_NOTES_OFF, 0 ); + _MIDI_SendControlChange( channel, 0x78, 0 ); + } + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_SetChannelVolume + + Sets the volume of the specified midi channel. +---------------------------------------------------------------------*/ + +static void _MIDI_SetChannelVolume + ( + int channel, + int volume + ) + + { + int status; + int remotevolume; + + _MIDI_ChannelVolume[ channel ] = volume; + + if ( _MIDI_RerouteFunctions[ channel ] != NULL ) + { + remotevolume = volume * _MIDI_TotalVolume; + remotevolume *= _MIDI_UserChannelVolume[ channel ]; + remotevolume /= MIDI_MaxVolume; + remotevolume >>= 8; + + status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel, + MIDI_VOLUME, remotevolume ); + if ( status == MIDI_DONT_PLAY ) + { + return; + } + } + + if ( _MIDI_Funcs == NULL ) + { + return; + } + + if ( _MIDI_Funcs->ControlChange == NULL ) + { + return; + } + + // For user volume + volume *= _MIDI_UserChannelVolume[ channel ]; + + if ( _MIDI_Funcs->SetVolume == NULL ) + { + volume *= _MIDI_TotalVolume; + volume /= MIDI_MaxVolume; + } + + // For user volume + volume >>= 8; + + _MIDI_Funcs->ControlChange( channel, MIDI_VOLUME, volume ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetUserChannelVolume + + Sets the volume of the specified midi channel. +---------------------------------------------------------------------*/ + +void MIDI_SetUserChannelVolume + ( + int channel, + int volume + ) + + { + // Convert channel from 1-16 to 0-15 + channel--; + + volume = max( 0, volume ); + volume = min( volume, 256 ); + + if ( ( channel >= 0 ) && ( channel < NUM_MIDI_CHANNELS ) ) + { + _MIDI_UserChannelVolume[ channel ] = volume; + _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] ); + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_ResetUserChannelVolume + + Sets the volume of the specified midi channel. +---------------------------------------------------------------------*/ + +void MIDI_ResetUserChannelVolume + ( + void + ) + + { + int channel; + + for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ ) + { + _MIDI_UserChannelVolume[ channel ] = 256; + } + + _MIDI_SendChannelVolumes(); + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_SendChannelVolumes + + Sets the volume on all the midi channels. +---------------------------------------------------------------------*/ + +static void _MIDI_SendChannelVolumes + ( + void + ) + + { + int channel; + + for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ ) + { + _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] ); + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_Reset + + Resets the MIDI device to General Midi defaults. +---------------------------------------------------------------------*/ + +int MIDI_Reset + ( + void + ) + + { + int channel; + long time; + unsigned flags; + + MIDI_AllNotesOff(); + + for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ ) + { + _MIDI_SendControlChange( channel, MIDI_RESET_ALL_CONTROLLERS, 0 ); + _MIDI_SendControlChange( channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB ); + _MIDI_SendControlChange( channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB ); + _MIDI_SendControlChange( channel, MIDI_DATAENTRY_MSB, 2 ); /* Pitch Bend Sensitivity MSB */ + _MIDI_SendControlChange( channel, MIDI_DATAENTRY_LSB, 0 ); /* Pitch Bend Sensitivity LSB */ + _MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume; + } + + _MIDI_SendChannelVolumes(); + + Reset = TRUE; + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetVolume + + Sets the total volume of the music. +---------------------------------------------------------------------*/ + +int MIDI_SetVolume + ( + int volume + ) + + { + int i; + + if ( _MIDI_Funcs == NULL ) + { + return( MIDI_NullMidiModule ); + } + + volume = min( MIDI_MaxVolume, volume ); + volume = max( 0, volume ); + + _MIDI_TotalVolume = volume; + + if ( _MIDI_Funcs->SetVolume ) + { + _MIDI_Funcs->SetVolume( volume ); + + for( i = 0; i < NUM_MIDI_CHANNELS; i++ ) + { + if ( _MIDI_RerouteFunctions[ i ] != NULL ) + { + _MIDI_SetChannelVolume( i, _MIDI_ChannelVolume[ i ] ); + } + } + } + else + { + _MIDI_SendChannelVolumes(); + } + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_GetVolume + + Returns the total volume of the music. +---------------------------------------------------------------------*/ + +int MIDI_GetVolume + ( + void + ) + + { + int volume; + + if ( _MIDI_Funcs == NULL ) + { + return( MIDI_NullMidiModule ); + } + + if ( _MIDI_Funcs->GetVolume ) + { + volume = _MIDI_Funcs->GetVolume(); + } + else + { + volume = _MIDI_TotalVolume; + } + + return( volume ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetContext + + Sets the song context. +---------------------------------------------------------------------*/ + +void MIDI_SetContext + ( + int context + ) + + { + if ( ( context > 0 ) && ( context < EMIDI_NUM_CONTEXTS ) ) + { + _MIDI_Context = context; + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_GetContext + + Returns the current song context. +---------------------------------------------------------------------*/ + +int MIDI_GetContext + ( + void + ) + + { + return _MIDI_Context; + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetLoopFlag + + Sets whether the song should loop when finished or not. +---------------------------------------------------------------------*/ + +void MIDI_SetLoopFlag + ( + int loopflag + ) + + { + _MIDI_Loop = loopflag; + } + + +/*--------------------------------------------------------------------- + Function: MIDI_ContinueSong + + Continues playback of a paused song. +---------------------------------------------------------------------*/ + +void MIDI_ContinueSong + ( + void + ) + + { + if ( _MIDI_SongLoaded ) + { + _MIDI_SongActive = TRUE; + MPU_Unpause(); + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_PauseSong + + Pauses playback of the current song. +---------------------------------------------------------------------*/ + +void MIDI_PauseSong + ( + void + ) + + { + if ( _MIDI_SongLoaded ) + { + _MIDI_SongActive = FALSE; + MIDI_AllNotesOff(); + MPU_Pause(); + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SongPlaying + + Returns whether a song is playing or not. +---------------------------------------------------------------------*/ + +int MIDI_SongPlaying + ( + void + ) + + { + return( _MIDI_SongActive ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetMidiFuncs + + Selects the routines that send the MIDI data to the music device. +---------------------------------------------------------------------*/ + +void MIDI_SetMidiFuncs + ( + midifuncs *funcs + ) + + { + _MIDI_Funcs = funcs; + } + + +/*--------------------------------------------------------------------- + Function: MIDI_StopSong + + Stops playback of the currently playing song. +---------------------------------------------------------------------*/ + +void MIDI_StopSong + ( + void + ) + + { + if ( _MIDI_SongLoaded ) + { + _MIDI_SongActive = FALSE; + _MIDI_SongLoaded = FALSE; + + MIDI_Reset(); + _MIDI_ResetTracks(); + + if ( _MIDI_Funcs->ReleasePatches ) + { + _MIDI_Funcs->ReleasePatches(); + } + + USRHOOKS_FreeMem( _MIDI_TrackPtr ); + + _MIDI_TrackPtr = NULL; + _MIDI_NumTracks = 0; + _MIDI_TrackMemSize = 0; + + _MIDI_TotalTime = 0; + _MIDI_TotalTicks = 0; + _MIDI_TotalBeats = 0; + _MIDI_TotalMeasures = 0; + + MPU_Reset(); + } + } + + +/*--------------------------------------------------------------------- + Function: MIDI_PlaySong + + Begins playback of a MIDI song. +---------------------------------------------------------------------*/ + +int MIDI_PlaySong + ( + unsigned char *song, + int loopflag + ) + + { + int numtracks; + int format; + long headersize; + long tracklength; + track *CurrentTrack; + unsigned char *ptr; + int status; + DWORD i; + + if ( _MIDI_SongLoaded ) + { + MIDI_StopSong(); + } + + MPU_Init(MUSIC_SoundDevice); + + _MIDI_Loop = loopflag; + + if ( _MIDI_Funcs == NULL ) + { + return( MIDI_NullMidiModule ); + } + + if ( *( unsigned long * )song != MIDI_HEADER_SIGNATURE ) + { + return( MIDI_InvalidMidiFile ); + } + + song += 4; + + headersize = _MIDI_ReadNumber( song, 4 ); + song += 4; + format = _MIDI_ReadNumber( song, 2 ); + _MIDI_NumTracks = _MIDI_ReadNumber( song + 2, 2 ); + _MIDI_Division = _MIDI_ReadNumber( song + 4, 2 ); + if ( _MIDI_Division < 0 ) + { + // If a SMPTE time division is given, just set to 96 so no errors occur + _MIDI_Division = 96; + } + + if ( format > MAX_FORMAT ) + { + return( MIDI_UnknownMidiFormat ); + } + + ptr = song + headersize; + + if ( _MIDI_NumTracks == 0 ) + { + return( MIDI_NoTracks ); + } + + _MIDI_TrackMemSize = _MIDI_NumTracks * sizeof( track ); + status = USRHOOKS_GetMem( (void**)&_MIDI_TrackPtr, _MIDI_TrackMemSize ); + if ( status != USRHOOKS_Ok ) + { + return( MIDI_NoMemory ); + } + + CurrentTrack = _MIDI_TrackPtr; + numtracks = _MIDI_NumTracks; + while( numtracks-- ) + { + if ( *( unsigned long * )ptr != MIDI_TRACK_SIGNATURE ) + { + USRHOOKS_FreeMem( _MIDI_TrackPtr ); + + _MIDI_TrackPtr = NULL; + _MIDI_TrackMemSize = 0; + + return( MIDI_InvalidTrack ); + } + + tracklength = _MIDI_ReadNumber( ptr + 4, 4 ); + ptr += 8; + CurrentTrack->start = ptr; + ptr += tracklength; + CurrentTrack++; + } + + if ( _MIDI_Funcs->GetVolume != NULL ) + { + _MIDI_TotalVolume = _MIDI_Funcs->GetVolume(); + } + + _MIDI_InitEMIDI(); + + if ( _MIDI_Funcs->LoadPatch ) + { + MIDI_LoadTimbres(); + } + + _MIDI_ResetTracks(); + + if ( !Reset ) + { + MIDI_Reset(); + } + + Reset = FALSE; + + MIDI_SetDivision( _MIDI_Division ); + //MIDI_SetTempo( 120 ); + + _MIDI_SongLoaded = TRUE; + _MIDI_SongActive = TRUE; + + while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); + MPU_BeginPlayback(); + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetTempo + + Sets the song tempo. +---------------------------------------------------------------------*/ + +void MIDI_SetTempo + ( + int tempo + ) + + { + long tickspersecond; + + MIDI_Tempo = tempo; + tickspersecond = ( ( tempo ) * _MIDI_Division ) / 60; + _MIDI_FPSecondsPerTick = ( 1 << TIME_PRECISION ) / tickspersecond; + MPU_SetTempo(tempo); + } + +void MIDI_SetDivision(int division) +{ + MPU_SetDivision(division); +} + + +/*--------------------------------------------------------------------- + Function: MIDI_GetTempo + + Returns the song tempo. +---------------------------------------------------------------------*/ + +int MIDI_GetTempo + ( + void + ) + + { + return( MIDI_Tempo ); + } + + +/*--------------------------------------------------------------------- + Function: _MIDI_ProcessNextTick + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +static int _MIDI_ProcessNextTick + ( + void + ) + + { + int event; + int channel; + int command; + track *Track; + int tracknum; + int status; + int c1; + int c2; + int TimeSet = FALSE; + + Track = _MIDI_TrackPtr; + tracknum = 0; + while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) ) + { + while ( ( Track->active ) && ( Track->delay == 0 ) ) + { + GET_NEXT_EVENT( Track, event ); + + if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL ) + { + switch( event ) + { + case MIDI_SYSEX : + case MIDI_SYSEX_CONTINUE : + _MIDI_SysEx( Track ); + break; + + case MIDI_META_EVENT : + _MIDI_MetaEvent( Track ); + break; + } + + if ( Track->active ) + { + Track->delay = _MIDI_ReadDelta( Track ); + } + + continue; + } + + if ( event & MIDI_RUNNING_STATUS ) + { + Track->RunningStatus = event; + } + else + { + event = Track->RunningStatus; + Track->pos--; + } + + channel = GET_MIDI_CHANNEL( event ); + command = GET_MIDI_COMMAND( event ); + + if ( _MIDI_CommandLengths[ command ] > 0 ) + { + GET_NEXT_EVENT( Track, c1 ); + if ( _MIDI_CommandLengths[ command ] > 1 ) + { + GET_NEXT_EVENT( Track, c2 ); + } + } + + if ( _MIDI_RerouteFunctions[ channel ] != NULL ) + { + status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 ); + + if ( status == MIDI_DONT_PLAY ) + { + Track->delay = _MIDI_ReadDelta( Track ); + continue; + } + } + + switch ( command ) + { + case MIDI_NOTE_OFF : + break; + + case MIDI_NOTE_ON : + break; + + case MIDI_POLY_AFTER_TCH : + if ( _MIDI_Funcs->PolyAftertouch ) + { + _MIDI_Funcs->PolyAftertouch( channel, c1, c2 ); + } + break; + + case MIDI_CONTROL_CHANGE : + TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet, + channel, c1, c2 ); + break; + + case MIDI_PROGRAM_CHANGE : + if ( ( _MIDI_Funcs->ProgramChange ) && + ( !Track->EMIDI_ProgramChange ) ) + { + _MIDI_Funcs->ProgramChange( channel, c1 ); + } + break; + + case MIDI_AFTER_TOUCH : + if ( _MIDI_Funcs->ChannelAftertouch ) + { + _MIDI_Funcs->ChannelAftertouch( channel, c1 ); + } + break; + + case MIDI_PITCH_BEND : + if ( _MIDI_Funcs->PitchBend ) + { + _MIDI_Funcs->PitchBend( channel, c1, c2 ); + } + break; + + default : + break; + } + + Track->delay = _MIDI_ReadDelta( Track ); + } + + Track->delay--; + Track++; + tracknum++; + + if ( _MIDI_ActiveTracks == 0 ) + { + break; + } + } + + _MIDI_AdvanceTick(); + + return( TimeSet ); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetSongTick + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MIDI_SetSongTick + ( + unsigned long PositionInTicks + ) + + { + if ( !_MIDI_SongLoaded ) + { + return; + } + + MIDI_PauseSong(); + + if ( PositionInTicks < _MIDI_PositionInTicks ) + { + _MIDI_ResetTracks(); + MIDI_Reset(); + } + + while( _MIDI_PositionInTicks < PositionInTicks ) + { + if ( _MIDI_ProcessNextTick() ) + { + break; + } + if ( _MIDI_ActiveTracks == 0 ) + { + _MIDI_ResetTracks(); + if ( !_MIDI_Loop ) + { + return; + } + break; + } + } + + MIDI_SetVolume( _MIDI_TotalVolume ); + MIDI_ContinueSong(); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetSongTime + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MIDI_SetSongTime + ( + unsigned long milliseconds + ) + + { + unsigned long mil; + unsigned long sec; + unsigned long newtime; + + if ( !_MIDI_SongLoaded ) + { + return; + } + + MIDI_PauseSong(); + + mil = ( ( milliseconds % 1000 ) << TIME_PRECISION ) / 1000; + sec = ( milliseconds / 1000 ) << TIME_PRECISION; + newtime = sec + mil; + + if ( newtime < _MIDI_Time ) + { + _MIDI_ResetTracks(); + MIDI_Reset(); + } + + while( _MIDI_Time < newtime ) + { + if ( _MIDI_ProcessNextTick() ) + { + break; + } + if ( _MIDI_ActiveTracks == 0 ) + { + _MIDI_ResetTracks(); + if ( !_MIDI_Loop ) + { + return; + } + break; + } + } + + MIDI_SetVolume( _MIDI_TotalVolume ); + MIDI_ContinueSong(); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_SetSongPosition + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MIDI_SetSongPosition + ( + int measure, + int beat, + int tick + ) + + { + unsigned long pos; + + if ( !_MIDI_SongLoaded ) + { + return; + } + + MIDI_PauseSong(); + + pos = RELATIVE_BEAT( measure, beat, tick ); + + if ( pos < (unsigned long)RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) ) + { + _MIDI_ResetTracks(); + MIDI_Reset(); + } + + while( (unsigned long)RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) < pos ) + { + if ( _MIDI_ProcessNextTick() ) + { + break; + } + if ( _MIDI_ActiveTracks == 0 ) + { + _MIDI_ResetTracks(); + if ( !_MIDI_Loop ) + { + return; + } + break; + } + } + + MIDI_SetVolume( _MIDI_TotalVolume ); + MIDI_ContinueSong(); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_GetSongPosition + + Returns the position of the song pointer in Measures, beats, ticks. +---------------------------------------------------------------------*/ + +void MIDI_GetSongPosition + ( + songposition *pos + ) + + { + unsigned long mil; + unsigned long sec; + + mil = ( _MIDI_Time & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000; + sec = _MIDI_Time >> TIME_PRECISION; + pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 ); + pos->tickposition = _MIDI_PositionInTicks; + pos->measure = _MIDI_Measure; + pos->beat = _MIDI_Beat; + pos->tick = _MIDI_Tick; + } + + +/*--------------------------------------------------------------------- + Function: MIDI_GetSongLength + + Returns the length of the song. +---------------------------------------------------------------------*/ + +void MIDI_GetSongLength + ( + songposition *pos + ) + + { + unsigned long mil; + unsigned long sec; + + mil = ( _MIDI_TotalTime & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000; + sec = _MIDI_TotalTime >> TIME_PRECISION; + + pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 ); + pos->measure = _MIDI_TotalMeasures; + pos->beat = _MIDI_TotalBeats; + pos->tick = _MIDI_TotalTicks; + pos->tickposition = 0; + } + + +/*--------------------------------------------------------------------- + Function: MIDI_InitEMIDI + + Sets up the EMIDI +---------------------------------------------------------------------*/ + +static void _MIDI_InitEMIDI + ( + void + ) + + { + int event; + int command; + int channel; + int length; + int IncludeFound; + track *Track; + int tracknum; + int type; + int c1; + int c2; + + type = EMIDI_GeneralMIDI; + + _MIDI_ResetTracks(); + + _MIDI_TotalTime = 0; + _MIDI_TotalTicks = 0; + _MIDI_TotalBeats = 0; + _MIDI_TotalMeasures = 0; + + Track = _MIDI_TrackPtr; + tracknum = 0; + while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) ) + { + _MIDI_Tick = 0; + _MIDI_Beat = 1; + _MIDI_Measure = 1; + _MIDI_Time = 0; + _MIDI_BeatsPerMeasure = 4; + _MIDI_TicksPerBeat = _MIDI_Division; + _MIDI_TimeBase = 4; + + _MIDI_PositionInTicks = 0; + _MIDI_ActiveTracks = 0; + _MIDI_Context = -1; + + Track->RunningStatus = 0; + Track->active = TRUE; + + Track->EMIDI_ProgramChange = FALSE; + Track->EMIDI_VolumeChange = FALSE; + Track->EMIDI_IncludeTrack = TRUE; + + memset( Track->context, 0, sizeof( Track->context ) ); + + while( Track->delay > 0 ) + { + _MIDI_AdvanceTick(); + Track->delay--; + } + + IncludeFound = FALSE; + while ( Track->active ) + { + GET_NEXT_EVENT( Track, event ); + + if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL ) + { + switch( event ) + { + case MIDI_SYSEX : + case MIDI_SYSEX_CONTINUE : + _MIDI_SysEx( Track ); + break; + + case MIDI_META_EVENT : + _MIDI_MetaEvent( Track ); + break; + } + + if ( Track->active ) + { + Track->delay = _MIDI_ReadDelta( Track ); + while( Track->delay > 0 ) + { + _MIDI_AdvanceTick(); + Track->delay--; + } + } + + continue; + } + + if ( event & MIDI_RUNNING_STATUS ) + { + Track->RunningStatus = event; + } + else + { + event = Track->RunningStatus; + Track->pos--; + } + + channel = GET_MIDI_CHANNEL( event ); + command = GET_MIDI_COMMAND( event ); + length = _MIDI_CommandLengths[ command ]; + + if ( command == MIDI_CONTROL_CHANGE ) + { + if ( *Track->pos == MIDI_MONO_MODE_ON ) + { + length++; + } + GET_NEXT_EVENT( Track, c1 ); + GET_NEXT_EVENT( Track, c2 ); + length -= 2; + + switch( c1 ) + { + case EMIDI_LOOP_START : + case EMIDI_SONG_LOOP_START : + if ( c2 == 0 ) + { + Track->context[ 0 ].loopcount = EMIDI_INFINITE; + } + else + { + Track->context[ 0 ].loopcount = c2; + } + + Track->context[ 0 ].pos = Track->pos; + Track->context[ 0 ].loopstart = Track->pos; + Track->context[ 0 ].RunningStatus = Track->RunningStatus; + Track->context[ 0 ].time = _MIDI_Time; + Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; + Track->context[ 0 ].tick = _MIDI_Tick; + Track->context[ 0 ].beat = _MIDI_Beat; + Track->context[ 0 ].measure = _MIDI_Measure; + Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; + Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; + Track->context[ 0 ].TimeBase = _MIDI_TimeBase; + break; + + case EMIDI_LOOP_END : + case EMIDI_SONG_LOOP_END : + if ( c2 == EMIDI_END_LOOP_VALUE ) + { + Track->context[ 0 ].loopstart = NULL; + Track->context[ 0 ].loopcount = 0; + } + break; + + case EMIDI_INCLUDE_TRACK : + if ( EMIDI_AffectsCurrentCard( c2, type ) ) + { + //printf( "Include track %d on card %d\n", tracknum, c2 ); + IncludeFound = TRUE; + Track->EMIDI_IncludeTrack = TRUE; + } + else if ( !IncludeFound ) + { + //printf( "Track excluded %d on card %d\n", tracknum, c2 ); + IncludeFound = TRUE; + Track->EMIDI_IncludeTrack = FALSE; + } + break; + + case EMIDI_EXCLUDE_TRACK : + if ( EMIDI_AffectsCurrentCard( c2, type ) ) + { + //printf( "Exclude track %d on card %d\n", tracknum, c2 ); + Track->EMIDI_IncludeTrack = FALSE; + } + break; + + case EMIDI_PROGRAM_CHANGE : + if ( !Track->EMIDI_ProgramChange ) + //printf( "Program change on track %d\n", tracknum ); + Track->EMIDI_ProgramChange = TRUE; + break; + + case EMIDI_VOLUME_CHANGE : + if ( !Track->EMIDI_VolumeChange ) + //printf( "Volume change on track %d\n", tracknum ); + Track->EMIDI_VolumeChange = TRUE; + break; + + case EMIDI_CONTEXT_START : + if ( ( c2 > 0 ) && ( c2 < EMIDI_NUM_CONTEXTS ) ) + { + Track->context[ c2 ].pos = Track->pos; + Track->context[ c2 ].loopstart = Track->context[ 0 ].loopstart; + Track->context[ c2 ].loopcount = Track->context[ 0 ].loopcount; + Track->context[ c2 ].RunningStatus = Track->RunningStatus; + Track->context[ c2 ].time = _MIDI_Time; + Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; + Track->context[ c2 ].tick = _MIDI_Tick; + Track->context[ c2 ].beat = _MIDI_Beat; + Track->context[ c2 ].measure = _MIDI_Measure; + Track->context[ c2 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; + Track->context[ c2 ].TicksPerBeat = _MIDI_TicksPerBeat; + Track->context[ c2 ].TimeBase = _MIDI_TimeBase; + } + break; + + case EMIDI_CONTEXT_END : + break; + } + } + + Track->pos += length; + Track->delay = _MIDI_ReadDelta( Track ); + + while( Track->delay > 0 ) + { + _MIDI_AdvanceTick(); + Track->delay--; + } + } + + _MIDI_TotalTime = max( _MIDI_TotalTime, _MIDI_Time ); + if ( RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) > + RELATIVE_BEAT( _MIDI_TotalMeasures, _MIDI_TotalBeats, + _MIDI_TotalTicks ) ) + { + _MIDI_TotalTicks = _MIDI_Tick; + _MIDI_TotalBeats = _MIDI_Beat; + _MIDI_TotalMeasures = _MIDI_Measure; + } + + Track++; + tracknum++; + } + + _MIDI_ResetTracks(); + } + + +/*--------------------------------------------------------------------- + Function: MIDI_LoadTimbres + + Preloads the timbres on cards that use patch-caching. +---------------------------------------------------------------------*/ + +void MIDI_LoadTimbres + ( + void + ) + + { + int event; + int command; + int channel; + int length; + int Finished; + track *Track; + int tracknum; + + Track = _MIDI_TrackPtr; + tracknum = 0; + while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) ) + { + Finished = FALSE; + while ( !Finished ) + { + GET_NEXT_EVENT( Track, event ); + + if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL ) + { + switch( event ) + { + case MIDI_SYSEX : + case MIDI_SYSEX_CONTINUE : + length = _MIDI_ReadDelta( Track ); + Track->pos += length; + break; + + case MIDI_META_EVENT : + GET_NEXT_EVENT( Track, command ); + GET_NEXT_EVENT( Track, length ); + + if ( command == MIDI_END_OF_TRACK ) + { + Finished = TRUE; + } + + Track->pos += length; + break; + } + + if ( !Finished ) + { + _MIDI_ReadDelta( Track ); + } + + continue; + } + + if ( event & MIDI_RUNNING_STATUS ) + { + Track->RunningStatus = event; + } + else + { + event = Track->RunningStatus; + Track->pos--; + } + + channel = GET_MIDI_CHANNEL( event ); + command = GET_MIDI_COMMAND( event ); + length = _MIDI_CommandLengths[ command ]; + + if ( command == MIDI_CONTROL_CHANGE ) + { + if ( *Track->pos == MIDI_MONO_MODE_ON ) + { + length++; + } + + if ( *Track->pos == EMIDI_PROGRAM_CHANGE ) + { + _MIDI_Funcs->LoadPatch( *( Track->pos + 1 ) ); + } + } + + if ( channel == MIDI_RHYTHM_CHANNEL ) + { + if ( command == MIDI_NOTE_ON ) + { + _MIDI_Funcs->LoadPatch( 128 + *Track->pos ); + } + } + else + { + if ( command == MIDI_PROGRAM_CHANGE ) + { + _MIDI_Funcs->LoadPatch( *Track->pos ); + } + } + Track->pos += length; + _MIDI_ReadDelta( Track ); + } + Track++; + tracknum++; + } + + _MIDI_ResetTracks(); + } + + +void MIDI_UpdateMusic(void) +{ + if (!_MIDI_SongLoaded || !_MIDI_SongActive) return; + while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); +} + diff --git a/polymer/eduke32/source/jaudiolib/midi.h b/polymer/eduke32/source/jaudiolib/midi.h new file mode 100644 index 000000000..343d99536 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/midi.h @@ -0,0 +1,100 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: MIDI.H + + author: James R. Dose + date: May 25, 1994 + + Public header for MIDI.C. Midi song file playback routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __MIDI_H +#define __MIDI_H + +enum MIDI_Errors + { + MIDI_Warning = -2, + MIDI_Error = -1, + MIDI_Ok = 0, + MIDI_NullMidiModule, + MIDI_InvalidMidiFile, + MIDI_UnknownMidiFormat, + MIDI_NoTracks, + MIDI_InvalidTrack, + MIDI_NoMemory, + MIDI_DPMI_Error + }; + + +#define MIDI_PASS_THROUGH 1 +#define MIDI_DONT_PLAY 0 + +#define MIDI_MaxVolume 255 + +extern char MIDI_PatchMap[ 128 ]; + +typedef struct + { + void ( *NoteOff )( int channel, int key, int velocity ); + void ( *NoteOn )( int channel, int key, int velocity ); + void ( *PolyAftertouch )( int channel, int key, int pressure ); + void ( *ControlChange )( int channel, int number, int value ); + void ( *ProgramChange )( int channel, int program ); + void ( *ChannelAftertouch )( int channel, int pressure ); + void ( *PitchBend )( int channel, int lsb, int msb ); + void ( *ReleasePatches )( void ); + void ( *LoadPatch )( int number ); + void ( *SetVolume )( int volume ); + int ( *GetVolume )( void ); + void ( *FinishBuffer )( void ); + } midifuncs; + +void MIDI_RerouteMidiChannel( int channel, int ( *function )( int event, int c1, int c2 ) ); +int MIDI_AllNotesOff( void ); +void MIDI_SetUserChannelVolume( int channel, int volume ); +void MIDI_ResetUserChannelVolume( void ); +int MIDI_Reset( void ); +int MIDI_SetVolume( int volume ); +int MIDI_GetVolume( void ); +void MIDI_SetMidiFuncs( midifuncs *funcs ); +void MIDI_SetContext( int context ); +int MIDI_GetContext( void ); +void MIDI_SetLoopFlag( int loopflag ); +void MIDI_ContinueSong( void ); +void MIDI_PauseSong( void ); +int MIDI_SongPlaying( void ); +void MIDI_StopSong( void ); +int MIDI_PlaySong( unsigned char *song, int loopflag ); +void MIDI_SetTempo( int tempo ); +int MIDI_GetTempo( void ); +void MIDI_SetSongTick( unsigned long PositionInTicks ); +void MIDI_SetSongTime( unsigned long milliseconds ); +void MIDI_SetSongPosition( int measure, int beat, int tick ); +void MIDI_GetSongPosition( songposition *pos ); +void MIDI_GetSongLength( songposition *pos ); +void MIDI_LoadTimbres( void ); +void MIDI_UpdateMusic(void); +void MIDI_SetDivision( int division ); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/mpu401.c b/polymer/eduke32/source/jaudiolib/mpu401.c new file mode 100644 index 000000000..988e38a24 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mpu401.c @@ -0,0 +1,475 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: MPU401.C + + author: James R. Dose + date: January 1, 1994 + + Low level routines to support sending of MIDI data to MPU401 + compatible MIDI interfaces. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include "mpu401.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +static HMIDISTRM hmido = (HMIDISTRM)-1; +static MIDIOUTCAPS midicaps; +static DWORD mididevice = -1; + +typedef struct { + long time; + long stream; + long event; +} MIDIEVENTHEAD; +#define PAD(x) ((((x)+3)&(~3))) + +#define BUFFERLEN (32*4*4) +#define NUMBUFFERS 6 +static char eventbuf[NUMBUFFERS][BUFFERLEN]; +static int eventcnt[NUMBUFFERS]; +static MIDIHDR bufferheaders[NUMBUFFERS]; + int _MPU_CurrentBuffer = 0; + int _MPU_BuffersWaiting = 0; + +extern unsigned long _MIDI_GlobalPositionInTicks; +unsigned long _MPU_LastEvent=0; + +#define MIDI_NOTE_OFF 0x80 +#define MIDI_NOTE_ON 0x90 +#define MIDI_POLY_AFTER_TCH 0xA0 +#define MIDI_CONTROL_CHANGE 0xB0 +#define MIDI_PROGRAM_CHANGE 0xC0 +#define MIDI_AFTER_TOUCH 0xD0 +#define MIDI_PITCH_BEND 0xE0 +#define MIDI_META_EVENT 0xFF +#define MIDI_END_OF_TRACK 0x2F +#define MIDI_TEMPO_CHANGE 0x51 +#define MIDI_MONO_MODE_ON 0x7E +#define MIDI_ALL_NOTES_OFF 0x7B + + +/********************************************************************** + + Memory locked functions: + +**********************************************************************/ + + +void MPU_FinishBuffer( int buffer ) +{ + if (!eventcnt[buffer]) return; + ZeroMemory(&bufferheaders[buffer], sizeof(MIDIHDR)); + bufferheaders[buffer].lpData = eventbuf[buffer]; + bufferheaders[buffer].dwBufferLength = + bufferheaders[buffer].dwBytesRecorded = eventcnt[buffer]; + midiOutPrepareHeader((HMIDIOUT)hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); + midiStreamOut(hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); +// printf("Sending %d bytes (buffer %d)\n",eventcnt[buffer],buffer); + _MPU_BuffersWaiting++; +} + +void MPU_BeginPlayback( void ) +{ + _MPU_LastEvent = _MIDI_GlobalPositionInTicks; + if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); +} + +void MPU_Pause(void) +{ + if (hmido != (HMIDISTRM)-1) midiStreamPause(hmido); +} + +void MPU_Unpause(void) +{ + if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); +} + + +void CALLBACK MPU_MIDICallback(HMIDIOUT handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) +{ + int i; + switch (uMsg) { + case MOM_DONE: + midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR*)dwParam1, sizeof(MIDIHDR)); + for (i=0;i BUFFERLEN) { + // buffer over-full + nextbuffer = MPU_GetNextBuffer(); + if (nextbuffer < 0) { +// printf("All buffers full!\n"); + return; + } + MPU_FinishBuffer(_MPU_CurrentBuffer); + _MPU_CurrentBuffer = nextbuffer; + } + + p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; + ((long*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; + ((long*)p)[1] = 0; + ((long*)p)[2] = (MEVT_SHORTMSG << 24) | ((*((long*)data)) & masks[count-1]); + eventcnt[_MPU_CurrentBuffer] += 12; + } else { + padded = PAD(count); + if (eventcnt[_MPU_CurrentBuffer] + 12 + padded > BUFFERLEN) { + // buffer over-full + nextbuffer = MPU_GetNextBuffer(); + if (nextbuffer < 0) { +// printf("All buffers full!\n"); + return; + } + MPU_FinishBuffer(_MPU_CurrentBuffer); + _MPU_CurrentBuffer = nextbuffer; + } + + p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; + ((long*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; + ((long*)p)[1] = 0; + ((long*)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl); + p+=12; eventcnt[_MPU_CurrentBuffer] += 12; + for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++) + *(p++) = *(data++); + for (; padded>0; padded--, eventcnt[_MPU_CurrentBuffer]++) + *(p++) = 0; + } + _MPU_LastEvent = _MIDI_GlobalPositionInTicks; +} + + +/*--------------------------------------------------------------------- + Function: MPU_SendMidiImmediate + + Sends a MIDI message immediately to the the music device. +---------------------------------------------------------------------*/ +void MPU_SendMidiImmediate( char *data, int count ) +{ + MIDIHDR mhdr; + static int masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl }; + + if (!count) return; + if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((long*)data)) & masks[count-1]); + else { + ZeroMemory(&mhdr, sizeof(mhdr)); + mhdr.lpData = data; + mhdr.dwBufferLength = count; + midiOutPrepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); + midiOutLongMsg((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); + while (!(mhdr.dwFlags & MHDR_DONE)) ; + midiOutUnprepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); + } +} + + +/*--------------------------------------------------------------------- + Function: MPU_Reset + + Resets the MPU401 card. +---------------------------------------------------------------------*/ + +int MPU_Reset + ( + void + ) + + { + midiStreamStop(hmido); + midiStreamClose(hmido); + + return( MPU_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MPU_Init + + Detects and initializes the MPU401 card. +---------------------------------------------------------------------*/ + +int MPU_Init + ( + int addr + ) + + { + int i; + + for (i=0;i +#include +#ifndef _MSC_VER +#include +#endif +#include "dsoundout.h" +#include "usrhooks.h" +#include "linklist.h" +#include "pitch.h" +#include "multivoc.h" +#include "_multivc.h" +#include "osd.h" + +#ifdef __MINGW32__ +#define min(a,b) (((a)<(b))?(a):(b)) +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + +#define STEREO 1 +#define SIXTEEN_BIT 2 + +#define MONO_8BIT 0 +#define STEREO_8BIT ( STEREO ) +#define MONO_16BIT ( SIXTEEN_BIT ) +#define STEREO_16BIT ( STEREO | SIXTEEN_BIT ) + +#define RoundFixed( fixedval, bits ) \ + ( \ + ( \ + (fixedval) + ( 1 << ( (bits) - 1 ) )\ + ) >> (bits) \ + ) + +#define IS_QUIET( ptr ) ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] ) + +static int MV_ReverbLevel; +static int MV_ReverbDelay; +static VOLUME16 *MV_ReverbTable = NULL; + +//static signed short MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ]; +static signed short MV_VolumeTable[ 63 + 1 ][ 256 ]; + +//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ]; +static Pan MV_PanTable[ MV_NumPanPositions ][ 63 + 1 ]; + +static int MV_Installed = FALSE; +static int MV_SoundCard = -1; +static int MV_TotalVolume = MV_MaxTotalVolume; +static int MV_MaxVoices = 1; +static int MV_Recording; + +static int MV_BufferSize = 0; +static int MV_BufferLength; + +static int MV_NumberOfBuffers = NumberOfBuffers; + +static int MV_MixMode = MONO_8BIT; +static int MV_Channels = 1; +static int MV_Bits = 8; + +static int MV_Silence = SILENCE_8BIT; +static int MV_SwapLeftRight = FALSE; + +static int MV_RequestedMixRate; +static int MV_MixRate; + +static int MV_BuffShift; + +static int MV_TotalMemory; + +static int MV_BufferEmpty[ NumberOfBuffers ]; +char *MV_MixBuffer[ NumberOfBuffers + 1 ]; +static char *MV_MixBufferPtr = NULL; + +static VoiceNode *MV_Voices = NULL; + +static VoiceNode VoiceList; +static VoiceNode VoicePool; + +static int MV_MixPage = 0; +static int MV_VoiceHandle = MV_MinVoiceHandle; + +static void ( *MV_CallBackFunc )( unsigned long ) = NULL; +static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL; +static void ( *MV_MixFunction )( VoiceNode *voice, int buffer ); + +static int MV_MaxVolume = 63; + +char *MV_HarshClipTable; +char *MV_MixDestination; +short *MV_LeftVolume; +short *MV_RightVolume; +int MV_SampleSize = 1; +int MV_RightChannelOffset; + +unsigned long MV_MixPosition; + +int MV_ErrorCode = MV_Ok; + +#define MV_SetErrorCode( status ) \ + MV_ErrorCode = ( status ); + + +/*--------------------------------------------------------------------- + Function: MV_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *MV_ErrorString + ( + int ErrorNumber + ) + + { + char *ErrorString; + + switch( ErrorNumber ) + { + case MV_Warning : + case MV_Error : + ErrorString = MV_ErrorString( MV_ErrorCode ); + break; + + case MV_Ok : + ErrorString = "Multivoc ok."; + break; + + case MV_UnsupportedCard : + ErrorString = "Selected sound card is not supported by Multivoc."; + break; + + case MV_NotInstalled : + ErrorString = "Multivoc not installed."; + break; + + case MV_NoVoices : + ErrorString = "No free voices available to Multivoc."; + break; + + case MV_NoMem : + ErrorString = "Out of memory in Multivoc."; + break; + + case MV_VoiceNotFound : + ErrorString = "No voice with matching handle found."; + break; + + case MV_BlasterError : + ErrorString = DSOUND_ErrorString( DSOUND_ErrorCode ); + break; + + case MV_DPMI_Error : + ErrorString = "DPMI Error in Multivoc."; + break; + + case MV_InvalidVOCFile : + ErrorString = "Invalid VOC file passed in to Multivoc."; + break; + + case MV_InvalidWAVFile : + ErrorString = "Invalid WAV file passed in to Multivoc."; + break; + + case MV_InvalidMixMode : + ErrorString = "Invalid mix mode request in Multivoc."; + break; + + case MV_IrqFailure : + ErrorString = "Playback failed, possibly due to an invalid or conflicting IRQ."; + break; + + case MV_DMAFailure : + ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel."; + break; + + case MV_DMA16Failure : + ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel. \n" + "Make sure the 16-bit DMA channel is correct."; + break; + + case MV_NullRecordFunction : + ErrorString = "Null record function passed to MV_StartRecording."; + break; + + default : + ErrorString = "Unknown Multivoc error code."; + break; + } + + return( ErrorString ); + } + + +/********************************************************************** + + Memory locked functions: + +**********************************************************************/ + + +/*--------------------------------------------------------------------- + Function: MV_GetBufferSize + + Returns the buffer size for the given samplerate. +---------------------------------------------------------------------*/ +#define BASEBUFSZ (512+128) +static unsigned MV_GetBufferSize(unsigned samplerate) +{ + static unsigned lastsr = 0, lastbufsz = 0; + + if (samplerate == lastsr) return lastbufsz; + + lastsr = samplerate; + lastbufsz = (samplerate*BASEBUFSZ/22050)&(~15); + + return lastbufsz; +} + + +/*--------------------------------------------------------------------- + Function: MV_Mix + + Mixes the sound into the buffer. +---------------------------------------------------------------------*/ + +static void MV_Mix + ( + VoiceNode *voice, + int buffer + ) + + { + char *start; + int length; + long voclength; + unsigned long position; + unsigned long rate; + unsigned long FixedPointBufferSize; + + if ( ( voice->length == 0 ) && ( voice->GetSound( voice ) != KeepPlaying ) ) + { + return; + } + + length = MixBufferSize; + FixedPointBufferSize = voice->FixedPointBufferSize; + + MV_MixDestination = MV_MixBuffer[ buffer ]; + MV_LeftVolume = voice->LeftVolume; + MV_RightVolume = voice->RightVolume; + + if ( ( MV_Channels == 2 ) && ( IS_QUIET( MV_LeftVolume ) ) ) + { + MV_LeftVolume = MV_RightVolume; + MV_MixDestination += MV_RightChannelOffset; + } + + // Add this voice to the mix + while( length > 0 ) + { + start = voice->sound; + rate = voice->RateScale; + position = voice->position; + + // Check if the last sample in this buffer would be + // beyond the length of the sample block + if ( ( position + FixedPointBufferSize ) >= voice->length ) + { + if ( position < voice->length ) + { + voclength = ( voice->length - position + rate - 1 ) / rate; + } + else + { + voice->GetSound( voice ); + return; + } + } + else + { + voclength = length; + } + + voice->mix( position, rate, start, voclength ); + + if ( voclength & 1 ) + { + MV_MixPosition += rate; + voclength -= 1; + } + voice->position = MV_MixPosition; + + length -= voclength; + + if ( voice->position >= voice->length ) + { + // Get the next block of sound + if ( voice->GetSound( voice ) != KeepPlaying ) + { + return; + } + + if ( length > 0 ) + { + // Get the position of the last sample in the buffer + FixedPointBufferSize = voice->RateScale * ( length - 1 ); + } + } + } + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayVoice + + Adds a voice to the play list. +---------------------------------------------------------------------*/ + +void MV_PlayVoice + ( + VoiceNode *voice + ) + + { + unsigned flags; + + flags = DisableInterrupts(); + LL_SortedInsertion( &VoiceList, voice, prev, next, VoiceNode, priority ); + + RestoreInterrupts( flags ); + } + + +/*--------------------------------------------------------------------- + Function: MV_StopVoice + + Removes the voice from the play list and adds it to the free list. +---------------------------------------------------------------------*/ + +void MV_StopVoice + ( + VoiceNode *voice + ) + + { + unsigned flags; + + flags = DisableInterrupts(); + + // move the voice from the play list to the free list + LL_Remove( voice, next, prev ); + LL_Add( &VoicePool, voice, next, prev ); + + RestoreInterrupts( flags ); + } + + +/*--------------------------------------------------------------------- + Function: MV_ServiceVoc + + Starts playback of the waiting buffer and mixes the next one. +---------------------------------------------------------------------*/ + +// static int backcolor = 1; + +int MV_ServiceVoc + ( + int buffer + ) + + { + VoiceNode *voice; + VoiceNode *next; + + // Get the currently playing buffer + MV_MixPage = buffer; + + // Toggle which buffer we'll mix next + MV_MixPage++; + if ( MV_MixPage >= MV_NumberOfBuffers ) + { + MV_MixPage -= MV_NumberOfBuffers; + } + + if ( MV_ReverbLevel == 0 ) + { + // Initialize buffer + //Commented out so that the buffer is always cleared. + //This is so the guys at Echo Speech can mix into the + //buffer even when no sounds are playing. + //if ( !MV_BufferEmpty[ MV_MixPage ] ) + { + ClearBuffer_DW( MV_MixBuffer[ MV_MixPage ], MV_Silence, MV_BufferSize >> 2 ); + MV_BufferEmpty[ MV_MixPage ] = TRUE; + } + } + else + { + char *end; + char *source; + char *dest; + int count; + int length; + + end = MV_MixBuffer[ 0 ] + MV_BufferLength; + dest = MV_MixBuffer[ MV_MixPage ]; + source = MV_MixBuffer[ MV_MixPage ] - MV_ReverbDelay; + if ( source < MV_MixBuffer[ 0 ] ) + { + source += MV_BufferLength; + } + + length = MV_BufferSize; + while( length > 0 ) + { + count = length; + if ( source + count > end ) + { + count = end - source; + } + + if ( MV_Bits == 16 ) + { + if ( MV_ReverbTable != NULL ) + { + MV_16BitReverb( source, dest, MV_ReverbTable, count / 2 ); + } + else + { + MV_16BitReverbFast( source, dest, count / 2, MV_ReverbLevel ); + } + } + else + { + if ( MV_ReverbTable != NULL ) + { + MV_8BitReverb( source, dest, MV_ReverbTable, count ); + } + else + { + MV_8BitReverbFast( source, dest, count, MV_ReverbLevel ); + } + } + + // if we go through the loop again, it means that we've wrapped around the buffer + source = MV_MixBuffer[ 0 ]; + dest += count; + length -= count; + } + } + + // Play any waiting voices + for( voice = VoiceList.next; voice != &VoiceList; voice = next ) + { +// if ( ( voice < &MV_Voices[ 0 ] ) || ( voice > &MV_Voices[ 8 ] ) ) +// { +// SetBorderColor(backcolor++); +// break; +// } + + MV_BufferEmpty[ MV_MixPage ] = FALSE; + + MV_MixFunction( voice, MV_MixPage ); + + next = voice->next; + + // Is this voice done? + if ( !voice->Playing ) + { + MV_StopVoice( voice ); + + if ( MV_CallBackFunc ) + { + MV_CallBackFunc( voice->callbackval ); + } + } + } + + return MV_MixPage; + } + + +/*--------------------------------------------------------------------- + Function: MV_GetNextVOCBlock + + Interperate the information of a VOC format sound file. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextVOCBlock + ( + VoiceNode *voice + ) + + { + unsigned char *ptr; + int blocktype; + int lastblocktype; + unsigned long blocklength; + unsigned long samplespeed; + unsigned int tc; + int packtype; + int voicemode; + int done; + unsigned BitsPerSample; + unsigned Channels; + unsigned Format; + + if ( voice->BlockLength > 0 ) + { + voice->position -= voice->length; + voice->sound += voice->length >> 16; + if ( voice->bits == 16 ) + { + voice->sound += voice->length >> 16; + } + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + return( KeepPlaying ); + } + + if ( ( voice->length > 0 ) && ( voice->LoopEnd != NULL ) && + ( voice->LoopStart != NULL ) ) + { + voice->BlockLength = voice->LoopSize; + voice->sound = voice->LoopStart; + voice->position = 0; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + return( KeepPlaying ); + } + + ptr = ( unsigned char * )voice->NextBlock; + + voice->Playing = TRUE; + + voicemode = 0; + lastblocktype = 0; + packtype = 0; + + done = FALSE; + while( !done ) + { + // Stop playing if we get a NULL pointer + if ( ptr == NULL ) + { + voice->Playing = FALSE; + done = TRUE; + break; + } + + blocktype = ( int )*ptr; + blocklength = ( *( unsigned long * )( ptr + 1 ) ) & 0x00ffffff; + ptr += 4; + + switch( blocktype ) + { + case 0 : + // End of data + if ( ( voice->LoopStart == NULL ) || + ( voice->LoopStart >= ( ptr - 4 ) ) ) + { + voice->Playing = FALSE; + done = TRUE; + } + else + { + voice->BlockLength = (char*)( ptr - 4 ) - voice->LoopStart; + voice->sound = voice->LoopStart; + voice->position = 0; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + return( KeepPlaying ); + } + break; + + case 1 : + // Sound data block + voice->bits = 8; + if ( lastblocktype != 8 ) + { + tc = ( unsigned int )*ptr << 8; + packtype = *( ptr + 1 ); + } + + ptr += 2; + blocklength -= 2; + + samplespeed = 256000000L / ( 65536 - tc ); + + // Skip packed or stereo data + if ( ( packtype != 0 ) || ( voicemode != 0 ) ) + { + ptr += blocklength; + } + else + { + done = TRUE; + } + voicemode = 0; + break; + + case 2 : + // Sound continuation block + samplespeed = voice->SamplingRate; + done = TRUE; + break; + + case 3 : + // Silence + // Not implimented. + ptr += blocklength; + break; + + case 4 : + // Marker + // Not implimented. + ptr += blocklength; + break; + + case 5 : + // ASCII string + // Not implimented. + ptr += blocklength; + break; + + case 6 : + // Repeat begin + if ( voice->LoopEnd == NULL ) + { + voice->LoopCount = *( unsigned short * )ptr; + voice->LoopStart = ptr + blocklength; + } + ptr += blocklength; + break; + + case 7 : + // Repeat end + ptr += blocklength; + if ( lastblocktype == 6 ) + { + voice->LoopCount = 0; + } + else + { + if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) ) + { + ptr = voice->LoopStart; + if ( voice->LoopCount < 0xffff ) + { + voice->LoopCount--; + if ( voice->LoopCount == 0 ) + { + voice->LoopStart = NULL; + } + } + } + } + break; + + case 8 : + // Extended block + voice->bits = 8; + tc = *( unsigned short * )ptr; + packtype = *( ptr + 2 ); + voicemode = *( ptr + 3 ); + ptr += blocklength; + break; + + case 9 : + // New sound data block + samplespeed = *( unsigned long * )ptr; + BitsPerSample = ( unsigned )*( ptr + 4 ); + Channels = ( unsigned )*( ptr + 5 ); + Format = ( unsigned )*( unsigned short * )( ptr + 6 ); + + if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) && + ( Format == VOC_8BIT ) ) + { + ptr += 12; + blocklength -= 12; + voice->bits = 8; + done = TRUE; + } + else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) && + ( Format == VOC_16BIT ) ) + { + ptr += 12; + blocklength -= 12; + voice->bits = 16; + done = TRUE; + } + else + { + ptr += blocklength; + } + break; + + default : + // Unknown data. Probably not a VOC file. + voice->Playing = FALSE; + done = TRUE; + break; + } + + lastblocktype = blocktype; + } + + if ( voice->Playing ) + { + voice->NextBlock = ptr + blocklength; + voice->sound = ptr; + + voice->SamplingRate = samplespeed; + voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; + + // Multiply by MixBufferSize - 1 + voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) - + voice->RateScale; + + if ( voice->LoopEnd != NULL ) + { + if ( blocklength > ( unsigned long )voice->LoopEnd ) + { + blocklength = ( unsigned long )voice->LoopEnd; + } + else + { + voice->LoopEnd = ( char * )blocklength; + } + + voice->LoopStart = voice->sound + ( unsigned long )voice->LoopStart; + voice->LoopEnd = voice->sound + ( unsigned long )voice->LoopEnd; + voice->LoopSize = voice->LoopEnd - voice->LoopStart; + } + + if ( voice->bits == 16 ) + { + blocklength /= 2; + } + + voice->position = 0; + voice->length = min( blocklength, 0x8000 ); + voice->BlockLength = blocklength - voice->length; + voice->length <<= 16; + + MV_SetVoiceMixMode( voice ); + + return( KeepPlaying ); + } + + return( NoMoreData ); + } + + +/*--------------------------------------------------------------------- + Function: MV_GetNextDemandFeedBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextDemandFeedBlock + ( + VoiceNode *voice + ) + + { + if ( voice->BlockLength > 0 ) + { + voice->position -= voice->length; + voice->sound += voice->length >> 16; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return( KeepPlaying ); + } + + if ( voice->DemandFeed == NULL ) + { + return( NoMoreData ); + } + + voice->position = 0; + ( voice->DemandFeed )( &voice->sound, &voice->BlockLength ); + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + if ( ( voice->length > 0 ) && ( voice->sound != NULL ) ) + { + return( KeepPlaying ); + } + return( NoMoreData ); + } + + +/*--------------------------------------------------------------------- + Function: MV_GetNextRawBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextRawBlock + ( + VoiceNode *voice + ) + + { + if ( voice->BlockLength <= 0 ) + { + if ( voice->LoopStart == NULL ) + { + voice->Playing = FALSE; + return( NoMoreData ); + } + + voice->BlockLength = voice->LoopSize; + voice->NextBlock = voice->LoopStart; + voice->length = 0; + voice->position = 0; + } + + voice->sound = voice->NextBlock; + voice->position -= voice->length; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->NextBlock += voice->length; + if ( voice->bits == 16 ) + { + voice->NextBlock += voice->length; + } + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return( KeepPlaying ); + } + + +/*--------------------------------------------------------------------- + Function: MV_GetNextWAVBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextWAVBlock + ( + VoiceNode *voice + ) + + { + if ( voice->BlockLength <= 0 ) + { + if ( voice->LoopStart == NULL ) + { + voice->Playing = FALSE; + return( NoMoreData ); + } + + voice->BlockLength = voice->LoopSize; + voice->NextBlock = voice->LoopStart; + voice->length = 0; + voice->position = 0; + } + + voice->sound = voice->NextBlock; + voice->position -= voice->length; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->NextBlock += voice->length; + if ( voice->bits == 16 ) + { + voice->NextBlock += voice->length; + } + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return( KeepPlaying ); + } + + +/*--------------------------------------------------------------------- + Function: MV_ServiceRecord + + Starts recording of the waiting buffer. +---------------------------------------------------------------------*/ + +static void MV_ServiceRecord + ( + void + ) + + { + if ( MV_RecordFunc ) + { + MV_RecordFunc( MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize, + MixBufferSize ); + } + + // Toggle which buffer we'll mix next + MV_MixPage++; + if ( MV_MixPage >= NumberOfBuffers ) + { + MV_MixPage = 0; + } + } + + +/*--------------------------------------------------------------------- + Function: MV_GetVoice + + Locates the voice with the specified handle. +---------------------------------------------------------------------*/ + +VoiceNode *MV_GetVoice + ( + int handle + ) + + { + VoiceNode *voice; + unsigned flags; + + flags = DisableInterrupts(); + + for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next ) + { + if ( handle == voice->handle ) + { + break; + } + } + + RestoreInterrupts( flags ); + + if ( voice == &VoiceList ) + { + MV_SetErrorCode( MV_VoiceNotFound ); + voice = NULL; + } + + return( voice ); + } + + +/*--------------------------------------------------------------------- + Function: MV_VoicePlaying + + Checks if the voice associated with the specified handle is + playing. +---------------------------------------------------------------------*/ + +int MV_VoicePlaying + ( + int handle + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( FALSE ); + } + + voice = MV_GetVoice( handle ); + + if ( voice == NULL ) + { + return( FALSE ); + } + + return( TRUE ); + } + + +/*--------------------------------------------------------------------- + Function: MV_KillAllVoices + + Stops output of all currently active voices. +---------------------------------------------------------------------*/ + +int MV_KillAllVoices + ( + void + ) + + { + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + // Remove all the voices from the list + while( VoiceList.next != &VoiceList ) + { + MV_Kill( VoiceList.next->handle ); + } + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_Kill + + Stops output of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int MV_Kill + ( + int handle + ) + + { + VoiceNode *voice; + unsigned flags; + unsigned long callbackval; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + flags = DisableInterrupts(); + + voice = MV_GetVoice( handle ); + if ( voice == NULL ) + { + RestoreInterrupts( flags ); + MV_SetErrorCode( MV_VoiceNotFound ); + return( MV_Error ); + } + + callbackval = voice->callbackval; + + MV_StopVoice( voice ); + + RestoreInterrupts( flags ); + + if ( MV_CallBackFunc ) + { + MV_CallBackFunc( callbackval ); + } + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_VoicesPlaying + + Determines the number of currently active voices. +---------------------------------------------------------------------*/ + +int MV_VoicesPlaying + ( + void + ) + + { + VoiceNode *voice; + int NumVoices = 0; + unsigned flags; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( 0 ); + } + + flags = DisableInterrupts(); + + for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next ) + { + NumVoices++; + } + + RestoreInterrupts( flags ); + + return( NumVoices ); + } + + +/*--------------------------------------------------------------------- + Function: MV_AllocVoice + + Retrieve an inactive or lower priority voice for output. +---------------------------------------------------------------------*/ + +VoiceNode *MV_AllocVoice + ( + int priority + ) + + { + VoiceNode *voice; + VoiceNode *node; + unsigned flags; + +//return( NULL ); + if ( MV_Recording ) + { + return( NULL ); + } + + flags = DisableInterrupts(); + + // Check if we have any free voices + if ( LL_Empty( &VoicePool, next, prev ) ) + { + // check if we have a higher priority than a voice that is playing. + voice = VoiceList.next; + for( node = voice->next; node != &VoiceList; node = node->next ) + { + if ( node->priority < voice->priority ) + { + voice = node; + } + } + + if ( priority >= voice->priority ) + { + MV_Kill( voice->handle ); + } + } + + // Check if any voices are in the voice pool + if ( LL_Empty( &VoicePool, next, prev ) ) + { + // No free voices + RestoreInterrupts( flags ); + return( NULL ); + } + + voice = VoicePool.next; + LL_Remove( voice, next, prev ); + RestoreInterrupts( flags ); + + // Find a free voice handle + do + { + MV_VoiceHandle++; + if ( MV_VoiceHandle < MV_MinVoiceHandle ) + { + MV_VoiceHandle = MV_MinVoiceHandle; + } + } + while( MV_VoicePlaying( MV_VoiceHandle ) ); + + voice->handle = MV_VoiceHandle; + + return( voice ); + } + + +/*--------------------------------------------------------------------- + Function: MV_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int MV_VoiceAvailable + ( + int priority + ) + + { + VoiceNode *voice; + VoiceNode *node; + unsigned flags; + + // Check if we have any free voices + if ( !LL_Empty( &VoicePool, next, prev ) ) + { + return( TRUE ); + } + + flags = DisableInterrupts(); + + // check if we have a higher priority than a voice that is playing. + voice = VoiceList.next; + for( node = VoiceList.next; node != &VoiceList; node = node->next ) + { + if ( node->priority < voice->priority ) + { + voice = node; + } + } + + RestoreInterrupts( flags ); + + if ( ( voice != &VoiceList ) && ( priority >= voice->priority ) ) + { + return( TRUE ); + } + + return( FALSE ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetVoicePitch + + Sets the pitch for the specified voice. +---------------------------------------------------------------------*/ + +void MV_SetVoicePitch + ( + VoiceNode *voice, + unsigned long rate, + int pitchoffset + ) + + { + voice->SamplingRate = rate; + voice->PitchScale = PITCH_GetScale( pitchoffset ); + voice->RateScale = ( rate * voice->PitchScale ) / MV_MixRate; + + // Multiply by MixBufferSize - 1 + voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) - + voice->RateScale; + } + + +/*--------------------------------------------------------------------- + Function: MV_SetPitch + + Sets the pitch for the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int MV_SetPitch + ( + int handle, + int pitchoffset + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + voice = MV_GetVoice( handle ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_VoiceNotFound ); + return( MV_Error ); + } + + MV_SetVoicePitch( voice, voice->SamplingRate, pitchoffset ); + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetFrequency + + Sets the frequency for the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int MV_SetFrequency + ( + int handle, + int frequency + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + voice = MV_GetVoice( handle ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_VoiceNotFound ); + return( MV_Error ); + } + + MV_SetVoicePitch( voice, frequency, 0 ); + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_GetVolumeTable + + Returns a pointer to the volume table associated with the specified + volume. +---------------------------------------------------------------------*/ + +static short *MV_GetVolumeTable + ( + int vol + ) + + { + int volume; + short *table; + + volume = MIX_VOLUME( vol ); + + table = (short*)&MV_VolumeTable[ volume ]; + + return( table ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetVoiceMixMode + + Selects which method should be used to mix the voice. +---------------------------------------------------------------------*/ + +static void MV_SetVoiceMixMode + ( + VoiceNode *voice + ) + + { + unsigned flags; + int test; + + flags = DisableInterrupts(); + + test = T_DEFAULT; + if ( MV_Bits == 8 ) + { + test |= T_8BITS; + } + + if ( voice->bits == 16 ) + { + test |= T_16BITSOURCE; + } + + if ( MV_Channels == 1 ) + { + test |= T_MONO; + } + else + { + if ( IS_QUIET( voice->RightVolume ) ) + { + test |= T_RIGHTQUIET; + } + else if ( IS_QUIET( voice->LeftVolume ) ) + { + test |= T_LEFTQUIET; + } + } + + // Default case + voice->mix = MV_Mix8BitMono; + + switch( test ) + { + case T_8BITS | T_MONO | T_16BITSOURCE : + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_MONO : + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE | T_RIGHTQUIET : + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_RIGHTQUIET : + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE : + voice->mix = MV_Mix8BitStereo16; + break; + + case T_8BITS : + voice->mix = MV_Mix8BitStereo; + break; + + case T_MONO | T_16BITSOURCE : + voice->mix = MV_Mix16BitMono16; + break; + + case T_MONO : + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix16BitMono16; + break; + + case T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE | T_RIGHTQUIET : + voice->mix = MV_Mix16BitMono16; + break; + + case T_RIGHTQUIET : + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE : + voice->mix = MV_Mix16BitStereo16; + break; + + case T_SIXTEENBIT_STEREO : + voice->mix = MV_Mix16BitStereo; + break; + + default : + voice->mix = MV_Mix8BitMono; + } + + RestoreInterrupts( flags ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetVoiceVolume + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +void MV_SetVoiceVolume + ( + VoiceNode *voice, + int vol, + int left, + int right + ) + + { + if ( MV_Channels == 1 ) + { + left = vol; + right = vol; + } + + if ( MV_SwapLeftRight ) + { + // SBPro uses reversed panning + voice->LeftVolume = MV_GetVolumeTable( right ); + voice->RightVolume = MV_GetVolumeTable( left ); + } + else + { + voice->LeftVolume = MV_GetVolumeTable( left ); + voice->RightVolume = MV_GetVolumeTable( right ); + } + + MV_SetVoiceMixMode( voice ); + } + + +/*--------------------------------------------------------------------- + Function: MV_EndLooping + + Stops the voice associated with the specified handle from looping + without stoping the sound. +---------------------------------------------------------------------*/ + +int MV_EndLooping + ( + int handle + ) + + { + VoiceNode *voice; + unsigned flags; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + flags = DisableInterrupts(); + + voice = MV_GetVoice( handle ); + if ( voice == NULL ) + { + RestoreInterrupts( flags ); + MV_SetErrorCode( MV_VoiceNotFound ); + return( MV_Warning ); + } + + voice->LoopCount = 0; + voice->LoopStart = NULL; + voice->LoopEnd = NULL; + + RestoreInterrupts( flags ); + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetPan + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int MV_SetPan + ( + int handle, + int vol, + int left, + int right + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + voice = MV_GetVoice( handle ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_VoiceNotFound ); + return( MV_Warning ); + } + + MV_SetVoiceVolume( voice, vol, left, right ); + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int MV_Pan3D + ( + int handle, + int angle, + int distance + ) + + { + int left; + int right; + int mid; + int volume; + int status; + + if ( distance < 0 ) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME( distance ); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max( 0, 255 - distance ); + + status = MV_SetPan( handle, mid, left, right ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetReverb + + Sets the level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetReverb + ( + int reverb + ) + + { + MV_ReverbLevel = MIX_VOLUME( reverb ); + MV_ReverbTable = &MV_VolumeTable[ MV_ReverbLevel ]; + } + + +/*--------------------------------------------------------------------- + Function: MV_SetFastReverb + + Sets the level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetFastReverb + ( + int reverb + ) + + { + MV_ReverbLevel = max( 0, min( 16, reverb ) ); + MV_ReverbTable = NULL; + } + + +/*--------------------------------------------------------------------- + Function: MV_GetMaxReverbDelay + + Returns the maximum delay time for reverb. +---------------------------------------------------------------------*/ + +int MV_GetMaxReverbDelay + ( + void + ) + + { + int maxdelay; + + maxdelay = MixBufferSize * MV_NumberOfBuffers; + + return maxdelay; + } + + +/*--------------------------------------------------------------------- + Function: MV_GetReverbDelay + + Returns the current delay time for reverb. +---------------------------------------------------------------------*/ + +int MV_GetReverbDelay + ( + void + ) + + { + return MV_ReverbDelay / MV_SampleSize; + } + + +/*--------------------------------------------------------------------- + Function: MV_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetReverbDelay + ( + int delay + ) + + { + int maxdelay; + + maxdelay = MV_GetMaxReverbDelay(); + MV_ReverbDelay = max( MixBufferSize, min( delay, maxdelay ) ); + MV_ReverbDelay *= MV_SampleSize; + } + + +/*--------------------------------------------------------------------- + Function: MV_SetMixMode + + Prepares Multivoc to play stereo of mono digitized sounds. +---------------------------------------------------------------------*/ + +int MV_SetMixMode + ( + int numchannels, + int samplebits + ) + + { + int mode; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + mode = 0; + if ( numchannels == 2 ) + { + mode |= STEREO; + } + if ( samplebits == 16 ) + { + mode |= SIXTEEN_BIT; + } + + MV_MixMode = DSOUND_SetMixMode( mode ); + + MV_Channels = 1; + if ( MV_MixMode & STEREO ) + { + MV_Channels = 2; + } + + MV_Bits = 8; + if ( MV_MixMode & SIXTEEN_BIT ) + { + MV_Bits = 16; + } + + MV_BuffShift = 7 + MV_Channels; + MV_SampleSize = sizeof( MONO8 ) * MV_Channels; + + if ( MV_Bits == 8 ) + { + MV_Silence = SILENCE_8BIT; + } + else + { + MV_Silence = SILENCE_16BIT; + MV_BuffShift += 1; + MV_SampleSize *= 2; + } + + MV_BufferSize = MixBufferSize * MV_SampleSize; + MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize; + MV_BufferLength = TotalBufferSize; + + MV_RightChannelOffset = MV_SampleSize / 2; + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_StartPlayback + + Starts the sound playback engine. +---------------------------------------------------------------------*/ + +int MV_StartPlayback + ( + void + ) + + { + int status; + int buffer; + + // Initialize the buffers + ClearBuffer_DW( MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2 ); + for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ ) + { + MV_BufferEmpty[ buffer ] = TRUE; + } + + // Set the mix buffer variables + MV_MixPage = 1; + + MV_MixFunction = MV_Mix; + + MV_MixRate = MV_RequestedMixRate; + + // Start playback + status = DSOUND_BeginBufferedPlayback( MV_MixBuffer[ 0 ], MV_ServiceVoc, TotalBufferSize, MV_NumberOfBuffers ); + if ( status != DSOUND_Ok ) + { + MV_SetErrorCode( MV_BlasterError ); + return( MV_Error ); + } + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_StopPlayback + + Stops the sound playback engine. +---------------------------------------------------------------------*/ + +void MV_StopPlayback + ( + void + ) + + { + VoiceNode *voice; + VoiceNode *next; + unsigned flags; + + // Stop sound playback + DSOUND_StopPlayback(); + + // Make sure all callbacks are done. + flags = DisableInterrupts(); + + for( voice = VoiceList.next; voice != &VoiceList; voice = next ) + { + next = voice->next; + + MV_StopVoice( voice ); + + if ( MV_CallBackFunc ) + { + MV_CallBackFunc( voice->callbackval ); + } + } + + RestoreInterrupts( flags ); + } + + +#if 0 +/*--------------------------------------------------------------------- + Function: MV_StartRecording + + Starts the sound recording engine. +---------------------------------------------------------------------*/ + +int MV_StartRecording + ( + int MixRate, + void ( *function )( char *ptr, int length ) + ) + + { + int status; + + switch( MV_SoundCard ) + { + case SoundBlaster : + break; + + default : + MV_SetErrorCode( MV_UnsupportedCard ); + return( MV_Error ); + break; + } + + if ( function == NULL ) + { + MV_SetErrorCode( MV_NullRecordFunction ); + return( MV_Error ); + } + + MV_StopPlayback(); + + // Initialize the buffers + ClearBuffer_DW( MV_MixBuffer[ 0 ], SILENCE_8BIT, TotalBufferSize >> 2 ); + + // Set the mix buffer variables + MV_MixPage = 0; + + MV_RecordFunc = function; + + // Start playback + switch( MV_SoundCard ) + { + case SoundBlaster : + status = BLASTER_BeginBufferedRecord( MV_MixBuffer[ 0 ], + TotalBufferSize, NumberOfBuffers, MixRate, MONO_8BIT, + MV_ServiceRecord ); + + if ( status != BLASTER_Ok ) + { + MV_SetErrorCode( MV_BlasterError ); + return( MV_Error ); + } + break; + } + + MV_Recording = TRUE; + return( MV_Ok ); + } +#endif + +#if 0 +/*--------------------------------------------------------------------- + Function: MV_StopRecord + + Stops the sound record engine. +---------------------------------------------------------------------*/ + +void MV_StopRecord + ( + void + ) + + { + // Stop sound playback + switch( MV_SoundCard ) + { + case SoundBlaster : + BLASTER_StopPlayback(); + break; + } + + MV_Recording = FALSE; + MV_StartPlayback(); + } +#endif + + +/*--------------------------------------------------------------------- + Function: MV_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int MV_StartDemandFeedPlayback + ( + void ( *function )( char **ptr, unsigned long *length ), + int rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice( priority ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_NoVoices ); + return( MV_Error ); + } + + voice->wavetype = DemandFeed; + voice->bits = 8; + voice->GetSound = MV_GetNextDemandFeedBlock; + voice->NextBlock = NULL; + voice->DemandFeed = function; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->position = 0; + voice->sound = NULL; + voice->length = 0; + voice->BlockLength = 0; + voice->Playing = TRUE; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + + MV_SetVoicePitch( voice, rate, pitchoffset ); + MV_SetVoiceVolume( voice, vol, left, right ); + MV_PlayVoice( voice ); + + return( voice->handle ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayRaw + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayRaw + ( + char *ptr, + unsigned long length, + unsigned rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int status; + + status = MV_PlayLoopedRaw( ptr, length, NULL, NULL, rate, pitchoffset, + vol, left, right, priority, callbackval ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedRaw + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayLoopedRaw + ( + char *ptr, + long length, + char *loopstart, + char *loopend, + unsigned rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + VoiceNode *voice; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice( priority ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_NoVoices ); + return( MV_Error ); + } + + voice->wavetype = Raw; + voice->bits = 8; + voice->GetSound = MV_GetNextRawBlock; + voice->Playing = TRUE; + voice->NextBlock = ptr; + voice->position = 0; + voice->BlockLength = length; + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = loopstart; + voice->LoopEnd = loopend; + voice->LoopSize = ( voice->LoopEnd - voice->LoopStart ) + 1; + + MV_SetVoicePitch( voice, rate, pitchoffset ); + MV_SetVoiceVolume( voice, vol, left, right ); + MV_PlayVoice( voice ); + + return( voice->handle ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayWAV + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayWAV + ( + char *ptr, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int status; + + status = MV_PlayLoopedWAV( ptr, -1, -1, pitchoffset, vol, left, right, + priority, callbackval ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int MV_PlayWAV3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + int left; + int right; + int mid; + int volume; + int status; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + if ( distance < 0 ) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME( distance ); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max( 0, 255 - distance ); + + status = MV_PlayWAV( ptr, pitchoffset, mid, left, right, priority, + callbackval ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedWAV + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayLoopedWAV + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + riff_header *riff; + format_header *format; + data_header *data; + VoiceNode *voice; + int length; + int absloopend; + int absloopstart; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + riff = ( riff_header * )ptr; + + if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) || + ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) || + ( strncmp( riff->fmt, "fmt ", 4) != 0 ) ) + { + MV_SetErrorCode( MV_InvalidWAVFile ); + return( MV_Error ); + } + + format = ( format_header * )( riff + 1 ); + data = ( data_header * )( ( ( char * )format ) + riff->format_size ); + + // Check if it's PCM data. + if ( format->wFormatTag != 1 ) + { + MV_SetErrorCode( MV_InvalidWAVFile ); + return( MV_Error ); + } + + if ( format->nChannels != 1 ) + { + MV_SetErrorCode( MV_InvalidWAVFile ); + return( MV_Error ); + } + + if ( ( format->nBitsPerSample != 8 ) && + ( format->nBitsPerSample != 16 ) ) + { + MV_SetErrorCode( MV_InvalidWAVFile ); + return( MV_Error ); + } + + if ( strncmp( data->DATA, "data", 4 ) != 0 ) + { + MV_SetErrorCode( MV_InvalidWAVFile ); + return( MV_Error ); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice( priority ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_NoVoices ); + return( MV_Error ); + } + + voice->wavetype = WAV; + voice->bits = format->nBitsPerSample; + voice->GetSound = MV_GetNextWAVBlock; + + length = data->size; + absloopstart = loopstart; + absloopend = loopend; + if ( voice->bits == 16 ) + { + loopstart *= 2; + data->size &= ~1; + loopend *= 2; + length /= 2; + } + + loopend = min( loopend, data->size ); + absloopend = min( absloopend, length ); + + voice->Playing = TRUE; + voice->DemandFeed = NULL; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->position = 0; + voice->length = 0; + voice->BlockLength = absloopend; + voice->NextBlock = ( char * )( data + 1 ); + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = voice->NextBlock + loopstart; + voice->LoopEnd = voice->NextBlock + loopend; + voice->LoopSize = absloopend - absloopstart; + + if ( ( loopstart >= data->size ) || ( loopstart < 0 ) ) + { + voice->LoopStart = NULL; + voice->LoopEnd = NULL; + voice->BlockLength = length; + } + + MV_SetVoicePitch( voice, format->nSamplesPerSec, pitchoffset ); + MV_SetVoiceVolume( voice, vol, left, right ); + MV_PlayVoice( voice ); + + return( voice->handle ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int MV_PlayVOC3D + ( + char *ptr, + int pitchoffset, + int angle, + int distance, + int priority, + unsigned long callbackval + ) + + { + int left; + int right; + int mid; + int volume; + int status; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + if ( distance < 0 ) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME( distance ); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max( 0, 255 - distance ); + + status = MV_PlayVOC( ptr, pitchoffset, mid, left, right, priority, + callbackval ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayVOC + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayVOC + ( + char *ptr, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + int status; + + status = MV_PlayLoopedVOC( ptr, -1, -1, pitchoffset, vol, left, right, + priority, callbackval ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedVOC + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int MV_PlayLoopedVOC + ( + char *ptr, + long loopstart, + long loopend, + int pitchoffset, + int vol, + int left, + int right, + int priority, + unsigned long callbackval + ) + + { + VoiceNode *voice; + int status; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + // Make sure it's a valid VOC file. + status = strncmp( ptr, "Creative Voice File", 19 ); + if ( status != 0 ) + { + MV_SetErrorCode( MV_InvalidVOCFile ); + return( MV_Error ); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice( priority ); + if ( voice == NULL ) + { + MV_SetErrorCode( MV_NoVoices ); + return( MV_Error ); + } + + voice->wavetype = VOC; + voice->bits = 8; + voice->GetSound = MV_GetNextVOCBlock; + voice->NextBlock = ptr + *( unsigned short int * )( ptr + 0x14 ); + voice->DemandFeed = NULL; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->PitchScale = PITCH_GetScale( pitchoffset ); + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = ( char * )loopstart; + voice->LoopEnd = ( char * )loopend; + voice->LoopSize = loopend - loopstart + 1; + + if ( loopstart < 0 ) + { + voice->LoopStart = NULL; + voice->LoopEnd = NULL; + } + + MV_SetVoiceVolume( voice, vol, left, right ); + MV_PlayVoice( voice ); + + return( voice->handle ); + } + + +/*--------------------------------------------------------------------- + Function: MV_CreateVolumeTable + + Create the table used to convert sound data to a specific volume + level. +---------------------------------------------------------------------*/ + +void MV_CreateVolumeTable + ( + int index, + int volume, + int MaxVolume + ) + + { + int val; + int level; + int i; + + level = ( volume * MaxVolume ) / MV_MaxTotalVolume; + if ( MV_Bits == 16 ) + { + for( i = 0; i < 65536; i += 256 ) + { + val = i - 0x8000; + val *= level; + val /= MV_MaxVolume; + MV_VolumeTable[ index ][ i / 256 ] = val; + } + } + else + { + for( i = 0; i < 256; i++ ) + { + val = i - 0x80; + val *= level; + val /= MV_MaxVolume; + MV_VolumeTable[ volume ][ i ] = val; + } + } + } + + +/*--------------------------------------------------------------------- + Function: MV_CalcVolume + + Create the table used to convert sound data to a specific volume + level. +---------------------------------------------------------------------*/ + +void MV_CalcVolume + ( + int MaxVolume + ) + + { + int volume; + + for( volume = 0; volume < 128; volume++ ) + { + MV_HarshClipTable[ volume ] = 0; + MV_HarshClipTable[ volume + 384 ] = 255; + } + for( volume = 0; volume < 256; volume++ ) + { + MV_HarshClipTable[ volume + 128 ] = volume; + } + + // For each volume level, create a translation table with the + // appropriate volume calculated. + for( volume = 0; volume <= MV_MaxVolume; volume++ ) + { + MV_CreateVolumeTable( volume, volume, MaxVolume ); + } + } + + +/*--------------------------------------------------------------------- + Function: MV_CalcPanTable + + Create the table used to determine the stereo volume level of + a sound located at a specific angle and distance from the listener. +---------------------------------------------------------------------*/ + +void MV_CalcPanTable + ( + void + ) + + { + int level; + int angle; + int distance; + int HalfAngle; + int ramp; + + HalfAngle = ( MV_NumPanPositions / 2 ); + + for( distance = 0; distance <= MV_MaxVolume; distance++ ) + { + level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume; + for( angle = 0; angle <= HalfAngle / 2; angle++ ) + { + ramp = level - ( ( level * angle ) / + ( MV_NumPanPositions / 4 ) ); + + MV_PanTable[ angle ][ distance ].left = ramp; + MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp; + MV_PanTable[ HalfAngle + angle ][ distance ].left = level; + MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level; + + MV_PanTable[ angle ][ distance ].right = level; + MV_PanTable[ HalfAngle - angle ][ distance ].right = level; + MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp; + MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp; + } + } + } + + +/*--------------------------------------------------------------------- + Function: MV_SetVolume + + Sets the volume of digitized sound playback. +---------------------------------------------------------------------*/ + +void MV_SetVolume + ( + int volume + ) + + { + volume = max( 0, volume ); + volume = min( volume, MV_MaxTotalVolume ); + + MV_TotalVolume = volume; + + // Calculate volume table + MV_CalcVolume( volume ); + } + + +/*--------------------------------------------------------------------- + Function: MV_GetVolume + + Returns the volume of digitized sound playback. +---------------------------------------------------------------------*/ + +int MV_GetVolume + ( + void + ) + + { + return( MV_TotalVolume ); + } + + +/*--------------------------------------------------------------------- + Function: MV_SetCallBack + + Set the function to call when a voice stops. +---------------------------------------------------------------------*/ + +void MV_SetCallBack + ( + void ( *function )( unsigned long ) + ) + + { + MV_CallBackFunc = function; + } + + +/*--------------------------------------------------------------------- + Function: MV_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void MV_SetReverseStereo + ( + int setting + ) + + { + MV_SwapLeftRight = setting; + } + + +/*--------------------------------------------------------------------- + Function: MV_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int MV_GetReverseStereo + ( + void + ) + + { + return( MV_SwapLeftRight ); + } + +#if 0 +/*--------------------------------------------------------------------- + Function: MV_TestPlayback + + Checks if playback has started. +---------------------------------------------------------------------*/ + +int MV_TestPlayback + ( + void + ) + + { + unsigned flags; + long time; + int start; + int status; + int pos; + + flags = DisableInterrupts(); + _enable(); + + status = MV_Error; + start = MV_MixPage; + time = clock() + CLOCKS_PER_SEC * 2; + + while( clock() < time ) + { + if ( MV_MixPage != start ) + { + status = MV_Ok; + } + } + + RestoreInterrupts( flags ); + + if ( status != MV_Ok ) + { + // Just in case an error doesn't get reported + MV_SetErrorCode( MV_DMAFailure ); + + switch( MV_SoundCard ) + { + case SoundBlaster : + pos = BLASTER_GetCurrentPos(); + break; + + default : + MV_SetErrorCode( MV_UnsupportedCard ); + pos = -2; + break; + } + + if ( pos > 0 ) + { + MV_SetErrorCode( MV_IrqFailure ); + } + else if ( pos == 0 ) + { + if ( MV_Bits == 16 ) + { + MV_SetErrorCode( MV_DMA16Failure ); + } + else + { + MV_SetErrorCode( MV_DMAFailure ); + } + } + } + + return( status ); + } +#endif + + +/*--------------------------------------------------------------------- + Function: MV_Init + + Perform the initialization of variables and memory used by + Multivoc. +---------------------------------------------------------------------*/ + +int MV_Init + ( + int soundcard, + int MixRate, + int Voices, + int numchannels, + int samplebits + ) + + { + char *ptr; + int status; + int buffer; + int index; + + if ( MV_Installed ) + { + MV_Shutdown(); + } + + printOSD("Initializing MultiVoc...\n"); + + MV_SetErrorCode( MV_Ok ); + + MV_TotalMemory = Voices * sizeof( VoiceNode ) + sizeof( HARSH_CLIP_TABLE_8 ); + status = USRHOOKS_GetMem( ( void ** )&ptr, MV_TotalMemory ); + if ( status != USRHOOKS_Ok ) + { + MV_SetErrorCode( MV_NoMem ); + return( MV_Error ); + } + + MV_Voices = ( VoiceNode * )ptr; + MV_HarshClipTable = ptr + ( MV_TotalMemory - sizeof( HARSH_CLIP_TABLE_8 ) ); + + // Set number of voices before calculating volume table + MV_MaxVoices = Voices; + + printOSD(" - Maximum voices: %d\n", MV_MaxVoices); + + LL_Reset( &VoiceList, next, prev ); + LL_Reset( &VoicePool, next, prev ); + + for( index = 0; index < Voices; index++ ) + { + LL_Add( &VoicePool, &MV_Voices[ index ], next, prev ); + } + + // Set the sampling rate + MV_RequestedMixRate = MixRate; + + printOSD(" - Using %d byte mixing buffers\n", MixBufferSize); + + // Allocate mix buffer within 1st megabyte + ptr = (char *)malloc(TotalBufferSize + 4); // FIXME: temporarily fixes bounds error somewhere... + if ( !ptr ) + { + USRHOOKS_FreeMem( MV_Voices ); + MV_Voices = NULL; + MV_TotalMemory = 0; + + MV_SetErrorCode( MV_NoMem ); + return( MV_Error ); + } + + MV_MixBufferPtr = ptr; + + MV_SetReverseStereo( FALSE ); + + // Initialize the sound card + status = DSOUND_Init(soundcard, MixRate, numchannels, samplebits, + TotalBufferSize); + if ( status != DSOUND_Ok ) + { + MV_SetErrorCode( MV_BlasterError ); + } + + if ( MV_ErrorCode != MV_Ok ) + { + status = MV_ErrorCode; + + USRHOOKS_FreeMem( MV_Voices ); + MV_Voices = NULL; + MV_TotalMemory = 0; + + free(ptr); + + MV_SetErrorCode( status ); + return( MV_Error ); + } + + MV_SoundCard = soundcard; + MV_Installed = TRUE; + MV_CallBackFunc = NULL; + MV_RecordFunc = NULL; + MV_Recording = FALSE; + MV_ReverbLevel = 0; + MV_ReverbTable = NULL; + + // Set Mixer to play stereo digitized sound + MV_SetMixMode( numchannels, samplebits ); + MV_ReverbDelay = MV_BufferSize * 3; + + //MV_MixBuffer[ MV_NumberOfBuffers ] = ptr; + for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ ) + { + MV_MixBuffer[ buffer ] = ptr; + ptr += MV_BufferSize; + } + + // Calculate pan table + MV_CalcPanTable(); + + MV_SetVolume( MV_MaxTotalVolume ); + + // Start the playback engine + status = MV_StartPlayback(); + if ( status != MV_Ok ) + { + // Preserve error code while we shutdown. + status = MV_ErrorCode; + MV_Shutdown(); + MV_SetErrorCode( status ); + return( MV_Error ); + } + + return( MV_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MV_Shutdown + + Restore any resources allocated by Multivoc back to the system. +---------------------------------------------------------------------*/ + +int MV_Shutdown + ( + void + ) + + { + int buffer; + unsigned flags; + + if ( !MV_Installed ) + { + return( MV_Ok ); + } + + printOSD("Uninitializing MultiVoc...\n"); + + flags = DisableInterrupts(); + + MV_KillAllVoices(); + + MV_Installed = FALSE; + + // Stop the sound recording engine + if ( MV_Recording ) + { + //MV_StopRecord(); + } + + // Stop the sound playback engine + MV_StopPlayback(); + + // Shutdown the sound card + DSOUND_Shutdown(); + + RestoreInterrupts( flags ); + + // Free any voices we allocated + USRHOOKS_FreeMem( MV_Voices ); + MV_Voices = NULL; + MV_TotalMemory = 0; + + LL_Reset( &VoiceList, next, prev ); + LL_Reset( &VoicePool, next, prev ); + + MV_MaxVoices = 1; + + // Release the descriptor from our mix buffer + if (MV_MixBufferPtr) free(MV_MixBufferPtr); + MV_MixBufferPtr = NULL; + + for( buffer = 0; buffer < NumberOfBuffers; buffer++ ) + { + MV_MixBuffer[ buffer ] = NULL; + } + + return( MV_Ok ); + } + + diff --git a/polymer/eduke32/source/jaudiolib/multivoc.h b/polymer/eduke32/source/jaudiolib/multivoc.h new file mode 100644 index 000000000..19af4479e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/multivoc.h @@ -0,0 +1,117 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + file: MULTIVOC.H + + author: James R. Dose + date: December 20, 1993 + + Public header for MULTIVOC.C + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __MULTIVOC_H +#define __MULTIVOC_H + +#define MV_MinVoiceHandle 1 + +extern int MV_ErrorCode; + +enum MV_Errors + { + MV_Warning = -2, + MV_Error = -1, + MV_Ok = 0, + MV_UnsupportedCard, + MV_NotInstalled, + MV_NoVoices, + MV_NoMem, + MV_VoiceNotFound, + MV_BlasterError, + MV_DPMI_Error, + MV_InvalidVOCFile, + MV_InvalidWAVFile, + MV_InvalidMixMode, + MV_IrqFailure, + MV_DMAFailure, + MV_DMA16Failure, + MV_NullRecordFunction + }; + +char *MV_ErrorString( int ErrorNumber ); +int MV_VoicePlaying( int handle ); +int MV_KillAllVoices( void ); +int MV_Kill( int handle ); +int MV_VoicesPlaying( void ); +int MV_VoiceAvailable( int priority ); +int MV_SetPitch( int handle, int pitchoffset ); +int MV_SetFrequency( int handle, int frequency ); +int MV_EndLooping( int handle ); +int MV_SetPan( int handle, int vol, int left, int right ); +int MV_Pan3D( int handle, int angle, int distance ); +void MV_SetReverb( int reverb ); +void MV_SetFastReverb( int reverb ); +int MV_GetMaxReverbDelay( void ); +int MV_GetReverbDelay( void ); +void MV_SetReverbDelay( int delay ); +int MV_SetMixMode( int numchannels, int samplebits ); +int MV_StartPlayback( void ); +void MV_StopPlayback( void ); +int MV_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) ); +void MV_StopRecord( void ); +int MV_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ), + int rate, int pitchoffset, int vol, int left, int right, + int priority, unsigned long callbackval ); +int MV_PlayRaw( char *ptr, unsigned long length, + unsigned rate, int pitchoffset, int vol, int left, + int right, int priority, unsigned long callbackval ); +int MV_PlayLoopedRaw( char *ptr, long length, + char *loopstart, char *loopend, unsigned rate, int pitchoffset, + int vol, int left, int right, int priority, + unsigned long callbackval ); +int MV_PlayWAV( char *ptr, int pitchoffset, int vol, int left, + int right, int priority, unsigned long callbackval ); +int MV_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); +int MV_PlayLoopedWAV( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +int MV_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ); +int MV_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right, + int priority, unsigned long callbackval ); +int MV_PlayLoopedVOC( char *ptr, long loopstart, long loopend, + int pitchoffset, int vol, int left, int right, int priority, + unsigned long callbackval ); +void MV_CreateVolumeTable( int index, int volume, int MaxVolume ); +void MV_SetVolume( int volume ); +int MV_GetVolume( void ); +void MV_SetCallBack( void ( *function )( unsigned long ) ); +void MV_SetReverseStereo( int setting ); +int MV_GetReverseStereo( void ); +int MV_Init( int soundcard, int MixRate, int Voices, int numchannels, + int samplebits ); +int MV_Shutdown( void ); + +void MV_Update(void); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/music.c b/polymer/eduke32/source/jaudiolib/music.c new file mode 100644 index 000000000..2e396d0e1 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/music.c @@ -0,0 +1,595 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: MUSIC.C + + author: James R. Dose + date: March 25, 1994 + + Device independant music playback routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +#include +#include "music.h" +#include "midi.h" +#include "mpu401.h" + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + +#ifdef __MINGW32__ +#define max(a,b) (((a)>(b))?(a):(b)) +#define min(a,b) (((a)<(b))?(a):(b)) +#endif + +int MUSIC_SoundDevice = -1; +int MUSIC_ErrorCode = MUSIC_Ok; + +static midifuncs MUSIC_MidiFunctions; + +static int MUSIC_FadeLength; +static int MUSIC_FadeRate; +static unsigned MUSIC_CurrentFadeVolume; +static unsigned MUSIC_LastFadeVolume; +static int MUSIC_EndingFadeVolume; + +int MUSIC_InitMidi( int card, midifuncs *Funcs, int Address ); + +#define MUSIC_SetErrorCode( status ) \ + MUSIC_ErrorCode = ( status ); + +/*--------------------------------------------------------------------- + Function: MUSIC_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +char *MUSIC_ErrorString + ( + int ErrorNumber + ) + + { + char *ErrorString; + + switch( ErrorNumber ) + { + case MUSIC_Warning : + case MUSIC_Error : + ErrorString = MUSIC_ErrorString( MUSIC_ErrorCode ); + break; + + case MUSIC_Ok : + ErrorString = "Music ok."; + break; + + case MUSIC_ASSVersion : + ErrorString = "Apogee Sound System Version WinMM " + "Programmed by Jim Dose, Ported by Jonathon Fowler\n" + "(c) Copyright 1996 James R. Dose. All Rights Reserved.\n"; + break; + + case MUSIC_SoundCardError : + case MUSIC_MPU401Error : + ErrorString = "Could not detect MPU-401."; + break; + + case MUSIC_InvalidCard : + ErrorString = "Invalid Music device."; + break; + + case MUSIC_MidiError : + ErrorString = "Error playing MIDI file."; + break; + + case MUSIC_TaskManError : + ErrorString = "TaskMan error."; + break; + + case MUSIC_DPMI_Error : + ErrorString = "DPMI Error in MUSIC."; + break; + + default : + ErrorString = "Unknown Music error code."; + break; + } + + return( ErrorString ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +int MUSIC_Init + ( + int SoundCard, + int Address + ) + + { + int i; + int status; + + for( i = 0; i < 128; i++ ) + { + MIDI_PatchMap[ i ] = i; + } + + MUSIC_SoundDevice = SoundCard; + + status = MUSIC_InitMidi( SoundCard, &MUSIC_MidiFunctions, Address ); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int MUSIC_Shutdown + ( + void + ) + + { + int status; + + status = MUSIC_Ok; + + MIDI_StopSong(); + + //MPU_Reset(); + + return( status ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetVolume + + Sets the volume of music playback. +---------------------------------------------------------------------*/ + +void MUSIC_SetVolume + ( + int volume + ) + + { + volume = max( 0, volume ); + volume = min( volume, 255 ); + + if ( MUSIC_SoundDevice != -1 ) + { + MIDI_SetVolume( volume ); + } + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetMidiChannelVolume + + Sets the volume of music playback on the specified MIDI channel. +---------------------------------------------------------------------*/ + +void MUSIC_SetMidiChannelVolume + ( + int channel, + int volume + ) + + { + MIDI_SetUserChannelVolume( channel, volume ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_ResetMidiChannelVolumes + + Sets the volume of music playback on all MIDI channels to full volume. +---------------------------------------------------------------------*/ + +void MUSIC_ResetMidiChannelVolumes + ( + void + ) + + { + MIDI_ResetUserChannelVolume(); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetVolume + + Returns the volume of music playback. +---------------------------------------------------------------------*/ + +int MUSIC_GetVolume + ( + void + ) + + { + if ( MUSIC_SoundDevice == -1 ) + { + return( 0 ); + } + return( MIDI_GetVolume() ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetLoopFlag + + Set whether the music will loop or end when it reaches the end of + the song. +---------------------------------------------------------------------*/ + +void MUSIC_SetLoopFlag + ( + int loopflag + ) + + { + MIDI_SetLoopFlag( loopflag ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SongPlaying + + Returns whether there is a song playing. +---------------------------------------------------------------------*/ + +int MUSIC_SongPlaying + ( + void + ) + + { + return( MIDI_SongPlaying() ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Continue + + Continues playback of a paused song. +---------------------------------------------------------------------*/ + +void MUSIC_Continue + ( + void + ) + + { + MIDI_ContinueSong(); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_Pause + + Pauses playback of a song. +---------------------------------------------------------------------*/ + +void MUSIC_Pause + ( + void + ) + + { + MIDI_PauseSong(); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_StopSong + + Stops playback of current song. +---------------------------------------------------------------------*/ + +int MUSIC_StopSong + ( + void + ) + + { + MUSIC_StopFade(); + MIDI_StopSong(); + MUSIC_SetErrorCode( MUSIC_Ok ); + return( MUSIC_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_PlaySong + + Begins playback of MIDI song. +---------------------------------------------------------------------*/ + +int MUSIC_PlaySong + ( + unsigned char *song, + int loopflag + ) + + { + int status; + + MUSIC_StopSong(); + + status = MIDI_PlaySong( song, loopflag ); + if ( status != MIDI_Ok ) + { + MUSIC_SetErrorCode( MUSIC_MidiError ); + return( MUSIC_Warning ); + } + + return( MUSIC_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetContext + + Sets the song context. +---------------------------------------------------------------------*/ + +void MUSIC_SetContext + ( + int context + ) + + { + MIDI_SetContext( context ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetContext + + Returns the current song context. +---------------------------------------------------------------------*/ + +int MUSIC_GetContext + ( + void + ) + + { + return MIDI_GetContext(); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongTick + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongTick + ( + unsigned long PositionInTicks + ) + + { + MIDI_SetSongTick( PositionInTicks ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongTime + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongTime + ( + unsigned long milliseconds + ) + + { + MIDI_SetSongTime( milliseconds ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_SetSongPosition + + Sets the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_SetSongPosition + ( + int measure, + int beat, + int tick + ) + + { + MIDI_SetSongPosition( measure, beat, tick ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetSongPosition + + Returns the position of the song pointer. +---------------------------------------------------------------------*/ + +void MUSIC_GetSongPosition + ( + songposition *pos + ) + + { + MIDI_GetSongPosition( pos ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_GetSongLength + + Returns the length of the song. +---------------------------------------------------------------------*/ + +void MUSIC_GetSongLength + ( + songposition *pos + ) + + { + MIDI_GetSongLength( pos ); + } + + +int MUSIC_InitMidi + ( + int card, + midifuncs *Funcs, + int Address + ) + + { + int status; + + Funcs->NoteOff = MPU_NoteOff; + Funcs->NoteOn = MPU_NoteOn; + Funcs->PolyAftertouch = MPU_PolyAftertouch; + Funcs->ControlChange = MPU_ControlChange; + Funcs->ProgramChange = MPU_ProgramChange; + Funcs->ChannelAftertouch = MPU_ChannelAftertouch; + Funcs->PitchBend = MPU_PitchBend; + Funcs->ReleasePatches = NULL; + Funcs->LoadPatch = NULL; + Funcs->SetVolume = NULL /*MPU_SetVolume*/; + Funcs->GetVolume = NULL /*MPU_GetVolume*/; + + MIDI_SetMidiFuncs( Funcs ); + + return( MIDI_Ok ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_FadeVolume + + Fades music volume from current level to another over a specified + period of time. +---------------------------------------------------------------------*/ + +int MUSIC_FadeVolume + ( + int tovolume, + int milliseconds + ) + + { + int fromvolume; + + MIDI_SetVolume( tovolume ); + return( MUSIC_Ok ); +} + + +/*--------------------------------------------------------------------- + Function: MUSIC_FadeActive + + Returns whether the fade routine is active. +---------------------------------------------------------------------*/ + +int MUSIC_FadeActive + ( + void + ) + + { + return( 0 ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_StopFade + + Stops fading the music. +---------------------------------------------------------------------*/ + +void MUSIC_StopFade + ( + void + ) + + { + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_RerouteMidiChannel + + Sets callback function to reroute MIDI commands from specified + function. +---------------------------------------------------------------------*/ + +void MUSIC_RerouteMidiChannel + ( + int channel, + int ( *function )( int event, int c1, int c2 ) + ) + + { + MIDI_RerouteMidiChannel( channel, function ); + } + + +/*--------------------------------------------------------------------- + Function: MUSIC_RegisterTimbreBank + + Halts playback of all sounds. +---------------------------------------------------------------------*/ + +void MUSIC_RegisterTimbreBank + ( + unsigned char *timbres + ) + + { + } + + +void MUSIC_Update(void) +{ + MIDI_UpdateMusic(); +} + diff --git a/polymer/eduke32/source/jaudiolib/music.h b/polymer/eduke32/source/jaudiolib/music.h new file mode 100644 index 000000000..028790d92 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/music.h @@ -0,0 +1,90 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: MUSIC.H + + author: James R. Dose + date: March 25, 1994 + + Public header for MUSIC.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __MUSIC_H +#define __MUSIC_H + +extern int MUSIC_ErrorCode; + +enum MUSIC_ERRORS + { + MUSIC_Warning = -2, + MUSIC_Error = -1, + MUSIC_Ok = 0, + MUSIC_ASSVersion, + MUSIC_SoundCardError, + MUSIC_MPU401Error, + MUSIC_InvalidCard, + MUSIC_MidiError, + MUSIC_TaskManError, + MUSIC_DPMI_Error + }; + +typedef struct + { + unsigned long tickposition; + unsigned long milliseconds; + unsigned int measure; + unsigned int beat; + unsigned int tick; + } songposition; + +#define MUSIC_LoopSong ( 1 == 1 ) +#define MUSIC_PlayOnce ( !MUSIC_LoopSong ) + +char *MUSIC_ErrorString( int ErrorNumber ); +int MUSIC_Init( int SoundCard, int Address ); +int MUSIC_Shutdown( void ); +void MUSIC_SetVolume( int volume ); +void MUSIC_SetMidiChannelVolume( int channel, int volume ); +void MUSIC_ResetMidiChannelVolumes( void ); +int MUSIC_GetVolume( void ); +void MUSIC_SetLoopFlag( int loopflag ); +int MUSIC_SongPlaying( void ); +void MUSIC_Continue( void ); +void MUSIC_Pause( void ); +int MUSIC_StopSong( void ); +int MUSIC_PlaySong( unsigned char *song, int loopflag ); +void MUSIC_SetContext( int context ); +int MUSIC_GetContext( void ); +void MUSIC_SetSongTick( unsigned long PositionInTicks ); +void MUSIC_SetSongTime( unsigned long milliseconds ); +void MUSIC_SetSongPosition( int measure, int beat, int tick ); +void MUSIC_GetSongPosition( songposition *pos ); +void MUSIC_GetSongLength( songposition *pos ); +int MUSIC_FadeVolume( int tovolume, int milliseconds ); +int MUSIC_FadeActive( void ); +void MUSIC_StopFade( void ); +void MUSIC_RerouteMidiChannel( int channel, int ( *function )( int event, int c1, int c2 ) ); +void MUSIC_RegisterTimbreBank( unsigned char *timbres ); +void MUSIC_Update(void); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/mv_mix.masm b/polymer/eduke32/source/jaudiolib/mv_mix.masm new file mode 100644 index 000000000..92742de36 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix.masm @@ -0,0 +1,487 @@ +.586P + +EXTRN _MV_HarshClipTable : dword +EXTRN _MV_MixDestination : dword +EXTRN _MV_MixPosition : dword +EXTRN _MV_LeftVolume : dword +EXTRN _MV_RightVolume : dword +EXTRN _MV_SampleSize : dword +EXTRN _MV_RightChannelOffset : dword + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +;================ +; +; MV_Mix8BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix8BitMono +_MV_Mix8BitMono: +; Two at once + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [apatch7+2],bl + mov byte ptr [apatch8+2],bl + mov byte ptr [apatch9+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume ; Since we're mono, use left volume + mov dword ptr [apatch1+4],ebx + mov dword ptr [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx, 128 + mov dword ptr [apatch3+2],ebx + mov dword ptr [apatch4+2],ebx + + ; Rate scale ptr + mov dword ptr [apatch5+2],edx + mov dword ptr [apatch6+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je short exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte ptr [esi+eax] ; get first sample + movzx ebx, byte ptr [esi+ebx] ; get second sample + +;ALIGN 4 +mix8Mloop: + movzx edx, byte ptr [edi] ; get current sample from destination +apatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte ptr [edi + 1] ; get current sample from destination +apatch3: + mov eax, [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 1 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte ptr [esi+eax] ; get fourth sample + movzx eax, byte ptr [esi+edx] ; get third sample +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix8BitStereo +_MV_Mix8BitStereo: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [bpatch8+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [bpatch6+3],ebx + mov dword ptr [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [bpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [bpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx,128 + mov dword ptr [bpatch4+2],ebx + mov dword ptr [bpatch5+2],ebx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short exit8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte ptr [esi+eax] ; get first sample + +;ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte ptr [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte ptr [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov [edi], al ; write left sample to destination +bpatch5: + mov ebx, [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 2 ; move destination to second sample + movzx ebx, byte ptr [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix16BitMono +_MV_Mix16BitMono: +; Two at once + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [cpatch5+3],bl + mov byte ptr [cpatch6+3],bl + add bl,bl + mov byte ptr [cpatch7+2],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [cpatch1+4],ebx + mov dword ptr [cpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [cpatch3+2],edx + mov dword ptr [cpatch4+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je exit16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte ptr [esi+eax] ; get first sample + movzx ebx, byte ptr [esi+ebx] ; get second sample + +;ALIGN 4 +mix16Mloop: + movsx edx, word ptr [edi] ; get current sample from destination +cpatch1: + movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample +cpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +cpatch5: + movsx edx, word ptr [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + add ebx, edx ; mix second sample + mov [edi], ax ; write new sample to destination + mov edx, ebp ; begin calculating third sample + + cmp ebx, -32768 ; Harsh clip sample + jge short m16skip3 + mov ebx, -32768 + jmp short m16skip4 +m16skip3: + cmp ebx, 32767 + jle short m16skip4 + mov ebx, 32767 +m16skip4: +cpatch3: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +cpatch6: + mov [edi + 2], bx ; write new sample to destination + shr eax, 16 ; finish calculation for fourth sample + +cpatch4: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte ptr [esi+eax] ; get fourth sample +cpatch7: + add edi, 4 ; move destination to third sample + movzx eax, byte ptr [esi+edx] ; get third sample + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix16BitStereo +_MV_Mix16BitStereo: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [dpatch6+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [dpatch4+3],ebx + mov dword ptr [dpatch5+3],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [dpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [dpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [dpatch3+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte ptr [esi+eax] ; get first sample + +;ALIGN 4 +mix16Sloop: +dpatch1: + movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample + movsx edx, word ptr [edi] ; get current sample from destination +dpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +dpatch3: + add ebp,12345678h ; advance frac pointer +dpatch4: + movsx edx, word ptr [edi+12345678h] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + add ebx, edx ; mix right sample + mov [edi], ax ; write left sample to destination + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch5: + mov [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch6: + add edi, 4 ; move destination to second sample + movzx ebx, byte ptr [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit16S: + popad + ret + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/mv_mix.nasm b/polymer/eduke32/source/jaudiolib/mv_mix.nasm new file mode 100644 index 000000000..af01017f5 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix.nasm @@ -0,0 +1,524 @@ +;Copyright (C) 1994-1995 Apogee Software, Ltd. +; +;This program is free software; you can redistribute it and/or +;modify it under the terms of the GNU General Public License +;as published by the Free Software Foundation; either version 2 +;of the License, or (at your option) any later version. +; +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; +;See the GNU General Public License for more details. +; +;You should have received a copy of the GNU General Public License +;along with this program; if not, write to the Free Software +;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; +;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) + +CPU 386 + +SECTION .data + +%ifdef UNDERSCORES + +%define MV_Mix8BitMono _MV_Mix8BitMono +%define MV_Mix8BitStereo _MV_Mix8BitStereo +%define MV_Mix16BitMono _MV_Mix16BitMono +%define MV_Mix16BitStereo _MV_Mix16BitStereo + +%else + +%define _MV_HarshClipTable MV_HarshClipTable +%define _MV_MixDestination MV_MixDestination +%define _MV_MixPosition MV_MixPosition +%define _MV_LeftVolume MV_LeftVolume +%define _MV_RightVolume MV_RightVolume +%define _MV_SampleSize MV_SampleSize +%define _MV_RightChannelOffset MV_RightChannelOffset + +%endif + + EXTERN _MV_HarshClipTable + EXTERN _MV_MixDestination + EXTERN _MV_MixPosition + EXTERN _MV_LeftVolume + EXTERN _MV_RightVolume + EXTERN _MV_SampleSize + EXTERN _MV_RightChannelOffset + + GLOBAL MV_Mix8BitMono + GLOBAL MV_Mix8BitStereo + GLOBAL MV_Mix16BitMono + GLOBAL MV_Mix16BitStereo + + +;================ +; +; MV_Mix8BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix8BitMono: +; Two at once + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [apatch7+2],bl + mov byte [apatch8+2],bl + mov byte [apatch9+3],bl + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] ; Since we're mono, use left volume + mov dword [apatch1+4],ebx + mov dword [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, dword [_MV_HarshClipTable] + add ebx, 128 + mov dword [apatch3+2],ebx + mov dword [apatch4+2],ebx + + ; Rate scale ptr + mov dword [apatch5+2],edx + mov dword [apatch6+2],edx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je short exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte [esi+eax] ; get first sample + movzx ebx, byte [esi+ebx] ; get second sample + + ALIGN 4 +mix8Mloop: + movzx edx, byte [edi] ; get current sample from destination +apatch1: + movsx eax, byte [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte [edi + 1] ; get current sample from destination +apatch3: + mov eax, dword [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov byte [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, dword [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 1 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov byte [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte [esi+eax] ; get fourth sample + movzx eax, byte [esi+edx] ; get third sample +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix8BitStereo: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [bpatch8+2],bl + + ; Right channel offset + mov ebx, dword [_MV_RightChannelOffset] + mov dword [bpatch6+3],ebx + mov dword [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [bpatch1+4],ebx + + mov ebx, dword [_MV_RightVolume] + mov dword [bpatch2+4],ebx + + ; Rate scale ptr + mov dword [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, dword [_MV_HarshClipTable] + add ebx,128 + mov dword [bpatch4+2],ebx + mov dword [bpatch5+2],ebx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short EXIT8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte [esi+eax] ; get first sample + + ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, dword [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov byte [edi], al ; write left sample to destination +bpatch5: + mov ebx, dword [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov byte [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 2 ; move destination to second sample + movzx ebx, byte [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix16BitMono: +; Two at once + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [cpatch5+3],bl + mov byte [cpatch6+3],bl + add bl,bl + mov byte [cpatch7+2],bl + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [cpatch1+4],ebx + mov dword [cpatch2+4],ebx + + ; Rate scale ptr + mov dword [cpatch3+2],edx + mov dword [cpatch4+2],edx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je near EXIT16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte [esi+eax] ; get first sample + movzx ebx, byte [esi+ebx] ; get second sample + + ALIGN 4 +mix16Mloop: + movsx edx, word [edi] ; get current sample from destination +cpatch1: + movsx eax, word [2*eax+12345678h] ; volume translate first sample +cpatch2: + movsx ebx, word [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +cpatch5: + movsx edx, word [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + add ebx, edx ; mix second sample + mov word [edi], ax ; write new sample to destination + mov edx, ebp ; begin calculating third sample + + cmp ebx, -32768 ; Harsh clip sample + jge short m16skip3 + mov ebx, -32768 + jmp short m16skip4 +m16skip3: + cmp ebx, 32767 + jle short m16skip4 + mov ebx, 32767 +m16skip4: +cpatch3: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +cpatch6: + mov word [edi + 2], bx ; write new sample to destination + shr eax, 16 ; finish calculation for fourth sample + +cpatch4: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte [esi+eax] ; get fourth sample +cpatch7: + add edi, 4 ; move destination to third sample + movzx eax, byte [esi+edx] ; get third sample + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix16BitStereo: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [dpatch6+2],bl + + ; Right channel offset + mov ebx, dword [_MV_RightChannelOffset] + mov dword [dpatch4+3],ebx + mov dword [dpatch5+3],ebx + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [dpatch1+4],ebx + + mov ebx, dword [_MV_RightVolume] + mov dword [dpatch2+4],ebx + + ; Rate scale ptr + mov dword [dpatch3+2],edx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je near exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte [esi+eax] ; get first sample + + ALIGN 4 +mix16Sloop: +dpatch1: + movsx eax, word [2*ebx+12345678h] ; volume translate left sample + movsx edx, word [edi] ; get current sample from destination +dpatch2: + movsx ebx, word [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +dpatch3: + add ebp,12345678h ; advance frac pointer +dpatch4: + movsx edx, word [edi+12345678h] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + add ebx, edx ; mix right sample + mov word [edi], ax ; write left sample to destination + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch5: + mov word [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch6: + add edi, 4 ; move destination to second sample + movzx ebx, byte [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +exit16S: + popad + ret + diff --git a/polymer/eduke32/source/jaudiolib/mv_mix.wasm b/polymer/eduke32/source/jaudiolib/mv_mix.wasm new file mode 100644 index 000000000..7f6ca7971 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix.wasm @@ -0,0 +1,491 @@ +.586P + +EXTRN _MV_HarshClipTable : dword +EXTRN _MV_MixDestination : dword +EXTRN _MV_MixPosition : dword +EXTRN _MV_LeftVolume : dword +EXTRN _MV_RightVolume : dword +EXTRN _MV_SampleSize : dword +EXTRN _MV_RightChannelOffset : dword + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +;================ +; +; MV_Mix8BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix8BitMono_ +MV_Mix8BitMono_: +; Two at once + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [apatch7+2],bl + mov byte ptr [apatch8+2],bl + mov byte ptr [apatch9+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume ; Since we're mono, use left volume + mov dword ptr [apatch1+4],ebx + mov dword ptr [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx, 128 + mov dword ptr [apatch3+2],ebx + mov dword ptr [apatch4+2],ebx + + ; Rate scale ptr + mov dword ptr [apatch5+2],edx + mov dword ptr [apatch6+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je short exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte ptr [esi+eax] ; get first sample + movzx ebx, byte ptr [esi+ebx] ; get second sample + +;ALIGN 4 +mix8Mloop: + movzx edx, byte ptr [edi] ; get current sample from destination +apatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte ptr [edi + 1] ; get current sample from destination +apatch3: + mov eax, [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 1 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte ptr [esi+eax] ; get fourth sample + movzx eax, byte ptr [esi+edx] ; get third sample +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix8BitStereo_ +MV_Mix8BitStereo_: + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [bpatch8+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [bpatch6+3],ebx + mov dword ptr [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [bpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [bpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx,128 + mov dword ptr [bpatch4+2],ebx + mov dword ptr [bpatch5+2],ebx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short exit8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte ptr [esi+eax] ; get first sample + +;ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte ptr [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte ptr [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov [edi], al ; write left sample to destination +bpatch5: + mov ebx, [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 2 ; move destination to second sample + movzx ebx, byte ptr [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix16BitMono_ +MV_Mix16BitMono_: +; Two at once + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [cpatch5+3],bl + mov byte ptr [cpatch6+3],bl + add bl,bl + mov byte ptr [cpatch7+2],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [cpatch1+4],ebx + mov dword ptr [cpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [cpatch3+2],edx + mov dword ptr [cpatch4+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je exit16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movzx eax, byte ptr [esi+eax] ; get first sample + movzx ebx, byte ptr [esi+ebx] ; get second sample + +;ALIGN 4 +mix16Mloop: + movsx edx, word ptr [edi] ; get current sample from destination +cpatch1: + movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample +cpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +cpatch5: + movsx edx, word ptr [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + add ebx, edx ; mix second sample + mov [edi], ax ; write new sample to destination + mov edx, ebp ; begin calculating third sample + + cmp ebx, -32768 ; Harsh clip sample + jge short m16skip3 + mov ebx, -32768 + jmp short m16skip4 +m16skip3: + cmp ebx, 32767 + jle short m16skip4 + mov ebx, 32767 +m16skip4: +cpatch3: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +cpatch6: + mov [edi + 2], bx ; write new sample to destination + shr eax, 16 ; finish calculation for fourth sample + +cpatch4: + add ebp,12345678h ; advance frac pointer + movzx ebx, byte ptr [esi+eax] ; get fourth sample +cpatch7: + add edi, 4 ; move destination to third sample + movzx eax, byte ptr [esi+edx] ; get third sample + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix16BitStereo_ +MV_Mix16BitStereo_: + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [dpatch6+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [dpatch4+3],ebx + mov dword ptr [dpatch5+3],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [dpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [dpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [dpatch3+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movzx ebx, byte ptr [esi+eax] ; get first sample + +;ALIGN 4 +mix16Sloop: +dpatch1: + movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample + movsx edx, word ptr [edi] ; get current sample from destination +dpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +dpatch3: + add ebp,12345678h ; advance frac pointer +dpatch4: + movsx edx, word ptr [edi+12345678h] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + add ebx, edx ; mix right sample + mov [edi], ax ; write left sample to destination + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch5: + mov [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch6: + add edi, 4 ; move destination to second sample + movzx ebx, byte ptr [esi+edx] ; get second sample + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit16S: + popad + ret + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/mv_mix16.masm b/polymer/eduke32/source/jaudiolib/mv_mix16.masm new file mode 100644 index 000000000..a949ba915 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix16.masm @@ -0,0 +1,507 @@ +.586P + +EXTRN _MV_HarshClipTable:DWORD +EXTRN _MV_MixDestination:DWORD +EXTRN _MV_MixPosition:DWORD +EXTRN _MV_LeftVolume:DWORD +EXTRN _MV_RightVolume:DWORD +EXTRN _MV_SampleSize:DWORD +EXTRN _MV_RightChannelOffset:DWORD + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + + +;================ +; +; MV_Mix8BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix8BitMono16 +_MV_Mix8BitMono16: +; Two at once + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [apatch7+2],bl + mov byte ptr [apatch8+2],bl + mov byte ptr [apatch9+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume ; Since we're mono, use left volume + mov dword ptr [apatch1+4],ebx + mov dword ptr [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx, 128 + mov dword ptr [apatch3+2],ebx + mov dword ptr [apatch4+2],ebx + + ; Rate scale ptr + mov dword ptr [apatch5+2],edx + mov dword ptr [apatch6+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movsx eax, byte ptr [esi+2*eax] ; get first sample + movsx ebx, byte ptr [esi+2*ebx] ; get second sample + add eax, 80h + add ebx, 80h + +;ALIGN 4 +mix8Mloop: + movzx edx, byte ptr [edi] ; get current sample from destination +apatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte ptr [edi + 1] ; get current sample from destination +apatch3: + mov eax, [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 2 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movsx ebx, byte ptr [esi+2*eax] ; get fourth sample + movsx eax, byte ptr [esi+2*edx] ; get third sample + add ebx, 80h + add eax, 80h +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix8BitStereo16 +_MV_Mix8BitStereo16: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [bpatch8+2],bl + ; mov byte ptr [bpatch9+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [bpatch6+3],ebx + mov dword ptr [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [bpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [bpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx,128 + mov dword ptr [bpatch4+2],ebx + mov dword ptr [bpatch5+2],ebx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short exit8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movsx ebx, byte ptr [esi+2*eax] ; get first sample + add ebx, 80h + +;ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte ptr [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte ptr [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov [edi], al ; write left sample to destination +bpatch5: + mov ebx, [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 1 ; move destination to second sample + movsx ebx, byte ptr [esi+2*edx] ; get second sample + add ebx, 80h + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix16BitMono16 +_MV_Mix16BitMono16: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [cpatch4+2],bl + mov byte ptr [cpatch5+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [cpatch2+4],ebx + inc ebx + mov dword ptr [cpatch1+4],ebx + + ; Rate scale ptr + mov dword ptr [cpatch3+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov ebx,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for first sample + movzx eax, word ptr [esi+2*ebx] ; get low byte of sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + movsx edx, word ptr [edi] ; get current sample from destination + +;ALIGN 4 +mix16Mloop: +cpatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample +cpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + add eax, edx ; mix low byte of sample +cpatch5: + movsx edx, word ptr [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + mov ebx, ebp ; begin calculating second sample + mov [edi], ax ; write new sample to destination + + shr ebx, 16 ; finish calculation for second sample +cpatch3: + add ebp, 12345678h ; advance frac pointer + + movzx eax, word ptr [esi+2*ebx] ; get second sample +cpatch4: + add edi, 2 ; move destination to second sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC _MV_Mix16BitStereo16 +_MV_Mix16BitStereo16: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [dpatch9+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [dpatch7+3],ebx + mov dword ptr [dpatch8+3],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [dpatch1+4],ebx + inc ebx + mov dword ptr [dpatch2+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [dpatch3+4],ebx + inc ebx + mov dword ptr [dpatch4+4],ebx + + ; Rate scale ptr + mov dword ptr [dpatch5+2],edx + + ; Source ptr + mov dword ptr [dpatch6+4],esi + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; esi - scratch +; ecx - count +; edi - destination +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov ebx,ebp ; begin calculating first sample + shr ebx,16 ; finish calculation for first sample + + movzx edx, word ptr [esi+2*ebx] ; get first sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + +;ALIGN 4 +mix16Sloop: + ; Left channel +dpatch1: + movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample +dpatch2: + movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + + ; Right channel +dpatch3: + movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample +dpatch4: + movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample + lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample + +dpatch7: + movsx edx, word ptr [edi+12345678h] ; get current sample from destination +dpatch5: + add ebp,12345678h ; advance frac pointer + + add eax, edx ; mix left sample + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + movsx edx, word ptr [edi+2] ; get current sample from destination + mov [edi], ax ; write left sample to destination + add ebx, edx ; mix right sample + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch8: + mov [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch9: + add edi, 4 ; move destination to second sample + +dpatch6: + movzx edx, word ptr [2*edx+12345678h] ; get second sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit16S: + popad + ret + + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/mv_mix16.nasm b/polymer/eduke32/source/jaudiolib/mv_mix16.nasm new file mode 100644 index 000000000..110329ecb --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix16.nasm @@ -0,0 +1,544 @@ +;Copyright (C) 1994-1995 Apogee Software, Ltd. +; +;This program is free software; you can redistribute it and/or +;modify it under the terms of the GNU General Public License +;as published by the Free Software Foundation; either version 2 +;of the License, or (at your option) any later version. +; +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; +;See the GNU General Public License for more details. +; +;You should have received a copy of the GNU General Public License +;along with this program; if not, write to the Free Software +;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; +;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) + + +CPU 386 + +SECTION .data + +%ifdef UNDERSCORES + +%define MV_Mix8BitMono16 _MV_Mix8BitMono16 +%define MV_Mix8BitStereo16 _MV_Mix8BitStereo16 +%define MV_Mix16BitMono16 _MV_Mix16BitMono16 +%define MV_Mix16BitStereo16 _MV_Mix16BitStereo16 + +%else + +%define _MV_HarshClipTable MV_HarshClipTable +%define _MV_MixDestination MV_MixDestination +%define _MV_MixPosition MV_MixPosition +%define _MV_LeftVolume MV_LeftVolume +%define _MV_RightVolume MV_RightVolume +%define _MV_SampleSize MV_SampleSize +%define _MV_RightChannelOffset MV_RightChannelOffset + +%endif + + EXTERN _MV_HarshClipTable + EXTERN _MV_MixDestination + EXTERN _MV_MixPosition + EXTERN _MV_LeftVolume + EXTERN _MV_RightVolume + EXTERN _MV_SampleSize + EXTERN _MV_RightChannelOffset + + GLOBAL MV_Mix8BitMono16 + GLOBAL MV_Mix8BitStereo16 + GLOBAL MV_Mix16BitMono16 + GLOBAL MV_Mix16BitStereo16 + +%define OFFSET + +;================ +; +; MV_Mix8BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix8BitMono16: +; Two at once + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [apatch7+2],bl + mov byte [apatch8+2],bl + mov byte [apatch9+3],bl + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] ; Since we're mono, use left volume + mov dword [apatch1+4],ebx + mov dword [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, dword [_MV_HarshClipTable] + add ebx, 128 + mov dword [apatch3+2],ebx + mov dword [apatch4+2],ebx + + ; Rate scale ptr + mov dword [apatch5+2],edx + mov dword [apatch6+2],edx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je near exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movsx eax, byte [esi+2*eax] ; get first sample + movsx ebx, byte [esi+2*ebx] ; get second sample + add eax, 80h + add ebx, 80h + + ALIGN 4 +mix8Mloop: + movzx edx, byte [edi] ; get current sample from destination +apatch1: + movsx eax, byte [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte [edi + 1] ; get current sample from destination +apatch3: + mov eax, dword [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov byte [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, dword [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 2 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov byte [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movsx ebx, byte [esi+2*eax] ; get fourth sample + movsx eax, byte [esi+2*edx] ; get third sample + add ebx, 80h + add eax, 80h +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix8BitStereo16: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [bpatch8+2],bl + ; mov byte [bpatch9+2],bl + + ; Right channel offset + mov ebx, dword [_MV_RightChannelOffset] + mov dword [bpatch6+3],ebx + mov dword [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [bpatch1+4],ebx + + mov ebx, dword [_MV_RightVolume] + mov dword [bpatch2+4],ebx + + ; Rate scale ptr + mov dword [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, dword [_MV_HarshClipTable] + add ebx,128 + mov dword [bpatch4+2],ebx + mov dword [bpatch5+2],ebx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short EXIT8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movsx ebx, byte [esi+2*eax] ; get first sample + add ebx, 80h + + ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, dword [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov byte [edi], al ; write left sample to destination +bpatch5: + mov ebx, dword [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov byte [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 1 ; move destination to second sample + movsx ebx, byte [esi+2*edx] ; get second sample + add ebx, 80h + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix16BitMono16: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [cpatch4+2],bl + mov byte [cpatch5+3],bl + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [cpatch2+4],ebx + inc ebx + mov dword [cpatch1+4],ebx + + ; Rate scale ptr + mov dword [cpatch3+2],edx + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je near EXIT16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov ebx,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for first sample + movzx eax, word [esi+2*ebx] ; get low byte of sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + movsx edx, word [edi] ; get current sample from destination + + ALIGN 4 +mix16Mloop: +cpatch1: + movsx eax, byte [2*eax+12345678h] ; volume translate low byte of sample +cpatch2: + movsx ebx, word [2*ebx+12345678h] ; volume translate high byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + add eax, edx ; mix low byte of sample +cpatch5: + movsx edx, word [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + mov ebx, ebp ; begin calculating second sample + mov word [edi], ax ; write new sample to destination + + shr ebx, 16 ; finish calculation for second sample +cpatch3: + add ebp, 12345678h ; advance frac pointer + + movzx eax, word [esi+2*ebx] ; get second sample +cpatch4: + add edi, 2 ; move destination to second sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + + ALIGN 4 +MV_Mix16BitStereo16: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, dword [_MV_SampleSize] + mov byte [dpatch9+2],bl + + ; Right channel offset + mov ebx, dword [_MV_RightChannelOffset] + mov dword [dpatch7+3],ebx + mov dword [dpatch8+3],ebx + + ; Volume table ptr + mov ebx, dword [_MV_LeftVolume] + mov dword [dpatch1+4],ebx + inc ebx + mov dword [dpatch2+4],ebx + + mov ebx, dword [_MV_RightVolume] + mov dword [dpatch3+4],ebx + inc ebx + mov dword [dpatch4+4],ebx + + ; Rate scale ptr + mov dword [dpatch5+2],edx + + ; Source ptr + mov dword [dpatch6+4],esi + + mov edi, dword [_MV_MixDestination] ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je near exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; esi - scratch +; ecx - count +; edi - destination +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov ebx,ebp ; begin calculating first sample + shr ebx,16 ; finish calculation for first sample + + movzx edx, word [esi+2*ebx] ; get first sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + + ALIGN 4 +mix16Sloop: + ; Left channel +dpatch1: + movsx eax, word [2*esi+12345678h] ; volume translate high byte of sample +dpatch2: + movsx ebx, byte [2*edx+12345678h] ; volume translate low byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + + ; Right channel +dpatch3: + movsx esi, word [2*esi+12345678h] ; volume translate high byte of sample +dpatch4: + movsx ebx, byte [2*edx+12345678h] ; volume translate low byte of sample + lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample + +dpatch7: + movsx edx, word [edi+12345678h] ; get current sample from destination +dpatch5: + add ebp,12345678h ; advance frac pointer + + add eax, edx ; mix left sample + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + movsx edx, word [edi+2] ; get current sample from destination + mov word [edi], ax ; write left sample to destination + add ebx, edx ; mix right sample + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch8: + mov word [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch9: + add edi, 4 ; move destination to second sample + +dpatch6: + movzx edx, word [2*edx+12345678h] ; get second sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov dword [_MV_MixDestination], edi ; Store the current write position + mov dword [_MV_MixPosition], ebp ; return position +exit16S: + popad + ret + diff --git a/polymer/eduke32/source/jaudiolib/mv_mix16.wasm b/polymer/eduke32/source/jaudiolib/mv_mix16.wasm new file mode 100644 index 000000000..3d6e711d6 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mv_mix16.wasm @@ -0,0 +1,511 @@ +.586P + +EXTRN _MV_HarshClipTable:DWORD +EXTRN _MV_MixDestination:DWORD +EXTRN _MV_MixPosition:DWORD +EXTRN _MV_LeftVolume:DWORD +EXTRN _MV_RightVolume:DWORD +EXTRN _MV_SampleSize:DWORD +EXTRN _MV_RightChannelOffset:DWORD + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + + +;================ +; +; MV_Mix8BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix8BitMono16_ +MV_Mix8BitMono16_: +; Two at once + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [apatch7+2],bl + mov byte ptr [apatch8+2],bl + mov byte ptr [apatch9+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume ; Since we're mono, use left volume + mov dword ptr [apatch1+4],ebx + mov dword ptr [apatch2+4],ebx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx, 128 + mov dword ptr [apatch3+2],ebx + mov dword ptr [apatch4+2],ebx + + ; Rate scale ptr + mov dword ptr [apatch5+2],edx + mov dword ptr [apatch6+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + shr ecx, 1 ; double sample count + cmp ecx, 0 + je exit8m + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; apatch1 - volume table +; apatch2 - volume table +; apatch3 - harsh clip table +; apatch4 - harsh clip table +; apatch5 - sample rate +; apatch6 - sample rate + + mov eax,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr eax,16 ; finish calculation for first sample + + mov ebx,ebp ; begin calculating second sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for second sample + + movsx eax, byte ptr [esi+2*eax] ; get first sample + movsx ebx, byte ptr [esi+2*ebx] ; get second sample + add eax, 80h + add ebx, 80h + +;ALIGN 4 +mix8Mloop: + movzx edx, byte ptr [edi] ; get current sample from destination +apatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample +apatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample + add eax, edx ; mix first sample +apatch9: + movzx edx, byte ptr [edi + 1] ; get current sample from destination +apatch3: + mov eax, [eax + 12345678h] ; harsh clip new sample + add ebx, edx ; mix second sample + mov [edi], al ; write new sample to destination + mov edx, ebp ; begin calculating third sample +apatch4: + mov ebx, [ebx + 12345678h] ; harsh clip new sample +apatch5: + add ebp,12345678h ; advance frac pointer + shr edx, 16 ; finish calculation for third sample + mov eax, ebp ; begin calculating fourth sample +apatch7: + add edi, 2 ; move destination to second sample + shr eax, 16 ; finish calculation for fourth sample + mov [edi], bl ; write new sample to destination +apatch6: + add ebp,12345678h ; advance frac pointer + movsx ebx, byte ptr [esi+2*eax] ; get fourth sample + movsx eax, byte ptr [esi+2*edx] ; get third sample + add ebx, 80h + add eax, 80h +apatch8: + add edi, 2 ; move destination to third sample + dec ecx ; decrement count + jnz mix8Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit8m: + popad + ret + + +;================ +; +; MV_Mix8BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix8BitStereo16_ +MV_Mix8BitStereo16_: + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + inc esi + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [bpatch8+2],bl + ; mov byte ptr [bpatch9+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [bpatch6+3],ebx + mov dword ptr [bpatch7+2],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [bpatch1+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [bpatch2+4],ebx + + ; Rate scale ptr + mov dword ptr [bpatch3+2],edx + + ; Harsh Clip table ptr + mov ebx, _MV_HarshClipTable + add ebx,128 + mov dword ptr [bpatch4+2],ebx + mov dword ptr [bpatch5+2],ebx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je short exit8S + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; bpatch1 - left volume table +; bpatch2 - right volume table +; bpatch3 - sample rate +; bpatch4 - harsh clip table +; bpatch5 - harsh clip table + + mov eax,ebp ; begin calculating first sample + shr eax,16 ; finish calculation for first sample + + movsx ebx, byte ptr [esi+2*eax] ; get first sample + add ebx, 80h + +;ALIGN 4 +mix8Sloop: +bpatch1: + movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample + movzx edx, byte ptr [edi] ; get current sample from destination +bpatch2: + movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample + add eax, edx ; mix left sample +bpatch3: + add ebp,12345678h ; advance frac pointer +bpatch6: + movzx edx, byte ptr [edi+12345678h] ; get current sample from destination +bpatch4: + mov eax, [eax + 12345678h] ; harsh clip left sample + add ebx, edx ; mix right sample + mov [edi], al ; write left sample to destination +bpatch5: + mov ebx, [ebx + 12345678h] ; harsh clip right sample + mov edx, ebp ; begin calculating second sample +bpatch7: + mov [edi+12345678h], bl ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +bpatch8: + add edi, 1 ; move destination to second sample + movsx ebx, byte ptr [esi+2*edx] ; get second sample + add ebx, 80h + dec ecx ; decrement count + jnz mix8Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position + +EXIT8S: + popad + ret + + +;================ +; +; MV_Mix16BitMono16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix16BitMono16_ +MV_Mix16BitMono16_: + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [cpatch4+2],bl + mov byte ptr [cpatch5+3],bl + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [cpatch2+4],ebx + inc ebx + mov dword ptr [cpatch1+4],ebx + + ; Rate scale ptr + mov dword ptr [cpatch3+2],edx + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16M + +; eax - scratch +; ebx - scratch +; edx - scratch +; ecx - count +; edi - destination +; esi - source +; ebp - frac pointer +; cpatch1 - volume table +; cpatch2 - volume table +; cpatch3 - sample rate +; cpatch4 - sample rate + + mov ebx,ebp ; begin calculating first sample + add ebp,edx ; advance frac pointer + shr ebx,16 ; finish calculation for first sample + movzx eax, word ptr [esi+2*ebx] ; get low byte of sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + movsx edx, word ptr [edi] ; get current sample from destination + +;ALIGN 4 +mix16Mloop: +cpatch1: + movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample +cpatch2: + movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + add eax, edx ; mix low byte of sample +cpatch5: + movsx edx, word ptr [edi + 2] ; get current sample from destination + + cmp eax, -32768 ; Harsh clip sample + jge short m16skip1 + mov eax, -32768 + jmp short m16skip2 +m16skip1: + cmp eax, 32767 + jle short m16skip2 + mov eax, 32767 +m16skip2: + mov ebx, ebp ; begin calculating second sample + mov [edi], ax ; write new sample to destination + + shr ebx, 16 ; finish calculation for second sample +cpatch3: + add ebp, 12345678h ; advance frac pointer + + movzx eax, word ptr [esi+2*ebx] ; get second sample +cpatch4: + add edi, 2 ; move destination to second sample + xor eax, 8000h + movzx ebx, ah + sub ah, ah + + dec ecx ; decrement count + jnz mix16Mloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +EXIT16M: + popad + ret + + +;================ +; +; MV_Mix16BitStereo16 +; +;================ + +; eax - position +; edx - rate +; ebx - start +; ecx - number of samples to mix + +ALIGN 16 +PUBLIC MV_Mix16BitStereo16_ +MV_Mix16BitStereo16_: + pushad + ; Thanks to Lauri Liinat for spotting this lunacy + ;mov eax, dword ptr [esp + 0*4 + 9*4] + ;mov edx, dword ptr [esp + 1*4 + 9*4] + ;mov ebx, dword ptr [esp + 2*4 + 9*4] + ;mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov ebp, eax + + mov esi, ebx ; Source pointer + + ; Sample size + mov ebx, _MV_SampleSize + mov byte ptr [dpatch9+2],bl + + ; Right channel offset + mov ebx, _MV_RightChannelOffset + mov dword ptr [dpatch7+3],ebx + mov dword ptr [dpatch8+3],ebx + + ; Volume table ptr + mov ebx, _MV_LeftVolume + mov dword ptr [dpatch1+4],ebx + inc ebx + mov dword ptr [dpatch2+4],ebx + + mov ebx, _MV_RightVolume + mov dword ptr [dpatch3+4],ebx + inc ebx + mov dword ptr [dpatch4+4],ebx + + ; Rate scale ptr + mov dword ptr [dpatch5+2],edx + + ; Source ptr + mov dword ptr [dpatch6+4],esi + + mov edi, _MV_MixDestination ; Get the position to write to + + ; Number of samples to mix + cmp ecx, 0 + je exit16S + +; eax - scratch +; ebx - scratch +; edx - scratch +; esi - scratch +; ecx - count +; edi - destination +; ebp - frac pointer +; dpatch1 - left volume table +; dpatch2 - right volume table +; dpatch3 - sample rate + + mov ebx,ebp ; begin calculating first sample + shr ebx,16 ; finish calculation for first sample + + movzx edx, word ptr [esi+2*ebx] ; get first sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + +;ALIGN 4 +mix16Sloop: + ; Left channel +dpatch1: + movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample +dpatch2: + movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample + lea eax, [ eax + ebx + 80h ] ; mix high byte of sample + + ; Right channel +dpatch3: + movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample +dpatch4: + movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample + lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample + +dpatch7: + movsx edx, word ptr [edi+12345678h] ; get current sample from destination +dpatch5: + add ebp,12345678h ; advance frac pointer + + add eax, edx ; mix left sample + + cmp eax, -32768 ; Harsh clip sample + jge short s16skip1 + mov eax, -32768 + jmp short s16skip2 +s16skip1: + cmp eax, 32767 + jle short s16skip2 + mov eax, 32767 +s16skip2: + movsx edx, word ptr [edi+2] ; get current sample from destination + mov [edi], ax ; write left sample to destination + add ebx, edx ; mix right sample + + cmp ebx, -32768 ; Harsh clip sample + jge short s16skip3 + mov ebx, -32768 + jmp short s16skip4 +s16skip3: + cmp ebx, 32767 + jle short s16skip4 + mov ebx, 32767 +s16skip4: + + mov edx, ebp ; begin calculating second sample +dpatch8: + mov [edi+12345678h], bx ; write right sample to destination + shr edx, 16 ; finish calculation for second sample +dpatch9: + add edi, 4 ; move destination to second sample + +dpatch6: + movzx edx, word ptr [2*edx+12345678h] ; get second sample + xor edx, 8000h ; Change from signed to unsigned + movzx esi, dh ; put high byte in esi + sub dh, dh ; lo byte in edx + + dec ecx ; decrement count + jnz mix16Sloop ; loop + + mov _MV_MixDestination, edi ; Store the current write position + mov _MV_MixPosition, ebp ; return position +exit16S: + popad + ret + + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/mvreverb.masm b/polymer/eduke32/source/jaudiolib/mvreverb.masm new file mode 100644 index 000000000..9a432534b --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mvreverb.masm @@ -0,0 +1,202 @@ +.586P + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +;================ +; +; MV_16BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + +ALIGN 16 +PUBLIC _MV_16BitReverb +_MV_16BitReverb: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov esi, eax + lea edi, [edx - 2] + +;ALIGN 4 +rev16loop: + movzx eax, word ptr [esi] ; get sample + add edi, 2 + + movzx edx, ah + sub ah, ah + + movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample + xor edx, 80h + + movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample + add esi, 2 + + lea eax, [ eax + edx + 80h ] ; mix high byte of sample + dec ecx ; decrement count + + mov [edi], ax ; write new sample to destination + jnz rev16loop ; loop + + popad + ret + + +;================ +; +; MV_8BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + +ALIGN 16 +PUBLIC _MV_8BitReverb +_MV_8BitReverb: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov esi, eax + lea edi, [edx - 1] + + xor eax, eax + +;ALIGN 4 +rev8loop: +; movzx eax, byte ptr [esi] ; get sample + mov al, byte ptr [esi] ; get sample + inc edi + +; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample + mov al, byte ptr [2*eax+ebx] ; volume translate sample + inc esi + +; add eax, 80h + add al, 80h + dec ecx ; decrement count + + mov [edi], al ; write new sample to destination + jnz rev8loop ; loop + + popad + ret + + +;================ +; +; MV_16BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + +ALIGN 16 +PUBLIC _MV_16BitReverbFast +_MV_16BitReverbFast: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov esi, eax + mov eax,OFFSET rpatch16+3 + + mov [eax],cl + lea edi, [edx - 2] + +;ALIGN 4 +frev16loop: + mov ax, word ptr [esi] ; get sample + add edi, 2 + +rpatch16: + sar ax, 5 ;;;;Add 1 before shift + add esi, 2 + + mov [edi], ax ; write new sample to destination + dec ebx ; decrement count + + jnz frev16loop ; loop + + popad + ret + + +;================ +; +; MV_8BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + +ALIGN 16 +PUBLIC _MV_8BitReverbFast +_MV_8BitReverbFast: + pushad + mov eax, dword ptr [esp + 0*4 + 9*4] + mov edx, dword ptr [esp + 1*4 + 9*4] + mov ebx, dword ptr [esp + 2*4 + 9*4] + mov ecx, dword ptr [esp + 3*4 + 9*4] + + mov esi, eax + mov eax,OFFSET rpatch8+2 + + mov edi, edx + mov edx, 80h + + mov [eax],cl + mov eax, 80h + + shr eax, cl + + dec edi + sub edx, eax + +;ALIGN 4 +frev8loop: + mov al, byte ptr [esi] ; get sample + inc esi + + mov ecx, eax + inc edi + +rpatch8: + shr eax, 3 + xor ecx, 80h ; flip the sign bit + + shr ecx, 7 ; shift the sign down to 1 + add eax, edx + + add eax, ecx ; add sign bit to round to 0 + dec ebx ; decrement count + + mov [edi], al ; write new sample to destination + jnz frev8loop ; loop + + popad + ret + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/mvreverb.nasm b/polymer/eduke32/source/jaudiolib/mvreverb.nasm new file mode 100644 index 000000000..4574fa6b6 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mvreverb.nasm @@ -0,0 +1,230 @@ +;Copyright (C) 1994-1995 Apogee Software, Ltd. +; +;This program is free software; you can redistribute it and/or +;modify it under the terms of the GNU General Public License +;as published by the Free Software Foundation; either version 2 +;of the License, or (at your option) any later version. +; +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; +;See the GNU General Public License for more details. +; +;You should have received a copy of the GNU General Public License +;along with this program; if not, write to the Free Software +;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; +;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) + +CPU 386 + +SECTION .data + +%ifdef UNDERSCORES + +%define MV_16BitReverb _MV_16BitReverb +%define MV_8BitReverb _MV_8BitReverb +%define MV_16BitReverbFast _MV_16BitReverbFast +%define MV_8BitReverbFast _MV_8BitReverbFast + +%endif + + GLOBAL MV_16BitReverb + GLOBAL MV_8BitReverb + GLOBAL MV_16BitReverbFast + GLOBAL MV_8BitReverbFast + +%define OFFSET + +;================ +; +; MV_16BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + + ALIGN 4 +MV_16BitReverb: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov esi, eax + lea edi, [edx - 2] + + ALIGN 4 +rev16loop: + movzx eax, word [esi] ; get sample + add edi, 2 + + movzx edx, ah + sub ah, ah + + movsx eax, byte [2*eax+ebx+1] ; volume translate low byte of sample + xor edx, 80h + + movsx edx, word [2*edx+ebx] ; volume translate high byte of sample + add esi, 2 + + lea eax, [ eax + edx + 80h ] ; mix high byte of sample + dec ecx ; decrement count + + mov word [edi], ax ; write new sample to destination + jnz rev16loop ; loop + + popad + ret + + +;================ +; +; MV_8BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + + ALIGN 4 +MV_8BitReverb: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov esi, eax + lea edi, [edx - 1] + + xor eax, eax + + ALIGN 4 +rev8loop: +; movzx eax, byte ptr [esi] ; get sample + mov al, byte [esi] ; get sample + inc edi + +; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample + mov al, byte [2*eax+ebx] ; volume translate sample + inc esi + +; add eax, 80h + add al, 80h + dec ecx ; decrement count + + mov byte [edi], al ; write new sample to destination + jnz rev8loop ; loop + + popad + ret + + +;================ +; +; MV_16BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + + ALIGN 4 +MV_16BitReverbFast: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov esi, eax + mov eax,OFFSET rpatch16+3 + + mov byte [eax],cl + lea edi, [edx - 2] + + ALIGN 4 +frev16loop: + mov ax, word [esi] ; get sample + add edi, 2 + +rpatch16: + sar ax, 5 ;;;;Add 1 before shift + add esi, 2 + + mov word [edi], ax ; write new sample to destination + dec ebx ; decrement count + + jnz frev16loop ; loop + + popad + ret + + +;================ +; +; MV_8BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + + ALIGN 4 +MV_8BitReverbFast: + pushad + mov eax, dword [esp + 0*4 + 9*4] + mov edx, dword [esp + 1*4 + 9*4] + mov ebx, dword [esp + 2*4 + 9*4] + mov ecx, dword [esp + 3*4 + 9*4] + + mov esi, eax + mov eax,OFFSET rpatch8+2 + + mov edi, edx + mov edx, 80h + + mov byte [eax],cl + mov eax, 80h + + shr eax, cl + + dec edi + sub edx, eax + + ALIGN 4 +frev8loop: + mov al, byte [esi] ; get sample + inc esi + + mov ecx, eax + inc edi + +rpatch8: + shr eax, 3 + xor ecx, 80h ; flip the sign bit + + shr ecx, 7 ; shift the sign down to 1 + add eax, edx + + add eax, ecx ; add sign bit to round to 0 + dec ebx ; decrement count + + mov byte [edi], al ; write new sample to destination + jnz frev8loop ; loop + + popad + ret + diff --git a/polymer/eduke32/source/jaudiolib/mvreverb.wasm b/polymer/eduke32/source/jaudiolib/mvreverb.wasm new file mode 100644 index 000000000..249d71b1f --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/mvreverb.wasm @@ -0,0 +1,174 @@ +.586P + +CODE SEGMENT PUBLIC USE32 'DATA' +ASSUME cs:CODE,ds:CODE + +;================ +; +; MV_16BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + +ALIGN 16 +PUBLIC MV_16BitReverb_ +MV_16BitReverb_: + mov esi, eax + lea edi, [edx - 2] + +;ALIGN 4 +rev16loop: + movzx eax, word ptr [esi] ; get sample + add edi, 2 + + movzx edx, ah + sub ah, ah + + movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample + xor edx, 80h + + movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample + add esi, 2 + + lea eax, [ eax + edx + 80h ] ; mix high byte of sample + dec ecx ; decrement count + + mov [edi], ax ; write new sample to destination + jnz rev16loop ; loop + + ret + + +;================ +; +; MV_8BitReverb +; +;================ + +; eax - source position +; edx - destination position +; ebx - Volume table +; ecx - number of samples + +ALIGN 16 +PUBLIC MV_8BitReverb_ +MV_8BitReverb_: + mov esi, eax + lea edi, [edx - 1] + + xor eax, eax + +;ALIGN 4 +rev8loop: +; movzx eax, byte ptr [esi] ; get sample + mov al, byte ptr [esi] ; get sample + inc edi + +; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample + mov al, byte ptr [2*eax+ebx] ; volume translate sample + inc esi + +; add eax, 80h + add al, 80h + dec ecx ; decrement count + + mov [edi], al ; write new sample to destination + jnz rev8loop ; loop + + ret + + +;================ +; +; MV_16BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + +ALIGN 16 +PUBLIC MV_16BitReverbFast_ +MV_16BitReverbFast_: + mov esi, eax + mov eax,OFFSET rpatch16+3 + + mov [eax],cl + lea edi, [edx - 2] + +;ALIGN 4 +frev16loop: + mov ax, word ptr [esi] ; get sample + add edi, 2 + +rpatch16: + sar ax, 5 ;;;;Add 1 before shift + add esi, 2 + + mov [edi], ax ; write new sample to destination + dec ebx ; decrement count + + jnz frev16loop ; loop + + ret + + +;================ +; +; MV_8BitReverbFast +; +;================ + +; eax - source position +; edx - destination position +; ebx - number of samples +; ecx - shift + +ALIGN 16 +PUBLIC MV_8BitReverbFast_ +MV_8BitReverbFast_: + mov esi, eax + mov eax,OFFSET rpatch8+2 + + mov edi, edx + mov edx, 80h + + mov [eax],cl + mov eax, 80h + + shr eax, cl + + dec edi + sub edx, eax + +;ALIGN 4 +frev8loop: + mov al, byte ptr [esi] ; get sample + inc esi + + mov ecx, eax + inc edi + +rpatch8: + shr eax, 3 + xor ecx, 80h ; flip the sign bit + + shr ecx, 7 ; shift the sign down to 1 + add eax, edx + + add eax, ecx ; add sign bit to round to 0 + dec ebx ; decrement count + + mov [edi], al ; write new sample to destination + jnz frev8loop ; loop + + ret + +CODE ENDS +END diff --git a/polymer/eduke32/source/jaudiolib/pitch.c b/polymer/eduke32/source/jaudiolib/pitch.c new file mode 100644 index 000000000..a49e2c9e1 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/pitch.c @@ -0,0 +1,197 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: PITCH.C + + author: James R. Dose + date: June 14, 1993 + + Routines for pitch scaling. + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +//#include +#include "standard.h" +#include "pitch.h" + +#define MAXDETUNE 25 + +static unsigned long PitchTable[ 12 ][ MAXDETUNE ] = + { + { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c, + 0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907, + 0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8, + 0x10e98 }, + { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5, + 0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9, + 0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06, + 0x11eaf }, + { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409, + 0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b, + 0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08, + 0x12fbc }, + { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566, + 0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c, + 0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d, + 0x141cb }, + { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc, + 0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea, + 0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424, + 0x154ee }, + { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a, + 0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5, + 0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e, + 0x16934 }, + { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1, + 0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce, + 0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc, + 0x17eae }, + { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2, + 0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17, + 0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480, + 0x1956f }, + { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00, + 0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4, + 0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d, + 0x1ad8b }, + { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f, + 0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8, + 0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609, + 0x1c716 }, + { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93, + 0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839, + 0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109, + 0x1e225 }, + { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24, + 0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e, + 0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3, + 0x1fed1 } + }; + + +//static int PITCH_Installed = FALSE; + + +/*--------------------------------------------------------------------- + Function: PITCH_Init + + Initializes pitch table. +---------------------------------------------------------------------*/ +/* +void PITCH_Init + ( + void + ) + + { + int note; + int detune; + + if ( !PITCH_Installed ) + { + for( note = 0; note < 12; note++ ) + { + for( detune = 0; detune < MAXDETUNE; detune++ ) + { + PitchTable[ note ][ detune ] = 0x10000 * + pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) ); + } + } + + PITCH_Installed = TRUE; + } + } +*/ + +/********************************************************************** + + Memory locked functions: + +**********************************************************************/ + + +/*--------------------------------------------------------------------- + Function: PITCH_GetScale + + Returns a fixed-point value to scale number the specified amount. +---------------------------------------------------------------------*/ + +unsigned long PITCH_GetScale + ( + int pitchoffset + ) + + { + unsigned long scale; + int octaveshift; + int noteshift; + int note; + int detune; + +// if ( !PITCH_Installed ) +// { +// PITCH_Init(); +// } + + if ( pitchoffset == 0 ) + { + return( PitchTable[ 0 ][ 0 ] ); + } + + noteshift = pitchoffset % 1200; + if ( noteshift < 0 ) + { + noteshift += 1200; + } + + note = noteshift / 100; + detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE ); + octaveshift = ( pitchoffset - noteshift ) / 1200; + + if ( detune < 0 ) + { + detune += ( 100 / MAXDETUNE ); + note--; + if ( note < 0 ) + { + note += 12; + octaveshift--; + } + } + + scale = PitchTable[ note ][ detune ]; + + if ( octaveshift < 0 ) + { + scale >>= -octaveshift; + } + else + { + scale <<= octaveshift; + } + + return( scale ); + } + + + diff --git a/polymer/eduke32/source/jaudiolib/pitch.h b/polymer/eduke32/source/jaudiolib/pitch.h new file mode 100644 index 000000000..b054507a7 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/pitch.h @@ -0,0 +1,44 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: PITCH.H + + author: James R. Dose + date: June 14, 1994 + + Public header for PITCH.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __PITCH_H +#define __PITCH_H + +enum PITCH_ERRORS + { + PITCH_Warning = -2, + PITCH_Error = -1, + PITCH_Ok = 0, + }; + +//void PITCH_Init( void ); +unsigned long PITCH_GetScale( int pitchoffset ); +#endif diff --git a/polymer/eduke32/source/jaudiolib/sdlout.c b/polymer/eduke32/source/jaudiolib/sdlout.c new file mode 100644 index 000000000..37c510a16 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/sdlout.c @@ -0,0 +1,266 @@ +/* + * DirectSound output code for MultiVoc + * by Jonathon Fowler (jonof@edgenetwk.com) + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "sdlout.h" +#include "SDL.h" +#include +#include +#include "osd.h" + +#include "sdlayer.h" + +#if defined(__WATCOMC__) || defined(_MSC_VER) +#include +#endif + + +#ifndef RENDERTYPESDL +#error The SDL output module for AudioLib only works with the SDL interface. +#endif + +static int (*_SDLSOUND_CallBack)(int) = NULL; +static int _SDLSOUND_BufferLength = 0; +static int _SDLSOUND_NumBuffers = 0; +static char *_SDLSOUND_MixBuffer = NULL; + +static int SDLSOUND_Installed = FALSE; + +int SDLSOUND_ErrorCode = SDLSOUND_Ok; + +#define SDLSOUND_SetErrorCode( status ) \ + SDLSOUND_ErrorCode = ( status ); + +static void isr(void *userdata, unsigned char *stream, int len); + +/* + * DisableInterrupts + * Enter the critical section. + */ +int DisableInterrupts(void) +{ + SDL_LockAudio(); + + return 0; +} + + +/* + * RestoreInterrupts + * Leave the critical section. + */ +int RestoreInterrupts(int a) +{ + SDL_UnlockAudio(); + + return 0; + a=a; +} + + +/* + * SDLSOUND_ErrorString + * Returns a description of an error code. + */ +char *SDLSOUND_ErrorString(int errorcode) +{ + switch (errorcode) { + case SDLSOUND_Warning: + case SDLSOUND_Error: + return SDLSOUND_ErrorString(SDLSOUND_ErrorCode); + + case SDLSOUND_Ok: + return "SDL Sound ok."; + + default: + return "Unknown SDL sound error code."; + } +} + + +/* + * SDLSOUND_Init + * Initializes the SDL sound objects. + */ +int SDLSOUND_Init(int soundcard, int mixrate, int numchannels, int samplebits, int buffersize) +{ + SDL_AudioSpec spec,got; + + if (SDLSOUND_Installed) { + SDLSOUND_Shutdown(); + } + + printOSD("Initializing SDL sound...\n"); + + printOSD(" - Requested sound format\n" + " Channels: %d\n" + " Sample rate: %dHz\n" + " Sample size: %d bits\n", + numchannels, mixrate, samplebits); + + spec.freq = mixrate; + spec.format = (samplebits == 8 ? AUDIO_U8 : AUDIO_S16LSB); + spec.channels = (numchannels == 1 ? 1:2); + spec.samples = (buffersize >> (spec.channels-1)) >> (samplebits==16); + spec.callback = isr; + spec.userdata = NULL; + + + SDLSOUND_Installed = TRUE; + + SDLSOUND_SetErrorCode(SDLSOUND_Ok); + return SDLSOUND_Ok; +} + + +/* + * SDLSOUND_Shutdown + * Shuts down SDL sound and it's associates. + */ +int SDLSOUND_Shutdown(void) +{ + int i; + + if (SDLSOUND_Installed) printOSD("Uninitializing SDL sound...\n"); + + SDLSOUND_Installed = FALSE; + + SDLSOUND_StopPlayback(); + + + SDLSOUND_SetErrorCode(SDLSOUND_Ok); + return SDLSOUND_Ok; +} + + +/* + * SDLSOUND_SetMixMode + * Bit of filler for the future. + */ +int SDLSOUND_SetMixMode(int mode) +{ + return mode; +} + + +static void isr(void *userdata, unsigned char *stream, int len) +{ + // otherwise we just service the interrupt + if (_DSOUND_CallBack) { + + p = _DSOUND_CallBack(rv-WAIT_OBJECT_0-1); + + hr = IDirectSoundBuffer_Lock(lpDSBSecondary, p*_DSOUND_BufferLength, _DSOUND_BufferLength, + &lockptr, &lockbytes, &lockptr2, &lockbytes2, 0); + if (hr == DSERR_BUFFERLOST) { + hr = IDirectSoundBuffer_Restore(lpDSBSecondary); + } + if (hr == DS_OK) { + /* +#define copybuf(S,D,c) \ + ({ void *__S=(S), *__D=(D); long __c=(c); \ + __asm__ __volatile__ ("rep; movsl" \ + : "+S" (__S), "+D" (__D), "+c" (__c) : : "memory", "cc"); \ + 0; }) +*/ + //copybuf(_DSOUND_MixBuffer + p * _DSOUND_BufferLength, lockptr, _DSOUND_BufferLength >> 2); + memcpy(lockptr, _DSOUND_MixBuffer + p * _DSOUND_BufferLength, _DSOUND_BufferLength); + IDirectSoundBuffer_Unlock(lpDSBSecondary, lockptr, lockbytes, lockptr2, lockbytes2); + } + + } + } +} + + +/* + * SDLSOUND_BeginBufferedPlayback + * Unpause SDL sound playback. + */ +int DSOUND_BeginBufferedPlayback(char *BufferStart, int (*CallBackFunc)(int), int buffersize, int numdivisions) +{ + _SDLSOUND_CallBack = CallBackFunc; + _SDLSOUND_MixBuffer = BufferStart; + + _SDLSOUND_BufferLength = buffersize/numdivisions; + _SDLSOUND_NumBuffers = numdivisions; + + return SDLSOUND_Ok; +} + + +/* + * DSOUND_StopPlayback + * Halts the playback thread. + */ +int DSOUND_StopPlayback(void) +{ +// DWORD exitcode; + BOOL t; + int i; + + if (isrthread) { + SetEvent(isrfinish); + + printOSD("DirectSound: Waiting for sound thread to exit\n"); + if (WaitForSingleObject(isrthread, 300) == WAIT_OBJECT_0) + printOSD("DirectSound: Sound thread has exited\n"); + else + printOSD("DirectSound: Sound thread failed to exit!\n"); + /* + while (1) { + if (!GetExitCodeThread(isrthread, &exitcode)) { + DSOUND_SetErrorCode(DSOUND_FailedGetExitCode); + return DSOUND_Warning; + } + if (exitcode != STILL_ACTIVE) break; + }*/ + + CloseHandle(isrthread); + isrthread = NULL; + } + + if (isrfinish) { + CloseHandle(isrfinish); + isrfinish = NULL; + } + + if (lpDSBSecondary) { + IDirectSoundBuffer_Stop(lpDSBSecondary); + } + + if (hPosNotify) { + for (i=0; i<_DSOUND_NumBuffers; i++) { + if (hPosNotify[i]) CloseHandle(hPosNotify[i]); + } + free(hPosNotify); + hPosNotify = NULL; + } + + return DSOUND_Ok; +} + + diff --git a/polymer/eduke32/source/jaudiolib/sdlout.h b/polymer/eduke32/source/jaudiolib/sdlout.h new file mode 100644 index 000000000..73dbf545e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/sdlout.h @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#ifndef __sdlout_h__ +#define __sdlout_h__ + +enum SDLSOUND_ERRORS { + SDLSOUND_Warning = -2, + SDLSOUND_Error = -1, + SDLSOUND_Ok = 0 +}; + +extern int SDLSOUND_ErrorCode; + +char *SDLSOUND_ErrorString(int); + +int DisableInterrupts(void); // simulated using critical sections +int RestoreInterrupts(int); + +int SDLSOUND_Init(int soundcard, int mixrate, int numchannels, int samplebits, int buffersize); +int SDLSOUND_Shutdown(void); + +int SDLSOUND_SetMixMode(int mode); +int SDLSOUND_BeginBufferedPlayback(char *BufferStart, int (*CallBackFunc)(int), int buffersize, int numdivisions); +int SDLSOUND_StopPlayback(void); + +#endif // __sdlout_h__ + diff --git a/polymer/eduke32/source/jaudiolib/standard.h b/polymer/eduke32/source/jaudiolib/standard.h new file mode 100644 index 000000000..167c605df --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/standard.h @@ -0,0 +1,73 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: STANDARD.H + + author: James R. Dose + date: May 25, 1994 + + Header containing standard definitions. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __STANDARD_H +#define __STANDARD_H + +typedef int boolean; +typedef int errorcode; + +#ifndef TRUE + #define TRUE ( 1 == 1 ) + #define FALSE ( !TRUE ) +#endif + +enum STANDARD_ERRORS + { + Warning = -2, + FatalError = -1, + Success = 0 + }; + +#define BITSET( data, bit ) \ + ( ( ( data ) & ( bit ) ) == ( bit ) ) + +#define ARRAY_LENGTH( array ) \ + ( sizeof( array ) / sizeof( ( array )[ 0 ] ) ) + +#define WITHIN_BOUNDS( array, index ) \ + ( ( 0 <= ( index ) ) && ( ( index ) < ARRAY_LENGTH( array ) ) ) + +#define FOREVER for( ; ; ) + +#ifdef NDEBUG + #define DEBUGGING 0 +#else + #define DEBUGGING 1 +#endif + +#define DEBUG_CODE \ + if ( DEBUGGING == 0 ) \ + { \ + } \ + else + +#endif diff --git a/polymer/eduke32/source/jaudiolib/usrhooks.h b/polymer/eduke32/source/jaudiolib/usrhooks.h new file mode 100644 index 000000000..25e3fcf10 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/usrhooks.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +/********************************************************************** + module: USRHOOKS.H + + author: James R. Dose + date: July 26, 1994 + + Public header file for USRHOOKS.C. + + This module contains cover functions for operations the library + needs that may be restricted by the calling program. The function + prototypes in this header should not be modified. +**********************************************************************/ + +#ifndef __USRHOOKS_H +#define __USRHOOKS_H + +/*--------------------------------------------------------------------- + Error definitions +---------------------------------------------------------------------*/ + +enum USRHOOKS_Errors + { + USRHOOKS_Warning = -2, + USRHOOKS_Error = -1, + USRHOOKS_Ok = 0 + }; + + +/*--------------------------------------------------------------------- + Function Prototypes +---------------------------------------------------------------------*/ + +int USRHOOKS_GetMem( void **ptr, unsigned long size ); +int USRHOOKS_FreeMem( void *ptr ); + +#endif diff --git a/polymer/eduke32/source/jfaud_sounds.cpp b/polymer/eduke32/source/jfaud_sounds.cpp new file mode 100644 index 000000000..b96271813 --- /dev/null +++ b/polymer/eduke32/source/jfaud_sounds.cpp @@ -0,0 +1,681 @@ +/* + * Audio support for JFDuke3D using JFAud + * by Jonathon Fowler (jonof@edgenetwork.org) + * + * Duke Nukem 3D is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Original Source: 1996 - Todd Replogle + * Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms + */ + +#ifdef __APPLE__ +# include +#else +# include "jfaud.hpp" +#endif + +#include "types.h" +#include "duke3d.h" +extern "C" { +#ifdef RENDERTYPEWIN +# include "winlayer.h" +#endif +#include "osd.h" +long numenvsnds; +} + +#define SOUNDM_LOOP 1 +#define SOUNDM_MSFX 2 +#define SOUNDM_DUKE 4 +#define SOUNDM_PARENT 8 +#define SOUNDM_GLOBAL 16 +#define SOUNDM_NICE 64 // Added for JFDuke3D so JFAud doesn't use nearest filtering for the sound +#define SOUNDM_PLAYER 128 + +#define UNITSPERMETRE 1024.0 +#define ZUNITSPERMETRE 8192.0 + +#include + +class KenFile : public JFAudFile { +private: + int fh; +public: + KenFile(const char *filename, const char *subfilename) + : JFAudFile(filename, subfilename) + { + fh = kopen4load(const_cast(filename), 0); + } + + virtual ~KenFile() + { + if (fh >= 0) kclose(fh); + } + + virtual bool IsOpen(void) const { return fh >= 0; } + + virtual long Read(long nbytes, void *buf) + { + if (fh < 0) return -1; + return kread(fh, buf, nbytes); + } + virtual long Seek(long pos, SeekFrom where) + { + int when; + if (fh < 0) return -1; + switch (where) { + case JFAudFile::Set: when = SEEK_SET; break; + case JFAudFile::Cur: when = SEEK_CUR; break; + case JFAudFile::End: when = SEEK_END; break; + default: return -1; + } + return klseek(fh, pos, when); + } + virtual long Tell(void) const + { + if (fh < 0) return -1; + return klseek(fh, 0, SEEK_CUR); + } + virtual long Length(void) const + { + if (fh < 0) return -1; + return kfilelength(fh); + } +}; + +static JFAudFile *openfile(const char *fn, const char *subfn) +{ + return static_cast(new KenFile(fn,subfn)); +} + +static void logfunc(const char *s) { initprintf("jfaud: %s", s); } + +#define PITCHRANGE 2 // octave range in each direction +#define PITCHSTEPS 24 // pitch points per octave +static float pitchtable[PITCHRANGE*PITCHSTEPS*2+1]; +static void buildpitchtable(void) +{ + int i,j; + + for (i=-PITCHRANGE*PITCHSTEPS; i<=PITCHRANGE*PITCHSTEPS; i++) { + pitchtable[i+PITCHRANGE*PITCHSTEPS] = pow(1.0005777895, (1200.0/PITCHSTEPS)*(float)i); + } +} +static float translatepitch(int p) +{ + float t; + int x; + x = (p * PITCHSTEPS / 1200) + PITCHRANGE*PITCHSTEPS; + if (x < 0) x = 0; + else if (x > (int)(sizeof(pitchtable)/sizeof(float))) x = sizeof(pitchtable)/sizeof(float); + t = pitchtable[x]; + /*if (t > 2.0) { + initprintf("translatepitch(%d) > 2.0\n", p); + t = 2.0; + }*/ + return t; +} + +typedef struct { + JFAudMixerChannel *chan; + int owner; // sprite number + int soundnum; // sound number +} SoundChannel; + +static SoundChannel *chans = NULL; +static JFAud *jfaud = NULL; + +static bool havemidi = false, havewave = false; + + +static void stopcallback(int r) +{ + jfaud->FreeSound(chans[r].chan); + chans[r].chan = NULL; + chans[r].owner = -1; +} + +void testcallback(unsigned long num) +{ +} + +static int keephandle(JFAudMixerChannel *handle, int soundnum, int owner) +{ + int i, freeh=-1; + for (i=NumVoices-1;i>=0;i--) { + if ((!chans[i].chan || !jfaud->IsValidSound(chans[i].chan)) && freeh<0) freeh=i; + else if (chans[i].chan == handle) { freeh=i; break; } + } + if (freeh<0) { + initprintf("Warning: keephandle() exhausted handle space!\n"); + return -1; + } + + chans[freeh].chan = handle; + chans[freeh].soundnum = soundnum; + chans[freeh].owner = owner; + + return freeh; +} + +void SoundStartup(void) +{ + int i; + + if (FXDevice < 0) return; + + if (jfaud) return; + buildpitchtable(); + + JFAud_SetLogFunc(logfunc); + + jfaud = new JFAud(); + if (!jfaud) return; + + jfaud->SetUserOpenFunc(openfile); +#ifdef _WIN32 + jfaud->SetWindowHandle((void*)win_gethwnd()); +#endif + + havewave = havemidi = false; + if (!jfaud->InitWave(NULL, NumVoices, MixRate)) { + delete jfaud; + jfaud = NULL; + return; + } + + chans = new SoundChannel[NumVoices]; + if (!chans) { + delete jfaud; + jfaud = NULL; + return; + } + + havewave = true; + + for (i=NumVoices-1; i>=0; i--) { + chans[i].owner = -1; + } + + if (jfaud->InitMIDI(NULL)) havemidi = true; +} + +void SoundShutdown(void) +{ + if (jfaud) delete jfaud; + if (chans) delete [] chans; + jfaud = NULL; + chans = NULL; + havewave = havemidi = false; +} + +void MusicStartup(void) +{ +} + +void MusicShutdown(void) +{ +} + +void AudioUpdate(void) +{ + int i; + + if (!jfaud) return; + if (havewave) + for (i=NumVoices-1; i>=0; i--) { + if (chans[i].chan && !jfaud->IsValidSound(chans[i].chan)) + chans[i].chan = NULL; + } + jfaud->Update(); +} + + +static char menunum = 0; +void intomenusounds(void) +{ + short i; + short menusnds[] = { + LASERTRIP_EXPLODE, DUKE_GRUNT, DUKE_LAND_HURT, + CHAINGUN_FIRE, SQUISHED, KICK_HIT, + PISTOL_RICOCHET, PISTOL_BODYHIT, PISTOL_FIRE, + SHOTGUN_FIRE, BOS1_WALK, RPG_EXPLODE, + PIPEBOMB_BOUNCE, PIPEBOMB_EXPLODE, NITEVISION_ONOFF, + RPG_SHOOT, SELECT_WEAPON + }; + sound(menusnds[menunum++]); + menunum %= sizeof(menusnds)/sizeof(menusnds[0]); +} + +void playmusic(char *fn) +{ + char dafn[BMAX_PATH], *dotpos; + int i; + const char *extns[] = { ".ogg",".mp3",".mid", NULL }; + + if (!MusicToggle) return; + if (!jfaud) return; + + dotpos = Bstrrchr(fn,'.'); + if (dotpos && Bstrcasecmp(dotpos,".mid")) { + // has extension but isn't midi + jfaud->PlayMusic(fn, NULL); + } else { + Bstrcpy(dafn,fn); + dotpos = Bstrrchr(dafn,'.'); + if (!dotpos) dotpos = dafn+strlen(dafn); + + for (i=0; extns[i]; i++) { + Bstrcpy(dotpos, extns[i]); + if (jfaud->PlayMusic(dafn, NULL)) return; + } + } +} + +char loadsound(unsigned short num) { return 1; } + +int isspritemakingsound(short i, int num) // if num<0, check if making any sound at all +{ + int j,n=0; + + if (!jfaud || !havewave) return 0; + for (j=NumVoices-1; j>=0; j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan)) continue; + if (chans[j].owner == i) + if (num < 0 || chans[j].soundnum == num) n++; + } + return n; +} + +int issoundplaying(int num) +{ + int j,n=0; + + if (!jfaud || !havewave) return 0; + for (j=NumVoices-1; j>=0; j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan)) continue; + if (chans[j].soundnum == num) n++; + } + + return n; +} + +int xyzsound(short num, short i, long x, long y, long z) +{ + JFAudMixerChannel *chan; + int r, global = 0; + float gain = 1.0, pitch = 1.0; + + if (!jfaud || !havewave || + num >= NUM_SOUNDS || + ((soundm[num] & SOUNDM_PARENT) && ud.lockout) || // parental mode + SoundToggle == 0 || + (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3) || + (ps[myconnectindex].gm & MODE_MENU) + ) return -1; + + if (soundm[num] & SOUNDM_PLAYER) { + sound(num); + return 0; + } + +// swaplong(&y,&z); +// y = -y>>4; + + if (soundm[num] & SOUNDM_DUKE) { + // Duke speech, one at a time only + int j; + + if (VoiceToggle == 0 || + (ud.multimode > 1 && PN == APLAYER && sprite[i].yvel != screenpeek && ud.coop != 1) + ) return -1; + + for (j=NumVoices-1; j>=0; j--) { + if (!chans[j].chan || chans[j].owner < 0) continue; + if (soundm[ chans[j].soundnum ] & SOUNDM_DUKE) return -1; + } + } + + // XXX: here goes musicandsfx ranging. This will change the refdist. + + { + int ps = soundps[num], pe = soundpe[num], cx; + cx = klabs(pe-ps); + if (cx) { + if (ps < pe) pitch = translatepitch(ps + rand()%cx); + else pitch = translatepitch(pe + rand()%cx); + } else pitch = translatepitch(ps); + } + + if (ps[screenpeek].sound_pitch) pitch = translatepitch(ps[screenpeek].sound_pitch); + + //gain += soundvo[num]; +/* if (PN != MUSICANDSFX && + !cansee(ps[screenpeek].oposx,ps[screenpeek].oposy,ps[screenpeek].oposz-(24<<8), + ps[screenpeek].cursectnum,SX,SY,SZ-(24<<8),SECT) ) + gain *= 1.0/32.0; */ + + switch(num) + { + case PIPEBOMB_EXPLODE: + case LASERTRIP_EXPLODE: + case RPG_EXPLODE: + gain = 1.0; + global = 1; + if (sector[ps[screenpeek].cursectnum].lotag == 2) pitch -= translatepitch(1024); + break; + default: + if(sector[ps[screenpeek].cursectnum].lotag == 2 && (soundm[num]&SOUNDM_DUKE) == 0) + pitch = translatepitch(-768); + //if( sndist > 31444 && PN != MUSICANDSFX) + // return -1; + break; + } + if (ps[screenpeek].sound_pitch) pitch = translatepitch(ps[screenpeek].sound_pitch); +/* + // XXX: this is shit + if( Sound[num].num > 0 && PN != MUSICANDSFX ) + { + if( SoundOwner[num][0].i == i ) stopsound(num); + else if( Sound[num].num > 1 ) stopsound(num); + else if( badguy(&sprite[i]) && sprite[i].extra <= 0 ) stopsound(num); + } +*/ + + chan = jfaud->PlaySound(sounds[num], NULL, soundpr[num]); + if (!chan) return -1; + + chan->SetGain(gain); + chan->SetPitch(pitch); + chan->SetLoop(soundm[num] & SOUNDM_LOOP); + if (soundm[num] & SOUNDM_GLOBAL) global = 1; + chan->SetFilter((soundm[num]&SOUNDM_NICE) ? JFAudMixerChannel::Filter4Point : JFAudMixerChannel::FilterNearest); + + if (PN == APLAYER && sprite[i].yvel == screenpeek) { + chan->SetRolloff(0.0); + chan->SetFollowListener(true); + chan->SetPosition(0.0, 0.0, 0.0); + } else { + chan->SetRolloff(global ? 0.0 : 0.3); + chan->SetFollowListener(false); + chan->SetPosition((float)x/UNITSPERMETRE, (float)z/ZUNITSPERMETRE, (float)y/UNITSPERMETRE); + } + + r = keephandle(chan, num, i); + if (r >= 0) chan->SetStopCallback(stopcallback, r); + chan->Play(); + + return 0; +} + +void sound(short num) +{ + JFAudMixerChannel *chan; + int r; + float pitch = 1.0; + + if (!jfaud || !havewave || + num >= NUM_SOUNDS || + SoundToggle == 0 || + ((soundm[num] & SOUNDM_DUKE) && VoiceToggle == 0) || + ((soundm[num] & SOUNDM_PARENT) && ud.lockout) // parental mode + ) return; + + { + int ps = soundps[num], pe = soundpe[num], cx; + cx = klabs(pe-ps); + if (cx) { + if (ps < pe) pitch = translatepitch(ps + rand()%cx); + else pitch = translatepitch(pe + rand()%cx); + } else pitch = translatepitch(ps); + } + + chan = jfaud->PlaySound(sounds[num], NULL, soundpr[num]); + if (!chan) return; + + chan->SetGain(1.0); + chan->SetPitch(pitch); + chan->SetLoop(soundm[num] & SOUNDM_LOOP); + chan->SetRolloff(0.0); + chan->SetFollowListener(true); + chan->SetPosition(0.0, 0.0, 0.0); + chan->SetFilter((soundm[num]&SOUNDM_NICE) ? JFAudMixerChannel::Filter4Point : JFAudMixerChannel::FilterNearest); + + r = keephandle(chan, num, -1); + if (r >= 0) chan->SetStopCallback(stopcallback, r); + chan->Play(); +} + +int spritesound(unsigned short num, short i) +{ + if (num >= NUM_SOUNDS) return -1; + return xyzsound(num,i,SX,SY,SZ); +} + +void stopsound(short num) +{ + int j; + + if (!jfaud || !havewave) return; + for (j=NumVoices-1;j>=0;j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan) || chans[j].soundnum != num) continue; + + jfaud->FreeSound(chans[j].chan); + chans[j].chan = NULL; + chans[j].owner = -1; + } +} + +void stopspritesound(short num, short i) +{ + int j; + + if (!jfaud || !havewave) return; + for (j=NumVoices-1;j>=0;j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan) || chans[j].owner != i || chans[j].soundnum != num) continue; + + jfaud->FreeSound(chans[j].chan); + chans[j].chan = NULL; + chans[j].owner = -1; + return; + } +} + +void stopenvsound(short num, short i) +{ + int j; + + if (!jfaud || !havewave) return; + for (j=NumVoices-1;j>=0;j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan) || chans[j].owner != i) continue; + + jfaud->FreeSound(chans[j].chan); + chans[j].chan = NULL; + chans[j].owner = -1; + } +} + +void pan3dsound(void) +{ + JFAudMixer *mix; + int j, global; + short i; + long cx, cy, cz, sx,sy,sz; + short ca,cs; + float gain; + + numenvsnds = 0; + if (!jfaud || !havewave) return; + mix = jfaud->GetWave(); + if (!mix) return; + + if(ud.camerasprite == -1) { + cx = ps[screenpeek].oposx; + cy = -ps[screenpeek].oposz>>4; + cz = ps[screenpeek].oposy; + cs = ps[screenpeek].cursectnum; + ca = ps[screenpeek].ang+ps[screenpeek].look_ang; + } else { + cx = sprite[ud.camerasprite].x; + cy = -sprite[ud.camerasprite].z>>4; + cz = sprite[ud.camerasprite].y; + cs = sprite[ud.camerasprite].sectnum; + ca = sprite[ud.camerasprite].ang; + } + + mix->SetListenerPosition((float)cx/UNITSPERMETRE, (float)cy/UNITSPERMETRE, (float)cz/ZUNITSPERMETRE); + mix->SetListenerOrientation((float)sintable[(ca-512)&2047]/16384.0, 0.0, (float)sintable[ca&2047]/16384.0, + 0.0, 1.0, 0.0); + + for (j=NumVoices-1; j>=0; j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan) || chans[j].owner < 0) continue; + + global = 0; + gain = 1.0; + i = chans[j].owner; + + sx = sprite[i].x; + sy = -sprite[i].z >> 4; + sz = sprite[i].y; + + //gain += soundvo[num]; +// if (PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,sx,sy,sz-(24<<8),SECT) ) +// gain *= 1.0/32.0; + + if(PN == MUSICANDSFX && SLT < 999) numenvsnds++; + if( soundm[ chans[j].soundnum ]&SOUNDM_GLOBAL ) global = 1; + + switch(chans[j].soundnum) { + case PIPEBOMB_EXPLODE: + case LASERTRIP_EXPLODE: + case RPG_EXPLODE: + gain = 1.0; + global = 1; + break; + default: + //if( sndist > 31444 && PN != MUSICANDSFX) { + // stopsound(j); + // continue; + //} + break; + } + + // A sound may move from player-relative 3D if the viewpoint shifts from the player + // through a viewscreen or viewpoint switching + chans[j].chan->SetGain(gain); + if (PN == APLAYER && sprite[i].yvel == screenpeek) { + chans[j].chan->SetRolloff(0.0); + chans[j].chan->SetFollowListener(true); + chans[j].chan->SetPosition(0.0, 0.0, 0.0); + } else { + chans[j].chan->SetRolloff(global ? 0.0 : 0.3); + chans[j].chan->SetFollowListener(false); + chans[j].chan->SetPosition((float)sx/UNITSPERMETRE, (float)sy/UNITSPERMETRE, (float)sz/ZUNITSPERMETRE); + } + } +} + +void clearsoundlocks(void) +{ +} + +void FX_SetVolume( int volume ) +{ +} + +void FX_SetReverseStereo( int setting ) +{ +} + +void FX_SetReverb( int reverb ) +{ +} + +void FX_SetReverbDelay( int delay ) +{ +} + +int FX_VoiceAvailable( int priority ) +{ + int j; + + if (!jfaud) return 0; + for (j=NumVoices-1;j>=0;j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan)) return 1; + } + return 0; +} + +int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ) +{ + printf("FX_PlayVOC3D()\n"); + return 0; +} + +int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance, + int priority, unsigned long callbackval ) +{ + printf("FX_PlayWAV3D()\n"); + return 0; +} + +int FX_StopSound( int handle ) +{ + printf("FX_StopSound()\n"); + return 0; +} + +int FX_StopAllSounds( void ) +{ + int j; + + if (!jfaud || !havewave) return 0; + for (j=NumVoices-1; j>=0; j--) { + if (!chans[j].chan || !jfaud->IsValidSound(chans[j].chan)) continue; + + jfaud->FreeSound(chans[j].chan); + chans[j].chan = NULL; + chans[j].owner = -1; + } + + return 0; +} + +void MUSIC_SetVolume( int volume ) +{ +} + +void MUSIC_Pause( void ) +{ + if (jfaud) jfaud->PauseMusic(true); +} + +void MUSIC_Continue( void ) +{ + if (jfaud) jfaud->PauseMusic(false); +} + +int MUSIC_StopSong( void ) +{ + if (jfaud) jfaud->StopMusic(); + return 0; +} + +void MUSIC_RegisterTimbreBank( unsigned char *timbres ) +{ +} + diff --git a/polymer/eduke32/source/jmact/_control.h b/polymer/eduke32/source/jmact/_control.h new file mode 100644 index 000000000..b53513170 --- /dev/null +++ b/polymer/eduke32/source/jmact/_control.h @@ -0,0 +1,271 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is NOT part of Duke Nukem 3D version 1.5 - Atomic Edition +However, it is either an older version of a file that is, or is +some test code written during the development of Duke Nukem 3D. +This file is provided purely for educational interest. + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + +//**************************************************************************** +// +// Private header for CONTROL.C +// +//**************************************************************************** + +#ifndef _control_private +#define _control_private +#ifdef __cplusplus +extern "C" { +#endif + +//**************************************************************************** +// +// DEFINES +// +//**************************************************************************** + +#define BUTTON0_SCAN_1 sc_Space +#define BUTTON0_SCAN_2 sc_Enter +#define BUTTON0_SCAN_3 sc_kpad_Enter +#define BUTTON1_SCAN sc_Escape + +#define AXISUNDEFINED 0x7f +#define BUTTONUNDEFINED 0x7f +#define KEYUNDEFINED 0x7f + +#define SENSITIVE 0x400 +//#define MINSENSITIVE 0x30 + +#define THRESHOLD 0x200 +#define MINTHRESHOLD 0x80 + +#define USERINPUTDELAY 200 + +#define ResetMouse 0 +#define GetMouseButtons 3 +#define GetMouseDelta 11 + +#define MouseInt 0x33 +#define JoyMax 0xa00 +#define MaxJoyValue 5000 +#define MINIMUMMOUSESENSITIVITY 0x1000 +#define DEFAULTMOUSESENSITIVITY 0x7000+MINIMUMMOUSESENSITIVITY + +#define CONTROL_NUM_FLAGS 64 +#define INSTANT_ONOFF 0 +#define TOGGLE_ONOFF 1 + +#define MAXCONTROLVALUE 0x7fff + +// Maximum number of buttons for any controller +#define MAXBUTTONS 32 + +// Number of Mouse buttons + +#define MAXMOUSEBUTTONS 6 + +// Number of Mouse Axes + +#define MAXMOUSEAXES 2 + +// Number of JOY buttons + +#define MAXJOYBUTTONS 32 + +// Number of JOY axes + +#define MAXJOYAXES 6 + +// Number of GamePad axes + +#define MAXGAMEPADAXES 2 + +// Number of axes + +#define MAXAXES 6 + +// NORMAL axis scale + +#define NORMALAXISSCALE (65536) + +#define BUTTONSET(x,value) \ + (\ + ((x)>31) ?\ + (CONTROL_ButtonState2 |= (value<<((x)-32))) :\ + (CONTROL_ButtonState1 |= (value<<(x)))\ + ) + +#define BUTTONCLEAR(x) \ + (\ + ((x)>31) ?\ + (CONTROL_ButtonState2 &= (~(1<<((x)-32)))) :\ + (CONTROL_ButtonState1 &= (~(1<<(x))))\ + ) + +#define BUTTONHELDSET(x,value)\ + (\ + ((x)>31) ?\ + (CONTROL_ButtonHeldState2 |= value<<((x)-32)) :\ + (CONTROL_ButtonHeldState1 |= value<<(x))\ + ) + +#define LIMITCONTROL(x)\ + {\ + if ((*x)>MAXCONTROLVALUE) \ + {\ + (*x) = MAXCONTROLVALUE;\ + }\ + if ((*x)<-MAXCONTROLVALUE) \ + {\ + (*x) = -MAXCONTROLVALUE;\ + }\ + } +#define SGN(x) \ + ( ( (x) > 0 ) ? 1 : ( (x) < 0 ) ? -1 : 0 ) + +//**************************************************************************** +// +// TYPEDEFS +// +//**************************************************************************** + +typedef enum + { + motion_Left = -1, + motion_Up = -1, + motion_None = 0, + motion_Right = 1, + motion_Down = 1 + } motion; + + +typedef struct + { + int32 joyMinX; + int32 joyMinY; + int32 threshMinX; + int32 threshMinY; + int32 threshMaxX; + int32 threshMaxY; + int32 joyMaxX; + int32 joyMaxY; + int32 joyMultXL; + int32 joyMultYL; + int32 joyMultXH; + int32 joyMultYH; + } JoystickDef; + +// int32 ThrottleMin; +// int32 RudderMin; +// int32 ThrottlethreshMin; +// int32 RudderthreshMin; +// int32 ThrottlethreshMax; +// int32 RudderthreshMax; +// int32 ThrottleMax; +// int32 RudderMax; +// int32 ThrottleMultL; +// int32 RudderMultL; +// int32 ThrottleMultH; +// int32 RudderMultH; + +/* +typedef struct + { + byte active : 1; + byte used : 1; + byte toggle : 1; + byte buttonheld : 1; + byte cleared : 1; + } controlflags; +typedef struct + { + volatile byte active : 1; + volatile byte used : 1; + volatile byte toggle : 1; + volatile byte buttonheld : 1; + volatile byte cleared : 1; + } controlflags; +*/ +typedef struct + { + byte active ; + byte used ; + byte toggle ; + byte buttonheld ; + int32 cleared ; + } controlflags; + +typedef struct + { + kb_scancode key1; + kb_scancode key2; + } controlkeymaptype; + +typedef struct + { + byte singleclicked; + byte doubleclicked; + word extra; + } controlbuttontype; + +typedef struct + { + byte analogmap; + byte minmap; + byte maxmap; + byte extra; + } controlaxismaptype; + +typedef struct + { + int32 analog; + int32 digital; + } controlaxistype; + + +//*************************************************************************** +// +// PROTOTYPES +// +//*************************************************************************** + +void CONTROL_GetMouseDelta( void ); +byte CONTROL_GetMouseButtons( void ); +boolean CONTROL_StartMouse( void ); +void CONTROL_GetJoyAbs( void ); +void CONTROL_GetJoyDelta( void ); +void CONTROL_SetJoyScale( void ); +boolean CONTROL_StartJoy( int32 joy ); +void CONTROL_ShutJoy( int32 joy ); +void CONTROL_SetFlag( int32 which, boolean active ); +void CONTROL_ButtonFunctionState( boolean * state ); +boolean CONTROL_KeyboardFunctionPressed( int32 whichfunction ); +boolean CONTROL_CheckRange( int32 which ); +int32 CONTROL_GetTime( void ); +void CONTROL_AxisFunctionState( boolean * state ); +void CONTROL_GetJoyMovement( ControlInfo * info ); + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/_scrplib.h b/polymer/eduke32/source/jmact/_scrplib.h new file mode 100644 index 000000000..b27db8045 --- /dev/null +++ b/polymer/eduke32/source/jmact/_scrplib.h @@ -0,0 +1,209 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is NOT part of Duke Nukem 3D version 1.5 - Atomic Edition +However, it is either an older version of a file that is, or is +some test code written during the development of Duke Nukem 3D. +This file is provided purely for educational interest. + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +// scrplib.h + +#ifndef _scriplib_private +#define _scriplib_private +#ifdef __cplusplus +extern "C" { +#endif + +#define SCRIPTSECTIONSTART ('[') +#define SCRIPTSECTIONEND (']') +#define SCRIPTENTRYSEPARATOR ('=') +#define SCRIPTCOMMENT (';') +#define SCRIPTEOL ('\n') +#define SCRIPTNULL ('\0') +#define SCRIPTSTRINGSEPARATOR ('"') +#define SCRIPTHEXFIRST ('0') +#define SCRIPTHEXSECOND ('x') +#define SCRIPTSPACE (' ') +#define SCRIPTDEFAULTVALUE ('~') +#define MAXSCRIPTFILES 20 +#define SCRIPT(scripthandle,item) (scriptfiles[(scripthandle)]->item) + +typedef enum + { + linetype_comment, + linetype_section, + linetype_entry + } linetype_t; + +typedef struct scriptline + { + int32 type; + void * ptr; + struct scriptline *nextline; + struct scriptline *prevline; + } ScriptLineType; + +typedef struct scriptentry + { + char * name; + char * value; + struct scriptentry *nextentry; + struct scriptentry *preventry; + } ScriptEntryType; + +typedef struct scriptsection + { + char * name; + ScriptEntryType *entries; + ScriptLineType *lastline; + struct scriptsection *nextsection; + struct scriptsection *prevsection; + } ScriptSectionType; + +typedef struct + { + ScriptSectionType * script; + ScriptSectionType * lastsection; + ScriptLineType * scriptlines; + char scriptfilename[128]; + } script_t; + +/* +============== += += SCRIPT_New += +============== +*/ + +int32 SCRIPT_New( void ); + +/* +============== += += SCRIPT_Delete += +============== +*/ +void SCRIPT_Delete( int32 scripthandle ); + +/* +============== += += SCRIPT_FreeSection += +============== +*/ +void SCRIPT_FreeSection( ScriptSectionType * section ); + +/* +============== += += SafeWriteString += +============== +*/ +void SafeWriteString (int32 handle, char * string); + +/* +============== += += SCRIPT_AddLine += +============== +*/ + + +ScriptLineType * SCRIPT_AddLine + ( + ScriptLineType * root, + int32 type, + void * ptr + ); + +/* +============== += += SCRIPT_SectionExists += +============== +*/ +ScriptSectionType * SCRIPT_SectionExists + ( + int32 scripthandle, + char * sectionname + ); + +/* +============== += += SCRIPT_AddSection += +============== +*/ +ScriptSectionType * SCRIPT_AddSection( int32 scripthandle, char * sectionname ); + +/* +============== += += SCRIPT_EntryExists += +============== +*/ +ScriptEntryType * SCRIPT_EntryExists + ( + ScriptSectionType * section, + char * entryname + ); + +/* +============== += += SCRIPT_AddEntry += +============== +*/ +void SCRIPT_AddEntry + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * entryvalue + ); + +/* +============== += += SCRIPT_DecodeToken += +============== +*/ + +void SCRIPT_DecodeToken ( int32 scripthandle, char * str ); + + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/animlib.c b/polymer/eduke32/source/jmact/animlib.c new file mode 100644 index 000000000..6a1c840b9 --- /dev/null +++ b/polymer/eduke32/source/jmact/animlib.c @@ -0,0 +1,368 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#include "compat.h" +#include "types.h" +#include "develop.h" +#include "util_lib.h" +#include "animlib.h" + +//**************************************************************************** +// +// GLOBALS +// +//**************************************************************************** + +//**************************************************************************** +// +// LOCALS +// +//**************************************************************************** +static anim_t * anim=NULL; +static boolean Anim_Started = false; + +//**************************************************************************** +// +// CheckAnimStarted () +// +//**************************************************************************** + +static void CheckAnimStarted ( char * funcname ) + { + if (!Anim_Started) + Error("ANIMLIB_%s: Anim has not been initialized\n",funcname); + } +//**************************************************************************** +// +// findpage () +// - given a frame number return the large page number it resides in +// +//**************************************************************************** + +uint16 findpage (uint16 framenumber) + { + uint16 i; + + CheckAnimStarted ( "findpage" ); + for(i=0; ilpheader.nLps; i++) + { + if + ( + anim->LpArray[i].baseRecord <= framenumber && + anim->LpArray[i].baseRecord + anim->LpArray[i].nRecords > framenumber + ) + return(i); + } + return(i); + } + + +//**************************************************************************** +// +// loadpage () +// - seek out and load in the large page specified +// +//**************************************************************************** + +void loadpage (uint16 pagenumber, uint16 *pagepointer) + { + int32 size; + byte * buffer; + + CheckAnimStarted ( "loadpage" ); + buffer = anim->buffer; + if (anim->curlpnum != pagenumber) + { + anim->curlpnum = pagenumber; + buffer += 0xb00 + (pagenumber*0x10000); + size = sizeof(lp_descriptor); + /* + Bmemcpy(&anim->curlp,buffer,size); + + // JBF: why didn't this get read from the LpArray[] table? + anim->curlp.baseRecord = B_LITTLE16(anim->curlp.baseRecord); + anim->curlp.nRecords = B_LITTLE16(anim->curlp.nRecords); + anim->curlp.nBytes = B_LITTLE16(anim->curlp.nBytes); + */ + Bmemcpy(&anim->curlp, &anim->LpArray[pagenumber], size); + + buffer += size + sizeof(uint16); + Bmemcpy(pagepointer,buffer,anim->curlp.nBytes+(anim->curlp.nRecords*2)); + } + } + + +//**************************************************************************** +// +// CPlayRunSkipDump () +// - This version of the decompressor is here for portability to non PC's +// +//**************************************************************************** + +void CPlayRunSkipDump (char *srcP, char *dstP) + { + signed char cnt; + uint16 wordCnt; + byte pixel; + + +nextOp: + cnt = (signed char) *srcP++; + if (cnt > 0) + goto dump; + if (cnt == 0) + goto run; + cnt -= 0x80; + if (cnt == 0) + goto longOp; +/* shortSkip */ + dstP += cnt; /* adding 7-bit count to 32-bit pointer */ + goto nextOp; +dump: + do + { + *dstP++ = *srcP++; + } while (--cnt); + goto nextOp; +run: + wordCnt = (byte)*srcP++; /* 8-bit unsigned count */ + pixel = *srcP++; + do + { + *dstP++ = pixel; + } while (--wordCnt); + + goto nextOp; +longOp: + wordCnt = B_LITTLE16(*((uint16 *)srcP)); + srcP += sizeof(uint16); + if ((int16)wordCnt <= 0) + goto notLongSkip; /* Do SIGNED test. */ + +/* longSkip. */ + dstP += wordCnt; + goto nextOp; + +notLongSkip: + if (wordCnt == 0) + goto stop; + wordCnt -= 0x8000; /* Remove sign bit. */ + if (wordCnt >= 0x4000) + goto longRun; + +/* longDump. */ + do + { + *dstP++ = *srcP++; + } while (--wordCnt); + goto nextOp; + +longRun: + wordCnt -= 0x4000; /* Clear "longRun" bit. */ + pixel = *srcP++; + do + { + *dstP++ = pixel; + } while (--wordCnt); + goto nextOp; + +stop: /* all done */ + ; + } + + + +//**************************************************************************** +// +// renderframe () +// - draw the frame sepcified from the large page in the buffer pointed to +// +//**************************************************************************** + +void renderframe (uint16 framenumber, uint16 *pagepointer) + { + uint16 offset=0; + uint16 i; + uint16 destframe; + byte *ppointer; + + CheckAnimStarted ( "renderframe" ); + destframe = framenumber - anim->curlp.baseRecord; + + for(i = 0; i < destframe; i++) + { + offset += B_LITTLE16(pagepointer[i]); + } + ppointer = (byte *)pagepointer; + + ppointer+=anim->curlp.nRecords*2+offset; + if(ppointer[1]) + { + ppointer += (4 + B_LITTLE16(((uint16 *)ppointer)[1]) + (B_LITTLE16(((uint16 *)ppointer)[1]) & 1)); + } + else + { + ppointer+=4; + } + + CPlayRunSkipDump (ppointer, anim->imagebuffer); + } + + +//**************************************************************************** +// +// drawframe () +// - high level frame draw routine +// +//**************************************************************************** + +void drawframe (uint16 framenumber) + { + CheckAnimStarted ( "drawframe" ); + loadpage(findpage(framenumber), anim->thepage); + renderframe(framenumber, anim->thepage); + } + + +//**************************************************************************** +// +// ANIM_LoadAnim () +// +//**************************************************************************** + +void ANIM_LoadAnim (char * buffer) + { + uint16 i; + int32 size; + + if (!Anim_Started) { + anim = SafeMalloc(sizeof(anim_t)); + Anim_Started = true; + } + + anim->buffer = buffer; + anim->curlpnum = 0xffff; + anim->currentframe = -1; + size = sizeof(lpfileheader); + Bmemcpy(&anim->lpheader, buffer, size ); + + anim->lpheader.id = B_LITTLE32(anim->lpheader.id); + anim->lpheader.maxLps = B_LITTLE16(anim->lpheader.maxLps); + anim->lpheader.nLps = B_LITTLE16(anim->lpheader.nLps); + anim->lpheader.nRecords = B_LITTLE32(anim->lpheader.nRecords); + anim->lpheader.maxRecsPerLp = B_LITTLE16(anim->lpheader.maxRecsPerLp); + anim->lpheader.lpfTableOffset = B_LITTLE16(anim->lpheader.lpfTableOffset); + anim->lpheader.contentType = B_LITTLE32(anim->lpheader.contentType); + anim->lpheader.width = B_LITTLE16(anim->lpheader.width); + anim->lpheader.height = B_LITTLE16(anim->lpheader.height); + anim->lpheader.nFrames = B_LITTLE32(anim->lpheader.nFrames); + anim->lpheader.framesPerSecond = B_LITTLE16(anim->lpheader.framesPerSecond); + + buffer += size+128; + // load the color palette + for (i = 0; i < 768; i += 3) + { + anim->pal[i+2] = *buffer++; + anim->pal[i+1] = *buffer++; + anim->pal[i] = *buffer++; + buffer++; + } + // read in large page descriptors + size = sizeof(anim->LpArray); + Bmemcpy(&anim->LpArray,buffer,size); + + for (i = 0; i < size/sizeof(lp_descriptor); i++) + { + anim->LpArray[i].baseRecord = B_LITTLE16(anim->LpArray[i].baseRecord); + anim->LpArray[i].nRecords = B_LITTLE16(anim->LpArray[i].nRecords); + anim->LpArray[i].nBytes = B_LITTLE16(anim->LpArray[i].nBytes); + } + } + +//**************************************************************************** +// +// ANIM_FreeAnim () +// +//**************************************************************************** + +void ANIM_FreeAnim ( void ) + { + if (Anim_Started) + { + SafeFree(anim); + Anim_Started = false; + } + } + +//**************************************************************************** +// +// ANIM_NumFrames () +// +//**************************************************************************** + +int32 ANIM_NumFrames ( void ) + { + CheckAnimStarted ( "NumFrames" ); + return anim->lpheader.nRecords; + } + +//**************************************************************************** +// +// ANIM_DrawFrame () +// +//**************************************************************************** + +byte * ANIM_DrawFrame (int32 framenumber) + { + int32 cnt; + + CheckAnimStarted ( "DrawFrame" ); + if ((anim->currentframe != -1) && (anim->currentframe<=framenumber)) + { + for (cnt = anim->currentframe; cnt < framenumber; cnt++) + drawframe (cnt); + } + else + { + for (cnt = 0; cnt < framenumber; cnt++) + drawframe (cnt); + } + anim->currentframe = framenumber; + return anim->imagebuffer; + } + +//**************************************************************************** +// +// ANIM_GetPalette () +// +//**************************************************************************** + +byte * ANIM_GetPalette ( void ) + { + CheckAnimStarted ( "GetPalette" ); + return anim->pal; + } diff --git a/polymer/eduke32/source/jmact/animlib.h b/polymer/eduke32/source/jmact/animlib.h new file mode 100644 index 000000000..92cb1cab8 --- /dev/null +++ b/polymer/eduke32/source/jmact/animlib.h @@ -0,0 +1,175 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +///////////////////////////////////////////////////////////////////////////// +// +// ANIMLIB.H +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef _animlib_public_ +#define _animlib_public_ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +# define PACKED __attribute__ ((packed)) +#else +# define PACKED +# ifdef _MSC_VER +# pragma pack(1) +# endif +# ifdef __WATCOMC__ +# pragma pack(push,1); +# endif +#endif + +// structure declarations for deluxe animate large page files */ + +typedef struct PACKED + { + uint32 id; // 4 character ID == "LPF " */ + uint16 maxLps; // max # largePages allowed. 256 FOR NOW. */ + uint16 nLps; // # largePages in this file. */ + uint32 nRecords; // # records in this file. 65534 is current limit plus */ + // one for last-to-first delta for looping the animation */ + uint16 maxRecsPerLp; // # records permitted in an lp. 256 FOR NOW. */ + uint16 lpfTableOffset; // Absolute Seek position of lpfTable. 1280 FOR NOW. + // The lpf Table is an array of 256 large page structures + // that is used to facilitate finding records in an anim + // file without having to seek through all of the Large + // Pages to find which one a specific record lives in. */ + uint32 contentType; // 4 character ID == "ANIM" */ + uint16 width; // Width of screen in pixels. */ + uint16 height; // Height of screen in pixels. */ + byte variant; // 0==ANIM. */ + byte version; // 0==frame rate is multiple of 18 cycles/sec. + // 1==frame rate is multiple of 70 cycles/sec. */ + byte hasLastDelta; // 1==Last record is a delta from last-to-first frame. */ + byte lastDeltaValid; // 0==The last-to-first delta (if present) hasn't been + // updated to match the current first&last frames, so it + // should be ignored. */ + byte pixelType; // /* 0==256 color. */ + byte CompressionType;// /* 1==(RunSkipDump) Only one used FOR NOW. */ + byte otherRecsPerFrm;// /* 0 FOR NOW. */ + byte bitmaptype; // /* 1==320x200, 256-color. Only one implemented so far. */ + byte recordTypes[32];// /* Not yet implemented. */ + uint32 nFrames; // /* In case future version adds other records at end of + // file, we still know how many actual frames. + // NOTE: DOES include last-to-first delta when present. */ + uint16 framesPerSecond; // Number of frames to play per second. */ + uint16 pad2[29]; // 58 bytes of filler to round up to 128 bytes total. */ + } lpfileheader; + +// this is the format of a large page structure +typedef struct PACKED + { + uint16 baseRecord; // Number of first record in this large page. + uint16 nRecords; // Number of records in lp. + // bit 15 of "nRecords" == "has continuation from previous lp". + // bit 14 of "nRecords" == "final record continues on next lp". + uint16 nBytes; // Total number of bytes of contents, excluding header. + } lp_descriptor; + +#undef PACKED +#ifdef _MSC_VER +# pragma pack() +#endif +#ifdef __WATCOMC__ +# pragma pack(pop); +#endif + +typedef struct + { + uint16 framecount; // current frame of anim + lpfileheader lpheader; // file header will be loaded into this structure + lp_descriptor LpArray[256]; // arrays of large page structs used to find frames + uint16 curlpnum; // initialize to an invalid Large page number + lp_descriptor curlp; // header of large page currently in memory + uint16 thepage[0x8000]; // buffer where current large page is loaded + byte imagebuffer[0x10000]; // buffer where anim frame is decoded + byte * buffer; + byte pal[768]; + int32 currentframe; + } anim_t; + +//**************************************************************************** +// +// ANIM_LoadAnim () +// +// Setup internal anim data structure +// +//**************************************************************************** + +void ANIM_LoadAnim (char * buffer); + +//**************************************************************************** +// +// ANIM_FreeAnim () +// +// Free up internal anim data structure +// +//**************************************************************************** + +void ANIM_FreeAnim ( void ); + +//**************************************************************************** +// +// ANIM_NumFrames () +// +// returns the number of frames in the current anim +// +//**************************************************************************** + +int32 ANIM_NumFrames ( void ); + +//**************************************************************************** +// +// ANIM_DrawFrame () +// +// Draw the frame to a returned buffer +// +//**************************************************************************** + +byte * ANIM_DrawFrame (int32 framenumber); + +//**************************************************************************** +// +// ANIM_GetPalette () +// +// return the palette of the anim +//**************************************************************************** + +byte * ANIM_GetPalette ( void ); + +extern anim_t * anim; + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/control.c b/polymer/eduke32/source/jmact/control.c new file mode 100644 index 000000000..2eb65e1f0 --- /dev/null +++ b/polymer/eduke32/source/jmact/control.c @@ -0,0 +1,982 @@ +/* + * control.c + * MACT library controller handling + * + * Derived from MACT386.LIB disassembly by Jonathon Fowler + * + */ + +#include "types.h" +#include "keyboard.h" +#include "mouse.h" +#include "control.h" +#include "_control.h" +#include "util_lib.h" + +#include "baselayer.h" +#include "compat.h" +#include "pragmas.h" + + +boolean CONTROL_JoyPresent = false; +boolean CONTROL_JoystickEnabled = false; +boolean CONTROL_MousePresent = false; +boolean CONTROL_MouseEnabled = false; +uint32 CONTROL_ButtonState1 = 0; +uint32 CONTROL_ButtonHeldState1 = 0; +uint32 CONTROL_ButtonState2 = 0; +uint32 CONTROL_ButtonHeldState2 = 0; + +static int32 CONTROL_UserInputDelay = -1; +static int32 CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY; +static int32 CONTROL_NumMouseButtons = 0; +static int32 CONTROL_NumMouseAxes = 0; +static int32 CONTROL_NumJoyButtons = 0; +static int32 CONTROL_NumJoyAxes = 0; +static controlflags CONTROL_Flags[CONTROL_NUM_FLAGS]; +static controlbuttontype CONTROL_MouseButtonMapping[MAXMOUSEBUTTONS], + CONTROL_JoyButtonMapping[MAXJOYBUTTONS]; +static controlkeymaptype CONTROL_KeyMapping[CONTROL_NUM_FLAGS]; +static controlaxismaptype CONTROL_MouseAxesMap[MAXMOUSEAXES], // maps physical axes onto virtual ones + CONTROL_JoyAxesMap[MAXJOYAXES]; +static controlaxistype CONTROL_MouseAxes[MAXMOUSEAXES], // physical axes + CONTROL_JoyAxes[MAXJOYAXES]; +static controlaxistype CONTROL_LastMouseAxes[MAXMOUSEAXES], + CONTROL_LastJoyAxes[MAXJOYAXES]; +static int32 CONTROL_MouseAxesScale[MAXMOUSEAXES], CONTROL_JoyAxesScale[MAXJOYAXES]; +static int32 CONTROL_MouseButtonState[MAXMOUSEBUTTONS], CONTROL_JoyButtonState[MAXJOYBUTTONS]; +static int32 CONTROL_MouseButtonClickedTime[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedTime[MAXJOYBUTTONS]; +static boolean CONTROL_MouseButtonClickedState[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedState[MAXJOYBUTTONS]; +static boolean CONTROL_MouseButtonClicked[MAXMOUSEBUTTONS], CONTROL_JoyButtonClicked[MAXJOYBUTTONS]; +static byte CONTROL_MouseButtonClickedCount[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS]; +static boolean CONTROL_UserInputCleared[3]; +static int32 (*GetTime)(void); +static boolean CONTROL_Started = false; +static int32 ticrate; +static int32 CONTROL_DoubleClickSpeed; + + +void CONTROL_GetMouseDelta(void) +{ + int32 x,y; + + MOUSE_GetDelta(&x, &y); + + /* What in the name of all things sacred is this? + if (labs(*x) > labs(*y)) { + *x /= 3; + } else { + *y /= 3; + } + *y = *y * 96; + *x = (*x * 32 * CONTROL_MouseSensitivity) >> 15; + */ + + CONTROL_MouseAxes[0].analog = mulscale8(x, CONTROL_MouseSensitivity); + CONTROL_MouseAxes[1].analog = mulscale6(y, CONTROL_MouseSensitivity); +} + +int32 CONTROL_GetMouseSensitivity(void) +{ + return (CONTROL_MouseSensitivity - MINIMUMMOUSESENSITIVITY); +} + +void CONTROL_SetMouseSensitivity(int32 newsensitivity) +{ + CONTROL_MouseSensitivity = newsensitivity + MINIMUMMOUSESENSITIVITY; +} + +boolean CONTROL_StartMouse(void) +{ + CONTROL_NumMouseButtons = MAXMOUSEBUTTONS; + return MOUSE_Init(); +} + +void CONTROL_GetJoyAbs( void ) +{ +} + +void CONTROL_FilterJoyDelta(void) +{ +} + +void CONTROL_GetJoyDelta( void ) +{ + int32 i; + + for (i=0; i> 5; +} + + +void CONTROL_SetJoyScale( void ) +{ +} + +void CONTROL_CenterJoystick + ( + void ( *CenterCenter )( void ), + void ( *UpperLeft )( void ), + void ( *LowerRight )( void ), + void ( *CenterThrottle )( void ), + void ( *CenterRudder )( void ) + ) +{ +} + +boolean CONTROL_StartJoy(int32 joy) +{ + return (inputdevices & 3) == 3; +} + +void CONTROL_ShutJoy(int32 joy) +{ + CONTROL_JoyPresent = false; +} + +int32 CONTROL_GetTime(void) +{ + static int32 t = 0; + t += 5; + return t; +} + +boolean CONTROL_CheckRange(int32 which) +{ + if ((uint32)which < (uint32)CONTROL_NUM_FLAGS) return false; + //Error("CONTROL_CheckRange: Index %d out of valid range for %d control flags.", + // which, CONTROL_NUM_FLAGS); + return true; +} + +void CONTROL_SetFlag(int32 which, boolean active) +{ + if (CONTROL_CheckRange(which)) return; + + if (CONTROL_Flags[which].toggle == INSTANT_ONOFF) { + CONTROL_Flags[which].active = active; + } else { + if (active) { + CONTROL_Flags[which].buttonheld = false; + } else if (CONTROL_Flags[which].buttonheld == false) { + CONTROL_Flags[which].buttonheld = true; + CONTROL_Flags[which].active = (CONTROL_Flags[which].active ? false : true); + } + } +} + +boolean CONTROL_KeyboardFunctionPressed(int32 which) +{ + boolean key1 = 0, key2 = 0; + + if (CONTROL_CheckRange(which)) return false; + + if (!CONTROL_Flags[which].used) return false; + + if (CONTROL_KeyMapping[which].key1 != KEYUNDEFINED) + key1 = KB_KeyDown[ CONTROL_KeyMapping[which].key1 ] ? true : false; + + if (CONTROL_KeyMapping[which].key2 != KEYUNDEFINED) + key2 = KB_KeyDown[ CONTROL_KeyMapping[which].key2 ] ? true : false; + + return (key1 | key2); +} + +void CONTROL_ClearKeyboardFunction(int32 which) +{ + if (CONTROL_CheckRange(which)) return; + + if (!CONTROL_Flags[which].used) return; + + if (CONTROL_KeyMapping[which].key1 != KEYUNDEFINED) + KB_KeyDown[ CONTROL_KeyMapping[which].key1 ] = 0; + + if (CONTROL_KeyMapping[which].key2 != KEYUNDEFINED) + KB_KeyDown[ CONTROL_KeyMapping[which].key2 ] = 0; +} + +void CONTROL_DefineFlag( int32 which, boolean toggle ) +{ + if (CONTROL_CheckRange(which)) return; + + CONTROL_Flags[which].active = false; + CONTROL_Flags[which].used = true; + CONTROL_Flags[which].toggle = toggle; + CONTROL_Flags[which].buttonheld = false; + CONTROL_Flags[which].cleared = 0; +} + +boolean CONTROL_FlagActive( int32 which ) +{ + if (CONTROL_CheckRange(which)) return false; + + return CONTROL_Flags[which].used; +} + +void CONTROL_MapKey( int32 which, kb_scancode key1, kb_scancode key2 ) +{ + if (CONTROL_CheckRange(which)) return; + + CONTROL_KeyMapping[which].key1 = key1 ? key1 : KEYUNDEFINED; + CONTROL_KeyMapping[which].key2 = key2 ? key2 : KEYUNDEFINED; +} + +void CONTROL_PrintKeyMap(void) +{ + int32 i; + + for (i=0;i= (uint32)MAXMOUSEBUTTONS) { + //Error("CONTROL_MapButton: button %d out of valid range for %d mouse buttons.", + // whichbutton, CONTROL_NumMouseButtons); + return; + } + set = CONTROL_MouseButtonMapping; + break; + + case controldevice_joystick: + if ((uint32)whichbutton >= (uint32)MAXJOYBUTTONS) { + //Error("CONTROL_MapButton: button %d out of valid range for %d joystick buttons.", + // whichbutton, CONTROL_NumJoyButtons); + return; + } + set = CONTROL_JoyButtonMapping; + break; + + default: + //Error("CONTROL_MapButton: invalid controller device type"); + return; + } + + if (doubleclicked) + set[whichbutton].doubleclicked = whichfunction; + else + set[whichbutton].singleclicked = whichfunction; +} + +void CONTROL_MapAnalogAxis( int32 whichaxis, int32 whichanalog, controldevice device ) +{ + controlaxismaptype *set; + + if ((uint32)whichanalog >= (uint32)analog_maxtype) { + //Error("CONTROL_MapAnalogAxis: analog function %d out of valid range for %d analog functions.", + // whichanalog, analog_maxtype); + return; + } + + switch (device) { + case controldevice_mouse: + if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { + //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d mouse axes.", + // whichaxis, MAXMOUSEAXES); + return; + } + + set = CONTROL_MouseAxesMap; + break; + + case controldevice_joystick: + if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { + //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d joystick axes.", + // whichaxis, MAXJOYAXES); + return; + } + + set = CONTROL_JoyAxesMap; + break; + + default: + //Error("CONTROL_MapAnalogAxis: invalid controller device type"); + return; + } + + set[whichaxis].analogmap = whichanalog; +} + +void CONTROL_SetAnalogAxisScale( int32 whichaxis, int32 axisscale, controldevice device ) +{ + int32 *set; + + switch (device) { + case controldevice_mouse: + if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { + //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d mouse axes.", + // whichaxis, MAXMOUSEAXES); + return; + } + + set = CONTROL_MouseAxesScale; + break; + + case controldevice_joystick: + if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { + //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d joystick axes.", + // whichaxis, MAXJOYAXES); + return; + } + + set = CONTROL_JoyAxesScale; + break; + + default: + //Error("CONTROL_SetAnalogAxisScale: invalid controller device type"); + return; + } + + set[whichaxis] = axisscale; +} + +void CONTROL_MapDigitalAxis( int32 whichaxis, int32 whichfunction, int32 direction, controldevice device ) +{ + controlaxismaptype *set; + + if (CONTROL_CheckRange(whichfunction)) whichfunction = AXISUNDEFINED; + + switch (device) { + case controldevice_mouse: + if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { + //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d mouse axes.", + // whichaxis, MAXMOUSEAXES); + return; + } + + set = CONTROL_MouseAxesMap; + break; + + case controldevice_joystick: + if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { + //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d joystick axes.", + // whichaxis, MAXJOYAXES); + return; + } + + set = CONTROL_JoyAxesMap; + break; + + default: + //Error("CONTROL_MapDigitalAxis: invalid controller device type"); + return; + } + + switch (direction) { // JBF: this is all very much a guess. The ASM puzzles me. + case axis_up: + case axis_left: + set[whichaxis].minmap = whichfunction; + break; + case axis_down: + case axis_right: + set[whichaxis].maxmap = whichfunction; + break; + default: + break; + } +} + +void CONTROL_ClearFlags(void) +{ + int32 i; + + for (i=0;i> i) & 1; + + DeviceButtonState[i] = bs; + ButtonClickedState[i] = false; + + if (bs) { + if (ButtonClicked[i] == false) { + ButtonClicked[i] = true; + + if (ButtonClickedCount[i] == 0 || tm > ButtonClickedTime[i]) { + ButtonClickedTime[i] = tm + CONTROL_DoubleClickSpeed; + ButtonClickedCount[i] = 1; + } + else if (tm < ButtonClickedTime[i]) { + ButtonClickedState[i] = true; + ButtonClickedTime[i] = 0; + ButtonClickedCount[i] = 2; + } + } + else if (ButtonClickedCount[i] == 2) { + ButtonClickedState[i] = true; + } + } else { + if (ButtonClickedCount[i] == 2) + ButtonClickedCount[i] = 0; + + ButtonClicked[i] = false; + } + } +} + +void CONTROL_GetDeviceButtons(void) +{ + int32 t; + + t = GetTime(); + + if (CONTROL_MouseEnabled) { + DoGetDeviceButtons( + MOUSE_GetButtons(), t, + CONTROL_NumMouseButtons, + CONTROL_MouseButtonState, + CONTROL_MouseButtonClickedTime, + CONTROL_MouseButtonClickedState, + CONTROL_MouseButtonClicked, + CONTROL_MouseButtonClickedCount + ); + } + + if (CONTROL_JoystickEnabled) { + int32 buttons = joyb; + if (joynumhats > 0 && joyhat[0] != -1) { + static int32 hatstate[] = { 1, 1|2, 2, 2|4, 4, 4|8, 8, 8|1 }; + int val; + + // thanks SDL for this much more sensible method + val = ((joyhat[0] + 4500 / 2) % 36000) / 4500; + if (val < 8) buttons |= hatstate[val] << min(MAXJOYBUTTONS,joynumbuttons); + } + + DoGetDeviceButtons( + buttons, t, + CONTROL_NumJoyButtons, + CONTROL_JoyButtonState, + CONTROL_JoyButtonClickedTime, + CONTROL_JoyButtonClickedState, + CONTROL_JoyButtonClicked, + CONTROL_JoyButtonClickedCount + ); + } +} + +void CONTROL_DigitizeAxis(int32 axis, controldevice device) +{ + controlaxistype *set, *lastset; + + switch (device) { + case controldevice_mouse: + set = CONTROL_MouseAxes; + lastset = CONTROL_LastMouseAxes; + break; + + case controldevice_joystick: + set = CONTROL_JoyAxes; + lastset = CONTROL_LastJoyAxes; + break; + + default: return; + } + + if (set[axis].analog > 0) { + if (set[axis].analog > THRESHOLD) { // if very much in one direction, + set[axis].digital = 1; // set affirmative + } else { + if (set[axis].analog > MINTHRESHOLD) { // if hanging in limbo, + if (lastset[axis].digital == 1) // set if in same direction as last time + set[axis].digital = 1; + } + } + } else { + if (set[axis].analog < -THRESHOLD) { + set[axis].digital = -1; + } else { + if (set[axis].analog < -MINTHRESHOLD) { + if (lastset[axis].digital == -1) + set[axis].digital = -1; + } + } + } +} + +void CONTROL_ScaleAxis(int32 axis, controldevice device) +{ + controlaxistype *set; + int32 *scale; + + switch (device) { + case controldevice_mouse: + set = CONTROL_MouseAxes; + scale = CONTROL_MouseAxesScale; + break; + + case controldevice_joystick: + set = CONTROL_JoyAxes; + scale = CONTROL_JoyAxesScale; + break; + + default: return; + } + + set[axis].analog = mulscale16(set[axis].analog, scale[axis]); +} + +void CONTROL_ApplyAxis(int32 axis, ControlInfo *info, controldevice device) +{ + controlaxistype *set; + controlaxismaptype *map; + + switch (device) { + case controldevice_mouse: + set = CONTROL_MouseAxes; + map = CONTROL_MouseAxesMap; + break; + + case controldevice_joystick: + set = CONTROL_JoyAxes; + map = CONTROL_JoyAxesMap; + break; + + default: return; + } + + switch (map[axis].analogmap) { + case analog_turning: info->dyaw += set[axis].analog; break; + case analog_strafing: info->dx += set[axis].analog; break; + case analog_lookingupanddown: info->dpitch += set[axis].analog; break; + case analog_elevation: info->dy += set[axis].analog; break; + case analog_rolling: info->droll += set[axis].analog; break; + case analog_moving: info->dz += set[axis].analog; break; + default: break; + } +} + +void CONTROL_PollDevices(ControlInfo *info) +{ + int32 i; + + memcpy(CONTROL_LastMouseAxes, CONTROL_MouseAxes, sizeof(CONTROL_MouseAxes)); + memcpy(CONTROL_LastJoyAxes, CONTROL_JoyAxes, sizeof(CONTROL_JoyAxes)); + + memset(CONTROL_MouseAxes, 0, sizeof(CONTROL_MouseAxes)); + memset(CONTROL_JoyAxes, 0, sizeof(CONTROL_JoyAxes)); + memset(info, 0, sizeof(ControlInfo)); + + if (CONTROL_MouseEnabled) { + CONTROL_GetMouseDelta(); + + for (i=0; idir = dir_None; + + // checks if CONTROL_UserInputDelay is too far in the future due to clock skew? + if (GetTime() + ((ticrate * USERINPUTDELAY) / 1000) < CONTROL_UserInputDelay) + CONTROL_UserInputDelay = -1; + + if (GetTime() >= CONTROL_UserInputDelay) { + if (CONTROL_MouseAxes[1].digital == -1) + info->dir = dir_North; + else if (CONTROL_MouseAxes[1].digital == 1) + info->dir = dir_South; + else if (CONTROL_MouseAxes[0].digital == -1) + info->dir = dir_West; + else if (CONTROL_MouseAxes[0].digital == 1) + info->dir = dir_East; + + if (CONTROL_JoyAxes[1].digital == -1) + info->dir = dir_North; + else if (CONTROL_JoyAxes[1].digital == 1) + info->dir = dir_South; + else if (CONTROL_JoyAxes[0].digital == -1) + info->dir = dir_West; + else if (CONTROL_JoyAxes[0].digital == 1) + info->dir = dir_East; + } + + info->button0 = CONTROL_MouseButtonState[0] | CONTROL_JoyButtonState[0]; + info->button1 = CONTROL_MouseButtonState[1] | CONTROL_JoyButtonState[1]; + + if (KB_KeyDown[sc_kpad_8] || KB_KeyDown[sc_UpArrow]) + info->dir = dir_North; + else if (KB_KeyDown[sc_kpad_2] || KB_KeyDown[sc_DownArrow]) + info->dir = dir_South; + else if (KB_KeyDown[sc_kpad_4] || KB_KeyDown[sc_LeftArrow]) + info->dir = dir_West; + else if (KB_KeyDown[sc_kpad_6] || KB_KeyDown[sc_RightArrow]) + info->dir = dir_East; + + if (KB_KeyDown[BUTTON0_SCAN_1] || KB_KeyDown[BUTTON0_SCAN_2] || KB_KeyDown[BUTTON0_SCAN_3]) + info->button0 = 1; + if (KB_KeyDown[BUTTON1_SCAN]) + info->button1 = 1; + + if (CONTROL_UserInputCleared[1]) { + if (!info->button0) + CONTROL_UserInputCleared[1] = false; + else + info->button0 = false; + } + if (CONTROL_UserInputCleared[2]) { + if (!info->button1) + CONTROL_UserInputCleared[2] = false; + else + info->button1 = false; + } +} + +void CONTROL_ClearUserInput( UserInput *info ) +{ + switch (info->dir) { + case dir_North: + case dir_South: + case dir_East: + case dir_West: + CONTROL_UserInputCleared[0] = true; + CONTROL_UserInputDelay = GetTime() + ((ticrate * USERINPUTDELAY) / 1000); + switch (info->dir) { + case dir_North: KB_KeyDown[sc_UpArrow] = KB_KeyDown[sc_kpad_8] = 0; break; + case dir_South: KB_KeyDown[sc_DownArrow] = KB_KeyDown[sc_kpad_2] = 0; break; + case dir_East: KB_KeyDown[sc_LeftArrow] = KB_KeyDown[sc_kpad_4] = 0; break; + case dir_West: KB_KeyDown[sc_RightArrow] = KB_KeyDown[sc_kpad_6] = 0; break; + default: break; + } + break; + default: break; + } + if (info->button0) CONTROL_UserInputCleared[1] = true; + if (info->button1) CONTROL_UserInputCleared[2] = true; +} + +void CONTROL_ClearButton( int32 whichbutton ) +{ + if (CONTROL_CheckRange( whichbutton )) return; + BUTTONCLEAR( whichbutton ); + CONTROL_Flags[whichbutton].cleared = true; +} + +void CONTROL_GetInput( ControlInfo *info ) +{ + int32 i, periphs[CONTROL_NUM_FLAGS]; + + CONTROL_PollDevices( info ); + + memset(periphs, 0, sizeof(periphs)); + CONTROL_ButtonFunctionState(periphs); + CONTROL_AxisFunctionState(periphs); + + CONTROL_ButtonHeldState1 = CONTROL_ButtonState1; + CONTROL_ButtonHeldState2 = CONTROL_ButtonState2; + CONTROL_ButtonState1 = CONTROL_ButtonState2 = 0; + + for (i=0; i0)); + CONTROL_JoyPresent = ((inputdevices & 3) == 3); + CONTROL_JoystickEnabled = CONTROL_JoyPresent; + break; + } + + if (CONTROL_MousePresent) + initprintf("CONTROL_Startup: Mouse Present\n"); + if (CONTROL_JoyPresent) + initprintf("CONTROL_Startup: Joystick Present\n"); + + CONTROL_ButtonState1 = 0; + CONTROL_ButtonState2 = 0; + CONTROL_ButtonHeldState1 = 0; + CONTROL_ButtonHeldState2 = 0; + + memset(CONTROL_UserInputCleared, 0, sizeof(CONTROL_UserInputCleared)); + + for (i=0; i31) ? \ + ((CONTROL_ButtonState2>>( (x) - 32) ) & 1) :\ + ((CONTROL_ButtonState1>> (x) ) & 1) \ + ) +#define BUTTONHELD(x) \ + ( \ + ((x)>31) ? \ + ((CONTROL_ButtonHeldState2>>((x)-32)) & 1) :\ + ((CONTROL_ButtonHeldState1>>(x)) & 1)\ + ) +#define BUTTONJUSTPRESSED(x) \ + ( BUTTON( x ) && !BUTTONHELD( x ) ) +#define BUTTONRELEASED(x) \ + ( !BUTTON( x ) && BUTTONHELD( x ) ) +#define BUTTONSTATECHANGED(x) \ + ( BUTTON( x ) != BUTTONHELD( x ) ) + + +//*************************************************************************** +// +// TYPEDEFS +// +//*************************************************************************** +typedef enum + { + axis_up, + axis_down, + axis_left, + axis_right + } axisdirection; + +typedef enum + { + analog_turning=0, + analog_strafing=1, + analog_lookingupanddown=2, + analog_elevation=3, + analog_rolling=4, + analog_moving=5, + analog_maxtype + } analogcontrol; + +typedef enum + { + dir_North, + dir_NorthEast, + dir_East, + dir_SouthEast, + dir_South, + dir_SouthWest, + dir_West, + dir_NorthWest, + dir_None + } direction; + +typedef struct + { + boolean button0; + boolean button1; + direction dir; + } UserInput; + +typedef struct + { + fixed dx; + fixed dy; + fixed dz; + fixed dyaw; + fixed dpitch; + fixed droll; + } ControlInfo; + +typedef enum + { + controltype_keyboard, + controltype_keyboardandmouse, + controltype_keyboardandjoystick + } controltype; + +typedef enum + { + controldevice_keyboard, + controldevice_mouse, + controldevice_joystick + } controldevice; + + +//*************************************************************************** +// +// GLOBALS +// +//*************************************************************************** + +extern boolean CONTROL_MousePresent; +extern boolean CONTROL_JoyPresent; +extern boolean CONTROL_MouseEnabled; +extern boolean CONTROL_JoystickEnabled; +extern uint32 CONTROL_ButtonState1; +extern uint32 CONTROL_ButtonHeldState1; +extern uint32 CONTROL_ButtonState2; +extern uint32 CONTROL_ButtonHeldState2; + + +//*************************************************************************** +// +// PROTOTYPES +// +//*************************************************************************** + +void CONTROL_MapKey( int32 which, kb_scancode key1, kb_scancode key2 ); +void CONTROL_MapButton + ( + int32 whichfunction, + int32 whichbutton, + boolean doubleclicked, + controldevice device + ); +void CONTROL_DefineFlag( int32 which, boolean toggle ); +boolean CONTROL_FlagActive( int32 which ); +void CONTROL_ClearAssignments( void ); +void CONTROL_GetUserInput( UserInput *info ); +void CONTROL_GetInput( ControlInfo *info ); +void CONTROL_ClearButton( int32 whichbutton ); +void CONTROL_ClearUserInput( UserInput *info ); +void CONTROL_WaitRelease( void ); +void CONTROL_Ack( void ); +void CONTROL_CenterJoystick + ( + void ( *CenterCenter )( void ), + void ( *UpperLeft )( void ), + void ( *LowerRight )( void ), + void ( *CenterThrottle )( void ), + void ( *CenterRudder )( void ) + ); +int32 CONTROL_GetMouseSensitivity( void ); +void CONTROL_SetMouseSensitivity( int32 newsensitivity ); +boolean CONTROL_Startup + ( + controltype which, + int32 ( *TimeFunction )( void ), + int32 ticspersecond + ); +void CONTROL_Shutdown( void ); + +void CONTROL_SetDoubleClickDelay(int32 delay); +int32 CONTROL_GetDoubleClickDelay(void); + +void CONTROL_MapAnalogAxis + ( + int32 whichaxis, + int32 whichanalog, + controldevice device + ); + +void CONTROL_MapDigitalAxis + ( + int32 whichaxis, + int32 whichfunction, + int32 direction, + controldevice device + ); +void CONTROL_SetAnalogAxisScale + ( + int32 whichaxis, + int32 axisscale, + controldevice device + ); + +void CONTROL_PrintKeyMap(void); +void CONTROL_PrintControlFlag(int32 which); +void CONTROL_PrintAxes( void ); + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/develop.h b/polymer/eduke32/source/jmact/develop.h new file mode 100644 index 000000000..74b962674 --- /dev/null +++ b/polymer/eduke32/source/jmact/develop.h @@ -0,0 +1,66 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef _develop_public +#define _develop_public +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVELOPMENT 0 +#define SHAREWARE 0 +#define LOCATIONINFO 1 +#define SOFTWAREERROR 1 +#define MEMORYCORRUPTIONTEST 1 +#define PRECACHETEST 0 +#define DATACORRUPTIONTEST 0 +#define RANDOMNUMBERTEST 0 + + +#if ( LOCATIONINFO == 1 ) + +#define funcstart() \ + { \ + SoftError( "funcstart : module '%s' at line %d.\n", __FILE__, __LINE__ );\ + } + +#define funcend() \ + { \ + SoftError( " funcend : module '%s' at line %d.\n", __FILE__, __LINE__ );\ + } + +#else + +#define funcstart() +#define funcend() + +#endif + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/file_lib.c b/polymer/eduke32/source/jmact/file_lib.c new file mode 100644 index 000000000..64a9ab85a --- /dev/null +++ b/polymer/eduke32/source/jmact/file_lib.c @@ -0,0 +1,136 @@ +/* + * file_lib.c + * File functions to emulate MACT + * + * by Jonathon Fowler + * + * Since we weren't given the source for MACT386.LIB so I've had to do some + * creative interpolation here. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#include "types.h" +#include "file_lib.h" +#include "util_lib.h" +#include "compat.h" +#include "cache1d.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#ifndef O_TEXT +#define O_TEXT 0 +#endif +#ifndef F_OK +#define F_OK 0 +#endif + +#define MaxFiles 20 +static char *FileNames[MaxFiles]; + +int32 SafeOpen(const char *filename, int32 mode, int32 sharemode) +{ + int32 h; + + h = openfrompath(filename, mode, sharemode); + if (h < 0) Error("Error opening %s: %s", filename, strerror(errno)); + + if (h < MaxFiles) { + if (FileNames[h]) SafeFree(FileNames[h]); + FileNames[h] = (char*)SafeMalloc(strlen(filename)+1); + if (FileNames[h]) strcpy(FileNames[h], filename); + } + + return h; +} + +int32 SafeOpenRead(const char *filename, int32 filetype) +{ + int32 h; + + switch (filetype) { + case filetype_binary: + return SafeOpen(filename, O_RDONLY|O_BINARY, S_IREAD); + case filetype_text: + return SafeOpen(filename, O_RDONLY|O_TEXT, S_IREAD); + default: + Error("SafeOpenRead: Illegal filetype specified"); + return -1; + } +} + +void SafeClose ( int32 handle ) +{ + int r; + + if (handle < 0) return; + if (close(handle) < 0) { + if (handle < MaxFiles) + Error("Unable to close file %s", FileNames[handle]); + else + Error("Unable to close file"); + } + + if (handle < MaxFiles && FileNames[handle]) { + SafeFree(FileNames[handle]); + FileNames[handle] = NULL; + } +} + +boolean SafeFileExists(const char *filename) +{ + if (!access(filename, F_OK)) return true; + return false; +} + +int32 SafeFileLength ( int32 handle ) +{ + if (handle < 0) return -1; + return Bfilelength(handle); +} + +void SafeRead(int32 handle, void *buffer, int32 count) +{ + int32 b; + + b = read(handle, buffer, count); + if (b != count) { + close(handle); + if (handle < MaxFiles) + Error("File read failure %s reading %d bytes from file %s.", + strerror(errno), count, FileNames[handle]); + else + Error("File read failure %s reading %d bytes.", + strerror(errno), count); + } +} + + diff --git a/polymer/eduke32/source/jmact/file_lib.h b/polymer/eduke32/source/jmact/file_lib.h new file mode 100644 index 000000000..f5a2ee04d --- /dev/null +++ b/polymer/eduke32/source/jmact/file_lib.h @@ -0,0 +1,260 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + +#ifndef _file_lib_public +#define _file_lib_public +#ifdef __cplusplus +extern "C" { +#endif + +enum + { + filetype_binary, + filetype_text + }; + +enum + { + access_read, + access_write, + access_append + }; + +//========================================================================== +// +// SafeOpenWrite - Opens a file for writing, returns handle +// +//========================================================================== +int32 SafeOpenWrite ( const char * filename, int32 filetype ); + +//========================================================================== +// +// SafeOpenRead - Opens a file for reading, returns handle +// +//========================================================================== +int32 SafeOpenRead ( const char * filename, int32 filetype ); + +//========================================================================== +// +// SafeOpenAppend - Opens a file for appending, returns handle +// +//========================================================================== +int32 SafeOpenAppend ( const char * filename, int32 filetype ); + +//========================================================================== +// +// SafeClose - Close a file denoted by the file handle +// +//========================================================================== +void SafeClose ( int32 handle ); + +//========================================================================== +// +// SafeFileExists - Checks for existence of file +// +//========================================================================== +boolean SafeFileExists ( const char * filename ); + +//========================================================================== +// +// SafeFileLength - Get length of a file pointed to by handle +// +//========================================================================== +int32 SafeFileLength ( int32 handle ); + +//========================================================================== +// +// SafeRead - reads from a handle +// +// handle - handle of file to read from +// +// buffer - pointer of buffer to read into +// +// count - number of bytes to read +// +//========================================================================== +void SafeRead (int32 handle, void *buffer, int32 count); + +//========================================================================== +// +// SafeWrite - writes to a handle +// +// handle - handle of file to write to +// +// buffer - pointer of buffer to write from +// +// count - number of bytes to write +// +//========================================================================== +void SafeWrite (int32 handle, void *buffer, int32 count); + +//========================================================================== +// +// LoadFile - Load a file +// +// filename - name of file +// +// bufferptr - pointer to pointer of buffer to read into +// +// returns number of bytes read +// +//========================================================================== +int32 LoadFile ( const char * filename, void ** bufferptr ); + +//========================================================================== +// +// SaveFile - Save a file +// +// filename - name of file +// +// bufferptr - pointer to buffer to write from +// +// count - number of bytes to write +// +//========================================================================== +void SaveFile ( const char * filename, void * bufferptr, int32 count ); + +//========================================================================== +// +// GetPathFromEnvironment - Add a pathname described in an environment +// variable to a standard filename. +// +// fullname - final string containing entire path +// +// envname - string naming enivronment variable +// +// filename - standard filename +// +//========================================================================== +void GetPathFromEnvironment( char *fullname, const char *envname, const char *filename ); + +//========================================================================== +// +// DefaultExtension - Add a default extension to a path +// +// path - a path +// +// extension - default extension should include '.' +// +//========================================================================== +void DefaultExtension (char *path, const char *extension); + +//========================================================================== +// +// DefaultPath - Add the default path to a filename if it doesn't have one +// +// path - filename +// +// extension - default path +// +//========================================================================== +void DefaultPath (char *path, const char *basepath); + +//========================================================================== +// +// ExtractFileBase - Extract the base filename from a path +// +// path - the path +// +// dest - where the file base name will be placed +// +//========================================================================== +void ExtractFileBase (char *path, char *dest); + +//========================================================================== +// +// GetExtension - Extract the extension from a name +// returns true if an extension is found +// returns false otherwise +// +//========================================================================== +boolean GetExtension( char *filename, char *extension ); + +//========================================================================== +// +// SetExtension - Sets the extension from a name. Assumes that enough +// space is left at the end of the string to hold an extension. +// +//========================================================================== +void SetExtension( char *filename, const char *extension ); + +#ifdef __MSDOS__ +//****************************************************************************** +// +// GetPath +// +// Purpose +// To parse the directory entered by the user to make the directory. +// +// Parms +// Path - the path to be parsed. +// +// Returns +// Pointer to next path +// +//****************************************************************************** +char * GetPath (char * path, char *dir); + +//****************************************************************************** +// +// ChangeDirectory () +// +// Purpose +// To change to a directory. Checks for drive changes. +// +// Parms +// path - The path to change to. +// +// Returns +// TRUE - If successful. +// FALSE - If unsuccessful. +// +//****************************************************************************** +boolean ChangeDirectory (char * path); + +//****************************************************************************** +// +// ChangeDrive () +// +// Purpose +// To change drives. +// +// Parms +// drive - The drive to change to. +// +// Returns +// TRUE - If drive change successful. +// FALSE - If drive change unsuccessful. +// +//****************************************************************************** +boolean ChangeDrive (char *drive); + +#endif + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/keyboard.c b/polymer/eduke32/source/jmact/keyboard.c new file mode 100644 index 000000000..8bf48e764 --- /dev/null +++ b/polymer/eduke32/source/jmact/keyboard.c @@ -0,0 +1,289 @@ +/* + * keyboard.c + * MACT library -to- JonoF's Build Port Keyboard Glue + * + * by Jonathon Fowler + * + * Since we don't have the source to the MACT library I've had to + * concoct some magic to glue its idea of controllers into that of + * my Build port. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "compat.h" +#include "types.h" +#include "keyboard.h" +#include "control.h" + + +kb_scancode KB_LastScan; + +static boolean numpad = 0; + +// translation table for taking key names to scancodes and back again +static struct { + char *key; + kb_scancode sc; +} sctokeylut[] = { + { "Escape", 0x1 }, + { "1", 0x2 }, + { "2", 0x3 }, + { "3", 0x4 }, + { "4", 0x5 }, + { "5", 0x6 }, + { "6", 0x7 }, + { "7", 0x8 }, + { "8", 0x9 }, + { "9", 0xa }, + { "0", 0xb }, + { "-", 0xc }, + { "=", 0xd }, + { "BakSpc", 0xe }, + { "Tab", 0xf }, + { "Q", 0x10 }, + { "W", 0x11 }, + { "E", 0x12 }, + { "R", 0x13 }, + { "T", 0x14 }, + { "Y", 0x15 }, + { "U", 0x16 }, + { "I", 0x17 }, + { "O", 0x18 }, + { "P", 0x19 }, + { "[", 0x1a }, + { "]", 0x1b }, + { "Enter", 0x1c }, + { "LCtrl", 0x1d }, + { "A", 0x1e }, + { "S", 0x1f }, + { "D", 0x20 }, + { "F", 0x21 }, + { "G", 0x22 }, + { "H", 0x23 }, + { "J", 0x24 }, + { "K", 0x25 }, + { "L", 0x26 }, + { ";", 0x27 }, + { "'", 0x28 }, + { "`", 0x29 }, + { "LShift", 0x2a }, + { "\\", 0x2b }, + { "Z", 0x2c }, + { "X", 0x2d }, + { "C", 0x2e }, + { "V", 0x2f }, + { "B", 0x30 }, + { "N", 0x31 }, + { "M", 0x32 }, + { ",", 0x33 }, + { ".", 0x34 }, + { "/", 0x35 }, + { "RShift", 0x36 }, + { "Kpad*", 0x37 }, + { "LAlt", 0x38 }, + { "Space", 0x39 }, + { "CapLck", 0x3a }, + { "F1", 0x3b }, + { "F2", 0x3c }, + { "F3", 0x3d }, + { "F4", 0x3e }, + { "F5", 0x3f }, + { "F6", 0x40 }, + { "F7", 0x41 }, + { "F8", 0x42 }, + { "F9", 0x43 }, + { "F10", 0x44 }, + { "NumLck", 0x45 }, + { "ScrLck", 0x46 }, + { "Kpad7", 0x47 }, + { "Kpad8", 0x48 }, + { "Kpad9", 0x49 }, + { "Kpad-", 0x4a }, + { "Kpad4", 0x4b }, + { "Kpad5", 0x4c }, + { "Kpad6", 0x4d }, + { "Kpad+", 0x4e }, + { "Kpad1", 0x4f }, + { "Kpad2", 0x50 }, + { "Kpad3", 0x51 }, + { "Kpad0", 0x52 }, + { "Kpad.", 0x53 }, + { "F11", 0x57 }, + { "F12", 0x58 }, + { "KpdEnt", 0x9c }, + { "RCtrl", 0x9d }, + { "Kpad/", 0xb5 }, + { "RAlt", 0xb8 }, + { "PrtScn", 0xb7 }, + { "Pause", 0xc5 }, + { "Home", 0xc7 }, + { "Up", 0xc8 }, + { "PgUp", 0xc9 }, + { "Left", 0xcb }, + { "Right", 0xcd }, + { "End", 0xcf }, + { "Down", 0xd0 }, + { "PgDn", 0xd1 }, + { "Insert", 0xd2 }, + { "Delete", 0xd3 }, +}; + +// translation table for turning scancode into ascii characters +/* +static char sctoasc[2][256] = { + { +// 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 9, // 0x00 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, 0, 'a', 's', // 0x10 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'','`', 0, '\\','z', 'x', 'c', 'v', // 0x20 + 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, // 0x30 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, // 0x40 + 0, 0, 0, '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, // 0x90 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0 + 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xc0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xd0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0xf0 + }, + { +// 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, 9, // 0x00 + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13, 0, 'A', 'S', // 0x10 + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', // 0x20 + 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, // 0x30 + 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', // 0x40 + '2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, // 0x90 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0 + 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xc0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xd0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0xf0 + } +}; +*/ + +boolean KB_KeyWaiting( void ) +{ + return bkbhit(); +// return (keyfifoplc != keyfifoend); +} + +char KB_Getch( void ) +{ +/* + unsigned char ch; + char shifted; + if (keyfifoplc == keyfifoend) return 0; + ch = keyfifo[keyfifoplc]; + keyfifoplc = ((keyfifoplc+2)&(KEYFIFOSIZ-1)); + + shifted = ((keystatus[0x2a]!=0)||(keystatus[0x36]!=0)); + if (ch >= 0x47 && ch <= 0x52) shifted = numpad; + + return sctoasc[shifted][ch]; +*/ + return (char)bgetchar(); +} + +void KB_Addch( char ch ) +{ +} + +void KB_FlushKeyboardQueue( void ) +{ + //keyfifoplc = keyfifoend = 0; + bflushchars(); +} + +void KB_ClearKeysDown( void ) +{ + int i; + KB_LastScan = 0; + memset(keystatus, 0, sizeof(keystatus)); + //keyfifoplc = keyfifoend = 0; + //bflushchars(); +} + +char *KB_ScanCodeToString( kb_scancode scancode ) +{ + unsigned s; + + for (s=0; s < (sizeof(sctokeylut)/sizeof(sctokeylut[0])); s++) + if (sctokeylut[s].sc == scancode) return sctokeylut[s].key; + + return ""; +} + +kb_scancode KB_StringToScanCode( char * string ) +{ + unsigned s; + + for (s=0; s < (sizeof(sctokeylut)/sizeof(sctokeylut[0])); s++) + if (!Bstrcasecmp(sctokeylut[s].key, string)) return sctokeylut[s].sc; + + return 0; +} + +void KB_TurnKeypadOn( void ) +{ + numpad = 1; +} + +void KB_TurnKeypadOff( void ) +{ + numpad = 0; +} + +boolean KB_KeypadActive( void ) +{ + return numpad; +} + +static void KB_KeyEvent( long scancode, long keypressed ) +{ + if (keypressed) KB_LastScan = scancode; +} + +void KB_Startup( void ) +{ + numpad = 0; + setkeypresscallback(KB_KeyEvent); +} + +void KB_Shutdown( void ) +{ + setkeypresscallback((void(*)(long,long))NULL); +} + diff --git a/polymer/eduke32/source/jmact/keyboard.h b/polymer/eduke32/source/jmact/keyboard.h new file mode 100644 index 000000000..059cf9092 --- /dev/null +++ b/polymer/eduke32/source/jmact/keyboard.h @@ -0,0 +1,230 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef _keyboard_public +#define _keyboard_public +#ifdef __cplusplus +extern "C" { +#endif + +#include "baselayer.h" // for the keyboard stuff + +/* +============================================================================= + + DEFINES + +============================================================================= +*/ + +typedef uint8 kb_scancode; + +#define sc_None 0 +#define sc_Bad 0xff +#define sc_Comma 0x33 +#define sc_Period 0x34 +#define sc_Return 0x1c +#define sc_Enter sc_Return +#define sc_Escape 0x01 +#define sc_Space 0x39 +#define sc_BackSpace 0x0e +#define sc_Tab 0x0f +#define sc_LeftAlt 0x38 +#define sc_LeftControl 0x1d +#define sc_CapsLock 0x3a +#define sc_LeftShift 0x2a +#define sc_RightShift 0x36 +#define sc_F1 0x3b +#define sc_F2 0x3c +#define sc_F3 0x3d +#define sc_F4 0x3e +#define sc_F5 0x3f +#define sc_F6 0x40 +#define sc_F7 0x41 +#define sc_F8 0x42 +#define sc_F9 0x43 +#define sc_F10 0x44 +#define sc_F11 0x57 +#define sc_F12 0x58 +#define sc_Kpad_Star 0x37 +#define sc_Pause 0x59 +#define sc_ScrollLock 0x46 +#define sc_NumLock 0x45 +#define sc_Slash 0x35 +#define sc_SemiColon 0x27 +#define sc_Quote 0x28 +#define sc_Tilde 0x29 +#define sc_BackSlash 0x2b + +#define sc_OpenBracket 0x1a +#define sc_CloseBracket 0x1b + +#define sc_1 0x02 +#define sc_2 0x03 +#define sc_3 0x04 +#define sc_4 0x05 +#define sc_5 0x06 +#define sc_6 0x07 +#define sc_7 0x08 +#define sc_8 0x09 +#define sc_9 0x0a +#define sc_0 0x0b +#define sc_Minus 0x0c +#define sc_Equals 0x0d +#define sc_Plus 0x0d + +#define sc_kpad_1 0x4f +#define sc_kpad_2 0x50 +#define sc_kpad_3 0x51 +#define sc_kpad_4 0x4b +#define sc_kpad_5 0x4c +#define sc_kpad_6 0x4d +#define sc_kpad_7 0x47 +#define sc_kpad_8 0x48 +#define sc_kpad_9 0x49 +#define sc_kpad_0 0x52 +#define sc_kpad_Minus 0x4a +#define sc_kpad_Plus 0x4e +#define sc_kpad_Period 0x53 + +#define sc_A 0x1e +#define sc_B 0x30 +#define sc_C 0x2e +#define sc_D 0x20 +#define sc_E 0x12 +#define sc_F 0x21 +#define sc_G 0x22 +#define sc_H 0x23 +#define sc_I 0x17 +#define sc_J 0x24 +#define sc_K 0x25 +#define sc_L 0x26 +#define sc_M 0x32 +#define sc_N 0x31 +#define sc_O 0x18 +#define sc_P 0x19 +#define sc_Q 0x10 +#define sc_R 0x13 +#define sc_S 0x1f +#define sc_T 0x14 +#define sc_U 0x16 +#define sc_V 0x2f +#define sc_W 0x11 +#define sc_X 0x2d +#define sc_Y 0x15 +#define sc_Z 0x2c + +// Extended scan codes + +#define sc_UpArrow 0xc8 //0x5a +#define sc_DownArrow 0xd0 //0x6a +#define sc_LeftArrow 0xcb //0x6b +#define sc_RightArrow 0xcd //0x6c +#define sc_Insert 0xd2 //0x5e +#define sc_Delete 0xd3 //0x5f +#define sc_Home 0xc7 //0x61 +#define sc_End 0xcf //0x62 +#define sc_PgUp 0xc9 //0x63 +#define sc_PgDn 0xd1 //0x64 +#define sc_RightAlt 0xb8 //0x65 +#define sc_RightControl 0x9d //0x66 +#define sc_kpad_Slash 0xb5 //0x67 +#define sc_kpad_Enter 0x9c //0x68 +#define sc_PrintScreen 0xb7 //0x69 +#define sc_LastScanCode 0x6e + +// Ascii scan codes + +#define asc_Enter 13 +#define asc_Escape 27 +#define asc_BackSpace 8 +#define asc_Tab 9 +#define asc_Space 32 + +#define MAXKEYBOARDSCAN 128 + + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +//extern byte KB_KeyDown[ MAXKEYBOARDSCAN ]; // Keyboard state array +#define KB_KeyDown keystatus +extern kb_scancode KB_LastScan; + + +/* +============================================================================= + + MACROS + +============================================================================= +*/ + +#define KB_GetLastScanCode() ( KB_LastScan ) + +#define KB_SetLastScanCode( scancode ) { KB_LastScan = ( scancode ); } + +#define KB_ClearLastScanCode() { KB_SetLastScanCode( sc_None ); } + +#define KB_KeyPressed( scan ) ( keystatus[ ( scan ) ] != 0 ) + +#define KB_ClearKeyDown( scan ) { keystatus[ ( scan ) ] = FALSE; } + + +/* +============================================================================= + + FUNCTION PROTOTYPES + +============================================================================= +*/ + +boolean KB_KeyWaiting( void ); // Checks if a character is waiting in the keyboard queue +char KB_Getch( void ); // Gets the next keypress +void KB_Addch( char ch ); // Adds key to end of queue +void KB_FlushKeyboardQueue( void ); // Empties the keyboard queue of all waiting characters. +void KB_ClearKeysDown( void ); // Clears all keys down flags. +char * KB_ScanCodeToString( kb_scancode scancode ); // convert scancode into a string +kb_scancode KB_StringToScanCode( char * string ); // convert a string into a scancode +void KB_TurnKeypadOn( void ); // turn the keypad on +void KB_TurnKeypadOff( void ); // turn the keypad off +boolean KB_KeypadActive( void ); // check whether keypad is active +void KB_Startup( void ); +void KB_Shutdown( void ); + +#define KB_FlushKeyBoardQueue KB_FlushKeyboardQueue +#define KB_GetCh KB_Getch + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/mathutil.c b/polymer/eduke32/source/jmact/mathutil.c new file mode 100644 index 000000000..422051cce --- /dev/null +++ b/polymer/eduke32/source/jmact/mathutil.c @@ -0,0 +1,112 @@ +/* + * mathutil.c + * Mathematical utility functions to emulate MACT + * + * by Jonathon Fowler + * + * Since we weren't given the source for MACT386.LIB so I've had to do some + * creative interpolation here. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "types.h" + +#if 0 +// Ken's reverse-engineering job +int32 FindDistance2D(int32 x, int32 y) +{ + int32 i; + x = labs(x); + y = labs(y); + if (!x) return(y); + if (!y) return(x); + if (y < x) { i = x; x = y; y = i; } //swap x, y + x += (x>>1); + return ((x>>6)+(x>>2)+y-(y>>5)-(y>>7)); //handle 1 octant +} + +// My abomination +#define square(x) ((x)*(x)) +/* +int32 FindDistance2D(int32 dx, int32 dy) +{ +// return (int32)floor(sqrt((double)(sqr(dx)+sqr(dy)))); + return ksqrt(square(dx)+square(dy)); +} +*/ +int32 FindDistance3D(int32 dx, int32 dy, int32 dz) +{ +// return (int32)floor(sqrt((double)(sqr(dx)+sqr(dy)+sqr(dz)))); + return ksqrt(square(dx)+square(dy)+square(dz)); +} + +#else + +#include + +// This extracted from the Rise of the Triad source RT_UTIL.C :-| + +#define SWAP(a,b) \ + { \ + a=(a)^(b); \ + b=(a)^(b); \ + a=(a)^(b); \ + } + +int32 FindDistance2D(int32 x, int32 y) +{ + int32 t; + + x= abs(x); /* absolute values */ + y= abs(y); + + if (x>1); + + return (x - (x>>5) - (x>>7) + (t>>2) + (t>>6)); +} + + +int32 FindDistance3D(int32 x, int32 y, int32 z) + { + int32 t; + + x= abs(x); /* absolute values */ + y= abs(y); + z= abs(z); + + if (x>4) + (t>>2) + (t>>3)); + } +#endif diff --git a/polymer/eduke32/source/jmact/mathutil.h b/polymer/eduke32/source/jmact/mathutil.h new file mode 100644 index 000000000..c5856c98a --- /dev/null +++ b/polymer/eduke32/source/jmact/mathutil.h @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is NOT part of Duke Nukem 3D version 1.5 - Atomic Edition +However, it is either an older version of a file that is, or is +some test code written during the development of Duke Nukem 3D. +This file is provided purely for educational interest. + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + + +extern int32 FindDistance2D(int32 dx, int32 dy); +extern int32 FindDistance3D(int32 dx, int32 dy, int32 dz); +extern int32 FindDistance3D_HP(int32 dx, int32 dy, int32 dz); +extern int32 ArcTangentAppx(int32 dx, int32 dy); + diff --git a/polymer/eduke32/source/jmact/mouse.c b/polymer/eduke32/source/jmact/mouse.c new file mode 100644 index 000000000..3be081550 --- /dev/null +++ b/polymer/eduke32/source/jmact/mouse.c @@ -0,0 +1,88 @@ +/* + * mouse.c + * MACT library -to- JonoF's Build Port Mouse Glue + * + * by Jonathon Fowler + * + * Since we don't have the source to the MACT library I've had to + * concoct some magic to glue its idea of controllers into that of + * my Build port. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "types.h" +#include "mouse.h" +#include "baselayer.h" + + +boolean MOUSE_Init( void ) +{ + initmouse(); + return ((inputdevices & 2) == 2); +} + + +void MOUSE_Shutdown( void ) +{ + uninitmouse(); +} + + +void MOUSE_ShowCursor( void ) +{ +} + + +void MOUSE_HideCursor( void ) +{ +} + + +int32 MOUSE_GetButtons( void ) +{ + int32 buttons; + readmousebstatus(&buttons); + return buttons; +} + + +int32 MOUSE_ClearButton( int32 b ) +{ + return (mouseb &= ~b); +} + + +void MOUSE_GetPosition( int32*x, int32*y ) +{ +} + + +void MOUSE_GetDelta( int32*x, int32*y ) +{ + readmousexy(x,y); +} + + + diff --git a/polymer/eduke32/source/jmact/mouse.h b/polymer/eduke32/source/jmact/mouse.h new file mode 100644 index 000000000..57e376db3 --- /dev/null +++ b/polymer/eduke32/source/jmact/mouse.h @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef __mouse_h +#define __mouse_h +#ifdef __cplusplus +extern "C" { +#endif + +#define LEFT_MOUSE 1 +#define RIGHT_MOUSE 2 +#define MIDDLE_MOUSE 4 +#define THUMB_MOUSE 8 +#define WHEELDOWN_MOUSE 16 +#define WHEELUP_MOUSE 32 +#define LEFT_MOUSE_PRESSED( button ) ( ( ( button ) & LEFT_MOUSE ) != 0 ) +#define RIGHT_MOUSE_PRESSED( button ) ( ( ( button ) & RIGHT_MOUSE ) != 0 ) +#define MIDDLE_MOUSE_PRESSED( button ) ( ( ( button ) & MIDDLE_MOUSE ) != 0 ) + +boolean MOUSE_Init( void ); +void MOUSE_Shutdown( void ); +void MOUSE_ShowCursor( void ); +void MOUSE_HideCursor( void ); +int32 MOUSE_GetButtons( void ); +int32 MOUSE_ClearButton( int32 b ); +void MOUSE_GetPosition( int32*x, int32*y ); +void MOUSE_GetDelta( int32*x, int32*y ); + +#ifdef __cplusplus +}; +#endif +#endif /* __mouse_h */ diff --git a/polymer/eduke32/source/jmact/scriplib.c b/polymer/eduke32/source/jmact/scriplib.c new file mode 100644 index 000000000..6ce59bf69 --- /dev/null +++ b/polymer/eduke32/source/jmact/scriplib.c @@ -0,0 +1,918 @@ +/* + * scriplib.c + * MACT library Script file parsing and writing + * + * by Jonathon Fowler + * + * Since we weren't given the source for MACT386.LIB so I've had to do some + * creative interpolation here. + * + * This all should be rewritten in a much much cleaner fashion. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "compat.h" +#include "types.h" +#include "scriplib.h" +#include "util_lib.h" +#include "file_lib.h" +#include "_scrplib.h" +#include +#include +#include + +#ifdef __WATCOMC__ +#include +#endif + + +static script_t *scriptfiles[MAXSCRIPTFILES]; + + +#define SC(s) scriptfiles[s] + + +int32 SCRIPT_New(void) +{ + int32 i; + + for (i=0; i= MAXSCRIPTFILES) return; + + if (!SC(scripthandle)) return; + + if (SCRIPT(scripthandle,script)) { + while (SCRIPT(scripthandle,script)->nextsection != SCRIPT(scripthandle,script)) { + s = SCRIPT(scripthandle,script)->nextsection; + SCRIPT_FreeSection(SCRIPT(scripthandle,script)); + SafeFree(SCRIPT(scripthandle,script)); + SCRIPT(scripthandle,script) = s; + } + + SafeFree(SCRIPT(scripthandle,script)); + } + + SafeFree(SC(scripthandle)); + SC(scripthandle) = 0; +} + +void SCRIPT_FreeSection(ScriptSectionType * section) +{ + ScriptEntryType *e; + + if (!section) return; + if (!section->entries) return; + + while (section->entries->nextentry != section->entries) { + e = section->entries->nextentry; + SafeFree(section->entries); + section->entries = e; + } + + SafeFree(section->entries); + free(section->name); +} + +#define AllocSection(s) \ + { \ + (s) = SafeMalloc(sizeof(ScriptSectionType)); \ + (s)->name = NULL; \ + (s)->entries = NULL; \ + (s)->lastline = NULL; \ + (s)->nextsection = (s); \ + (s)->prevsection = (s); \ + } +#define AllocEntry(e) \ + { \ + (e) = SafeMalloc(sizeof(ScriptEntryType)); \ + (e)->name = NULL; \ + (e)->value = NULL; \ + (e)->nextentry = (e); \ + (e)->preventry = (e); \ + } + +ScriptSectionType * SCRIPT_SectionExists( int32 scripthandle, char * sectionname ) +{ + ScriptSectionType *s, *ls=NULL; + + if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL; + if (!sectionname) return NULL; + if (!SC(scripthandle)) return NULL; + if (!SCRIPT(scripthandle,script)) return NULL; + + for (s = SCRIPT(scripthandle,script); ls != s; ls=s,s=s->nextsection) + if (!Bstrcasecmp(s->name, sectionname)) return s; + + return NULL; +} + +ScriptSectionType * SCRIPT_AddSection( int32 scripthandle, char * sectionname ) +{ + ScriptSectionType *s,*s2; + + if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL; + if (!sectionname) return NULL; + if (!SC(scripthandle)) return NULL; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + if (s) return s; + + AllocSection(s); + s->name = strdup(sectionname); + if (!SCRIPT(scripthandle,script)) { + SCRIPT(scripthandle,script) = s; + } else { + s2 = SCRIPT(scripthandle,script); + while (s2->nextsection != s2) s2=s2->nextsection; + s2->nextsection = s; + s->prevsection = s2; + } + + return s; +} + +ScriptEntryType * SCRIPT_EntryExists ( ScriptSectionType * section, char * entryname ) +{ + ScriptEntryType *e,*le=NULL; + + if (!section) return NULL; + if (!entryname) return NULL; + if (!section->entries) return NULL; + + for (e = section->entries; le != e; le=e,e=e->nextentry) + if (!Bstrcasecmp(e->name, entryname)) return e; + + return NULL; +} + +void SCRIPT_AddEntry ( int32 scripthandle, char * sectionname, char * entryname, char * entryvalue ) +{ + ScriptSectionType *s; + ScriptEntryType *e,*e2; + + if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return; + if (!sectionname || !entryname || !entryvalue) return; + if (!SC(scripthandle)) return; + +// s = SCRIPT_SectionExists(scripthandle, sectionname); +// if (!s) { + s = SCRIPT_AddSection(scripthandle, sectionname); + if (!s) return; +// } + + e = SCRIPT_EntryExists(s, entryname); + if (!e) { + AllocEntry(e); + e->name = strdup(entryname); + if (!s->entries) { + s->entries = e; + } else { + e2 = s->entries; + while (e2->nextentry != e2) e2=e2->nextentry; + e2->nextentry = e; + e->preventry = e2; + } + } + + if (e->value) free(e->value); + e->value = strdup(entryvalue); +} + + +int32 SCRIPT_ParseBuffer(int32 scripthandle, char *data, int32 length) +{ + char *fence = data + length; + char *dp, *sp, ch=0, lastch=0; + char *currentsection = ""; + char *currententry = NULL; + char *currentvalue = NULL; + enum { + ParsingIdle, + ParsingSectionBegin, + ParsingSectionName, + ParsingEntry, + ParsingValueBegin, + ParsingValue + }; + enum { + ExpectingSection = 1, + ExpectingEntry = 2, + ExpectingAssignment = 4, + ExpectingValue = 8, + ExpectingComment = 16 + }; + int state; + int expect; + int linenum=1; + int rv = 0; +#define SETRV(v) if (v>rv||rv==0) rv=v + + if (!data) return 1; + if (length < 0) return 1; + + dp = sp = data; + state = ParsingIdle; + expect = ExpectingSection | ExpectingEntry; + +#define EATLINE(p) while (length > 0 && *p != '\n' && *p != '\r') { p++; length--; } +#define LETTER() { lastch = ch; ch = *(sp++); length--; } + + while (length > 0) { + switch (state) { + case ParsingIdle: + LETTER(); + switch (ch) { + // whitespace + case ' ': + case '\t': continue; + case '\n': if (lastch == '\r') continue; linenum++; continue; + case '\r': linenum++; continue; + + case ';': + /*case '#':*/ + EATLINE(sp); + continue; + + case '[': if (!(expect & ExpectingSection)) { + // Unexpected section start + printf("Unexpected start of section on line %d.\n", linenum); + SETRV(-1); + EATLINE(sp); + continue; + } else { + state = ParsingSectionBegin; + continue; + } + + default: if (isalpha(ch)) { + if (!(expect & ExpectingEntry)) { + // Unexpected name start + printf("Unexpected entry label on line %d.\n", linenum); + SETRV(-1); + EATLINE(sp); + continue; + } else { + currententry = dp = sp-1; + state = ParsingEntry; + continue; + } + } else { + // Unexpected character + printf("Illegal character (ASCII %d) on line %d.\n", ch, linenum); + SETRV(-1); + EATLINE(sp); + continue; + } + } + + case ParsingSectionBegin: + currentsection = dp = sp; + state = ParsingSectionName; + case ParsingSectionName: + LETTER(); + switch (ch) { + case '\n': + case '\r': // Unexpected newline + printf("Unexpected newline on line %d.\n", linenum); + SETRV(-1); + state = ParsingIdle; + linenum++; + continue; + + case ']': + *(dp) = 0; // Add new section + expect = ExpectingSection | ExpectingEntry; + state = ParsingIdle; + EATLINE(sp); + continue; + + default: + dp++; + continue; + } + + case ParsingEntry: + LETTER(); + switch (ch) { + case ';': + /*case '#':*/ + // unexpected comment + EATLINE(sp); + printf("Unexpected comment on line %d.\n", linenum); + SETRV(-1); + case '\n': + case '\r': + // Unexpected newline + printf("Unexpected newline on line %d.\n", linenum); + SETRV(-1); + expect = ExpectingSection | ExpectingEntry; + state = ParsingIdle; + linenum++; + continue; + + case '=': + // Entry name finished, now for the value + while (*dp == ' ' || *dp == '\t') dp--; + *(++dp) = 0; + state = ParsingValueBegin; + continue; + + default: + dp++; + continue; + } + + case ParsingValueBegin: + currentvalue = dp = sp; + state = ParsingValue; + case ParsingValue: + LETTER(); + switch (ch) { + case '\n': + case '\r': + // value complete, add it using parsed name + while (*dp == ' ' && *dp == '\t') dp--; + *(dp) = 0; + while (*currentvalue == ' ' || *currentvalue == '\t') currentvalue++; + state = ParsingIdle; + linenum++; + + SCRIPT_AddSection(scripthandle,currentsection); + SCRIPT_AddEntry(scripthandle,currentsection,currententry,currentvalue); + continue; + + default: + dp++; + continue; + } + + default: length=0; + continue; + } + } + + if (sp > fence) printf("Stepped outside the fence!\n"); + + return rv; +} + + +//--- + +int32 SCRIPT_Init( char * name ) +{ + int32 h = SCRIPT_New(); + + if (h >= 0) strncpy(SCRIPT(h,scriptfilename), name, 127); + + return h; +} + +void SCRIPT_Free( int32 scripthandle ) +{ + SCRIPT_Delete(scripthandle); +} + +int32 SCRIPT_Parse ( char *data, int32 length, char * name ) +{ + return 0; +} + +int32 SCRIPT_Load ( char * filename ) +{ + int32 s,h,l; + char *b; + + h = SafeOpenRead(filename, filetype_binary); + l = SafeFileLength(h)+1; + b = (char *)SafeMalloc(l); + SafeRead(h,b,l-1); + b[l-1] = '\n'; // JBF 20040111: evil nasty hack to trick my evil nasty parser + SafeClose(h); + + s = SCRIPT_Init(filename); + if (s<0) { + SafeFree(b); + return -1; + } + + SCRIPT_ParseBuffer(s,b,l); + + SafeFree(b); + + return s; +} + +void SCRIPT_Save (int32 scripthandle, char * filename) +{ + char *section, *entry, *value; + int sec, ent, numsect, nument; + FILE *fp; + + + if (!filename) return; + if (!SC(scripthandle)) return; + + fp = fopen(filename, "w"); + if (!fp) return; + + numsect = SCRIPT_NumberSections(scripthandle); + for (sec=0; sec0) fprintf(fp, "\n"); + if (section[0] != 0) + fprintf(fp, "[%s]\n", section); + + nument = SCRIPT_NumberEntries(scripthandle,section); + for (ent=0; entnextsection) c++; + + return c; +} + +char * SCRIPT_Section( int32 scripthandle, int32 which ) +{ + ScriptSectionType *s,*ls=NULL; + + if (!SC(scripthandle)) return ""; + if (!SCRIPT(scripthandle,script)) return ""; + + for (s = SCRIPT(scripthandle,script); which>0 && ls != s; ls=s, s=s->nextsection, which--) ; + + return s->name; +} + +int32 SCRIPT_NumberEntries( int32 scripthandle, char * sectionname ) +{ + ScriptSectionType *s; + ScriptEntryType *e,*le=NULL; + int32 c=0; + + if (!SC(scripthandle)) return 0; + if (!SCRIPT(scripthandle,script)) return 0; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + if (!s) return 0; + + for (e = s->entries; le != e; le=e,e=e->nextentry) c++; + return c; +} + +char * SCRIPT_Entry( int32 scripthandle, char * sectionname, int32 which ) +{ + ScriptSectionType *s; + ScriptEntryType *e,*le=NULL; + + if (!SC(scripthandle)) return 0; + if (!SCRIPT(scripthandle,script)) return 0; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + if (!s) return ""; + + for (e = s->entries; which>0 && le != e; le=e, e=e->nextentry, which--) ; + return e->name; +} + +char * SCRIPT_GetRaw(int32 scripthandle, char * sectionname, char * entryname) +{ + ScriptSectionType *s; + ScriptEntryType *e; + + if (!SC(scripthandle)) return 0; + if (!SCRIPT(scripthandle,script)) return 0; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + if (!e) return ""; + return e->value; +} + +boolean SCRIPT_GetString( int32 scripthandle, char * sectionname, char * entryname, char * dest ) +{ + ScriptSectionType *s; + ScriptEntryType *e; + char *p, ch; + int c; + + if (!SC(scripthandle)) return 1; + if (!SCRIPT(scripthandle,script)) return 1; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + //dest[0] = 0; + if (!e) return 1; + + p = e->value; + c = 0; + + if (*p == '\"') { + // quoted string + p++; + while ((ch = *(p++))) { + switch (ch) { + case '\\': + ch = *(p++); + switch (ch) { + case 0: return 0; + case 'n': dest[c++] = '\n'; break; + case 'r': dest[c++] = '\r'; break; + case 't': dest[c++] = '\t'; break; + default: dest[c++] = ch; break; + } + break; + case '\"': + dest[c] = 0; + return 0; + default: + dest[c++] = ch; + break; + } + } + } else { + while ((ch = *(p++))) { + if (ch == ' ' || ch == '\t') { dest[c] = 0; break; } + else dest[c++] = ch; + } + } + + return 0; +} + +boolean SCRIPT_GetDoubleString( int32 scripthandle, char * sectionname, char * entryname, char * dest1, char * dest2 ) +{ + ScriptSectionType *s; + ScriptEntryType *e; + char *p, ch; + int c,d=0; + + if (!SC(scripthandle)) return 1; + if (!SCRIPT(scripthandle,script)) return 1; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + //dest1[0] = 0; + //dest2[0] = 0; + if (!e) return 1; + + p = e->value; + c = 0; + + if (*p == '\"') { + // quoted string + p++; + while ((ch = *(p++))) { + switch (ch) { + case '\\': + ch = *(p++); + switch (ch) { + case 0: return 0; + case 'n': dest1[c++] = '\n'; break; + case 'r': dest1[c++] = '\r'; break; + case 't': dest1[c++] = '\t'; break; + default: dest1[c++] = ch; break; + } + break; + case '\"': + dest1[c] = 0; + goto breakme; + default: + dest1[c++] = ch; + break; + } + } + if (ch == 0) return 0; + } else { + while ((ch = *(p++))) { + if (ch == ' ' || ch == '\t') { dest1[c] = 0; break; } + else dest1[c++] = ch; + } + } + +breakme: + while (*p == ' ' || *p == '\t') p++; + if (*p == 0) return 0; + + c = 0; + + if (*p == '\"') { + // quoted string + p++; + while ((ch = *(p++))) { + switch (ch) { + case '\\': + ch = *(p++); + switch (ch) { + case 0: return 0; + case 'n': dest2[c++] = '\n'; break; + case 'r': dest2[c++] = '\r'; break; + case 't': dest2[c++] = '\t'; break; + default: dest2[c++] = ch; break; + } + break; + case '\"': + dest2[c] = 0; + return 0; + default: + dest2[c++] = ch; + break; + } + } + } else { + while ((ch = *(p++))) { + if (ch == ' ' || ch == '\t') { dest2[c] = 0; break; } + else dest2[c++] = ch; + } + } + + return 0; +} + +boolean SCRIPT_GetNumber( int32 scripthandle, char * sectionname, char * entryname, int32 * number ) +{ + ScriptSectionType *s; + ScriptEntryType *e; + char *p; + + if (!SC(scripthandle)) return 1; + if (!SCRIPT(scripthandle,script)) return 1; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + if (!e) return 1;// *number = 0; + else { + if (e->value[0] == '0' && e->value[1] == 'x') { + // hex + *number = strtol(e->value+2, &p, 16); + if (p == e->value || *p != 0 || *p != ' ' || *p != '\t') return 1; + } else { + // decimal + *number = strtol(e->value, &p, 10); + if (p == e->value || *p != 0 || *p != ' ' || *p != '\t') return 1; + } + } + + return 0; +} + +boolean SCRIPT_GetBoolean( int32 scripthandle, char * sectionname, char * entryname, boolean * boole ) +{ + ScriptSectionType *s; + ScriptEntryType *e; + + if (!SC(scripthandle)) return 1; + if (!SCRIPT(scripthandle,script)) return 1; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + if (!e) return 1;// *boole = 0; + else { + if (!Bstrncasecmp(e->value, "true", 4)) *boole = 1; + else if (!Bstrncasecmp(e->value, "false", 5)) *boole = 0; + else if (e->value[0] == '1' && (e->value[1] == ' ' || e->value[1] == '\t' || e->value[1] == 0)) *boole = 1; + else if (e->value[0] == '0' && (e->value[1] == ' ' || e->value[1] == '\t' || e->value[1] == 0)) *boole = 0; + } + + return 0; +} + +boolean SCRIPT_GetDouble( int32 scripthandle, char * sectionname, char * entryname, double * number ) +{ + ScriptSectionType *s; + ScriptEntryType *e; + + if (!SC(scripthandle)) return 1; + if (!SCRIPT(scripthandle,script)) return 1; + + s = SCRIPT_SectionExists(scripthandle, sectionname); + e = SCRIPT_EntryExists(s, entryname); + + if (!e) return 1;// *number = 0.0; + else { + } + + return 0; +} + +void SCRIPT_PutComment( int32 scripthandle, char * sectionname, char * comment ) +{ +} + +void SCRIPT_PutEOL( int32 scripthandle, char * sectionname ) +{ +} + +void SCRIPT_PutMultiComment + ( + int32 scripthandle, + char * sectionname, + char * comment, + ... + ) +{ +} + +void SCRIPT_PutSection( int32 scripthandle, char * sectionname ) +{ + SCRIPT_AddSection(scripthandle, sectionname); +} + +void SCRIPT_PutRaw + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * raw + ) +{ + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); +} + +void SCRIPT_PutString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * string + ) +{ + char *raw,*q,*p; + int len = 3; + if (!string) string = ""; + + for (q=string; *q; q++) { + if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2; + else if (*q >= ' ') len++; + } + p = raw = Bmalloc(len); + *(p++) = '"'; + for (q=string; *q; q++) { + if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; } + else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; } + else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; } + else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; } + else if (*q >= ' ') *(p++) = *q; + } + *(p++) = '"'; + *p=0; + + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); + Bfree(raw); +} + +void SCRIPT_PutDoubleString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * string1, + char * string2 + ) +{ + char *raw,*q,*p; + int len = 6; + if (!string1) string1 = ""; + if (!string2) string2 = ""; + + for (q=string1; *q; q++) { + if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2; + else if (*q >= ' ') len++; + } + for (q=string2; *q; q++) { + if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2; + else if (*q >= ' ') len++; + } + p = raw = Bmalloc(len); + *(p++) = '"'; + for (q=string1; *q; q++) { + if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; } + else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; } + else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; } + else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; } + else if (*q >= ' ') *(p++) = *q; + } + *(p++) = '"'; + *(p++) = ' '; + *(p++) = '"'; + for (q=string2; *q; q++) { + if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; } + else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; } + else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; } + else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; } + else if (*q >= ' ') *(p++) = *q; + } + *(p++) = '"'; + *p=0; + + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); + Bfree(raw); +} + +void SCRIPT_PutNumber + ( + int32 scripthandle, + char * sectionname, + char * entryname, + int32 number, + boolean hexadecimal, + boolean defaultvalue + ) +{ + char raw[64]; + + if (hexadecimal) sprintf(raw, "0x%lX", number); + else sprintf(raw, "%ld", number); + + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); +} + +void SCRIPT_PutBoolean + ( + int32 scripthandle, + char * sectionname, + char * entryname, + boolean boole + ) +{ + char raw[2] = "0"; + + if (boole) raw[0] = '1'; + + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); +} + +void SCRIPT_PutDouble + ( + int32 scripthandle, + char * sectionname, + char * entryname, + double number, + boolean defaultvalue + ) +{ + char raw[64]; + + sprintf(raw, "%g", number); + + SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw); +} + diff --git a/polymer/eduke32/source/jmact/scriplib.h b/polymer/eduke32/source/jmact/scriplib.h new file mode 100644 index 000000000..ab8d1b7e9 --- /dev/null +++ b/polymer/eduke32/source/jmact/scriplib.h @@ -0,0 +1,355 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + +// scriplib.h + +#ifndef _scriplib_public +#define _scriplib_public +#ifdef __cplusplus +extern "C" { +#endif + +/* +============== += += SCRIPT_Init += +============== +*/ +int32 SCRIPT_Init( char * name ); + + +/* +============== += += SCRIPT_Free += +============== +*/ +void SCRIPT_Free( int32 scripthandle ); + +/* +============== += += SCRIPT_Parse += +============== +*/ + +int32 SCRIPT_Parse ( char *data, int32 length, char * name ); + + +/* +============== += += SCRIPT_Load += +============== +*/ + +int32 SCRIPT_Load ( char * filename ); + +/* +============== += += SCRIPT_Save += +============== +*/ +void SCRIPT_Save (int32 scripthandle, char * filename); + + +/* +============== += += SCRIPT_NumberSections += +============== +*/ + +int32 SCRIPT_NumberSections( int32 scripthandle ); + +/* +============== += += SCRIPT_Section += +============== +*/ + +char * SCRIPT_Section( int32 scripthandle, int32 which ); + +/* +============== += += SCRIPT_NumberEntries += +============== +*/ + +int32 SCRIPT_NumberEntries( int32 scripthandle, char * sectionname ); + +/* +============== += += SCRIPT_Entry += +============== +*/ + +char * SCRIPT_Entry( int32 scripthandle, char * sectionname, int32 which ); + + +/* +============== += += SCRIPT_GetRaw += +============== +*/ +char * SCRIPT_GetRaw(int32 scripthandle, char * sectionname, char * entryname); + +/* +============== += += SCRIPT_GetString += +============== +*/ +boolean SCRIPT_GetString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * dest + ); + +/* +============== += += SCRIPT_GetDoubleString += +============== +*/ +boolean SCRIPT_GetDoubleString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * dest1, + char * dest2 + ); + +/* +============== += += SCRIPT_GetNumber += +============== +*/ +boolean SCRIPT_GetNumber + ( + int32 scripthandle, + char * sectionname, + char * entryname, + int32 * number + ); + +/* +============== += += SCRIPT_GetBoolean += +============== +*/ +boolean SCRIPT_GetBoolean + ( + int32 scripthandle, + char * sectionname, + char * entryname, + boolean * boole + ); + +/* +============== += += SCRIPT_GetDouble += +============== +*/ + +boolean SCRIPT_GetDouble + ( + int32 scripthandle, + char * sectionname, + char * entryname, + double * number + ); + + + +/* +============== += += SCRIPT_PutComment += +============== +*/ +void SCRIPT_PutComment( int32 scripthandle, char * sectionname, char * comment ); + +/* +============== += += SCRIPT_PutEOL += +============== +*/ +void SCRIPT_PutEOL( int32 scripthandle, char * sectionname ); + +/* +============== += += SCRIPT_PutMultiComment += +============== +*/ +void SCRIPT_PutMultiComment + ( + int32 scripthandle, + char * sectionname, + char * comment, + ... + ); + +/* +============== += += SCRIPT_PutSection += +============== +*/ +void SCRIPT_PutSection( int32 scripthandle, char * sectionname ); + +/* +============== += += SCRIPT_PutRaw += +============== +*/ +void SCRIPT_PutRaw + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * raw + ); + +/* +============== += += SCRIPT_PutString += +============== +*/ +void SCRIPT_PutString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * string + ); + +/* +============== += += SCRIPT_PutDoubleString += +============== +*/ +void SCRIPT_PutDoubleString + ( + int32 scripthandle, + char * sectionname, + char * entryname, + char * string1, + char * string2 + ); + +/* +============== += += SCRIPT_PutNumber += +============== +*/ +void SCRIPT_PutNumber + ( + int32 scripthandle, + char * sectionname, + char * entryname, + int32 number, + boolean hexadecimal, + boolean defaultvalue + ); + +/* +============== += += SCRIPT_PutBoolean += +============== +*/ +void SCRIPT_PutBoolean + ( + int32 scripthandle, + char * sectionname, + char * entryname, + boolean boole + ); + +/* +============== += += SCRIPT_PutDouble += +============== +*/ + +void SCRIPT_PutDouble + ( + int32 scripthandle, + char * sectionname, + char * entryname, + double number, + boolean defaultvalue + ); + + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/types.h b/polymer/eduke32/source/jmact/types.h new file mode 100644 index 000000000..98e24485a --- /dev/null +++ b/polymer/eduke32/source/jmact/types.h @@ -0,0 +1,112 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#ifndef _types_public +#define _types_public +#ifdef __cplusplus +extern "C" { +#endif + + +//*************************************************************************** +// +// Global Data Types (For portability) +// +//*************************************************************************** + +typedef unsigned char uint8; +typedef uint8 byte; +typedef signed char int8; + +typedef unsigned short int uint16; +typedef uint16 word; +typedef short int int16; + +typedef unsigned long uint32; +typedef long int32; +typedef uint32 dword; + +typedef int32 fixed; +typedef int32 boolean; +typedef float float32; +typedef double float64; +//typedef long double float128; +typedef float64 appfloat; + +#define MAXINT32 0x7fffffff +#define MININT32 -0x80000000 +#define MAXUINT32 0xffffffff +#define MINUINT32 0 + +#define MAXINT16 0x7fff +#define MININT16 -0x8000 +#define MAXUINT16 0xffff +#define MINUINT16 0 + +//*************************************************************************** +// +// boolean values +// +//*************************************************************************** + +#define true ( 1 == 1 ) +#define false ( ! true ) + +#ifndef TRUE + #define TRUE ( 1 == 1 ) + #define FALSE ( !TRUE ) +#endif + +//*************************************************************************** +// +// BYTE ACCESS MACROS +// +//*************************************************************************** + +// WORD macros +#define Int16_HighByte( x ) ( (uint8) ((x)>>8) ) +#define Int16_LowByte( x ) ( (uint8) ((x)&0xff) ) + +// DWORD macros +#define Int32_4Byte( x ) ( (uint8) ((x)>>24)&0xff ) +#define Int32_3Byte( x ) ( (uint8) (((x)>>16)&0xff) ) +#define Int32_2Byte( x ) ( (uint8) (((x)>>8)&0xff) ) +#define Int32_1Byte( x ) ( (uint8) ((x)&0xff) ) + +#ifdef __WATCOMC__ +# ifndef strcasecmp +# define strcasecmp stricmp +# endif +# ifndef strncasecmp +# define strncasecmp strnicmp +# endif +#endif + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jmact/util_lib.c b/polymer/eduke32/source/jmact/util_lib.c new file mode 100644 index 000000000..42848d4d8 --- /dev/null +++ b/polymer/eduke32/source/jmact/util_lib.c @@ -0,0 +1,153 @@ +/* + * util_lib.c + * Utility functions to emulate MACT + * + * by Jonathon Fowler + * + * Since we weren't given the source for MACT386.LIB so I've had to do some + * creative interpolation here. + * + */ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "compat.h" +#include "types.h" +#include "util_lib.h" +#include "baselayer.h" + +//#define MOTOROLA + + +static void (*ShutDown)(void) = NULL; // this is defined by whoever links us + + +void RegisterShutdownFunction( void (* sh) (void) ) +{ + ShutDown = sh; +} + +#ifndef RENDERTYPEWIN +void Error(char *error, ...) +{ + va_list va; + + if (ShutDown) ShutDown(); + + if (error) { + va_start(va, error); + vprintf(error, va); + va_end(va); + printf("\n\n"); + } + + exit((error != NULL)); +} +#endif + +char CheckParm(char *check) +{ + int c; + + for (c=1;c<_buildargc;c++) { + if (_buildargv[c][0] == '/' || _buildargv[c][0] == '-') + if (!Bstrcasecmp(&_buildargv[c][1], check)) return c; + } + + return 0; +} + +void *SafeMalloc (int32 size) +{ + void *p; + + p = malloc(size); + if (!p) Error("SafeMalloc failure for %d bytes",size); + + return p; +} + +void SafeFree (void * ptr) +{ + if (!ptr) Error("Tried to deallocate NULL pointer."); + free(ptr); +} + +void SafeRealloc (void ** ptr, int32 newsize) +{ + void *p; + + p = realloc(*ptr, newsize); + if (!p) Error("SafeRealloc failure for %d bytes",newsize); + + *ptr = p; +} + +int32 ParseHex (char *hex) +{ + return strtol(hex, NULL, 16); +} + +int32 ParseNum (char *str) +{ + return strtol(str, NULL, 10); +} + +int16 MotoShort (int16 l) +{ +#if B_LITTLE_ENDIAN != 0 + return l; +#else + return ((l & 0x00ff) << 8) | ((l & 0xff00) >> 8); +#endif +} + +int16 IntelShort (int16 l) +{ +#if B_BIG_ENDIAN != 0 + return ((l & 0x00ff) << 8) | ((l & 0xff00) >> 8); +#else + return l; +#endif +} + +int32 MotoLong (int32 l) +{ +#if B_LITTLE_ENDIAN != 0 + return l; +#else + int32 t = ((l & 0x00ff00ffl) << 8) | ((l & 0xff00ff00l) >> 8); + return ((t & 0x0000ffffl) << 16) | ((t & 0xffff0000l) >> 16); +#endif +} + +int32 IntelLong (int32 l) +{ +#if B_BIG_ENDIAN != 0 + int32 t = ((l & 0x00ff00ffl) << 8) | ((l & 0xff00ff00l) >> 8); + return ((t & 0x0000ffffl) << 16) | ((t & 0xffff0000l) >> 16); +#else + return l; +#endif +} + diff --git a/polymer/eduke32/source/jmact/util_lib.h b/polymer/eduke32/source/jmact/util_lib.h new file mode 100644 index 000000000..8e1e631c9 --- /dev/null +++ b/polymer/eduke32/source/jmact/util_lib.h @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +//*************************************************************************** +// +// UTIL_LIB.C - various utils +// +//*************************************************************************** + +#ifndef _util_lib_public +#define _util_lib_public +#ifdef __cplusplus +extern "C" { +#endif + +#if RENDERTYPEWIN +#include "winlayer.h" +#define _argc _buildargc +#define _argv _buildargv +#endif + +void RegisterShutdownFunction( void (* sh) (void) ); +void Error (char *error, ...); + +char CheckParm (char *check); + +void *SafeMalloc (int32 size); +int32 SafeMallocSize (void * ptr); +void SafeFree (void * ptr); +void SafeRealloc (void ** ptr, int32 newsize); +int32 ParseHex (char *hex); +int32 ParseNum (char *str); +int16 MotoShort (int16 l); +int16 IntelShort (int16 l); +int32 MotoLong (int32 l); +int32 IntelLong (int32 l); + +void HeapSort(char * base, int32 nel, int32 width, int32 (*compare)(), void (*switcher)()); + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/keys.h b/polymer/eduke32/source/keys.h new file mode 100644 index 000000000..fbf20155e --- /dev/null +++ b/polymer/eduke32/source/keys.h @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1997, 2005 - 3D Realms Entertainment + +This file is part of Shadow Warrior version 1.2 + +Shadow Warrior is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1997 - Frank Maddin and Jim Norwood +Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + +#ifndef KEYS_H + +#define KEYS_H + + #define NUM_CODES 128 + + #define ESC 0x1B + #define ENTER 0x0D + + #define KEYSC_ESC 1 + #define KEYSC_1 2 + #define KEYSC_2 3 + #define KEYSC_3 4 + #define KEYSC_4 5 + #define KEYSC_5 6 + #define KEYSC_6 7 + #define KEYSC_7 8 + #define KEYSC_8 9 + #define KEYSC_9 10 + #define KEYSC_0 11 + #define KEYSC_DASH 12 + #define KEYSC_EQUAL 13 + + #define KEYSC_BS 14 + #define KEYSC_TAB 15 + #define KEYSC_Q 16 + #define KEYSC_W 17 + #define KEYSC_E 18 + #define KEYSC_R 19 + #define KEYSC_T 20 + #define KEYSC_Y 21 + #define KEYSC_U 22 + #define KEYSC_I 23 + #define KEYSC_O 24 + #define KEYSC_P 25 + #define KEYSC_LBRACK 26 + #define KEYSC_RBRACK 27 + #define KEYSC_ENTER 28 + + #define KEYSC_CTRL 29 + #define KEYSC_A 30 + #define KEYSC_S 31 + #define KEYSC_D 32 + #define KEYSC_F 33 + #define KEYSC_G 34 + #define KEYSC_H 35 + #define KEYSC_J 36 + #define KEYSC_K 37 + #define KEYSC_L 38 + #define KEYSC_SEMI 39 + #define KEYSC_QUOTE 40 + #define KEYSC_BQUOTE 41 + #define KEYSC_TILDE 41 + + #define KEYSC_LSHIFT 42 + #define KEYSC_BSLASH 43 + #define KEYSC_Z 44 + #define KEYSC_X 45 + #define KEYSC_C 46 + #define KEYSC_V 47 + #define KEYSC_B 48 + #define KEYSC_N 49 + #define KEYSC_M 50 + #define KEYSC_COMMA 51 + #define KEYSC_PERIOD 52 + #define KEYSC_SLASH 53 + #define KEYSC_RSHIFT 54 + #define KEYSC_STAR 55 + + #define KEYSC_ALT 56 + #define KEYSC_SPACE 57 + #define KEYSC_CAPS 58 + + #define KEYSC_F1 59 + #define KEYSC_F2 60 + #define KEYSC_F3 61 + #define KEYSC_F4 62 + #define KEYSC_F5 63 + #define KEYSC_F6 64 + #define KEYSC_F7 65 + #define KEYSC_F8 66 + #define KEYSC_F9 67 + #define KEYSC_F10 68 + + #define KEYSC_F11 0x57 + #define KEYSC_F12 0x58 + + #define KEYSC_NUM 69 + #define KEYSC_SCROLL 70 + + #define KEYSC_HOME 71 + #define KEYSC_UP 72 + #define KEYSC_PGUP 73 + #define KEYSC_GMINUS 74 + #define KEYSC_LEFT 75 + #define KEYSC_KP5 76 + #define KEYSC_RIGHT 77 + #define KEYSC_GPLUS 78 + #define KEYSC_END 79 + #define KEYSC_DOWN 80 + #define KEYSC_PGDN 81 + #define KEYSC_INS 82 + #define KEYSC_DEL 83 + + #define asc_Esc 27 + #define asc_Enter 13 + #define asc_Space 32 + +#endif diff --git a/polymer/eduke32/source/mapster32.h b/polymer/eduke32/source/mapster32.h new file mode 100644 index 000000000..2692b60b5 --- /dev/null +++ b/polymer/eduke32/source/mapster32.h @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - Richard Gobeille + +This file is part of Mapster32 + +Mapster32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#define TICSPERFRAME 3 + +// #define VULGARITY + +char *defsfilename = "duke3d.def"; + +extern char keystatus[]; +extern short defaultspritecstat; +extern long posx, posy, posz, horiz, qsetmode; +extern short ang, cursectnum; +extern short ceilingheinum, floorheinum; +extern char names[MAXTILES][25]; + +extern long ydim16, xdimgame, ydimgame, bppgame, xdim2d, ydim2d; + +extern long zmode, kensplayerheight, zlock; + +extern short editstatus, searchit; +extern long searchx, searchy, osearchx, osearchy; //search input +extern short searchsector, searchwall, searchstat; //search output + +extern short temppicnum, tempcstat, templotag, temphitag, tempextra; +extern char tempshade, temppal, tempvis, tempxrepeat, tempyrepeat, somethingintab; + +static long ototalclock = 0, clockval[16], clockcnt = 0; + +#define NUMOPTIONS 9 +#define NUMKEYS 19 + +char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0,0}; +char keys[NUMBUILDKEYS] = + { + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x47,0x49, + 0x9c,0x1c,0xd,0xc,0xf,0x45 + }; + +int nextvoxid = 0; + +extern long whitecol; +extern char vgapal16[4*256]; +extern void AutoAlignWalls(long nWall0, long ply); +extern char changechar(char dachar, long dadir, char smooshyalign, char boundcheck); +extern void _printmessage16(char name[82]); +extern void updatenumsprites(void); + +extern long lastpm16time, synctics; +extern long halfxdim16, midydim16, zoom; +extern void fixrepeats(short i); + +char autospritehelp=0,autosecthelp=0; +static char pskysearch[MAXSECTORS]; +short MinRate=24, MinD=3; +long xoldtimerhandler, lastmessagetime; + +static char tempbuf[1024]; //1024 +static int numsprite[MAXSPRITES]; +static int multisprite[MAXSPRITES]; +static char lo[32]; +char levelname[255]; +static short curwall=0,curwallnum=0; +static short cursearchsprite=0,cursearchspritenum=0,cursector_lotag=0,cursectornum=0; +static short search_lotag=0,search_hitag=0; +static char wallsprite=0; +static char helpon=0; +//static char onwater=0; +static char onnames=4; +static char usedcount=1; +static short cursprite; +long mousxplc,mousyplc; +long ppointhighlight; +static int counter=0; +char nosprites=0,purpleon=0,skill=4; +char framerateon=1,tabgraphic=2,shadepreview=0,autosave=1; + + +static char sidemode=0; +extern long vel, svel, hvel, angvel; +long xvel, yvel, timoff; + +void SearchSectorsForward(); +void SearchSectorsBackward(); +void SpriteName(short spritenum, char *lo2); +int ActorMem(long i); +void PrintStatus(char *string,int num,char x,char y,char color); +void SetBOSS1Palette(); +void SetSLIMEPalette(); +void SetWATERPalette(); +void SetGAMEPalette(); +void kensetpalette(char *vgapal); + +extern short grid; + +extern void EditSpriteData(short spritenum); +extern void EditWallData(short wallnum); +extern void EditSectorData(short sectnum); + +char GAMEpalette[768]; +char WATERpalette[768]; +char SLIMEpalette[768]; +char TITLEpalette[768]; +char REALMSpalette[768]; +char BOSS1palette[768]; + +char num_tables; + +int updownunits=1024; +extern short highlightsector[MAXSECTORS], highlightsectorcnt; +extern short highlight[MAXWALLS]; +extern short pointhighlight, linehighlight, highlightcnt; +extern short asksave; + +char getmessage[162], getmessageleng; +long getmessagetimeoff, charsperline; +extern long startposx, startposy, startposz; +extern short startang, startsectnum; + +long autosavetimer; +extern long numsprites; +extern char spritecol2d[MAXTILES][2]; +extern char custom2dcolors; +extern char mlook; + +int intro=0; +extern long frameplace, ydim16, halfxdim16, midydim16, zoom; +extern char pow2char[8]; + +static int acurpalette=0; + +extern void showsectordata(short sectnum); +extern void showwalldata(short wallnum); +extern void showspritedata(short spritenum); +extern long checksectorpointer(short i, short sectnum); + +extern double msens; + +void ContextHelp(short spritenum); +void ResetKeys(); + +extern void clearfilenames(void), fixspritesectors(void); + #define KEY_PRESSED(sc) KB_KeyPressed((sc)) diff --git a/polymer/eduke32/source/menus.c b/polymer/eduke32/source/menus.c new file mode 100644 index 000000000..4e7b24bb2 --- /dev/null +++ b/polymer/eduke32/source/menus.c @@ -0,0 +1,4043 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "mouse.h" +#include "osd.h" +#include + +extern char inputloc; +extern int recfilep; +//extern char vgacompatible; +short probey=0,lastprobey=0,last_menu,globalskillsound=-1; +short sh,onbar,buttonstat,deletespot; +short last_zero,last_fifty,last_onehundred,last_threehundred = 0; + +static char fileselect = 1, menunamecnt, menuname[256][64], curpath[80], menupath[80]; + +static CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL; +static int numdirs=0, numfiles=0; +static int currentlist=0; + +static int function, whichkey; +static int changesmade, newvidmode, curvidmode, newfullscreen; +static int vidsets[16] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }, curvidset, newvidset = 0; + +static char *mousebuttonnames[] = { "Left", "Right", "Middle", "Thumb", "Wheel Down", "Wheel Up" }; + +void cmenu(short cm) +{ + current_menu = cm; + + if( (cm >= 1000 && cm <= 1009) ) + return; + + if( cm == 0 ) + probey = last_zero; + else if(cm == 50) + probey = last_fifty; + else if(cm == 100) + probey = last_onehundred; + else if(cm >= 300 && cm < 400) + probey = last_threehundred; + else if(cm == 110) + probey = 1; + else probey = 0; + lastprobey = -1; +} + +void savetemp(char *fn,long daptr,long dasiz) +{ + FILE *fp; + + if ((fp = fopen(fn,"wb")) == (FILE *)NULL) + return; + + fwrite((char *)daptr,dasiz,1,fp); + + fclose(fp); +} + +void getangplayers(short snum) +{ + short i,a; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if(i != snum) + { + a = ps[snum].ang+getangle(ps[i].posx-ps[snum].posx,ps[i].posy-ps[snum].posy); + a = a-1024; + rotatesprite( + (320<<15) + (((sintable[(a+512)&2047])>>7)<<15), + (320<<15) - (((sintable[a&2047])>>8)<<15), + klabs(sintable[((a>>1)+768)&2047]<<2),0,APLAYER,0,ps[i].palookup,0,0,0,xdim-1,ydim-1); + } + } +} + +#define LMB (buttonstat&1) +#define RMB (buttonstat&2) + +ControlInfo minfo; + +long mi; + +static int probe_(int type,int x,int y,int i,int n) +{ + short centre, s; + + s = 1+(CONTROL_GetMouseSensitivity()>>4); + + if( ControllerType == 1 && CONTROL_MousePresent ) + { + CONTROL_GetInput( &minfo ); + mi += minfo.dz; + } + + else minfo.dz = minfo.dyaw = 0; + + if( x == (320>>1) ) + centre = 320>>2; + else centre = 0; + + if(!buttonstat) + { + if( KB_KeyPressed( sc_UpArrow ) || KB_KeyPressed( sc_PgUp ) || KB_KeyPressed( sc_kpad_8 ) || + mi < -8192 ) + { + mi = 0; + KB_ClearKeyDown( sc_UpArrow ); + KB_ClearKeyDown( sc_kpad_8 ); + KB_ClearKeyDown( sc_PgUp ); + sound(KICK_HIT); + + probey--; + if(probey < 0) probey = n-1; + minfo.dz = 0; + } + if( KB_KeyPressed( sc_DownArrow ) || KB_KeyPressed( sc_PgDn ) || KB_KeyPressed( sc_kpad_2 ) + || mi > 8192 ) + { + mi = 0; + KB_ClearKeyDown( sc_DownArrow ); + KB_ClearKeyDown( sc_kpad_2 ); + KB_ClearKeyDown( sc_PgDn ); + sound(KICK_HIT); + probey++; + minfo.dz = 0; + } + } + + if(probey >= n) + probey = 0; + + if(centre) + { + // rotatesprite(((320>>1)+(centre)+54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1); + // rotatesprite(((320>>1)-(centre)-54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1); + + rotatesprite(((320>>1)+(centre>>1)+70)<<16,(y+(probey*i)-4)<<16,65536L>>type,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1); + rotatesprite(((320>>1)-(centre>>1)-70)<<16,(y+(probey*i)-4)<<16,65536L>>type,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1); + } + else + rotatesprite((x<<16)-((tilesizx[BIGFNTCURSOR]-4)<<(16-type)),(y+(probey*i)-(4>>type))<<16,65536L>>type,0,SPINNINGNUKEICON+(((totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1); + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed( sc_kpad_Enter ) || KB_KeyPressed( sc_Enter ) || (LMB && !onbar) ) + { + if(current_menu != 110) + sound(PISTOL_BODYHIT); + KB_ClearKeyDown( sc_Enter ); + KB_ClearKeyDown( sc_Space ); + KB_ClearKeyDown( sc_kpad_Enter ); + return(probey); + } + else if( KB_KeyPressed( sc_Escape ) || (RMB) ) + { + onbar = 0; + KB_ClearKeyDown( sc_Escape ); + sound(EXITMENUSOUND); + return(-1); + } + else + { + if(onbar == 0) return(-probey-2); + if ( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -128 ) ) + return(probey); + else if ( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 128 ) ) + return(probey); + else return(-probey-2); + } +} +int probe(int x,int y,int i,int n) { return probe_(0,x,y,i,n); } +int probesm(int x,int y,int i,int n) { return probe_(1,x,y,i,n); } + +int menutext(int x,int y,short s,short p,char *t) +{ + short i, ac, centre; + + y -= 12; + + i = centre = 0; + + if( x == (320>>1) ) + { + while( *(t+i) ) + { + if(*(t+i) == ' ') + { + centre += 5; + i++; + continue; + } + ac = 0; + if(*(t+i) >= '0' && *(t+i) <= '9') + ac = *(t+i) - '0' + BIGALPHANUM-10; + else if(*(t+i) >= 'a' && *(t+i) <= 'z') + ac = toupper(*(t+i)) - 'A' + BIGALPHANUM; + else if(*(t+i) >= 'A' && *(t+i) <= 'Z') + ac = *(t+i) - 'A' + BIGALPHANUM; + else switch(*(t+i)) + { + case '-': + ac = BIGALPHANUM-11; + break; + case '.': + ac = BIGPERIOD; + break; + case '\'': + ac = BIGAPPOS; + break; + case ',': + ac = BIGCOMMA; + break; + case '!': + ac = BIGX; + break; + case '?': + ac = BIGQ; + break; + case ';': + ac = BIGSEMI; + break; + case ':': + ac = BIGSEMI; + break; + default: + centre += 5; + i++; + continue; + } + + centre += tilesizx[ac]-1; + i++; + } + } + + if(centre) + x = (320-centre-10)>>1; + + while(*t) + { + if(*t == ' ') {x+=5;t++;continue;} + ac = 0; + if(*t >= '0' && *t <= '9') + ac = *t - '0' + BIGALPHANUM-10; + else if(*t >= 'a' && *t <= 'z') + ac = toupper(*t) - 'A' + BIGALPHANUM; + else if(*t >= 'A' && *t <= 'Z') + ac = *t - 'A' + BIGALPHANUM; + else switch(*t) + { + case '-': + ac = BIGALPHANUM-11; + break; + case '.': + ac = BIGPERIOD; + break; + case ',': + ac = BIGCOMMA; + break; + case '!': + ac = BIGX; + break; + case '\'': + ac = BIGAPPOS; + break; + case '?': + ac = BIGQ; + break; + case ';': + ac = BIGSEMI; + break; + case ':': + ac = BIGCOLIN; + break; + default: + x += 5; + t++; + continue; + } + + rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,10+16,0,0,xdim-1,ydim-1); + + x += tilesizx[ac]; + t++; + } + return (x); +} + +static void bar_(int type, int x,int y,short *p,short dainc,char damodify,short s, short pa) +{ + short xloc; + char rev; + + if(dainc < 0) { dainc = -dainc; rev = 1; } + else rev = 0; + y-=2; + + if(damodify) + { + if(rev == 0) + { + if( *p > 0 && (KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) ) ) // && onbar) ) + { + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + + *p -= dainc; + if(*p < 0) + *p = 0; + sound(KICK_HIT); + } + if( *p < 63 && (KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) ) )//&& onbar) ) + { + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + + *p += dainc; + if(*p > 63) + *p = 63; + sound(KICK_HIT); + } + } + else + { + if( *p > 0 && (KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) ) )//&& onbar) ) + { + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + + *p -= dainc; + if(*p < 0) + *p = 0; + sound(KICK_HIT); + } + if( *p < 64 && (KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) ) ) // && onbar) ) + { + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + + *p += dainc; + if(*p > 64) + *p = 64; + sound(KICK_HIT); + } + } + } + + xloc = *p; + + rotatesprite( (x<<16)+(22<<(16-type)),(y<<16)-(3<<(16-type)),65536L>>type,0,SLIDEBAR,s,pa,10,0,0,xdim-1,ydim-1); + if(rev == 0) + rotatesprite( (x<<16)+((xloc+1)<<(16-type)),(y<<16)+(1<<(16-type)),65536L>>type,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1); + else + rotatesprite( (x<<16)+((65-xloc)<<(16-type)),(y<<16)+(1<<(16-type)),65536L>>type,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1); +} + +void bar(int x,int y,short *p,short dainc,char damodify,short s, short pa) { bar_(0,x,y,p,dainc,damodify,s,pa); } +void barsm(int x,int y,short *p,short dainc,char damodify,short s, short pa) { bar_(1,x,y,p,dainc,damodify,s,pa); } + +static void modval(int min, int max,int *p,short dainc,char damodify) +{ + char rev; + + if(dainc < 0) { dainc = -dainc; rev = 1; } + else rev = 0; + + if(damodify) + { + if(rev == 0) + { + if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) ) // && onbar) ) + { + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + + *p -= dainc; + if(*p < min) + *p = max; + sound(PISTOL_BODYHIT); + } + if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) )//&& onbar) ) + { + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + + *p += dainc; + if(*p > max) + *p = min; + sound(PISTOL_BODYHIT); + } + } + else + { + if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ))//&& onbar )) + { + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + + *p -= dainc; + if(*p < min) + *p = max; + sound(PISTOL_BODYHIT); + } + if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ))// && onbar) ) + { + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + + *p += dainc; + if(*p > max) + *p = min; + sound(PISTOL_BODYHIT); + } + } + } +} + +#define SHX(X) 0 +// ((x==X)*(-sh)) +#define PHX(X) 0 +// ((x==X)?1:2) +#define MWIN(X) rotatesprite( 320<<15,200<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1) +#define MWINXY(X,OX,OY) rotatesprite( ( 320+(OX) )<<15, ( 200+(OY) )<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1) + +extern int loadpheader(char spot,struct savehead *saveh); + +static struct savehead savehead; +//static int32 volnum,levnum,plrskl,numplr; +//static char brdfn[BMAX_PATH]; +short lastsavedpos = -1; + +void dispnames(void) +{ + short x, c = 160; + + c += 64; + for(x = 0;x <= 108;x += 12) + rotatesprite((c+91-64)<<16,(x+56)<<16,65536L,0,TEXTBOX,24,0,10,0,0,xdim-1,ydim-1); + + rotatesprite(22<<16,97<<16,65536L,0,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1); + rotatesprite(180<<16,97<<16,65536L,1024,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1); + rotatesprite(99<<16,50<<16,65536L,512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1); + rotatesprite(103<<16,144<<16,65536L,1024+512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1); + + for (x=0;x<=9;x++) + minitext(c,48+(12*x),ud.savegame[x],2,10+16); +} + +void clearfilenames(void) +{ + klistfree(finddirs); + klistfree(findfiles); + finddirs = findfiles = NULL; + numfiles = numdirs = 0; +} + +int getfilenames(char *path, char kind[]) +{ + CACHE1D_FIND_REC *r; + + clearfilenames(); + finddirs = klistpath(path,"*",CACHE1D_FIND_DIR); + findfiles = klistpath(path,kind,CACHE1D_FIND_FILE); + for (r = finddirs; r; r=r->next) numdirs++; + for (r = findfiles; r; r=r->next) numfiles++; + + finddirshigh = finddirs; + findfileshigh = findfiles; + currentlist = 0; + if (findfileshigh) currentlist = 1; + + return(0); +} + +long quittimer = 0; + +void menus(void) +{ + CACHE1D_FIND_REC *dir; + short c,x,i; + long l,m; + char *p = NULL; + + getpackets(); + + if(ControllerType == 1 && CONTROL_MousePresent) + { + if(buttonstat != 0 && !onbar) + { + x = MOUSE_GetButtons()<<3; + if( x ) buttonstat = x<<3; + else buttonstat = 0; + } + else + buttonstat = MOUSE_GetButtons(); + } + else buttonstat = 0; + + if( (ps[myconnectindex].gm&MODE_MENU) == 0 ) + { + walock[TILE_LOADSHOT] = 1; + return; + } + + ps[myconnectindex].gm &= (0xff-MODE_TYPE); + ps[myconnectindex].fta = 0; + + x = 0; + + sh = 4-(sintable[(totalclock<<4)&2047]>>11); + + if(bpp > 8 && (ps[myconnectindex].gm&MODE_GAME || (ps[myconnectindex].gm&MODE_DEMO && ud.recstat != 0))) + { + long x,y,y1=0,y2=ydim; + for(y=y1;y= 1000 && current_menu <= 2999 && current_menu >= 300 && current_menu <= 369)) + vscrn(); + + switch(current_menu) + { + case 25000: + gametext(160,90,"SELECT A SAVE SPOT BEFORE",0,2+8+16); + gametext(160,90+9,"YOU QUICK RESTORE.",0,2+8+16); + + x = probe(186,124,0,0); + if(x >= -1) + { + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + ps[myconnectindex].gm &= ~MODE_MENU; + } + break; + + case 20000: + x = probe(326,190,0,0); + gametext(160,50-8,"YOU ARE PLAYING THE SHAREWARE",0,2+8+16); + gametext(160,59-8,"VERSION OF DUKE NUKEM 3D. WHILE",0,2+8+16); + gametext(160,68-8,"THIS VERSION IS REALLY COOL, YOU",0,2+8+16); + gametext(160,77-8,"ARE MISSING OVER 75%% OF THE TOTAL",0,2+8+16); + gametext(160,86-8,"GAME, ALONG WITH OTHER GREAT EXTRAS",0,2+8+16); + gametext(160,95-8,"AND GAMES, WHICH YOU'LL GET WHEN",0,2+8+16); + gametext(160,104-8,"YOU ORDER THE COMPLETE VERSION AND",0,2+8+16); + gametext(160,113-8,"GET THE FINAL TWO EPISODES.",0,2+8+16); + + gametext(160,113+8,"PLEASE READ THE 'HOW TO ORDER' ITEM",0,2+8+16); + gametext(160,122+8,"ON THE MAIN MENU IF YOU WISH TO",0,2+8+16); + gametext(160,131+8,"UPGRADE TO THE FULL REGISTERED",0,2+8+16); + gametext(160,140+8,"VERSION OF DUKE NUKEM 3D.",0,2+8+16); + gametext(160,149+16,"PRESS ANY KEY...",0,2+8+16); + + if( x >= -1 ) cmenu(100); + break; + + case 20001: + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"NETWORK GAME"); + + x = probe(160,100-18,18,3); + + if (x == -1) cmenu(0); + else if (x == 2) cmenu(20010); + else if (x == 1) cmenu(20020); + else if (x == 0) cmenu(20002); + + menutext(160,100-18,0,0,"PLAYER SETUP"); + menutext(160,100,0,0,"JOIN GAME"); + menutext(160,100+18,0,0,"HOST GAME"); + break; + + case 20002: + case 20003: + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"PLAYER SETUP"); + + if (current_menu == 20002) { + x = probe(46,50,20,2); + + if (x == -1) cmenu(20001); + else if (x == 0) { + strcpy(buf, myname); + inputloc = strlen(buf); + current_menu = 20003; + + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + } else if (x == 1) { + // send colour update + } + } else { + x = strget(40+100,50-9,buf,31,0); + if (x) { + if (x == 1) { + strcpy(myname,buf); + // send name update + } + + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + + current_menu = 20002; + } + } + + menutext(40,50,0,0,"NAME"); + if (current_menu == 20002) gametext(40+100,50-9,myname,0,2+8+16); + + menutext(40,50+20,0,0,"COLOR"); + rotatesprite((40+120)<<16,(50+20+(tilesizy[APLAYER]>>1))<<16,65536L,0,APLAYER,0,0,10,0,0,xdim-1,ydim-1); + + break; + + case 20010: + //note: this menu does not seem to be used and has not been updated to support custom game types + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"HOST NETWORK GAME"); + + x = probe(46,50,80,2); + + if (x == -1) { + cmenu(20001); + probey = 2; + } + else if (x == 0) cmenu(20011); + + menutext(40,50,0,0,"GAME OPTIONS"); + minitext(90,60, "GAME TYPE" ,2,26); + minitext(90,60+8, "EPISODE" ,2,26); + minitext(90,60+8+8, "LEVEL" ,2,26); + minitext(90,60+8+8+8, "MONSTERS" ,2,26); + if (ud.m_coop == 0) + minitext(90,60+8+8+8+8, "MARKERS" ,2,26); + else if (ud.m_coop == 1) + minitext(90,60+8+8+8+8, "FRIENDLY FIRE",2,26); + minitext(90,60+8+8+8+8+8, "USER MAP" ,2,26); + + /* if (ud.m_coop == 1) minitext(90+60,60,"COOPERATIVE PLAY",0,26); + else if (ud.m_coop == 2) minitext(90+60,60,"DUKEMATCH (NO SPAWN)",0,26); + else minitext(90+60,60,"DUKEMATCH (SPAWN)",0,26);*/ + gametext(90+60,60,gametype_names[ud.m_coop],0,26); + + minitext(90+60,60+8, volume_names[ud.m_volume_number],0,26); + minitext(90+60,60+8+8, level_names[11*ud.m_volume_number+ud.m_level_number],0,26); + if (ud.m_monsters_off == 0 || ud.m_player_skill > 0) + minitext(90+60,60+8+8+8, skill_names[ud.m_player_skill],0,26); + else minitext(90+60,60+8+8+8, "NONE",0,28); + if (ud.m_coop == 0) { + if (ud.m_marker) minitext(90+60,60+8+8+8+8,"ON",0,26); + else minitext(90+60,60+8+8+8+8,"OFF",0,26); + } else if (ud.m_coop == 1) { + if (ud.m_ffire) minitext(90+60,60+8+8+8+8,"ON",0,26); + else minitext(90+60,60+8+8+8+8,"OFF",0,26); + } + + menutext(40,50+80,0,0,"LAUNCH GAME"); + break; + + case 20011: + c = (320>>1) - 120; + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"NET GAME OPTIONS"); + + x = probe(c,57-8,16,8); + + switch(x) + { + case -1: + cmenu(20010); + break; + case 0: + ud.m_coop++; + if(ud.m_coop == 3) ud.m_coop = 0; + break; + case 1: + if (!VOLUMEONE) { + ud.m_volume_number++; + if(ud.m_volume_number == num_volumes) ud.m_volume_number = 0; + if(ud.m_volume_number == 0 && ud.m_level_number > 6) + ud.m_level_number = 0; + if(ud.m_level_number > 10) ud.m_level_number = 0; + } + break; + case 2: + ud.m_level_number++; + if (!VOLUMEONE) { + if(ud.m_volume_number == 0 && ud.m_level_number > 6) + ud.m_level_number = 0; + } else { + if(ud.m_volume_number == 0 && ud.m_level_number > 5) + ud.m_level_number = 0; + } + if(ud.m_level_number > 10) ud.m_level_number = 0; + break; + case 3: + if(ud.m_monsters_off == 1 && ud.m_player_skill > 0) + ud.m_monsters_off = 0; + + if(ud.m_monsters_off == 0) + { + ud.m_player_skill++; + if(ud.m_player_skill > 3) + { + ud.m_player_skill = 0; + ud.m_monsters_off = 1; + } + } + else ud.m_monsters_off = 0; + + break; + + case 4: + if(ud.m_coop == 0) + ud.m_marker = !ud.m_marker; + break; + + case 5: + if(ud.m_coop == 1) + ud.m_ffire = !ud.m_ffire; + break; + + case 6: + // pick the user map + break; + + case 7: + cmenu(20010); + break; + } + + c += 40; + + // if(ud.m_coop==1) gametext(c+70,57-7-9,"COOPERATIVE PLAY",0,2+8+16); + // else if(ud.m_coop==2) gametext(c+70,57-7-9,"DUKEMATCH (NO SPAWN)",0,2+8+16); + // else gametext(c+70,57-7-9,"DUKEMATCH (SPAWN)",0,2+8+16); + gametext(c+70,57-7-9,gametype_names[ud.m_coop],0,26); + + gametext(c+70,57+16-7-9,volume_names[ud.m_volume_number],0,2+8+16); + + gametext(c+70,57+16+16-7-9,&level_names[11*ud.m_volume_number+ud.m_level_number][0],0,2+8+16); + + if(ud.m_monsters_off == 0 || ud.m_player_skill > 0) + gametext(c+70,57+16+16+16-7-9,skill_names[ud.m_player_skill],0,2+8+16); + else gametext(c+70,57+16+16+16-7-9,"NONE",0,2+8+16); + + if(ud.m_coop == 0) + { + if(ud.m_marker) + gametext(c+70,57+16+16+16+16-7-9,"ON",0,2+8+16); + else gametext(c+70,57+16+16+16+16-7-9,"OFF",0,2+8+16); + } + + if(ud.m_coop == 1) + { + if(ud.m_ffire) + gametext(c+70,57+16+16+16+16+16-7-9,"ON",0,2+8+16); + else gametext(c+70,57+16+16+16+16+16-7-9,"OFF",0,2+8+16); + } + + c -= 44; + + menutext(c,57-9,SHX(-2),PHX(-2),"GAME TYPE"); + + sprintf(tempbuf,"EPISODE %ld",ud.m_volume_number+1); + menutext(c,57+16-9,SHX(-3),PHX(-3),tempbuf); + + sprintf(tempbuf,"LEVEL %ld",ud.m_level_number+1); + menutext(c,57+16+16-9,SHX(-4),PHX(-4),tempbuf); + + menutext(c,57+16+16+16-9,SHX(-5),PHX(-5),"MONSTERS"); + + if(ud.m_coop == 0) + menutext(c,57+16+16+16+16-9,SHX(-6),PHX(-6),"MARKERS"); + else + menutext(c,57+16+16+16+16-9,SHX(-6),1,"MARKERS"); + + if(ud.m_coop == 1) + menutext(c,57+16+16+16+16+16-9,SHX(-6),PHX(-6),"FR. FIRE"); + else menutext(c,57+16+16+16+16+16-9,SHX(-6),1,"FR. FIRE"); + + if (VOLUMEALL) { + menutext(c,57+16+16+16+16+16+16-9,SHX(-7),boardfilename[0] == 0,"USER MAP"); + if( boardfilename[0] != 0 ) + gametext(c+70+44,57+16+16+16+16+16,boardfilename,0,2+8+16); + } else { + menutext(c,57+16+16+16+16+16+16-9,SHX(-7),1,"USER MAP"); + } + + menutext(c,57+16+16+16+16+16+16+16-9,SHX(-8),PHX(-8),"ACCEPT"); + break; + + case 20020: + case 20021: // editing server + case 20022: // editing port + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"JOIN NETWORK GAME"); + + if (current_menu == 20020) { + x = probe(46,50,20,3); + + if (x == -1) { + cmenu(20001); + probey = 1; + } else if (x == 0) { + strcpy(buf, "localhost"); + inputloc = strlen(buf); + current_menu = 20021; + } else if (x == 1) { + strcpy(buf, "19014"); + inputloc = strlen(buf); + current_menu = 20022; + } else if (x == 2) { + } + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + } else if (current_menu == 20021) { + x = strget(40+100,50-9,buf,31,0); + if (x) { + if (x == 1) { + //strcpy(myname,buf); + } + + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + + current_menu = 20020; + } + } else if (current_menu == 20022) { + x = strget(40+100,50+20-9,buf,5,997); + if (x) { + if (x == 1) { + //strcpy(myname,buf); + } + + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + + current_menu = 20020; + } + } + + menutext(40,50,0,0,"SERVER"); + if (current_menu != 20021) gametext(40+100,50-9,"server",0,2+8+16); + + menutext(40,50+20,0,0,"PORT"); + if (current_menu != 20022) { + sprintf(tempbuf,"%d",19014); + gametext(40+100,50+20-9,tempbuf,0,2+8+16); + } + + menutext(160,50+20+20,0,0,"CONNECT"); + + + // ADDRESS + // PORT + // CONNECT + break; + + case 15001: + case 15000: + + gametext(160,90,"LOAD last game:",0,2+8+16); + + sprintf(tempbuf,"\"%s\"",ud.savegame[lastsavedpos]); + gametext(160,99,tempbuf,0,2+8+16); + + gametext(160,99+9,"(Y/N)",0,2+8+16); + + if( KB_KeyPressed(sc_Escape) || KB_KeyPressed(sc_N) || RMB) + { + if(sprite[ps[myconnectindex].i].extra <= 0) + { + if (enterlevel(MODE_GAME)) backtomenu(); + return; + } + + KB_ClearKeyDown(sc_N); + KB_ClearKeyDown(sc_Escape); + + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + KB_FlushKeyboardQueue(); + KB_ClearKeysDown(); + FX_StopAllSounds(); + + if(ud.multimode > 1) + { + loadplayer(-1-lastsavedpos); + ps[myconnectindex].gm = MODE_GAME; + } + else + { + c = loadplayer(lastsavedpos); + if(c == 0) + ps[myconnectindex].gm = MODE_GAME; + } + } + + probe(186,124+9,0,0); + + break; + + case 10000: + case 10001: + + c = 60; + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"ADULT MODE"); + + x = probe(60,50+16,16,2); + if(x == -1) { cmenu(202); probey = 6; break; } + + menutext(c,50+16,SHX(-2),PHX(-2),"ADULT MODE"); + menutext(c,50+16+16,SHX(-3),PHX(-3),"ENTER PASSWORD"); + + if(ud.lockout) menutext(c+160+40,50+16,0,0,"OFF"); + else menutext(c+160+40,50+16,0,0,"ON"); + + if(current_menu == 10001) + { + gametext(160,50+16+16+16+16-12,"ENTER PASSWORD",0,2+8+16); + x = strget((320>>1),50+16+16+16+16,buf,19, 998); + + if( x ) + { + if(ud.pwlockout[0] == 0 || ud.lockout == 0 ) + strcpy(&ud.pwlockout[0],buf); + else if( strcmp(buf,&ud.pwlockout[0]) == 0 ) + { + ud.lockout = 0; + buf[0] = 0; + + for(x=0;x= 0 ) + wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra; + + } + current_menu = 10000; + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_kpad_Enter); + KB_FlushKeyboardQueue(); + } + } + else + { + if(x == 0) + { + if( ud.lockout == 1 ) + { + if(ud.pwlockout[0] == 0) + { + ud.lockout = 0; + for(x=0;x= 0 ) + wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra; + } + else + { + buf[0] = 0; + current_menu = 10001; + inputloc = 0; + KB_FlushKeyboardQueue(); + } + } + else + { + ud.lockout = 1; + + for(x=0;x>1,512,TILE_LOADSHOT,-32,0,4+10+64,0,0,xdim-1,ydim-1); + + dispnames(); + + sprintf(tempbuf,"PLAYERS: %-2ld ",savehead.numplr); + gametext(160,156,tempbuf,0,2+8+16); + + sprintf(tempbuf,"EPISODE: %-2ld / LEVEL: %-2ld / SKILL: %-2ld",1+savehead.volnum,1+savehead.levnum,savehead.plrskl); + gametext(160,168,tempbuf,0,2+8+16); + + if (savehead.volnum == 0 && savehead.levnum == 7) + gametext(160,180,savehead.boardfn,0,2+8+16); + + gametext(160,90,"LOAD game:",0,2+8+16); + sprintf(tempbuf,"\"%s\"",ud.savegame[current_menu-1000]); + gametext(160,99,tempbuf,0,2+8+16); + gametext(160,99+9,"(Y/N)",0,2+8+16); + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + lastsavedpos = current_menu-1000; + + KB_FlushKeyboardQueue(); + KB_ClearKeysDown(); + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + + if(ud.multimode > 1) + { + if( ps[myconnectindex].gm&MODE_GAME ) + { + loadplayer(-1-lastsavedpos); + ps[myconnectindex].gm = MODE_GAME; + } + else + { + tempbuf[0] = 126; + tempbuf[1] = lastsavedpos; + tempbuf[2] = myconnectindex; + for(x=connecthead;x>=0;x=connectpoint2[x]) + { + if (x != myconnectindex) sendpacket(x,tempbuf,3); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + getpackets(); + + loadplayer(lastsavedpos); + + multiflag = 0; + } + } + else + { + c = loadplayer(lastsavedpos); + if(c == 0) + ps[myconnectindex].gm = MODE_GAME; + } + + break; + } + if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB) + { + KB_ClearKeyDown(sc_N); + KB_ClearKeyDown(sc_Escape); + sound(EXITMENUSOUND); + if(ps[myconnectindex].gm&MODE_DEMO) cmenu(300); + else + { + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + } + + probe(186,124+9,0,0); + + break; + + case 1500: + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + KB_FlushKeyboardQueue(); + cmenu(100); + } + if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB) + { + KB_ClearKeyDown(sc_N); + KB_ClearKeyDown(sc_Escape); + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + ps[myconnectindex].gm &= ~MODE_MENU; + sound(EXITMENUSOUND); + break; + } + probe(186,124,0,0); + gametext(160,90,"ABORT this game?",0,2+8+16); + gametext(160,90+9,"(Y/N)",0,2+8+16); + + break; + + case 2000: + case 2001: + case 2002: + case 2003: + case 2004: + case 2005: + case 2006: + case 2007: + case 2008: + case 2009: + + rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1); + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"SAVE GAME"); + + rotatesprite(101<<16,97<<16,65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64,0,0,xdim-1,ydim-1); + sprintf(tempbuf,"PLAYERS: %-2ld ",ud.multimode); + gametext(160,156,tempbuf,0,2+8+16); + + sprintf(tempbuf,"EPISODE: %-2ld / LEVEL: %-2ld / SKILL: %-2ld",1+ud.volume_number,1+ud.level_number,ud.player_skill); + gametext(160,168,tempbuf,0,2+8+16); + + if (ud.volume_number == 0 && ud.level_number == 7) + gametext(160,180,boardfilename,0,2+8+16); + + dispnames(); + + gametext(160,90,"OVERWRITE previous SAVED game?",0,2+8+16); + gametext(160,90+9,"(Y/N)",0,2+8+16); + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + inputloc = strlen(&ud.savegame[current_menu-2000][0]); + + cmenu(current_menu-2000+360); + + KB_FlushKeyboardQueue(); + break; + } + if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB) + { + KB_ClearKeyDown(sc_N); + KB_ClearKeyDown(sc_Escape); + cmenu(351); + sound(EXITMENUSOUND); + } + + probe(186,124,0,0); + + break; + + case 990: + case 991: + case 992: + case 993: + case 994: + case 995: + case 996: + case 997: + case 998: + c = 160; + if (!VOLUMEALL || !PLUTOPAK) { + //rotatesprite(c<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1); + rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(c,24,0,0,current_menu == 998 ? "PORT CREDITS" : "CREDITS"); + + l = 8; + } else { + l = 3; + } + + if(KB_KeyPressed(sc_Escape)) { cmenu(0); break; } + + if( KB_KeyPressed( sc_LeftArrow ) || + KB_KeyPressed( sc_kpad_4 ) || + KB_KeyPressed( sc_UpArrow ) || + KB_KeyPressed( sc_PgUp ) || + KB_KeyPressed( sc_kpad_8 ) ) + { + KB_ClearKeyDown(sc_LeftArrow); + KB_ClearKeyDown(sc_kpad_4); + KB_ClearKeyDown(sc_UpArrow); + KB_ClearKeyDown(sc_PgUp); + KB_ClearKeyDown(sc_kpad_8); + + sound(KICK_HIT); + current_menu--; + if(current_menu < 990) current_menu = 990+l; + } + else if( + KB_KeyPressed( sc_PgDn ) || + KB_KeyPressed( sc_Enter ) || + KB_KeyPressed( sc_Space ) || + KB_KeyPressed( sc_kpad_Enter ) || + KB_KeyPressed( sc_RightArrow ) || + KB_KeyPressed( sc_DownArrow ) || + KB_KeyPressed( sc_kpad_2 ) || + KB_KeyPressed( sc_kpad_9 ) || + KB_KeyPressed( sc_kpad_6 ) ) + { + KB_ClearKeyDown(sc_PgDn); + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_RightArrow); + KB_ClearKeyDown(sc_kpad_Enter); + KB_ClearKeyDown(sc_kpad_6); + KB_ClearKeyDown(sc_kpad_9); + KB_ClearKeyDown(sc_kpad_2); + KB_ClearKeyDown(sc_DownArrow); + KB_ClearKeyDown(sc_Space); + sound(KICK_HIT); + current_menu++; + if(current_menu > 990+l) current_menu = 990; + } + + if (!VOLUMEALL || !PLUTOPAK) { + switch (current_menu) { + case 990: + gametext(c,40, "ORIGINAL CONCEPT",0,2+8+16); + gametext(c,40+9, "TODD REPLOGLE",0,2+8+16); + gametext(c,40+9+9, "ALLEN H. BLUM III",0,2+8+16); + + gametext(c,40+9+9+9+9, "PRODUCED & DIRECTED BY",0,2+8+16); + gametext(c,40+9+9+9+9+9, "GREG MALONE",0,2+8+16); + + gametext(c,40+9+9+9+9+9+9+9, "EXECUTIVE PRODUCER",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9, "GEORGE BROUSSARD",0,2+8+16); + + gametext(c,40+9+9+9+9+9+9+9+9+9+9, "BUILD ENGINE",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"KEN SILVERMAN",0,2+8+16); + break; + case 991: + gametext(c,40, "GAME PROGRAMMING",0,2+8+16); + gametext(c,40+9, "TODD REPLOGLE",0,2+8+16); + + gametext(c,40+9+9+9, "3D ENGINE/TOOLS/NET",0,2+8+16); + gametext(c,40+9+9+9+9, "KEN SILVERMAN",0,2+8+16); + + gametext(c,40+9+9+9+9+9+9, "NETWORK LAYER/SETUP PROGRAM",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9, "MARK DOCHTERMANN",0,2+8+16); + break; + case 992: + gametext(c,40, "MAP DESIGN",0,2+8+16); + gametext(c,40+9, "ALLEN H BLUM III",0,2+8+16); + gametext(c,40+9+9, "RICHARD GRAY",0,2+8+16); + + gametext(c,40+9+9+9+9, "3D MODELING",0,2+8+16); + gametext(c,40+9+9+9+9+9, "CHUCK JONES",0,2+8+16); + gametext(c,40+9+9+9+9+9+9, "SAPPHIRE CORPORATION",0,2+8+16); + + gametext(c,40+9+9+9+9+9+9+9+9, "ARTWORK",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9+9, "DIRK JONES, STEPHEN HORNBACK",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9+9+9, "JAMES STOREY, DAVID DEMARET",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"DOUGLAS R WOOD",0,2+8+16); + break; + case 993: + gametext(c,40, "SOUND ENGINE",0,2+8+16); + gametext(c,40+9, "JIM DOSE",0,2+8+16); + + gametext(c,40+9+9+9, "SOUND & MUSIC DEVELOPMENT",0,2+8+16); + gametext(c,40+9+9+9+9, "ROBERT PRINCE",0,2+8+16); + gametext(c,40+9+9+9+9+9, "LEE JACKSON",0,2+8+16); + + gametext(c,40+9+9+9+9+9+9+9, "VOICE TALENT",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9, "LANI MINELLA - VOICE PRODUCER",0,2+8+16); + gametext(c,40+9+9+9+9+9+9+9+9+9, "JON ST. JOHN AS \"DUKE NUKEM\"",0,2+8+16); + break; + case 994: + gametext(c,60, "GRAPHIC DESIGN",0,2+8+16); + gametext(c,60+9, "PACKAGING, MANUAL, ADS",0,2+8+16); + gametext(c,60+9+9, "ROBERT M. ATKINS",0,2+8+16); + gametext(c,60+9+9+9, "MICHAEL HADWIN",0,2+8+16); + + gametext(c,60+9+9+9+9+9, "SPECIAL THANKS TO",0,2+8+16); + gametext(c,60+9+9+9+9+9+9, "STEVEN BLACKBURN, TOM HALL",0,2+8+16); + gametext(c,60+9+9+9+9+9+9+9, "SCOTT MILLER, JOE SIEGLER",0,2+8+16); + gametext(c,60+9+9+9+9+9+9+9+9, "TERRY NAGY, COLLEEN COMPTON",0,2+8+16); + gametext(c,60+9+9+9+9+9+9+9+9+9, "HASH INC., FORMGEN, INC.",0,2+8+16); + break; + case 995: + gametext(c,49, "THE 3D REALMS BETA TESTERS",0,2+8+16); + + gametext(c,49+9+9, "NATHAN ANDERSON, WAYNE BENNER",0,2+8+16); + gametext(c,49+9+9+9, "GLENN BRENSINGER, ROB BROWN",0,2+8+16); + gametext(c,49+9+9+9+9, "ERIK HARRIS, KEN HECKBERT",0,2+8+16); + gametext(c,49+9+9+9+9+9, "TERRY HERRIN, GREG HIVELY",0,2+8+16); + gametext(c,49+9+9+9+9+9+9, "HANK LEUKART, ERIC BAKER",0,2+8+16); + gametext(c,49+9+9+9+9+9+9+9, "JEFF RAUSCH, KELLY ROGERS",0,2+8+16); + gametext(c,49+9+9+9+9+9+9+9+9, "MIKE DUNCAN, DOUG HOWELL",0,2+8+16); + gametext(c,49+9+9+9+9+9+9+9+9+9, "BILL BLAIR",0,2+8+16); + break; + case 996: + gametext(c,32, "COMPANY PRODUCT SUPPORT",0,2+8+16); + + gametext(c,32+9+9, "THE FOLLOWING COMPANIES WERE COOL",0,2+8+16); + gametext(c,32+9+9+9, "ENOUGH TO GIVE US LOTS OF STUFF",0,2+8+16); + gametext(c,32+9+9+9+9, "DURING THE MAKING OF DUKE NUKEM 3D.",0,2+8+16); + + gametext(c,32+9+9+9+9+9+9, "ALTEC LANSING MULTIMEDIA",0,2+8+16); + gametext(c,32+9+9+9+9+9+9+9, "FOR TONS OF SPEAKERS AND THE",0,2+8+16); + gametext(c,32+9+9+9+9+9+9+9+9, "THX-LICENSED SOUND SYSTEM",0,2+8+16); + gametext(c,32+9+9+9+9+9+9+9+9+9, "FOR INFO CALL 1-800-548-0620",0,2+8+16); + + gametext(c,32+9+9+9+9+9+9+9+9+9+9+9,"CREATIVE LABS, INC.",0,2+8+16); + + gametext(c,32+9+9+9+9+9+9+9+9+9+9+9+9+9,"THANKS FOR THE HARDWARE, GUYS.",0,2+8+16); + break; + case 997: + gametext(c,50, "DUKE NUKEM IS A TRADEMARK OF",0,2+8+16); + gametext(c,50+9, "3D REALMS ENTERTAINMENT",0,2+8+16); + + gametext(c,50+9+9+9, "DUKE NUKEM",0,2+8+16); + gametext(c,50+9+9+9+9, "(C) 1996 3D REALMS ENTERTAINMENT",0,2+8+16); + + if (VOLUMEONE) { + gametext(c,106, "PLEASE READ LICENSE.DOC FOR SHAREWARE",0,2+8+16); + gametext(c,106+9, "DISTRIBUTION GRANTS AND RESTRICTIONS",0,2+8+16); + } + + gametext(c,VOLUMEONE?134:115, "MADE IN DALLAS, TEXAS USA",0,2+8+16); + break; + case 998: + l = 10; + goto cheat_for_port_credits; + } + break; + } + + // Plutonium pak menus + switch(current_menu) + { + case 990: + case 991: + case 992: + rotatesprite(160<<16,200<<15,65536L,0,2504+current_menu-990,0,0,10+64,0,0,xdim-1,ydim-1); + break; + case 993: // JBF 20031220 + rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,0,0,10+64,0,0,xdim-1,ydim-1); + menutext(160,28,0,0,"PORT CREDITS"); + +cheat_for_port_credits: + if (conversion == 13) l = (-2); + gametext(160,38-l,"EDUKE PORT TO JFDUKE, NEW FEATURES,",0,2+8+16); + gametext(160,38+8-l,"FUNCTIONS, AND ENGINE MODIFICATIONS",0,2+8+16); + p = "Richard \"TerminX\" Gobeille, EDuke32 team"; + minitext(160-(Bstrlen(p)<<1), 38+8+10-l, p, 8, 10+16+128); + + gametext(160,70-l,"DUKE3D AND BUILD ENGINE PORTING,",0,2+8+16); + gametext(160,70+8-l, "MODIFICATIONS, AND GENERAL GUIDANCE",0,2+8+16); + p = "Jonathon \"JonoF\" Fowler"; + minitext(160-(Bstrlen(p)<<1), 70+8+10-l, p, 8, 10+16+128); + + gametext(160,102-l,"\"POLYMOST\" OPENGL RENDERER",0,2+8+16); + gametext(160,102+8-l,"NETWORKING, OTHER CODE",0,2+8+16); + p = "Ken Silverman"; + minitext(160-(Bstrlen(p)<<1), 102+8+10-l, p, 8, 10+16+128); + + + // /* for (i=0;i<7;i++) { + // switch (i) { + // case 0: p = "This program is distributed under the terms of the"; break; + // case 1: p = "GNU General Public License version 2 as published by the"; break; + // case 2: p = "Free Software Foundation. See GNU.TXT for details."; break; + // case 3: p = NULL; break; + // case 4: p = "Visit http://www.eduke32.com for the source code,"; break; + // case 5: p = "latest news, and the current version of this port."; break; + // case 6: p = "EDuke originally by Matt Saettler."; break; + // } + // if (!p) continue; + // //minitext(160-(Bstrlen(p)<<1)+1, 110+10+1+(i*7)-l, p, 4, 10+16+128); + // minitext(160-(Bstrlen(p)<<1), 130+10+(i*7)-l, p, /*12*/8, 10+16+128); + // } + // */ + { + const char *scroller[] = { + "This program is distributed under the terms of the", + "GNU General Public License version 2 as published by the", + "Free Software Foundation. See GNU.TXT for details.", + "", + "EDuke originally by Matthew Saettler", + "", + "Thanks to these people for their input and contributions:", + "", + "Ed Coolidge", + "Javier Martinez", + "Jeff Hart", + "Jonathan Smith", + "Jose del Castillo", + "Lachlan McDonald", + "Matthew Palmer", + "Peter Green", + "Pierre-Loup Archambeaud Griffais", + "", + "--x--", + "", + "", + "", + "", + "" + }; + const int numlines = sizeof(scroller)/sizeof(char *); + for (m=0,i=(totalclock/104)%numlines; m<6; m++,i++) { + if (i==numlines) i=0; + minitext(160-(Bstrlen(scroller[i])<<1), 100+10+10+8+4+(m*7)-l, (char*)scroller[i], 8, 10+16+128); + } + } + + for (i=0;i<2;i++) { + switch (i) { + case 0: p = "www.eduke32.com"; break; + case 1: p = ""; break; // fuck I am lazy + } + minitext(160-(Bstrlen(p)<<1), 135+10+10+10+10+4+(i*7)-l, p, 8, 10+16+128); + } + break; + } + break; + + case 0: + c = (320>>1); + rotatesprite(c<<16,28<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1); + if (PLUTOPAK) // JBF 20030804 + rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1); + x = probe(c,67,16,6); + if(x >= 0) + { + if( ud.multimode > 1 && x == 0 && ud.recstat != 2) + { + if( movesperpacket == 4 && myconnectindex != connecthead ) + break; + + last_zero = 0; + cmenu( 600 ); + } + else + { + last_zero = x; + switch(x) + { + case 0: + cmenu(100); + break; + //case 1: break;//cmenu(20001);break; // JBF 20031128: I'm taking over the TEN menu option + case 1: cmenu(202);break; // JBF 20031205: was 200 + case 2: + if(movesperpacket == 4 && connecthead != myconnectindex) + break; + cmenu(300); + break; + case 3: KB_FlushKeyboardQueue();cmenu(400);break; + case 4: cmenu(990);break; + case 5: cmenu(500);break; + } + } + } + + if(KB_KeyPressed(sc_Q)) cmenu(500); + + if(x == -1) + { + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + + if(movesperpacket == 4) + { + if( myconnectindex == connecthead ) + menutext(c,67,SHX(-2),PHX(-2),"NEW GAME"); + else + menutext(c,67,SHX(-2),1,"NEW GAME"); + } + else + menutext(c,67,SHX(-2),PHX(-2),"NEW GAME"); + + // menutext(c,67+16,0,1,"NETWORK GAME"); + + menutext(c,67+16/*+16*/,SHX(-3),PHX(-3),"OPTIONS"); + + if(movesperpacket == 4 && connecthead != myconnectindex) + menutext(c,67+16+16/*+16*/,SHX(-4),1,"LOAD GAME"); + else menutext(c,67+16+16/*+16*/,SHX(-4),PHX(-4),"LOAD GAME"); + + if (!VOLUMEALL) { + + menutext(c,67+16+16+16/*+16*/,SHX(-5),PHX(-5),"HOW TO ORDER"); + } else { + + menutext(c,67+16+16+16/*+16*/,SHX(-5),PHX(-5),"HELP"); + } + + menutext(c,67+16+16+16+16/*+16*/,SHX(-6),PHX(-6),"CREDITS"); + + + menutext(c,67+16+16+16+16+16/*+16*/,SHX(-7),PHX(-7),"QUIT"); + break; + + case 50: + c = (320>>1); + rotatesprite(c<<16,32<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1); + if (PLUTOPAK) // JBF 20030804 + rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1); + x = probe(c,67,16,7); + switch(x) + { + case 0: + if(movesperpacket == 4 && myconnectindex != connecthead) + break; + if(ud.multimode < 2 || ud.recstat == 2) + cmenu(1500); + else + { + cmenu(600); + last_fifty = 0; + } + break; + case 1: + if(movesperpacket == 4 && connecthead != myconnectindex) + break; + if(ud.recstat != 2) + { + last_fifty = 1; + cmenu(350); + setview(0,0,xdim-1,ydim-1); + } + break; + case 2: + if(movesperpacket == 4 && connecthead != myconnectindex) + break; + last_fifty = 2; + cmenu(300); + break; + case 3: + last_fifty = 3; + cmenu(202); // JBF 20031205: was 200 + break; + case 4: + last_fifty = 4; + KB_FlushKeyboardQueue(); + cmenu(400); + break; + case 5: + if(numplayers < 2) + { + last_fifty = 5; + cmenu(501); + } + break; + case 6: + last_fifty = 6; + cmenu(500); + break; + case -1: + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + break; + } + + if( KB_KeyPressed(sc_Q) ) + cmenu(500); + + if(movesperpacket == 4 && connecthead != myconnectindex) + { + menutext(c,67 ,SHX(-2),1,"NEW GAME"); + menutext(c,67+16 ,SHX(-3),1,"SAVE GAME"); + menutext(c,67+16+16 ,SHX(-4),1,"LOAD GAME"); + } + else + { + menutext(c,67 ,SHX(-2),PHX(-2),"NEW GAME"); + menutext(c,67+16 ,SHX(-3),PHX(-3),"SAVE GAME"); + menutext(c,67+16+16 ,SHX(-4),PHX(-4),"LOAD GAME"); + } + + menutext(c,67+16+16+16 ,SHX(-5),PHX(-5),"OPTIONS"); + if (!VOLUMEALL) { + menutext(c,67+16+16+16+16 ,SHX(-6),PHX(-6),"HOW TO ORDER"); + } else { + menutext(c,67+16+16+16+16 ,SHX(-6),PHX(-6)," HELP"); + } + if(numplayers > 1) + menutext(c,67+16+16+16+16+16 ,SHX(-7),1,"QUIT TO TITLE"); + else menutext(c,67+16+16+16+16+16 ,SHX(-7),PHX(-7),"QUIT TO TITLE"); + menutext(c,67+16+16+16+16+16+16,SHX(-8),PHX(-8),"QUIT GAME"); + break; + + case 100: + rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,24,0,0,"SELECT AN EPISODE"); + // if(boardfilename[0]) + if (PLUTOPAK) + x = probe(160,60-(num_volumes*2),20,num_volumes+1); + // else x = probe(160,60,20,4); + // if(boardfilename[0]) + else + x = probe(160,VOLUMEONE?60:60-(num_volumes*2),20,VOLUMEONE?3:num_volumes+1); + // else x = probe(160,60,20,3); + if(x >= 0) + { + if (VOLUMEONE) { + if(x > 0) + cmenu(20000); + else + { + ud.m_volume_number = x; + ud.m_level_number = 0; + last_onehundred = x; + cmenu(110); + } + } + + if (!VOLUMEONE) { + if(x == num_volumes /*&& boardfilename[0]*/) + { + //ud.m_volume_number = 0; + //ud.m_level_number = 7; + currentlist = 1; + last_onehundred = x; + cmenu(101); + } + else + { + ud.m_volume_number = x; + ud.m_level_number = 0; + last_onehundred = x; + cmenu(110); + } + } + } + else if(x == -1) + { + if(ps[myconnectindex].gm&MODE_GAME) cmenu(50); + else cmenu(0); + } + + + + c = 80; + if (VOLUMEONE) { + menutext(160,60,SHX(-2),PHX(-2),volume_names[0]); + menutext(160,60+20,SHX(-3),1,volume_names[1]); + menutext(160,60+20+20,SHX(-4),1,volume_names[2]); + if (PLUTOPAK) + menutext(160,60+20+20,SHX(-5),1,volume_names[3]); + } else { + for (i=0;i 0) + { + while(KB_KeyPressed(sc_End)?seeker->next:seeker->prev) + seeker = KB_KeyPressed(sc_End)?seeker->next:seeker->prev; + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + sound(KICK_HIT); + } + } + else if((KB_KeyPressed(sc_PgUp)|KB_KeyPressed(sc_PgDn)) > 0) + { + seeker = currentlist?findfileshigh:finddirshigh; + i = 6; + while(i>0) { + if(KB_KeyPressed(sc_PgDn)?seeker->next:seeker->prev) + seeker = KB_KeyPressed(sc_PgDn)?seeker->next:seeker->prev; + i--; + } + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + sound(KICK_HIT); + } + } + else + { + char ch2, ch; + ch = KB_Getch(); + if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) { + if (ch >= 'a') ch -= ('a'-'A'); + while (seeker) { + ch2 = seeker->name[0]; + if (ch2 >= 'a' && ch2 <= 'z') ch2 -= ('a'-'A'); + if (ch2 == ch) break; + seeker = seeker->next; + } + if (seeker) { + if (currentlist) findfileshigh = seeker; + else finddirshigh = seeker; + sound(KICK_HIT); + } + } + } + } + gametext(40+4,12+32,"DIRECTORIES",0,2+8+16); + + if (finddirshigh) { + dir = finddirshigh; + for(i=0; i<2; i++) if (!dir->prev) break; else dir=dir->prev; + for(i=2; i>-2 && dir; i--, dir=dir->next) { + if (dir == finddirshigh) c=0; else c=16; + minitextshade(40,1+12+32+8*(3-i),dir->name,c,0,26); + } + } + + gametext(40+4,8+32+40+8-1,"MAP FILES",0,2+8+16); + + if (findfileshigh) { + dir = findfileshigh; + for(i=0; i<4; i++) if (!dir->prev) break; else dir=dir->prev; + for(i=4; i>-4 && dir; i--, dir=dir->next) { + if (dir == findfileshigh) c=0; else c=16; + minitextshade(40,(8+32+8*5)+8*(6-i),dir->name,c,2,26); + } + } + + if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) || + KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) || + KB_KeyPressed( sc_Tab ) ) + { + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + KB_ClearKeyDown( sc_Tab ); + currentlist = 1-currentlist; + sound(KICK_HIT); + } + + onbar = 0; + probey = 2; + if (currentlist == 0) x = probe(50,12+32+16+4,0,3); + else x = probe(50,8+32+40+40+4,0,3); + + if (probey == 1) { + if (currentlist == 0) { + if (finddirshigh) + if (finddirshigh->prev) finddirshigh = finddirshigh->prev; + } else { + if (findfileshigh) + if (findfileshigh->prev) findfileshigh = findfileshigh->prev; + } + } else if (probey == 0) { + if (currentlist == 0) { + if (finddirshigh) + if (finddirshigh->next) finddirshigh = finddirshigh->next; + } else { + if (findfileshigh) + if (findfileshigh->next) findfileshigh = findfileshigh->next; + } + } + + if(x == -1) { + cmenu(100); + clearfilenames(); + boardfilename[0] = 0; + } + else if(x >= 0) + { + if (currentlist == 0) { + if (!finddirshigh) break; + strcat(boardfilename, finddirshigh->name); + strcat(boardfilename, "/"); + Bcorrectfilename(boardfilename, 1); + cmenu(101); + KB_FlushKeyboardQueue(); + } else { + if (!findfileshigh) break; + strcat(boardfilename, findfileshigh->name); + ud.m_volume_number = 0; + ud.m_level_number = 7; + cmenu(110); + } + clearfilenames(); + } + break; + + + + case 110: + c = (320>>1); + rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(c,24,0,0,"SELECT SKILL"); + x = probe(c,70,19,4); + if(x >= 0) + { + switch(x) + { + case 0: globalskillsound = JIBBED_ACTOR6;break; + case 1: globalskillsound = BONUS_SPEECH1;break; + case 2: globalskillsound = DUKE_GETWEAPON2;break; + case 3: globalskillsound = JIBBED_ACTOR5;break; + } + + sound(globalskillsound); + + ud.m_player_skill = x+1; + if(x == 3) ud.m_respawn_monsters = 1; + else ud.m_respawn_monsters = 0; + + ud.m_monsters_off = ud.monsters_off = 0; + + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + + ud.multimode = 1; + + if(ud.m_volume_number == 3) + { + flushperms(); + setview(0,0,xdim-1,ydim-1); + clearview(0L); + nextpage(); + } + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill); + if (enterlevel(MODE_GAME)) backtomenu(); + } + else if(x == -1) + { + cmenu(100); + KB_FlushKeyboardQueue(); + } + + menutext(c,70,SHX(-2),PHX(-2),skill_names[0]); + menutext(c,70+19,SHX(-3),PHX(-3),skill_names[1]); + menutext(c,70+19+19,SHX(-4),PHX(-4),skill_names[2]); + menutext(c,70+19+19+19,SHX(-5),PHX(-5),skill_names[3]); + break; + + case 200: + + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"GAME OPTIONS"); + + c = (320>>1)-120; + + { + int io, ii, yy, d=c+160+40, enabled; + char *opts[] = { + "Crosshair", + "Level stats", + "Status bar size", + "-", + "Mouse aiming type", + "Mouse aiming toggle", + "Invert mouse aim", + "Auto-aiming", + "Run key style", + "Auto weapon switching", + "-", + "Screen size", + "Detail", + "Shadows", + "Screen tilting", + "-", + "Record demo", + "-", + "More...", + NULL + }; + + yy = 34; + for (ii=io=0; opts[ii]; ii++) { + if (opts[ii][0] == '-' && !opts[ii][1]) { + if (io <= probey) yy += 4; + continue; + } + if (io < probey) yy += 8; + io++; + } + + onbar = (probey == 2 || probey == 9); + x = probesm(c,yy+5,0,io); + + if (x == -1) { cmenu(202); break; } + + yy = 34; + for (ii=io=0; opts[ii]; ii++) { + if (opts[ii][0] == '-' && !opts[ii][1]) { + yy += 4; + continue; + } + enabled = 1; + switch (io) { + case 0: if (x==io) ud.crosshair = 1-ud.crosshair; + modval(0,1,(int *)&ud.crosshair,1,probey==0); + gametextpal(d,yy, ud.crosshair ? "On" : "Off", 0, 0); break; + case 1: if (x==io) ud.levelstats = 1-ud.levelstats; + modval(0,1,(int *)&ud.levelstats,1,probey==1); + gametextpal(d,yy, ud.levelstats ? "Shown" : "Hidden", 0, 0); break; + case 2: + { + short sbs, sbsl; + sbs = sbsl = scale(max(0,ud.statusbarscale-50),63,100-50); + barsm(d+8,yy+7, (short *)&sbs,9,x==io,SHX(-5),PHX(-5)); + if (x == io && sbs != sbsl) { + sbs = scale(sbs,100-50,63)+50; + setstatusbarscale(sbs); + } + } + break; + case 3: if (ps[myconnectindex].gm&MODE_GAME || numplayers > 1) enabled = 0; + if (enabled && x==io) ud.mouseaiming = !ud.mouseaiming; + if (enabled) modval(0,1,(int *)&ud.mouseaiming,1,probey==3); + // don't change when in a multiplayer game + // because the state is sent during getnames() + // however, this will be fixed later + gametextpal(d,yy, ud.mouseaiming ? "Held" : "Toggle", enabled?0:10, 0); break; + case 4: enabled = !ud.mouseaiming; + if (enabled && x==io) myaimmode = 1-myaimmode; + if (enabled) modval(0,1,(int *)&myaimmode,1,probey==4); + gametextpal(d,yy, myaimmode && enabled ? "On" : "Off", enabled?0:10, 0); break; + case 5: if (x==io) ud.mouseflip = 1-ud.mouseflip; + modval(0,1,(int *)&ud.mouseflip,1,probey==5); + gametextpal(d,yy, ud.mouseflip ? "On" : "Off", 0, 0); break; + case 6: if (ps[myconnectindex].gm&MODE_GAME || numplayers > 1) enabled = 0; + if (enabled && x==io) AutoAim = 1-AutoAim; + if (enabled) modval(0,1,(int *)&AutoAim,1,probey==6); + gametextpal(d,yy, AutoAim ? "On" : "Off", enabled?0:10, 0); break; + case 7: if (x==io) ud.runkey_mode = 1-ud.runkey_mode; + modval(0,1,(int *)&ud.runkey_mode,1,probey==7); + gametextpal(d,yy, ud.runkey_mode ? "Classic" : "Modern", 0, 0); break; + case 8: if (ps[myconnectindex].gm&MODE_GAME || numplayers > 1) enabled = 0; + if (enabled && x==io) { ud.weaponswitch = (ud.weaponswitch == 3) ? 0 : ud.weaponswitch+1; } + if (enabled) modval(0,3,(int *)&ud.weaponswitch,1,probey==8); + { char *s[] = { "Off", "Pickup", "Empty", "Both" }; + gametextpal(d,yy, s[ud.weaponswitch], enabled?0:10, 0); break; } + break; + case 9: barsm(d+8,yy+7, (short *)&ud.screen_size,-4,x==io,SHX(-5),PHX(-5)); break; + case 10: if (x==io) ud.detail = 1-ud.detail; + modval(0,1,(int *)&ud.detail,1,probey==10); + gametextpal(d,yy, ud.detail ? "High" : "Low", 0, 0); break; + case 11: if (x==io) ud.shadows = 1-ud.shadows; + modval(0,1,(int *)&ud.shadows,1,probey==11); + gametextpal(d,yy, ud.shadows ? "On" : "Off", 0, 0); break; + case 12: if (x==io) ud.screen_tilting = 1-ud.screen_tilting; + modval(0,1,(int *)&ud.screen_tilting,1,probey==12); + gametextpal(d,yy, ud.screen_tilting ? "On" : "Off", 0, 0); break; // original had a 'full' option + case 13: if (x==io) { + enabled = !((ps[myconnectindex].gm&MODE_GAME) && ud.m_recstat != 1); + if( (ps[myconnectindex].gm&MODE_GAME) ) closedemowrite(); + else ud.m_recstat = !ud.m_recstat; + } + if( (ps[myconnectindex].gm&MODE_GAME) && ud.m_recstat != 1 ) + enabled = 0; + gametextpal(d,yy, ud.m_recstat ? ((ud.m_recstat && enabled && ps[myconnectindex].gm&MODE_GAME) ? "Recording" : "On") : "Off", 0, !enabled ? 1 : 0); break; + case 14: if (x==io) cmenu(201); break; + default: break; + } + gametextpal(c,yy, opts[ii], enabled?5:15, 2); + io++; + yy += 8; + } + } + break; + + case 201: + + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"GAME OPTIONS"); + + c = (320>>1)-120; + + { + int io, ii, yy, d=c+160+40, enabled; + char *opts[] = { + "HUD weapon", + "FPS counter", + "-", + "Hightile textures", + "Precache textures", + "GL texture compression", + "Cache textures on disk", + "Compress disk cache", + "-", + "Models", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "-", + "Previous page", + NULL + }; + + yy = 34; + for (ii=io=0; opts[ii]; ii++) { + if (opts[ii][0] == '-' && !opts[ii][1]) { + if (io <= probey) yy += 4; + continue; + } + if (io < probey) yy += 8; + io++; + } + + onbar = (probey == 2 || probey == 9); + x = probesm(c,yy+5,0,io); + + if (x == -1) { cmenu(202); break; } + + yy = 34; + for (ii=io=0; opts[ii]; ii++) { + if (opts[ii][0] == '-' && !opts[ii][1]) { + yy += 4; + continue; + } + enabled = 1; + switch (io) { + case 0: if (x==io) ud.drawweapon = 1-ud.drawweapon; + modval(0,1,(int *)&ud.drawweapon,1,probey==0); + gametextpal(d,yy, ud.drawweapon ? "On" : "Off", 0, 0); break; + case 1: if (x==io) ud.tickrate = 1-ud.tickrate; + modval(0,1,(int *)&ud.tickrate,1,probey==1); + gametextpal(d,yy, ud.tickrate ? "On" : "Off", 0, 0); break; + case 2: if (x==io) usehightile = 1-usehightile; + modval(0,1,(int *)&usehightile,1,probey==2); + gametextpal(d,yy, usehightile ? "On" : "Off", 0, 0); break; + case 3: enabled = usehightile; + if (enabled && x==io) useprecache = !useprecache; + if (enabled) modval(0,1,(int *)&useprecache,1,probey==3); + // don't change when in a multiplayer game + // because the state is sent during getnames() + // however, this will be fixed later + gametextpal(d,yy, useprecache && enabled ? "On" : "Off", enabled?0:10, 0); break; + case 4: enabled = usehightile; + if (enabled && x==io) glusetexcompr = !glusetexcompr; + if (enabled) modval(0,1,(int *)&glusetexcompr,1,probey==4); + gametextpal(d,yy, glusetexcompr && enabled ? "On" : "Off", enabled?0:10, 0); break; + case 5: enabled = (glusetexcompr && usehightile && useprecache); + if (enabled && x==io) glusetexcache = !glusetexcache; + if (enabled) modval(0,1,(int *)&glusetexcache,1,probey==5); + gametextpal(d,yy, glusetexcache && enabled ? "On" : "Off", enabled?0:10, 0); break; + case 6: enabled = (glusetexcompr && usehightile && useprecache && glusetexcache); + if (enabled && x==io) glusetexcachecompression = !glusetexcachecompression; + if (enabled) modval(0,1,(int *)&glusetexcachecompression,1,probey==6); + gametextpal(d,yy, glusetexcachecompression && enabled ? "On" : "Off", enabled?0:10, 0); break; + case 7: if (x==io) usemodels = 1-usemodels; + modval(0,1,(int *)&usemodels,1,probey==7); + gametextpal(d,yy, usemodels ? "On" : "Off", 0, 0); break; + case 8: if (x==io) cmenu(200); break; + default: break; + } + gametextpal(c,yy, opts[ii], enabled?5:15, 2); + io++; + yy += 8; + } + } + break; + + // JBF 20031205: Second level options menu selection + case 202: + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"OPTIONS"); + + c = 200>>1; + + onbar = 0; + x = probe(160,c-18-18-18,18,7); + + switch (x) { + case -1: + if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);else cmenu(0); + break; + + case 0: + cmenu(200); + break; + + case 1: + cmenu(700); + break; + + case 2: + { + int dax = xdim, day = ydim, daz; + curvidmode = newvidmode = checkvideomode(&dax,&day,bpp,fullscreen); + if (newvidmode == 0x7fffffffl) newvidmode = validmodecnt; + newfullscreen = fullscreen; + changesmade = 0; + + dax = 0; + for (day = 0; day < validmodecnt; day++) { + if (dax == sizeof(vidsets)/sizeof(vidsets[1])) break; + for (daz = 0; daz < dax; daz++) + if ((validmode[day].bpp|((validmode[day].fs&1)<<16)) == (vidsets[daz]&0x1ffffl)) break; + if (vidsets[daz] != -1) continue; + if (validmode[day].bpp == 8) { + vidsets[dax++] = 8|((validmode[day].fs&1)<<16); + vidsets[dax++] = 0x20000|8|((validmode[day].fs&1)<<16); + } else + vidsets[dax++] = 0x20000|validmode[day].bpp|((validmode[day].fs&1)<<16); + } + for (dax = 0; dax < (long)(sizeof(vidsets)/sizeof(vidsets[1])) && vidsets[dax] != -1; dax++) + if (vidsets[dax] == (((getrendermode()>=2)<<17)|(fullscreen<<16)|bpp)) break; + if (dax < (long)(sizeof(vidsets)/sizeof(vidsets[1]))) newvidset = dax; + curvidset = newvidset; + + cmenu(203); + } + break; + + case 3: + currentlist = 0; + case 4: + case 5: + if (x==5 && (!CONTROL_JoystickEnabled || !CONTROL_JoyPresent)) break; + cmenu(204+x-3); + break; + + case 6: +#ifndef AUSTRALIA + cmenu(10000); +#endif + break; + } + + menutext(160,c-18-18-18,0,0,"GAME OPTIONS"); + menutext(160,c-18-18, 0,0,"SOUND OPTIONS"); + menutext(160,c-18, 0,0,"VIDEO SETTINGS"); + menutext(160,c, 0,0,"KEYBOARD SETUP"); + menutext(160,c+18, 0,0,"MOUSE SETUP"); + menutext(160,c+18+18, 0,CONTROL_JoyPresent==0 || CONTROL_JoystickEnabled==0,"JOYSTICK SETUP"); + menutext(160,c+18+18+18,0,0,"PARENTAL LOCK"); + break; + + // JBF 20031206: Video settings menu + case 203: + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"VIDEO SETTINGS"); + + c = (320>>1)-120; + +#if defined(POLYMOST) && defined(USE_OPENGL) + x = 7; +#else + x = 5; +#endif + onbar = (probey == 4); + if (probey == 0 || probey == 1 || probey == 2) + x = probe(c+6,50,16,x); + else if (probey == 3) + x = probe(c+6,50+16+16+22,0,x); + else + x = probe(c+6,50+62-16-16-16,16,x); + + if (probey==0 && (KB_KeyPressed(sc_LeftArrow) || KB_KeyPressed(sc_RightArrow))) { + sound(PISTOL_BODYHIT); + x=0; + } + switch (x) { + case -1: + cmenu(202); + probey = 2; + break; + + case 0: + do { + if (KB_KeyPressed(sc_LeftArrow)) { + newvidmode--; + if (newvidmode < 0) newvidmode = validmodecnt-1; + } else { + newvidmode++; + if (newvidmode >= validmodecnt) newvidmode = 0; + } + } while ((validmode[newvidmode].fs&1) != ((vidsets[newvidset]>>16)&1) || validmode[newvidmode].bpp != (vidsets[newvidset] & 0x0ffff)); + //OSD_Printf("New mode is %dx%dx%d-%d %d\n",validmode[newvidmode].xdim,validmode[newvidmode].ydim,validmode[newvidmode].bpp,validmode[newvidmode].fs,newvidmode); + if ((curvidmode == 0x7fffffffl && newvidmode == validmodecnt) || curvidmode == newvidmode) + changesmade &= ~1; + else + changesmade |= 1; + KB_ClearKeyDown(sc_LeftArrow); + KB_ClearKeyDown(sc_RightArrow); + break; + + case 1: + { + int lastvidset, lastvidmode, safevidmode = -1; + lastvidset = newvidset; + lastvidmode = newvidmode; + // find the next vidset compatible with the current fullscreen setting + while (vidsets[0] != -1) { + newvidset++; + if (newvidset == sizeof(vidsets)/sizeof(vidsets[0]) || vidsets[newvidset] == -1) { newvidset = -1; continue; } + if (((vidsets[newvidset]>>16)&1) != newfullscreen) continue; + break; + } + + if ((vidsets[newvidset] & 0x0ffff) != (vidsets[lastvidset] & 0x0ffff)) { + // adjust the video mode to something legal for the new vidset + do { + newvidmode++; + if (newvidmode == lastvidmode) break; // end of cycle + if (newvidmode >= validmodecnt) newvidmode = 0; + if (validmode[newvidmode].bpp == (vidsets[newvidset]&0x0ffff) && + validmode[newvidmode].fs == newfullscreen && + validmode[newvidmode].xdim <= validmode[lastvidmode].xdim && + (safevidmode==-1?1:(validmode[newvidmode].xdim>=validmode[safevidmode].xdim)) && + validmode[newvidmode].ydim <= validmode[lastvidmode].ydim && + (safevidmode==-1?1:(validmode[newvidmode].ydim>=validmode[safevidmode].ydim)) + ) + safevidmode = newvidmode; + } while (1); + if (safevidmode == -1) { + //OSD_Printf("No best fit!\n"); + newvidmode = lastvidmode; + newvidset = lastvidset; + } else { + //OSD_Printf("Best fit is %dx%dx%d-%d %d\n",validmode[safevidmode].xdim,validmode[safevidmode].ydim,validmode[safevidmode].bpp,validmode[safevidmode].fs,safevidmode); + newvidmode = safevidmode; + } + } + if (newvidset != curvidset) changesmade |= 4; else changesmade &= ~4; + if (newvidmode != curvidmode) changesmade |= 1; else changesmade &= ~1; + } + break; + + case 2: + newfullscreen = !newfullscreen; + { + int lastvidset, lastvidmode, safevidmode = -1, safevidset = -1; + lastvidset = newvidset; + lastvidmode = newvidmode; + // find the next vidset compatible with the current fullscreen setting + while (vidsets[0] != -1) { + newvidset++; + if (newvidset == lastvidset) break; + if (newvidset == sizeof(vidsets)/sizeof(vidsets[0]) || vidsets[newvidset] == -1) { newvidset = -1; continue; } + if (((vidsets[newvidset]>>16)&1) != newfullscreen) continue; + if ((vidsets[newvidset] & 0x2ffff) != (vidsets[lastvidset] & 0x2ffff)) { + if ((vidsets[newvidset] & 0x20000) == (vidsets[lastvidset] & 0x20000)) safevidset = newvidset; + continue; + } + break; + } + if (newvidset == lastvidset) { + if (safevidset == -1) { + newfullscreen = !newfullscreen; + break; + } else { + newvidset = safevidset; + } + } + + // adjust the video mode to something legal for the new vidset + do { + newvidmode++; + if (newvidmode == lastvidmode) break; // end of cycle + if (newvidmode >= validmodecnt) newvidmode = 0; + if (validmode[newvidmode].bpp == (vidsets[newvidset]&0x0ffff) && + validmode[newvidmode].fs == newfullscreen && + validmode[newvidmode].xdim <= validmode[lastvidmode].xdim && + (safevidmode==-1?1:(validmode[newvidmode].xdim>=validmode[safevidmode].xdim)) && + validmode[newvidmode].ydim <= validmode[lastvidmode].ydim && + (safevidmode==-1?1:(validmode[newvidmode].ydim>=validmode[safevidmode].ydim)) + ) + safevidmode = newvidmode; + } while (1); + if (safevidmode == -1) { + //OSD_Printf("No best fit!\n"); + newvidmode = lastvidmode; + newvidset = lastvidset; + newfullscreen = !newfullscreen; + } else { + //OSD_Printf("Best fit is %dx%dx%d-%d %d\n",validmode[safevidmode].xdim,validmode[safevidmode].ydo,,validmode[safevidmode].bpp,validmode[safevidmode].fs,safevidmode); + newvidmode = safevidmode; + } + if (newvidset != curvidset) changesmade |= 4; else changesmade &= ~4; + if (newvidmode != curvidmode) changesmade |= 1; else changesmade &= ~1; + } + if (newfullscreen == fullscreen) changesmade &= ~2; else changesmade |= 2; + break; + + case 3: + if (!changesmade) break; + { + long pxdim, pydim, pfs, pbpp, prend; + long nxdim, nydim, nfs, nbpp, nrend; + + pxdim = xdim; pydim = ydim; pbpp = bpp; pfs = fullscreen; prend = getrendermode(); + nxdim = (newvidmode==validmodecnt)?xdim:validmode[newvidmode].xdim; + nydim = (newvidmode==validmodecnt)?ydim:validmode[newvidmode].ydim; + nfs = newfullscreen; + nbpp = (newvidmode==validmodecnt)?bpp:validmode[newvidmode].bpp; + nrend = (vidsets[newvidset] & 0x20000) ? (nbpp==8?2:3) : 0; + + if (setgamemode(nfs, nxdim, nydim, nbpp) < 0) { + if (setgamemode(pfs, pxdim, pydim, pbpp) < 0) { + setrendermode(prend); + gameexit("Failed restoring old video mode."); + } else onvideomodechange(pbpp > 8); + } else onvideomodechange(nbpp > 8); + vscrn(); + setrendermode(nrend); + + curvidmode = newvidmode; curvidset = newvidset; + changesmade = 0; + + ScreenMode = fullscreen; + ScreenWidth = xdim; + ScreenHeight = ydim; + ScreenBPP = bpp; + } + break; + + case 4: + break; + +#if defined(POLYMOST) && defined(USE_OPENGL) + case 5: + if (bpp==8) break; + switch (gltexfiltermode) { + case 0: gltexfiltermode = 3; break; + case 3: gltexfiltermode = 5; break; + case 5: gltexfiltermode = 0; break; + default: gltexfiltermode = 3; break; + } + gltexapplyprops(); + break; + + case 6: + if (bpp==8) break; + glanisotropy *= 2; + if (glanisotropy > glinfo.maxanisotropy) glanisotropy = 1; + gltexapplyprops(); + break; +#endif + } + + menutext(c,50,0,0,"RESOLUTION"); + sprintf(tempbuf,"%ld x %ld", + (newvidmode==validmodecnt)?xdim:validmode[newvidmode].xdim, + (newvidmode==validmodecnt)?ydim:validmode[newvidmode].ydim); + gametext(c+154,50-8,tempbuf,0,2+8+16); + + menutext(c,50+16,0,0,"VIDEO MODE"); + sprintf(tempbuf, "%dbit %s", vidsets[newvidset]&0x0ffff, (vidsets[newvidset]&0x20000)?"Polymost":"Classic"); + gametext(c+154,50+16-8,tempbuf,0,2+8+16); + + menutext(c,50+16+16,0,0,"FULLSCREEN"); + menutext(c+154,50+16+16,0,0,newfullscreen?"YES":"NO"); + + menutext(c+16,50+16+16+22,0,changesmade==0,"APPLY CHANGES"); + + menutext(c,50+62+16,SHX(-6),PHX(-6),"BRIGHTNESS"); + { + short ss = ud.brightness; + bar(c+167,50+62+16,&ss,8,x==4,SHX(-6),PHX(-6)); + if(x==4) { + ud.brightness = ss; + setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0],0); + } + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + menutext(c,50+62+16+16,0,bpp==8,"FILTERING"); + switch (gltexfiltermode) { + case 0: strcpy(tempbuf,"NEAREST"); break; + case 3: strcpy(tempbuf,"BILINEAR"); break; + case 5: strcpy(tempbuf,"TRILINEAR"); break; + default: strcpy(tempbuf,"OTHER"); break; + } + menutext(c+154,50+62+16+16,0,bpp==8,tempbuf); + + menutext(c,50+62+16+16+16,0,bpp==8,"ANISOTROPY"); + if (glanisotropy == 1) strcpy(tempbuf,"NONE"); + else sprintf(tempbuf,"%ld-tap",glanisotropy); + menutext(c+154,50+62+16+16+16,0,bpp==8,tempbuf); +#endif + break; + + case 204: + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"KEYS SETUP"); + + c = (320>>1)-120; + + onbar = 0; + x = probe(0,0,0,NUMGAMEFUNCTIONS); + + if (x==-1) { + cmenu(202); + probey = 3; + } else if (x>=0) { + function = probey; + whichkey = currentlist; + cmenu(210); + KB_FlushKeyboardQueue(); + KB_ClearLastScanCode(); + break; + } + + // the top of our list + m = probey - 6; + if (m < 0) m = 0; + else if (m + 13 >= NUMGAMEFUNCTIONS) m = NUMGAMEFUNCTIONS-13; + + if (probey == gamefunc_Show_Console) currentlist = 0; + else if (KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || + KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || + KB_KeyPressed( sc_Tab )) { + currentlist ^= 1; + KB_ClearKeyDown( sc_LeftArrow ); + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_4 ); + KB_ClearKeyDown( sc_kpad_6 ); + KB_ClearKeyDown( sc_Tab ); + sound(KICK_HIT); + } else if (KB_KeyPressed( sc_Delete )) { + KeyboardKeys[probey][currentlist] = 0; + CONTROL_MapKey( probey, KeyboardKeys[probey][0], KeyboardKeys[probey][1] ); + sound(KICK_HIT); + KB_ClearKeyDown( sc_Delete ); + } + + for (l=0; l < min(13,NUMGAMEFUNCTIONS); l++) { + p = CONFIG_FunctionNumToName(m+l); + if (!p) continue; + + strcpy(tempbuf, p); + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitextshade(70,34+l*8,tempbuf,(m+l == probey)?0:16,1,10+16); + + //strcpy(tempbuf, KB_ScanCodeToString(KeyboardKeys[m+l][0])); + strcpy(tempbuf, getkeyname(KeyboardKeys[m+l][0])); + if (!tempbuf[0]) strcpy(tempbuf, " -"); + minitextshade(70+100,34+l*8,tempbuf, + (m+l == probey && !currentlist?0:16),2,10+16); + + //strcpy(tempbuf, KB_ScanCodeToString(KeyboardKeys[m+l][1])); + strcpy(tempbuf, getkeyname(KeyboardKeys[m+l][1])); + if (!tempbuf[0]) strcpy(tempbuf, " -"); + minitextshade(70+120+34,34+l*8,tempbuf, + (m+l == probey && currentlist?0:16),2,10+16); + } + + gametext(160,144,"UP/DOWN = SELECT ACTION",0,2+8+16); + gametext(160,144+9,"LEFT/RIGHT = SELECT LIST",0,2+8+16); + gametext(160,144+9+9,"ENTER = MODIFY DELETE = CLEAR",0,2+8+16); + + break; + + case 210: { + int32 sc; + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"KEYS SETUP"); + + gametext(320>>1,90,"PRESS THE KEY TO ASSIGN AS",0,2+8+16); + sprintf(tempbuf,"%s FOR \"%s\"", whichkey?"SECONDARY":"PRIMARY", CONFIG_FunctionNumToName(function)); + gametext(320>>1,90+9,tempbuf,0,2+8+16); + gametext(320>>1,90+9+9+9,"PRESS \"ESCAPE\" TO CANCEL",0,2+8+16); + + sc = KB_GetLastScanCode(); + if ( sc != sc_None ) { + if ( sc == sc_Escape ) { + sound(EXITMENUSOUND); + } else { + sound(PISTOL_BODYHIT); + + KeyboardKeys[function][whichkey] = KB_GetLastScanCode(); + if (function == gamefunc_Show_Console) + OSD_CaptureKey(KB_GetLastScanCode()); + else + CONTROL_MapKey( function, KeyboardKeys[function][0], KeyboardKeys[function][1] ); + } + + cmenu(204); + + currentlist = whichkey; + probey = function; + + KB_ClearKeyDown(sc); + } + + break; + } + case 205: + rotatesprite(320<<15,10<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,15,0,0,"MOUSE SETUP"); + + c = 60-4; + + onbar = (probey == (MAXMOUSEBUTTONS-2)*2+2); + if (probey < (MAXMOUSEBUTTONS-2)*2+2) + x = probe(0,0,0,(MAXMOUSEBUTTONS-2)*2+2+2); + else + x = probe(c+6,125-((MAXMOUSEBUTTONS-2)*2+2)*16,16,(MAXMOUSEBUTTONS-2)*2+2+2); + + if (x==-1) { + cmenu(202); + probey = 4; + break; + } else if (x == (MAXMOUSEBUTTONS-2)*2+2) { + // sensitivity + } else if (x == (MAXMOUSEBUTTONS-2)*2+2+1) { + //advanced + cmenu(212); + break; + } else if (x >= 0) { + //set an option + cmenu(211); + function = 0; + whichkey = x; + if (x < (MAXMOUSEBUTTONS-2)*2) + probey = MouseFunctions[x>>1][x&1]; + else + probey = MouseFunctions[x-4][0]; + if (probey < 0) probey = NUMGAMEFUNCTIONS-1; + break; + } + + for (l=0; l < (MAXMOUSEBUTTONS-2)*2+2; l++) { + tempbuf[0] = 0; + if (l < (MAXMOUSEBUTTONS-2)*2) { + if (l&1) { + Bstrcpy(tempbuf, "Double "); + m = MouseFunctions[l>>1][1]; + } else + m = MouseFunctions[l>>1][0]; + Bstrcat(tempbuf, mousebuttonnames[l>>1]); + } else { + Bstrcpy(tempbuf, mousebuttonnames[l-(MAXMOUSEBUTTONS-2)]); + m = MouseFunctions[l-(MAXMOUSEBUTTONS-2)][0]; + } + + minitextshade(c+20,30+l*8,tempbuf,(l==probey)?0:16,1,10+16); + + if (m == -1) + minitextshade(c+100+20,30+l*8," -NONE-",(l==probey)?0:16,2,10+16); + else { + strcpy(tempbuf, CONFIG_FunctionNumToName(m)); + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitextshade(c+100+20,30+l*8,tempbuf,(l==probey)?0:16,2,10+16); + } + } + + { + short sense; + sense = CONTROL_GetMouseSensitivity()>>10; + + menutext(c,125,SHX(-7),PHX(-7),"SENSITIVITY"); + bar(c+167,125,&sense,4,x==(MAXMOUSEBUTTONS-2)*2+2,SHX(-7),PHX(-7)); + CONTROL_SetMouseSensitivity( sense<<10 ); + } + + menutext(c,125+16,0,0,"ADVANCED..."); + + if (probey < (MAXMOUSEBUTTONS-2)*2+2) { + gametext(160,149,"UP/DOWN = SELECT BUTTON",0,2+8+16); + gametext(160,149+9,"ENTER = MODIFY",0,2+8+16); + } + break; + + case 211: + rotatesprite(320<<15,10<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + if (function == 0) menutext(320>>1,15,0,0,"MOUSE SETUP"); + else if (function == 1) menutext(320>>1,15,0,0,"ADVANCED MOUSE"); + else if (function == 2) menutext(320>>1,15,0,0,"JOYSTICK BUTTONS"); + else if (function == 3) menutext(320>>1,15,0,0,"JOYSTICK AXES"); + + x = probe(0,0,0,NUMGAMEFUNCTIONS); + + if (x==-1) { + if (function == 0) { // mouse button + cmenu(205); + probey = whichkey; + } else if (function == 1) { // mouse digital axis + cmenu(212); + probey = 2+(whichkey^2); + } else if (function == 2) { // joystick button/hat + cmenu(207); + probey = whichkey; + } else if (function == 3) { // joystick digital axis + cmenu((whichkey>>2)+208); + probey = 1+((whichkey>>1)&1)*4+(whichkey&1); + } + break; + } else if (x >= 0) { + if (x == NUMGAMEFUNCTIONS-1) x = -1; + + if (function == 0) { + if (whichkey < (MAXMOUSEBUTTONS-2)*2) { + MouseFunctions[whichkey>>1][whichkey&1] = x; + CONTROL_MapButton( x, whichkey>>1, whichkey&1, controldevice_mouse); + } else { + MouseFunctions[whichkey-(MAXMOUSEBUTTONS-2)][0] = x; + CONTROL_MapButton( x, whichkey-(MAXMOUSEBUTTONS-2), 0, controldevice_mouse); + } + cmenu(205); + probey = whichkey; + } else if (function == 1) { + MouseDigitalFunctions[whichkey>>1][whichkey&1] = x; + CONTROL_MapDigitalAxis(whichkey>>1, x, whichkey&1, controldevice_mouse); + cmenu(212); + probey = 2+(whichkey^2); + } else if (function == 2) { + if (whichkey < 2*joynumbuttons) { + JoystickFunctions[whichkey>>1][whichkey&1] = x; + CONTROL_MapButton( x, whichkey>>1, whichkey&1, controldevice_joystick); + } else { + JoystickFunctions[joynumbuttons + (whichkey-2*joynumbuttons)][0] = x; + CONTROL_MapButton( x, joynumbuttons + (whichkey-2*joynumbuttons), 0, controldevice_joystick); + } + cmenu(207); + probey = whichkey; + } else if (function == 3) { + JoystickDigitalFunctions[whichkey>>1][whichkey&1] = x; + CONTROL_MapDigitalAxis(whichkey>>1, x, whichkey&1, controldevice_joystick); + cmenu((whichkey>>2)+208); + probey = 1+((whichkey>>1)&1)*4+(whichkey&1); + } + break; + } + + gametext(320>>1,25,"SELECT A FUNCTION TO ASSIGN",0,2+8+16); + + if (function == 0) { + if (whichkey < (MAXMOUSEBUTTONS-2)*2) + sprintf(tempbuf,"TO %s%s", (whichkey&1)?"DOUBLE-CLICKED ":"", mousebuttonnames[whichkey>>1]); + else + Bstrcpy(tempbuf, mousebuttonnames[whichkey-(MAXMOUSEBUTTONS-2)]); + } else if (function == 1) { + Bstrcpy(tempbuf,"TO DIGITAL "); + switch (whichkey) { + case 0: Bstrcat(tempbuf, "LEFT"); break; + case 1: Bstrcat(tempbuf, "RIGHT"); break; + case 2: Bstrcat(tempbuf, "UP"); break; + case 3: Bstrcat(tempbuf, "DOWN"); break; + } + } else if (function == 2) { + static char *directions[] = { "UP", "RIGHT", "DOWN", "LEFT" }; + if (whichkey < 2*joynumbuttons) + Bsprintf(tempbuf,"TO %s%s", (whichkey&1)?"DOUBLE-CLICKED ":"", getjoyname(1,whichkey>>1)); + else + Bsprintf(tempbuf,"TO HAT %s", directions[whichkey-2*joynumbuttons]); + } else if (function == 3) { + Bsprintf(tempbuf,"TO DIGITAL %s %s",getjoyname(0,whichkey>>1),(whichkey&1)?"POSITIVE":"NEGATIVE"); + } + + gametext(320>>1,25+9,tempbuf,0,2+8+16); + + if (KB_KeyPressed( sc_End )) { KB_ClearKeyDown(sc_End); probey = NUMGAMEFUNCTIONS-1; sound(KICK_HIT); } + else if (KB_KeyPressed( sc_Home )) { KB_ClearKeyDown(sc_Home); probey = 0; sound(KICK_HIT); } + + m = probey - 6; + if (m < 0) m = 0; + else if (m + 13 >= NUMGAMEFUNCTIONS) m = NUMGAMEFUNCTIONS-13; + + for (l=0; l < min(13,NUMGAMEFUNCTIONS); l++) { + if (l+m == NUMGAMEFUNCTIONS-1) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(m+l)); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(100,46+l*8,tempbuf,(m+l == probey)?0:16,10+16); + } + + gametext(320>>1,154,"PRESS \"ESCAPE\" TO CANCEL",0,2+8+16); + + break; + + case 212: + rotatesprite(320<<15,10<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,15,0,0,"ADVANCED MOUSE"); + + c = (320>>1)-120; + + onbar = (probey == 0 || probey == 1); + if (probey < 2) + x = probe(c+6,40,16,6); + else if (probey < 6) { + m=50; + x = probe(c+6+10,91-(10+10),10,6); + } else { + x = probe(c+6,140-(16+16+16+16+16+16),16,6); + } + + switch (x) { + case -1: + cmenu(205); + probey = (MAXMOUSEBUTTONS-2)*2+2+1; + break; + + case 0: + // x-axis scale + case 1: + // y-axis scale + break; + + case 2: + // digital up + case 3: + // digital down + case 4: + // digital left + case 5: + // digital right + function = 1; + whichkey = (x-2)^2; // flip the actual axis number + cmenu(211); + probey = MouseDigitalFunctions[whichkey>>1][whichkey&1]; + if (probey < 0) probey = NUMGAMEFUNCTIONS-1; + break; + + case 6: + // analogue x + case 7: + // analogue y + l = MouseAnalogueAxes[x-6]; + if (l == analog_turning) l = analog_strafing; + else if (l == analog_strafing) l = analog_lookingupanddown; + else if (l == analog_lookingupanddown) l = analog_moving; + else if (l == analog_moving) l = -1; + else l = analog_turning; + MouseAnalogueAxes[x-6] = l; + CONTROL_MapAnalogAxis(x-6,l,controldevice_mouse); + break; + + } + + menutext(c,40,0,0,"X-AXIS SCALE"); + l = (MouseAnalogueScale[0]+262144) >> 13; + bar(c+160+40,40,(short *)&l,1,x==0,0,0); + l = (l<<13)-262144; + if (l != MouseAnalogueScale[0]) { + CONTROL_SetAnalogAxisScale( 0, l, controldevice_mouse ); + MouseAnalogueScale[0] = l; + } + Bsprintf(tempbuf,"%s%.2f",l>=0?" ":"",(float)l/65536.0); + gametext(c+160-16,40-8,tempbuf,0,2+8+16); + + menutext(c,40+16,0,0,"Y-AXIS SCALE"); + l = (MouseAnalogueScale[1]+262144) >> 13; + bar(c+160+40,40+16,(short *)&l,1,x==1,0,0); + l = (l<<13)-262144; + if (l != MouseAnalogueScale[1]) { + CONTROL_SetAnalogAxisScale( 1, l, controldevice_mouse ); + MouseAnalogueScale[1] = l; + } + Bsprintf(tempbuf,"%s%.2f",l>=0?" ":"",(float)l/65536.0); + gametext(c+160-16,40+16-8,tempbuf,0,2+8+16); + + menutext(c,40+16+16+8,0,0,"DIGITAL AXES ACTIONS"); + + gametext(c+10,84,"UP:",0,2+8+16); + if (MouseDigitalFunctions[1][0] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(MouseDigitalFunctions[1][0])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(c+10+60,85,tempbuf,0,10+16); + + gametext(c+10,84+10,"DOWN:",0,2+8+16); + if (MouseDigitalFunctions[1][1] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(MouseDigitalFunctions[1][1])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(c+10+60,85+10,tempbuf,0,10+16); + + gametext(c+10,84+10+10,"LEFT:",0,2+8+16); + if (MouseDigitalFunctions[0][0] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(MouseDigitalFunctions[0][0])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(c+10+60,85+10+10,tempbuf,0,10+16); + + gametext(c+10,84+10+10+10,"RIGHT:",0,2+8+16); + if (MouseDigitalFunctions[0][1] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(MouseDigitalFunctions[0][1])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(c+10+60,85+10+10+10,tempbuf,0,10+16); + + /* JBF 20040107: It would appear giving these options confuses some tinkerers, so they've + * been moved to the bottom, and hidden in case I dare to reenable them again. + menutext(c,116+16+8,0,0,"ANALOG X"); + if (CONFIG_AnalogNumToName( MouseAnalogueAxes[0] )) { + p = CONFIG_AnalogNumToName( MouseAnalogueAxes[0] ); + if (p) { + gametext(c+148+4,118+16, strchr(p,'_')+1, 0, 2+8+16 ); + } + } + if (probey == 6) gametext(160,158,"Default is \"turning\"",8,2+8+16); + + menutext(c,116+16+16+8,0,0,"ANALOG Y"); + if (CONFIG_AnalogNumToName( MouseAnalogueAxes[1] )) { + p = CONFIG_AnalogNumToName( MouseAnalogueAxes[1] ); + if (p) { + gametext(c+148+4,118+16+16, strchr(p,'_')+1, 0, 2+8+16 ); + } + } + if (probey == 7) gametext(160,158,"Default is \"moving\"",8,2+8+16); + */ + break; + + case 206: + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"JOYSTICK SETUP"); + + x = probe(160,100-18,18,3); + + switch (x) { + case -1: + cmenu(202); + probey = 5; + break; + case 0: + case 1: + cmenu(207+x); + break; + case 2: + cmenu(213); + break; + } + + menutext(160,100-18,0,0,"EDIT BUTTONS"); + menutext(160,100,0,0,"EDIT AXES"); + menutext(160,100+18,0,0,"DEAD ZONES"); + + break; + + case 207: + rotatesprite(320<<15,10<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,15,0,0,"JOYSTICK BUTTONS"); + + c = 2*joynumbuttons + 4*(joynumhats>0); + + x = probe(0,0,0,c); + + if (x == -1) { + cmenu(206); + probey = 0; + break; + } else if (x >= 0) { + function = 2; + whichkey = x; + cmenu(211); + if (x < 2*joynumbuttons) { + probey = JoystickFunctions[x>>1][x&1]; + } else { + probey = JoystickFunctions[joynumbuttons + (x-2*joynumbuttons)][0]; + } + if (probey < 0) probey = NUMGAMEFUNCTIONS-1; + break; + } + + // the top of our list + if (c < 13) m = 0; + else { + m = probey - 6; + if (m < 0) m = 0; + else if (m + 13 >= c) m = c-13; + } + + for (l=0; l>1)); + x = JoystickFunctions[(l+m)>>1][(l+m)&1]; + } else { + static char *directions[] = { "Up", "Right", "Down", "Left" }; + sprintf(tempbuf, "Hat %s", directions[(l+m)-2*joynumbuttons]); + x = JoystickFunctions[joynumbuttons + ((l+m)-2*joynumbuttons)][0]; + } + minitextshade(80-4,33+l*8,tempbuf,(m+l == probey)?0:16,1,10+16); + + if (x == -1) + minitextshade(176,33+l*8," -NONE-",(m+l==probey)?0:16,2,10+16); + else { + strcpy(tempbuf, CONFIG_FunctionNumToName(x)); + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitextshade(176,33+l*8,tempbuf,(m+l==probey)?0:16,2,10+16); + } + } + + gametext(160,149,"UP/DOWN = SELECT BUTTON",0,2+8+16); + gametext(160,149+9,"ENTER = MODIFY",0,2+8+16); + break; + + case 208: + case 209: + case 217: + case 218: + case 219: + case 220: + case 221: + case 222: + { + int thispage, twothispage; + + rotatesprite(320<<15,10<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,15,0,0,"JOYSTICK AXES"); + + thispage = (current_menu < 217) ? (current_menu-208) : (current_menu-217)+2; + twothispage = (thispage*2+1 < joynumaxes); + + onbar = 0; + switch (probey) { + case 0: + case 4: onbar = 1; x = probe(88,45+(probey==4)*64,0,1+(4< 2) { + if (thispage == ((joynumaxes+1)/2)-1) cmenu(208); + else { + if (current_menu == 209) cmenu(217); + else cmenu( current_menu+1 ); + } + } + break; + + case 4: // bar + if (!twothispage && joynumaxes > 2) + cmenu(208); + case 0: break; + + case 1: // digitals + case 2: + case 5: + case 6: + function = 3; + whichkey = ((thispage*2+(x==5||x==6)) << 1) + (x==2||x==6); + cmenu(211); + probey = JoystickDigitalFunctions[whichkey>>1][whichkey&1]; + if (probey < 0) probey = NUMGAMEFUNCTIONS-1; + break; + + case 3: // analogues + case 7: + l = JoystickAnalogueAxes[thispage*2+(x==7)]; + if (l == analog_turning) l = analog_strafing; + else if (l == analog_strafing) l = analog_lookingupanddown; + else if (l == analog_lookingupanddown) l = analog_moving; + else if (l == analog_moving) l = -1; + else l = analog_turning; + JoystickAnalogueAxes[thispage*2+(x==7)] = l; + CONTROL_MapAnalogAxis(thispage*2+(x==7),l,controldevice_joystick); + break; + default:break; + } + + Bsprintf(tempbuf,getjoyname(0,thispage*2)); + menutext(42,32,0,0,tempbuf); + if (twothispage) + { + Bsprintf(tempbuf,getjoyname(0,thispage*2+1)); + menutext(42,32+64,0,0,tempbuf); + } + gametext(76,38,"SCALE",0,2+8+16); + l = (JoystickAnalogueScale[thispage*2]+262144) >> 13; + bar(140+56,38+8,(short *)&l,1,x==0,0,0); + l = (l<<13)-262144; + if (l != JoystickAnalogueScale[thispage*2]) { + CONTROL_SetAnalogAxisScale( thispage*2, l, controldevice_joystick ); + JoystickAnalogueScale[thispage*2] = l; + } + Bsprintf(tempbuf,"%s%.2f",l>=0?" ":"",(float)l/65536.0); + gametext(140,38,tempbuf,0,2+8+16); + + gametext(76,38+15,"DIGITAL",0,2+8+16); + if (JoystickDigitalFunctions[thispage*2][0] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[thispage*2][0])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(140+12,38+15,tempbuf,0,10+16); + + if (JoystickDigitalFunctions[thispage*2][1] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[thispage*2][1])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(140+12+72,38+15,tempbuf,0,10+16); + + gametext(76,38+15+15,"ANALOG",0,2+8+16); + if (CONFIG_AnalogNumToName( JoystickAnalogueAxes[thispage*2] )) { + p = CONFIG_AnalogNumToName( JoystickAnalogueAxes[thispage*2] ); + if (p) { + gametext(140+12,38+15+15, strchr(p,'_')+1, 0, 2+8+16 ); + } + } + + if (twothispage) { + gametext(76,38+64,"SCALE",0,2+8+16); + l = (JoystickAnalogueScale[thispage*2+1]+262144) >> 13; + bar(140+56,38+8+64,(short *)&l,1,x==4,0,0); + l = (l<<13)-262144; + if (l != JoystickAnalogueScale[thispage*2+1]) { + CONTROL_SetAnalogAxisScale( thispage*2+1, l, controldevice_joystick ); + JoystickAnalogueScale[thispage*2+1] = l; + } + Bsprintf(tempbuf,"%s%.2f",l>=0?" ":"",(float)l/65536.0); + gametext(140,38+64,tempbuf,0,2+8+16); + + gametext(76,38+64+15,"DIGITAL",0,2+8+16); + if (JoystickDigitalFunctions[thispage*2+1][0] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[thispage*2+1][0])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(140+12,38+15+64,tempbuf,0,10+16); + + if (JoystickDigitalFunctions[thispage*2+1][1] < 0) + strcpy(tempbuf, " -NONE-"); + else + strcpy(tempbuf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[thispage*2+1][1])); + + for (i=0;tempbuf[i];i++) if (tempbuf[i]=='_') tempbuf[i] = ' '; + minitext(140+12+72,38+15+64,tempbuf,0,10+16); + + gametext(76,38+64+15+15,"ANALOG",0,2+8+16); + if (CONFIG_AnalogNumToName( JoystickAnalogueAxes[thispage*2+1] )) { + p = CONFIG_AnalogNumToName( JoystickAnalogueAxes[thispage*2+1] ); + if (p) { + gametext(140+12,38+64+15+15, strchr(p,'_')+1, 0, 2+8+16 ); + } + } + } + + if (joynumaxes > 2) { + menutext(320>>1,twothispage?158:108,SHX(-10),(joynumaxes<=2),"NEXT..."); + sprintf(tempbuf,"Page %d of %d",thispage+1,(joynumaxes+1)/2); + gametext(320-100,158,tempbuf,0,2+8+16); + } + break; + } + + case 213: + case 214: + case 215: + case 216: { // Pray this is enough pages for now :-| + int first,last; + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"JOY DEAD ZONES"); + + first = 4*(current_menu-213); + last = min(4*(current_menu-213)+4,joynumaxes); + + onbar = 1; + x = probe(320,48,15,2*(last-first)+(joynumaxes>4)); + + if (x==-1) { + cmenu(206); + probey = 2; + break; + } else if (x==2*(last-first) && joynumaxes>4) { + cmenu( (current_menu-213) == (joynumaxes/4) ? 213 : (current_menu+1) ); + probey = 0; + break; + } + + for (m=first;m4) { + menutext(32,48+30*(last-first),0,0,"NEXT..."); + sprintf(tempbuf,"Page %d of %d", 1+(current_menu-213), (joynumaxes+3)/4); + gametext(320-100,158,tempbuf,0,2+8+16); + } + break; + } + + case 700: + case 701: + c = (320>>1)-120; + rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"SOUND OPTIONS"); + onbar = ( probey == 2 || probey == 3 ); + + x = probe(c,50,16,7); + switch(x) + { + case -1: + if(ps[myconnectindex].gm&MODE_GAME && current_menu == 701) + { + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + + else cmenu(202); + probey = 1; + break; + case 0: + if (FXDevice >= 0) + { + SoundToggle = 1-SoundToggle; + if( SoundToggle == 0 ) + { + FX_StopAllSounds(); + clearsoundlocks(); + } + onbar = 0; + } + break; + case 1: + + if(numplayers < 2) + if(MusicDevice >= 0) + { + MusicToggle = 1-MusicToggle; + if( MusicToggle == 0 ) MUSIC_Pause(); + else + { + if(ud.recstat != 2 && ps[myconnectindex].gm&MODE_GAME) + playmusic(&music_fn[0][music_select][0]); + else playmusic(&env_music_fn[0][0]); + + MUSIC_Continue(); + } + } + onbar = 0; + + break; + case 4: + if(SoundToggle && (FXDevice >= 0)) VoiceToggle = 1-VoiceToggle; + onbar = 0; + break; + case 5: + if(SoundToggle && (FXDevice >= 0)) AmbienceToggle = 1-AmbienceToggle; + onbar = 0; + break; + case 6: + if(SoundToggle && (FXDevice >= 0)) + { + ReverseStereo = 1-ReverseStereo; + FX_SetReverseStereo(ReverseStereo); + } + onbar = 0; + break; + default: + onbar = 1; + break; + } + + if(SoundToggle && FXDevice >= 0) menutext(c+160+40,50,0,(FXDevice<0),"ON"); + else menutext(c+160+40,50,0,(FXDevice<0),"OFF"); + + if(MusicToggle && (MusicDevice >= 0) && (numplayers<2)) + menutext(c+160+40,50+16,0,(MusicDevice < 0),"ON"); + else menutext(c+160+40,50+16,0,(MusicDevice < 0),"OFF"); + + menutext(c,50,SHX(-2),(FXDevice<0),"SOUND"); + menutext(c,50+16+16,SHX(-4),(FXDevice<0)||SoundToggle==0,"SOUND VOLUME"); + { + l = FXVolume; + FXVolume >>= 2; + bar(c+167+40,50+16+16,(short *)&FXVolume,4,(FXDevice>=0)&&x==2,SHX(-4),SoundToggle==0||(FXDevice<0)); + if(l != FXVolume) + FXVolume <<= 2; + if(l != FXVolume) + FX_SetVolume( (short) FXVolume ); + } + menutext(c,50+16,SHX(-3),(MusicDevice<0),"MUSIC"); + menutext(c,50+16+16+16,SHX(-5),(MusicDevice<0)||MusicToggle==0,"MUSIC VOLUME"); + { + l = MusicVolume; + MusicVolume >>= 2; + bar(c+167+40,50+16+16+16, + (short *)&MusicVolume,4, + (MusicDevice>=0) && x==3,SHX(-5), + MusicToggle==0||(MusicDevice<0)); + MusicVolume <<= 2; + if(l != MusicVolume) + MUSIC_SetVolume( (short) MusicVolume ); + + } + menutext(c,50+16+16+16+16,SHX(-6),(FXDevice<0)||SoundToggle==0,"DUKE TALK"); + menutext(c,50+16+16+16+16+16,SHX(-7),(FXDevice<0)||SoundToggle==0,"AMBIENCE"); + + menutext(c,50+16+16+16+16+16+16,SHX(-8),(FXDevice<0)||SoundToggle==0,"FLIP STEREO"); + + if(VoiceToggle) menutext(c+160+40,50+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"ON"); + else menutext(c+160+40,50+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"OFF"); + + if(AmbienceToggle) menutext(c+160+40,50+16+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"ON"); + else menutext(c+160+40,50+16+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"OFF"); + + if(ReverseStereo) menutext(c+160+40,50+16+16+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"ON"); + else menutext(c+160+40,50+16+16+16+16+16+16,0,(FXDevice<0)||SoundToggle==0,"OFF"); + + + break; + + case 350: + cmenu(351); + screencapt = 1; + displayrooms(myconnectindex,65536); + //savetemp("duke3d.tmp",waloff[TILE_SAVESHOT],160*100); + screencapt = 0; + break; + + case 360: + case 361: + case 362: + case 363: + case 364: + case 365: + case 366: + case 367: + case 368: + case 369: + case 351: + case 300: + + c = 320>>1; + rotatesprite(c<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1); + rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + + if(current_menu == 300) menutext(c,24,0,0,"LOAD GAME"); + else menutext(c,24,0,0,"SAVE GAME"); + + if(current_menu >= 360 && current_menu <= 369 ) + { + sprintf(tempbuf,"PLAYERS: %-2ld ",ud.multimode); + gametext(160,156,tempbuf,0,2+8+16); + sprintf(tempbuf,"EPISODE: %-2ld / LEVEL: %-2ld / SKILL: %-2ld",1+ud.volume_number,1+ud.level_number,ud.player_skill); + gametext(160,168,tempbuf,0,2+8+16); + if (ud.volume_number == 0 && ud.level_number == 7) + gametext(160,180,boardfilename,0,2+8+16); + + x = strget((320>>1),184,&ud.savegame[current_menu-360][0],19, 999 ); + + if(x == -1) + { + // readsavenames(); + ps[myconnectindex].gm = MODE_GAME; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + goto DISPLAYNAMES; + } + + if( x == 1 ) + { + if( ud.savegame[current_menu-360][0] == 0 ) + { + KB_FlushKeyboardQueue(); + cmenu(351); + } + else + { + if(ud.multimode > 1) + saveplayer(-1-(current_menu-360)); + else saveplayer(current_menu-360); + lastsavedpos = current_menu-360; + ps[myconnectindex].gm = MODE_GAME; + + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + KB_ClearKeyDown(sc_Escape); + sound(EXITMENUSOUND); + } + } + + rotatesprite(101<<16,97<<16,65536>>1,512,TILE_SAVESHOT,-32,0,2+4+8+64,0,0,xdim-1,ydim-1); + dispnames(); + rotatesprite((c+67+strlen(&ud.savegame[current_menu-360][0])*4)<<16,(50+12*probey)<<16,32768L-10240,0,SPINNINGNUKEICON+(((totalclock)>>3)%7),0,0,10,0,0,xdim-1,ydim-1); + break; + } + + last_threehundred = probey; + + x = probe(c+68,54,12,10); + + if(current_menu == 300) + { + if( ud.savegame[probey][0] ) + { + if( lastprobey != probey ) + { + loadpheader(probey,&savehead); + lastprobey = probey; + } + + rotatesprite(101<<16,97<<16,65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64,0,0,xdim-1,ydim-1); + sprintf(tempbuf,"PLAYERS: %-2ld ",savehead.numplr); + gametext(160,156,tempbuf,0,2+8+16); + sprintf(tempbuf,"EPISODE: %-2ld / LEVEL: %-2ld / SKILL: %-2ld",1+savehead.volnum,1+savehead.levnum,savehead.plrskl); + gametext(160,168,tempbuf,0,2+8+16); + if (savehead.volnum == 0 && savehead.levnum == 7) + gametext(160,180,savehead.boardfn,0,2+8+16); + } + else menutext(69,70,0,0,"EMPTY"); + } + else + { + if( ud.savegame[probey][0] ) + { + if(lastprobey != probey) + loadpheader(probey,&savehead); + lastprobey = probey; + rotatesprite(101<<16,97<<16,65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64,0,0,xdim-1,ydim-1); + } + else menutext(69,70,0,0,"EMPTY"); + sprintf(tempbuf,"PLAYERS: %-2ld ",ud.multimode); + gametext(160,156,tempbuf,0,2+8+16); + sprintf(tempbuf,"EPISODE: %-2ld / LEVEL: %-2ld / SKILL: %-2ld",1+ud.volume_number,1+ud.level_number,ud.player_skill); + gametext(160,168,tempbuf,0,2+8+16); + if (ud.volume_number == 0 && ud.level_number == 7) + gametext(160,180,boardfilename,0,2+8+16); + } + + switch( x ) + { + case -1: + if(current_menu == 300) + { + if( (ps[myconnectindex].gm&MODE_GAME) != MODE_GAME) + { + cmenu(0); + break; + } + else + ps[myconnectindex].gm &= ~MODE_MENU; + } + else + ps[myconnectindex].gm = MODE_GAME; + + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + + break; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + if( current_menu == 300) + { + if( ud.savegame[x][0] ) + current_menu = (1000+x); + } + else + { + if( ud.savegame[x][0] != 0) + current_menu = 2000+x; + else + { + KB_FlushKeyboardQueue(); + current_menu = (360+x); + ud.savegame[x][0] = 0; + inputloc = 0; + } + } + break; + } + +DISPLAYNAMES: + dispnames(); + break; + + case 400: + case 401: + if (VOLUMEALL) goto VOLUME_ALL_40x; + case 402: + case 403: + + c = 320>>1; + + if( KB_KeyPressed( sc_LeftArrow ) || + KB_KeyPressed( sc_kpad_4 ) || + KB_KeyPressed( sc_UpArrow ) || + KB_KeyPressed( sc_PgUp ) || + KB_KeyPressed( sc_kpad_8 ) ) + { + KB_ClearKeyDown(sc_LeftArrow); + KB_ClearKeyDown(sc_kpad_4); + KB_ClearKeyDown(sc_UpArrow); + KB_ClearKeyDown(sc_PgUp); + KB_ClearKeyDown(sc_kpad_8); + + sound(KICK_HIT); + current_menu--; + if(current_menu < 400) current_menu = 403; + } + else if( + KB_KeyPressed( sc_PgDn ) || + KB_KeyPressed( sc_Enter ) || + KB_KeyPressed( sc_kpad_Enter ) || + KB_KeyPressed( sc_RightArrow ) || + KB_KeyPressed( sc_DownArrow ) || + KB_KeyPressed( sc_kpad_2 ) || + KB_KeyPressed( sc_kpad_9 ) || + KB_KeyPressed( sc_Space ) || + KB_KeyPressed( sc_kpad_6 ) ) + { + KB_ClearKeyDown(sc_PgDn); + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_RightArrow); + KB_ClearKeyDown(sc_kpad_Enter); + KB_ClearKeyDown(sc_kpad_6); + KB_ClearKeyDown(sc_kpad_9); + KB_ClearKeyDown(sc_kpad_2); + KB_ClearKeyDown(sc_DownArrow); + KB_ClearKeyDown(sc_Space); + sound(KICK_HIT); + current_menu++; + if(current_menu > 403) current_menu = 400; + } + + if( KB_KeyPressed(sc_Escape) ) + { + if(ps[myconnectindex].gm&MODE_GAME) + cmenu(50); + else cmenu(0); + return; + } + + flushperms(); + rotatesprite(0,0,65536L,0,ORDERING+current_menu-400,0,0,10+16+64,0,0,xdim-1,ydim-1); + + break; +VOLUME_ALL_40x: + + c = 320>>1; + + if( KB_KeyPressed( sc_LeftArrow ) || + KB_KeyPressed( sc_kpad_4 ) || + KB_KeyPressed( sc_UpArrow ) || + KB_KeyPressed( sc_PgUp ) || + KB_KeyPressed( sc_kpad_8 ) ) + { + KB_ClearKeyDown(sc_LeftArrow); + KB_ClearKeyDown(sc_kpad_4); + KB_ClearKeyDown(sc_UpArrow); + KB_ClearKeyDown(sc_PgUp); + KB_ClearKeyDown(sc_kpad_8); + + sound(KICK_HIT); + current_menu--; + if(current_menu < 400) current_menu = 401; + } + else if( + KB_KeyPressed( sc_PgDn ) || + KB_KeyPressed( sc_Enter ) || + KB_KeyPressed( sc_kpad_Enter ) || + KB_KeyPressed( sc_RightArrow ) || + KB_KeyPressed( sc_DownArrow ) || + KB_KeyPressed( sc_kpad_2 ) || + KB_KeyPressed( sc_kpad_9 ) || + KB_KeyPressed( sc_Space ) || + KB_KeyPressed( sc_kpad_6 ) ) + { + KB_ClearKeyDown(sc_PgDn); + KB_ClearKeyDown(sc_Enter); + KB_ClearKeyDown(sc_RightArrow); + KB_ClearKeyDown(sc_kpad_Enter); + KB_ClearKeyDown(sc_kpad_6); + KB_ClearKeyDown(sc_kpad_9); + KB_ClearKeyDown(sc_kpad_2); + KB_ClearKeyDown(sc_DownArrow); + KB_ClearKeyDown(sc_Space); + sound(KICK_HIT); + current_menu++; + if(current_menu > 401) current_menu = 400; + } + + if( KB_KeyPressed(sc_Escape) ) + { + if(ps[myconnectindex].gm&MODE_GAME) + cmenu(50); + else cmenu(0); + return; + } + + flushperms(); + switch(current_menu) + { + case 400: + rotatesprite(0,0,65536L,0,TEXTSTORY,0,0,10+16+64, 0,0,xdim-1,ydim-1); + break; + case 401: + rotatesprite(0,0,65536L,0,F1HELP,0,0,10+16+64, 0,0,xdim-1,ydim-1); + break; + } + + break; + + case 500: + c = 320>>1; + + gametext(c,90,"Are you sure you want to quit?",0,2+8+16); + gametext(c,99,"(Y/N)",0,2+8+16); + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + KB_FlushKeyboardQueue(); + + if( gamequit == 0 && ( numplayers > 1 ) ) + { + if(ps[myconnectindex].gm&MODE_GAME) + { + gamequit = 1; + quittimer = totalclock+120; + } + else + { + sendlogoff(); + gameexit(" "); + } + } + else if( numplayers < 2 ) + gameexit(" "); + + if( ( totalclock > quittimer ) && ( gamequit == 1) ) + gameexit("Timed out."); + } + + x = probe(186,124,0,0); + if(x == -1 || KB_KeyPressed(sc_N) || RMB) + { + KB_ClearKeyDown(sc_N); + quittimer = 0; + if( ps[myconnectindex].gm&MODE_DEMO ) + ps[myconnectindex].gm = MODE_DEMO; + else + { + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + } + + break; + case 501: + c = 320>>1; + gametext(c,90,"Quit to Title?",0,2+8+16); + gametext(c,99,"(Y/N)",0,2+8+16); + + if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB ) + { + KB_FlushKeyboardQueue(); + ps[myconnectindex].gm = MODE_DEMO; + if(ud.recstat == 1) + closedemowrite(); + cmenu(0); + } + + x = probe(186,124,0,0); + + if(x == -1 || KB_KeyPressed(sc_N) || RMB) + { + ps[myconnectindex].gm &= ~MODE_MENU; + if(ud.multimode < 2 && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + } + + break; + + case 601: + displayfragbar(); + rotatesprite(160<<16,29<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,34,0,0,&ud.user_name[myconnectindex][0]); + + sprintf(tempbuf,"Waiting for master"); + gametext(160,50,tempbuf,0,2+8+16); + gametext(160,59,"to select level",0,2+8+16); + + if( KB_KeyPressed(sc_Escape) ) + { + KB_ClearKeyDown(sc_Escape); + sound(EXITMENUSOUND); + cmenu(0); + } + break; + + case 602: + if(menunamecnt == 0) + { + // getfilenames("SUBD"); + getfilenames(".","*.MAP"); + if (menunamecnt == 0) + cmenu(600); + } + case 603: + c = (320>>1) - 120; + displayfragbar(); + rotatesprite(320>>1<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(320>>1,24,0,0,"USER MAPS"); + for(x=0;x 256 ) ) + { + KB_ClearKeyDown( sc_RightArrow ); + KB_ClearKeyDown( sc_kpad_6 ); + probey += 15; + if(probey >= menunamecnt) + probey -= 15; + else sound(KICK_HIT); + } + + onbar = 0; + x = probe(0,0,0,menunamecnt); + + if(x == -1) cmenu(600); + else if(x >= 0) + { + tempbuf[0] = 8; + tempbuf[1] = ud.m_level_number = 6; + tempbuf[2] = ud.m_volume_number = 0; + tempbuf[3] = ud.m_player_skill+1; + + if(ud.player_skill == 3) + ud.m_respawn_monsters = 1; + else ud.m_respawn_monsters = 0; + + if(ud.m_coop == 0) ud.m_respawn_items = 1; + else ud.m_respawn_items = 0; + + ud.m_respawn_inventory = 1; + + tempbuf[4] = ud.m_monsters_off; + tempbuf[5] = ud.m_respawn_monsters; + tempbuf[6] = ud.m_respawn_items; + tempbuf[7] = ud.m_respawn_inventory; + tempbuf[8] = ud.m_coop; + tempbuf[9] = ud.m_marker; + + x = strlen(menuname[probey]); + + copybufbyte(menuname[probey],tempbuf+10,x); + copybufbyte(menuname[probey],boardfilename,x+1); + + for(c=connecthead;c>=0;c=connectpoint2[c]) + { + if (c != myconnectindex) sendpacket(c,tempbuf,x+10); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1); + if (enterlevel(MODE_GAME)) backtomenu(); + } + break; + + case 600: + c = (320>>1) - 120; + if((ps[myconnectindex].gm&MODE_GAME) != MODE_GAME) + displayfragbar(); + rotatesprite(160<<16,26<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1); + menutext(160,31,0,0,&ud.user_name[myconnectindex][0]); + + x = probe(c,57-8,16,8); + + switch(x) + { + case -1: + ud.m_recstat = 0; + if(ps[myconnectindex].gm&MODE_GAME) cmenu(50); + else cmenu(0); + break; + case 0: + ud.m_coop++; + if(ud.m_coop == num_gametypes) ud.m_coop = 0; + break; + case 1: + if (!VOLUMEONE) { + ud.m_volume_number++; + if(ud.m_volume_number == num_volumes) ud.m_volume_number = 0; + if(ud.m_volume_number == 0 && ud.m_level_number > 6) + ud.m_level_number = 0; + if(ud.m_level_number > 10) ud.m_level_number = 0; + } + break; + case 2: + ud.m_level_number++; + if (!VOLUMEONE) { + if(ud.m_volume_number == 0 && ud.m_level_number > 6) + ud.m_level_number = 0; + } else { + if(ud.m_volume_number == 0 && ud.m_level_number > 5) + ud.m_level_number = 0; + } + if(ud.m_level_number > 10) ud.m_level_number = 0; + break; + case 3: + if(ud.m_monsters_off == 1 && ud.m_player_skill > 0) + ud.m_monsters_off = 0; + + if(ud.m_monsters_off == 0) + { + ud.m_player_skill++; + if(ud.m_player_skill > 3) + { + ud.m_player_skill = 0; + ud.m_monsters_off = 1; + } + } + else ud.m_monsters_off = 0; + + break; + + case 4: + if((gametype_flags[ud.m_coop] & GAMETYPE_FLAG_MARKEROPTION)) + ud.m_marker = !ud.m_marker; + break; + + case 5: + if((gametype_flags[ud.m_coop] & GAMETYPE_FLAG_COOP)) + ud.m_ffire = !ud.m_ffire; + break; + + case 6: + if (VOLUMEALL) { + if(boardfilename[0] == 0) break; + + tempbuf[0] = 5; + tempbuf[1] = ud.m_level_number = 7; + tempbuf[2] = ud.m_volume_number = 0; + tempbuf[3] = ud.m_player_skill+1; + + ud.level_number = ud.m_level_number; + ud.volume_number = ud.m_volume_number; + + if( ud.m_player_skill == 3 ) ud.m_respawn_monsters = 1; + else ud.m_respawn_monsters = 0; + + if((gametype_flags[ud.m_coop] & GAMETYPE_FLAG_ITEMRESPAWN)) ud.m_respawn_items = 1; + else ud.m_respawn_items = 0; + + ud.m_respawn_inventory = 1; + + tempbuf[4] = ud.m_monsters_off; + tempbuf[5] = ud.m_respawn_monsters; + tempbuf[6] = ud.m_respawn_items; + tempbuf[7] = ud.m_respawn_inventory; + tempbuf[8] = ud.m_coop; + tempbuf[9] = ud.m_marker; + tempbuf[10] = ud.m_ffire; + + for(c=connecthead;c>=0;c=connectpoint2[c]) + { + resetweapons(c); + resetinventory(c); + + } + for(c=connecthead;c>=0;c=connectpoint2[c]) + { + if (c != myconnectindex) sendpacket(c,tempbuf,11); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1); + if (enterlevel(MODE_GAME)) backtomenu(); + + return; + } + case 7: + + tempbuf[0] = 5; + tempbuf[1] = ud.m_level_number; + tempbuf[2] = ud.m_volume_number; + tempbuf[3] = ud.m_player_skill+1; + + if( ud.m_player_skill == 3 ) ud.m_respawn_monsters = 1; + else ud.m_respawn_monsters = 0; + + if((gametype_flags[ud.m_coop] & GAMETYPE_FLAG_ITEMRESPAWN)) ud.m_respawn_items = 1; + else ud.m_respawn_items = 0; + + ud.m_respawn_inventory = 1; + + tempbuf[4] = ud.m_monsters_off; + tempbuf[5] = ud.m_respawn_monsters; + tempbuf[6] = ud.m_respawn_items; + tempbuf[7] = ud.m_respawn_inventory; + tempbuf[8] = ud.m_coop; + tempbuf[9] = ud.m_marker; + tempbuf[10] = ud.m_ffire; + + for(c=connecthead;c>=0;c=connectpoint2[c]) + { + resetweapons(c); + resetinventory(c); + + } + for(c=connecthead;c>=0;c=connectpoint2[c]) + { + if(c != myconnectindex) sendpacket(c,tempbuf,11); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1); + if (enterlevel(MODE_GAME)) backtomenu(); + + return; + + } + + c += 40; + + //if(ud.m_coop==1) gametext(c+70,57-7-9,"COOPERATIVE PLAY",0,2+8+16); + //else if(ud.m_coop==2) gametext(c+70,57-7-9,"DUKEMATCH (NO SPAWN)",0,2+8+16); + //else gametext(c+70,57-7-9,"DUKEMATCH (SPAWN)",0,2+8+16); + gametext(c+70,57-7-9,gametype_names[ud.m_coop],0,2+8+16); + if (VOLUMEONE) { + gametext(c+70,57+16-7-9,volume_names[ud.m_volume_number],0,2+8+16); + } else { + gametext(c+70,57+16-7-9,volume_names[ud.m_volume_number],0,2+8+16); + } + + gametext(c+70,57+16+16-7-9,&level_names[11*ud.m_volume_number+ud.m_level_number][0],0,2+8+16); + + if(ud.m_monsters_off == 0 || ud.m_player_skill > 0) + gametext(c+70,57+16+16+16-7-9,skill_names[ud.m_player_skill],0,2+8+16); + else gametext(c+70,57+16+16+16-7-9,"NONE",0,2+8+16); + + if(gametype_flags[ud.m_coop] & GAMETYPE_FLAG_MARKEROPTION) + { + if(ud.m_marker) + gametext(c+70,57+16+16+16+16-7-9,"ON",0,2+8+16); + else gametext(c+70,57+16+16+16+16-7-9,"OFF",0,2+8+16); + } + + if(gametype_flags[ud.m_coop] & GAMETYPE_FLAG_COOP) + { + if(ud.m_ffire) + gametext(c+70,57+16+16+16+16+16-7-9,"ON",0,2+8+16); + else gametext(c+70,57+16+16+16+16+16-7-9,"OFF",0,2+8+16); + } + + c -= 44; + + menutext(c,57-9,SHX(-2),PHX(-2),"GAME TYPE"); + + if (VOLUMEONE) { + sprintf(tempbuf,"EPISODE %ld",ud.m_volume_number+1); + menutext(c,57+16-9,SHX(-3),1,tempbuf); + } else { + sprintf(tempbuf,"EPISODE %ld",ud.m_volume_number+1); + menutext(c,57+16-9,SHX(-3),PHX(-3),tempbuf); + } + + sprintf(tempbuf,"LEVEL %ld",ud.m_level_number+1); + menutext(c,57+16+16-9,SHX(-4),PHX(-4),tempbuf); + + menutext(c,57+16+16+16-9,SHX(-5),PHX(-5),"MONSTERS"); + + if(gametype_flags[ud.m_coop] & GAMETYPE_FLAG_MARKEROPTION) + menutext(c,57+16+16+16+16-9,SHX(-6),PHX(-6),"MARKERS"); + else + menutext(c,57+16+16+16+16-9,SHX(-6),1,"MARKERS"); + + if(gametype_flags[ud.m_coop] & GAMETYPE_FLAG_COOP) + menutext(c,57+16+16+16+16+16-9,SHX(-6),PHX(-6),"FR. FIRE"); + else menutext(c,57+16+16+16+16+16-9,SHX(-6),1,"FR. FIRE"); + + if (VOLUMEALL) { + menutext(c,57+16+16+16+16+16+16-9,SHX(-7),boardfilename[0] == 0,"USER MAP"); + if( boardfilename[0] != 0 ) + gametext(c+70+44,57+16+16+16+16+16,boardfilename,0,2+8+16); + } else { + menutext(c,57+16+16+16+16+16+16-9,SHX(-7),1,"USER MAP"); + } + + menutext(c,57+16+16+16+16+16+16+16-9,SHX(-8),PHX(-8),"START GAME"); + + break; + } + + if( (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU) + { + vscrn(); + cameraclock = totalclock; + cameradist = 65536L; + } +} diff --git a/polymer/eduke32/source/misc/buildres.rc b/polymer/eduke32/source/misc/buildres.rc new file mode 100644 index 000000000..5f22e6354 --- /dev/null +++ b/polymer/eduke32/source/misc/buildres.rc @@ -0,0 +1,30 @@ +#include + +100 ICON "rsrc/build_icon.ico" +200 BITMAP "rsrc/build.bmp" + +1000 DIALOGEX DISCARDABLE 20, 40, 265, 233 +STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +CAPTION "Startup" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", 100, "STATIC", SS_BITMAP | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 5, 5, 255, 255 + CONTROL "Starting Build Editor for Duke Nukem 3D...", 101, "STATIC", SS_CENTER | WS_CHILD | WS_VISIBLE, 5, 79, 255, 8 + CONTROL "", 102, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 5, 92, 255, 138 +END + +2000 DIALOGEX DISCARDABLE 20, 40, 279, 168 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | DS_CONTROL +CAPTION "Dialog" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Video mode", -1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 5, 3, 128, 64 + CONTROL "&Fullscreen", 100, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 45, 15, 49, 10 + CONTROL "&2D mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 30, 37, 8 + CONTROL "", 101, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 50, 28, 75, 56 + CONTROL "&3D mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 47, 37, 8 + CONTROL "", 102, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 50, 46, 75, 56 + CONTROL "&Continue", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 140, 145, 64, 17 + CONTROL "E&xit", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 208, 145, 64, 17 +END + diff --git a/polymer/eduke32/source/misc/gameres.rc b/polymer/eduke32/source/misc/gameres.rc new file mode 100644 index 000000000..df1d1c2f2 --- /dev/null +++ b/polymer/eduke32/source/misc/gameres.rc @@ -0,0 +1,14 @@ +#include + +100 ICON "rsrc/game_icon.ico" +200 BITMAP "rsrc/game.bmp" + +1000 DIALOGEX DISCARDABLE 20, 40, 265, 233 +STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU +CAPTION "Startup" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", 100, "STATIC", SS_BITMAP | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 5, 5, 255, 255 + CONTROL "Starting EDuke32...", 101, "STATIC", SS_CENTER | WS_CHILD | WS_VISIBLE, 5, 79, 255, 8 + CONTROL "", 102, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 5, 92, 255, 138 +END diff --git a/polymer/eduke32/source/names.h b/polymer/eduke32/source/names.h new file mode 100644 index 000000000..aa4803f84 --- /dev/null +++ b/polymer/eduke32/source/names.h @@ -0,0 +1,766 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2004, 2005 - Richard Gobeille (EDuke32 functionality) + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + +#define SECTOREFFECTOR 1 +#define ACTIVATOR 2 +#define TOUCHPLATE 3 +#define ACTIVATORLOCKED 4 +#define MUSICANDSFX 5 +#define LOCATORS 6 +#define CYCLER 7 +#define MASTERSWITCH 8 +#define RESPAWN 9 +#define GPSPEED 10 +#define FOF 13 +#define ARROW 20 +#define FIRSTGUNSPRITE 21 +#define CHAINGUNSPRITE 22 +#define RPGSPRITE 23 +#define FREEZESPRITE 24 +#define SHRINKERSPRITE 25 +#define HEAVYHBOMB 26 +#define TRIPBOMBSPRITE 27 +#define SHOTGUNSPRITE 28 +#define DEVISTATORSPRITE 29 +#define HEALTHBOX 30 +#define AMMOBOX 31 +#define GROWSPRITEICON 32 +#define INVENTORYBOX 33 +#define FREEZEAMMO 37 +#define AMMO 40 +#define BATTERYAMMO 41 +#define DEVISTATORAMMO 42 +#define RPGAMMO 44 +#define GROWAMMO 45 +#define CRYSTALAMMO 46 +#define HBOMBAMMO 47 +#define AMMOLOTS 48 +#define SHOTGUNAMMO 49 +#define COLA 51 +#define SIXPAK 52 +#define FIRSTAID 53 +#define SHIELD 54 +#define STEROIDS 55 +#define AIRTANK 56 +#define JETPACK 57 +#define HEATSENSOR 59 +#define ACCESSCARD 60 +#define BOOTS 61 +#define MIRRORBROKE 70 +#define CLOUDYOCEAN 78 +#define CLOUDYSKIES 79 +#define MOONSKY1 80 +#define MOONSKY2 81 +#define MOONSKY3 82 +#define MOONSKY4 83 +#define BIGORBIT1 84 +#define BIGORBIT2 85 +#define BIGORBIT3 86 +#define BIGORBIT4 87 +#define BIGORBIT5 88 +#define LA 89 +#define REDSKY1 98 +#define REDSKY2 99 +#define ATOMICHEALTH 100 +#define TECHLIGHT2 120 +#define TECHLIGHTBUST2 121 +#define TECHLIGHT4 122 +#define TECHLIGHTBUST4 123 +#define WALLLIGHT4 124 +#define WALLLIGHTBUST4 125 +#define ACCESSSWITCH 130 +#define SLOTDOOR 132 +#define LIGHTSWITCH 134 +#define SPACEDOORSWITCH 136 +#define SPACELIGHTSWITCH 138 +#define FRANKENSTINESWITCH 140 +#define NUKEBUTTON 142 +#define MULTISWITCH 146 +#define DOORTILE5 150 +#define DOORTILE6 151 +#define DOORTILE1 152 +#define DOORTILE2 153 +#define DOORTILE3 154 +#define DOORTILE4 155 +#define DOORTILE7 156 +#define DOORTILE8 157 +#define DOORTILE9 158 +#define DOORTILE10 159 +#define DOORSHOCK 160 +#define DIPSWITCH 162 +#define DIPSWITCH2 164 +#define TECHSWITCH 166 +#define DIPSWITCH3 168 +#define ACCESSSWITCH2 170 +#define REFLECTWATERTILE 180 +#define FLOORSLIME 200 +#define BIGFORCE 230 +#define EPISODE 247 +#define MASKWALL9 255 +#define W_LIGHT 260 +#define SCREENBREAK1 263 +#define SCREENBREAK2 264 +#define SCREENBREAK3 265 +#define SCREENBREAK4 266 +#define SCREENBREAK5 267 +#define SCREENBREAK6 268 +#define SCREENBREAK7 269 +#define SCREENBREAK8 270 +#define SCREENBREAK9 271 +#define SCREENBREAK10 272 +#define SCREENBREAK11 273 +#define SCREENBREAK12 274 +#define SCREENBREAK13 275 +#define MASKWALL1 285 +#define W_TECHWALL1 293 +#define W_TECHWALL2 297 +#define W_TECHWALL15 299 +#define W_TECHWALL3 301 +#define W_TECHWALL4 305 +#define W_TECHWALL10 306 +#define W_TECHWALL16 307 +#define WATERTILE2 336 +#define BPANNEL1 341 +#define PANNEL1 342 +#define PANNEL2 343 +#define WATERTILE 344 +#define STATIC 351 +#define W_SCREENBREAK 357 +#define W_HITTECHWALL3 360 +#define W_HITTECHWALL4 361 +#define W_HITTECHWALL2 362 +#define W_HITTECHWALL1 363 +#define MASKWALL10 387 +#define MASKWALL11 391 +#define DOORTILE22 395 +#define FANSPRITE 407 +#define FANSPRITEBROKE 411 +#define FANSHADOW 412 +#define FANSHADOWBROKE 416 +#define DOORTILE18 447 +#define DOORTILE19 448 +#define DOORTILE20 449 +// #define SPACESHUTTLE 487 +#define SATELLITE 489 +#define VIEWSCREEN2 499 +#define VIEWSCREENBROKE 501 +#define VIEWSCREEN 502 +#define GLASS 503 +#define GLASS2 504 +#define STAINGLASS1 510 +#define MASKWALL5 514 +#define SATELITE 516 +#define FUELPOD 517 +#define SLIMEPIPE 538 +#define CRACK1 546 +#define CRACK2 547 +#define CRACK3 548 +#define CRACK4 549 +#define FOOTPRINTS 550 +#define DOMELITE 551 +#define CAMERAPOLE 554 +#define CHAIR1 556 +#define CHAIR2 557 +#define BROKENCHAIR 559 +#define MIRROR 560 +#define WATERFOUNTAIN 563 +#define WATERFOUNTAINBROKE 567 +#define FEMMAG1 568 +#define TOILET 569 +#define STALL 571 +#define STALLBROKE 573 +#define FEMMAG2 577 +#define REACTOR2 578 +#define REACTOR2BURNT 579 +#define REACTOR2SPARK 580 +#define GRATE1 595 +#define BGRATE1 596 +#define SOLARPANNEL 602 +#define NAKED1 603 +#define ANTENNA 607 +#define MASKWALL12 609 +#define TOILETBROKE 615 +#define PIPE2 616 +#define PIPE1B 617 +#define PIPE3 618 +#define PIPE1 619 +#define CAMERA1 621 +#define BRICK 626 +#define SPLINTERWOOD 630 +#define PIPE2B 633 +#define BOLT1 634 +#define W_NUMBERS 640 +#define WATERDRIP 660 +#define WATERBUBBLE 661 +#define WATERBUBBLEMAKER 662 +#define W_FORCEFIELD 663 +#define VACUUM 669 +#define FOOTPRINTS2 672 +#define FOOTPRINTS3 673 +#define FOOTPRINTS4 674 +#define EGG 675 +#define SCALE 678 +#define CHAIR3 680 +#define CAMERALIGHT 685 +#define MOVIECAMERA 686 +#define IVUNIT 689 +#define POT1 694 +#define POT2 695 +#define POT3 697 +#define PIPE3B 700 +#define WALLLIGHT3 701 +#define WALLLIGHTBUST3 702 +#define WALLLIGHT1 703 +#define WALLLIGHTBUST1 704 +#define WALLLIGHT2 705 +#define WALLLIGHTBUST2 706 +#define LIGHTSWITCH2 712 +#define WAITTOBESEATED 716 +#define DOORTILE14 717 +#define STATUE 753 +#define MIKE 762 +#define VASE 765 +#define SUSHIPLATE1 768 +#define SUSHIPLATE2 769 +#define SUSHIPLATE3 774 +#define SUSHIPLATE4 779 +#define DOORTILE16 781 +#define SUSHIPLATE5 792 +#define OJ 806 +#define MASKWALL13 830 +#define HURTRAIL 859 +#define POWERSWITCH1 860 +#define LOCKSWITCH1 862 +#define POWERSWITCH2 864 +#define ATM 867 +#define STATUEFLASH 869 +#define ATMBROKE 888 +#define BIGHOLE2 893 +#define STRIPEBALL 901 +#define QUEBALL 902 +#define POCKET 903 +#define WOODENHORSE 904 +#define TREE1 908 +#define TREE2 910 +#define CACTUS 911 +#define MASKWALL2 913 +#define MASKWALL3 914 +#define MASKWALL4 915 +#define FIREEXT 916 +#define TOILETWATER 921 +#define NEON1 925 +#define NEON2 926 +#define CACTUSBROKE 939 +#define BOUNCEMINE 940 +#define BROKEFIREHYDRENT 950 +#define BOX 951 +#define BULLETHOLE 952 +#define BOTTLE1 954 +#define BOTTLE2 955 +#define BOTTLE3 956 +#define BOTTLE4 957 +#define FEMPIC5 963 +#define FEMPIC6 964 +#define FEMPIC7 965 +#define HYDROPLANT 969 +#define OCEANSPRITE1 971 +#define OCEANSPRITE2 972 +#define OCEANSPRITE3 973 +#define OCEANSPRITE4 974 +#define OCEANSPRITE5 975 +#define GENERICPOLE 977 +#define CONE 978 +#define HANGLIGHT 979 +#define HYDRENT 981 +#define MASKWALL14 988 +#define TIRE 990 +#define PIPE5 994 +#define PIPE6 995 +#define PIPE4 996 +#define PIPE4B 997 +#define BROKEHYDROPLANT 1003 +#define PIPE5B 1005 +#define NEON3 1007 +#define NEON4 1008 +#define NEON5 1009 +#define BOTTLE5 1012 +#define BOTTLE6 1013 +#define BOTTLE8 1014 +#define SPOTLITE 1020 +#define HANGOOZ 1022 +#define MASKWALL15 1024 +#define BOTTLE7 1025 +#define HORSEONSIDE 1026 +#define GLASSPIECES 1031 +#define HORSELITE 1034 +#define DONUTS 1045 +#define NEON6 1046 +#define MASKWALL6 1059 +#define CLOCK 1060 +#define RUBBERCAN 1062 +#define BROKENCLOCK 1067 +#define PLUG 1069 +#define OOZFILTER 1079 +#define FLOORPLASMA 1082 +#define REACTOR 1088 +#define REACTORSPARK 1092 +#define REACTORBURNT 1096 +#define DOORTILE15 1102 +#define HANDSWITCH 1111 +#define CIRCLEPANNEL 1113 +#define CIRCLEPANNELBROKE 1114 +#define PULLSWITCH 1122 +#define MASKWALL8 1124 +#define BIGHOLE 1141 +#define ALIENSWITCH 1142 +#define DOORTILE21 1144 +#define HANDPRINTSWITCH 1155 +#define BOTTLE10 1157 +#define BOTTLE11 1158 +#define BOTTLE12 1159 +#define BOTTLE13 1160 +#define BOTTLE14 1161 +#define BOTTLE15 1162 +#define BOTTLE16 1163 +#define BOTTLE17 1164 +#define BOTTLE18 1165 +#define BOTTLE19 1166 +#define DOORTILE17 1169 +#define MASKWALL7 1174 +#define JAILBARBREAK 1175 +#define DOORTILE11 1178 +#define DOORTILE12 1179 +#define VENDMACHINE 1212 +#define VENDMACHINEBROKE 1214 +#define COLAMACHINE 1215 +#define COLAMACHINEBROKE 1217 +#define CRANEPOLE 1221 +#define CRANE 1222 +#define BARBROKE 1225 +#define BLOODPOOL 1226 +#define NUKEBARREL 1227 +#define NUKEBARRELDENTED 1228 +#define NUKEBARRELLEAKED 1229 +#define CANWITHSOMETHING 1232 +#define MONEY 1233 +#define BANNER 1236 +#define EXPLODINGBARREL 1238 +#define EXPLODINGBARREL2 1239 +#define FIREBARREL 1240 +#define SEENINE 1247 +#define SEENINEDEAD 1248 +#define STEAM 1250 +#define CEILINGSTEAM 1255 +#define PIPE6B 1260 +#define TRANSPORTERBEAM 1261 +#define RAT 1267 +#define TRASH 1272 +#define FEMPIC1 1280 +#define FEMPIC2 1289 +#define BLANKSCREEN 1293 +#define PODFEM1 1294 +#define FEMPIC3 1298 +#define FEMPIC4 1306 +#define FEM1 1312 +#define FEM2 1317 +#define FEM3 1321 +#define FEM5 1323 +#define BLOODYPOLE 1324 +#define FEM4 1325 +#define FEM6 1334 +#define FEM6PAD 1335 +#define FEM8 1336 +#define HELECOPT 1346 +#define FETUSJIB 1347 +#define HOLODUKE 1348 +#define SPACEMARINE 1353 +#define INDY 1355 +#define FETUS 1358 +#define FETUSBROKE 1359 +#define MONK 1352 +#define LUKE 1354 +#define COOLEXPLOSION1 1360 +#define WATERSPLASH2 1380 +#define FIREVASE 1390 +#define SCRATCH 1393 +#define FEM7 1395 +#define APLAYERTOP 1400 +#define APLAYER 1405 +#define PLAYERONWATER 1420 +#define DUKELYINGDEAD 1518 +#define DUKETORSO 1520 +#define DUKEGUN 1528 +#define DUKELEG 1536 +#define SHARK 1550 +#define BLOOD 1620 +#define FIRELASER 1625 +#define TRANSPORTERSTAR 1630 +#define SPIT 1636 +#define LOOGIE 1637 +#define FIST 1640 +#define FREEZEBLAST 1641 +#define DEVISTATORBLAST 1642 +#define SHRINKSPARK 1646 +#define TONGUE 1647 +#define MORTER 1650 +#define SHRINKEREXPLOSION 1656 +#define RADIUSEXPLOSION 1670 +#define FORCERIPPLE 1671 +#define LIZTROOP 1680 +#define LIZTROOPRUNNING 1681 +#define LIZTROOPSTAYPUT 1682 +#define LIZTOP 1705 +#define LIZTROOPSHOOT 1715 +#define LIZTROOPJETPACK 1725 +#define LIZTROOPDSPRITE 1734 +#define LIZTROOPONTOILET 1741 +#define LIZTROOPJUSTSIT 1742 +#define LIZTROOPDUCKING 1744 +#define HEADJIB1 1768 +#define ARMJIB1 1772 +#define LEGJIB1 1776 +#define CANNONBALL 1817 +#define OCTABRAIN 1820 +#define OCTABRAINSTAYPUT 1821 +#define OCTATOP 1845 +#define OCTADEADSPRITE 1855 +#define INNERJAW 1860 +#define DRONE 1880 +#define EXPLOSION2 1890 +#define COMMANDER 1920 +#define COMMANDERSTAYPUT 1921 +#define RECON 1960 +#define TANK 1975 +#define PIGCOP 2000 +#define PIGCOPSTAYPUT 2001 +#define PIGCOPDIVE 2045 +#define PIGCOPDEADSPRITE 2060 +#define PIGTOP 2061 +#define LIZMAN 2120 +#define LIZMANSTAYPUT 2121 +#define LIZMANSPITTING 2150 +#define LIZMANFEEDING 2160 +#define LIZMANJUMP 2165 +#define LIZMANDEADSPRITE 2185 +#define FECES 2200 +#define LIZMANHEAD1 2201 +#define LIZMANARM1 2205 +#define LIZMANLEG1 2209 +#define EXPLOSION2BOT 2219 +#define USERWEAPON 2235 +#define HEADERBAR 2242 +#define JIBS1 2245 +#define JIBS2 2250 +#define JIBS3 2255 +#define JIBS4 2260 +#define JIBS5 2265 +#define BURNING 2270 +#define FIRE 2271 +#define JIBS6 2286 +#define BLOODSPLAT1 2296 +#define BLOODSPLAT3 2297 +#define BLOODSPLAT2 2298 +#define BLOODSPLAT4 2299 +#define OOZ 2300 +#define OOZ2 2309 +#define WALLBLOOD1 2301 +#define WALLBLOOD2 2302 +#define WALLBLOOD3 2303 +#define WALLBLOOD4 2304 +#define WALLBLOOD5 2305 +#define WALLBLOOD6 2306 +#define WALLBLOOD7 2307 +#define WALLBLOOD8 2308 +#define BURNING2 2310 +#define FIRE2 2311 +#define CRACKKNUCKLES 2324 +#define SMALLSMOKE 2329 +#define SMALLSMOKEMAKER 2330 +#define FLOORFLAME 2333 +#define ROTATEGUN 2360 +#define GREENSLIME 2370 +#define WATERDRIPSPLASH 2380 +#define SCRAP6 2390 +#define SCRAP1 2400 +#define SCRAP2 2404 +#define SCRAP3 2408 +#define SCRAP4 2412 +#define SCRAP5 2416 +#define ORGANTIC 2420 +#define BETAVERSION 2440 +#define PLAYERISHERE 2442 +#define PLAYERWASHERE 2443 +#define SELECTDIR 2444 +#define F1HELP 2445 +#define NOTCHON 2446 +#define NOTCHOFF 2447 +#define GROWSPARK 2448 +#define DUKEICON 2452 +#define BADGUYICON 2453 +#define FOODICON 2454 +#define GETICON 2455 +#define MENUSCREEN 2456 +#define MENUBAR 2457 +#define KILLSICON 2458 +#define FIRSTAID_ICON 2460 +#define HEAT_ICON 2461 +#define BOTTOMSTATUSBAR 2462 +#define BOOT_ICON 2463 +#define FRAGBAR 2465 +#define JETPACK_ICON 2467 +#define AIRTANK_ICON 2468 +#define STEROIDS_ICON 2469 +#define HOLODUKE_ICON 2470 +#define ACCESS_ICON 2471 +#define DIGITALNUM 2472 +#define DUKECAR 2491 +#define CAMCORNER 2482 +#define CAMLIGHT 2484 +#define LOGO 2485 +#define TITLE 2486 +#define NUKEWARNINGICON 2487 +#define MOUSECURSOR 2488 +#define SLIDEBAR 2489 +#define DREALMS 2492 +#define BETASCREEN 2493 +#define WINDOWBORDER1 2494 +#define TEXTBOX 2495 +#define WINDOWBORDER2 2496 +#define DUKENUKEM 2497 +#define THREEDEE 2498 +#define INGAMEDUKETHREEDEE 2499 +#define TENSCREEN 2500 +#define PLUTOPAKSPRITE 2501 +#define DEVISTATOR 2510 +#define KNEE 2521 +#define CROSSHAIR 2523 +#define FIRSTGUN 2524 +#define FIRSTGUNRELOAD 2528 +#define FALLINGCLIP 2530 +#define CLIPINHAND 2531 +#define HAND 2532 +#define SHELL 2533 +#define SHOTGUNSHELL 2535 +#define CHAINGUN 2536 +#define RPGGUN 2544 +#define RPGMUZZLEFLASH 2545 +#define FREEZE 2548 +#define CATLITE 2552 +#define SHRINKER 2556 +#define HANDHOLDINGLASER 2563 +#define TRIPBOMB 2566 +#define LASERLINE 2567 +#define HANDHOLDINGACCESS 2568 +#define HANDREMOTE 2570 +#define HANDTHROW 2573 +#define TIP 2576 +#define GLAIR 2578 +#define SCUBAMASK 2581 +#define SPACEMASK 2584 +#define FORCESPHERE 2590 +#define SHOTSPARK1 2595 +#define RPG 2605 +#define LASERSITE 2612 +#define SHOTGUN 2613 +#define BOSS1 2630 +#define BOSS1STAYPUT 2631 +#define BOSS1SHOOT 2660 +#define BOSS1LOB 2670 +#define BOSSTOP 2696 +#define BOSS2 2710 +#define BOSS3 2760 +#define SPINNINGNUKEICON 2813 +#define BIGFNTCURSOR 2820 +#define SMALLFNTCURSOR 2821 +#define STARTALPHANUM 2822 +#define ENDALPHANUM 2915 +#define BIGALPHANUM 2940 +#define BIGPERIOD 3002 +#define BIGCOMMA 3003 +#define BIGX 3004 +#define BIGQ 3005 +#define BIGSEMI 3006 +#define BIGCOLIN 3007 +#define THREEBYFIVE 3010 +#define BIGAPPOS 3022 +#define BLANK 3026 +#define MINIFONT 3072 +#define BUTTON1 3164 +#define GLASS3 3187 +#define RESPAWNMARKERRED 3190 +#define RESPAWNMARKERYELLOW 3200 +#define RESPAWNMARKERGREEN 3210 +#define BONUSSCREEN 3240 +#define VIEWBORDER 3250 +#define VICTORY1 3260 +#define ORDERING 3270 +#define TEXTSTORY 3280 +#define LOADSCREEN 3281 +#define BORNTOBEWILDSCREEN 3370 +#define BLIMP 3400 +#define FEM9 3450 +#define FOOTPRINT 3701 +#define FRAMEEFFECT1_13 3999 +#define POOP 4094 +#define FRAMEEFFECT1 4095 +#define PANNEL3 4099 +#define SCREENBREAK14 4120 +#define SCREENBREAK15 4123 +#define SCREENBREAK19 4125 +#define SCREENBREAK16 4127 +#define SCREENBREAK17 4128 +#define SCREENBREAK18 4129 +#define W_TECHWALL11 4130 +#define W_TECHWALL12 4131 +#define W_TECHWALL13 4132 +#define W_TECHWALL14 4133 +#define W_TECHWALL5 4134 +#define W_TECHWALL6 4136 +#define W_TECHWALL7 4138 +#define W_TECHWALL8 4140 +#define W_TECHWALL9 4142 +#define BPANNEL3 4100 +#define W_HITTECHWALL16 4144 +#define W_HITTECHWALL10 4145 +#define W_HITTECHWALL15 4147 +#define W_MILKSHELF 4181 +#define W_MILKSHELFBROKE 4203 +#define PURPLELAVA 4240 +#define LAVABUBBLE 4340 +#define DUKECUTOUT 4352 +#define TARGET 4359 +#define GUNPOWDERBARREL 4360 +#define DUCK 4361 +#define HATRACK 4367 +#define DESKLAMP 4370 +#define COFFEEMACHINE 4372 +#define CUPS 4373 +#define GAVALS 4374 +#define GAVALS2 4375 +#define POLICELIGHTPOLE 4377 +#define FLOORBASKET 4388 +#define PUKE 4389 +#define DOORTILE23 4391 +#define TOPSECRET 4396 +#define SPEAKER 4397 +#define TEDDYBEAR 4400 +#define ROBOTDOG 4402 +#define ROBOTPIRATE 4404 +#define ROBOTMOUSE 4407 +#define MAIL 4410 +#define MAILBAG 4413 +#define HOTMEAT 4427 +#define COFFEEMUG 4438 +#define DONUTS2 4440 +#define TRIPODCAMERA 4444 +#define METER 4453 +#define DESKPHONE 4454 +#define GUMBALLMACHINE 4458 +#define GUMBALLMACHINEBROKE 4459 +#define PAPER 4460 +#define MACE 4464 +#define GENERICPOLE2 4465 +#define XXXSTACY 4470 +#define WETFLOOR 4495 +#define BROOM 4496 +#define MOP 4497 +#define LETTER 4502 +#define PIRATE1A 4510 +#define PIRATE4A 4511 +#define PIRATE2A 4512 +#define PIRATE5A 4513 +#define PIRATE3A 4514 +#define PIRATE6A 4515 +#define PIRATEHALF 4516 +#define CHESTOFGOLD 4520 +#define SIDEBOLT1 4525 +#define FOODOBJECT1 4530 +#define FOODOBJECT2 4531 +#define FOODOBJECT3 4532 +#define FOODOBJECT4 4533 +#define FOODOBJECT5 4534 +#define FOODOBJECT6 4535 +#define FOODOBJECT7 4536 +#define FOODOBJECT8 4537 +#define FOODOBJECT9 4538 +#define FOODOBJECT10 4539 +#define FOODOBJECT11 4540 +#define FOODOBJECT12 4541 +#define FOODOBJECT13 4542 +#define FOODOBJECT14 4543 +#define FOODOBJECT15 4544 +#define FOODOBJECT16 4545 +#define FOODOBJECT17 4546 +#define FOODOBJECT18 4547 +#define FOODOBJECT19 4548 +#define FOODOBJECT20 4549 +#define HEADLAMP 4550 +#define TAMPON 4557 +#define SKINNEDCHICKEN 4554 +#define FEATHEREDCHICKEN 4555 +#define ROBOTDOG2 4560 +#define JOLLYMEAL 4569 +#define DUKEBURGER 4570 +#define SHOPPINGCART 4576 +#define CANWITHSOMETHING2 4580 +#define CANWITHSOMETHING3 4581 +#define CANWITHSOMETHING4 4582 +#define SNAKEP 4590 +#define DOLPHIN1 4591 +#define DOLPHIN2 4592 +#define NEWBEAST 4610 +#define NEWBEASTSTAYPUT 4611 +#define NEWBEASTJUMP 4690 +#define NEWBEASTHANG 4670 +#define NEWBEASTHANGDEAD 4671 +#define BOSS4 4740 +#define BOSS4STAYPUT 4741 +#define FEM10 4864 +#define TOUGHGAL 4866 +#define MAN 4871 +#define MAN2 4872 +#define WOMAN 4874 +#define PLEASEWAIT 4887 +#define NATURALLIGHTNING 4890 +#define WEATHERWARN 4893 +#define DUKETAG 4900 +#define SIGN1 4909 +#define SIGN2 4912 +#define JURYGUY 4943 + +// These tile positions are reserved! +#define RESERVEDSLOT1 6132 +#define RESERVEDSLOT2 6133 +#define RESERVEDSLOT3 6134 +#define RESERVEDSLOT4 6135 +#define RESERVEDSLOT5 6136 +#define RESERVEDSLOT6 6137 +#define RESERVEDSLOT7 6138 +#define RESERVEDSLOT8 6139 +#define RESERVEDSLOT9 6140 +#define RESERVEDSLOT10 6141 +#define RESERVEDSLOT11 6142 +#define RESERVEDSLOT12 6143 diff --git a/polymer/eduke32/source/namesdyn.c b/polymer/eduke32/source/namesdyn.c new file mode 100644 index 000000000..24999b8c3 --- /dev/null +++ b/polymer/eduke32/source/namesdyn.c @@ -0,0 +1,2421 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +// Maybe this should be called "hacks.c" instead of "namesdyn.c"... + +#include "build.h" +#include "duke3d.h" +#include "compat.h" + +unsigned short SECTOREFFECTOR = 1; +unsigned short ACTIVATOR = 2; +unsigned short TOUCHPLATE = 3; +unsigned short ACTIVATORLOCKED = 4; +unsigned short MUSICANDSFX = 5; +unsigned short LOCATORS = 6; +unsigned short CYCLER = 7; +unsigned short MASTERSWITCH = 8; +unsigned short RESPAWN = 9; +unsigned short GPSPEED = 10; +unsigned short FOF = 13; +unsigned short ARROW = 20; +unsigned short FIRSTGUNSPRITE = 21; +unsigned short CHAINGUNSPRITE = 22; +unsigned short RPGSPRITE = 23; +unsigned short FREEZESPRITE = 24; +unsigned short SHRINKERSPRITE = 25; +unsigned short HEAVYHBOMB = 26; +unsigned short TRIPBOMBSPRITE = 27; +unsigned short SHOTGUNSPRITE = 28; +unsigned short DEVISTATORSPRITE = 29; +unsigned short HEALTHBOX = 30; +unsigned short AMMOBOX = 31; +unsigned short GROWSPRITEICON = 32; +unsigned short INVENTORYBOX = 33; +unsigned short FREEZEAMMO = 37; +unsigned short AMMO = 40; +unsigned short BATTERYAMMO = 41; +unsigned short DEVISTATORAMMO = 42; +unsigned short RPGAMMO = 44; +unsigned short GROWAMMO = 45; +unsigned short CRYSTALAMMO = 46; +unsigned short HBOMBAMMO = 47; +unsigned short AMMOLOTS = 48; +unsigned short SHOTGUNAMMO = 49; +unsigned short COLA = 51; +unsigned short SIXPAK = 52; +unsigned short FIRSTAID = 53; +unsigned short SHIELD = 54; +unsigned short STEROIDS = 55; +unsigned short AIRTANK = 56; +unsigned short JETPACK = 57; +unsigned short HEATSENSOR = 59; +unsigned short ACCESSCARD = 60; +unsigned short BOOTS = 61; +unsigned short MIRRORBROKE = 70; +unsigned short CLOUDYOCEAN = 78; +unsigned short CLOUDYSKIES = 79; +unsigned short MOONSKY1 = 80; +unsigned short MOONSKY2 = 81; +unsigned short MOONSKY3 = 82; +unsigned short MOONSKY4 = 83; +unsigned short BIGORBIT1 = 84; +unsigned short BIGORBIT2 = 85; +unsigned short BIGORBIT3 = 86; +unsigned short BIGORBIT4 = 87; +unsigned short BIGORBIT5 = 88; +unsigned short LA = 89; +unsigned short REDSKY1 = 98; +unsigned short REDSKY2 = 99; +unsigned short ATOMICHEALTH = 100; +unsigned short TECHLIGHT2 = 120; +unsigned short TECHLIGHTBUST2 = 121; +unsigned short TECHLIGHT4 = 122; +unsigned short TECHLIGHTBUST4 = 123; +unsigned short WALLLIGHT4 = 124; +unsigned short WALLLIGHTBUST4 = 125; +unsigned short ACCESSSWITCH = 130; +unsigned short SLOTDOOR = 132; +unsigned short LIGHTSWITCH = 134; +unsigned short SPACEDOORSWITCH = 136; +unsigned short SPACELIGHTSWITCH = 138; +unsigned short FRANKENSTINESWITCH = 140; +unsigned short NUKEBUTTON = 142; +unsigned short MULTISWITCH = 146; +unsigned short DOORTILE5 = 150; +unsigned short DOORTILE6 = 151; +unsigned short DOORTILE1 = 152; +unsigned short DOORTILE2 = 153; +unsigned short DOORTILE3 = 154; +unsigned short DOORTILE4 = 155; +unsigned short DOORTILE7 = 156; +unsigned short DOORTILE8 = 157; +unsigned short DOORTILE9 = 158; +unsigned short DOORTILE10 = 159; +unsigned short DOORSHOCK = 160; +unsigned short DIPSWITCH = 162; +unsigned short DIPSWITCH2 = 164; +unsigned short TECHSWITCH = 166; +unsigned short DIPSWITCH3 = 168; +unsigned short ACCESSSWITCH2 = 170; +unsigned short REFLECTWATERTILE = 180; +unsigned short FLOORSLIME = 200; +unsigned short BIGFORCE = 230; +unsigned short EPISODE = 247; +unsigned short MASKWALL9 = 255; +unsigned short W_LIGHT = 260; +unsigned short SCREENBREAK1 = 263; +unsigned short SCREENBREAK2 = 264; +unsigned short SCREENBREAK3 = 265; +unsigned short SCREENBREAK4 = 266; +unsigned short SCREENBREAK5 = 267; +unsigned short SCREENBREAK6 = 268; +unsigned short SCREENBREAK7 = 269; +unsigned short SCREENBREAK8 = 270; +unsigned short SCREENBREAK9 = 271; +unsigned short SCREENBREAK10 = 272; +unsigned short SCREENBREAK11 = 273; +unsigned short SCREENBREAK12 = 274; +unsigned short SCREENBREAK13 = 275; +unsigned short MASKWALL1 = 285; +unsigned short W_TECHWALL1 = 293; +unsigned short W_TECHWALL2 = 297; +unsigned short W_TECHWALL15 = 299; +unsigned short W_TECHWALL3 = 301; +unsigned short W_TECHWALL4 = 305; +unsigned short W_TECHWALL10 = 306; +unsigned short W_TECHWALL16 = 307; +unsigned short WATERTILE2 = 336; +unsigned short BPANNEL1 = 341; +unsigned short PANNEL1 = 342; +unsigned short PANNEL2 = 343; +unsigned short WATERTILE = 344; +unsigned short STATIC = 351; +unsigned short W_SCREENBREAK = 357; +unsigned short W_HITTECHWALL3 = 360; +unsigned short W_HITTECHWALL4 = 361; +unsigned short W_HITTECHWALL2 = 362; +unsigned short W_HITTECHWALL1 = 363; +unsigned short MASKWALL10 = 387; +unsigned short MASKWALL11 = 391; +unsigned short DOORTILE22 = 395; +unsigned short FANSPRITE = 407; +unsigned short FANSPRITEBROKE = 411; +unsigned short FANSHADOW = 412; +unsigned short FANSHADOWBROKE = 416; +unsigned short DOORTILE18 = 447; +unsigned short DOORTILE19 = 448; +unsigned short DOORTILE20 = 449; +unsigned short SATELLITE = 489; +unsigned short VIEWSCREEN2 = 499; +unsigned short VIEWSCREENBROKE = 501; +unsigned short VIEWSCREEN = 502; +unsigned short GLASS = 503; +unsigned short GLASS2 = 504; +unsigned short STAINGLASS1 = 510; +unsigned short MASKWALL5 = 514; +unsigned short SATELITE = 516; +unsigned short FUELPOD = 517; +unsigned short SLIMEPIPE = 538; +unsigned short CRACK1 = 546; +unsigned short CRACK2 = 547; +unsigned short CRACK3 = 548; +unsigned short CRACK4 = 549; +unsigned short FOOTPRINTS = 550; +unsigned short DOMELITE = 551; +unsigned short CAMERAPOLE = 554; +unsigned short CHAIR1 = 556; +unsigned short CHAIR2 = 557; +unsigned short BROKENCHAIR = 559; +unsigned short MIRROR = 560; +unsigned short WATERFOUNTAIN = 563; +unsigned short WATERFOUNTAINBROKE = 567; +unsigned short FEMMAG1 = 568; +unsigned short TOILET = 569; +unsigned short STALL = 571; +unsigned short STALLBROKE = 573; +unsigned short FEMMAG2 = 577; +unsigned short REACTOR2 = 578; +unsigned short REACTOR2BURNT = 579; +unsigned short REACTOR2SPARK = 580; +unsigned short GRATE1 = 595; +unsigned short BGRATE1 = 596; +unsigned short SOLARPANNEL = 602; +unsigned short NAKED1 = 603; +unsigned short ANTENNA = 607; +unsigned short MASKWALL12 = 609; +unsigned short TOILETBROKE = 615; +unsigned short PIPE2 = 616; +unsigned short PIPE1B = 617; +unsigned short PIPE3 = 618; +unsigned short PIPE1 = 619; +unsigned short CAMERA1 = 621; +unsigned short BRICK = 626; +unsigned short SPLINTERWOOD = 630; +unsigned short PIPE2B = 633; +unsigned short BOLT1 = 634; +unsigned short W_NUMBERS = 640; +unsigned short WATERDRIP = 660; +unsigned short WATERBUBBLE = 661; +unsigned short WATERBUBBLEMAKER = 662; +unsigned short W_FORCEFIELD = 663; +unsigned short VACUUM = 669; +unsigned short FOOTPRINTS2 = 672; +unsigned short FOOTPRINTS3 = 673; +unsigned short FOOTPRINTS4 = 674; +unsigned short EGG = 675; +unsigned short SCALE = 678; +unsigned short CHAIR3 = 680; +unsigned short CAMERALIGHT = 685; +unsigned short MOVIECAMERA = 686; +unsigned short IVUNIT = 689; +unsigned short POT1 = 694; +unsigned short POT2 = 695; +unsigned short POT3 = 697; +unsigned short PIPE3B = 700; +unsigned short WALLLIGHT3 = 701; +unsigned short WALLLIGHTBUST3 = 702; +unsigned short WALLLIGHT1 = 703; +unsigned short WALLLIGHTBUST1 = 704; +unsigned short WALLLIGHT2 = 705; +unsigned short WALLLIGHTBUST2 = 706; +unsigned short LIGHTSWITCH2 = 712; +unsigned short WAITTOBESEATED = 716; +unsigned short DOORTILE14 = 717; +unsigned short STATUE = 753; +unsigned short MIKE = 762; +unsigned short VASE = 765; +unsigned short SUSHIPLATE1 = 768; +unsigned short SUSHIPLATE2 = 769; +unsigned short SUSHIPLATE3 = 774; +unsigned short SUSHIPLATE4 = 779; +unsigned short DOORTILE16 = 781; +unsigned short SUSHIPLATE5 = 792; +unsigned short OJ = 806; +unsigned short MASKWALL13 = 830; +unsigned short HURTRAIL = 859; +unsigned short POWERSWITCH1 = 860; +unsigned short LOCKSWITCH1 = 862; +unsigned short POWERSWITCH2 = 864; +unsigned short ATM = 867; +unsigned short STATUEFLASH = 869; +unsigned short ATMBROKE = 888; +unsigned short BIGHOLE2 = 893; +unsigned short STRIPEBALL = 901; +unsigned short QUEBALL = 902; +unsigned short POCKET = 903; +unsigned short WOODENHORSE = 904; +unsigned short TREE1 = 908; +unsigned short TREE2 = 910; +unsigned short CACTUS = 911; +unsigned short MASKWALL2 = 913; +unsigned short MASKWALL3 = 914; +unsigned short MASKWALL4 = 915; +unsigned short FIREEXT = 916; +unsigned short TOILETWATER = 921; +unsigned short NEON1 = 925; +unsigned short NEON2 = 926; +unsigned short CACTUSBROKE = 939; +unsigned short BOUNCEMINE = 940; +unsigned short BROKEFIREHYDRENT = 950; +unsigned short BOX = 951; +unsigned short BULLETHOLE = 952; +unsigned short BOTTLE1 = 954; +unsigned short BOTTLE2 = 955; +unsigned short BOTTLE3 = 956; +unsigned short BOTTLE4 = 957; +unsigned short FEMPIC5 = 963; +unsigned short FEMPIC6 = 964; +unsigned short FEMPIC7 = 965; +unsigned short HYDROPLANT = 969; +unsigned short OCEANSPRITE1 = 971; +unsigned short OCEANSPRITE2 = 972; +unsigned short OCEANSPRITE3 = 973; +unsigned short OCEANSPRITE4 = 974; +unsigned short OCEANSPRITE5 = 975; +unsigned short GENERICPOLE = 977; +unsigned short CONE = 978; +unsigned short HANGLIGHT = 979; +unsigned short HYDRENT = 981; +unsigned short MASKWALL14 = 988; +unsigned short TIRE = 990; +unsigned short PIPE5 = 994; +unsigned short PIPE6 = 995; +unsigned short PIPE4 = 996; +unsigned short PIPE4B = 997; +unsigned short BROKEHYDROPLANT = 1003; +unsigned short PIPE5B = 1005; +unsigned short NEON3 = 1007; +unsigned short NEON4 = 1008; +unsigned short NEON5 = 1009; +unsigned short BOTTLE5 = 1012; +unsigned short BOTTLE6 = 1013; +unsigned short BOTTLE8 = 1014; +unsigned short SPOTLITE = 1020; +unsigned short HANGOOZ = 1022; +unsigned short MASKWALL15 = 1024; +unsigned short BOTTLE7 = 1025; +unsigned short HORSEONSIDE = 1026; +unsigned short GLASSPIECES = 1031; +unsigned short HORSELITE = 1034; +unsigned short DONUTS = 1045; +unsigned short NEON6 = 1046; +unsigned short MASKWALL6 = 1059; +unsigned short CLOCK = 1060; +unsigned short RUBBERCAN = 1062; +unsigned short BROKENCLOCK = 1067; +unsigned short PLUG = 1069; +unsigned short OOZFILTER = 1079; +unsigned short FLOORPLASMA = 1082; +unsigned short REACTOR = 1088; +unsigned short REACTORSPARK = 1092; +unsigned short REACTORBURNT = 1096; +unsigned short DOORTILE15 = 1102; +unsigned short HANDSWITCH = 1111; +unsigned short CIRCLEPANNEL = 1113; +unsigned short CIRCLEPANNELBROKE = 1114; +unsigned short PULLSWITCH = 1122; +unsigned short MASKWALL8 = 1124; +unsigned short BIGHOLE = 1141; +unsigned short ALIENSWITCH = 1142; +unsigned short DOORTILE21 = 1144; +unsigned short HANDPRINTSWITCH = 1155; +unsigned short BOTTLE10 = 1157; +unsigned short BOTTLE11 = 1158; +unsigned short BOTTLE12 = 1159; +unsigned short BOTTLE13 = 1160; +unsigned short BOTTLE14 = 1161; +unsigned short BOTTLE15 = 1162; +unsigned short BOTTLE16 = 1163; +unsigned short BOTTLE17 = 1164; +unsigned short BOTTLE18 = 1165; +unsigned short BOTTLE19 = 1166; +unsigned short DOORTILE17 = 1169; +unsigned short MASKWALL7 = 1174; +unsigned short JAILBARBREAK = 1175; +unsigned short DOORTILE11 = 1178; +unsigned short DOORTILE12 = 1179; +unsigned short VENDMACHINE = 1212; +unsigned short VENDMACHINEBROKE = 1214; +unsigned short COLAMACHINE = 1215; +unsigned short COLAMACHINEBROKE = 1217; +unsigned short CRANEPOLE = 1221; +unsigned short CRANE = 1222; +unsigned short BARBROKE = 1225; +unsigned short BLOODPOOL = 1226; +unsigned short NUKEBARREL = 1227; +unsigned short NUKEBARRELDENTED = 1228; +unsigned short NUKEBARRELLEAKED = 1229; +unsigned short CANWITHSOMETHING = 1232; +unsigned short MONEY = 1233; +unsigned short BANNER = 1236; +unsigned short EXPLODINGBARREL = 1238; +unsigned short EXPLODINGBARREL2 = 1239; +unsigned short FIREBARREL = 1240; +unsigned short SEENINE = 1247; +unsigned short SEENINEDEAD = 1248; +unsigned short STEAM = 1250; +unsigned short CEILINGSTEAM = 1255; +unsigned short PIPE6B = 1260; +unsigned short TRANSPORTERBEAM = 1261; +unsigned short RAT = 1267; +unsigned short TRASH = 1272; +unsigned short FEMPIC1 = 1280; +unsigned short FEMPIC2 = 1289; +unsigned short BLANKSCREEN = 1293; +unsigned short PODFEM1 = 1294; +unsigned short FEMPIC3 = 1298; +unsigned short FEMPIC4 = 1306; +unsigned short FEM1 = 1312; +unsigned short FEM2 = 1317; +unsigned short FEM3 = 1321; +unsigned short FEM5 = 1323; +unsigned short BLOODYPOLE = 1324; +unsigned short FEM4 = 1325; +unsigned short FEM6 = 1334; +unsigned short FEM6PAD = 1335; +unsigned short FEM8 = 1336; +unsigned short HELECOPT = 1346; +unsigned short FETUSJIB = 1347; +unsigned short HOLODUKE = 1348; +unsigned short SPACEMARINE = 1353; +unsigned short INDY = 1355; +unsigned short FETUS = 1358; +unsigned short FETUSBROKE = 1359; +unsigned short MONK = 1352; +unsigned short LUKE = 1354; +unsigned short COOLEXPLOSION1 = 1360; +unsigned short WATERSPLASH2 = 1380; +unsigned short FIREVASE = 1390; +unsigned short SCRATCH = 1393; +unsigned short FEM7 = 1395; +unsigned short APLAYERTOP = 1400; +unsigned short APLAYER = 1405; +unsigned short PLAYERONWATER = 1420; +unsigned short DUKELYINGDEAD = 1518; +unsigned short DUKETORSO = 1520; +unsigned short DUKEGUN = 1528; +unsigned short DUKELEG = 1536; +unsigned short SHARK = 1550; +unsigned short BLOOD = 1620; +unsigned short FIRELASER = 1625; +unsigned short TRANSPORTERSTAR = 1630; +unsigned short SPIT = 1636; +unsigned short LOOGIE = 1637; +unsigned short FIST = 1640; +unsigned short FREEZEBLAST = 1641; +unsigned short DEVISTATORBLAST = 1642; +unsigned short SHRINKSPARK = 1646; +unsigned short TONGUE = 1647; +unsigned short MORTER = 1650; +unsigned short SHRINKEREXPLOSION = 1656; +unsigned short RADIUSEXPLOSION = 1670; +unsigned short FORCERIPPLE = 1671; +unsigned short LIZTROOP = 1680; +unsigned short LIZTROOPRUNNING = 1681; +unsigned short LIZTROOPSTAYPUT = 1682; +unsigned short LIZTOP = 1705; +unsigned short LIZTROOPSHOOT = 1715; +unsigned short LIZTROOPJETPACK = 1725; +unsigned short LIZTROOPDSPRITE = 1734; +unsigned short LIZTROOPONTOILET = 1741; +unsigned short LIZTROOPJUSTSIT = 1742; +unsigned short LIZTROOPDUCKING = 1744; +unsigned short HEADJIB1 = 1768; +unsigned short ARMJIB1 = 1772; +unsigned short LEGJIB1 = 1776; +unsigned short CANNONBALL = 1817; +unsigned short OCTABRAIN = 1820; +unsigned short OCTABRAINSTAYPUT = 1821; +unsigned short OCTATOP = 1845; +unsigned short OCTADEADSPRITE = 1855; +unsigned short INNERJAW = 1860; +unsigned short DRONE = 1880; +unsigned short EXPLOSION2 = 1890; +unsigned short COMMANDER = 1920; +unsigned short COMMANDERSTAYPUT = 1921; +unsigned short RECON = 1960; +unsigned short TANK = 1975; +unsigned short PIGCOP = 2000; +unsigned short PIGCOPSTAYPUT = 2001; +unsigned short PIGCOPDIVE = 2045; +unsigned short PIGCOPDEADSPRITE = 2060; +unsigned short PIGTOP = 2061; +unsigned short LIZMAN = 2120; +unsigned short LIZMANSTAYPUT = 2121; +unsigned short LIZMANSPITTING = 2150; +unsigned short LIZMANFEEDING = 2160; +unsigned short LIZMANJUMP = 2165; +unsigned short LIZMANDEADSPRITE = 2185; +unsigned short FECES = 2200; +unsigned short LIZMANHEAD1 = 2201; +unsigned short LIZMANARM1 = 2205; +unsigned short LIZMANLEG1 = 2209; +unsigned short EXPLOSION2BOT = 2219; +unsigned short USERWEAPON = 2235; +unsigned short HEADERBAR = 2242; +unsigned short JIBS1 = 2245; +unsigned short JIBS2 = 2250; +unsigned short JIBS3 = 2255; +unsigned short JIBS4 = 2260; +unsigned short JIBS5 = 2265; +unsigned short BURNING = 2270; +unsigned short FIRE = 2271; +unsigned short JIBS6 = 2286; +unsigned short BLOODSPLAT1 = 2296; +unsigned short BLOODSPLAT3 = 2297; +unsigned short BLOODSPLAT2 = 2298; +unsigned short BLOODSPLAT4 = 2299; +unsigned short OOZ = 2300; +unsigned short OOZ2 = 2309; +unsigned short WALLBLOOD1 = 2301; +unsigned short WALLBLOOD2 = 2302; +unsigned short WALLBLOOD3 = 2303; +unsigned short WALLBLOOD4 = 2304; +unsigned short WALLBLOOD5 = 2305; +unsigned short WALLBLOOD6 = 2306; +unsigned short WALLBLOOD7 = 2307; +unsigned short WALLBLOOD8 = 2308; +unsigned short BURNING2 = 2310; +unsigned short FIRE2 = 2311; +unsigned short CRACKKNUCKLES = 2324; +unsigned short SMALLSMOKE = 2329; +unsigned short SMALLSMOKEMAKER = 2330; +unsigned short FLOORFLAME = 2333; +unsigned short ROTATEGUN = 2360; +unsigned short GREENSLIME = 2370; +unsigned short WATERDRIPSPLASH = 2380; +unsigned short SCRAP6 = 2390; +unsigned short SCRAP1 = 2400; +unsigned short SCRAP2 = 2404; +unsigned short SCRAP3 = 2408; +unsigned short SCRAP4 = 2412; +unsigned short SCRAP5 = 2416; +unsigned short ORGANTIC = 2420; +unsigned short BETAVERSION = 2440; +unsigned short PLAYERISHERE = 2442; +unsigned short PLAYERWASHERE = 2443; +unsigned short SELECTDIR = 2444; +unsigned short F1HELP = 2445; +unsigned short NOTCHON = 2446; +unsigned short NOTCHOFF = 2447; +unsigned short GROWSPARK = 2448; +unsigned short DUKEICON = 2452; +unsigned short BADGUYICON = 2453; +unsigned short FOODICON = 2454; +unsigned short GETICON = 2455; +unsigned short MENUSCREEN = 2456; +unsigned short MENUBAR = 2457; +unsigned short KILLSICON = 2458; +unsigned short FIRSTAID_ICON = 2460; +unsigned short HEAT_ICON = 2461; +unsigned short BOTTOMSTATUSBAR = 2462; +unsigned short BOOT_ICON = 2463; +unsigned short FRAGBAR = 2465; +unsigned short JETPACK_ICON = 2467; +unsigned short AIRTANK_ICON = 2468; +unsigned short STEROIDS_ICON = 2469; +unsigned short HOLODUKE_ICON = 2470; +unsigned short ACCESS_ICON = 2471; +unsigned short DIGITALNUM = 2472; +unsigned short DUKECAR = 2491; +unsigned short CAMCORNER = 2482; +unsigned short CAMLIGHT = 2484; +unsigned short LOGO = 2485; +unsigned short TITLE = 2486; +unsigned short NUKEWARNINGICON = 2487; +unsigned short MOUSECURSOR = 2488; +unsigned short SLIDEBAR = 2489; +unsigned short DREALMS = 2492; +unsigned short BETASCREEN = 2493; +unsigned short WINDOWBORDER1 = 2494; +unsigned short TEXTBOX = 2495; +unsigned short WINDOWBORDER2 = 2496; +unsigned short DUKENUKEM = 2497; +unsigned short THREEDEE = 2498; +unsigned short INGAMEDUKETHREEDEE = 2499; +unsigned short TENSCREEN = 2500; +unsigned short PLUTOPAKSPRITE = 2501; +unsigned short DEVISTATOR = 2510; +unsigned short KNEE = 2521; +unsigned short CROSSHAIR = 2523; +unsigned short FIRSTGUN = 2524; +unsigned short FIRSTGUNRELOAD = 2528; +unsigned short FALLINGCLIP = 2530; +unsigned short CLIPINHAND = 2531; +unsigned short HAND = 2532; +unsigned short SHELL = 2533; +unsigned short SHOTGUNSHELL = 2535; +unsigned short CHAINGUN = 2536; +unsigned short RPGGUN = 2544; +unsigned short RPGMUZZLEFLASH = 2545; +unsigned short FREEZE = 2548; +unsigned short CATLITE = 2552; +unsigned short SHRINKER = 2556; +unsigned short HANDHOLDINGLASER = 2563; +unsigned short TRIPBOMB = 2566; +unsigned short LASERLINE = 2567; +unsigned short HANDHOLDINGACCESS = 2568; +unsigned short HANDREMOTE = 2570; +unsigned short HANDTHROW = 2573; +unsigned short TIP = 2576; +unsigned short GLAIR = 2578; +unsigned short SCUBAMASK = 2581; +unsigned short SPACEMASK = 2584; +unsigned short FORCESPHERE = 2590; +unsigned short SHOTSPARK1 = 2595; +unsigned short RPG = 2605; +unsigned short LASERSITE = 2612; +unsigned short SHOTGUN = 2613; +unsigned short BOSS1 = 2630; +unsigned short BOSS1STAYPUT = 2631; +unsigned short BOSS1SHOOT = 2660; +unsigned short BOSS1LOB = 2670; +unsigned short BOSSTOP = 2696; +unsigned short BOSS2 = 2710; +unsigned short BOSS3 = 2760; +unsigned short SPINNINGNUKEICON = 2813; +unsigned short BIGFNTCURSOR = 2820; +unsigned short SMALLFNTCURSOR = 2821; +unsigned short STARTALPHANUM = 2822; +unsigned short ENDALPHANUM = 2915; +unsigned short BIGALPHANUM = 2940; +unsigned short BIGPERIOD = 3002; +unsigned short BIGCOMMA = 3003; +unsigned short BIGX = 3004; +unsigned short BIGQ = 3005; +unsigned short BIGSEMI = 3006; +unsigned short BIGCOLIN = 3007; +unsigned short THREEBYFIVE = 3010; +unsigned short BIGAPPOS = 3022; +unsigned short BLANK = 3026; +unsigned short MINIFONT = 3072; +unsigned short BUTTON1 = 3164; +unsigned short GLASS3 = 3187; +unsigned short RESPAWNMARKERRED = 3190; +unsigned short RESPAWNMARKERYELLOW = 3200; +unsigned short RESPAWNMARKERGREEN = 3210; +unsigned short BONUSSCREEN = 3240; +unsigned short VIEWBORDER = 3250; +unsigned short VICTORY1 = 3260; +unsigned short ORDERING = 3270; +unsigned short TEXTSTORY = 3280; +unsigned short LOADSCREEN = 3281; +unsigned short BORNTOBEWILDSCREEN = 3370; +unsigned short BLIMP = 3400; +unsigned short FEM9 = 3450; +unsigned short FOOTPRINT = 3701; +unsigned short FRAMEEFFECT1_13 = 3999; +unsigned short POOP = 4094; +unsigned short FRAMEEFFECT1 = 4095; +unsigned short PANNEL3 = 4099; +unsigned short SCREENBREAK14 = 4120; +unsigned short SCREENBREAK15 = 4123; +unsigned short SCREENBREAK19 = 4125; +unsigned short SCREENBREAK16 = 4127; +unsigned short SCREENBREAK17 = 4128; +unsigned short SCREENBREAK18 = 4129; +unsigned short W_TECHWALL11 = 4130; +unsigned short W_TECHWALL12 = 4131; +unsigned short W_TECHWALL13 = 4132; +unsigned short W_TECHWALL14 = 4133; +unsigned short W_TECHWALL5 = 4134; +unsigned short W_TECHWALL6 = 4136; +unsigned short W_TECHWALL7 = 4138; +unsigned short W_TECHWALL8 = 4140; +unsigned short W_TECHWALL9 = 4142; +unsigned short BPANNEL3 = 4100; +unsigned short W_HITTECHWALL16 = 4144; +unsigned short W_HITTECHWALL10 = 4145; +unsigned short W_HITTECHWALL15 = 4147; +unsigned short W_MILKSHELF = 4181; +unsigned short W_MILKSHELFBROKE = 4203; +unsigned short PURPLELAVA = 4240; +unsigned short LAVABUBBLE = 4340; +unsigned short DUKECUTOUT = 4352; +unsigned short TARGET = 4359; +unsigned short GUNPOWDERBARREL = 4360; +unsigned short DUCK = 4361; +unsigned short HATRACK = 4367; +unsigned short DESKLAMP = 4370; +unsigned short COFFEEMACHINE = 4372; +unsigned short CUPS = 4373; +unsigned short GAVALS = 4374; +unsigned short GAVALS2 = 4375; +unsigned short POLICELIGHTPOLE = 4377; +unsigned short FLOORBASKET = 4388; +unsigned short PUKE = 4389; +unsigned short DOORTILE23 = 4391; +unsigned short TOPSECRET = 4396; +unsigned short SPEAKER = 4397; +unsigned short TEDDYBEAR = 4400; +unsigned short ROBOTDOG = 4402; +unsigned short ROBOTPIRATE = 4404; +unsigned short ROBOTMOUSE = 4407; +unsigned short MAIL = 4410; +unsigned short MAILBAG = 4413; +unsigned short HOTMEAT = 4427; +unsigned short COFFEEMUG = 4438; +unsigned short DONUTS2 = 4440; +unsigned short TRIPODCAMERA = 4444; +unsigned short METER = 4453; +unsigned short DESKPHONE = 4454; +unsigned short GUMBALLMACHINE = 4458; +unsigned short GUMBALLMACHINEBROKE = 4459; +unsigned short PAPER = 4460; +unsigned short MACE = 4464; +unsigned short GENERICPOLE2 = 4465; +unsigned short XXXSTACY = 4470; +unsigned short WETFLOOR = 4495; +unsigned short BROOM = 4496; +unsigned short MOP = 4497; +unsigned short LETTER = 4502; +unsigned short PIRATE1A = 4510; +unsigned short PIRATE4A = 4511; +unsigned short PIRATE2A = 4512; +unsigned short PIRATE5A = 4513; +unsigned short PIRATE3A = 4514; +unsigned short PIRATE6A = 4515; +unsigned short PIRATEHALF = 4516; +unsigned short CHESTOFGOLD = 4520; +unsigned short SIDEBOLT1 = 4525; +unsigned short FOODOBJECT1 = 4530; +unsigned short FOODOBJECT2 = 4531; +unsigned short FOODOBJECT3 = 4532; +unsigned short FOODOBJECT4 = 4533; +unsigned short FOODOBJECT5 = 4534; +unsigned short FOODOBJECT6 = 4535; +unsigned short FOODOBJECT7 = 4536; +unsigned short FOODOBJECT8 = 4537; +unsigned short FOODOBJECT9 = 4538; +unsigned short FOODOBJECT10 = 4539; +unsigned short FOODOBJECT11 = 4540; +unsigned short FOODOBJECT12 = 4541; +unsigned short FOODOBJECT13 = 4542; +unsigned short FOODOBJECT14 = 4543; +unsigned short FOODOBJECT15 = 4544; +unsigned short FOODOBJECT16 = 4545; +unsigned short FOODOBJECT17 = 4546; +unsigned short FOODOBJECT18 = 4547; +unsigned short FOODOBJECT19 = 4548; +unsigned short FOODOBJECT20 = 4549; +unsigned short HEADLAMP = 4550; +unsigned short TAMPON = 4557; +unsigned short SKINNEDCHICKEN = 4554; +unsigned short FEATHEREDCHICKEN = 4555; +unsigned short ROBOTDOG2 = 4560; +unsigned short JOLLYMEAL = 4569; +unsigned short DUKEBURGER = 4570; +unsigned short SHOPPINGCART = 4576; +unsigned short CANWITHSOMETHING2 = 4580; +unsigned short CANWITHSOMETHING3 = 4581; +unsigned short CANWITHSOMETHING4 = 4582; +unsigned short SNAKEP = 4590; +unsigned short DOLPHIN1 = 4591; +unsigned short DOLPHIN2 = 4592; +unsigned short NEWBEAST = 4610; +unsigned short NEWBEASTSTAYPUT = 4611; +unsigned short NEWBEASTJUMP = 4690; +unsigned short NEWBEASTHANG = 4670; +unsigned short NEWBEASTHANGDEAD = 4671; +unsigned short BOSS4 = 4740; +unsigned short BOSS4STAYPUT = 4741; +unsigned short FEM10 = 4864; +unsigned short TOUGHGAL = 4866; +unsigned short MAN = 4871; +unsigned short MAN2 = 4872; +unsigned short WOMAN = 4874; +unsigned short PLEASEWAIT = 4887; +unsigned short NATURALLIGHTNING = 4890; +unsigned short WEATHERWARN = 4893; +unsigned short DUKETAG = 4900; +unsigned short SIGN1 = 4909; +unsigned short SIGN2 = 4912; +unsigned short JURYGUY = 4943; +unsigned short RESERVEDSLOT1 = 6132; +unsigned short RESERVEDSLOT2 = 6133; +unsigned short RESERVEDSLOT3 = 6134; +unsigned short RESERVEDSLOT4 = 6135; +unsigned short RESERVEDSLOT5 = 6136; +unsigned short RESERVEDSLOT6 = 6137; +unsigned short RESERVEDSLOT7 = 6138; +unsigned short RESERVEDSLOT8 = 6139; +unsigned short RESERVEDSLOT9 = 6140; +unsigned short RESERVEDSLOT10 = 6141; +unsigned short RESERVEDSLOT11 = 6142; +unsigned short RESERVEDSLOT12 = 6143; + +unsigned short dynamictostatic[MAXTILES]; + +void processnames(char *szLabel, long lValue) +{ + switch (szLabel[0]) { + case 'A': + if (!Bstrcmp(szLabel,"ACTIVATOR")) ACTIVATOR = lValue; + else if (!Bstrcmp(szLabel,"ACTIVATORLOCKED")) ACTIVATORLOCKED = lValue; + else if (!Bstrcmp(szLabel,"ARROW")) ARROW = lValue; + else if (!Bstrcmp(szLabel,"AMMOBOX")) AMMOBOX = lValue; + else if (!Bstrcmp(szLabel,"AMMO")) AMMO = lValue; + else if (!Bstrcmp(szLabel,"AMMOLOTS")) AMMOLOTS = lValue; + else if (!Bstrcmp(szLabel,"AIRTANK")) AIRTANK = lValue; + else if (!Bstrcmp(szLabel,"ACCESSCARD")) ACCESSCARD = lValue; + else if (!Bstrcmp(szLabel,"ATOMICHEALTH")) ATOMICHEALTH = lValue; + else if (!Bstrcmp(szLabel,"ACCESSSWITCH")) ACCESSSWITCH = lValue; + else if (!Bstrcmp(szLabel,"ACCESSSWITCH2")) ACCESSSWITCH2 = lValue; + else if (!Bstrcmp(szLabel,"ANTENNA")) ANTENNA = lValue; + else if (!Bstrcmp(szLabel,"ATM")) ATM = lValue; + else if (!Bstrcmp(szLabel,"ATMBROKE")) ATMBROKE = lValue; + else if (!Bstrcmp(szLabel,"ALIENSWITCH")) ALIENSWITCH = lValue; + else if (!Bstrcmp(szLabel,"APLAYERTOP")) APLAYERTOP = lValue; + else if (!Bstrcmp(szLabel,"APLAYER")) APLAYER = lValue; + else if (!Bstrcmp(szLabel,"ARMJIB1")) ARMJIB1 = lValue; + else if (!Bstrcmp(szLabel,"AIRTANK_ICON")) AIRTANK_ICON = lValue; + else if (!Bstrcmp(szLabel,"ACCESS_ICON")) ACCESS_ICON = lValue; + break; + case 'B': + if (!Bstrcmp(szLabel,"BATTERYAMMO")) BATTERYAMMO = lValue; + else if (!Bstrcmp(szLabel,"BOOTS")) BOOTS = lValue; + else if (!Bstrcmp(szLabel,"BIGORBIT1")) BIGORBIT1 = lValue; + else if (!Bstrcmp(szLabel,"BIGORBIT2")) BIGORBIT2 = lValue; + else if (!Bstrcmp(szLabel,"BIGORBIT3")) BIGORBIT3 = lValue; + else if (!Bstrcmp(szLabel,"BIGORBIT4")) BIGORBIT4 = lValue; + else if (!Bstrcmp(szLabel,"BIGORBIT5")) BIGORBIT5 = lValue; + else if (!Bstrcmp(szLabel,"BIGFORCE")) BIGFORCE = lValue; + else if (!Bstrcmp(szLabel,"BPANNEL1")) BPANNEL1 = lValue; + else if (!Bstrcmp(szLabel,"BROKENCHAIR")) BROKENCHAIR = lValue; + else if (!Bstrcmp(szLabel,"BGRATE1")) BGRATE1 = lValue; + else if (!Bstrcmp(szLabel,"BRICK")) BRICK = lValue; + else if (!Bstrcmp(szLabel,"BOLT1")) BOLT1 = lValue; + else if (!Bstrcmp(szLabel,"BIGHOLE2")) BIGHOLE2 = lValue; + else if (!Bstrcmp(szLabel,"BOUNCEMINE")) BOUNCEMINE = lValue; + else if (!Bstrcmp(szLabel,"BROKEFIREHYDRENT")) BROKEFIREHYDRENT = lValue; + else if (!Bstrcmp(szLabel,"BOX")) BOX = lValue; + else if (!Bstrcmp(szLabel,"BULLETHOLE")) BULLETHOLE = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE1")) BOTTLE1 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE2")) BOTTLE2 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE3")) BOTTLE3 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE4")) BOTTLE4 = lValue; + else if (!Bstrcmp(szLabel,"BROKEHYDROPLANT")) BROKEHYDROPLANT = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE5")) BOTTLE5 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE6")) BOTTLE6 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE8")) BOTTLE8 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE7")) BOTTLE7 = lValue; + else if (!Bstrcmp(szLabel,"BROKENCLOCK")) BROKENCLOCK = lValue; + else if (!Bstrcmp(szLabel,"BIGHOLE")) BIGHOLE = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE10")) BOTTLE10 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE11")) BOTTLE11 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE12")) BOTTLE12 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE13")) BOTTLE13 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE14")) BOTTLE14 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE15")) BOTTLE15 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE16")) BOTTLE16 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE17")) BOTTLE17 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE18")) BOTTLE18 = lValue; + else if (!Bstrcmp(szLabel,"BOTTLE19")) BOTTLE19 = lValue; + else if (!Bstrcmp(szLabel,"BARBROKE")) BARBROKE = lValue; + else if (!Bstrcmp(szLabel,"BLOODPOOL")) BLOODPOOL = lValue; + else if (!Bstrcmp(szLabel,"BANNER")) BANNER = lValue; + else if (!Bstrcmp(szLabel,"BLANKSCREEN")) BLANKSCREEN = lValue; + else if (!Bstrcmp(szLabel,"BLOODYPOLE")) BLOODYPOLE = lValue; + else if (!Bstrcmp(szLabel,"BLOOD")) BLOOD = lValue; + else if (!Bstrcmp(szLabel,"BURNING")) BURNING = lValue; + else if (!Bstrcmp(szLabel,"BLOODSPLAT1")) BLOODSPLAT1 = lValue; + else if (!Bstrcmp(szLabel,"BLOODSPLAT3")) BLOODSPLAT3 = lValue; + else if (!Bstrcmp(szLabel,"BLOODSPLAT2")) BLOODSPLAT2 = lValue; + else if (!Bstrcmp(szLabel,"BLOODSPLAT4")) BLOODSPLAT4 = lValue; + else if (!Bstrcmp(szLabel,"BURNING2")) BURNING2 = lValue; + else if (!Bstrcmp(szLabel,"BETAVERSION")) BETAVERSION = lValue; + else if (!Bstrcmp(szLabel,"BADGUYICON")) BADGUYICON = lValue; + else if (!Bstrcmp(szLabel,"BOTTOMSTATUSBAR")) BOTTOMSTATUSBAR = lValue; + else if (!Bstrcmp(szLabel,"BOOT_ICON")) BOOT_ICON = lValue; + else if (!Bstrcmp(szLabel,"BETASCREEN")) BETASCREEN = lValue; + else if (!Bstrcmp(szLabel,"BOSS1")) BOSS1 = lValue; + else if (!Bstrcmp(szLabel,"BOSS1STAYPUT")) BOSS1STAYPUT = lValue; + else if (!Bstrcmp(szLabel,"BOSS1SHOOT")) BOSS1SHOOT = lValue; + else if (!Bstrcmp(szLabel,"BOSS1LOB")) BOSS1LOB = lValue; + else if (!Bstrcmp(szLabel,"BOSSTOP")) BOSSTOP = lValue; + else if (!Bstrcmp(szLabel,"BOSS2")) BOSS2 = lValue; + else if (!Bstrcmp(szLabel,"BOSS3")) BOSS3 = lValue; + else if (!Bstrcmp(szLabel,"BIGFNTCURSOR")) BIGFNTCURSOR = lValue; + else if (!Bstrcmp(szLabel,"BIGALPHANUM")) BIGALPHANUM = lValue; + else if (!Bstrcmp(szLabel,"BIGPERIOD")) BIGPERIOD = lValue; + else if (!Bstrcmp(szLabel,"BIGCOMMA")) BIGCOMMA = lValue; + else if (!Bstrcmp(szLabel,"BIGX")) BIGX = lValue; + else if (!Bstrcmp(szLabel,"BIGQ")) BIGQ = lValue; + else if (!Bstrcmp(szLabel,"BIGSEMI")) BIGSEMI = lValue; + else if (!Bstrcmp(szLabel,"BIGCOLIN")) BIGCOLIN = lValue; + else if (!Bstrcmp(szLabel,"BIGAPPOS")) BIGAPPOS = lValue; + else if (!Bstrcmp(szLabel,"BLANK")) BLANK = lValue; + else if (!Bstrcmp(szLabel,"BUTTON1")) BUTTON1 = lValue; + else if (!Bstrcmp(szLabel,"BONUSSCREEN")) BONUSSCREEN = lValue; + else if (!Bstrcmp(szLabel,"BORNTOBEWILDSCREEN")) BORNTOBEWILDSCREEN = lValue; + else if (!Bstrcmp(szLabel,"BLIMP")) BLIMP = lValue; + else if (!Bstrcmp(szLabel,"BPANNEL3")) BPANNEL3 = lValue; + else if (!Bstrcmp(szLabel,"BROOM")) BROOM = lValue; + else if (!Bstrcmp(szLabel,"BOSS4")) BOSS4 = lValue; + else if (!Bstrcmp(szLabel,"BOSS4STAYPUT")) BOSS4STAYPUT = lValue; + break; + case 'C': + if (!Bstrcmp(szLabel,"CYCLER")) CYCLER = lValue; + else if (!Bstrcmp(szLabel,"CHAINGUNSPRITE")) CHAINGUNSPRITE = lValue; + else if (!Bstrcmp(szLabel,"CRYSTALAMMO")) CRYSTALAMMO = lValue; + else if (!Bstrcmp(szLabel,"COLA")) COLA = lValue; + else if (!Bstrcmp(szLabel,"CLOUDYOCEAN")) CLOUDYOCEAN = lValue; + else if (!Bstrcmp(szLabel,"CLOUDYSKIES")) CLOUDYSKIES = lValue; + else if (!Bstrcmp(szLabel,"CRACK1")) CRACK1 = lValue; + else if (!Bstrcmp(szLabel,"CRACK2")) CRACK2 = lValue; + else if (!Bstrcmp(szLabel,"CRACK3")) CRACK3 = lValue; + else if (!Bstrcmp(szLabel,"CRACK4")) CRACK4 = lValue; + else if (!Bstrcmp(szLabel,"CAMERAPOLE")) CAMERAPOLE = lValue; + else if (!Bstrcmp(szLabel,"CHAIR1")) CHAIR1 = lValue; + else if (!Bstrcmp(szLabel,"CHAIR2")) CHAIR2 = lValue; + else if (!Bstrcmp(szLabel,"CAMERA1")) CAMERA1 = lValue; + else if (!Bstrcmp(szLabel,"CHAIR3")) CHAIR3 = lValue; + else if (!Bstrcmp(szLabel,"CAMERALIGHT")) CAMERALIGHT = lValue; + else if (!Bstrcmp(szLabel,"CACTUS")) CACTUS = lValue; + else if (!Bstrcmp(szLabel,"CACTUSBROKE")) CACTUSBROKE = lValue; + else if (!Bstrcmp(szLabel,"CONE")) CONE = lValue; + else if (!Bstrcmp(szLabel,"CLOCK")) CLOCK = lValue; + else if (!Bstrcmp(szLabel,"CIRCLEPANNEL")) CIRCLEPANNEL = lValue; + else if (!Bstrcmp(szLabel,"CIRCLEPANNELBROKE")) CIRCLEPANNELBROKE = lValue; + else if (!Bstrcmp(szLabel,"COLAMACHINE")) COLAMACHINE = lValue; + else if (!Bstrcmp(szLabel,"COLAMACHINEBROKE")) COLAMACHINEBROKE = lValue; + else if (!Bstrcmp(szLabel,"CRANEPOLE")) CRANEPOLE = lValue; + else if (!Bstrcmp(szLabel,"CRANE")) CRANE = lValue; + else if (!Bstrcmp(szLabel,"CANWITHSOMETHING")) CANWITHSOMETHING = lValue; + else if (!Bstrcmp(szLabel,"CEILINGSTEAM")) CEILINGSTEAM = lValue; + else if (!Bstrcmp(szLabel,"COOLEXPLOSION1")) COOLEXPLOSION1 = lValue; + else if (!Bstrcmp(szLabel,"CANNONBALL")) CANNONBALL = lValue; + else if (!Bstrcmp(szLabel,"COMMANDER")) COMMANDER = lValue; + else if (!Bstrcmp(szLabel,"COMMANDERSTAYPUT")) COMMANDERSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"CRACKKNUCKLES")) CRACKKNUCKLES = lValue; + else if (!Bstrcmp(szLabel,"CAMCORNER")) CAMCORNER = lValue; + else if (!Bstrcmp(szLabel,"CAMLIGHT")) CAMLIGHT = lValue; + else if (!Bstrcmp(szLabel,"CROSSHAIR")) CROSSHAIR = lValue; + else if (!Bstrcmp(szLabel,"CLIPINHAND")) CLIPINHAND = lValue; + else if (!Bstrcmp(szLabel,"CHAINGUN")) CHAINGUN = lValue; + else if (!Bstrcmp(szLabel,"CATLITE")) CATLITE = lValue; + else if (!Bstrcmp(szLabel,"COFFEEMACHINE")) COFFEEMACHINE = lValue; + else if (!Bstrcmp(szLabel,"CUPS")) CUPS = lValue; + else if (!Bstrcmp(szLabel,"COFFEEMUG")) COFFEEMUG = lValue; + else if (!Bstrcmp(szLabel,"CHESTOFGOLD")) CHESTOFGOLD = lValue; + else if (!Bstrcmp(szLabel,"CANWITHSOMETHING2")) CANWITHSOMETHING2 = lValue; + else if (!Bstrcmp(szLabel,"CANWITHSOMETHING3")) CANWITHSOMETHING3 = lValue; + else if (!Bstrcmp(szLabel,"CANWITHSOMETHING4")) CANWITHSOMETHING4 = lValue; + break; + case 'D': + if (!Bstrcmp(szLabel,"DEVISTATORSPRITE")) DEVISTATORSPRITE = lValue; + else if (!Bstrcmp(szLabel,"DEVISTATORAMMO")) DEVISTATORAMMO = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE5")) DOORTILE5 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE6")) DOORTILE6 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE1")) DOORTILE1 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE2")) DOORTILE2 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE3")) DOORTILE3 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE4")) DOORTILE4 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE7")) DOORTILE7 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE8")) DOORTILE8 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE9")) DOORTILE9 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE10")) DOORTILE10 = lValue; + else if (!Bstrcmp(szLabel,"DOORSHOCK")) DOORSHOCK = lValue; + else if (!Bstrcmp(szLabel,"DIPSWITCH")) DIPSWITCH = lValue; + else if (!Bstrcmp(szLabel,"DIPSWITCH2")) DIPSWITCH2 = lValue; + else if (!Bstrcmp(szLabel,"DIPSWITCH3")) DIPSWITCH3 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE22")) DOORTILE22 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE18")) DOORTILE18 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE19")) DOORTILE19 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE20")) DOORTILE20 = lValue; + else if (!Bstrcmp(szLabel,"DOMELITE")) DOMELITE = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE14")) DOORTILE14 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE16")) DOORTILE16 = lValue; + else if (!Bstrcmp(szLabel,"DONUTS")) DONUTS = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE15")) DOORTILE15 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE21")) DOORTILE21 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE17")) DOORTILE17 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE11")) DOORTILE11 = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE12")) DOORTILE12 = lValue; + else if (!Bstrcmp(szLabel,"DUKELYINGDEAD")) DUKELYINGDEAD = lValue; + else if (!Bstrcmp(szLabel,"DUKETORSO")) DUKETORSO = lValue; + else if (!Bstrcmp(szLabel,"DUKEGUN")) DUKEGUN = lValue; + else if (!Bstrcmp(szLabel,"DUKELEG")) DUKELEG = lValue; + else if (!Bstrcmp(szLabel,"DEVISTATORBLAST")) DEVISTATORBLAST = lValue; + else if (!Bstrcmp(szLabel,"DRONE")) DRONE = lValue; + else if (!Bstrcmp(szLabel,"DUKEICON")) DUKEICON = lValue; + else if (!Bstrcmp(szLabel,"DIGITALNUM")) DIGITALNUM = lValue; + else if (!Bstrcmp(szLabel,"DUKECAR")) DUKECAR = lValue; + else if (!Bstrcmp(szLabel,"DREALMS")) DREALMS = lValue; + else if (!Bstrcmp(szLabel,"DUKENUKEM")) DUKENUKEM = lValue; + else if (!Bstrcmp(szLabel,"DEVISTATOR")) DEVISTATOR = lValue; + else if (!Bstrcmp(szLabel,"DUKECUTOUT")) DUKECUTOUT = lValue; + else if (!Bstrcmp(szLabel,"DUCK")) DUCK = lValue; + else if (!Bstrcmp(szLabel,"DESKLAMP")) DESKLAMP = lValue; + else if (!Bstrcmp(szLabel,"DOORTILE23")) DOORTILE23 = lValue; + else if (!Bstrcmp(szLabel,"DONUTS2")) DONUTS2 = lValue; + else if (!Bstrcmp(szLabel,"DESKPHONE")) DESKPHONE = lValue; + else if (!Bstrcmp(szLabel,"DUKEBURGER")) DUKEBURGER = lValue; + else if (!Bstrcmp(szLabel,"DOLPHIN1")) DOLPHIN1 = lValue; + else if (!Bstrcmp(szLabel,"DOLPHIN2")) DOLPHIN2 = lValue; + else if (!Bstrcmp(szLabel,"DUKETAG")) DUKETAG = lValue; + break; + case 'E': + if (!Bstrcmp(szLabel,"EPISODE")) EPISODE = lValue; + else if (!Bstrcmp(szLabel,"EGG")) EGG = lValue; + else if (!Bstrcmp(szLabel,"EXPLODINGBARREL")) EXPLODINGBARREL = lValue; + else if (!Bstrcmp(szLabel,"EXPLODINGBARREL2")) EXPLODINGBARREL2 = lValue; + else if (!Bstrcmp(szLabel,"EXPLOSION2")) EXPLOSION2 = lValue; + else if (!Bstrcmp(szLabel,"EXPLOSION2BOT")) EXPLOSION2BOT = lValue; + else if (!Bstrcmp(szLabel,"ENDALPHANUM")) ENDALPHANUM = lValue; + break; + case 'F': + if (!Bstrcmp(szLabel,"FOF")) FOF = lValue; + else if (!Bstrcmp(szLabel,"FIRSTGUNSPRITE")) FIRSTGUNSPRITE = lValue; + else if (!Bstrcmp(szLabel,"FREEZESPRITE")) FREEZESPRITE = lValue; + else if (!Bstrcmp(szLabel,"FREEZEAMMO")) FREEZEAMMO = lValue; + else if (!Bstrcmp(szLabel,"FIRSTAID")) FIRSTAID = lValue; + else if (!Bstrcmp(szLabel,"FRANKENSTINESWITCH")) FRANKENSTINESWITCH = lValue; + else if (!Bstrcmp(szLabel,"FLOORSLIME")) FLOORSLIME = lValue; + else if (!Bstrcmp(szLabel,"FANSPRITE")) FANSPRITE = lValue; + else if (!Bstrcmp(szLabel,"FANSPRITEBROKE")) FANSPRITEBROKE = lValue; + else if (!Bstrcmp(szLabel,"FANSHADOW")) FANSHADOW = lValue; + else if (!Bstrcmp(szLabel,"FANSHADOWBROKE")) FANSHADOWBROKE = lValue; + else if (!Bstrcmp(szLabel,"FUELPOD")) FUELPOD = lValue; + else if (!Bstrcmp(szLabel,"FOOTPRINTS")) FOOTPRINTS = lValue; + else if (!Bstrcmp(szLabel,"FEMMAG1")) FEMMAG1 = lValue; + else if (!Bstrcmp(szLabel,"FEMMAG2")) FEMMAG2 = lValue; + else if (!Bstrcmp(szLabel,"FOOTPRINTS2")) FOOTPRINTS2 = lValue; + else if (!Bstrcmp(szLabel,"FOOTPRINTS3")) FOOTPRINTS3 = lValue; + else if (!Bstrcmp(szLabel,"FOOTPRINTS4")) FOOTPRINTS4 = lValue; + else if (!Bstrcmp(szLabel,"FIREEXT")) FIREEXT = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC5")) FEMPIC5 = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC6")) FEMPIC6 = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC7")) FEMPIC7 = lValue; + else if (!Bstrcmp(szLabel,"FLOORPLASMA")) FLOORPLASMA = lValue; + else if (!Bstrcmp(szLabel,"FIREBARREL")) FIREBARREL = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC1")) FEMPIC1 = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC2")) FEMPIC2 = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC3")) FEMPIC3 = lValue; + else if (!Bstrcmp(szLabel,"FEMPIC4")) FEMPIC4 = lValue; + else if (!Bstrcmp(szLabel,"FEM1")) FEM1 = lValue; + else if (!Bstrcmp(szLabel,"FEM2")) FEM2 = lValue; + else if (!Bstrcmp(szLabel,"FEM3")) FEM3 = lValue; + else if (!Bstrcmp(szLabel,"FEM5")) FEM5 = lValue; + else if (!Bstrcmp(szLabel,"FEM4")) FEM4 = lValue; + else if (!Bstrcmp(szLabel,"FEM6")) FEM6 = lValue; + else if (!Bstrcmp(szLabel,"FEM6PAD")) FEM6PAD = lValue; + else if (!Bstrcmp(szLabel,"FEM8")) FEM8 = lValue; + else if (!Bstrcmp(szLabel,"FETUSJIB")) FETUSJIB = lValue; + else if (!Bstrcmp(szLabel,"FETUS")) FETUS = lValue; + else if (!Bstrcmp(szLabel,"FETUSBROKE")) FETUSBROKE = lValue; + else if (!Bstrcmp(szLabel,"FIREVASE")) FIREVASE = lValue; + else if (!Bstrcmp(szLabel,"FEM7")) FEM7 = lValue; + else if (!Bstrcmp(szLabel,"FIRELASER")) FIRELASER = lValue; + else if (!Bstrcmp(szLabel,"FIST")) FIST = lValue; + else if (!Bstrcmp(szLabel,"FREEZEBLAST")) FREEZEBLAST = lValue; + else if (!Bstrcmp(szLabel,"FORCERIPPLE")) FORCERIPPLE = lValue; + else if (!Bstrcmp(szLabel,"FECES")) FECES = lValue; + else if (!Bstrcmp(szLabel,"FIRE")) FIRE = lValue; + else if (!Bstrcmp(szLabel,"FIRE2")) FIRE2 = lValue; + else if (!Bstrcmp(szLabel,"FLOORFLAME")) FLOORFLAME = lValue; + else if (!Bstrcmp(szLabel,"F1HELP")) F1HELP = lValue; + else if (!Bstrcmp(szLabel,"FOODICON")) FOODICON = lValue; + else if (!Bstrcmp(szLabel,"FIRSTAID_ICON")) FIRSTAID_ICON = lValue; + else if (!Bstrcmp(szLabel,"FRAGBAR")) FRAGBAR = lValue; + else if (!Bstrcmp(szLabel,"FIRSTGUN")) FIRSTGUN = lValue; + else if (!Bstrcmp(szLabel,"FIRSTGUNRELOAD")) FIRSTGUNRELOAD = lValue; + else if (!Bstrcmp(szLabel,"FALLINGCLIP")) FALLINGCLIP = lValue; + else if (!Bstrcmp(szLabel,"FREEZE")) FREEZE = lValue; + else if (!Bstrcmp(szLabel,"FORCESPHERE")) FORCESPHERE = lValue; + else if (!Bstrcmp(szLabel,"FEM9")) FEM9 = lValue; + else if (!Bstrcmp(szLabel,"FOOTPRINT")) FOOTPRINT = lValue; + else if (!Bstrcmp(szLabel,"FRAMEEFFECT1")) FRAMEEFFECT1 = lValue; + else if (!Bstrcmp(szLabel,"FRAMEEFFECT1_13")) FRAMEEFFECT1_13 = lValue; + else if (!Bstrcmp(szLabel,"FLOORBASKET")) FLOORBASKET = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT1")) FOODOBJECT1 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT2")) FOODOBJECT2 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT3")) FOODOBJECT3 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT4")) FOODOBJECT4 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT5")) FOODOBJECT5 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT6")) FOODOBJECT6 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT7")) FOODOBJECT7 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT8")) FOODOBJECT8 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT9")) FOODOBJECT9 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT10")) FOODOBJECT10 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT11")) FOODOBJECT11 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT12")) FOODOBJECT12 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT13")) FOODOBJECT13 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT14")) FOODOBJECT14 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT15")) FOODOBJECT15 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT16")) FOODOBJECT16 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT17")) FOODOBJECT17 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT18")) FOODOBJECT18 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT19")) FOODOBJECT19 = lValue; + else if (!Bstrcmp(szLabel,"FOODOBJECT20")) FOODOBJECT20 = lValue; + else if (!Bstrcmp(szLabel,"FEATHEREDCHICKEN")) FEATHEREDCHICKEN = lValue; + else if (!Bstrcmp(szLabel,"FEM10")) FEM10 = lValue; + break; + case 'G': + if (!Bstrcmp(szLabel,"GPSPEED")) GPSPEED = lValue; + else if (!Bstrcmp(szLabel,"GROWSPRITEICON")) GROWSPRITEICON = lValue; + else if (!Bstrcmp(szLabel,"GROWAMMO")) GROWAMMO = lValue; + else if (!Bstrcmp(szLabel,"GLASS")) GLASS = lValue; + else if (!Bstrcmp(szLabel,"GLASS2")) GLASS2 = lValue; + else if (!Bstrcmp(szLabel,"GRATE1")) GRATE1 = lValue; + else if (!Bstrcmp(szLabel,"GENERICPOLE")) GENERICPOLE = lValue; + else if (!Bstrcmp(szLabel,"GLASSPIECES")) GLASSPIECES = lValue; + else if (!Bstrcmp(szLabel,"GREENSLIME")) GREENSLIME = lValue; + else if (!Bstrcmp(szLabel,"GROWSPARK")) GROWSPARK = lValue; + else if (!Bstrcmp(szLabel,"GETICON")) GETICON = lValue; + else if (!Bstrcmp(szLabel,"GLAIR")) GLAIR = lValue; + else if (!Bstrcmp(szLabel,"GLASS3")) GLASS3 = lValue; + else if (!Bstrcmp(szLabel,"GUNPOWDERBARREL")) GUNPOWDERBARREL = lValue; + else if (!Bstrcmp(szLabel,"GAVALS")) GAVALS = lValue; + else if (!Bstrcmp(szLabel,"GAVALS2")) GAVALS2 = lValue; + else if (!Bstrcmp(szLabel,"GUMBALLMACHINE")) GUMBALLMACHINE = lValue; + else if (!Bstrcmp(szLabel,"GUMBALLMACHINEBROKE")) GUMBALLMACHINEBROKE = lValue; + else if (!Bstrcmp(szLabel,"GENERICPOLE2")) GENERICPOLE2 = lValue; + break; + case 'H': + if (!Bstrcmp(szLabel,"HEAVYHBOMB")) HEAVYHBOMB = lValue; + else if (!Bstrcmp(szLabel,"HEALTHBOX")) HEALTHBOX = lValue; + else if (!Bstrcmp(szLabel,"HBOMBAMMO")) HBOMBAMMO = lValue; + else if (!Bstrcmp(szLabel,"HEATSENSOR")) HEATSENSOR = lValue; + else if (!Bstrcmp(szLabel,"HURTRAIL")) HURTRAIL = lValue; + else if (!Bstrcmp(szLabel,"HYDROPLANT")) HYDROPLANT = lValue; + else if (!Bstrcmp(szLabel,"HANGLIGHT")) HANGLIGHT = lValue; + else if (!Bstrcmp(szLabel,"HYDRENT")) HYDRENT = lValue; + else if (!Bstrcmp(szLabel,"HANGOOZ")) HANGOOZ = lValue; + else if (!Bstrcmp(szLabel,"HORSEONSIDE")) HORSEONSIDE = lValue; + else if (!Bstrcmp(szLabel,"HORSELITE")) HORSELITE = lValue; + else if (!Bstrcmp(szLabel,"HANDSWITCH")) HANDSWITCH = lValue; + else if (!Bstrcmp(szLabel,"HANDPRINTSWITCH")) HANDPRINTSWITCH = lValue; + else if (!Bstrcmp(szLabel,"HELECOPT")) HELECOPT = lValue; + else if (!Bstrcmp(szLabel,"HOLODUKE")) HOLODUKE = lValue; + else if (!Bstrcmp(szLabel,"HEADJIB1")) HEADJIB1 = lValue; + else if (!Bstrcmp(szLabel,"HEADERBAR")) HEADERBAR = lValue; + else if (!Bstrcmp(szLabel,"HEAT_ICON")) HEAT_ICON = lValue; + else if (!Bstrcmp(szLabel,"HOLODUKE_ICON")) HOLODUKE_ICON = lValue; + else if (!Bstrcmp(szLabel,"HAND")) HAND = lValue; + else if (!Bstrcmp(szLabel,"HANDHOLDINGLASER")) HANDHOLDINGLASER = lValue; + else if (!Bstrcmp(szLabel,"HANDHOLDINGACCESS")) HANDHOLDINGACCESS = lValue; + else if (!Bstrcmp(szLabel,"HANDREMOTE")) HANDREMOTE = lValue; + else if (!Bstrcmp(szLabel,"HANDTHROW")) HANDTHROW = lValue; + else if (!Bstrcmp(szLabel,"HATRACK")) HATRACK = lValue; + else if (!Bstrcmp(szLabel,"HOTMEAT")) HOTMEAT = lValue; + else if (!Bstrcmp(szLabel,"HEADLAMP")) HEADLAMP = lValue; + break; + case 'I': + if (!Bstrcmp(szLabel,"INVENTORYBOX")) INVENTORYBOX = lValue; + else if (!Bstrcmp(szLabel,"IVUNIT")) IVUNIT = lValue; + else if (!Bstrcmp(szLabel,"INDY")) INDY = lValue; + else if (!Bstrcmp(szLabel,"INNERJAW")) INNERJAW = lValue; + else if (!Bstrcmp(szLabel,"INGAMEDUKETHREEDEE")) INGAMEDUKETHREEDEE = lValue; + break; + case 'J': + if (!Bstrcmp(szLabel,"JETPACK")) JETPACK = lValue; + else if (!Bstrcmp(szLabel,"JAILBARBREAK")) JAILBARBREAK = lValue; + else if (!Bstrcmp(szLabel,"JIBS1")) JIBS1 = lValue; + else if (!Bstrcmp(szLabel,"JIBS2")) JIBS2 = lValue; + else if (!Bstrcmp(szLabel,"JIBS3")) JIBS3 = lValue; + else if (!Bstrcmp(szLabel,"JIBS4")) JIBS4 = lValue; + else if (!Bstrcmp(szLabel,"JIBS5")) JIBS5 = lValue; + else if (!Bstrcmp(szLabel,"JIBS6")) JIBS6 = lValue; + else if (!Bstrcmp(szLabel,"JETPACK_ICON")) JETPACK_ICON = lValue; + else if (!Bstrcmp(szLabel,"JOLLYMEAL")) JOLLYMEAL = lValue; + else if (!Bstrcmp(szLabel,"JURYGUY")) JURYGUY = lValue; + break; + case 'K': + if (!Bstrcmp(szLabel,"KILLSICON")) KILLSICON = lValue; + else if (!Bstrcmp(szLabel,"KNEE")) KNEE = lValue; + break; + case 'L': + if (!Bstrcmp(szLabel,"LOCATORS")) LOCATORS = lValue; + else if (!Bstrcmp(szLabel,"LA")) LA = lValue; + else if (!Bstrcmp(szLabel,"LIGHTSWITCH")) LIGHTSWITCH = lValue; + else if (!Bstrcmp(szLabel,"LIGHTSWITCH2")) LIGHTSWITCH2 = lValue; + else if (!Bstrcmp(szLabel,"LOCKSWITCH1")) LOCKSWITCH1 = lValue; + else if (!Bstrcmp(szLabel,"LUKE")) LUKE = lValue; + else if (!Bstrcmp(szLabel,"LOOGIE")) LOOGIE = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOP")) LIZTROOP = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPRUNNING")) LIZTROOPRUNNING = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPSTAYPUT")) LIZTROOPSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"LIZTOP")) LIZTOP = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPSHOOT")) LIZTROOPSHOOT = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPJETPACK")) LIZTROOPJETPACK = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPDSPRITE")) LIZTROOPDSPRITE = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPONTOILET")) LIZTROOPONTOILET = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPJUSTSIT")) LIZTROOPJUSTSIT = lValue; + else if (!Bstrcmp(szLabel,"LIZTROOPDUCKING")) LIZTROOPDUCKING = lValue; + else if (!Bstrcmp(szLabel,"LEGJIB1")) LEGJIB1 = lValue; + else if (!Bstrcmp(szLabel,"LIZMAN")) LIZMAN = lValue; + else if (!Bstrcmp(szLabel,"LIZMANSTAYPUT")) LIZMANSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"LIZMANSPITTING")) LIZMANSPITTING = lValue; + else if (!Bstrcmp(szLabel,"LIZMANFEEDING")) LIZMANFEEDING = lValue; + else if (!Bstrcmp(szLabel,"LIZMANJUMP")) LIZMANJUMP = lValue; + else if (!Bstrcmp(szLabel,"LIZMANDEADSPRITE")) LIZMANDEADSPRITE = lValue; + else if (!Bstrcmp(szLabel,"LIZMANHEAD1")) LIZMANHEAD1 = lValue; + else if (!Bstrcmp(szLabel,"LIZMANARM1")) LIZMANARM1 = lValue; + else if (!Bstrcmp(szLabel,"LIZMANLEG1")) LIZMANLEG1 = lValue; + else if (!Bstrcmp(szLabel,"LOGO")) LOGO = lValue; + else if (!Bstrcmp(szLabel,"LASERLINE")) LASERLINE = lValue; + else if (!Bstrcmp(szLabel,"LASERSITE")) LASERSITE = lValue; + else if (!Bstrcmp(szLabel,"LOADSCREEN")) LOADSCREEN = lValue; + else if (!Bstrcmp(szLabel,"LAVABUBBLE")) LAVABUBBLE = lValue; + else if (!Bstrcmp(szLabel,"LETTER")) LETTER = lValue; + break; + case 'M': + if (!Bstrcmp(szLabel,"MUSICANDSFX")) MUSICANDSFX = lValue; + else if (!Bstrcmp(szLabel,"MASTERSWITCH")) MASTERSWITCH = lValue; + else if (!Bstrcmp(szLabel,"MIRRORBROKE")) MIRRORBROKE = lValue; + else if (!Bstrcmp(szLabel,"MOONSKY1")) MOONSKY1 = lValue; + else if (!Bstrcmp(szLabel,"MOONSKY2")) MOONSKY2 = lValue; + else if (!Bstrcmp(szLabel,"MOONSKY3")) MOONSKY3 = lValue; + else if (!Bstrcmp(szLabel,"MOONSKY4")) MOONSKY4 = lValue; + else if (!Bstrcmp(szLabel,"MULTISWITCH")) MULTISWITCH = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL9")) MASKWALL9 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL1")) MASKWALL1 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL10")) MASKWALL10 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL11")) MASKWALL11 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL5")) MASKWALL5 = lValue; + else if (!Bstrcmp(szLabel,"MIRROR")) MIRROR = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL12")) MASKWALL12 = lValue; + else if (!Bstrcmp(szLabel,"MOVIECAMERA")) MOVIECAMERA = lValue; + else if (!Bstrcmp(szLabel,"MIKE")) MIKE = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL13")) MASKWALL13 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL2")) MASKWALL2 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL3")) MASKWALL3 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL4")) MASKWALL4 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL14")) MASKWALL14 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL15")) MASKWALL15 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL6")) MASKWALL6 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL8")) MASKWALL8 = lValue; + else if (!Bstrcmp(szLabel,"MASKWALL7")) MASKWALL7 = lValue; + else if (!Bstrcmp(szLabel,"MONEY")) MONEY = lValue; + else if (!Bstrcmp(szLabel,"MONK")) MONK = lValue; + else if (!Bstrcmp(szLabel,"MORTER")) MORTER = lValue; + else if (!Bstrcmp(szLabel,"MENUSCREEN")) MENUSCREEN = lValue; + else if (!Bstrcmp(szLabel,"MENUBAR")) MENUBAR = lValue; + else if (!Bstrcmp(szLabel,"MOUSECURSOR")) MOUSECURSOR = lValue; + else if (!Bstrcmp(szLabel,"MINIFONT")) MINIFONT = lValue; + else if (!Bstrcmp(szLabel,"MAIL")) MAIL = lValue; + else if (!Bstrcmp(szLabel,"MAILBAG")) MAILBAG = lValue; + else if (!Bstrcmp(szLabel,"METER")) METER = lValue; + else if (!Bstrcmp(szLabel,"MACE")) MACE = lValue; + else if (!Bstrcmp(szLabel,"MOP")) MOP = lValue; + else if (!Bstrcmp(szLabel,"MAN")) MAN = lValue; + else if (!Bstrcmp(szLabel,"MAN2")) MAN2 = lValue; + break; + case 'N': + if (!Bstrcmp(szLabel,"NUKEBUTTON")) NUKEBUTTON = lValue; + else if (!Bstrcmp(szLabel,"NAKED1")) NAKED1 = lValue; + else if (!Bstrcmp(szLabel,"NEON1")) NEON1 = lValue; + else if (!Bstrcmp(szLabel,"NEON2")) NEON2 = lValue; + else if (!Bstrcmp(szLabel,"NEON3")) NEON3 = lValue; + else if (!Bstrcmp(szLabel,"NEON4")) NEON4 = lValue; + else if (!Bstrcmp(szLabel,"NEON5")) NEON5 = lValue; + else if (!Bstrcmp(szLabel,"NEON6")) NEON6 = lValue; + else if (!Bstrcmp(szLabel,"NUKEBARREL")) NUKEBARREL = lValue; + else if (!Bstrcmp(szLabel,"NUKEBARRELDENTED")) NUKEBARRELDENTED = lValue; + else if (!Bstrcmp(szLabel,"NUKEBARRELLEAKED")) NUKEBARRELLEAKED = lValue; + else if (!Bstrcmp(szLabel,"NOTCHON")) NOTCHON = lValue; + else if (!Bstrcmp(szLabel,"NOTCHOFF")) NOTCHOFF = lValue; + else if (!Bstrcmp(szLabel,"NUKEWARNINGICON")) NUKEWARNINGICON = lValue; + else if (!Bstrcmp(szLabel,"NEWBEAST")) NEWBEAST = lValue; + else if (!Bstrcmp(szLabel,"NEWBEASTSTAYPUT")) NEWBEASTSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"NEWBEASTJUMP")) NEWBEASTJUMP = lValue; + else if (!Bstrcmp(szLabel,"NEWBEASTHANG")) NEWBEASTHANG = lValue; + else if (!Bstrcmp(szLabel,"NEWBEASTHANGDEAD")) NEWBEASTHANGDEAD = lValue; + else if (!Bstrcmp(szLabel,"NATURALLIGHTNING")) NATURALLIGHTNING = lValue; + break; + case 'O': + if (!Bstrcmp(szLabel,"OJ")) OJ = lValue; + else if (!Bstrcmp(szLabel,"OCEANSPRITE1")) OCEANSPRITE1 = lValue; + else if (!Bstrcmp(szLabel,"OCEANSPRITE2")) OCEANSPRITE2 = lValue; + else if (!Bstrcmp(szLabel,"OCEANSPRITE3")) OCEANSPRITE3 = lValue; + else if (!Bstrcmp(szLabel,"OCEANSPRITE4")) OCEANSPRITE4 = lValue; + else if (!Bstrcmp(szLabel,"OCEANSPRITE5")) OCEANSPRITE5 = lValue; + else if (!Bstrcmp(szLabel,"OOZFILTER")) OOZFILTER = lValue; + else if (!Bstrcmp(szLabel,"OCTABRAIN")) OCTABRAIN = lValue; + else if (!Bstrcmp(szLabel,"OCTABRAINSTAYPUT")) OCTABRAINSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"OCTATOP")) OCTATOP = lValue; + else if (!Bstrcmp(szLabel,"OCTADEADSPRITE")) OCTADEADSPRITE = lValue; + else if (!Bstrcmp(szLabel,"OOZ")) OOZ = lValue; + else if (!Bstrcmp(szLabel,"OOZ2")) OOZ2 = lValue; + else if (!Bstrcmp(szLabel,"ORGANTIC")) ORGANTIC = lValue; + else if (!Bstrcmp(szLabel,"ORDERING")) ORDERING = lValue; + break; + case 'P': + if (!Bstrcmp(szLabel,"PANNEL1")) PANNEL1 = lValue; + else if (!Bstrcmp(szLabel,"PANNEL2")) PANNEL2 = lValue; + else if (!Bstrcmp(szLabel,"PIPE2")) PIPE2 = lValue; + else if (!Bstrcmp(szLabel,"PIPE1B")) PIPE1B = lValue; + else if (!Bstrcmp(szLabel,"PIPE3")) PIPE3 = lValue; + else if (!Bstrcmp(szLabel,"PIPE1")) PIPE1 = lValue; + else if (!Bstrcmp(szLabel,"PIPE2B")) PIPE2B = lValue; + else if (!Bstrcmp(szLabel,"POT1")) POT1 = lValue; + else if (!Bstrcmp(szLabel,"POT2")) POT2 = lValue; + else if (!Bstrcmp(szLabel,"POT3")) POT3 = lValue; + else if (!Bstrcmp(szLabel,"PIPE3B")) PIPE3B = lValue; + else if (!Bstrcmp(szLabel,"POWERSWITCH1")) POWERSWITCH1 = lValue; + else if (!Bstrcmp(szLabel,"POWERSWITCH2")) POWERSWITCH2 = lValue; + else if (!Bstrcmp(szLabel,"POCKET")) POCKET = lValue; + else if (!Bstrcmp(szLabel,"PIPE5")) PIPE5 = lValue; + else if (!Bstrcmp(szLabel,"PIPE6")) PIPE6 = lValue; + else if (!Bstrcmp(szLabel,"PIPE4")) PIPE4 = lValue; + else if (!Bstrcmp(szLabel,"PIPE4B")) PIPE4B = lValue; + else if (!Bstrcmp(szLabel,"PIPE5B")) PIPE5B = lValue; + else if (!Bstrcmp(szLabel,"PLUG")) PLUG = lValue; + else if (!Bstrcmp(szLabel,"PULLSWITCH")) PULLSWITCH = lValue; + else if (!Bstrcmp(szLabel,"PIPE6B")) PIPE6B = lValue; + else if (!Bstrcmp(szLabel,"PODFEM1")) PODFEM1 = lValue; + else if (!Bstrcmp(szLabel,"PLAYERONWATER")) PLAYERONWATER = lValue; + else if (!Bstrcmp(szLabel,"PIGCOP")) PIGCOP = lValue; + else if (!Bstrcmp(szLabel,"PIGCOPSTAYPUT")) PIGCOPSTAYPUT = lValue; + else if (!Bstrcmp(szLabel,"PIGCOPDIVE")) PIGCOPDIVE = lValue; + else if (!Bstrcmp(szLabel,"PIGCOPDEADSPRITE")) PIGCOPDEADSPRITE = lValue; + else if (!Bstrcmp(szLabel,"PIGTOP")) PIGTOP = lValue; + else if (!Bstrcmp(szLabel,"PLAYERISHERE")) PLAYERISHERE = lValue; + else if (!Bstrcmp(szLabel,"PLAYERWASHERE")) PLAYERWASHERE = lValue; + else if (!Bstrcmp(szLabel,"PLUTOPAKSPRITE")) PLUTOPAKSPRITE = lValue; + else if (!Bstrcmp(szLabel,"POOP")) POOP = lValue; + else if (!Bstrcmp(szLabel,"PANNEL3")) PANNEL3 = lValue; + else if (!Bstrcmp(szLabel,"PURPLELAVA")) PURPLELAVA = lValue; + else if (!Bstrcmp(szLabel,"POLICELIGHTPOLE")) POLICELIGHTPOLE = lValue; + else if (!Bstrcmp(szLabel,"PUKE")) PUKE = lValue; + else if (!Bstrcmp(szLabel,"PAPER")) PAPER = lValue; + else if (!Bstrcmp(szLabel,"PIRATE1A")) PIRATE1A = lValue; + else if (!Bstrcmp(szLabel,"PIRATE4A")) PIRATE4A = lValue; + else if (!Bstrcmp(szLabel,"PIRATE2A")) PIRATE2A = lValue; + else if (!Bstrcmp(szLabel,"PIRATE5A")) PIRATE5A = lValue; + else if (!Bstrcmp(szLabel,"PIRATE3A")) PIRATE3A = lValue; + else if (!Bstrcmp(szLabel,"PIRATE6A")) PIRATE6A = lValue; + else if (!Bstrcmp(szLabel,"PIRATEHALF")) PIRATEHALF = lValue; + else if (!Bstrcmp(szLabel,"PLEASEWAIT")) PLEASEWAIT = lValue; + break; + case 'Q': + if (!Bstrcmp(szLabel,"QUEBALL")) QUEBALL = lValue; + break; + case 'R': + if (!Bstrcmp(szLabel,"RESPAWN")) RESPAWN = lValue; + else if (!Bstrcmp(szLabel,"RPGSPRITE")) RPGSPRITE = lValue; + else if (!Bstrcmp(szLabel,"RPGAMMO")) RPGAMMO = lValue; + else if (!Bstrcmp(szLabel,"REDSKY1")) REDSKY1 = lValue; + else if (!Bstrcmp(szLabel,"REDSKY2")) REDSKY2 = lValue; + else if (!Bstrcmp(szLabel,"REFLECTWATERTILE")) REFLECTWATERTILE = lValue; + else if (!Bstrcmp(szLabel,"REACTOR2")) REACTOR2 = lValue; + else if (!Bstrcmp(szLabel,"REACTOR2BURNT")) REACTOR2BURNT = lValue; + else if (!Bstrcmp(szLabel,"REACTOR2SPARK")) REACTOR2SPARK = lValue; + else if (!Bstrcmp(szLabel,"RUBBERCAN")) RUBBERCAN = lValue; + else if (!Bstrcmp(szLabel,"REACTOR")) REACTOR = lValue; + else if (!Bstrcmp(szLabel,"REACTORSPARK")) REACTORSPARK = lValue; + else if (!Bstrcmp(szLabel,"REACTORBURNT")) REACTORBURNT = lValue; + else if (!Bstrcmp(szLabel,"RAT")) RAT = lValue; + else if (!Bstrcmp(szLabel,"RADIUSEXPLOSION")) RADIUSEXPLOSION = lValue; + else if (!Bstrcmp(szLabel,"RECON")) RECON = lValue; + else if (!Bstrcmp(szLabel,"ROTATEGUN")) ROTATEGUN = lValue; + else if (!Bstrcmp(szLabel,"RPGGUN")) RPGGUN = lValue; + else if (!Bstrcmp(szLabel,"RPGMUZZLEFLASH")) RPGMUZZLEFLASH = lValue; + else if (!Bstrcmp(szLabel,"RPG")) RPG = lValue; + else if (!Bstrcmp(szLabel,"RESPAWNMARKERRED")) RESPAWNMARKERRED = lValue; + else if (!Bstrcmp(szLabel,"RESPAWNMARKERYELLOW")) RESPAWNMARKERYELLOW = lValue; + else if (!Bstrcmp(szLabel,"RESPAWNMARKERGREEN")) RESPAWNMARKERGREEN = lValue; + else if (!Bstrcmp(szLabel,"ROBOTDOG")) ROBOTDOG = lValue; + else if (!Bstrcmp(szLabel,"ROBOTPIRATE")) ROBOTPIRATE = lValue; + else if (!Bstrcmp(szLabel,"ROBOTMOUSE")) ROBOTMOUSE = lValue; + else if (!Bstrcmp(szLabel,"ROBOTDOG2")) ROBOTDOG2 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT1")) RESERVEDSLOT1 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT2")) RESERVEDSLOT2 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT3")) RESERVEDSLOT3 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT4")) RESERVEDSLOT4 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT5")) RESERVEDSLOT5 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT6")) RESERVEDSLOT6 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT7")) RESERVEDSLOT7 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT8")) RESERVEDSLOT8 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT9")) RESERVEDSLOT9 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT10")) RESERVEDSLOT10 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT11")) RESERVEDSLOT11 = lValue; + else if (!Bstrcmp(szLabel,"RESERVEDSLOT12")) RESERVEDSLOT12 = lValue; + break; + case 'S': + if (!Bstrcmp(szLabel,"SECTOREFFECTOR")) SECTOREFFECTOR = lValue; + else if (!Bstrcmp(szLabel,"SHRINKERSPRITE")) SHRINKERSPRITE = lValue; + else if (!Bstrcmp(szLabel,"SHOTGUNSPRITE")) SHOTGUNSPRITE = lValue; + else if (!Bstrcmp(szLabel,"SHOTGUNAMMO")) SHOTGUNAMMO = lValue; + else if (!Bstrcmp(szLabel,"SIXPAK")) SIXPAK = lValue; + else if (!Bstrcmp(szLabel,"SHIELD")) SHIELD = lValue; + else if (!Bstrcmp(szLabel,"STEROIDS")) STEROIDS = lValue; + else if (!Bstrcmp(szLabel,"SLOTDOOR")) SLOTDOOR = lValue; + else if (!Bstrcmp(szLabel,"SPACEDOORSWITCH")) SPACEDOORSWITCH = lValue; + else if (!Bstrcmp(szLabel,"SPACELIGHTSWITCH")) SPACELIGHTSWITCH = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK1")) SCREENBREAK1 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK2")) SCREENBREAK2 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK3")) SCREENBREAK3 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK4")) SCREENBREAK4 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK5")) SCREENBREAK5 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK6")) SCREENBREAK6 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK7")) SCREENBREAK7 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK8")) SCREENBREAK8 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK9")) SCREENBREAK9 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK10")) SCREENBREAK10 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK11")) SCREENBREAK11 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK12")) SCREENBREAK12 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK13")) SCREENBREAK13 = lValue; + else if (!Bstrcmp(szLabel,"STATIC")) STATIC = lValue; + else if (!Bstrcmp(szLabel,"SATELLITE")) SATELLITE = lValue; + else if (!Bstrcmp(szLabel,"STAINGLASS1")) STAINGLASS1 = lValue; + else if (!Bstrcmp(szLabel,"SATELITE")) SATELITE = lValue; + else if (!Bstrcmp(szLabel,"SLIMEPIPE")) SLIMEPIPE = lValue; + else if (!Bstrcmp(szLabel,"STALL")) STALL = lValue; + else if (!Bstrcmp(szLabel,"STALLBROKE")) STALLBROKE = lValue; + else if (!Bstrcmp(szLabel,"SOLARPANNEL")) SOLARPANNEL = lValue; + else if (!Bstrcmp(szLabel,"SPLINTERWOOD")) SPLINTERWOOD = lValue; + else if (!Bstrcmp(szLabel,"SCALE")) SCALE = lValue; + else if (!Bstrcmp(szLabel,"STATUE")) STATUE = lValue; + else if (!Bstrcmp(szLabel,"SUSHIPLATE1")) SUSHIPLATE1 = lValue; + else if (!Bstrcmp(szLabel,"SUSHIPLATE2")) SUSHIPLATE2 = lValue; + else if (!Bstrcmp(szLabel,"SUSHIPLATE3")) SUSHIPLATE3 = lValue; + else if (!Bstrcmp(szLabel,"SUSHIPLATE4")) SUSHIPLATE4 = lValue; + else if (!Bstrcmp(szLabel,"SUSHIPLATE5")) SUSHIPLATE5 = lValue; + else if (!Bstrcmp(szLabel,"STATUEFLASH")) STATUEFLASH = lValue; + else if (!Bstrcmp(szLabel,"STRIPEBALL")) STRIPEBALL = lValue; + else if (!Bstrcmp(szLabel,"SPOTLITE")) SPOTLITE = lValue; + else if (!Bstrcmp(szLabel,"SEENINE")) SEENINE = lValue; + else if (!Bstrcmp(szLabel,"SEENINEDEAD")) SEENINEDEAD = lValue; + else if (!Bstrcmp(szLabel,"STEAM")) STEAM = lValue; + else if (!Bstrcmp(szLabel,"SPACEMARINE")) SPACEMARINE = lValue; + else if (!Bstrcmp(szLabel,"SCRATCH")) SCRATCH = lValue; + else if (!Bstrcmp(szLabel,"SHARK")) SHARK = lValue; + else if (!Bstrcmp(szLabel,"SPIT")) SPIT = lValue; + else if (!Bstrcmp(szLabel,"SHRINKSPARK")) SHRINKSPARK = lValue; + else if (!Bstrcmp(szLabel,"SHRINKEREXPLOSION")) SHRINKEREXPLOSION = lValue; + else if (!Bstrcmp(szLabel,"SMALLSMOKE")) SMALLSMOKE = lValue; + else if (!Bstrcmp(szLabel,"SMALLSMOKEMAKER")) SMALLSMOKEMAKER = lValue; + else if (!Bstrcmp(szLabel,"SCRAP6")) SCRAP6 = lValue; + else if (!Bstrcmp(szLabel,"SCRAP1")) SCRAP1 = lValue; + else if (!Bstrcmp(szLabel,"SCRAP2")) SCRAP2 = lValue; + else if (!Bstrcmp(szLabel,"SCRAP3")) SCRAP3 = lValue; + else if (!Bstrcmp(szLabel,"SCRAP4")) SCRAP4 = lValue; + else if (!Bstrcmp(szLabel,"SCRAP5")) SCRAP5 = lValue; + else if (!Bstrcmp(szLabel,"SELECTDIR")) SELECTDIR = lValue; + else if (!Bstrcmp(szLabel,"STEROIDS_ICON")) STEROIDS_ICON = lValue; + else if (!Bstrcmp(szLabel,"SLIDEBAR")) SLIDEBAR = lValue; + else if (!Bstrcmp(szLabel,"SHELL")) SHELL = lValue; + else if (!Bstrcmp(szLabel,"SHOTGUNSHELL")) SHOTGUNSHELL = lValue; + else if (!Bstrcmp(szLabel,"SHRINKER")) SHRINKER = lValue; + else if (!Bstrcmp(szLabel,"SCUBAMASK")) SCUBAMASK = lValue; + else if (!Bstrcmp(szLabel,"SPACEMASK")) SPACEMASK = lValue; + else if (!Bstrcmp(szLabel,"SHOTSPARK1")) SHOTSPARK1 = lValue; + else if (!Bstrcmp(szLabel,"SHOTGUN")) SHOTGUN = lValue; + else if (!Bstrcmp(szLabel,"SPINNINGNUKEICON")) SPINNINGNUKEICON = lValue; + else if (!Bstrcmp(szLabel,"SMALLFNTCURSOR")) SMALLFNTCURSOR = lValue; + else if (!Bstrcmp(szLabel,"STARTALPHANUM")) STARTALPHANUM = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK14")) SCREENBREAK14 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK15")) SCREENBREAK15 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK19")) SCREENBREAK19 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK16")) SCREENBREAK16 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK17")) SCREENBREAK17 = lValue; + else if (!Bstrcmp(szLabel,"SCREENBREAK18")) SCREENBREAK18 = lValue; + else if (!Bstrcmp(szLabel,"SPEAKER")) SPEAKER = lValue; + else if (!Bstrcmp(szLabel,"SIDEBOLT1")) SIDEBOLT1 = lValue; + else if (!Bstrcmp(szLabel,"SKINNEDCHICKEN")) SKINNEDCHICKEN = lValue; + else if (!Bstrcmp(szLabel,"SHOPPINGCART")) SHOPPINGCART = lValue; + else if (!Bstrcmp(szLabel,"SNAKEP")) SNAKEP = lValue; + else if (!Bstrcmp(szLabel,"SIGN1")) SIGN1 = lValue; + else if (!Bstrcmp(szLabel,"SIGN2")) SIGN2 = lValue; + break; + case 'T': + if (!Bstrcmp(szLabel,"TOUCHPLATE")) TOUCHPLATE = lValue; + else if (!Bstrcmp(szLabel,"TRIPBOMBSPRITE")) TRIPBOMBSPRITE = lValue; + else if (!Bstrcmp(szLabel,"TECHLIGHT2")) TECHLIGHT2 = lValue; + else if (!Bstrcmp(szLabel,"TECHLIGHTBUST2")) TECHLIGHTBUST2 = lValue; + else if (!Bstrcmp(szLabel,"TECHLIGHT4")) TECHLIGHT4 = lValue; + else if (!Bstrcmp(szLabel,"TECHLIGHTBUST4")) TECHLIGHTBUST4 = lValue; + else if (!Bstrcmp(szLabel,"TECHSWITCH")) TECHSWITCH = lValue; + else if (!Bstrcmp(szLabel,"TOILET")) TOILET = lValue; + else if (!Bstrcmp(szLabel,"TOILETBROKE")) TOILETBROKE = lValue; + else if (!Bstrcmp(szLabel,"TREE1")) TREE1 = lValue; + else if (!Bstrcmp(szLabel,"TREE2")) TREE2 = lValue; + else if (!Bstrcmp(szLabel,"TOILETWATER")) TOILETWATER = lValue; + else if (!Bstrcmp(szLabel,"TIRE")) TIRE = lValue; + else if (!Bstrcmp(szLabel,"TRANSPORTERBEAM")) TRANSPORTERBEAM = lValue; + else if (!Bstrcmp(szLabel,"TRASH")) TRASH = lValue; + else if (!Bstrcmp(szLabel,"TRANSPORTERSTAR")) TRANSPORTERSTAR = lValue; + else if (!Bstrcmp(szLabel,"TONGUE")) TONGUE = lValue; + else if (!Bstrcmp(szLabel,"TANK")) TANK = lValue; + else if (!Bstrcmp(szLabel,"TITLE")) TITLE = lValue; + else if (!Bstrcmp(szLabel,"TEXTBOX")) TEXTBOX = lValue; + else if (!Bstrcmp(szLabel,"THREEDEE")) THREEDEE = lValue; + else if (!Bstrcmp(szLabel,"TENSCREEN")) TENSCREEN = lValue; + else if (!Bstrcmp(szLabel,"TRIPBOMB")) TRIPBOMB = lValue; + else if (!Bstrcmp(szLabel,"TIP")) TIP = lValue; + else if (!Bstrcmp(szLabel,"THREEBYFIVE")) THREEBYFIVE = lValue; + else if (!Bstrcmp(szLabel,"TEXTSTORY")) TEXTSTORY = lValue; + else if (!Bstrcmp(szLabel,"TARGET")) TARGET = lValue; + else if (!Bstrcmp(szLabel,"TOPSECRET")) TOPSECRET = lValue; + else if (!Bstrcmp(szLabel,"TEDDYBEAR")) TEDDYBEAR = lValue; + else if (!Bstrcmp(szLabel,"TRIPODCAMERA")) TRIPODCAMERA = lValue; + else if (!Bstrcmp(szLabel,"TAMPON")) TAMPON = lValue; + else if (!Bstrcmp(szLabel,"TOUGHGAL")) TOUGHGAL = lValue; + break; + case 'U': + if (!Bstrcmp(szLabel,"USERWEAPON")) USERWEAPON = lValue; + break; + case 'V': + if (!Bstrcmp(szLabel,"VIEWSCREEN2")) VIEWSCREEN2 = lValue; + else if (!Bstrcmp(szLabel,"VIEWSCREENBROKE")) VIEWSCREENBROKE = lValue; + else if (!Bstrcmp(szLabel,"VIEWSCREEN")) VIEWSCREEN = lValue; + else if (!Bstrcmp(szLabel,"VACUUM")) VACUUM = lValue; + else if (!Bstrcmp(szLabel,"VASE")) VASE = lValue; + else if (!Bstrcmp(szLabel,"VENDMACHINE")) VENDMACHINE = lValue; + else if (!Bstrcmp(szLabel,"VENDMACHINEBROKE")) VENDMACHINEBROKE = lValue; + else if (!Bstrcmp(szLabel,"VIEWBORDER")) VIEWBORDER = lValue; + else if (!Bstrcmp(szLabel,"VICTORY1")) VICTORY1 = lValue; + break; + case 'W': + if (!Bstrcmp(szLabel,"WALLLIGHT4")) WALLLIGHT4 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHTBUST4")) WALLLIGHTBUST4 = lValue; + else if (!Bstrcmp(szLabel,"W_LIGHT")) W_LIGHT = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL1")) W_TECHWALL1 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL2")) W_TECHWALL2 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL15")) W_TECHWALL15 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL3")) W_TECHWALL3 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL4")) W_TECHWALL4 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL10")) W_TECHWALL10 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL16")) W_TECHWALL16 = lValue; + else if (!Bstrcmp(szLabel,"WATERTILE2")) WATERTILE2 = lValue; + else if (!Bstrcmp(szLabel,"WATERTILE")) WATERTILE = lValue; + else if (!Bstrcmp(szLabel,"W_SCREENBREAK")) W_SCREENBREAK = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL3")) W_HITTECHWALL3 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL4")) W_HITTECHWALL4 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL2")) W_HITTECHWALL2 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL1")) W_HITTECHWALL1 = lValue; + else if (!Bstrcmp(szLabel,"WATERFOUNTAIN")) WATERFOUNTAIN = lValue; + else if (!Bstrcmp(szLabel,"WATERFOUNTAINBROKE")) WATERFOUNTAINBROKE = lValue; + else if (!Bstrcmp(szLabel,"W_NUMBERS")) W_NUMBERS = lValue; + else if (!Bstrcmp(szLabel,"WATERDRIP")) WATERDRIP = lValue; + else if (!Bstrcmp(szLabel,"WATERBUBBLE")) WATERBUBBLE = lValue; + else if (!Bstrcmp(szLabel,"WATERBUBBLEMAKER")) WATERBUBBLEMAKER = lValue; + else if (!Bstrcmp(szLabel,"W_FORCEFIELD")) W_FORCEFIELD = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHT3")) WALLLIGHT3 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHTBUST3")) WALLLIGHTBUST3 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHT1")) WALLLIGHT1 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHTBUST1")) WALLLIGHTBUST1 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHT2")) WALLLIGHT2 = lValue; + else if (!Bstrcmp(szLabel,"WALLLIGHTBUST2")) WALLLIGHTBUST2 = lValue; + else if (!Bstrcmp(szLabel,"WAITTOBESEATED")) WAITTOBESEATED = lValue; + else if (!Bstrcmp(szLabel,"WOODENHORSE")) WOODENHORSE = lValue; + else if (!Bstrcmp(szLabel,"WATERSPLASH2")) WATERSPLASH2 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD1")) WALLBLOOD1 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD2")) WALLBLOOD2 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD3")) WALLBLOOD3 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD4")) WALLBLOOD4 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD5")) WALLBLOOD5 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD6")) WALLBLOOD6 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD7")) WALLBLOOD7 = lValue; + else if (!Bstrcmp(szLabel,"WALLBLOOD8")) WALLBLOOD8 = lValue; + else if (!Bstrcmp(szLabel,"WATERDRIPSPLASH")) WATERDRIPSPLASH = lValue; + else if (!Bstrcmp(szLabel,"WINDOWBORDER1")) WINDOWBORDER1 = lValue; + else if (!Bstrcmp(szLabel,"WINDOWBORDER2")) WINDOWBORDER2 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL11")) W_TECHWALL11 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL12")) W_TECHWALL12 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL13")) W_TECHWALL13 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL14")) W_TECHWALL14 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL5")) W_TECHWALL5 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL6")) W_TECHWALL6 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL7")) W_TECHWALL7 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL8")) W_TECHWALL8 = lValue; + else if (!Bstrcmp(szLabel,"W_TECHWALL9")) W_TECHWALL9 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL16")) W_HITTECHWALL16 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL10")) W_HITTECHWALL10 = lValue; + else if (!Bstrcmp(szLabel,"W_HITTECHWALL15")) W_HITTECHWALL15 = lValue; + else if (!Bstrcmp(szLabel,"W_MILKSHELF")) W_MILKSHELF = lValue; + else if (!Bstrcmp(szLabel,"W_MILKSHELFBROKE")) W_MILKSHELFBROKE = lValue; + else if (!Bstrcmp(szLabel,"WETFLOOR")) WETFLOOR = lValue; + else if (!Bstrcmp(szLabel,"WOMAN")) WOMAN = lValue; + else if (!Bstrcmp(szLabel,"WEATHERWARN")) WEATHERWARN = lValue; + break; + case 'X': + if (!Bstrcmp(szLabel,"XXXSTACY")) XXXSTACY = lValue; + break; + } +} + +void setupdynamictostatic(void) +{ + clearbufbyte(dynamictostatic,MAXTILES,0); + dynamictostatic[SECTOREFFECTOR] = SECTOREFFECTOR__STATIC; + dynamictostatic[ACTIVATOR] = ACTIVATOR__STATIC; + dynamictostatic[TOUCHPLATE] = TOUCHPLATE__STATIC; + dynamictostatic[ACTIVATORLOCKED] = ACTIVATORLOCKED__STATIC; + dynamictostatic[MUSICANDSFX] = MUSICANDSFX__STATIC; + dynamictostatic[LOCATORS] = LOCATORS__STATIC; + dynamictostatic[CYCLER] = CYCLER__STATIC; + dynamictostatic[MASTERSWITCH] = MASTERSWITCH__STATIC; + dynamictostatic[RESPAWN] = RESPAWN__STATIC; + dynamictostatic[GPSPEED] = GPSPEED__STATIC; + dynamictostatic[FOF] = FOF__STATIC; + dynamictostatic[ARROW] = ARROW__STATIC; + dynamictostatic[FIRSTGUNSPRITE] = FIRSTGUNSPRITE__STATIC; + dynamictostatic[CHAINGUNSPRITE] = CHAINGUNSPRITE__STATIC; + dynamictostatic[RPGSPRITE] = RPGSPRITE__STATIC; + dynamictostatic[FREEZESPRITE] = FREEZESPRITE__STATIC; + dynamictostatic[SHRINKERSPRITE] = SHRINKERSPRITE__STATIC; + dynamictostatic[HEAVYHBOMB] = HEAVYHBOMB__STATIC; + dynamictostatic[TRIPBOMBSPRITE] = TRIPBOMBSPRITE__STATIC; + dynamictostatic[SHOTGUNSPRITE] = SHOTGUNSPRITE__STATIC; + dynamictostatic[DEVISTATORSPRITE] = DEVISTATORSPRITE__STATIC; + dynamictostatic[HEALTHBOX] = HEALTHBOX__STATIC; + dynamictostatic[AMMOBOX] = AMMOBOX__STATIC; + dynamictostatic[GROWSPRITEICON] = GROWSPRITEICON__STATIC; + dynamictostatic[INVENTORYBOX] = INVENTORYBOX__STATIC; + dynamictostatic[FREEZEAMMO] = FREEZEAMMO__STATIC; + dynamictostatic[AMMO] = AMMO__STATIC; + dynamictostatic[BATTERYAMMO] = BATTERYAMMO__STATIC; + dynamictostatic[DEVISTATORAMMO] = DEVISTATORAMMO__STATIC; + dynamictostatic[RPGAMMO] = RPGAMMO__STATIC; + dynamictostatic[GROWAMMO] = GROWAMMO__STATIC; + dynamictostatic[CRYSTALAMMO] = CRYSTALAMMO__STATIC; + dynamictostatic[HBOMBAMMO] = HBOMBAMMO__STATIC; + dynamictostatic[AMMOLOTS] = AMMOLOTS__STATIC; + dynamictostatic[SHOTGUNAMMO] = SHOTGUNAMMO__STATIC; + dynamictostatic[COLA] = COLA__STATIC; + dynamictostatic[SIXPAK] = SIXPAK__STATIC; + dynamictostatic[FIRSTAID] = FIRSTAID__STATIC; + dynamictostatic[SHIELD] = SHIELD__STATIC; + dynamictostatic[STEROIDS] = STEROIDS__STATIC; + dynamictostatic[AIRTANK] = AIRTANK__STATIC; + dynamictostatic[JETPACK] = JETPACK__STATIC; + dynamictostatic[HEATSENSOR] = HEATSENSOR__STATIC; + dynamictostatic[ACCESSCARD] = ACCESSCARD__STATIC; + dynamictostatic[BOOTS] = BOOTS__STATIC; + dynamictostatic[MIRRORBROKE] = MIRRORBROKE__STATIC; + dynamictostatic[CLOUDYOCEAN] = CLOUDYOCEAN__STATIC; + dynamictostatic[CLOUDYSKIES] = CLOUDYSKIES__STATIC; + dynamictostatic[MOONSKY1] = MOONSKY1__STATIC; + dynamictostatic[MOONSKY2] = MOONSKY2__STATIC; + dynamictostatic[MOONSKY3] = MOONSKY3__STATIC; + dynamictostatic[MOONSKY4] = MOONSKY4__STATIC; + dynamictostatic[BIGORBIT1] = BIGORBIT1__STATIC; + dynamictostatic[BIGORBIT2] = BIGORBIT2__STATIC; + dynamictostatic[BIGORBIT3] = BIGORBIT3__STATIC; + dynamictostatic[BIGORBIT4] = BIGORBIT4__STATIC; + dynamictostatic[BIGORBIT5] = BIGORBIT5__STATIC; + dynamictostatic[LA] = LA__STATIC; + dynamictostatic[REDSKY1] = REDSKY1__STATIC; + dynamictostatic[REDSKY2] = REDSKY2__STATIC; + dynamictostatic[ATOMICHEALTH] = ATOMICHEALTH__STATIC; + dynamictostatic[TECHLIGHT2] = TECHLIGHT2__STATIC; + dynamictostatic[TECHLIGHTBUST2] = TECHLIGHTBUST2__STATIC; + dynamictostatic[TECHLIGHT4] = TECHLIGHT4__STATIC; + dynamictostatic[TECHLIGHTBUST4] = TECHLIGHTBUST4__STATIC; + dynamictostatic[WALLLIGHT4] = WALLLIGHT4__STATIC; + dynamictostatic[WALLLIGHTBUST4] = WALLLIGHTBUST4__STATIC; + dynamictostatic[ACCESSSWITCH] = ACCESSSWITCH__STATIC; + dynamictostatic[SLOTDOOR] = SLOTDOOR__STATIC; + dynamictostatic[LIGHTSWITCH] = LIGHTSWITCH__STATIC; + dynamictostatic[SPACEDOORSWITCH] = SPACEDOORSWITCH__STATIC; + dynamictostatic[SPACELIGHTSWITCH] = SPACELIGHTSWITCH__STATIC; + dynamictostatic[FRANKENSTINESWITCH] = FRANKENSTINESWITCH__STATIC; + dynamictostatic[NUKEBUTTON] = NUKEBUTTON__STATIC; + dynamictostatic[MULTISWITCH] = MULTISWITCH__STATIC; + dynamictostatic[DOORTILE5] = DOORTILE5__STATIC; + dynamictostatic[DOORTILE6] = DOORTILE6__STATIC; + dynamictostatic[DOORTILE1] = DOORTILE1__STATIC; + dynamictostatic[DOORTILE2] = DOORTILE2__STATIC; + dynamictostatic[DOORTILE3] = DOORTILE3__STATIC; + dynamictostatic[DOORTILE4] = DOORTILE4__STATIC; + dynamictostatic[DOORTILE7] = DOORTILE7__STATIC; + dynamictostatic[DOORTILE8] = DOORTILE8__STATIC; + dynamictostatic[DOORTILE9] = DOORTILE9__STATIC; + dynamictostatic[DOORTILE10] = DOORTILE10__STATIC; + dynamictostatic[DOORSHOCK] = DOORSHOCK__STATIC; + dynamictostatic[DIPSWITCH] = DIPSWITCH__STATIC; + dynamictostatic[DIPSWITCH2] = DIPSWITCH2__STATIC; + dynamictostatic[TECHSWITCH] = TECHSWITCH__STATIC; + dynamictostatic[DIPSWITCH3] = DIPSWITCH3__STATIC; + dynamictostatic[ACCESSSWITCH2] = ACCESSSWITCH2__STATIC; + dynamictostatic[REFLECTWATERTILE] = REFLECTWATERTILE__STATIC; + dynamictostatic[FLOORSLIME] = FLOORSLIME__STATIC; + dynamictostatic[BIGFORCE] = BIGFORCE__STATIC; + dynamictostatic[EPISODE] = EPISODE__STATIC; + dynamictostatic[MASKWALL9] = MASKWALL9__STATIC; + dynamictostatic[W_LIGHT] = W_LIGHT__STATIC; + dynamictostatic[SCREENBREAK1] = SCREENBREAK1__STATIC; + dynamictostatic[SCREENBREAK2] = SCREENBREAK2__STATIC; + dynamictostatic[SCREENBREAK3] = SCREENBREAK3__STATIC; + dynamictostatic[SCREENBREAK4] = SCREENBREAK4__STATIC; + dynamictostatic[SCREENBREAK5] = SCREENBREAK5__STATIC; + dynamictostatic[SCREENBREAK6] = SCREENBREAK6__STATIC; + dynamictostatic[SCREENBREAK7] = SCREENBREAK7__STATIC; + dynamictostatic[SCREENBREAK8] = SCREENBREAK8__STATIC; + dynamictostatic[SCREENBREAK9] = SCREENBREAK9__STATIC; + dynamictostatic[SCREENBREAK10] = SCREENBREAK10__STATIC; + dynamictostatic[SCREENBREAK11] = SCREENBREAK11__STATIC; + dynamictostatic[SCREENBREAK12] = SCREENBREAK12__STATIC; + dynamictostatic[SCREENBREAK13] = SCREENBREAK13__STATIC; + dynamictostatic[MASKWALL1] = MASKWALL1__STATIC; + dynamictostatic[W_TECHWALL1] = W_TECHWALL1__STATIC; + dynamictostatic[W_TECHWALL2] = W_TECHWALL2__STATIC; + dynamictostatic[W_TECHWALL15] = W_TECHWALL15__STATIC; + dynamictostatic[W_TECHWALL3] = W_TECHWALL3__STATIC; + dynamictostatic[W_TECHWALL4] = W_TECHWALL4__STATIC; + dynamictostatic[W_TECHWALL10] = W_TECHWALL10__STATIC; + dynamictostatic[W_TECHWALL16] = W_TECHWALL16__STATIC; + dynamictostatic[WATERTILE2] = WATERTILE2__STATIC; + dynamictostatic[BPANNEL1] = BPANNEL1__STATIC; + dynamictostatic[PANNEL1] = PANNEL1__STATIC; + dynamictostatic[PANNEL2] = PANNEL2__STATIC; + dynamictostatic[WATERTILE] = WATERTILE__STATIC; + dynamictostatic[STATIC] = STATIC__STATIC; + dynamictostatic[W_SCREENBREAK] = W_SCREENBREAK__STATIC; + dynamictostatic[W_HITTECHWALL3] = W_HITTECHWALL3__STATIC; + dynamictostatic[W_HITTECHWALL4] = W_HITTECHWALL4__STATIC; + dynamictostatic[W_HITTECHWALL2] = W_HITTECHWALL2__STATIC; + dynamictostatic[W_HITTECHWALL1] = W_HITTECHWALL1__STATIC; + dynamictostatic[MASKWALL10] = MASKWALL10__STATIC; + dynamictostatic[MASKWALL11] = MASKWALL11__STATIC; + dynamictostatic[DOORTILE22] = DOORTILE22__STATIC; + dynamictostatic[FANSPRITE] = FANSPRITE__STATIC; + dynamictostatic[FANSPRITEBROKE] = FANSPRITEBROKE__STATIC; + dynamictostatic[FANSHADOW] = FANSHADOW__STATIC; + dynamictostatic[FANSHADOWBROKE] = FANSHADOWBROKE__STATIC; + dynamictostatic[DOORTILE18] = DOORTILE18__STATIC; + dynamictostatic[DOORTILE19] = DOORTILE19__STATIC; + dynamictostatic[DOORTILE20] = DOORTILE20__STATIC; + dynamictostatic[SATELLITE] = SATELLITE__STATIC; + dynamictostatic[VIEWSCREEN2] = VIEWSCREEN2__STATIC; + dynamictostatic[VIEWSCREENBROKE] = VIEWSCREENBROKE__STATIC; + dynamictostatic[VIEWSCREEN] = VIEWSCREEN__STATIC; + dynamictostatic[GLASS] = GLASS__STATIC; + dynamictostatic[GLASS2] = GLASS2__STATIC; + dynamictostatic[STAINGLASS1] = STAINGLASS1__STATIC; + dynamictostatic[MASKWALL5] = MASKWALL5__STATIC; + dynamictostatic[SATELITE] = SATELITE__STATIC; + dynamictostatic[FUELPOD] = FUELPOD__STATIC; + dynamictostatic[SLIMEPIPE] = SLIMEPIPE__STATIC; + dynamictostatic[CRACK1] = CRACK1__STATIC; + dynamictostatic[CRACK2] = CRACK2__STATIC; + dynamictostatic[CRACK3] = CRACK3__STATIC; + dynamictostatic[CRACK4] = CRACK4__STATIC; + dynamictostatic[FOOTPRINTS] = FOOTPRINTS__STATIC; + dynamictostatic[DOMELITE] = DOMELITE__STATIC; + dynamictostatic[CAMERAPOLE] = CAMERAPOLE__STATIC; + dynamictostatic[CHAIR1] = CHAIR1__STATIC; + dynamictostatic[CHAIR2] = CHAIR2__STATIC; + dynamictostatic[BROKENCHAIR] = BROKENCHAIR__STATIC; + dynamictostatic[MIRROR] = MIRROR__STATIC; + dynamictostatic[WATERFOUNTAIN] = WATERFOUNTAIN__STATIC; + dynamictostatic[WATERFOUNTAINBROKE] = WATERFOUNTAINBROKE__STATIC; + dynamictostatic[FEMMAG1] = FEMMAG1__STATIC; + dynamictostatic[TOILET] = TOILET__STATIC; + dynamictostatic[STALL] = STALL__STATIC; + dynamictostatic[STALLBROKE] = STALLBROKE__STATIC; + dynamictostatic[FEMMAG2] = FEMMAG2__STATIC; + dynamictostatic[REACTOR2] = REACTOR2__STATIC; + dynamictostatic[REACTOR2BURNT] = REACTOR2BURNT__STATIC; + dynamictostatic[REACTOR2SPARK] = REACTOR2SPARK__STATIC; + dynamictostatic[GRATE1] = GRATE1__STATIC; + dynamictostatic[BGRATE1] = BGRATE1__STATIC; + dynamictostatic[SOLARPANNEL] = SOLARPANNEL__STATIC; + dynamictostatic[NAKED1] = NAKED1__STATIC; + dynamictostatic[ANTENNA] = ANTENNA__STATIC; + dynamictostatic[MASKWALL12] = MASKWALL12__STATIC; + dynamictostatic[TOILETBROKE] = TOILETBROKE__STATIC; + dynamictostatic[PIPE2] = PIPE2__STATIC; + dynamictostatic[PIPE1B] = PIPE1B__STATIC; + dynamictostatic[PIPE3] = PIPE3__STATIC; + dynamictostatic[PIPE1] = PIPE1__STATIC; + dynamictostatic[CAMERA1] = CAMERA1__STATIC; + dynamictostatic[BRICK] = BRICK__STATIC; + dynamictostatic[SPLINTERWOOD] = SPLINTERWOOD__STATIC; + dynamictostatic[PIPE2B] = PIPE2B__STATIC; + dynamictostatic[BOLT1] = BOLT1__STATIC; + dynamictostatic[W_NUMBERS] = W_NUMBERS__STATIC; + dynamictostatic[WATERDRIP] = WATERDRIP__STATIC; + dynamictostatic[WATERBUBBLE] = WATERBUBBLE__STATIC; + dynamictostatic[WATERBUBBLEMAKER] = WATERBUBBLEMAKER__STATIC; + dynamictostatic[W_FORCEFIELD] = W_FORCEFIELD__STATIC; + dynamictostatic[VACUUM] = VACUUM__STATIC; + dynamictostatic[FOOTPRINTS2] = FOOTPRINTS2__STATIC; + dynamictostatic[FOOTPRINTS3] = FOOTPRINTS3__STATIC; + dynamictostatic[FOOTPRINTS4] = FOOTPRINTS4__STATIC; + dynamictostatic[EGG] = EGG__STATIC; + dynamictostatic[SCALE] = SCALE__STATIC; + dynamictostatic[CHAIR3] = CHAIR3__STATIC; + dynamictostatic[CAMERALIGHT] = CAMERALIGHT__STATIC; + dynamictostatic[MOVIECAMERA] = MOVIECAMERA__STATIC; + dynamictostatic[IVUNIT] = IVUNIT__STATIC; + dynamictostatic[POT1] = POT1__STATIC; + dynamictostatic[POT2] = POT2__STATIC; + dynamictostatic[POT3] = POT3__STATIC; + dynamictostatic[PIPE3B] = PIPE3B__STATIC; + dynamictostatic[WALLLIGHT3] = WALLLIGHT3__STATIC; + dynamictostatic[WALLLIGHTBUST3] = WALLLIGHTBUST3__STATIC; + dynamictostatic[WALLLIGHT1] = WALLLIGHT1__STATIC; + dynamictostatic[WALLLIGHTBUST1] = WALLLIGHTBUST1__STATIC; + dynamictostatic[WALLLIGHT2] = WALLLIGHT2__STATIC; + dynamictostatic[WALLLIGHTBUST2] = WALLLIGHTBUST2__STATIC; + dynamictostatic[LIGHTSWITCH2] = LIGHTSWITCH2__STATIC; + dynamictostatic[WAITTOBESEATED] = WAITTOBESEATED__STATIC; + dynamictostatic[DOORTILE14] = DOORTILE14__STATIC; + dynamictostatic[STATUE] = STATUE__STATIC; + dynamictostatic[MIKE] = MIKE__STATIC; + dynamictostatic[VASE] = VASE__STATIC; + dynamictostatic[SUSHIPLATE1] = SUSHIPLATE1__STATIC; + dynamictostatic[SUSHIPLATE2] = SUSHIPLATE2__STATIC; + dynamictostatic[SUSHIPLATE3] = SUSHIPLATE3__STATIC; + dynamictostatic[SUSHIPLATE4] = SUSHIPLATE4__STATIC; + dynamictostatic[DOORTILE16] = DOORTILE16__STATIC; + dynamictostatic[SUSHIPLATE5] = SUSHIPLATE5__STATIC; + dynamictostatic[OJ] = OJ__STATIC; + dynamictostatic[MASKWALL13] = MASKWALL13__STATIC; + dynamictostatic[HURTRAIL] = HURTRAIL__STATIC; + dynamictostatic[POWERSWITCH1] = POWERSWITCH1__STATIC; + dynamictostatic[LOCKSWITCH1] = LOCKSWITCH1__STATIC; + dynamictostatic[POWERSWITCH2] = POWERSWITCH2__STATIC; + dynamictostatic[ATM] = ATM__STATIC; + dynamictostatic[STATUEFLASH] = STATUEFLASH__STATIC; + dynamictostatic[ATMBROKE] = ATMBROKE__STATIC; + dynamictostatic[BIGHOLE2] = BIGHOLE2__STATIC; + dynamictostatic[STRIPEBALL] = STRIPEBALL__STATIC; + dynamictostatic[QUEBALL] = QUEBALL__STATIC; + dynamictostatic[POCKET] = POCKET__STATIC; + dynamictostatic[WOODENHORSE] = WOODENHORSE__STATIC; + dynamictostatic[TREE1] = TREE1__STATIC; + dynamictostatic[TREE2] = TREE2__STATIC; + dynamictostatic[CACTUS] = CACTUS__STATIC; + dynamictostatic[MASKWALL2] = MASKWALL2__STATIC; + dynamictostatic[MASKWALL3] = MASKWALL3__STATIC; + dynamictostatic[MASKWALL4] = MASKWALL4__STATIC; + dynamictostatic[FIREEXT] = FIREEXT__STATIC; + dynamictostatic[TOILETWATER] = TOILETWATER__STATIC; + dynamictostatic[NEON1] = NEON1__STATIC; + dynamictostatic[NEON2] = NEON2__STATIC; + dynamictostatic[CACTUSBROKE] = CACTUSBROKE__STATIC; + dynamictostatic[BOUNCEMINE] = BOUNCEMINE__STATIC; + dynamictostatic[BROKEFIREHYDRENT] = BROKEFIREHYDRENT__STATIC; + dynamictostatic[BOX] = BOX__STATIC; + dynamictostatic[BULLETHOLE] = BULLETHOLE__STATIC; + dynamictostatic[BOTTLE1] = BOTTLE1__STATIC; + dynamictostatic[BOTTLE2] = BOTTLE2__STATIC; + dynamictostatic[BOTTLE3] = BOTTLE3__STATIC; + dynamictostatic[BOTTLE4] = BOTTLE4__STATIC; + dynamictostatic[FEMPIC5] = FEMPIC5__STATIC; + dynamictostatic[FEMPIC6] = FEMPIC6__STATIC; + dynamictostatic[FEMPIC7] = FEMPIC7__STATIC; + dynamictostatic[HYDROPLANT] = HYDROPLANT__STATIC; + dynamictostatic[OCEANSPRITE1] = OCEANSPRITE1__STATIC; + dynamictostatic[OCEANSPRITE2] = OCEANSPRITE2__STATIC; + dynamictostatic[OCEANSPRITE3] = OCEANSPRITE3__STATIC; + dynamictostatic[OCEANSPRITE4] = OCEANSPRITE4__STATIC; + dynamictostatic[OCEANSPRITE5] = OCEANSPRITE5__STATIC; + dynamictostatic[GENERICPOLE] = GENERICPOLE__STATIC; + dynamictostatic[CONE] = CONE__STATIC; + dynamictostatic[HANGLIGHT] = HANGLIGHT__STATIC; + dynamictostatic[HYDRENT] = HYDRENT__STATIC; + dynamictostatic[MASKWALL14] = MASKWALL14__STATIC; + dynamictostatic[TIRE] = TIRE__STATIC; + dynamictostatic[PIPE5] = PIPE5__STATIC; + dynamictostatic[PIPE6] = PIPE6__STATIC; + dynamictostatic[PIPE4] = PIPE4__STATIC; + dynamictostatic[PIPE4B] = PIPE4B__STATIC; + dynamictostatic[BROKEHYDROPLANT] = BROKEHYDROPLANT__STATIC; + dynamictostatic[PIPE5B] = PIPE5B__STATIC; + dynamictostatic[NEON3] = NEON3__STATIC; + dynamictostatic[NEON4] = NEON4__STATIC; + dynamictostatic[NEON5] = NEON5__STATIC; + dynamictostatic[BOTTLE5] = BOTTLE5__STATIC; + dynamictostatic[BOTTLE6] = BOTTLE6__STATIC; + dynamictostatic[BOTTLE8] = BOTTLE8__STATIC; + dynamictostatic[SPOTLITE] = SPOTLITE__STATIC; + dynamictostatic[HANGOOZ] = HANGOOZ__STATIC; + dynamictostatic[MASKWALL15] = MASKWALL15__STATIC; + dynamictostatic[BOTTLE7] = BOTTLE7__STATIC; + dynamictostatic[HORSEONSIDE] = HORSEONSIDE__STATIC; + dynamictostatic[GLASSPIECES] = GLASSPIECES__STATIC; + dynamictostatic[HORSELITE] = HORSELITE__STATIC; + dynamictostatic[DONUTS] = DONUTS__STATIC; + dynamictostatic[NEON6] = NEON6__STATIC; + dynamictostatic[MASKWALL6] = MASKWALL6__STATIC; + dynamictostatic[CLOCK] = CLOCK__STATIC; + dynamictostatic[RUBBERCAN] = RUBBERCAN__STATIC; + dynamictostatic[BROKENCLOCK] = BROKENCLOCK__STATIC; + dynamictostatic[PLUG] = PLUG__STATIC; + dynamictostatic[OOZFILTER] = OOZFILTER__STATIC; + dynamictostatic[FLOORPLASMA] = FLOORPLASMA__STATIC; + dynamictostatic[REACTOR] = REACTOR__STATIC; + dynamictostatic[REACTORSPARK] = REACTORSPARK__STATIC; + dynamictostatic[REACTORBURNT] = REACTORBURNT__STATIC; + dynamictostatic[DOORTILE15] = DOORTILE15__STATIC; + dynamictostatic[HANDSWITCH] = HANDSWITCH__STATIC; + dynamictostatic[CIRCLEPANNEL] = CIRCLEPANNEL__STATIC; + dynamictostatic[CIRCLEPANNELBROKE] = CIRCLEPANNELBROKE__STATIC; + dynamictostatic[PULLSWITCH] = PULLSWITCH__STATIC; + dynamictostatic[MASKWALL8] = MASKWALL8__STATIC; + dynamictostatic[BIGHOLE] = BIGHOLE__STATIC; + dynamictostatic[ALIENSWITCH] = ALIENSWITCH__STATIC; + dynamictostatic[DOORTILE21] = DOORTILE21__STATIC; + dynamictostatic[HANDPRINTSWITCH] = HANDPRINTSWITCH__STATIC; + dynamictostatic[BOTTLE10] = BOTTLE10__STATIC; + dynamictostatic[BOTTLE11] = BOTTLE11__STATIC; + dynamictostatic[BOTTLE12] = BOTTLE12__STATIC; + dynamictostatic[BOTTLE13] = BOTTLE13__STATIC; + dynamictostatic[BOTTLE14] = BOTTLE14__STATIC; + dynamictostatic[BOTTLE15] = BOTTLE15__STATIC; + dynamictostatic[BOTTLE16] = BOTTLE16__STATIC; + dynamictostatic[BOTTLE17] = BOTTLE17__STATIC; + dynamictostatic[BOTTLE18] = BOTTLE18__STATIC; + dynamictostatic[BOTTLE19] = BOTTLE19__STATIC; + dynamictostatic[DOORTILE17] = DOORTILE17__STATIC; + dynamictostatic[MASKWALL7] = MASKWALL7__STATIC; + dynamictostatic[JAILBARBREAK] = JAILBARBREAK__STATIC; + dynamictostatic[DOORTILE11] = DOORTILE11__STATIC; + dynamictostatic[DOORTILE12] = DOORTILE12__STATIC; + dynamictostatic[VENDMACHINE] = VENDMACHINE__STATIC; + dynamictostatic[VENDMACHINEBROKE] = VENDMACHINEBROKE__STATIC; + dynamictostatic[COLAMACHINE] = COLAMACHINE__STATIC; + dynamictostatic[COLAMACHINEBROKE] = COLAMACHINEBROKE__STATIC; + dynamictostatic[CRANEPOLE] = CRANEPOLE__STATIC; + dynamictostatic[CRANE] = CRANE__STATIC; + dynamictostatic[BARBROKE] = BARBROKE__STATIC; + dynamictostatic[BLOODPOOL] = BLOODPOOL__STATIC; + dynamictostatic[NUKEBARREL] = NUKEBARREL__STATIC; + dynamictostatic[NUKEBARRELDENTED] = NUKEBARRELDENTED__STATIC; + dynamictostatic[NUKEBARRELLEAKED] = NUKEBARRELLEAKED__STATIC; + dynamictostatic[CANWITHSOMETHING] = CANWITHSOMETHING__STATIC; + dynamictostatic[MONEY] = MONEY__STATIC; + dynamictostatic[BANNER] = BANNER__STATIC; + dynamictostatic[EXPLODINGBARREL] = EXPLODINGBARREL__STATIC; + dynamictostatic[EXPLODINGBARREL2] = EXPLODINGBARREL2__STATIC; + dynamictostatic[FIREBARREL] = FIREBARREL__STATIC; + dynamictostatic[SEENINE] = SEENINE__STATIC; + dynamictostatic[SEENINEDEAD] = SEENINEDEAD__STATIC; + dynamictostatic[STEAM] = STEAM__STATIC; + dynamictostatic[CEILINGSTEAM] = CEILINGSTEAM__STATIC; + dynamictostatic[PIPE6B] = PIPE6B__STATIC; + dynamictostatic[TRANSPORTERBEAM] = TRANSPORTERBEAM__STATIC; + dynamictostatic[RAT] = RAT__STATIC; + dynamictostatic[TRASH] = TRASH__STATIC; + dynamictostatic[FEMPIC1] = FEMPIC1__STATIC; + dynamictostatic[FEMPIC2] = FEMPIC2__STATIC; + dynamictostatic[BLANKSCREEN] = BLANKSCREEN__STATIC; + dynamictostatic[PODFEM1] = PODFEM1__STATIC; + dynamictostatic[FEMPIC3] = FEMPIC3__STATIC; + dynamictostatic[FEMPIC4] = FEMPIC4__STATIC; + dynamictostatic[FEM1] = FEM1__STATIC; + dynamictostatic[FEM2] = FEM2__STATIC; + dynamictostatic[FEM3] = FEM3__STATIC; + dynamictostatic[FEM5] = FEM5__STATIC; + dynamictostatic[BLOODYPOLE] = BLOODYPOLE__STATIC; + dynamictostatic[FEM4] = FEM4__STATIC; + dynamictostatic[FEM6] = FEM6__STATIC; + dynamictostatic[FEM6PAD] = FEM6PAD__STATIC; + dynamictostatic[FEM8] = FEM8__STATIC; + dynamictostatic[HELECOPT] = HELECOPT__STATIC; + dynamictostatic[FETUSJIB] = FETUSJIB__STATIC; + dynamictostatic[HOLODUKE] = HOLODUKE__STATIC; + dynamictostatic[SPACEMARINE] = SPACEMARINE__STATIC; + dynamictostatic[INDY] = INDY__STATIC; + dynamictostatic[FETUS] = FETUS__STATIC; + dynamictostatic[FETUSBROKE] = FETUSBROKE__STATIC; + dynamictostatic[MONK] = MONK__STATIC; + dynamictostatic[LUKE] = LUKE__STATIC; + dynamictostatic[COOLEXPLOSION1] = COOLEXPLOSION1__STATIC; + dynamictostatic[WATERSPLASH2] = WATERSPLASH2__STATIC; + dynamictostatic[FIREVASE] = FIREVASE__STATIC; + dynamictostatic[SCRATCH] = SCRATCH__STATIC; + dynamictostatic[FEM7] = FEM7__STATIC; + dynamictostatic[APLAYERTOP] = APLAYERTOP__STATIC; + dynamictostatic[APLAYER] = APLAYER__STATIC; + dynamictostatic[PLAYERONWATER] = PLAYERONWATER__STATIC; + dynamictostatic[DUKELYINGDEAD] = DUKELYINGDEAD__STATIC; + dynamictostatic[DUKETORSO] = DUKETORSO__STATIC; + dynamictostatic[DUKEGUN] = DUKEGUN__STATIC; + dynamictostatic[DUKELEG] = DUKELEG__STATIC; + dynamictostatic[SHARK] = SHARK__STATIC; + dynamictostatic[BLOOD] = BLOOD__STATIC; + dynamictostatic[FIRELASER] = FIRELASER__STATIC; + dynamictostatic[TRANSPORTERSTAR] = TRANSPORTERSTAR__STATIC; + dynamictostatic[SPIT] = SPIT__STATIC; + dynamictostatic[LOOGIE] = LOOGIE__STATIC; + dynamictostatic[FIST] = FIST__STATIC; + dynamictostatic[FREEZEBLAST] = FREEZEBLAST__STATIC; + dynamictostatic[DEVISTATORBLAST] = DEVISTATORBLAST__STATIC; + dynamictostatic[SHRINKSPARK] = SHRINKSPARK__STATIC; + dynamictostatic[TONGUE] = TONGUE__STATIC; + dynamictostatic[MORTER] = MORTER__STATIC; + dynamictostatic[SHRINKEREXPLOSION] = SHRINKEREXPLOSION__STATIC; + dynamictostatic[RADIUSEXPLOSION] = RADIUSEXPLOSION__STATIC; + dynamictostatic[FORCERIPPLE] = FORCERIPPLE__STATIC; + dynamictostatic[LIZTROOP] = LIZTROOP__STATIC; + dynamictostatic[LIZTROOPRUNNING] = LIZTROOPRUNNING__STATIC; + dynamictostatic[LIZTROOPSTAYPUT] = LIZTROOPSTAYPUT__STATIC; + dynamictostatic[LIZTOP] = LIZTOP__STATIC; + dynamictostatic[LIZTROOPSHOOT] = LIZTROOPSHOOT__STATIC; + dynamictostatic[LIZTROOPJETPACK] = LIZTROOPJETPACK__STATIC; + dynamictostatic[LIZTROOPDSPRITE] = LIZTROOPDSPRITE__STATIC; + dynamictostatic[LIZTROOPONTOILET] = LIZTROOPONTOILET__STATIC; + dynamictostatic[LIZTROOPJUSTSIT] = LIZTROOPJUSTSIT__STATIC; + dynamictostatic[LIZTROOPDUCKING] = LIZTROOPDUCKING__STATIC; + dynamictostatic[HEADJIB1] = HEADJIB1__STATIC; + dynamictostatic[ARMJIB1] = ARMJIB1__STATIC; + dynamictostatic[LEGJIB1] = LEGJIB1__STATIC; + dynamictostatic[CANNONBALL] = CANNONBALL__STATIC; + dynamictostatic[OCTABRAIN] = OCTABRAIN__STATIC; + dynamictostatic[OCTABRAINSTAYPUT] = OCTABRAINSTAYPUT__STATIC; + dynamictostatic[OCTATOP] = OCTATOP__STATIC; + dynamictostatic[OCTADEADSPRITE] = OCTADEADSPRITE__STATIC; + dynamictostatic[INNERJAW] = INNERJAW__STATIC; + dynamictostatic[DRONE] = DRONE__STATIC; + dynamictostatic[EXPLOSION2] = EXPLOSION2__STATIC; + dynamictostatic[COMMANDER] = COMMANDER__STATIC; + dynamictostatic[COMMANDERSTAYPUT] = COMMANDERSTAYPUT__STATIC; + dynamictostatic[RECON] = RECON__STATIC; + dynamictostatic[TANK] = TANK__STATIC; + dynamictostatic[PIGCOP] = PIGCOP__STATIC; + dynamictostatic[PIGCOPSTAYPUT] = PIGCOPSTAYPUT__STATIC; + dynamictostatic[PIGCOPDIVE] = PIGCOPDIVE__STATIC; + dynamictostatic[PIGCOPDEADSPRITE] = PIGCOPDEADSPRITE__STATIC; + dynamictostatic[PIGTOP] = PIGTOP__STATIC; + dynamictostatic[LIZMAN] = LIZMAN__STATIC; + dynamictostatic[LIZMANSTAYPUT] = LIZMANSTAYPUT__STATIC; + dynamictostatic[LIZMANSPITTING] = LIZMANSPITTING__STATIC; + dynamictostatic[LIZMANFEEDING] = LIZMANFEEDING__STATIC; + dynamictostatic[LIZMANJUMP] = LIZMANJUMP__STATIC; + dynamictostatic[LIZMANDEADSPRITE] = LIZMANDEADSPRITE__STATIC; + dynamictostatic[FECES] = FECES__STATIC; + dynamictostatic[LIZMANHEAD1] = LIZMANHEAD1__STATIC; + dynamictostatic[LIZMANARM1] = LIZMANARM1__STATIC; + dynamictostatic[LIZMANLEG1] = LIZMANLEG1__STATIC; + dynamictostatic[EXPLOSION2BOT] = EXPLOSION2BOT__STATIC; + dynamictostatic[USERWEAPON] = USERWEAPON__STATIC; + dynamictostatic[HEADERBAR] = HEADERBAR__STATIC; + dynamictostatic[JIBS1] = JIBS1__STATIC; + dynamictostatic[JIBS2] = JIBS2__STATIC; + dynamictostatic[JIBS3] = JIBS3__STATIC; + dynamictostatic[JIBS4] = JIBS4__STATIC; + dynamictostatic[JIBS5] = JIBS5__STATIC; + dynamictostatic[BURNING] = BURNING__STATIC; + dynamictostatic[FIRE] = FIRE__STATIC; + dynamictostatic[JIBS6] = JIBS6__STATIC; + dynamictostatic[BLOODSPLAT1] = BLOODSPLAT1__STATIC; + dynamictostatic[BLOODSPLAT3] = BLOODSPLAT3__STATIC; + dynamictostatic[BLOODSPLAT2] = BLOODSPLAT2__STATIC; + dynamictostatic[BLOODSPLAT4] = BLOODSPLAT4__STATIC; + dynamictostatic[OOZ] = OOZ__STATIC; + dynamictostatic[OOZ2] = OOZ2__STATIC; + dynamictostatic[WALLBLOOD1] = WALLBLOOD1__STATIC; + dynamictostatic[WALLBLOOD2] = WALLBLOOD2__STATIC; + dynamictostatic[WALLBLOOD3] = WALLBLOOD3__STATIC; + dynamictostatic[WALLBLOOD4] = WALLBLOOD4__STATIC; + dynamictostatic[WALLBLOOD5] = WALLBLOOD5__STATIC; + dynamictostatic[WALLBLOOD6] = WALLBLOOD6__STATIC; + dynamictostatic[WALLBLOOD7] = WALLBLOOD7__STATIC; + dynamictostatic[WALLBLOOD8] = WALLBLOOD8__STATIC; + dynamictostatic[BURNING2] = BURNING2__STATIC; + dynamictostatic[FIRE2] = FIRE2__STATIC; + dynamictostatic[CRACKKNUCKLES] = CRACKKNUCKLES__STATIC; + dynamictostatic[SMALLSMOKE] = SMALLSMOKE__STATIC; + dynamictostatic[SMALLSMOKEMAKER] = SMALLSMOKEMAKER__STATIC; + dynamictostatic[FLOORFLAME] = FLOORFLAME__STATIC; + dynamictostatic[ROTATEGUN] = ROTATEGUN__STATIC; + dynamictostatic[GREENSLIME] = GREENSLIME__STATIC; + dynamictostatic[WATERDRIPSPLASH] = WATERDRIPSPLASH__STATIC; + dynamictostatic[SCRAP6] = SCRAP6__STATIC; + dynamictostatic[SCRAP1] = SCRAP1__STATIC; + dynamictostatic[SCRAP2] = SCRAP2__STATIC; + dynamictostatic[SCRAP3] = SCRAP3__STATIC; + dynamictostatic[SCRAP4] = SCRAP4__STATIC; + dynamictostatic[SCRAP5] = SCRAP5__STATIC; + dynamictostatic[ORGANTIC] = ORGANTIC__STATIC; + dynamictostatic[BETAVERSION] = BETAVERSION__STATIC; + dynamictostatic[PLAYERISHERE] = PLAYERISHERE__STATIC; + dynamictostatic[PLAYERWASHERE] = PLAYERWASHERE__STATIC; + dynamictostatic[SELECTDIR] = SELECTDIR__STATIC; + dynamictostatic[F1HELP] = F1HELP__STATIC; + dynamictostatic[NOTCHON] = NOTCHON__STATIC; + dynamictostatic[NOTCHOFF] = NOTCHOFF__STATIC; + dynamictostatic[GROWSPARK] = GROWSPARK__STATIC; + dynamictostatic[DUKEICON] = DUKEICON__STATIC; + dynamictostatic[BADGUYICON] = BADGUYICON__STATIC; + dynamictostatic[FOODICON] = FOODICON__STATIC; + dynamictostatic[GETICON] = GETICON__STATIC; + dynamictostatic[MENUSCREEN] = MENUSCREEN__STATIC; + dynamictostatic[MENUBAR] = MENUBAR__STATIC; + dynamictostatic[KILLSICON] = KILLSICON__STATIC; + dynamictostatic[FIRSTAID_ICON] = FIRSTAID_ICON__STATIC; + dynamictostatic[HEAT_ICON] = HEAT_ICON__STATIC; + dynamictostatic[BOTTOMSTATUSBAR] = BOTTOMSTATUSBAR__STATIC; + dynamictostatic[BOOT_ICON] = BOOT_ICON__STATIC; + dynamictostatic[FRAGBAR] = FRAGBAR__STATIC; + dynamictostatic[JETPACK_ICON] = JETPACK_ICON__STATIC; + dynamictostatic[AIRTANK_ICON] = AIRTANK_ICON__STATIC; + dynamictostatic[STEROIDS_ICON] = STEROIDS_ICON__STATIC; + dynamictostatic[HOLODUKE_ICON] = HOLODUKE_ICON__STATIC; + dynamictostatic[ACCESS_ICON] = ACCESS_ICON__STATIC; + dynamictostatic[DIGITALNUM] = DIGITALNUM__STATIC; + dynamictostatic[DUKECAR] = DUKECAR__STATIC; + dynamictostatic[CAMCORNER] = CAMCORNER__STATIC; + dynamictostatic[CAMLIGHT] = CAMLIGHT__STATIC; + dynamictostatic[LOGO] = LOGO__STATIC; + dynamictostatic[TITLE] = TITLE__STATIC; + dynamictostatic[NUKEWARNINGICON] = NUKEWARNINGICON__STATIC; + dynamictostatic[MOUSECURSOR] = MOUSECURSOR__STATIC; + dynamictostatic[SLIDEBAR] = SLIDEBAR__STATIC; + dynamictostatic[DREALMS] = DREALMS__STATIC; + dynamictostatic[BETASCREEN] = BETASCREEN__STATIC; + dynamictostatic[WINDOWBORDER1] = WINDOWBORDER1__STATIC; + dynamictostatic[TEXTBOX] = TEXTBOX__STATIC; + dynamictostatic[WINDOWBORDER2] = WINDOWBORDER2__STATIC; + dynamictostatic[DUKENUKEM] = DUKENUKEM__STATIC; + dynamictostatic[THREEDEE] = THREEDEE__STATIC; + dynamictostatic[INGAMEDUKETHREEDEE] = INGAMEDUKETHREEDEE__STATIC; + dynamictostatic[TENSCREEN] = TENSCREEN__STATIC; + dynamictostatic[PLUTOPAKSPRITE] = PLUTOPAKSPRITE__STATIC; + dynamictostatic[DEVISTATOR] = DEVISTATOR__STATIC; + dynamictostatic[KNEE] = KNEE__STATIC; + dynamictostatic[CROSSHAIR] = CROSSHAIR__STATIC; + dynamictostatic[FIRSTGUN] = FIRSTGUN__STATIC; + dynamictostatic[FIRSTGUNRELOAD] = FIRSTGUNRELOAD__STATIC; + dynamictostatic[FALLINGCLIP] = FALLINGCLIP__STATIC; + dynamictostatic[CLIPINHAND] = CLIPINHAND__STATIC; + dynamictostatic[HAND] = HAND__STATIC; + dynamictostatic[SHELL] = SHELL__STATIC; + dynamictostatic[SHOTGUNSHELL] = SHOTGUNSHELL__STATIC; + dynamictostatic[CHAINGUN] = CHAINGUN__STATIC; + dynamictostatic[RPGGUN] = RPGGUN__STATIC; + dynamictostatic[RPGMUZZLEFLASH] = RPGMUZZLEFLASH__STATIC; + dynamictostatic[FREEZE] = FREEZE__STATIC; + dynamictostatic[CATLITE] = CATLITE__STATIC; + dynamictostatic[SHRINKER] = SHRINKER__STATIC; + dynamictostatic[HANDHOLDINGLASER] = HANDHOLDINGLASER__STATIC; + dynamictostatic[TRIPBOMB] = TRIPBOMB__STATIC; + dynamictostatic[LASERLINE] = LASERLINE__STATIC; + dynamictostatic[HANDHOLDINGACCESS] = HANDHOLDINGACCESS__STATIC; + dynamictostatic[HANDREMOTE] = HANDREMOTE__STATIC; + dynamictostatic[HANDTHROW] = HANDTHROW__STATIC; + dynamictostatic[TIP] = TIP__STATIC; + dynamictostatic[GLAIR] = GLAIR__STATIC; + dynamictostatic[SCUBAMASK] = SCUBAMASK__STATIC; + dynamictostatic[SPACEMASK] = SPACEMASK__STATIC; + dynamictostatic[FORCESPHERE] = FORCESPHERE__STATIC; + dynamictostatic[SHOTSPARK1] = SHOTSPARK1__STATIC; + dynamictostatic[RPG] = RPG__STATIC; + dynamictostatic[LASERSITE] = LASERSITE__STATIC; + dynamictostatic[SHOTGUN] = SHOTGUN__STATIC; + dynamictostatic[BOSS1] = BOSS1__STATIC; + dynamictostatic[BOSS1STAYPUT] = BOSS1STAYPUT__STATIC; + dynamictostatic[BOSS1SHOOT] = BOSS1SHOOT__STATIC; + dynamictostatic[BOSS1LOB] = BOSS1LOB__STATIC; + dynamictostatic[BOSSTOP] = BOSSTOP__STATIC; + dynamictostatic[BOSS2] = BOSS2__STATIC; + dynamictostatic[BOSS3] = BOSS3__STATIC; + dynamictostatic[SPINNINGNUKEICON] = SPINNINGNUKEICON__STATIC; + dynamictostatic[BIGFNTCURSOR] = BIGFNTCURSOR__STATIC; + dynamictostatic[SMALLFNTCURSOR] = SMALLFNTCURSOR__STATIC; + dynamictostatic[STARTALPHANUM] = STARTALPHANUM__STATIC; + dynamictostatic[ENDALPHANUM] = ENDALPHANUM__STATIC; + dynamictostatic[BIGALPHANUM] = BIGALPHANUM__STATIC; + dynamictostatic[BIGPERIOD] = BIGPERIOD__STATIC; + dynamictostatic[BIGCOMMA] = BIGCOMMA__STATIC; + dynamictostatic[BIGX] = BIGX__STATIC; + dynamictostatic[BIGQ] = BIGQ__STATIC; + dynamictostatic[BIGSEMI] = BIGSEMI__STATIC; + dynamictostatic[BIGCOLIN] = BIGCOLIN__STATIC; + dynamictostatic[THREEBYFIVE] = THREEBYFIVE__STATIC; + dynamictostatic[BIGAPPOS] = BIGAPPOS__STATIC; + dynamictostatic[BLANK] = BLANK__STATIC; + dynamictostatic[MINIFONT] = MINIFONT__STATIC; + dynamictostatic[BUTTON1] = BUTTON1__STATIC; + dynamictostatic[GLASS3] = GLASS3__STATIC; + dynamictostatic[RESPAWNMARKERRED] = RESPAWNMARKERRED__STATIC; + dynamictostatic[RESPAWNMARKERYELLOW] = RESPAWNMARKERYELLOW__STATIC; + dynamictostatic[RESPAWNMARKERGREEN] = RESPAWNMARKERGREEN__STATIC; + dynamictostatic[BONUSSCREEN] = BONUSSCREEN__STATIC; + dynamictostatic[VIEWBORDER] = VIEWBORDER__STATIC; + dynamictostatic[VICTORY1] = VICTORY1__STATIC; + dynamictostatic[ORDERING] = ORDERING__STATIC; + dynamictostatic[TEXTSTORY] = TEXTSTORY__STATIC; + dynamictostatic[LOADSCREEN] = LOADSCREEN__STATIC; + dynamictostatic[BORNTOBEWILDSCREEN] = BORNTOBEWILDSCREEN__STATIC; + dynamictostatic[BLIMP] = BLIMP__STATIC; + dynamictostatic[FEM9] = FEM9__STATIC; + dynamictostatic[FOOTPRINT] = FOOTPRINT__STATIC; + dynamictostatic[POOP] = POOP__STATIC; + dynamictostatic[FRAMEEFFECT1] = FRAMEEFFECT1__STATIC; + dynamictostatic[FRAMEEFFECT1_13] = FRAMEEFFECT1_13__STATIC; + dynamictostatic[PANNEL3] = PANNEL3__STATIC; + dynamictostatic[SCREENBREAK14] = SCREENBREAK14__STATIC; + dynamictostatic[SCREENBREAK15] = SCREENBREAK15__STATIC; + dynamictostatic[SCREENBREAK19] = SCREENBREAK19__STATIC; + dynamictostatic[SCREENBREAK16] = SCREENBREAK16__STATIC; + dynamictostatic[SCREENBREAK17] = SCREENBREAK17__STATIC; + dynamictostatic[SCREENBREAK18] = SCREENBREAK18__STATIC; + dynamictostatic[W_TECHWALL11] = W_TECHWALL11__STATIC; + dynamictostatic[W_TECHWALL12] = W_TECHWALL12__STATIC; + dynamictostatic[W_TECHWALL13] = W_TECHWALL13__STATIC; + dynamictostatic[W_TECHWALL14] = W_TECHWALL14__STATIC; + dynamictostatic[W_TECHWALL5] = W_TECHWALL5__STATIC; + dynamictostatic[W_TECHWALL6] = W_TECHWALL6__STATIC; + dynamictostatic[W_TECHWALL7] = W_TECHWALL7__STATIC; + dynamictostatic[W_TECHWALL8] = W_TECHWALL8__STATIC; + dynamictostatic[W_TECHWALL9] = W_TECHWALL9__STATIC; + dynamictostatic[BPANNEL3] = BPANNEL3__STATIC; + dynamictostatic[W_HITTECHWALL16] = W_HITTECHWALL16__STATIC; + dynamictostatic[W_HITTECHWALL10] = W_HITTECHWALL10__STATIC; + dynamictostatic[W_HITTECHWALL15] = W_HITTECHWALL15__STATIC; + dynamictostatic[W_MILKSHELF] = W_MILKSHELF__STATIC; + dynamictostatic[W_MILKSHELFBROKE] = W_MILKSHELFBROKE__STATIC; + dynamictostatic[PURPLELAVA] = PURPLELAVA__STATIC; + dynamictostatic[LAVABUBBLE] = LAVABUBBLE__STATIC; + dynamictostatic[DUKECUTOUT] = DUKECUTOUT__STATIC; + dynamictostatic[TARGET] = TARGET__STATIC; + dynamictostatic[GUNPOWDERBARREL] = GUNPOWDERBARREL__STATIC; + dynamictostatic[DUCK] = DUCK__STATIC; + dynamictostatic[HATRACK] = HATRACK__STATIC; + dynamictostatic[DESKLAMP] = DESKLAMP__STATIC; + dynamictostatic[COFFEEMACHINE] = COFFEEMACHINE__STATIC; + dynamictostatic[CUPS] = CUPS__STATIC; + dynamictostatic[GAVALS] = GAVALS__STATIC; + dynamictostatic[GAVALS2] = GAVALS2__STATIC; + dynamictostatic[POLICELIGHTPOLE] = POLICELIGHTPOLE__STATIC; + dynamictostatic[FLOORBASKET] = FLOORBASKET__STATIC; + dynamictostatic[PUKE] = PUKE__STATIC; + dynamictostatic[DOORTILE23] = DOORTILE23__STATIC; + dynamictostatic[TOPSECRET] = TOPSECRET__STATIC; + dynamictostatic[SPEAKER] = SPEAKER__STATIC; + dynamictostatic[TEDDYBEAR] = TEDDYBEAR__STATIC; + dynamictostatic[ROBOTDOG] = ROBOTDOG__STATIC; + dynamictostatic[ROBOTPIRATE] = ROBOTPIRATE__STATIC; + dynamictostatic[ROBOTMOUSE] = ROBOTMOUSE__STATIC; + dynamictostatic[MAIL] = MAIL__STATIC; + dynamictostatic[MAILBAG] = MAILBAG__STATIC; + dynamictostatic[HOTMEAT] = HOTMEAT__STATIC; + dynamictostatic[COFFEEMUG] = COFFEEMUG__STATIC; + dynamictostatic[DONUTS2] = DONUTS2__STATIC; + dynamictostatic[TRIPODCAMERA] = TRIPODCAMERA__STATIC; + dynamictostatic[METER] = METER__STATIC; + dynamictostatic[DESKPHONE] = DESKPHONE__STATIC; + dynamictostatic[GUMBALLMACHINE] = GUMBALLMACHINE__STATIC; + dynamictostatic[GUMBALLMACHINEBROKE] = GUMBALLMACHINEBROKE__STATIC; + dynamictostatic[PAPER] = PAPER__STATIC; + dynamictostatic[MACE] = MACE__STATIC; + dynamictostatic[GENERICPOLE2] = GENERICPOLE2__STATIC; + dynamictostatic[XXXSTACY] = XXXSTACY__STATIC; + dynamictostatic[WETFLOOR] = WETFLOOR__STATIC; + dynamictostatic[BROOM] = BROOM__STATIC; + dynamictostatic[MOP] = MOP__STATIC; + dynamictostatic[LETTER] = LETTER__STATIC; + dynamictostatic[PIRATE1A] = PIRATE1A__STATIC; + dynamictostatic[PIRATE4A] = PIRATE4A__STATIC; + dynamictostatic[PIRATE2A] = PIRATE2A__STATIC; + dynamictostatic[PIRATE5A] = PIRATE5A__STATIC; + dynamictostatic[PIRATE3A] = PIRATE3A__STATIC; + dynamictostatic[PIRATE6A] = PIRATE6A__STATIC; + dynamictostatic[PIRATEHALF] = PIRATEHALF__STATIC; + dynamictostatic[CHESTOFGOLD] = CHESTOFGOLD__STATIC; + dynamictostatic[SIDEBOLT1] = SIDEBOLT1__STATIC; + dynamictostatic[FOODOBJECT1] = FOODOBJECT1__STATIC; + dynamictostatic[FOODOBJECT2] = FOODOBJECT2__STATIC; + dynamictostatic[FOODOBJECT3] = FOODOBJECT3__STATIC; + dynamictostatic[FOODOBJECT4] = FOODOBJECT4__STATIC; + dynamictostatic[FOODOBJECT5] = FOODOBJECT5__STATIC; + dynamictostatic[FOODOBJECT6] = FOODOBJECT6__STATIC; + dynamictostatic[FOODOBJECT7] = FOODOBJECT7__STATIC; + dynamictostatic[FOODOBJECT8] = FOODOBJECT8__STATIC; + dynamictostatic[FOODOBJECT9] = FOODOBJECT9__STATIC; + dynamictostatic[FOODOBJECT10] = FOODOBJECT10__STATIC; + dynamictostatic[FOODOBJECT11] = FOODOBJECT11__STATIC; + dynamictostatic[FOODOBJECT12] = FOODOBJECT12__STATIC; + dynamictostatic[FOODOBJECT13] = FOODOBJECT13__STATIC; + dynamictostatic[FOODOBJECT14] = FOODOBJECT14__STATIC; + dynamictostatic[FOODOBJECT15] = FOODOBJECT15__STATIC; + dynamictostatic[FOODOBJECT16] = FOODOBJECT16__STATIC; + dynamictostatic[FOODOBJECT17] = FOODOBJECT17__STATIC; + dynamictostatic[FOODOBJECT18] = FOODOBJECT18__STATIC; + dynamictostatic[FOODOBJECT19] = FOODOBJECT19__STATIC; + dynamictostatic[FOODOBJECT20] = FOODOBJECT20__STATIC; + dynamictostatic[HEADLAMP] = HEADLAMP__STATIC; + dynamictostatic[TAMPON] = TAMPON__STATIC; + dynamictostatic[SKINNEDCHICKEN] = SKINNEDCHICKEN__STATIC; + dynamictostatic[FEATHEREDCHICKEN] = FEATHEREDCHICKEN__STATIC; + dynamictostatic[ROBOTDOG2] = ROBOTDOG2__STATIC; + dynamictostatic[JOLLYMEAL] = JOLLYMEAL__STATIC; + dynamictostatic[DUKEBURGER] = DUKEBURGER__STATIC; + dynamictostatic[SHOPPINGCART] = SHOPPINGCART__STATIC; + dynamictostatic[CANWITHSOMETHING2] = CANWITHSOMETHING2__STATIC; + dynamictostatic[CANWITHSOMETHING3] = CANWITHSOMETHING3__STATIC; + dynamictostatic[CANWITHSOMETHING4] = CANWITHSOMETHING4__STATIC; + dynamictostatic[SNAKEP] = SNAKEP__STATIC; + dynamictostatic[DOLPHIN1] = DOLPHIN1__STATIC; + dynamictostatic[DOLPHIN2] = DOLPHIN2__STATIC; + dynamictostatic[NEWBEAST] = NEWBEAST__STATIC; + dynamictostatic[NEWBEASTSTAYPUT] = NEWBEASTSTAYPUT__STATIC; + dynamictostatic[NEWBEASTJUMP] = NEWBEASTJUMP__STATIC; + dynamictostatic[NEWBEASTHANG] = NEWBEASTHANG__STATIC; + dynamictostatic[NEWBEASTHANGDEAD] = NEWBEASTHANGDEAD__STATIC; + dynamictostatic[BOSS4] = BOSS4__STATIC; + dynamictostatic[BOSS4STAYPUT] = BOSS4STAYPUT__STATIC; + dynamictostatic[FEM10] = FEM10__STATIC; + dynamictostatic[TOUGHGAL] = TOUGHGAL__STATIC; + dynamictostatic[MAN] = MAN__STATIC; + dynamictostatic[MAN2] = MAN2__STATIC; + dynamictostatic[WOMAN] = WOMAN__STATIC; + dynamictostatic[PLEASEWAIT] = PLEASEWAIT__STATIC; + dynamictostatic[NATURALLIGHTNING] = NATURALLIGHTNING__STATIC; + dynamictostatic[WEATHERWARN] = WEATHERWARN__STATIC; + dynamictostatic[DUKETAG] = DUKETAG__STATIC; + dynamictostatic[SIGN1] = SIGN1__STATIC; + dynamictostatic[SIGN2] = SIGN2__STATIC; + dynamictostatic[JURYGUY] = JURYGUY__STATIC; + dynamictostatic[RESERVEDSLOT1] = RESERVEDSLOT1__STATIC; + dynamictostatic[RESERVEDSLOT2] = RESERVEDSLOT2__STATIC; + dynamictostatic[RESERVEDSLOT3] = RESERVEDSLOT3__STATIC; + dynamictostatic[RESERVEDSLOT4] = RESERVEDSLOT4__STATIC; + dynamictostatic[RESERVEDSLOT5] = RESERVEDSLOT5__STATIC; + dynamictostatic[RESERVEDSLOT6] = RESERVEDSLOT6__STATIC; + dynamictostatic[RESERVEDSLOT7] = RESERVEDSLOT7__STATIC; + dynamictostatic[RESERVEDSLOT8] = RESERVEDSLOT8__STATIC; + dynamictostatic[RESERVEDSLOT9] = RESERVEDSLOT9__STATIC; + dynamictostatic[RESERVEDSLOT10] = RESERVEDSLOT10__STATIC; + dynamictostatic[RESERVEDSLOT11] = RESERVEDSLOT11__STATIC; + dynamictostatic[RESERVEDSLOT12] = RESERVEDSLOT12__STATIC; + + weaponsandammosprites[0] = RPGSPRITE; + weaponsandammosprites[1] = CHAINGUNSPRITE; + weaponsandammosprites[2] = DEVISTATORAMMO; + weaponsandammosprites[3] = RPGAMMO; + weaponsandammosprites[4] = RPGAMMO; + weaponsandammosprites[5] = JETPACK; + weaponsandammosprites[6] = SHIELD; + weaponsandammosprites[7] = FIRSTAID; + weaponsandammosprites[8] = STEROIDS; + weaponsandammosprites[9] = RPGAMMO; + weaponsandammosprites[10] = RPGAMMO; + weaponsandammosprites[11] = RPGSPRITE; + weaponsandammosprites[12] = RPGAMMO; + weaponsandammosprites[13] = FREEZESPRITE; + weaponsandammosprites[14] = FREEZEAMMO; + + weapon_sprites[0] = KNEE; + weapon_sprites[1] = FIRSTGUNSPRITE; + weapon_sprites[2] = SHOTGUNSPRITE; + weapon_sprites[3] = CHAINGUNSPRITE; + weapon_sprites[4] = RPGSPRITE; + weapon_sprites[5] = HEAVYHBOMB; + weapon_sprites[6] = SHRINKERSPRITE; + weapon_sprites[7] = DEVISTATORSPRITE; + weapon_sprites[8] = TRIPBOMBSPRITE; + weapon_sprites[9] = FREEZESPRITE; + weapon_sprites[10] = HEAVYHBOMB; + weapon_sprites[11] = SHRINKERSPRITE; +} + +/* +void readnames() { + char buffer[1024], *p, *name, *number, *endptr; + int num, syms=0, line=0, a; + BFILE *fp; + + fp = fopenfrompath("NAMES.H","r"); + if (!fp) { + if ((fp = fopenfrompath("names.h","r")) == NULL) { + initprintf("Failed to open NAMES.H\n"); + return; + } + } + + //clearbufbyte(names, sizeof(names), 0); + //memset(names,0,sizeof(names)); + + initprintf("Loading NAMES.H\n"); + + while (Bfgets(buffer, 1024, fp)) { + a = Bstrlen(buffer); + if (a >= 1) { + if (a > 1) + if (buffer[a-2] == '\r') buffer[a-2] = 0; + if (buffer[a-1] == '\n') buffer[a-1] = 0; + } + + p = buffer; + line++; + while (*p == 32) p++; + if (*p == 0) continue; // blank line + + if (*p == '#') { + p++; + while (*p == 32) p++; + if (*p == 0) continue; // null directive + + else if (!Bstrncmp(p, "define ", 7)) { + // #define_... + p += 7; + while (*p == 32) p++; + if (*p == 0) { + initprintf("Error: Malformed #define at line %d\n", line-1); + continue; + } + + name = p; + while (*p != 32 && *p != 0) p++; + if (*p == 32) { + *(p++) = 0; + while (*p == 32) p++; + if (*p == 0) { // #define_NAME with no number + initprintf("Error: No number given for name \"%s\" (line %d)\n", name, line-1); + continue; + } + + number = p; + while (*p != 0) p++; + if (*p != 0) *p = 0; + + // add to list + num = Bstrtol(number, &endptr, 10); + if (*endptr != 0) { + p = endptr; + goto badline; + } + //initprintf("Grokked \"%s\" -> \"%d\"\n", name, num); + if (num < 0 || num >= MAXTILES) { + initprintf("Error: Constant %d for name \"%s\" out of range (line %d)\n", num, name, line-1); + continue; + } + processnames(name,num); + syms++; + + continue; + + } else { // #define_NAME with no number + initprintf("Error: No number given for name \"%s\" (line %d)\n", name, line-1); + continue; + } + } else goto badline; + } else if (*p == '/') { + if (*(p+1) == '/') continue; // comment + } +badline: + initprintf("Error: Invalid statement found at character %d on line %d\n", (p-buffer), line-1); + } + initprintf("Read %d lines, loaded %d names.\n", line, syms); + Bfclose(fp); +} +*/ diff --git a/polymer/eduke32/source/namesdyn.h b/polymer/eduke32/source/namesdyn.h new file mode 100644 index 000000000..793053e26 --- /dev/null +++ b/polymer/eduke32/source/namesdyn.h @@ -0,0 +1,1501 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +extern unsigned short SECTOREFFECTOR; +#define SECTOREFFECTOR__STATIC 1 +extern unsigned short ACTIVATOR; +#define ACTIVATOR__STATIC 2 +extern unsigned short TOUCHPLATE; +#define TOUCHPLATE__STATIC 3 +extern unsigned short ACTIVATORLOCKED; +#define ACTIVATORLOCKED__STATIC 4 +extern unsigned short MUSICANDSFX; +#define MUSICANDSFX__STATIC 5 +extern unsigned short LOCATORS; +#define LOCATORS__STATIC 6 +extern unsigned short CYCLER; +#define CYCLER__STATIC 7 +extern unsigned short MASTERSWITCH; +#define MASTERSWITCH__STATIC 8 +extern unsigned short RESPAWN; +#define RESPAWN__STATIC 9 +extern unsigned short GPSPEED; +#define GPSPEED__STATIC 10 +extern unsigned short FOF; +#define FOF__STATIC 13 +extern unsigned short ARROW; +#define ARROW__STATIC 20 +extern unsigned short FIRSTGUNSPRITE; +#define FIRSTGUNSPRITE__STATIC 21 +extern unsigned short CHAINGUNSPRITE; +#define CHAINGUNSPRITE__STATIC 22 +extern unsigned short RPGSPRITE; +#define RPGSPRITE__STATIC 23 +extern unsigned short FREEZESPRITE; +#define FREEZESPRITE__STATIC 24 +extern unsigned short SHRINKERSPRITE; +#define SHRINKERSPRITE__STATIC 25 +extern unsigned short HEAVYHBOMB; +#define HEAVYHBOMB__STATIC 26 +extern unsigned short TRIPBOMBSPRITE; +#define TRIPBOMBSPRITE__STATIC 27 +extern unsigned short SHOTGUNSPRITE; +#define SHOTGUNSPRITE__STATIC 28 +extern unsigned short DEVISTATORSPRITE; +#define DEVISTATORSPRITE__STATIC 29 +extern unsigned short HEALTHBOX; +#define HEALTHBOX__STATIC 30 +extern unsigned short AMMOBOX; +#define AMMOBOX__STATIC 31 +extern unsigned short GROWSPRITEICON; +#define GROWSPRITEICON__STATIC 32 +extern unsigned short INVENTORYBOX; +#define INVENTORYBOX__STATIC 33 +extern unsigned short FREEZEAMMO; +#define FREEZEAMMO__STATIC 37 +extern unsigned short AMMO; +#define AMMO__STATIC 40 +extern unsigned short BATTERYAMMO; +#define BATTERYAMMO__STATIC 41 +extern unsigned short DEVISTATORAMMO; +#define DEVISTATORAMMO__STATIC 42 +extern unsigned short RPGAMMO; +#define RPGAMMO__STATIC 44 +extern unsigned short GROWAMMO; +#define GROWAMMO__STATIC 45 +extern unsigned short CRYSTALAMMO; +#define CRYSTALAMMO__STATIC 46 +extern unsigned short HBOMBAMMO; +#define HBOMBAMMO__STATIC 47 +extern unsigned short AMMOLOTS; +#define AMMOLOTS__STATIC 48 +extern unsigned short SHOTGUNAMMO; +#define SHOTGUNAMMO__STATIC 49 +extern unsigned short COLA; +#define COLA__STATIC 51 +extern unsigned short SIXPAK; +#define SIXPAK__STATIC 52 +extern unsigned short FIRSTAID; +#define FIRSTAID__STATIC 53 +extern unsigned short SHIELD; +#define SHIELD__STATIC 54 +extern unsigned short STEROIDS; +#define STEROIDS__STATIC 55 +extern unsigned short AIRTANK; +#define AIRTANK__STATIC 56 +extern unsigned short JETPACK; +#define JETPACK__STATIC 57 +extern unsigned short HEATSENSOR; +#define HEATSENSOR__STATIC 59 +extern unsigned short ACCESSCARD; +#define ACCESSCARD__STATIC 60 +extern unsigned short BOOTS; +#define BOOTS__STATIC 61 +extern unsigned short MIRRORBROKE; +#define MIRRORBROKE__STATIC 70 +extern unsigned short CLOUDYOCEAN; +#define CLOUDYOCEAN__STATIC 78 +extern unsigned short CLOUDYSKIES; +#define CLOUDYSKIES__STATIC 79 +extern unsigned short MOONSKY1; +#define MOONSKY1__STATIC 80 +extern unsigned short MOONSKY2; +#define MOONSKY2__STATIC 81 +extern unsigned short MOONSKY3; +#define MOONSKY3__STATIC 82 +extern unsigned short MOONSKY4; +#define MOONSKY4__STATIC 83 +extern unsigned short BIGORBIT1; +#define BIGORBIT1__STATIC 84 +extern unsigned short BIGORBIT2; +#define BIGORBIT2__STATIC 85 +extern unsigned short BIGORBIT3; +#define BIGORBIT3__STATIC 86 +extern unsigned short BIGORBIT4; +#define BIGORBIT4__STATIC 87 +extern unsigned short BIGORBIT5; +#define BIGORBIT5__STATIC 88 +extern unsigned short LA; +#define LA__STATIC 89 +extern unsigned short REDSKY1; +#define REDSKY1__STATIC 98 +extern unsigned short REDSKY2; +#define REDSKY2__STATIC 99 +extern unsigned short ATOMICHEALTH; +#define ATOMICHEALTH__STATIC 100 +extern unsigned short TECHLIGHT2; +#define TECHLIGHT2__STATIC 120 +extern unsigned short TECHLIGHTBUST2; +#define TECHLIGHTBUST2__STATIC 121 +extern unsigned short TECHLIGHT4; +#define TECHLIGHT4__STATIC 122 +extern unsigned short TECHLIGHTBUST4; +#define TECHLIGHTBUST4__STATIC 123 +extern unsigned short WALLLIGHT4; +#define WALLLIGHT4__STATIC 124 +extern unsigned short WALLLIGHTBUST4; +#define WALLLIGHTBUST4__STATIC 125 +extern unsigned short ACCESSSWITCH; +#define ACCESSSWITCH__STATIC 130 +extern unsigned short SLOTDOOR; +#define SLOTDOOR__STATIC 132 +extern unsigned short LIGHTSWITCH; +#define LIGHTSWITCH__STATIC 134 +extern unsigned short SPACEDOORSWITCH; +#define SPACEDOORSWITCH__STATIC 136 +extern unsigned short SPACELIGHTSWITCH; +#define SPACELIGHTSWITCH__STATIC 138 +extern unsigned short FRANKENSTINESWITCH; +#define FRANKENSTINESWITCH__STATIC 140 +extern unsigned short NUKEBUTTON; +#define NUKEBUTTON__STATIC 142 +extern unsigned short MULTISWITCH; +#define MULTISWITCH__STATIC 146 +extern unsigned short DOORTILE5; +#define DOORTILE5__STATIC 150 +extern unsigned short DOORTILE6; +#define DOORTILE6__STATIC 151 +extern unsigned short DOORTILE1; +#define DOORTILE1__STATIC 152 +extern unsigned short DOORTILE2; +#define DOORTILE2__STATIC 153 +extern unsigned short DOORTILE3; +#define DOORTILE3__STATIC 154 +extern unsigned short DOORTILE4; +#define DOORTILE4__STATIC 155 +extern unsigned short DOORTILE7; +#define DOORTILE7__STATIC 156 +extern unsigned short DOORTILE8; +#define DOORTILE8__STATIC 157 +extern unsigned short DOORTILE9; +#define DOORTILE9__STATIC 158 +extern unsigned short DOORTILE10; +#define DOORTILE10__STATIC 159 +extern unsigned short DOORSHOCK; +#define DOORSHOCK__STATIC 160 +extern unsigned short DIPSWITCH; +#define DIPSWITCH__STATIC 162 +extern unsigned short DIPSWITCH2; +#define DIPSWITCH2__STATIC 164 +extern unsigned short TECHSWITCH; +#define TECHSWITCH__STATIC 166 +extern unsigned short DIPSWITCH3; +#define DIPSWITCH3__STATIC 168 +extern unsigned short ACCESSSWITCH2; +#define ACCESSSWITCH2__STATIC 170 +extern unsigned short REFLECTWATERTILE; +#define REFLECTWATERTILE__STATIC 180 +extern unsigned short FLOORSLIME; +#define FLOORSLIME__STATIC 200 +extern unsigned short BIGFORCE; +#define BIGFORCE__STATIC 230 +extern unsigned short EPISODE; +#define EPISODE__STATIC 247 +extern unsigned short MASKWALL9; +#define MASKWALL9__STATIC 255 +extern unsigned short W_LIGHT; +#define W_LIGHT__STATIC 260 +extern unsigned short SCREENBREAK1; +#define SCREENBREAK1__STATIC 263 +extern unsigned short SCREENBREAK2; +#define SCREENBREAK2__STATIC 264 +extern unsigned short SCREENBREAK3; +#define SCREENBREAK3__STATIC 265 +extern unsigned short SCREENBREAK4; +#define SCREENBREAK4__STATIC 266 +extern unsigned short SCREENBREAK5; +#define SCREENBREAK5__STATIC 267 +extern unsigned short SCREENBREAK6; +#define SCREENBREAK6__STATIC 268 +extern unsigned short SCREENBREAK7; +#define SCREENBREAK7__STATIC 269 +extern unsigned short SCREENBREAK8; +#define SCREENBREAK8__STATIC 270 +extern unsigned short SCREENBREAK9; +#define SCREENBREAK9__STATIC 271 +extern unsigned short SCREENBREAK10; +#define SCREENBREAK10__STATIC 272 +extern unsigned short SCREENBREAK11; +#define SCREENBREAK11__STATIC 273 +extern unsigned short SCREENBREAK12; +#define SCREENBREAK12__STATIC 274 +extern unsigned short SCREENBREAK13; +#define SCREENBREAK13__STATIC 275 +extern unsigned short MASKWALL1; +#define MASKWALL1__STATIC 285 +extern unsigned short W_TECHWALL1; +#define W_TECHWALL1__STATIC 293 +extern unsigned short W_TECHWALL2; +#define W_TECHWALL2__STATIC 297 +extern unsigned short W_TECHWALL15; +#define W_TECHWALL15__STATIC 299 +extern unsigned short W_TECHWALL3; +#define W_TECHWALL3__STATIC 301 +extern unsigned short W_TECHWALL4; +#define W_TECHWALL4__STATIC 305 +extern unsigned short W_TECHWALL10; +#define W_TECHWALL10__STATIC 306 +extern unsigned short W_TECHWALL16; +#define W_TECHWALL16__STATIC 307 +extern unsigned short WATERTILE2; +#define WATERTILE2__STATIC 336 +extern unsigned short BPANNEL1; +#define BPANNEL1__STATIC 341 +extern unsigned short PANNEL1; +#define PANNEL1__STATIC 342 +extern unsigned short PANNEL2; +#define PANNEL2__STATIC 343 +extern unsigned short WATERTILE; +#define WATERTILE__STATIC 344 +extern unsigned short STATIC; +#define STATIC__STATIC 351 +extern unsigned short W_SCREENBREAK; +#define W_SCREENBREAK__STATIC 357 +extern unsigned short W_HITTECHWALL3; +#define W_HITTECHWALL3__STATIC 360 +extern unsigned short W_HITTECHWALL4; +#define W_HITTECHWALL4__STATIC 361 +extern unsigned short W_HITTECHWALL2; +#define W_HITTECHWALL2__STATIC 362 +extern unsigned short W_HITTECHWALL1; +#define W_HITTECHWALL1__STATIC 363 +extern unsigned short MASKWALL10; +#define MASKWALL10__STATIC 387 +extern unsigned short MASKWALL11; +#define MASKWALL11__STATIC 391 +extern unsigned short DOORTILE22; +#define DOORTILE22__STATIC 395 +extern unsigned short FANSPRITE; +#define FANSPRITE__STATIC 407 +extern unsigned short FANSPRITEBROKE; +#define FANSPRITEBROKE__STATIC 411 +extern unsigned short FANSHADOW; +#define FANSHADOW__STATIC 412 +extern unsigned short FANSHADOWBROKE; +#define FANSHADOWBROKE__STATIC 416 +extern unsigned short DOORTILE18; +#define DOORTILE18__STATIC 447 +extern unsigned short DOORTILE19; +#define DOORTILE19__STATIC 448 +extern unsigned short DOORTILE20; +#define DOORTILE20__STATIC 449 +extern unsigned short SATELLITE; +#define SATELLITE__STATIC 489 +extern unsigned short VIEWSCREEN2; +#define VIEWSCREEN2__STATIC 499 +extern unsigned short VIEWSCREENBROKE; +#define VIEWSCREENBROKE__STATIC 501 +extern unsigned short VIEWSCREEN; +#define VIEWSCREEN__STATIC 502 +extern unsigned short GLASS; +#define GLASS__STATIC 503 +extern unsigned short GLASS2; +#define GLASS2__STATIC 504 +extern unsigned short STAINGLASS1; +#define STAINGLASS1__STATIC 510 +extern unsigned short MASKWALL5; +#define MASKWALL5__STATIC 514 +extern unsigned short SATELITE; +#define SATELITE__STATIC 516 +extern unsigned short FUELPOD; +#define FUELPOD__STATIC 517 +extern unsigned short SLIMEPIPE; +#define SLIMEPIPE__STATIC 538 +extern unsigned short CRACK1; +#define CRACK1__STATIC 546 +extern unsigned short CRACK2; +#define CRACK2__STATIC 547 +extern unsigned short CRACK3; +#define CRACK3__STATIC 548 +extern unsigned short CRACK4; +#define CRACK4__STATIC 549 +extern unsigned short FOOTPRINTS; +#define FOOTPRINTS__STATIC 550 +extern unsigned short DOMELITE; +#define DOMELITE__STATIC 551 +extern unsigned short CAMERAPOLE; +#define CAMERAPOLE__STATIC 554 +extern unsigned short CHAIR1; +#define CHAIR1__STATIC 556 +extern unsigned short CHAIR2; +#define CHAIR2__STATIC 557 +extern unsigned short BROKENCHAIR; +#define BROKENCHAIR__STATIC 559 +extern unsigned short MIRROR; +#define MIRROR__STATIC 560 +extern unsigned short WATERFOUNTAIN; +#define WATERFOUNTAIN__STATIC 563 +extern unsigned short WATERFOUNTAINBROKE; +#define WATERFOUNTAINBROKE__STATIC 567 +extern unsigned short FEMMAG1; +#define FEMMAG1__STATIC 568 +extern unsigned short TOILET; +#define TOILET__STATIC 569 +extern unsigned short STALL; +#define STALL__STATIC 571 +extern unsigned short STALLBROKE; +#define STALLBROKE__STATIC 573 +extern unsigned short FEMMAG2; +#define FEMMAG2__STATIC 577 +extern unsigned short REACTOR2; +#define REACTOR2__STATIC 578 +extern unsigned short REACTOR2BURNT; +#define REACTOR2BURNT__STATIC 579 +extern unsigned short REACTOR2SPARK; +#define REACTOR2SPARK__STATIC 580 +extern unsigned short GRATE1; +#define GRATE1__STATIC 595 +extern unsigned short BGRATE1; +#define BGRATE1__STATIC 596 +extern unsigned short SOLARPANNEL; +#define SOLARPANNEL__STATIC 602 +extern unsigned short NAKED1; +#define NAKED1__STATIC 603 +extern unsigned short ANTENNA; +#define ANTENNA__STATIC 607 +extern unsigned short MASKWALL12; +#define MASKWALL12__STATIC 609 +extern unsigned short TOILETBROKE; +#define TOILETBROKE__STATIC 615 +extern unsigned short PIPE2; +#define PIPE2__STATIC 616 +extern unsigned short PIPE1B; +#define PIPE1B__STATIC 617 +extern unsigned short PIPE3; +#define PIPE3__STATIC 618 +extern unsigned short PIPE1; +#define PIPE1__STATIC 619 +extern unsigned short CAMERA1; +#define CAMERA1__STATIC 621 +extern unsigned short BRICK; +#define BRICK__STATIC 626 +extern unsigned short SPLINTERWOOD; +#define SPLINTERWOOD__STATIC 630 +extern unsigned short PIPE2B; +#define PIPE2B__STATIC 633 +extern unsigned short BOLT1; +#define BOLT1__STATIC 634 +extern unsigned short W_NUMBERS; +#define W_NUMBERS__STATIC 640 +extern unsigned short WATERDRIP; +#define WATERDRIP__STATIC 660 +extern unsigned short WATERBUBBLE; +#define WATERBUBBLE__STATIC 661 +extern unsigned short WATERBUBBLEMAKER; +#define WATERBUBBLEMAKER__STATIC 662 +extern unsigned short W_FORCEFIELD; +#define W_FORCEFIELD__STATIC 663 +extern unsigned short VACUUM; +#define VACUUM__STATIC 669 +extern unsigned short FOOTPRINTS2; +#define FOOTPRINTS2__STATIC 672 +extern unsigned short FOOTPRINTS3; +#define FOOTPRINTS3__STATIC 673 +extern unsigned short FOOTPRINTS4; +#define FOOTPRINTS4__STATIC 674 +extern unsigned short EGG; +#define EGG__STATIC 675 +extern unsigned short SCALE; +#define SCALE__STATIC 678 +extern unsigned short CHAIR3; +#define CHAIR3__STATIC 680 +extern unsigned short CAMERALIGHT; +#define CAMERALIGHT__STATIC 685 +extern unsigned short MOVIECAMERA; +#define MOVIECAMERA__STATIC 686 +extern unsigned short IVUNIT; +#define IVUNIT__STATIC 689 +extern unsigned short POT1; +#define POT1__STATIC 694 +extern unsigned short POT2; +#define POT2__STATIC 695 +extern unsigned short POT3; +#define POT3__STATIC 697 +extern unsigned short PIPE3B; +#define PIPE3B__STATIC 700 +extern unsigned short WALLLIGHT3; +#define WALLLIGHT3__STATIC 701 +extern unsigned short WALLLIGHTBUST3; +#define WALLLIGHTBUST3__STATIC 702 +extern unsigned short WALLLIGHT1; +#define WALLLIGHT1__STATIC 703 +extern unsigned short WALLLIGHTBUST1; +#define WALLLIGHTBUST1__STATIC 704 +extern unsigned short WALLLIGHT2; +#define WALLLIGHT2__STATIC 705 +extern unsigned short WALLLIGHTBUST2; +#define WALLLIGHTBUST2__STATIC 706 +extern unsigned short LIGHTSWITCH2; +#define LIGHTSWITCH2__STATIC 712 +extern unsigned short WAITTOBESEATED; +#define WAITTOBESEATED__STATIC 716 +extern unsigned short DOORTILE14; +#define DOORTILE14__STATIC 717 +extern unsigned short STATUE; +#define STATUE__STATIC 753 +extern unsigned short MIKE; +#define MIKE__STATIC 762 +extern unsigned short VASE; +#define VASE__STATIC 765 +extern unsigned short SUSHIPLATE1; +#define SUSHIPLATE1__STATIC 768 +extern unsigned short SUSHIPLATE2; +#define SUSHIPLATE2__STATIC 769 +extern unsigned short SUSHIPLATE3; +#define SUSHIPLATE3__STATIC 774 +extern unsigned short SUSHIPLATE4; +#define SUSHIPLATE4__STATIC 779 +extern unsigned short DOORTILE16; +#define DOORTILE16__STATIC 781 +extern unsigned short SUSHIPLATE5; +#define SUSHIPLATE5__STATIC 792 +extern unsigned short OJ; +#define OJ__STATIC 806 +extern unsigned short MASKWALL13; +#define MASKWALL13__STATIC 830 +extern unsigned short HURTRAIL; +#define HURTRAIL__STATIC 859 +extern unsigned short POWERSWITCH1; +#define POWERSWITCH1__STATIC 860 +extern unsigned short LOCKSWITCH1; +#define LOCKSWITCH1__STATIC 862 +extern unsigned short POWERSWITCH2; +#define POWERSWITCH2__STATIC 864 +extern unsigned short ATM; +#define ATM__STATIC 867 +extern unsigned short STATUEFLASH; +#define STATUEFLASH__STATIC 869 +extern unsigned short ATMBROKE; +#define ATMBROKE__STATIC 888 +extern unsigned short BIGHOLE2; +#define BIGHOLE2__STATIC 893 +extern unsigned short STRIPEBALL; +#define STRIPEBALL__STATIC 901 +extern unsigned short QUEBALL; +#define QUEBALL__STATIC 902 +extern unsigned short POCKET; +#define POCKET__STATIC 903 +extern unsigned short WOODENHORSE; +#define WOODENHORSE__STATIC 904 +extern unsigned short TREE1; +#define TREE1__STATIC 908 +extern unsigned short TREE2; +#define TREE2__STATIC 910 +extern unsigned short CACTUS; +#define CACTUS__STATIC 911 +extern unsigned short MASKWALL2; +#define MASKWALL2__STATIC 913 +extern unsigned short MASKWALL3; +#define MASKWALL3__STATIC 914 +extern unsigned short MASKWALL4; +#define MASKWALL4__STATIC 915 +extern unsigned short FIREEXT; +#define FIREEXT__STATIC 916 +extern unsigned short TOILETWATER; +#define TOILETWATER__STATIC 921 +extern unsigned short NEON1; +#define NEON1__STATIC 925 +extern unsigned short NEON2; +#define NEON2__STATIC 926 +extern unsigned short CACTUSBROKE; +#define CACTUSBROKE__STATIC 939 +extern unsigned short BOUNCEMINE; +#define BOUNCEMINE__STATIC 940 +extern unsigned short BROKEFIREHYDRENT; +#define BROKEFIREHYDRENT__STATIC 950 +extern unsigned short BOX; +#define BOX__STATIC 951 +extern unsigned short BULLETHOLE; +#define BULLETHOLE__STATIC 952 +extern unsigned short BOTTLE1; +#define BOTTLE1__STATIC 954 +extern unsigned short BOTTLE2; +#define BOTTLE2__STATIC 955 +extern unsigned short BOTTLE3; +#define BOTTLE3__STATIC 956 +extern unsigned short BOTTLE4; +#define BOTTLE4__STATIC 957 +extern unsigned short FEMPIC5; +#define FEMPIC5__STATIC 963 +extern unsigned short FEMPIC6; +#define FEMPIC6__STATIC 964 +extern unsigned short FEMPIC7; +#define FEMPIC7__STATIC 965 +extern unsigned short HYDROPLANT; +#define HYDROPLANT__STATIC 969 +extern unsigned short OCEANSPRITE1; +#define OCEANSPRITE1__STATIC 971 +extern unsigned short OCEANSPRITE2; +#define OCEANSPRITE2__STATIC 972 +extern unsigned short OCEANSPRITE3; +#define OCEANSPRITE3__STATIC 973 +extern unsigned short OCEANSPRITE4; +#define OCEANSPRITE4__STATIC 974 +extern unsigned short OCEANSPRITE5; +#define OCEANSPRITE5__STATIC 975 +extern unsigned short GENERICPOLE; +#define GENERICPOLE__STATIC 977 +extern unsigned short CONE; +#define CONE__STATIC 978 +extern unsigned short HANGLIGHT; +#define HANGLIGHT__STATIC 979 +extern unsigned short HYDRENT; +#define HYDRENT__STATIC 981 +extern unsigned short MASKWALL14; +#define MASKWALL14__STATIC 988 +extern unsigned short TIRE; +#define TIRE__STATIC 990 +extern unsigned short PIPE5; +#define PIPE5__STATIC 994 +extern unsigned short PIPE6; +#define PIPE6__STATIC 995 +extern unsigned short PIPE4; +#define PIPE4__STATIC 996 +extern unsigned short PIPE4B; +#define PIPE4B__STATIC 997 +extern unsigned short BROKEHYDROPLANT; +#define BROKEHYDROPLANT__STATIC 1003 +extern unsigned short PIPE5B; +#define PIPE5B__STATIC 1005 +extern unsigned short NEON3; +#define NEON3__STATIC 1007 +extern unsigned short NEON4; +#define NEON4__STATIC 1008 +extern unsigned short NEON5; +#define NEON5__STATIC 1009 +extern unsigned short BOTTLE5; +#define BOTTLE5__STATIC 1012 +extern unsigned short BOTTLE6; +#define BOTTLE6__STATIC 1013 +extern unsigned short BOTTLE8; +#define BOTTLE8__STATIC 1014 +extern unsigned short SPOTLITE; +#define SPOTLITE__STATIC 1020 +extern unsigned short HANGOOZ; +#define HANGOOZ__STATIC 1022 +extern unsigned short MASKWALL15; +#define MASKWALL15__STATIC 1024 +extern unsigned short BOTTLE7; +#define BOTTLE7__STATIC 1025 +extern unsigned short HORSEONSIDE; +#define HORSEONSIDE__STATIC 1026 +extern unsigned short GLASSPIECES; +#define GLASSPIECES__STATIC 1031 +extern unsigned short HORSELITE; +#define HORSELITE__STATIC 1034 +extern unsigned short DONUTS; +#define DONUTS__STATIC 1045 +extern unsigned short NEON6; +#define NEON6__STATIC 1046 +extern unsigned short MASKWALL6; +#define MASKWALL6__STATIC 1059 +extern unsigned short CLOCK; +#define CLOCK__STATIC 1060 +extern unsigned short RUBBERCAN; +#define RUBBERCAN__STATIC 1062 +extern unsigned short BROKENCLOCK; +#define BROKENCLOCK__STATIC 1067 +extern unsigned short PLUG; +#define PLUG__STATIC 1069 +extern unsigned short OOZFILTER; +#define OOZFILTER__STATIC 1079 +extern unsigned short FLOORPLASMA; +#define FLOORPLASMA__STATIC 1082 +extern unsigned short REACTOR; +#define REACTOR__STATIC 1088 +extern unsigned short REACTORSPARK; +#define REACTORSPARK__STATIC 1092 +extern unsigned short REACTORBURNT; +#define REACTORBURNT__STATIC 1096 +extern unsigned short DOORTILE15; +#define DOORTILE15__STATIC 1102 +extern unsigned short HANDSWITCH; +#define HANDSWITCH__STATIC 1111 +extern unsigned short CIRCLEPANNEL; +#define CIRCLEPANNEL__STATIC 1113 +extern unsigned short CIRCLEPANNELBROKE; +#define CIRCLEPANNELBROKE__STATIC 1114 +extern unsigned short PULLSWITCH; +#define PULLSWITCH__STATIC 1122 +extern unsigned short MASKWALL8; +#define MASKWALL8__STATIC 1124 +extern unsigned short BIGHOLE; +#define BIGHOLE__STATIC 1141 +extern unsigned short ALIENSWITCH; +#define ALIENSWITCH__STATIC 1142 +extern unsigned short DOORTILE21; +#define DOORTILE21__STATIC 1144 +extern unsigned short HANDPRINTSWITCH; +#define HANDPRINTSWITCH__STATIC 1155 +extern unsigned short BOTTLE10; +#define BOTTLE10__STATIC 1157 +extern unsigned short BOTTLE11; +#define BOTTLE11__STATIC 1158 +extern unsigned short BOTTLE12; +#define BOTTLE12__STATIC 1159 +extern unsigned short BOTTLE13; +#define BOTTLE13__STATIC 1160 +extern unsigned short BOTTLE14; +#define BOTTLE14__STATIC 1161 +extern unsigned short BOTTLE15; +#define BOTTLE15__STATIC 1162 +extern unsigned short BOTTLE16; +#define BOTTLE16__STATIC 1163 +extern unsigned short BOTTLE17; +#define BOTTLE17__STATIC 1164 +extern unsigned short BOTTLE18; +#define BOTTLE18__STATIC 1165 +extern unsigned short BOTTLE19; +#define BOTTLE19__STATIC 1166 +extern unsigned short DOORTILE17; +#define DOORTILE17__STATIC 1169 +extern unsigned short MASKWALL7; +#define MASKWALL7__STATIC 1174 +extern unsigned short JAILBARBREAK; +#define JAILBARBREAK__STATIC 1175 +extern unsigned short DOORTILE11; +#define DOORTILE11__STATIC 1178 +extern unsigned short DOORTILE12; +#define DOORTILE12__STATIC 1179 +extern unsigned short VENDMACHINE; +#define VENDMACHINE__STATIC 1212 +extern unsigned short VENDMACHINEBROKE; +#define VENDMACHINEBROKE__STATIC 1214 +extern unsigned short COLAMACHINE; +#define COLAMACHINE__STATIC 1215 +extern unsigned short COLAMACHINEBROKE; +#define COLAMACHINEBROKE__STATIC 1217 +extern unsigned short CRANEPOLE; +#define CRANEPOLE__STATIC 1221 +extern unsigned short CRANE; +#define CRANE__STATIC 1222 +extern unsigned short BARBROKE; +#define BARBROKE__STATIC 1225 +extern unsigned short BLOODPOOL; +#define BLOODPOOL__STATIC 1226 +extern unsigned short NUKEBARREL; +#define NUKEBARREL__STATIC 1227 +extern unsigned short NUKEBARRELDENTED; +#define NUKEBARRELDENTED__STATIC 1228 +extern unsigned short NUKEBARRELLEAKED; +#define NUKEBARRELLEAKED__STATIC 1229 +extern unsigned short CANWITHSOMETHING; +#define CANWITHSOMETHING__STATIC 1232 +extern unsigned short MONEY; +#define MONEY__STATIC 1233 +extern unsigned short BANNER; +#define BANNER__STATIC 1236 +extern unsigned short EXPLODINGBARREL; +#define EXPLODINGBARREL__STATIC 1238 +extern unsigned short EXPLODINGBARREL2; +#define EXPLODINGBARREL2__STATIC 1239 +extern unsigned short FIREBARREL; +#define FIREBARREL__STATIC 1240 +extern unsigned short SEENINE; +#define SEENINE__STATIC 1247 +extern unsigned short SEENINEDEAD; +#define SEENINEDEAD__STATIC 1248 +extern unsigned short STEAM; +#define STEAM__STATIC 1250 +extern unsigned short CEILINGSTEAM; +#define CEILINGSTEAM__STATIC 1255 +extern unsigned short PIPE6B; +#define PIPE6B__STATIC 1260 +extern unsigned short TRANSPORTERBEAM; +#define TRANSPORTERBEAM__STATIC 1261 +extern unsigned short RAT; +#define RAT__STATIC 1267 +extern unsigned short TRASH; +#define TRASH__STATIC 1272 +extern unsigned short FEMPIC1; +#define FEMPIC1__STATIC 1280 +extern unsigned short FEMPIC2; +#define FEMPIC2__STATIC 1289 +extern unsigned short BLANKSCREEN; +#define BLANKSCREEN__STATIC 1293 +extern unsigned short PODFEM1; +#define PODFEM1__STATIC 1294 +extern unsigned short FEMPIC3; +#define FEMPIC3__STATIC 1298 +extern unsigned short FEMPIC4; +#define FEMPIC4__STATIC 1306 +extern unsigned short FEM1; +#define FEM1__STATIC 1312 +extern unsigned short FEM2; +#define FEM2__STATIC 1317 +extern unsigned short FEM3; +#define FEM3__STATIC 1321 +extern unsigned short FEM5; +#define FEM5__STATIC 1323 +extern unsigned short BLOODYPOLE; +#define BLOODYPOLE__STATIC 1324 +extern unsigned short FEM4; +#define FEM4__STATIC 1325 +extern unsigned short FEM6; +#define FEM6__STATIC 1334 +extern unsigned short FEM6PAD; +#define FEM6PAD__STATIC 1335 +extern unsigned short FEM8; +#define FEM8__STATIC 1336 +extern unsigned short HELECOPT; +#define HELECOPT__STATIC 1346 +extern unsigned short FETUSJIB; +#define FETUSJIB__STATIC 1347 +extern unsigned short HOLODUKE; +#define HOLODUKE__STATIC 1348 +extern unsigned short SPACEMARINE; +#define SPACEMARINE__STATIC 1353 +extern unsigned short INDY; +#define INDY__STATIC 1355 +extern unsigned short FETUS; +#define FETUS__STATIC 1358 +extern unsigned short FETUSBROKE; +#define FETUSBROKE__STATIC 1359 +extern unsigned short MONK; +#define MONK__STATIC 1352 +extern unsigned short LUKE; +#define LUKE__STATIC 1354 +extern unsigned short COOLEXPLOSION1; +#define COOLEXPLOSION1__STATIC 1360 +extern unsigned short WATERSPLASH2; +#define WATERSPLASH2__STATIC 1380 +extern unsigned short FIREVASE; +#define FIREVASE__STATIC 1390 +extern unsigned short SCRATCH; +#define SCRATCH__STATIC 1393 +extern unsigned short FEM7; +#define FEM7__STATIC 1395 +extern unsigned short APLAYERTOP; +#define APLAYERTOP__STATIC 1400 +extern unsigned short APLAYER; +#define APLAYER__STATIC 1405 +extern unsigned short PLAYERONWATER; +#define PLAYERONWATER__STATIC 1420 +extern unsigned short DUKELYINGDEAD; +#define DUKELYINGDEAD__STATIC 1518 +extern unsigned short DUKETORSO; +#define DUKETORSO__STATIC 1520 +extern unsigned short DUKEGUN; +#define DUKEGUN__STATIC 1528 +extern unsigned short DUKELEG; +#define DUKELEG__STATIC 1536 +extern unsigned short SHARK; +#define SHARK__STATIC 1550 +extern unsigned short BLOOD; +#define BLOOD__STATIC 1620 +extern unsigned short FIRELASER; +#define FIRELASER__STATIC 1625 +extern unsigned short TRANSPORTERSTAR; +#define TRANSPORTERSTAR__STATIC 1630 +extern unsigned short SPIT; +#define SPIT__STATIC 1636 +extern unsigned short LOOGIE; +#define LOOGIE__STATIC 1637 +extern unsigned short FIST; +#define FIST__STATIC 1640 +extern unsigned short FREEZEBLAST; +#define FREEZEBLAST__STATIC 1641 +extern unsigned short DEVISTATORBLAST; +#define DEVISTATORBLAST__STATIC 1642 +extern unsigned short SHRINKSPARK; +#define SHRINKSPARK__STATIC 1646 +extern unsigned short TONGUE; +#define TONGUE__STATIC 1647 +extern unsigned short MORTER; +#define MORTER__STATIC 1650 +extern unsigned short SHRINKEREXPLOSION; +#define SHRINKEREXPLOSION__STATIC 1656 +extern unsigned short RADIUSEXPLOSION; +#define RADIUSEXPLOSION__STATIC 1670 +extern unsigned short FORCERIPPLE; +#define FORCERIPPLE__STATIC 1671 +extern unsigned short LIZTROOP; +#define LIZTROOP__STATIC 1680 +extern unsigned short LIZTROOPRUNNING; +#define LIZTROOPRUNNING__STATIC 1681 +extern unsigned short LIZTROOPSTAYPUT; +#define LIZTROOPSTAYPUT__STATIC 1682 +extern unsigned short LIZTOP; +#define LIZTOP__STATIC 1705 +extern unsigned short LIZTROOPSHOOT; +#define LIZTROOPSHOOT__STATIC 1715 +extern unsigned short LIZTROOPJETPACK; +#define LIZTROOPJETPACK__STATIC 1725 +extern unsigned short LIZTROOPDSPRITE; +#define LIZTROOPDSPRITE__STATIC 1734 +extern unsigned short LIZTROOPONTOILET; +#define LIZTROOPONTOILET__STATIC 1741 +extern unsigned short LIZTROOPJUSTSIT; +#define LIZTROOPJUSTSIT__STATIC 1742 +extern unsigned short LIZTROOPDUCKING; +#define LIZTROOPDUCKING__STATIC 1744 +extern unsigned short HEADJIB1; +#define HEADJIB1__STATIC 1768 +extern unsigned short ARMJIB1; +#define ARMJIB1__STATIC 1772 +extern unsigned short LEGJIB1; +#define LEGJIB1__STATIC 1776 +extern unsigned short CANNONBALL; +#define CANNONBALL__STATIC 1817 +extern unsigned short OCTABRAIN; +#define OCTABRAIN__STATIC 1820 +extern unsigned short OCTABRAINSTAYPUT; +#define OCTABRAINSTAYPUT__STATIC 1821 +extern unsigned short OCTATOP; +#define OCTATOP__STATIC 1845 +extern unsigned short OCTADEADSPRITE; +#define OCTADEADSPRITE__STATIC 1855 +extern unsigned short INNERJAW; +#define INNERJAW__STATIC 1860 +extern unsigned short DRONE; +#define DRONE__STATIC 1880 +extern unsigned short EXPLOSION2; +#define EXPLOSION2__STATIC 1890 +extern unsigned short COMMANDER; +#define COMMANDER__STATIC 1920 +extern unsigned short COMMANDERSTAYPUT; +#define COMMANDERSTAYPUT__STATIC 1921 +extern unsigned short RECON; +#define RECON__STATIC 1960 +extern unsigned short TANK; +#define TANK__STATIC 1975 +extern unsigned short PIGCOP; +#define PIGCOP__STATIC 2000 +extern unsigned short PIGCOPSTAYPUT; +#define PIGCOPSTAYPUT__STATIC 2001 +extern unsigned short PIGCOPDIVE; +#define PIGCOPDIVE__STATIC 2045 +extern unsigned short PIGCOPDEADSPRITE; +#define PIGCOPDEADSPRITE__STATIC 2060 +extern unsigned short PIGTOP; +#define PIGTOP__STATIC 2061 +extern unsigned short LIZMAN; +#define LIZMAN__STATIC 2120 +extern unsigned short LIZMANSTAYPUT; +#define LIZMANSTAYPUT__STATIC 2121 +extern unsigned short LIZMANSPITTING; +#define LIZMANSPITTING__STATIC 2150 +extern unsigned short LIZMANFEEDING; +#define LIZMANFEEDING__STATIC 2160 +extern unsigned short LIZMANJUMP; +#define LIZMANJUMP__STATIC 2165 +extern unsigned short LIZMANDEADSPRITE; +#define LIZMANDEADSPRITE__STATIC 2185 +extern unsigned short FECES; +#define FECES__STATIC 2200 +extern unsigned short LIZMANHEAD1; +#define LIZMANHEAD1__STATIC 2201 +extern unsigned short LIZMANARM1; +#define LIZMANARM1__STATIC 2205 +extern unsigned short LIZMANLEG1; +#define LIZMANLEG1__STATIC 2209 +extern unsigned short EXPLOSION2BOT; +#define EXPLOSION2BOT__STATIC 2219 +extern unsigned short USERWEAPON; +#define USERWEAPON__STATIC 2235 +extern unsigned short HEADERBAR; +#define HEADERBAR__STATIC 2242 +extern unsigned short JIBS1; +#define JIBS1__STATIC 2245 +extern unsigned short JIBS2; +#define JIBS2__STATIC 2250 +extern unsigned short JIBS3; +#define JIBS3__STATIC 2255 +extern unsigned short JIBS4; +#define JIBS4__STATIC 2260 +extern unsigned short JIBS5; +#define JIBS5__STATIC 2265 +extern unsigned short BURNING; +#define BURNING__STATIC 2270 +extern unsigned short FIRE; +#define FIRE__STATIC 2271 +extern unsigned short JIBS6; +#define JIBS6__STATIC 2286 +extern unsigned short BLOODSPLAT1; +#define BLOODSPLAT1__STATIC 2296 +extern unsigned short BLOODSPLAT3; +#define BLOODSPLAT3__STATIC 2297 +extern unsigned short BLOODSPLAT2; +#define BLOODSPLAT2__STATIC 2298 +extern unsigned short BLOODSPLAT4; +#define BLOODSPLAT4__STATIC 2299 +extern unsigned short OOZ; +#define OOZ__STATIC 2300 +extern unsigned short OOZ2; +#define OOZ2__STATIC 2309 +extern unsigned short WALLBLOOD1; +#define WALLBLOOD1__STATIC 2301 +extern unsigned short WALLBLOOD2; +#define WALLBLOOD2__STATIC 2302 +extern unsigned short WALLBLOOD3; +#define WALLBLOOD3__STATIC 2303 +extern unsigned short WALLBLOOD4; +#define WALLBLOOD4__STATIC 2304 +extern unsigned short WALLBLOOD5; +#define WALLBLOOD5__STATIC 2305 +extern unsigned short WALLBLOOD6; +#define WALLBLOOD6__STATIC 2306 +extern unsigned short WALLBLOOD7; +#define WALLBLOOD7__STATIC 2307 +extern unsigned short WALLBLOOD8; +#define WALLBLOOD8__STATIC 2308 +extern unsigned short BURNING2; +#define BURNING2__STATIC 2310 +extern unsigned short FIRE2; +#define FIRE2__STATIC 2311 +extern unsigned short CRACKKNUCKLES; +#define CRACKKNUCKLES__STATIC 2324 +extern unsigned short SMALLSMOKE; +#define SMALLSMOKE__STATIC 2329 +extern unsigned short SMALLSMOKEMAKER; +#define SMALLSMOKEMAKER__STATIC 2330 +extern unsigned short FLOORFLAME; +#define FLOORFLAME__STATIC 2333 +extern unsigned short ROTATEGUN; +#define ROTATEGUN__STATIC 2360 +extern unsigned short GREENSLIME; +#define GREENSLIME__STATIC 2370 +extern unsigned short WATERDRIPSPLASH; +#define WATERDRIPSPLASH__STATIC 2380 +extern unsigned short SCRAP6; +#define SCRAP6__STATIC 2390 +extern unsigned short SCRAP1; +#define SCRAP1__STATIC 2400 +extern unsigned short SCRAP2; +#define SCRAP2__STATIC 2404 +extern unsigned short SCRAP3; +#define SCRAP3__STATIC 2408 +extern unsigned short SCRAP4; +#define SCRAP4__STATIC 2412 +extern unsigned short SCRAP5; +#define SCRAP5__STATIC 2416 +extern unsigned short ORGANTIC; +#define ORGANTIC__STATIC 2420 +extern unsigned short BETAVERSION; +#define BETAVERSION__STATIC 2440 +extern unsigned short PLAYERISHERE; +#define PLAYERISHERE__STATIC 2442 +extern unsigned short PLAYERWASHERE; +#define PLAYERWASHERE__STATIC 2443 +extern unsigned short SELECTDIR; +#define SELECTDIR__STATIC 2444 +extern unsigned short F1HELP; +#define F1HELP__STATIC 2445 +extern unsigned short NOTCHON; +#define NOTCHON__STATIC 2446 +extern unsigned short NOTCHOFF; +#define NOTCHOFF__STATIC 2447 +extern unsigned short GROWSPARK; +#define GROWSPARK__STATIC 2448 +extern unsigned short DUKEICON; +#define DUKEICON__STATIC 2452 +extern unsigned short BADGUYICON; +#define BADGUYICON__STATIC 2453 +extern unsigned short FOODICON; +#define FOODICON__STATIC 2454 +extern unsigned short GETICON; +#define GETICON__STATIC 2455 +extern unsigned short MENUSCREEN; +#define MENUSCREEN__STATIC 2456 +extern unsigned short MENUBAR; +#define MENUBAR__STATIC 2457 +extern unsigned short KILLSICON; +#define KILLSICON__STATIC 2458 +extern unsigned short FIRSTAID_ICON; +#define FIRSTAID_ICON__STATIC 2460 +extern unsigned short HEAT_ICON; +#define HEAT_ICON__STATIC 2461 +extern unsigned short BOTTOMSTATUSBAR; +#define BOTTOMSTATUSBAR__STATIC 2462 +extern unsigned short BOOT_ICON; +#define BOOT_ICON__STATIC 2463 +extern unsigned short FRAGBAR; +#define FRAGBAR__STATIC 2465 +extern unsigned short JETPACK_ICON; +#define JETPACK_ICON__STATIC 2467 +extern unsigned short AIRTANK_ICON; +#define AIRTANK_ICON__STATIC 2468 +extern unsigned short STEROIDS_ICON; +#define STEROIDS_ICON__STATIC 2469 +extern unsigned short HOLODUKE_ICON; +#define HOLODUKE_ICON__STATIC 2470 +extern unsigned short ACCESS_ICON; +#define ACCESS_ICON__STATIC 2471 +extern unsigned short DIGITALNUM; +#define DIGITALNUM__STATIC 2472 +extern unsigned short DUKECAR; +#define DUKECAR__STATIC 2491 +extern unsigned short CAMCORNER; +#define CAMCORNER__STATIC 2482 +extern unsigned short CAMLIGHT; +#define CAMLIGHT__STATIC 2484 +extern unsigned short LOGO; +#define LOGO__STATIC 2485 +extern unsigned short TITLE; +#define TITLE__STATIC 2486 +extern unsigned short NUKEWARNINGICON; +#define NUKEWARNINGICON__STATIC 2487 +extern unsigned short MOUSECURSOR; +#define MOUSECURSOR__STATIC 2488 +extern unsigned short SLIDEBAR; +#define SLIDEBAR__STATIC 2489 +extern unsigned short DREALMS; +#define DREALMS__STATIC 2492 +extern unsigned short BETASCREEN; +#define BETASCREEN__STATIC 2493 +extern unsigned short WINDOWBORDER1; +#define WINDOWBORDER1__STATIC 2494 +extern unsigned short TEXTBOX; +#define TEXTBOX__STATIC 2495 +extern unsigned short WINDOWBORDER2; +#define WINDOWBORDER2__STATIC 2496 +extern unsigned short DUKENUKEM; +#define DUKENUKEM__STATIC 2497 +extern unsigned short THREEDEE; +#define THREEDEE__STATIC 2498 +extern unsigned short INGAMEDUKETHREEDEE; +#define INGAMEDUKETHREEDEE__STATIC 2499 +extern unsigned short TENSCREEN; +#define TENSCREEN__STATIC 2500 +extern unsigned short PLUTOPAKSPRITE; +#define PLUTOPAKSPRITE__STATIC 2501 +extern unsigned short DEVISTATOR; +#define DEVISTATOR__STATIC 2510 +extern unsigned short KNEE; +#define KNEE__STATIC 2521 +extern unsigned short CROSSHAIR; +#define CROSSHAIR__STATIC 2523 +extern unsigned short FIRSTGUN; +#define FIRSTGUN__STATIC 2524 +extern unsigned short FIRSTGUNRELOAD; +#define FIRSTGUNRELOAD__STATIC 2528 +extern unsigned short FALLINGCLIP; +#define FALLINGCLIP__STATIC 2530 +extern unsigned short CLIPINHAND; +#define CLIPINHAND__STATIC 2531 +extern unsigned short HAND; +#define HAND__STATIC 2532 +extern unsigned short SHELL; +#define SHELL__STATIC 2533 +extern unsigned short SHOTGUNSHELL; +#define SHOTGUNSHELL__STATIC 2535 +extern unsigned short CHAINGUN; +#define CHAINGUN__STATIC 2536 +extern unsigned short RPGGUN; +#define RPGGUN__STATIC 2544 +extern unsigned short RPGMUZZLEFLASH; +#define RPGMUZZLEFLASH__STATIC 2545 +extern unsigned short FREEZE; +#define FREEZE__STATIC 2548 +extern unsigned short CATLITE; +#define CATLITE__STATIC 2552 +extern unsigned short SHRINKER; +#define SHRINKER__STATIC 2556 +extern unsigned short HANDHOLDINGLASER; +#define HANDHOLDINGLASER__STATIC 2563 +extern unsigned short TRIPBOMB; +#define TRIPBOMB__STATIC 2566 +extern unsigned short LASERLINE; +#define LASERLINE__STATIC 2567 +extern unsigned short HANDHOLDINGACCESS; +#define HANDHOLDINGACCESS__STATIC 2568 +extern unsigned short HANDREMOTE; +#define HANDREMOTE__STATIC 2570 +extern unsigned short HANDTHROW; +#define HANDTHROW__STATIC 2573 +extern unsigned short TIP; +#define TIP__STATIC 2576 +extern unsigned short GLAIR; +#define GLAIR__STATIC 2578 +extern unsigned short SCUBAMASK; +#define SCUBAMASK__STATIC 2581 +extern unsigned short SPACEMASK; +#define SPACEMASK__STATIC 2584 +extern unsigned short FORCESPHERE; +#define FORCESPHERE__STATIC 2590 +extern unsigned short SHOTSPARK1; +#define SHOTSPARK1__STATIC 2595 +extern unsigned short RPG; +#define RPG__STATIC 2605 +extern unsigned short LASERSITE; +#define LASERSITE__STATIC 2612 +extern unsigned short SHOTGUN; +#define SHOTGUN__STATIC 2613 +extern unsigned short BOSS1; +#define BOSS1__STATIC 2630 +extern unsigned short BOSS1STAYPUT; +#define BOSS1STAYPUT__STATIC 2631 +extern unsigned short BOSS1SHOOT; +#define BOSS1SHOOT__STATIC 2660 +extern unsigned short BOSS1LOB; +#define BOSS1LOB__STATIC 2670 +extern unsigned short BOSSTOP; +#define BOSSTOP__STATIC 2696 +extern unsigned short BOSS2; +#define BOSS2__STATIC 2710 +extern unsigned short BOSS3; +#define BOSS3__STATIC 2760 +extern unsigned short SPINNINGNUKEICON; +#define SPINNINGNUKEICON__STATIC 2813 +extern unsigned short BIGFNTCURSOR; +#define BIGFNTCURSOR__STATIC 2820 +extern unsigned short SMALLFNTCURSOR; +#define SMALLFNTCURSOR__STATIC 2821 +extern unsigned short STARTALPHANUM; +#define STARTALPHANUM__STATIC 2822 +extern unsigned short ENDALPHANUM; +#define ENDALPHANUM__STATIC 2915 +extern unsigned short BIGALPHANUM; +#define BIGALPHANUM__STATIC 2940 +extern unsigned short BIGPERIOD; +#define BIGPERIOD__STATIC 3002 +extern unsigned short BIGCOMMA; +#define BIGCOMMA__STATIC 3003 +extern unsigned short BIGX; +#define BIGX__STATIC 3004 +extern unsigned short BIGQ; +#define BIGQ__STATIC 3005 +extern unsigned short BIGSEMI; +#define BIGSEMI__STATIC 3006 +extern unsigned short BIGCOLIN; +#define BIGCOLIN__STATIC 3007 +extern unsigned short THREEBYFIVE; +#define THREEBYFIVE__STATIC 3010 +extern unsigned short BIGAPPOS; +#define BIGAPPOS__STATIC 3022 +extern unsigned short BLANK; +#define BLANK__STATIC 3026 +extern unsigned short MINIFONT; +#define MINIFONT__STATIC 3072 +extern unsigned short BUTTON1; +#define BUTTON1__STATIC 3164 +extern unsigned short GLASS3; +#define GLASS3__STATIC 3187 +extern unsigned short RESPAWNMARKERRED; +#define RESPAWNMARKERRED__STATIC 3190 +extern unsigned short RESPAWNMARKERYELLOW; +#define RESPAWNMARKERYELLOW__STATIC 3200 +extern unsigned short RESPAWNMARKERGREEN; +#define RESPAWNMARKERGREEN__STATIC 3210 +extern unsigned short BONUSSCREEN; +#define BONUSSCREEN__STATIC 3240 +extern unsigned short VIEWBORDER; +#define VIEWBORDER__STATIC 3250 +extern unsigned short VICTORY1; +#define VICTORY1__STATIC 3260 +extern unsigned short ORDERING; +#define ORDERING__STATIC 3270 +extern unsigned short TEXTSTORY; +#define TEXTSTORY__STATIC 3280 +extern unsigned short LOADSCREEN; +#define LOADSCREEN__STATIC 3281 +extern unsigned short BORNTOBEWILDSCREEN; +#define BORNTOBEWILDSCREEN__STATIC 3370 +extern unsigned short BLIMP; +#define BLIMP__STATIC 3400 +extern unsigned short FEM9; +#define FEM9__STATIC 3450 +extern unsigned short FOOTPRINT; +#define FOOTPRINT__STATIC 3701 +extern unsigned short FRAMEEFFECT1_13; +#define FRAMEEFFECT1_13__STATIC 3999 +extern unsigned short POOP; +#define POOP__STATIC 4094 +extern unsigned short FRAMEEFFECT1; +#define FRAMEEFFECT1__STATIC 4095 +extern unsigned short PANNEL3; +#define PANNEL3__STATIC 4099 +extern unsigned short SCREENBREAK14; +#define SCREENBREAK14__STATIC 4120 +extern unsigned short SCREENBREAK15; +#define SCREENBREAK15__STATIC 4123 +extern unsigned short SCREENBREAK19; +#define SCREENBREAK19__STATIC 4125 +extern unsigned short SCREENBREAK16; +#define SCREENBREAK16__STATIC 4127 +extern unsigned short SCREENBREAK17; +#define SCREENBREAK17__STATIC 4128 +extern unsigned short SCREENBREAK18; +#define SCREENBREAK18__STATIC 4129 +extern unsigned short W_TECHWALL11; +#define W_TECHWALL11__STATIC 4130 +extern unsigned short W_TECHWALL12; +#define W_TECHWALL12__STATIC 4131 +extern unsigned short W_TECHWALL13; +#define W_TECHWALL13__STATIC 4132 +extern unsigned short W_TECHWALL14; +#define W_TECHWALL14__STATIC 4133 +extern unsigned short W_TECHWALL5; +#define W_TECHWALL5__STATIC 4134 +extern unsigned short W_TECHWALL6; +#define W_TECHWALL6__STATIC 4136 +extern unsigned short W_TECHWALL7; +#define W_TECHWALL7__STATIC 4138 +extern unsigned short W_TECHWALL8; +#define W_TECHWALL8__STATIC 4140 +extern unsigned short W_TECHWALL9; +#define W_TECHWALL9__STATIC 4142 +extern unsigned short BPANNEL3; +#define BPANNEL3__STATIC 4100 +extern unsigned short W_HITTECHWALL16; +#define W_HITTECHWALL16__STATIC 4144 +extern unsigned short W_HITTECHWALL10; +#define W_HITTECHWALL10__STATIC 4145 +extern unsigned short W_HITTECHWALL15; +#define W_HITTECHWALL15__STATIC 4147 +extern unsigned short W_MILKSHELF; +#define W_MILKSHELF__STATIC 4181 +extern unsigned short W_MILKSHELFBROKE; +#define W_MILKSHELFBROKE__STATIC 4203 +extern unsigned short PURPLELAVA; +#define PURPLELAVA__STATIC 4240 +extern unsigned short LAVABUBBLE; +#define LAVABUBBLE__STATIC 4340 +extern unsigned short DUKECUTOUT; +#define DUKECUTOUT__STATIC 4352 +extern unsigned short TARGET; +#define TARGET__STATIC 4359 +extern unsigned short GUNPOWDERBARREL; +#define GUNPOWDERBARREL__STATIC 4360 +extern unsigned short DUCK; +#define DUCK__STATIC 4361 +extern unsigned short HATRACK; +#define HATRACK__STATIC 4367 +extern unsigned short DESKLAMP; +#define DESKLAMP__STATIC 4370 +extern unsigned short COFFEEMACHINE; +#define COFFEEMACHINE__STATIC 4372 +extern unsigned short CUPS; +#define CUPS__STATIC 4373 +extern unsigned short GAVALS; +#define GAVALS__STATIC 4374 +extern unsigned short GAVALS2; +#define GAVALS2__STATIC 4375 +extern unsigned short POLICELIGHTPOLE; +#define POLICELIGHTPOLE__STATIC 4377 +extern unsigned short FLOORBASKET; +#define FLOORBASKET__STATIC 4388 +extern unsigned short PUKE; +#define PUKE__STATIC 4389 +extern unsigned short DOORTILE23; +#define DOORTILE23__STATIC 4391 +extern unsigned short TOPSECRET; +#define TOPSECRET__STATIC 4396 +extern unsigned short SPEAKER; +#define SPEAKER__STATIC 4397 +extern unsigned short TEDDYBEAR; +#define TEDDYBEAR__STATIC 4400 +extern unsigned short ROBOTDOG; +#define ROBOTDOG__STATIC 4402 +extern unsigned short ROBOTPIRATE; +#define ROBOTPIRATE__STATIC 4404 +extern unsigned short ROBOTMOUSE; +#define ROBOTMOUSE__STATIC 4407 +extern unsigned short MAIL; +#define MAIL__STATIC 4410 +extern unsigned short MAILBAG; +#define MAILBAG__STATIC 4413 +extern unsigned short HOTMEAT; +#define HOTMEAT__STATIC 4427 +extern unsigned short COFFEEMUG; +#define COFFEEMUG__STATIC 4438 +extern unsigned short DONUTS2; +#define DONUTS2__STATIC 4440 +extern unsigned short TRIPODCAMERA; +#define TRIPODCAMERA__STATIC 4444 +extern unsigned short METER; +#define METER__STATIC 4453 +extern unsigned short DESKPHONE; +#define DESKPHONE__STATIC 4454 +extern unsigned short GUMBALLMACHINE; +#define GUMBALLMACHINE__STATIC 4458 +extern unsigned short GUMBALLMACHINEBROKE; +#define GUMBALLMACHINEBROKE__STATIC 4459 +extern unsigned short PAPER; +#define PAPER__STATIC 4460 +extern unsigned short MACE; +#define MACE__STATIC 4464 +extern unsigned short GENERICPOLE2; +#define GENERICPOLE2__STATIC 4465 +extern unsigned short XXXSTACY; +#define XXXSTACY__STATIC 4470 +extern unsigned short WETFLOOR; +#define WETFLOOR__STATIC 4495 +extern unsigned short BROOM; +#define BROOM__STATIC 4496 +extern unsigned short MOP; +#define MOP__STATIC 4497 +extern unsigned short LETTER; +#define LETTER__STATIC 4502 +extern unsigned short PIRATE1A; +#define PIRATE1A__STATIC 4510 +extern unsigned short PIRATE4A; +#define PIRATE4A__STATIC 4511 +extern unsigned short PIRATE2A; +#define PIRATE2A__STATIC 4512 +extern unsigned short PIRATE5A; +#define PIRATE5A__STATIC 4513 +extern unsigned short PIRATE3A; +#define PIRATE3A__STATIC 4514 +extern unsigned short PIRATE6A; +#define PIRATE6A__STATIC 4515 +extern unsigned short PIRATEHALF; +#define PIRATEHALF__STATIC 4516 +extern unsigned short CHESTOFGOLD; +#define CHESTOFGOLD__STATIC 4520 +extern unsigned short SIDEBOLT1; +#define SIDEBOLT1__STATIC 4525 +extern unsigned short FOODOBJECT1; +#define FOODOBJECT1__STATIC 4530 +extern unsigned short FOODOBJECT2; +#define FOODOBJECT2__STATIC 4531 +extern unsigned short FOODOBJECT3; +#define FOODOBJECT3__STATIC 4532 +extern unsigned short FOODOBJECT4; +#define FOODOBJECT4__STATIC 4533 +extern unsigned short FOODOBJECT5; +#define FOODOBJECT5__STATIC 4534 +extern unsigned short FOODOBJECT6; +#define FOODOBJECT6__STATIC 4535 +extern unsigned short FOODOBJECT7; +#define FOODOBJECT7__STATIC 4536 +extern unsigned short FOODOBJECT8; +#define FOODOBJECT8__STATIC 4537 +extern unsigned short FOODOBJECT9; +#define FOODOBJECT9__STATIC 4538 +extern unsigned short FOODOBJECT10; +#define FOODOBJECT10__STATIC 4539 +extern unsigned short FOODOBJECT11; +#define FOODOBJECT11__STATIC 4540 +extern unsigned short FOODOBJECT12; +#define FOODOBJECT12__STATIC 4541 +extern unsigned short FOODOBJECT13; +#define FOODOBJECT13__STATIC 4542 +extern unsigned short FOODOBJECT14; +#define FOODOBJECT14__STATIC 4543 +extern unsigned short FOODOBJECT15; +#define FOODOBJECT15__STATIC 4544 +extern unsigned short FOODOBJECT16; +#define FOODOBJECT16__STATIC 4545 +extern unsigned short FOODOBJECT17; +#define FOODOBJECT17__STATIC 4546 +extern unsigned short FOODOBJECT18; +#define FOODOBJECT18__STATIC 4547 +extern unsigned short FOODOBJECT19; +#define FOODOBJECT19__STATIC 4548 +extern unsigned short FOODOBJECT20; +#define FOODOBJECT20__STATIC 4549 +extern unsigned short HEADLAMP; +#define HEADLAMP__STATIC 4550 +extern unsigned short TAMPON; +#define TAMPON__STATIC 4557 +extern unsigned short SKINNEDCHICKEN; +#define SKINNEDCHICKEN__STATIC 4554 +extern unsigned short FEATHEREDCHICKEN; +#define FEATHEREDCHICKEN__STATIC 4555 +extern unsigned short ROBOTDOG2; +#define ROBOTDOG2__STATIC 4560 +extern unsigned short JOLLYMEAL; +#define JOLLYMEAL__STATIC 4569 +extern unsigned short DUKEBURGER; +#define DUKEBURGER__STATIC 4570 +extern unsigned short SHOPPINGCART; +#define SHOPPINGCART__STATIC 4576 +extern unsigned short CANWITHSOMETHING2; +#define CANWITHSOMETHING2__STATIC 4580 +extern unsigned short CANWITHSOMETHING3; +#define CANWITHSOMETHING3__STATIC 4581 +extern unsigned short CANWITHSOMETHING4; +#define CANWITHSOMETHING4__STATIC 4582 +extern unsigned short SNAKEP; +#define SNAKEP__STATIC 4590 +extern unsigned short DOLPHIN1; +#define DOLPHIN1__STATIC 4591 +extern unsigned short DOLPHIN2; +#define DOLPHIN2__STATIC 4592 +extern unsigned short NEWBEAST; +#define NEWBEAST__STATIC 4610 +extern unsigned short NEWBEASTSTAYPUT; +#define NEWBEASTSTAYPUT__STATIC 4611 +extern unsigned short NEWBEASTJUMP; +#define NEWBEASTJUMP__STATIC 4690 +extern unsigned short NEWBEASTHANG; +#define NEWBEASTHANG__STATIC 4670 +extern unsigned short NEWBEASTHANGDEAD; +#define NEWBEASTHANGDEAD__STATIC 4671 +extern unsigned short BOSS4; +#define BOSS4__STATIC 4740 +extern unsigned short BOSS4STAYPUT; +#define BOSS4STAYPUT__STATIC 4741 +extern unsigned short FEM10; +#define FEM10__STATIC 4864 +extern unsigned short TOUGHGAL; +#define TOUGHGAL__STATIC 4866 +extern unsigned short MAN; +#define MAN__STATIC 4871 +extern unsigned short MAN2; +#define MAN2__STATIC 4872 +extern unsigned short WOMAN; +#define WOMAN__STATIC 4874 +extern unsigned short PLEASEWAIT; +#define PLEASEWAIT__STATIC 4887 +extern unsigned short NATURALLIGHTNING; +#define NATURALLIGHTNING__STATIC 4890 +extern unsigned short WEATHERWARN; +#define WEATHERWARN__STATIC 4893 +extern unsigned short DUKETAG; +#define DUKETAG__STATIC 4900 +extern unsigned short SIGN1; +#define SIGN1__STATIC 4909 +extern unsigned short SIGN2; +#define SIGN2__STATIC 4912 +extern unsigned short JURYGUY; +#define JURYGUY__STATIC 4943 +extern unsigned short RESERVEDSLOT1; +#define RESERVEDSLOT1__STATIC 6132 +extern unsigned short RESERVEDSLOT2; +#define RESERVEDSLOT2__STATIC 6133 +extern unsigned short RESERVEDSLOT3; +#define RESERVEDSLOT3__STATIC 6134 +extern unsigned short RESERVEDSLOT4; +#define RESERVEDSLOT4__STATIC 6135 +extern unsigned short RESERVEDSLOT5; +#define RESERVEDSLOT5__STATIC 6136 +extern unsigned short RESERVEDSLOT6; +#define RESERVEDSLOT6__STATIC 6137 +extern unsigned short RESERVEDSLOT7; +#define RESERVEDSLOT7__STATIC 6138 +extern unsigned short RESERVEDSLOT8; +#define RESERVEDSLOT8__STATIC 6139 +extern unsigned short RESERVEDSLOT9; +#define RESERVEDSLOT9__STATIC 6140 +extern unsigned short RESERVEDSLOT10; +#define RESERVEDSLOT10__STATIC 6141 +extern unsigned short RESERVEDSLOT11; +#define RESERVEDSLOT11__STATIC 6142 +extern unsigned short RESERVEDSLOT12; +#define RESERVEDSLOT12__STATIC 6143 +extern unsigned short dynamictostatic[MAXTILES]; diff --git a/polymer/eduke32/source/osdcmds.c b/polymer/eduke32/source/osdcmds.c new file mode 100644 index 000000000..f871aaf46 --- /dev/null +++ b/polymer/eduke32/source/osdcmds.c @@ -0,0 +1,654 @@ +//------------------------------------------------------------------------- +/* +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "osdcmds.h" +#include "osd.h" +#include "baselayer.h" +#include "duke3d.h" +#include "crc32.h" + +#include + +struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat; + +int osdcmd_quit(const osdfuncparm_t *parm) +{ + extern long quittimer; + parm=parm; + if( gamequit == 0 && ( numplayers > 1 ) ) + { + if(ps[myconnectindex].gm&MODE_GAME) + { + gamequit = 1; + quittimer = totalclock+120; + } + else + { + sendlogoff(); + gameexit(" "); + } + } + else if( numplayers < 2 ) + gameexit(" "); + + return OSDCMD_OK; +} + +int osdcmd_echo(const osdfuncparm_t *parm) +{ + int i; + for (i = 0; i < parm->numparms; i++) { + if (i > 0) OSD_Printf(" "); + OSD_Printf("%s", parm->parms[i]); + } + OSD_Printf("\n"); + + return OSDCMD_OK; +} + +int osdcmd_changelevel(const osdfuncparm_t *parm) +{ + int volume=0,level,i; + char *p; + + if (!VOLUMEONE) { + if (parm->numparms != 2) return OSDCMD_SHOWHELP; + + volume = strtol(parm->parms[0], &p, 10) - 1; + if (p[0]) return OSDCMD_SHOWHELP; + level = strtol(parm->parms[1], &p, 10) - 1; + if (p[0]) return OSDCMD_SHOWHELP; + } else { + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + + level = strtol(parm->parms[0], &p, 10) - 1; + if (p[0]) return OSDCMD_SHOWHELP; + } + + if (volume < 0) return OSDCMD_SHOWHELP; + if (level < 0) return OSDCMD_SHOWHELP; + + if (!VOLUMEONE) { + if (volume > num_volumes) { + OSD_Printf("changelevel: invalid volume number (range 1-%ld)\n",num_volumes); + return OSDCMD_OK; + } + } + + if (volume == 0) { + if (level > 5) { + OSD_Printf("changelevel: invalid volume 1 level number (range 1-6)\n"); + return OSDCMD_OK; + } + } else { + if (level > 10) { + OSD_Printf("changelevel: invalid volume 2+ level number (range 1-11)\n"); + return OSDCMD_SHOWHELP; + } + } + + if (ps[myconnectindex].gm & MODE_GAME) { + // in-game behave like a cheat + osdcmd_cheatsinfo_stat.cheatnum = 2; + osdcmd_cheatsinfo_stat.volume = volume; + osdcmd_cheatsinfo_stat.level = level; + } else { + // out-of-game behave like a menu command + osdcmd_cheatsinfo_stat.cheatnum = -1; + + ud.m_volume_number = volume; + ud.m_level_number = level; + + ud.m_monsters_off = ud.monsters_off = 0; + + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + + ud.multimode = 1; + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill); + if (enterlevel(MODE_GAME)) backtomenu(); + } + + return OSDCMD_OK; +} + +int osdcmd_map(const osdfuncparm_t *parm) +{ + int i; + char filename[256]; + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + + strcpy(filename,parm->parms[0]); + if( strchr(filename,'.') == 0) + strcat(filename,".map"); + + if ((i = kopen4load(filename,0)) < 0) { + OSD_Printf("map: file \"%s\" not found.\n", filename); + return OSDCMD_OK; + } + kclose(i); + + strcpy(boardfilename, filename); + + if (ps[myconnectindex].gm & MODE_GAME) { + // in-game behave like a cheat + osdcmd_cheatsinfo_stat.cheatnum = 2; + osdcmd_cheatsinfo_stat.volume = 0; + osdcmd_cheatsinfo_stat.level = 7; + } else { + // out-of-game behave like a menu command + osdcmd_cheatsinfo_stat.cheatnum = -1; + + ud.m_volume_number = 0; + ud.m_level_number = 7; + + ud.m_monsters_off = ud.monsters_off = 0; + + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + + ud.multimode = 1; + + newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill); + if (enterlevel(MODE_GAME)) backtomenu(); + } + + return OSDCMD_OK; +} + +int osdcmd_god(const osdfuncparm_t *parm) +{ + parm=parm; + if (numplayers == 1 && ps[myconnectindex].gm & MODE_GAME) { + osdcmd_cheatsinfo_stat.cheatnum = 0; + } else { + OSD_Printf("god: Not in a single-player game.\n"); + } + + return OSDCMD_OK; +} + +int osdcmd_noclip(const osdfuncparm_t *parm) +{ + parm=parm; + if (numplayers == 1 && ps[myconnectindex].gm & MODE_GAME) { + osdcmd_cheatsinfo_stat.cheatnum = 20; + } else { + OSD_Printf("noclip: Not in a single-player game.\n"); + } + + return OSDCMD_OK; +} + +int osdcmd_fileinfo(const osdfuncparm_t *parm) +{ + unsigned long crc, length; + int i,j; + char buf[256]; + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + + if ((i = kopen4load((char *)parm->parms[0],0)) < 0) { + OSD_Printf("fileinfo: File \"%s\" not found.\n", parm->parms[0]); + return OSDCMD_OK; + } + + length = kfilelength(i); + + crc32init(&crc); + do { + j = kread(i,buf,256); + crc32block(&crc,buf,j); + } while (j == 256); + crc32finish(&crc); + + kclose(i); + + OSD_Printf("fileinfo: %s\n" + " File size: %d\n" + " CRC-32: %08X\n", + parm->parms[0], length, crc); + + return OSDCMD_OK; +} + +static int osdcmd_restartvid(const osdfuncparm_t *parm) +{ + extern long qsetmode; + + resetvideomode(); + if (setgamemode(ScreenMode,ScreenWidth,ScreenHeight,ScreenBPP)) + gameexit("restartvid: Reset failed...\n"); + onvideomodechange(ScreenBPP>8); + vscrn(); + + return OSDCMD_OK; +} + +static int osdcmd_vidmode(const osdfuncparm_t *parm) +{ + int newbpp = ScreenBPP, newwidth = ScreenWidth, + newheight = ScreenHeight, newfs = ScreenMode; + if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP; + + switch (parm->numparms) { + case 1: // bpp switch + newbpp = Batol(parm->parms[0]); + break; + case 2: // res switch + newwidth = Batol(parm->parms[0]); + newheight = Batol(parm->parms[1]); + break; + case 3: // res & bpp switch + case 4: + newwidth = Batol(parm->parms[0]); + newheight = Batol(parm->parms[1]); + newbpp = Batol(parm->parms[2]); + if (parm->numparms == 4) + newfs = (Batol(parm->parms[3]) != 0); + break; + } + + if (setgamemode(newfs,newwidth,newheight,newbpp)) { + initprintf("vidmode: Mode change failed!\n"); + if (setgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP)) + gameexit("vidmode: Reset failed!\n"); + } + ScreenBPP = newbpp; ScreenWidth = newwidth; ScreenHeight = newheight; + ScreenMode = newfs; + onvideomodechange(ScreenBPP>8); + vscrn(); + return OSDCMD_OK; +} + +static int osdcmd_setstatusbarscale(const osdfuncparm_t *parm) +{ + if (parm->numparms == 0) { + OSD_Printf("setstatusbarscale: scale is %d%%\n", ud.statusbarscale); + return OSDCMD_OK; + } else if (parm->numparms != 1) return OSDCMD_SHOWHELP; + + setstatusbarscale(Batol(parm->parms[0])); + OSD_Printf("setstatusbarscale: new scale is %d%%\n", ud.statusbarscale); + return OSDCMD_OK; +} + +static int osdcmd_spawn(const osdfuncparm_t *parm) +{ + long x=0,y=0,z=0; + unsigned short cstat=0,picnum=0; + unsigned char pal=0; + short ang=0; + short set=0, idx; + + if (numplayers > 1 || !(ps[myconnectindex].gm & MODE_GAME)) { + OSD_Printf("spawn: Can't spawn sprites in multiplayer games or demos\n"); + return OSDCMD_OK; + } + + switch (parm->numparms) { + case 7: // x,y,z + x = Batol(parm->parms[4]); + y = Batol(parm->parms[5]); + z = Batol(parm->parms[6]); + set |= 8; + case 4: // ang + ang = Batol(parm->parms[3]) & 2047; set |= 4; + case 3: // cstat + cstat = (unsigned short)Batol(parm->parms[2]); set |= 2; + case 2: // pal + pal = (unsigned char)Batol(parm->parms[1]); set |= 1; + case 1: // tile number + if (isdigit(parm->parms[0][0])) { + picnum = (unsigned short)Batol(parm->parms[0]); + } else { + int i,j; + for (j=0; j<2; j++) { + for (i=0; iparms[0])) || + (j == 1 && !Bstrcasecmp(label+(i<<6), parm->parms[0])) + ) { + picnum = (unsigned short)labelcode[i]; + break; + } + } + if (i= MAXTILES) { + OSD_Printf("spawn: Invalid tile number\n"); + return OSDCMD_OK; + } + break; + default: + return OSDCMD_SHOWHELP; + } + + idx = spawn(ps[myconnectindex].i, (short)picnum); + if (set & 1) sprite[idx].pal = (char)pal; + if (set & 2) sprite[idx].cstat = (short)cstat; + if (set & 4) sprite[idx].ang = ang; + if (set & 8) { + if (setsprite(idx, x,y,z) < 0) { + OSD_Printf("spawn: Sprite can't be spawned into null space\n"); + deletesprite(idx); + } + } + + return OSDCMD_OK; +} + +int osdcmd_setvar(const osdfuncparm_t *parm) +{ + int i, varval; + char varname[256]; + + if (parm->numparms != 2) return OSDCMD_SHOWHELP; + + if (ud.multimode != 1) + { + OSD_Printf("Command not allowed in multiplayer\n"); + return OSDCMD_OK; + } + + strcpy(varname,parm->parms[0]); + varval = Batol(parm->parms[1]); + + for(i=0;inumparms != 1) return OSDCMD_SHOWHELP; + parm=parm; + if (numplayers > 1) { + OSD_Printf("cmenu: disallowed in multiplayer\n"); + return OSDCMD_OK; + } else { + cmenu(Batol(parm->parms[0])); + } + + return OSDCMD_OK; +} + +int osdcmd_exec(const osdfuncparm_t *parm) +{ + char fn[BMAX_PATH]; + extern int load_script(char *szStartupScript); + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + Bstrcpy(fn,parm->parms[0]); + + if (load_script(fn)) { + OSD_Printf("exec: file \"%s\" not found.\n", fn); + return OSDCMD_OK; + } + return OSDCMD_OK; +} + +/* +static int osdcmd_vars(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms < 1); + + if (!Bstrcasecmp(parm->name, "myname")) { + if (showval) { OSD_Printf("Your name is \"%s\"\n", myname); } + else { + Bstrncpy(myname, parm->parms[0], sizeof(myname)-1); + myname[sizeof(myname)-1] = 0; + // XXX: now send the update over the wire + } + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "showcoords")) { + if (showval) { OSD_Printf("showcoords is %d\n", ud.coords); } + else ud.coords = (atoi(parm->parms[0]) != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "useprecache")) { + if (showval) { OSD_Printf("useprecache is %d\n", useprecache); } + else useprecache = (atoi(parm->parms[0]) != 0); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "drawweapon")) { + if (showval) { OSD_Printf("drawweapon is %d\n", ud.drawweapon); } + else ud.drawweapon = (atoi(parm->parms[0]) != 0); + return OSDCMD_OK; + } + return OSDCMD_SHOWHELP; +} +*/ +enum cvartypes { + CVAR_INT, + CVAR_UNSIGNEDINT, + CVAR_BOOL, + CVAR_STRING +}; + +struct cvarmappings { + char *name; + char *helpstr; + void *var; + int type; // 0 = integer, 1 = unsigned integer, 2 = boolean, 3 = string, |128 = not in multiplayer + int extra; // for string, is the length +} cvar[] = + { + { "showfps", "showfps: show the frame rate counter", (void*)&ud.tickrate, CVAR_BOOL, 0 }, + { "showcoords", "showcoords: show your position in the game world", (void*)&ud.coords, CVAR_BOOL, 0 }, + { "useprecache", "useprecache: enable/disable the pre-level caching routine", (void*)&useprecache, CVAR_BOOL, 0 }, + { "drawweapon", "drawweapon: enable/disable weapon drawing", (void*)&ud.drawweapon, CVAR_BOOL, 0 }, + { "name", "name: change your multiplayer nickname", (void*)&myname[0], CVAR_STRING, sizeof(myname) } + }; + +int osdcmd_cvar_set(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms == 0); + unsigned int i; + + for (i = 0; i < sizeof(cvar)/sizeof(struct cvarmappings); i++) { + if (!Bstrcasecmp(parm->name, cvar[i].name)) { + if ((cvar[i].type & 0x80) && ud.multimode != 1) { + // sound the alarm + OSD_Printf("Cvar \"%s\" locked in multiplayer.\n",cvar[i].name); + return OSDCMD_OK; + } else + switch (cvar[i].type&0x7f) { + case CVAR_INT: + case CVAR_UNSIGNEDINT: + case CVAR_BOOL: + { + int val; + if (showval) { + OSD_Printf("%s %d\n",cvar[i].name,*(int*)cvar[i].var); + return OSDCMD_OK; + } + + val = atoi(parm->parms[0]); + if (cvar[i].type == CVAR_BOOL) val = val != 0; + *(int*)cvar[i].var = val; + } break; + case CVAR_STRING: + { + if (showval) { + OSD_Printf("%s \"%s\"\n",cvar[i].name,(char*)cvar[i].var); + return OSDCMD_OK; + } + else { + Bstrncpy((char*)cvar[i].var, parm->parms[0], cvar[i].extra-1); + ((char*)cvar[i].var)[cvar[i].extra-1] = 0; + // XXX: now send the update over the wire + } + } break; + default: break; + } + } + } + OSD_Printf("\n"); + return OSDCMD_OK; +} + +int osdcmd_sensitivity(const osdfuncparm_t *parm) +{ + if (parm->numparms != 1) { + OSD_Printf("sensitivity %d\n",CONTROL_GetMouseSensitivity()>>10); + return OSDCMD_OK; + } + CONTROL_SetMouseSensitivity(atoi(parm->parms[0])<<10); + OSD_Printf("\n"); + return OSDCMD_OK; +} + +int osdcmd_gamma(const osdfuncparm_t *parm) +{ + if (parm->numparms != 1) { + OSD_Printf("gamma %d\n",ud.brightness>>2); + return OSDCMD_OK; + } + ud.brightness = atoi(parm->parms[0])<<2; + setbrightness(ud.brightness>>2,&ps[screenpeek].palette[0],0); + OSD_Printf("\n"); + return OSDCMD_OK; +} + +int osdcmd_give(const osdfuncparm_t *parm) +{ + int i; + + if (numplayers == 1 && ps[myconnectindex].gm & MODE_GAME) { + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + if (!Bstrcasecmp(parm->parms[0], "all")) { + osdcmd_cheatsinfo_stat.cheatnum = 1; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->parms[0], "health")) { + sprite[ps[myconnectindex].i].extra = 200; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->parms[0], "weapons")) { + osdcmd_cheatsinfo_stat.cheatnum = 21; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->parms[0], "ammo")) { + for (i=PISTOL_WEAPON;iparms[0], "armor")) { + ps[myconnectindex].shield_amount = 100; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->parms[0], "keys")) { + osdcmd_cheatsinfo_stat.cheatnum = 23; + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->parms[0], "inventory")) { + osdcmd_cheatsinfo_stat.cheatnum = 22; + return OSDCMD_OK; + } + } else { + OSD_Printf("give: Not in a single-player game.\n"); + return OSDCMD_OK; + } + return OSDCMD_SHOWHELP; +} + +void onvideomodechange(int newmode) +{ + char *pal; + + if (newmode) { + if (ps[screenpeek].palette == palette || + ps[screenpeek].palette == waterpal || + ps[screenpeek].palette == slimepal) + pal = palette; + else + pal = ps[screenpeek].palette; + } else { + pal = ps[screenpeek].palette; + } + + setbrightness(ud.brightness>>2, pal, 0); + restorepalette = 1; +} + +int registerosdcommands(void) +{ + unsigned int i; + + osdcmd_cheatsinfo_stat.cheatnum = -1; + + for (i=0; i: warps to the given level", osdcmd_changelevel); + } else { + OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); + OSD_RegisterFunction("map","map : loads the given user map", osdcmd_map); + } + OSD_RegisterFunction("cmenu","cmenu <#>: jumps to menu", osdcmd_cmenu); + OSD_RegisterFunction("exec","exec : executes a script", osdcmd_exec); + OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); + OSD_RegisterFunction("gamma","gamma : changes brightness", osdcmd_gamma); + OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); + OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + + OSD_RegisterFunction("setstatusbarscale","setstatusbarscale : changes the status bar scale", osdcmd_setstatusbarscale); + OSD_RegisterFunction("sensitivity","sensitivity : changes the mouse sensitivity", osdcmd_sensitivity); + OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); + OSD_RegisterFunction("setvar","setvar : sets the value of a gamevar", osdcmd_setvar); + + OSD_RegisterFunction("fileinfo","fileinfo : gets a file's information", osdcmd_fileinfo); + OSD_RegisterFunction("quit","quit: exits the game immediately", osdcmd_quit); + + /* OSD_RegisterFunction("myname","myname: change your multiplayer nickname", osdcmd_vars); + OSD_RegisterFunction("showfps","showfps: show the frame rate counter", osdcmd_vars); + OSD_RegisterFunction("showcoords","showcoords: show your position in the game world", osdcmd_vars); + OSD_RegisterFunction("useprecache","useprecache: enable/disable the pre-level caching routine", osdcmd_vars); + OSD_RegisterFunction("drawweapon","drawweapon: enable/disable weapon drawing", osdcmd_vars); */ + + OSD_RegisterFunction("restartvid","restartvid: reinitialised the video mode",osdcmd_restartvid); + OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); + + //baselayer_onvideomodechange = onvideomodechange; + + return 0; +} + diff --git a/polymer/eduke32/source/osdcmds.h b/polymer/eduke32/source/osdcmds.h new file mode 100644 index 000000000..d0c77b7b7 --- /dev/null +++ b/polymer/eduke32/source/osdcmds.h @@ -0,0 +1,14 @@ +#ifndef __osdcmds_h__ +#define __osdcmds_h__ + +struct osdcmd_cheatsinfo { + int cheatnum; // -1 = none, else = see cheats() + int volume,level; +}; + +extern struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat; + +int registerosdcommands(void); + +#endif // __osdcmds_h__ + diff --git a/polymer/eduke32/source/osdfuncs.c b/polymer/eduke32/source/osdfuncs.c new file mode 100644 index 000000000..0e2dfce1d --- /dev/null +++ b/polymer/eduke32/source/osdfuncs.c @@ -0,0 +1,90 @@ +#include "duke3d.h" +#include "build.h" +#include "namesdyn.h" + +void GAME_drawosdchar(int x, int y, char ch, int shade, int pal) +{ + short ac; + + if (ch == 32) return; + ac = ch-'!'+STARTALPHANUM; + if (ac < STARTALPHANUM || ac > ENDALPHANUM) return; + + rotatesprite(((x<<3)+x)<<16, (y<<3)<<16, 65536l, 0, ac, shade, pal, 8|16, 0, 0, xdim-1, ydim-1); +} + +void GAME_drawosdstr(int x, int y, char *ch, int len, int shade, int pal) +{ + short ac; + + for (x = (x<<3)+x; len>0; len--, ch++, x++) { + if (*ch == 32) { x+=5; continue; } + ac = *ch-'!'+STARTALPHANUM; + if (ac < STARTALPHANUM || ac > ENDALPHANUM) return; + + rotatesprite(x<<16, (y<<3)<<16, 65536l, 0, ac, shade, pal, 8|16, 0, 0, xdim-1, ydim-1); + if (*ch >= '0' && *ch <= '9') x+=8; + else x += tilesizx[ac]; + } +} + +void GAME_drawosdcursor(int x, int y, int type, int lastkeypress) +{ + short ac; + + if (type) ac = SMALLFNTCURSOR; + else ac = '_'-'!'+STARTALPHANUM; + + if (!((GetTime()-lastkeypress) & 0x40l)) + rotatesprite(((x<<3)+x)<<16, ((y<<3)+(type?-1:2))<<16, 65536l, 0, ac, 0, 8, 8|16, 0, 0, xdim-1, ydim-1); +} + +int GAME_getcolumnwidth(int w) +{ + return w/9; +} + +int GAME_getrowheight(int w) +{ + return w>>3; +} + +void GAME_onshowosd(int shown) +{ + if (numplayers == 1) + if ((shown && !ud.pause_on) || (!shown && ud.pause_on)) + KB_KeyDown[sc_Pause] = 1; +} + +//#define BGTILE 311 +//#define BGTILE 1156 +#define BGTILE 1141 // BIGHOLE +#define BORDTILE 3250 // VIEWBORDER +#define BITSTH 1+32+8+16 // high translucency +#define BITSTL 1+8+16 // low translucency +#define BITS 8+16+64 // solid +#define SHADE 16 +#define PALETTE 4 +void GAME_clearbackground(int c, int r) +{ + long x, y, xsiz, ysiz, tx2, ty2; + long daydim, bits; + + if (getrendermode() < 3) bits = BITS; else bits = BITSTL; + + daydim = r<<3; + + xsiz = tilesizx[BGTILE]; tx2 = xdim/xsiz; + ysiz = tilesizy[BGTILE]; ty2 = daydim/ysiz; + + for(x=0;x<=tx2;x++) + for(y=0;y<=ty2;y++) + rotatesprite(x*xsiz<<16,y*ysiz<<16,65536L,0,BGTILE,SHADE,PALETTE,bits,0,0,xdim,daydim); + + xsiz = tilesizy[BORDTILE]; tx2 = xdim/xsiz; + ysiz = tilesizx[BORDTILE]; + + for(x=0;x<=tx2;x++) + rotatesprite(x*xsiz<<16,(daydim+ysiz+1)<<16,65536L,1536,BORDTILE,SHADE-12,PALETTE,BITS,0,0,xdim,daydim+ysiz+1); +} + diff --git a/polymer/eduke32/source/osdfuncs.h b/polymer/eduke32/source/osdfuncs.h new file mode 100644 index 000000000..4f1ddaac1 --- /dev/null +++ b/polymer/eduke32/source/osdfuncs.h @@ -0,0 +1,8 @@ +void GAME_drawosdchar(int x, int y, char ch, int shade, int pal); +void GAME_drawosdstr(int x, int y, char *ch, int len, int shade, int pal); +void GAME_drawosdcursor(int x, int y, int type, int lastkeypress); +int GAME_getcolumnwidth(int w); +int GAME_getrowheight(int w); +void GAME_clearbackground(int c, int r); +void GAME_onshowosd(int shown); + diff --git a/polymer/eduke32/source/player.c b/polymer/eduke32/source/player.c new file mode 100644 index 000000000..dec88ea52 --- /dev/null +++ b/polymer/eduke32/source/player.c @@ -0,0 +1,5807 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +// Savage Baggage Masters + +#include "duke3d.h" + +long g_currentweapon; +long g_gun_pos; +long g_looking_arc; +long g_weapon_offset; +long g_gs; +long g_kb; +long g_looking_angSR1; +long g_weapon_xoffset; + +int32 turnheldtime; //MED +int32 lastcontroltime; //MED + +void setpal(struct player_struct *p) +{ + if(p->heat_on) p->palette = slimepal; + else if ((sector[p->cursectnum].ceilingpicnum >= FLOORSLIME)&&(sector[p->cursectnum].ceilingpicnum <=FLOORSLIME+2)) { + p->palette = slimepal; + } else { + if(sector[p->cursectnum].lotag == 2) p->palette = waterpal; + else p->palette = palette; + + } + restorepalette = 1; +} + +void fadepal(int r, int g, int b, int start, int end, int step) +{ + if (getrendermode() >= 3) return; + if (step > 0) for (; start < end; start += step) palto(r,g,b,start); + else for (; start >= end; start += step) palto(r,g,b,start); +} + +void incur_damage(short snum) +{ + long damage = 0L, shield_damage = 0L; + short i; + + struct player_struct *p; + + p = &ps[snum]; + + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_INCURDAMAGE, p->i, snum, -1); + + if(GetGameVarID(g_iReturnVarID,p->i,snum) == 0) + + { + sprite[p->i].extra -= p->extra_extra8>>8; + + damage = sprite[p->i].extra - p->last_extra; + + if ( damage < 0 ) + { + p->extra_extra8 = 0; + + if ( p->shield_amount > 0 ) + { + shield_damage = damage * (20 + (TRAND%30)) / 100; + damage -= shield_damage; + + p->shield_amount += shield_damage; + + if ( p->shield_amount < 0 ) + { + damage += p->shield_amount; + p->shield_amount = 0; + } + } + + sprite[p->i].extra = p->last_extra + damage; + } + + } + +} + +void quickkill(struct player_struct *p) +{ + p->pals[0] = 48; + p->pals[1] = 48; + p->pals[2] = 48; + p->pals_time = 48; + + sprite[p->i].extra = 0; + sprite[p->i].cstat |= 32768; + if(ud.god == 0) guts(&sprite[p->i],JIBS6,8,myconnectindex); + return; +} + +void forceplayerangle(struct player_struct *p) +{ + short n; + + n = 128-(TRAND&255); + + p->horiz += 64; + p->return_to_center = 9; + p->look_ang = n>>1; + p->rotscrnang = n>>1; +} + +void tracers(long x1,long y1,long z1,long x2,long y2,long z2,long n) +{ + long i, xv, yv, zv; + short sect = -1; + + i = n+1; + xv = (x2-x1)/i; + yv = (y2-y1)/i; + zv = (z2-z1)/i; + + if( ( klabs(x1-x2)+klabs(y1-y2) ) < 3084 ) + return; + + for(i=n;i>0;i--) + { + x1 += xv; + y1 += yv; + z1 += zv; + updatesector(x1,y1,§); + if(sect >= 0) + { + if(sector[sect].lotag == 2) + EGS(sect,x1,y1,z1,WATERBUBBLE,-32,4+(TRAND&3),4+(TRAND&3),TRAND&2047,0,0,ps[0].i,5); + else + EGS(sect,x1,y1,z1,SMALLSMOKE,-32,14,14,0,0,0,ps[0].i,5); + } + } +} + +void hitscantrail(long x1, long y1, long z1, long x2, long y2, long z2, short ang, short atwith) +{ + long xv, yv, zv, n, j, i; + short sect = -1; + + /* mathematical bullshit */ + + x1 += (sintable[(348+ang+512)&2047]/projectile[atwith].offset); + y1 += (sintable[(ang+348)&2047]/projectile[atwith].offset); + + /* find the distance between our player's projectile firing position and the impact point */ + + n = (FindDistance2D(x1-x2,y1-y2))/256; + + /* apply an offset if needed, defined in CONs */ + + z1 += (projectile[atwith].toffset<<8)+1024; + + /* figure out how much distance to put between each sprite */ + + xv = (x2-x1)/n; + yv = (y2-y1)/n; + zv = (z2-z1)/n; + + // Bsprintf(tempbuf,"%ld, %ld, %ld (%ld)",xv,yv,zv,n); + // AddLog(tempbuf); + + x1 += xv/4; + y1 += yv/4; + z1 += zv/4; + + /* spawn the trail sprites */ + + for(i=0;i= 0) + { + j = EGS(sect,x1,y1,z1,projectile[atwith].trail,-32,projectile[atwith].txrepeat,projectile[atwith].tyrepeat,ang,0,0,ps[0].i,0); + changespritestat(j,1); + } + else continue; + } +} + +long hits(short i) +{ + long sx,sy,sz; + short sect,hw,hs; + long zoff; + + if(PN == APLAYER) zoff = (40<<8); + else zoff = 0; + + hitscan(SX,SY,SZ-zoff,SECT, + sintable[(SA+512)&2047], + sintable[SA&2047], + 0,§,&hw,&hs,&sx,&sy,&sz,CLIPMASK1); + + return ( FindDistance2D( sx-SX,sy-SY ) ); +} + +long hitasprite(short i,short *hitsp) +{ + long sx,sy,sz,zoff; + short sect,hw; + + if(badguy(&sprite[i]) ) + zoff = (42<<8); + else if(PN == APLAYER) zoff = (39<<8); + else zoff = 0; + + hitscan(SX,SY,SZ-zoff,SECT, + sintable[(SA+512)&2047], + sintable[SA&2047], + 0,§,&hw,hitsp,&sx,&sy,&sz,CLIPMASK1); + + if(hw >= 0 && (wall[hw].cstat&16) && badguy(&sprite[i]) ) + return((1<<30)); + + return ( FindDistance2D(sx-SX,sy-SY) ); +} + +/* +long hitaspriteandwall(short i,short *hitsp,short *hitw,short *x, short *y) +{ + long sz; + short sect; + + hitscan(SX,SY,SZ,SECT, + sintable[(SA+512)&2047], + sintable[SA&2047], + 0,§,hitw,hitsp,x,y,&sz,CLIPMASK1); + + return ( FindDistance2D(*x-SX,*y-SY) ); +} +*/ + +long hitawall(struct player_struct *p,short *hitw) +{ + long sx,sy,sz; + short sect,hs; + + hitscan(p->posx,p->posy,p->posz,p->cursectnum, + sintable[(p->ang+512)&2047], + sintable[p->ang&2047], + 0,§,hitw,&hs,&sx,&sy,&sz,CLIPMASK0); + + return ( FindDistance2D(sx-p->posx,sy-p->posy) ); +} + +short aim(spritetype *s,short aang) +{ + char gotshrinker,gotfreezer; + short i, j, a, k, cans; + short aimstats[] = {10,13,1,2}; + long dx1, dy1, dx2, dy2, dx3, dy3, smax, sdist; + long xv, yv; + + a = s->ang; + + j = -1; + if(s->picnum == APLAYER && !ps[s->yvel].auto_aim) return -1; + + gotshrinker = s->picnum == APLAYER && *aplWeaponWorksLike[ps[s->yvel].curr_weapon] == SHRINKER_WEAPON; + gotfreezer = s->picnum == APLAYER && *aplWeaponWorksLike[ps[s->yvel].curr_weapon] == FREEZE_WEAPON; + + smax = 0x7fffffff; + + dx1 = sintable[(a+512-aang)&2047]; + dy1 = sintable[(a-aang)&2047]; + dx2 = sintable[(a+512+aang)&2047]; + dy2 = sintable[(a+aang)&2047]; + + dx3 = sintable[(a+512)&2047]; + dy3 = sintable[a&2047]; + + for(k=0;k<4;k++) + { + if( j >= 0 ) + break; + for(i=headspritestat[aimstats[k]];i >= 0;i=nextspritestat[i]) + if( sprite[i].xrepeat > 0 && sprite[i].extra >= 0 && (sprite[i].cstat&(257+32768)) == 257) + if( badguy(&sprite[i]) || k < 2 ) + { + if(badguy(&sprite[i]) || PN == APLAYER || PN == SHARK) + { + if( PN == APLAYER && + // ud.ffire == 0 && + (gametype_flags[ud.coop]& GAMETYPE_FLAG_PLAYERSFRIENDLY ) && + s->picnum == APLAYER && + s != &sprite[i]) + continue; + + if(gotshrinker && sprite[i].xrepeat < 30 ) + { + if (PN == SHARK) { + if(sprite[i].xrepeat < 20) continue; + continue; + } else if ((PN >= GREENSLIME)&&(PN <= GREENSLIME+7)) { + } else { + continue; + } + } + if(gotfreezer && sprite[i].pal == 1) continue; + } + + xv = (SX-s->x); + yv = (SY-s->y); + + if( (dy1*xv) <= (dx1*yv) ) + if( ( dy2*xv ) >= (dx2*yv) ) + { + sdist = mulscale(dx3,xv,14) + mulscale(dy3,yv,14); + if( sdist > 512 && sdist < smax ) + { + if(s->picnum == APLAYER) + a = (klabs(scale(SZ-s->z,10,sdist)-(ps[s->yvel].horiz+ps[s->yvel].horizoff-100)) < 100); + else a = 1; + + if(PN == ORGANTIC || PN == ROTATEGUN ) + cans = cansee(SX,SY,SZ,SECT,s->x,s->y,s->z-(32<<8),s->sectnum); + else cans = cansee(SX,SY,SZ-(32<<8),SECT,s->x,s->y,s->z-(32<<8),s->sectnum); + + if( a && cans ) + { + smax = sdist; + j = i; + } + } + } + } + } + + return j; +} + +short shoot(short i,short atwith) +{ + short sect, hitsect, hitspr, hitwall, l, sa, p, j, k, wh, scount; + long sx, sy, sz, vel, zvel, hitx, hity, hitz, x, oldzvel, dal; + unsigned char sizx,sizy; + spritetype *s; + + s = &sprite[i]; + sect = s->sectnum; + zvel = 0; + + if( s->picnum == APLAYER ) + { + p = s->yvel; + + sx = ps[p].posx; + sy = ps[p].posy; + sz = ps[p].posz+ps[p].pyoff+(4<<8); + sa = ps[p].ang; + + ps[p].crack_time = 777; + } + else + { + p = -1; + sa = s->ang; + sx = s->x; + sy = s->y; + sz = s->z-((s->yrepeat*tilesizy[s->picnum])<<1)+(4<<8); + if(s->picnum != ROTATEGUN) + { + sz -= (7<<8); + if(badguy(s) && PN != COMMANDER) + { + sx += (sintable[(sa+1024+96)&2047]>>7); + sy += (sintable[(sa+512+96)&2047]>>7); + } + } + } + + if(checkspriteflagsp(atwith,SPRITE_FLAG_PROJECTILE)) + { + /* Custom projectiles. This is a big hack. */ + + if (projectile[atwith].offset == 0) projectile[atwith].offset = 1; + + // writestring(sx,sy,sz,sect,sintable[(sa+512)&2047],sintable[sa&2047],zvel<<6); + if(projectile[atwith].workslike & PROJECTILE_FLAG_BLOOD || projectile[atwith].workslike & PROJECTILE_FLAG_KNEE) + { + + if(projectile[atwith].workslike & PROJECTILE_FLAG_BLOOD) + { + if(p >= 0) + sa += 64 - (TRAND&127); + else sa += 1024 + 64 - (TRAND&127); + zvel = 1024-(TRAND&2047); + } + + if(projectile[atwith].workslike & PROJECTILE_FLAG_KNEE) + { + if(p >= 0) + { + zvel = (100-ps[p].horiz-ps[p].horizoff)<<5; + sz += (6<<8); + sa += 15; + } + else if (!(projectile[atwith].workslike & PROJECTILE_FLAG_NOAIM)) + { + j = ps[findplayer(s,&x)].i; + zvel = ( (sprite[j].z-sz)<<8 ) / (x+1); + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + } + + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz,sect, + sintable[(sa+512)&2047], + sintable[sa&2047],zvel<<6, + &hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + + if(projectile[atwith].workslike & PROJECTILE_FLAG_BLOOD) + { + + if (projectile[atwith].range == 0) + projectile[atwith].range = 1024; + + if( FindDistance2D(sx-hitx,sy-hity) < projectile[atwith].range ) + if (FindDistance2D(wall[hitwall].x-wall[wall[hitwall].point2].x,wall[hitwall].y-wall[wall[hitwall].point2].y) > (mulscale(projectile[atwith].xrepeat+8,tilesizx[projectile[atwith].decal],3))) + if( hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE ) + if( ( wall[hitwall].nextsector >= 0 && hitsect >= 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + sector[hitsect].lotag == 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + (sector[hitsect].floorz-sector[wall[hitwall].nextsector].floorz) > (mulscale(projectile[atwith].yrepeat,tilesizy[projectile[atwith].decal],3)<<8) ) || + ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) ) + if( (wall[hitwall].cstat&16) == 0) + { + if(wall[hitwall].nextsector >= 0) + { + k = headspritesect[wall[hitwall].nextsector]; + while(k >= 0) + { + if(sprite[k].statnum == 3 && sprite[k].lotag == 13) + return 0; + k = nextspritesect[k]; + } + } + + if( wall[hitwall].nextwall >= 0 && + wall[wall[hitwall].nextwall].hitag != 0 ) + return 0; + + if(wall[hitwall].hitag == 0) + { + if(projectile[atwith].decal >= 0) + { + k = spawn(i,projectile[atwith].decal); + /* + sprite[k].xvel = -12; + sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x, + wall[hitwall].y-wall[wall[hitwall].point2].y)+512; + sprite[k].x = hitx; + sprite[k].y = hity; + sprite[k].z = hitz; + sprite[k].cstat |= (TRAND&4); + sprite[k].xrepeat = projectile[atwith].xrepeat; + sprite[k].yrepeat = projectile[atwith].yrepeat; + sprite[k].cstat = 16+(krand()&12); + ssp(k,CLIPMASK0); + setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z); + insertspriteq(k); + */ + + if(!spriteflags[projectile[atwith].decal] & SPRITE_FLAG_DECAL) + spriteflags[projectile[atwith].decal] |= SPRITE_FLAG_DECAL; + + k = spawn(i,projectile[atwith].decal); + sprite[k].xvel = -1; + sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x, + wall[hitwall].y-wall[wall[hitwall].point2].y)+512; + sprite[k].x = hitx; + sprite[k].y = hity; + sprite[k].z = hitz; + if(projectile[atwith].workslike & PROJECTILE_FLAG_RANDDECALSIZE) + { + wh = (TRAND&projectile[atwith].xrepeat); + if (wh < projectile[atwith].yrepeat) + wh = projectile[atwith].yrepeat; + sprite[k].xrepeat = wh; + sprite[k].yrepeat = wh; + } + else + { + sprite[k].xrepeat = projectile[atwith].xrepeat; + sprite[k].yrepeat = projectile[atwith].yrepeat; + } + sprite[k].z += sprite[k].yrepeat<<8; + // sprite[k].cstat = 16+(krand()&12); + sprite[k].cstat = 16; + + wh = (TRAND&1); + if (wh == 1) + sprite[k].cstat |= 4; + + wh = (TRAND&1); + if (wh == 1) + sprite[k].cstat |= 8; + + wh = sprite[k].sectnum; + sprite[k].shade = sector[wh].floorshade; + sprite[k].x -= mulscale13(1,sintable[(sprite[k].ang+2560)&2047]); + sprite[k].y -= mulscale13(1,sintable[(sprite[k].ang+2048)&2047]); + + ssp(k,CLIPMASK0); + insertspriteq(k); + changespritestat(k,5); + + } + // if( PN == OOZFILTER || PN == NEWBEAST ) + // sprite[k].pal = 6; + } + } + return 0; + } + + if(hitsect < 0) return 0; + + if ((projectile[atwith].range == 0) && (projectile[atwith].workslike & PROJECTILE_FLAG_KNEE)) + projectile[atwith].range = 1024; + + if( (projectile[atwith].range > 0) && (( klabs(sx-hitx)+klabs(sy-hity) ) > projectile[atwith].range) ) + return 0; + else + { + if(hitwall >= 0 || hitspr >= 0) + { + j = EGS(hitsect,hitx,hity,hitz,atwith,-15,0,0,sa,32,0,i,4); + thisprojectile[j].workslike = projectile[sprite[j].picnum].workslike; + sprite[j].extra = projectile[atwith].extra; + if(projectile[atwith].extra_rand > 0) + sprite[j].extra += (TRAND&projectile[atwith].extra_rand); + if(p >= 0) + { + if(projectile[atwith].spawns >= 0) + { + k = spawn(j,projectile[atwith].spawns); + sprite[k].z -= (8<<8); + } + if (projectile[atwith].sound > -1) spritesound(projectile[atwith].sound,j); + } + + if ( p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400 ) + sprite[j].extra += (max_player_health>>2); + + if( hitspr >= 0 && sprite[hitspr].picnum != ACCESSSWITCH && sprite[hitspr].picnum != ACCESSSWITCH2 ) + { + checkhitsprite(hitspr,j); + if(p >= 0) checkhitswitch(p,hitspr,1); + } + + else if( hitwall >= 0 ) + { + if( wall[hitwall].cstat&2 ) + if(wall[hitwall].nextsector >= 0) + if(hitz >= (sector[wall[hitwall].nextsector].floorz) ) + hitwall = wall[hitwall].nextwall; + + if( hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2 ) + { + checkhitwall(j,hitwall,hitx,hity,hitz,atwith); + if(p >= 0) checkhitswitch(p,hitwall,0); + } + } + } + else if(p >= 0 && zvel > 0 && sector[hitsect].lotag == 1) + { + j = spawn(ps[p].i,WATERSPLASH2); + sprite[j].x = hitx; + sprite[j].y = hity; + sprite[j].ang = ps[p].ang; // Total tweek + sprite[j].xvel = 32; + ssp(i,CLIPMASK0); + sprite[j].xvel = 0; + + } + } + return 0; + } + + + if(projectile[atwith].workslike & PROJECTILE_FLAG_BULLET) + { + + if( s->extra >= 0 ) s->shade = projectile[atwith].shade; + + if(p >= 0) + { + int angRange; + int zRange; + + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)+(5<<8); + if (((sprite[j].picnum >= GREENSLIME)&&(sprite[j].picnum <= GREENSLIME+7))||(sprite[j].picnum ==ROTATEGUN) ) + { + dal -= (8<<8); + return 0; + } + zvel = ( ( sprite[j].z-sz-dal )<<8 ) / ldist(&sprite[ps[p].i], &sprite[j]) ; + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + + angRange=32; + zRange=256; + SetGameVarID(g_iAngRangeVarID,32, i,p); + SetGameVarID(g_iZRangeVarID,256,i,p); + OnEvent(EVENT_GETSHOTRANGE, i,p, -1); + angRange=GetGameVarID(g_iAngRangeVarID,i,p); + zRange=GetGameVarID(g_iZRangeVarID,i,p); + + sa += (angRange/2)-(TRAND&(angRange-1)); + if(j == -1) + { + // no target + zvel = (100-ps[p].horiz-ps[p].horizoff)<<5; + } + zvel += (zRange/2)-(TRAND&(zRange-1)); + sz -= (2<<8); + } + else + { + j = findplayer(s,&x); + sz -= (4<<8); + zvel = ( (ps[j].posz-sz) <<8 ) / (ldist(&sprite[ps[j].i], s ) ); + if(s->picnum != BOSS1) + { + zvel += 128-(TRAND&255); + sa += 32-(TRAND&63); + } + else + { + zvel += 128-(TRAND&255); + sa = getangle(ps[j].posx-sx,ps[j].posy-sy)+64-(TRAND&127); + } + } + + if (projectile[atwith].cstat >= 0) s->cstat &= ~projectile[atwith].cstat; + else s->cstat &= ~257; + + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz,sect, + sintable[(sa+512)&2047], + sintable[sa&2047], + zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + + + if (projectile[atwith].cstat >= 0) s->cstat |= projectile[atwith].cstat; + else s->cstat |= 257; + + if(hitsect < 0) return 0; + + if( (projectile[atwith].range > 0) && (( klabs(sx-hitx)+klabs(sy-hity) ) > projectile[atwith].range) ) return 0; + + if (projectile[atwith].trail > -1) + hitscantrail(sx,sy,sz,hitx,hity,hitz,sa,atwith); + + if (projectile[atwith].workslike & PROJECTILE_FLAG_WATERBUBBLES) + { + if( (TRAND&15) == 0 && sector[hitsect].lotag == 2 ) + tracers(hitx,hity,hitz,sx,sy,sz,8-(ud.multimode>>1)); + } + + if(p >= 0) + { + k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,10,10,sa,0,0,i,4); + sprite[k].extra = projectile[atwith].extra; + sprite[k].yvel = atwith; // this is a hack to allow you to detect which weapon spawned a SHOTSPARK1 + hittype[k].temp_data[6] = hitwall; + hittype[k].temp_data[7] = hitsect; + hittype[k].temp_data[8] = hitspr; + + if(projectile[atwith].extra_rand > 0) + sprite[k].extra += (TRAND%projectile[atwith].extra_rand); + + if( hitwall == -1 && hitspr == -1) + { + if( zvel < 0 ) + { + if( sector[hitsect].ceilingstat&1 ) + { + sprite[k].xrepeat = 0; + sprite[k].yrepeat = 0; + return 0; + } + else + checkhitceiling(hitsect); + } + if (projectile[atwith].spawns >= 0) + { + wh=spawn(k,projectile[atwith].spawns); + if (projectile[atwith].sxrepeat > 4) sprite[wh].xrepeat=projectile[atwith].sxrepeat; + if (projectile[atwith].syrepeat > 4) sprite[wh].yrepeat=projectile[atwith].syrepeat; + } + } + + if(hitspr >= 0) + { + checkhitsprite(hitspr,k); + if( sprite[hitspr].picnum == APLAYER && (!(gametype_flags[ud.coop] & GAMETYPE_FLAG_COOP) || ud.ffire == 1) ) + { + l = spawn(k,JIBS6); + sprite[k].xrepeat = sprite[k].yrepeat = 0; + sprite[l].z += (4<<8); + sprite[l].xvel = 16; + sprite[l].xrepeat = sprite[l].yrepeat = 24; + sprite[l].ang += 64-(TRAND&127); + } + else { + if (projectile[atwith].spawns >= 0) + { + wh=spawn(k,projectile[atwith].spawns); + if (projectile[atwith].sxrepeat > 4) sprite[wh].xrepeat=projectile[atwith].sxrepeat; + if (projectile[atwith].syrepeat > 4) sprite[wh].yrepeat=projectile[atwith].syrepeat; + } + } + if(p >= 0 && ( + sprite[hitspr].picnum == DIPSWITCH || + sprite[hitspr].picnum == DIPSWITCH+1 || + sprite[hitspr].picnum == DIPSWITCH2 || + sprite[hitspr].picnum == DIPSWITCH2+1 || + sprite[hitspr].picnum == DIPSWITCH3 || + sprite[hitspr].picnum == DIPSWITCH3+1 || + sprite[hitspr].picnum == HANDSWITCH || + sprite[hitspr].picnum == HANDSWITCH+1) ) + { + checkhitswitch(p,hitspr,1); + return 0; + } + } + else if( hitwall >= 0 ) + { + if (projectile[atwith].spawns >= 0) + { + wh=spawn(k,projectile[atwith].spawns); + if (projectile[atwith].sxrepeat > 4) sprite[wh].xrepeat=projectile[atwith].sxrepeat; + if (projectile[atwith].syrepeat > 4) sprite[wh].yrepeat=projectile[atwith].syrepeat; + } + if( isadoorwall(wall[hitwall].picnum) == 1 ) + goto DOSKIPBULLETHOLE; + if(p >= 0 && ( + wall[hitwall].picnum == DIPSWITCH || + wall[hitwall].picnum == DIPSWITCH+1 || + wall[hitwall].picnum == DIPSWITCH2 || + wall[hitwall].picnum == DIPSWITCH2+1 || + wall[hitwall].picnum == DIPSWITCH3 || + wall[hitwall].picnum == DIPSWITCH3+1 || + wall[hitwall].picnum == HANDSWITCH || + wall[hitwall].picnum == HANDSWITCH+1) ) + { + checkhitswitch(p,hitwall,0); + return 0; + } + + if(wall[hitwall].hitag != 0 || ( wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0 ) ) + goto DOSKIPBULLETHOLE; + + if( hitsect >= 0 && sector[hitsect].lotag == 0 ) + if( wall[hitwall].overpicnum != BIGFORCE ) + if( (wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0 ) || + ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) ) + if( (wall[hitwall].cstat&16) == 0) + { + if(wall[hitwall].nextsector >= 0) + { + l = headspritesect[wall[hitwall].nextsector]; + while(l >= 0) + { + if(sprite[l].statnum == 3 && sprite[l].lotag == 13) + goto DOSKIPBULLETHOLE; + l = nextspritesect[l]; + } + } + + l = headspritestat[5]; + while(l >= 0) + { + if(sprite[l].picnum == projectile[atwith].decal) + if(dist(&sprite[l],&sprite[k]) < (12+(TRAND&7)) ) + goto DOSKIPBULLETHOLE; + l = nextspritestat[l]; + } + if (projectile[atwith].decal >= 0) + { + l = spawn(k,projectile[atwith].decal); + sprite[l].xvel = -1; + sprite[l].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x, + wall[hitwall].y-wall[wall[hitwall].point2].y)+512; + if(projectile[atwith].workslike & PROJECTILE_FLAG_RANDDECALSIZE) + { + wh = (TRAND&projectile[atwith].xrepeat); + if (wh < projectile[atwith].yrepeat) + wh = projectile[atwith].yrepeat; + sprite[l].xrepeat = wh; + sprite[l].yrepeat = wh; + } + else + { + sprite[l].xrepeat = projectile[atwith].xrepeat; + sprite[l].yrepeat = projectile[atwith].yrepeat; + } + sprite[l].cstat = 16+(krand()&12); + sprite[l].x -= mulscale13(1,sintable[(sprite[l].ang+2560)&2047]); + sprite[l].y -= mulscale13(1,sintable[(sprite[l].ang+2048)&2047]); + + ssp(l,CLIPMASK0); + insertspriteq(l); + } + } + +DOSKIPBULLETHOLE: + + if( wall[hitwall].cstat&2 ) + if(wall[hitwall].nextsector >= 0) + if(hitz >= (sector[wall[hitwall].nextsector].floorz) ) + hitwall = wall[hitwall].nextwall; + + checkhitwall(k,hitwall,hitx,hity,hitz,atwith); + } + } + else + { + k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,24,24,sa,0,0,i,4); + sprite[k].extra = projectile[atwith].extra; + sprite[k].yvel = atwith; // this is a hack to allow you to detect which weapon spawned a SHOTSPARK1 + hittype[k].temp_data[6] = hitwall; + hittype[k].temp_data[7] = hitsect; + hittype[k].temp_data[8] = hitspr; + + if( hitspr >= 0 ) + { + checkhitsprite(hitspr,k); + if( sprite[hitspr].picnum != APLAYER ) + { + if (projectile[atwith].spawns >= 0) + { + wh=spawn(k,projectile[atwith].spawns); + if (projectile[atwith].sxrepeat > 4) sprite[wh].xrepeat=projectile[atwith].sxrepeat; + if (projectile[atwith].syrepeat > 4) sprite[wh].yrepeat=projectile[atwith].syrepeat; + } + } + else sprite[k].xrepeat = sprite[k].yrepeat = 0; + } + else if( hitwall >= 0 ) + checkhitwall(k,hitwall,hitx,hity,hitz,atwith); + } + + if( (TRAND&255) < 4 ) + if (projectile[atwith].isound >= 0) + xyzsound(projectile[atwith].isound,k,hitx,hity,hitz); + + return 0; + } + + if(projectile[atwith].workslike & PROJECTILE_FLAG_RPG) + { + + /* if(projectile[atwith].workslike & PROJECTILE_FLAG_FREEZEBLAST) + sz += (3<<8);*/ + + if( s->extra >= 0 ) s->shade = projectile[atwith].shade; + + scount = 1; + vel = projectile[atwith].vel; + + j = -1; + + if(p >= 0) + { + // j = aim( s, AUTO_AIM_ANGLE ); // 48 + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)+(8<<8); + zvel = ( (sprite[j].z-sz-dal)*vel ) / ldist(&sprite[ps[p].i], &sprite[j]); + if( sprite[j].picnum != RECON ) + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + // else zvel = (100-ps[p].horiz-ps[p].horizoff)*81; + else zvel = ((100-ps[p].horiz-ps[p].horizoff)*(projectile[atwith].vel/8)); + if (projectile[atwith].sound > -1) spritesound(projectile[atwith].sound,i); + } + else + { + if (!(projectile[atwith].workslike & PROJECTILE_FLAG_NOAIM)) + { + j = findplayer(s,&x); + sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); + + l = ldist(&sprite[ps[j].i],s); + zvel = ( (ps[j].oposz-sz)*vel) / l; + + if( badguy(s) && (s->hitag&face_player_smart) ) + sa = s->ang+(TRAND&31)-16; + } + } + + + + if( p >= 0 && j >= 0) + l = j; + else l = -1; + + /* j = EGS(sect, + sx+(sintable[(348+sa+512)&2047]/448), + sy+(sintable[(sa+348)&2047]/448), + sz-(1<<8),atwith,0,14,14,sa,vel,zvel,i,4);*/ + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + j = EGS(sect, + sx+(sintable[(348+sa+512)&2047]/projectile[atwith].offset), + sy+(sintable[(sa+348)&2047]/projectile[atwith].offset), + sz-(1<<8),atwith,0,14,14,sa,vel,zvel,i,4); + + sprite[j].xrepeat=projectile[atwith].xrepeat; + sprite[j].yrepeat=projectile[atwith].yrepeat; + + + if(projectile[atwith].extra_rand > 0) + sprite[j].extra += (TRAND&projectile[atwith].extra_rand); + if(!(projectile[atwith].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS)) + sprite[j].yvel = l; + else + { + if (projectile[atwith].bounces >= 1) sprite[j].yvel = projectile[atwith].bounces; + else sprite[j].yvel = numfreezebounces; + // sprite[j].xrepeat >>= 1; + // sprite[j].yrepeat >>= 1; + sprite[j].zvel -= (2<<4); + } + /* + if(p == -1) + { + if(!(projectile[atwith].workslike & PROJECTILE_FLAG_BOUNCESOFFWALLS)) + { + sprite[j].xrepeat = projectile[atwith].xrepeat; // 30 + sprite[j].yrepeat = projectile[atwith].yrepeat; + sprite[j].extra >>= 2; + } + } + */ + if (projectile[atwith].cstat >= 0) sprite[j].cstat = projectile[atwith].cstat; + else sprite[j].cstat = 128; + if (projectile[atwith].clipdist >= 0) sprite[j].clipdist = projectile[atwith].clipdist; + else sprite[j].clipdist = 40; + + Bmemcpy(&thisprojectile[j], &projectile[sprite[j].picnum], sizeof(projectile[sprite[j].picnum])); + + // sa = s->ang+32-(TRAND&63); + // zvel = oldzvel+512-(TRAND&1023); + + return 0; + } + + } + + else + + { + switch(dynamictostatic[atwith]) + { + case BLOODSPLAT1__STATIC: + case BLOODSPLAT2__STATIC: + case BLOODSPLAT3__STATIC: + case BLOODSPLAT4__STATIC: + + if(p >= 0) + sa += 64 - (TRAND&127); + else sa += 1024 + 64 - (TRAND&127); + zvel = 1024-(TRAND&2047); + case KNEE__STATIC: + if(atwith == KNEE ) + { + if(p >= 0) + { + zvel = (100-ps[p].horiz-ps[p].horizoff)<<5; + sz += (6<<8); + sa += 15; + } + else + { + j = ps[findplayer(s,&x)].i; + zvel = ( (sprite[j].z-sz)<<8 ) / (x+1); + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + } + + // writestring(sx,sy,sz,sect,sintable[(sa+512)&2047],sintable[sa&2047],zvel<<6); + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz,sect, + sintable[(sa+512)&2047], + sintable[sa&2047],zvel<<6, + &hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + + if( atwith == BLOODSPLAT1 || atwith == BLOODSPLAT2 || atwith == BLOODSPLAT3 || atwith == BLOODSPLAT4 ) + { + if( FindDistance2D(sx-hitx,sy-hity) < 1024 ) + if( hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE ) + if( ( wall[hitwall].nextsector >= 0 && hitsect >= 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + sector[hitsect].lotag == 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + (sector[hitsect].floorz-sector[wall[hitwall].nextsector].floorz) > (16<<8) ) || + ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) ) + if( (wall[hitwall].cstat&16) == 0) + { + if(wall[hitwall].nextsector >= 0) + { + k = headspritesect[wall[hitwall].nextsector]; + while(k >= 0) + { + if(sprite[k].statnum == 3 && sprite[k].lotag == 13) + return 0; + k = nextspritesect[k]; + } + } + + if( wall[hitwall].nextwall >= 0 && + wall[wall[hitwall].nextwall].hitag != 0 ) + return 0; + + if(wall[hitwall].hitag == 0) + { + k = spawn(i,atwith); + sprite[k].xvel = -12; + sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x, + wall[hitwall].y-wall[wall[hitwall].point2].y)+512; + sprite[k].x = hitx; + sprite[k].y = hity; + sprite[k].z = hitz; + sprite[k].cstat |= (TRAND&4); + ssp(k,CLIPMASK0); + setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z); + if( PN == OOZFILTER || PN == NEWBEAST ) + sprite[k].pal = 6; + } + } + return 0; + } + + if(hitsect < 0) break; + + if( ( klabs(sx-hitx)+klabs(sy-hity) ) < 1024 ) + { + if(hitwall >= 0 || hitspr >= 0) + { + j = EGS(hitsect,hitx,hity,hitz,KNEE,-15,0,0,sa,32,0,i,4); + sprite[j].extra += (TRAND&7); + if(p >= 0) + { + k = spawn(j,SMALLSMOKE); + sprite[k].z -= (8<<8); + spritesound(KICK_HIT,j); + } + + if ( p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400 ) + sprite[j].extra += (max_player_health>>2); + + if( hitspr >= 0 && sprite[hitspr].picnum != ACCESSSWITCH && sprite[hitspr].picnum != ACCESSSWITCH2 ) + { + checkhitsprite(hitspr,j); + if(p >= 0) checkhitswitch(p,hitspr,1); + } + + else if( hitwall >= 0 ) + { + if( wall[hitwall].cstat&2 ) + if(wall[hitwall].nextsector >= 0) + if(hitz >= (sector[wall[hitwall].nextsector].floorz) ) + hitwall = wall[hitwall].nextwall; + + if( hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2 ) + { + checkhitwall(j,hitwall,hitx,hity,hitz,atwith); + if(p >= 0) checkhitswitch(p,hitwall,0); + } + } + } + else if(p >= 0 && zvel > 0 && sector[hitsect].lotag == 1) + { + j = spawn(ps[p].i,WATERSPLASH2); + sprite[j].x = hitx; + sprite[j].y = hity; + sprite[j].ang = ps[p].ang; // Total tweek + sprite[j].xvel = 32; + ssp(i,CLIPMASK0); + sprite[j].xvel = 0; + + } + } + + break; + + case SHOTSPARK1__STATIC: + case SHOTGUN__STATIC: + case CHAINGUN__STATIC: + + if( s->extra >= 0 ) s->shade = -96; + + if(p >= 0) + { + int angRange; + int zRange; + + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)+(5<<8); + if (((sprite[j].picnum>=GREENSLIME)&&(sprite[j].picnum<=GREENSLIME+7))||(sprite[j].picnum==ROTATEGUN)) { + + dal -= (8<<8); + + } + zvel = ( ( sprite[j].z-sz-dal )<<8 ) / ldist(&sprite[ps[p].i], &sprite[j]) ; + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + + angRange=32; + zRange=256; + SetGameVarID(g_iAngRangeVarID,32, i,p); + SetGameVarID(g_iZRangeVarID,256,i,p); + OnEvent(EVENT_GETSHOTRANGE, i,p, -1); + angRange=GetGameVarID(g_iAngRangeVarID,i,p); + zRange=GetGameVarID(g_iZRangeVarID,i,p); + + sa += (angRange/2)-(TRAND&(angRange-1)); + if(j == -1) + { + // no target + zvel = (100-ps[p].horiz-ps[p].horizoff)<<5; + } + zvel += (zRange/2)-(TRAND&(zRange-1)); + sz -= (2<<8); + } + else + { + j = findplayer(s,&x); + sz -= (4<<8); + zvel = ( (ps[j].posz-sz) <<8 ) / (ldist(&sprite[ps[j].i], s ) ); + if(s->picnum != BOSS1) + { + zvel += 128-(TRAND&255); + sa += 32-(TRAND&63); + } + else + { + zvel += 128-(TRAND&255); + sa = getangle(ps[j].posx-sx,ps[j].posy-sy)+64-(TRAND&127); + } + } + + s->cstat &= ~257; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz,sect, + sintable[(sa+512)&2047], + sintable[sa&2047], + zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + s->cstat |= 257; + + if(hitsect < 0) return 0; + + if( (TRAND&15) == 0 && sector[hitsect].lotag == 2 ) + tracers(hitx,hity,hitz,sx,sy,sz,8-(ud.multimode>>1)); + + if(p >= 0) + { + k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,10,10,sa,0,0,i,4); + sprite[k].extra = *actorscrptr[atwith]; + sprite[k].extra += (TRAND%6); + sprite[k].yvel = atwith; // this is a hack to allow you to detect which weapon spawned a SHOTSPARK1 + hittype[k].temp_data[6] = hitwall; + hittype[k].temp_data[7] = hitsect; + hittype[k].temp_data[8] = hitspr; + + + if( hitwall == -1 && hitspr == -1) + { + if( zvel < 0 ) + { + if( sector[hitsect].ceilingstat&1 ) + { + sprite[k].xrepeat = 0; + sprite[k].yrepeat = 0; + return 0; + } + else + checkhitceiling(hitsect); + } + spawn(k,SMALLSMOKE); + } + + if(hitspr >= 0) + { + checkhitsprite(hitspr,k); + if( sprite[hitspr].picnum == APLAYER && (!(gametype_flags[ud.coop]&GAMETYPE_FLAG_COOP ) || ud.ffire == 1) ) + { + l = spawn(k,JIBS6); + sprite[k].xrepeat = sprite[k].yrepeat = 0; + sprite[l].z += (4<<8); + sprite[l].xvel = 16; + sprite[l].xrepeat = sprite[l].yrepeat = 24; + sprite[l].ang += 64-(TRAND&127); + } + else spawn(k,SMALLSMOKE); + + if(p >= 0 && ( + sprite[hitspr].picnum == DIPSWITCH || + sprite[hitspr].picnum == DIPSWITCH+1 || + sprite[hitspr].picnum == DIPSWITCH2 || + sprite[hitspr].picnum == DIPSWITCH2+1 || + sprite[hitspr].picnum == DIPSWITCH3 || + sprite[hitspr].picnum == DIPSWITCH3+1 || + sprite[hitspr].picnum == HANDSWITCH || + sprite[hitspr].picnum == HANDSWITCH+1) ) + { + checkhitswitch(p,hitspr,1); + return 0; + } + } + else if( hitwall >= 0 ) + { + spawn(k,SMALLSMOKE); + + if( isadoorwall(wall[hitwall].picnum) == 1 ) + goto SKIPBULLETHOLE; + if(p >= 0 && ( + wall[hitwall].picnum == DIPSWITCH || + wall[hitwall].picnum == DIPSWITCH+1 || + wall[hitwall].picnum == DIPSWITCH2 || + wall[hitwall].picnum == DIPSWITCH2+1 || + wall[hitwall].picnum == DIPSWITCH3 || + wall[hitwall].picnum == DIPSWITCH3+1 || + wall[hitwall].picnum == HANDSWITCH || + wall[hitwall].picnum == HANDSWITCH+1) ) + { + checkhitswitch(p,hitwall,0); + return 0; + } + + if(wall[hitwall].hitag != 0 || ( wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0 ) ) + goto SKIPBULLETHOLE; + + if( hitsect >= 0 && sector[hitsect].lotag == 0 ) + if( wall[hitwall].overpicnum != BIGFORCE ) + if( (wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0 ) || + ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) ) + if( (wall[hitwall].cstat&16) == 0) + { + if(wall[hitwall].nextsector >= 0) + { + l = headspritesect[wall[hitwall].nextsector]; + while(l >= 0) + { + if(sprite[l].statnum == 3 && sprite[l].lotag == 13) + goto SKIPBULLETHOLE; + l = nextspritesect[l]; + } + } + + l = headspritestat[5]; + while(l >= 0) + { + if(sprite[l].picnum == BULLETHOLE) + if(dist(&sprite[l],&sprite[k]) < (12+(TRAND&7)) ) + goto SKIPBULLETHOLE; + l = nextspritestat[l]; + } + l = spawn(k,BULLETHOLE); + sprite[l].xvel = -1; + sprite[l].x = hitx; + sprite[l].y = hity; + sprite[l].z = hitz; + + sprite[l].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x, + wall[hitwall].y-wall[wall[hitwall].point2].y)+512; + + sprite[l].x -= mulscale13(1,sintable[(sprite[l].ang+2560)&2047]); + sprite[l].y -= mulscale13(1,sintable[(sprite[l].ang+2048)&2047]); + ssp(l,CLIPMASK0); + } + +SKIPBULLETHOLE: + + if( wall[hitwall].cstat&2 ) + if(wall[hitwall].nextsector >= 0) + if(hitz >= (sector[wall[hitwall].nextsector].floorz) ) + hitwall = wall[hitwall].nextwall; + + checkhitwall(k,hitwall,hitx,hity,hitz,SHOTSPARK1); + } + } + else + { + k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,24,24,sa,0,0,i,4); + sprite[k].extra = *actorscrptr[atwith]; + sprite[k].yvel = atwith; // this is a hack to allow you to detect which weapon spawned a SHOTSPARK1 + hittype[k].temp_data[6] = hitwall; + hittype[k].temp_data[7] = hitsect; + hittype[k].temp_data[8] = hitspr; + + if( hitspr >= 0 ) + { + checkhitsprite(hitspr,k); + if( sprite[hitspr].picnum != APLAYER ) + spawn(k,SMALLSMOKE); + else sprite[k].xrepeat = sprite[k].yrepeat = 0; + } + else if( hitwall >= 0 ) + checkhitwall(k,hitwall,hitx,hity,hitz,SHOTSPARK1); + } + + if( (TRAND&255) < 4 ) + xyzsound(PISTOL_RICOCHET,k,hitx,hity,hitz); + + return 0; + + case FIRELASER__STATIC: + case SPIT__STATIC: + case COOLEXPLOSION1__STATIC: + + if( s->extra >= 0 ) s->shade = -96; + + scount = 1; + if(atwith == SPIT) vel = 292; + else + { + if(atwith == COOLEXPLOSION1) + { + if(s->picnum == BOSS2) vel = 644; + else vel = 348; + sz -= (4<<7); + } + else + { + vel = 840; + sz -= (4<<7); + } + } + + if(p >= 0) + { + // j = aim( s, AUTO_AIM_ANGLE ); + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)-(12<<8); + zvel = ((sprite[j].z-sz-dal)*vel ) / ldist(&sprite[ps[p].i], &sprite[j]) ; + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + else + zvel = (100-ps[p].horiz-ps[p].horizoff)*98; + } + else + { + j = findplayer(s,&x); + // sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); + sa += 16-(TRAND&31); + zvel = ( ( (ps[j].oposz - sz + (3<<8) ) )*vel ) / ldist(&sprite[ps[j].i],s); + } + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + oldzvel = zvel; + + if(atwith == SPIT) { sizx = 18;sizy = 18,sz -= (10<<8); } + else + { + if( atwith == FIRELASER ) + { + if(p >= 0) + { + + sizx = 34; + sizy = 34; + } + else + { + sizx = 18; + sizy = 18; + } + } + else + { + sizx = 18; + sizy = 18; + } + } + + if(p >= 0) sizx = 7,sizy = 7; + + while(scount > 0) + { + j = EGS(sect,sx,sy,sz,atwith,-127,sizx,sizy,sa,vel,zvel,i,4); + sprite[j].extra += (TRAND&7); + + if(atwith == COOLEXPLOSION1) + { + sprite[j].shade = 0; + if(PN == BOSS2) + { + l = sprite[j].xvel; + sprite[j].xvel = 1024; + ssp(j,CLIPMASK0); + sprite[j].xvel = l; + sprite[j].ang += 128-(TRAND&255); + } + } + + sprite[j].cstat = 128; + sprite[j].clipdist = 4; + + sa = s->ang+32-(TRAND&63); + zvel = oldzvel+512-(TRAND&1023); + + scount--; + } + + return 0; + + case FREEZEBLAST__STATIC: + sz += (3<<8); + case RPG__STATIC: + + if( s->extra >= 0 ) s->shade = -96; + + scount = 1; + vel = 644; + + j = -1; + + if(p >= 0) + { + // j = aim( s, AUTO_AIM_ANGLE ); // 48 + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)+(8<<8); + zvel = ( (sprite[j].z-sz-dal)*vel ) / ldist(&sprite[ps[p].i], &sprite[j]); + if( sprite[j].picnum != RECON ) + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + else zvel = (100-ps[p].horiz-ps[p].horizoff)*81; + if(atwith == RPG) + spritesound(RPG_SHOOT,i); + + } + else + { + j = findplayer(s,&x); + sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); + if(PN == BOSS3) + sz -= (32<<8); + else if(PN == BOSS2) + { + vel += 128; + sz += 24<<8; + } + + l = ldist(&sprite[ps[j].i],s); + zvel = ( (ps[j].oposz-sz)*vel) / l; + + if( badguy(s) && (s->hitag&face_player_smart) ) + sa = s->ang+(TRAND&31)-16; + } + + if( p >= 0 && j >= 0) + l = j; + else l = -1; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + j = EGS(sect, + sx+(sintable[(348+sa+512)&2047]/448), + sy+(sintable[(sa+348)&2047]/448), + sz-(1<<8),atwith,0,14,14,sa,vel,zvel,i,4); + + sprite[j].extra += (TRAND&7); + if(atwith != FREEZEBLAST) + sprite[j].yvel = l; + else + { + sprite[j].yvel = numfreezebounces; + sprite[j].xrepeat >>= 1; + sprite[j].yrepeat >>= 1; + sprite[j].zvel -= (2<<4); + } + + if(p == -1) + { + if(PN == BOSS3) + { + if(TRAND&1) + { + sprite[j].x -= sintable[sa&2047]>>6; + sprite[j].y -= sintable[(sa+1024+512)&2047]>>6; + sprite[j].ang -= 8; + } + else + { + sprite[j].x += sintable[sa&2047]>>6; + sprite[j].y += sintable[(sa+1024+512)&2047]>>6; + sprite[j].ang += 4; + } + sprite[j].xrepeat = 42; + sprite[j].yrepeat = 42; + } + else if(PN == BOSS2) + { + sprite[j].x -= sintable[sa&2047]/56; + sprite[j].y -= sintable[(sa+1024+512)&2047]/56; + sprite[j].ang -= 8+(TRAND&255)-128; + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + } + else if(atwith != FREEZEBLAST) + { + sprite[j].xrepeat = 30; + sprite[j].yrepeat = 30; + sprite[j].extra >>= 2; + } + } + + else if(*aplWeaponWorksLike[ps[p].curr_weapon] == DEVISTATOR_WEAPON) + { + sprite[j].extra >>= 2; + sprite[j].ang += 16-(TRAND&31); + sprite[j].zvel += 256-(TRAND&511); + + if( ps[p].hbomb_hold_delay ) + { + sprite[j].x -= sintable[sa&2047]/644; + sprite[j].y -= sintable[(sa+1024+512)&2047]/644; + } + else + { + sprite[j].x += sintable[sa&2047]>>8; + sprite[j].y += sintable[(sa+1024+512)&2047]>>8; + } + sprite[j].xrepeat >>= 1; + sprite[j].yrepeat >>= 1; + } + + sprite[j].cstat = 128; + if(atwith == RPG) + sprite[j].clipdist = 4; + else + sprite[j].clipdist = 40; + + break; + + case HANDHOLDINGLASER__STATIC: + + if(p >= 0) + zvel = (100-ps[p].horiz-ps[p].horizoff)*32; + else zvel = 0; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz-ps[p].pyoff,sect, + sintable[(sa+512)&2047], + sintable[sa&2047], + zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + + j = 0; + if(hitspr >= 0) break; + + if(hitwall >= 0 && hitsect >= 0) + if( ((hitx-sx)*(hitx-sx)+(hity-sy)*(hity-sy)) < (290*290) ) + { + if( wall[hitwall].nextsector >= 0) + { + if( sector[wall[hitwall].nextsector].lotag <= 2 && sector[hitsect].lotag <= 2 ) + j = 1; + } + else if( sector[hitsect].lotag <= 2 ) + j = 1; + } + + if(j == 1) + { + long lTripBombControl=GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, ps[p].i, p); + k = EGS(hitsect,hitx,hity,hitz,TRIPBOMB,-16,4,5,sa,0,0,i,6); + if(lTripBombControl & TRIPBOMB_TIMER) + { + long lLifetime=GetGameVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, ps[p].i, p); + long lLifetimeVar=GetGameVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, ps[p].i, p); + // set timer. blows up when at zero.... + hittype[k].temp_data[7]=lLifetime + + mulscale(krand(),lLifetimeVar, 14) + - lLifetimeVar; + hittype[k].temp_data[6]=1; + } + else + + sprite[k].hitag = k; + spritesound(LASERTRIP_ONWALL,k); + sprite[k].xvel = -20; + ssp(k,CLIPMASK0); + sprite[k].cstat = 16; + hittype[k].temp_data[5] = sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x,wall[hitwall].y-wall[wall[hitwall].point2].y)-512; + + + } + return 0; + + case BOUNCEMINE__STATIC: + case MORTER__STATIC: + + if( s->extra >= 0 ) s->shade = -96; + + j = ps[findplayer(s,&x)].i; + x = ldist(&sprite[j],s); + + zvel = -x>>1; + + if(zvel < -4096) + zvel = -2048; + vel = x>>4; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + EGS(sect, + sx+(sintable[(512+sa+512)&2047]>>8), + sy+(sintable[(sa+512)&2047]>>8), + sz+(6<<8),atwith,-64,32,32,sa,vel,zvel,i,1); + break; + + case GROWSPARK__STATIC: + + if(p >= 0) + { + // j = aim( s, AUTO_AIM_ANGLE ); + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1)+(5<<8); + if (((sprite[j].picnum >= GREENSLIME)&&(sprite[j].picnum <= GREENSLIME+7))||(sprite[j].picnum ==ROTATEGUN) ) { + dal -= (8<<8); + + } + zvel = ( ( sprite[j].z-sz-dal )<<8 ) / (ldist(&sprite[ps[p].i], &sprite[j]) ); + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + else + { + sa += 16-(TRAND&31); + zvel = (100-ps[p].horiz-ps[p].horizoff)<<5; + zvel += 128-(TRAND&255); + } + + sz -= (2<<8); + } + else + { + j = findplayer(s,&x); + sz -= (4<<8); + zvel = ( (ps[j].posz-sz) <<8 ) / (ldist(&sprite[ps[j].i], s ) ); + zvel += 128-(TRAND&255); + sa += 32-(TRAND&63); + } + + k = 0; + + // RESHOOTGROW: + + s->cstat &= ~257; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + hitscan(sx,sy,sz,sect, + sintable[(sa+512)&2047], + sintable[sa&2047], + zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1); + + s->cstat |= 257; + + j = EGS(sect,hitx,hity,hitz,GROWSPARK,-16,28,28,sa,0,0,i,1); + + sprite[j].pal = 2; + sprite[j].cstat |= 130; + sprite[j].xrepeat = sprite[j].yrepeat = 1; + + if( hitwall == -1 && hitspr == -1 && hitsect >= 0) + { + if( zvel < 0 && (sector[hitsect].ceilingstat&1) == 0) + checkhitceiling(hitsect); + } + else if(hitspr >= 0) checkhitsprite(hitspr,j); + else if(hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2 ) + { + /* if(wall[hitwall].overpicnum == MIRROR && k == 0) + { + l = getangle( + wall[wall[hitwall].point2].x-wall[hitwall].x, + wall[wall[hitwall].point2].y-wall[hitwall].y); + + sx = hitx; + sy = hity; + sz = hitz; + sect = hitsect; + sa = ((l<<1) - sa)&2047; + sx += sintable[(sa+512)&2047]>>12; + sy += sintable[sa&2047]>>12; + + k++; + goto RESHOOTGROW; + } + else */ + checkhitwall(j,hitwall,hitx,hity,hitz,atwith); + } + + break; + + case SHRINKER__STATIC: + if( s->extra >= 0 ) s->shade = -96; + if(p >= 0) + { + // j = aim( s, AUTO_AIM_ANGLE ); + SetGameVarID(g_iAimAngleVarID,AUTO_AIM_ANGLE,i,p); + OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1); + j=-1; + if( GetGameVarID(g_iAimAngleVarID,i,p) > 0 ) + { + j = aim( s, GetGameVarID(g_iAimAngleVarID,i,p)); + } + + if(j >= 0) + { + dal = ((sprite[j].xrepeat*tilesizy[sprite[j].picnum])<<1); + zvel = ( (sprite[j].z-sz-dal-(4<<8))*768) / (ldist( &sprite[ps[p].i], &sprite[j])); + sa = getangle(sprite[j].x-sx,sprite[j].y-sy); + } + else zvel = (100-ps[p].horiz-ps[p].horizoff)*98; + } + else if(s->statnum != 3) + { + j = findplayer(s,&x); + l = ldist(&sprite[ps[j].i],s); + zvel = ( (ps[j].oposz-sz)*512) / l ; + } + else zvel = 0; + if (hittype[i].temp_data[9]) zvel = hittype[i].temp_data[9]; + j = EGS(sect, + sx+(sintable[(512+sa+512)&2047]>>12), + sy+(sintable[(sa+512)&2047]>>12), + sz+(2<<8),SHRINKSPARK,-16,28,28,sa,768,zvel,i,4); + + sprite[j].cstat = 128; + sprite[j].clipdist = 32; + + + return 0; + } + } + return (long) s; +} + +void displayloogie(short snum) +{ + long i, a, x, y, z; + + if(ps[snum].loogcnt == 0) return; + + y = (ps[snum].loogcnt<<2); + for(i=0;i>5; + z = 4096+((ps[snum].loogcnt+i)<<9); + x = (-sync[snum].avel)+(sintable[((ps[snum].loogcnt+i)<<6)&2047]>>10); + + rotatesprite( + (ps[snum].loogiex[i]+x)<<16,(200+ps[snum].loogiey[i]-y)<<16,z-(i<<8),256-a, + LOOGIE,0,0,2,0,0,xdim-1,ydim-1); + } +} + +char animatefist(short gs,short snum) +{ + short looking_arc,fisti,fistpal; + long fistzoom, fistz; + + fisti = ps[snum].fist_incs; + if(fisti > 32) fisti = 32; + if(fisti <= 0) return 0; + + looking_arc = klabs(ps[snum].look_ang)/9; + + fistzoom = 65536L - (sintable[(512+(fisti<<6))&2047]<<2); + if(fistzoom > 90612L) + fistzoom = 90612L; + if(fistzoom < 40920) + fistzoom = 40290; + fistz = 194 + (sintable[((6+fisti)<<7)&2047]>>9); + + if(sprite[ps[snum].i].pal == 1) + fistpal = 1; + else + fistpal = sector[ps[snum].cursectnum].floorpal; + + rotatesprite( + (-fisti+222+(sync[snum].avel>>4))<<16, + (looking_arc+fistz)<<16, + fistzoom,0,FIST,gs,fistpal,2,0,0,xdim-1,ydim-1); + + return 1; +} + +char animateknee(short gs,short snum) +{ + short knee_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-72,-32,-8}; + short looking_arc, pal; + + if(ps[snum].knee_incs > 11 || ps[snum].knee_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0; + + looking_arc = knee_y[ps[snum].knee_incs] + klabs(ps[snum].look_ang)/9; + + looking_arc -= (ps[snum].hard_landing<<3); + + if(sprite[ps[snum].i].pal == 1) + pal = 1; + else + { + pal = sector[ps[snum].cursectnum].floorpal; + if(pal == 0) + pal = ps[snum].palookup; + } + + myospal(105+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(knee_y[ps[snum].knee_incs]>>2),looking_arc+280-((ps[snum].horiz-ps[snum].horizoff)>>4),KNEE,gs,4,pal); + + return 1; +} + +char animateknuckles(short gs,short snum) +{ + short knuckle_frames[] = {0,1,2,2,3,3,3,2,2,1,0}; + short looking_arc, pal; + + if(ps[snum].knuckle_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0; + + looking_arc = klabs(ps[snum].look_ang)/9; + + looking_arc -= (ps[snum].hard_landing<<3); + + if(sprite[ps[snum].i].pal == 1) + pal = 1; + else + pal = sector[ps[snum].cursectnum].floorpal; + + myospal(160+(sync[snum].avel>>4)-(ps[snum].look_ang>>1),looking_arc+180-((ps[snum].horiz-ps[snum].horizoff)>>4),CRACKKNUCKLES+knuckle_frames[ps[snum].knuckle_incs>>1],gs,4,pal); + + return 1; +} + +long lastvisinc; + +void DoFire(short snum) +{ + int i; + + struct player_struct *p; + p = &ps[snum]; + + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_DOFIRE, p->i, snum, -1); + + if(GetGameVarID(g_iReturnVarID,p->i,snum) == 0) + { + if (p->weapon_pos != 0) return; + + // if ((aplWeaponWorksLike[p->curr_weapon][snum]!=KNEE_WEAPON) && (p->ammo_amount[p->curr_weapon] == 0)) + // return; + + //AddLog("DoFire()"); + if(aplWeaponWorksLike[p->curr_weapon][snum]!=KNEE_WEAPON) + { + //Bsprintf(g_szBuf,"%d: using Ammo. was: %d",p->curr_weapon,p->ammo_amount[p->curr_weapon]); + // AddLog(g_szBuf); + p->ammo_amount[p->curr_weapon]--; + } + + if(aplWeaponFireSound[p->curr_weapon][snum]) + { + //Bsprintf(g_szBuf,"DoFire():firesound(%ld)",aplWeaponFireSound[p->curr_weapon][snum]); + //AddLog(g_szBuf); + spritesound(aplWeaponFireSound[p->curr_weapon][snum],p->i); + } + + SetGameVarID(g_iWeaponVarID,p->curr_weapon,p->i,snum); + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + //Bsprintf(g_szBuf,"DoFire():shoot(%ld)",aplWeaponShoots[p->curr_weapon][snum]); + //AddLog(g_szBuf); + shoot(p->i,aplWeaponShoots[p->curr_weapon][snum]); + for(i=1;icurr_weapon][snum];i++) + { + //Bsprintf(g_szBuf,"DoFire():shoot(%ld)",aplWeaponShoots[p->curr_weapon][snum]); + //AddLog(g_szBuf); + + if(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_AMMOPERSHOT) + { + if(p->ammo_amount[p->curr_weapon] > 0) + { + p->ammo_amount[p->curr_weapon]--; + shoot(p->i,aplWeaponShoots[p->curr_weapon][snum]); + } + } + else + { + shoot(p->i,aplWeaponShoots[p->curr_weapon][snum]); + } + } + + if(! (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_NOVISIBLE )) + { + // make them visible if not set... + lastvisinc = totalclock+32; + p->visibility = 0; + } + + if( //!(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_CHECKATRELOAD) && + aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum] + && p->ammo_amount[p->curr_weapon] > 0 + && (aplWeaponClip[p->curr_weapon][snum]) + && ((p->ammo_amount[p->curr_weapon]%(aplWeaponClip[p->curr_weapon][snum]))==0) + ) + { + //AddLog("DoFire():ClipCheck"); + // do clip check... + p->kickback_pic=aplWeaponTotalTime[p->curr_weapon][snum]; + // is same as (*kb).... + } + + //Bsprintf(g_szBuf,"%d: Do fire: exit ammo: %d",p->curr_weapon,p->ammo_amount[p->curr_weapon]); + //AddLog(g_szBuf); + } +} + +void DoSpawn(short snum) +{ + int j; + + struct player_struct *p; + p = &ps[snum]; + + if(!aplWeaponSpawn[p->curr_weapon][snum]) + return; + + j = spawn(p->i, aplWeaponSpawn[p->curr_weapon][snum]); + + /* if((aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_SPAWNTYPE2 ) ) + { + // like shotgun shells + // p->kickback_pic++; + } + else */ + if((aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_SPAWNTYPE3 ) ) + { + // like chaingun shells + sprite[j].ang += 1024; + sprite[j].ang &= 2047; + sprite[j].xvel += 32; + sprite[j].z += (3<<8); + } + + ssp(j,CLIPMASK0); + +} + +void displaymasks(short snum) +{ + short i, p; + + if(sprite[ps[snum].i].pal == 1) + p = 1; + else + p = sector[ps[snum].cursectnum].floorpal; + + if(ps[snum].scuba_on) + { + if(ud.screen_size > 4) + { + rotatesprite(43<<16,(200-8-tilesizy[SCUBAMASK])<<16,65536,0,SCUBAMASK,0,p,2+16,windowx1,windowy1,windowx2,windowy2); + rotatesprite((320-43)<<16,(200-8-tilesizy[SCUBAMASK])<<16,65536,1024,SCUBAMASK,0,p,2+4+16,windowx1,windowy1,windowx2,windowy2); + } + else + { + rotatesprite(43<<16,(200-tilesizy[SCUBAMASK])<<16,65536,0,SCUBAMASK,0,p,2+16,windowx1,windowy1,windowx2,windowy2); + rotatesprite((320-43)<<16,(200-tilesizy[SCUBAMASK])<<16,65536,1024,SCUBAMASK,0,p,2+4+16,windowx1,windowy1,windowx2,windowy2); + } + } +} + +char animatetip(short gs,short snum) +{ + short p,looking_arc; + short tip_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16}; + + if(ps[snum].tipincs == 0) return 0; + + looking_arc = klabs(ps[snum].look_ang)/9; + looking_arc -= (ps[snum].hard_landing<<3); + + if(sprite[ps[snum].i].pal == 1) + p = 1; + else + p = sector[ps[snum].cursectnum].floorpal; + + /* if(ps[snum].access_spritenum >= 0) + p = sprite[ps[snum].access_spritenum].pal; + else + p = wall[ps[snum].access_wallnum].pal; + */ + myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1), + (tip_y[ps[snum].tipincs]>>1)+looking_arc+240-((ps[snum].horiz-ps[snum].horizoff)>>4),TIP+((26-ps[snum].tipincs)>>4),gs,0,p); + + return 1; +} + +char animateaccess(short gs,short snum) +{ + short access_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16}; + short looking_arc; + char p; + + if(ps[snum].access_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0; + + looking_arc = access_y[ps[snum].access_incs] + klabs(ps[snum].look_ang)/9; + looking_arc -= (ps[snum].hard_landing<<3); + + if(ps[snum].access_spritenum >= 0) + p = sprite[ps[snum].access_spritenum].pal; + else p = 0; + // else + // p = wall[ps[snum].access_wallnum].pal; + + if((ps[snum].access_incs-3) > 0 && (ps[snum].access_incs-3)>>3) + myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(access_y[ps[snum].access_incs]>>2),looking_arc+266-((ps[snum].horiz-ps[snum].horizoff)>>4),HANDHOLDINGLASER+(ps[snum].access_incs>>3),gs,0,p); + else + myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(access_y[ps[snum].access_incs]>>2),looking_arc+266-((ps[snum].horiz-ps[snum].horizoff)>>4),HANDHOLDINGACCESS,gs,4,p); + + return 1; +} + +short fistsign; + +void displayweapon(short snum) +{ + long gun_pos, looking_arc, cw; + long weapon_xoffset, i, j, x1, y1, x2; + char o,pal; + signed char gs; + struct player_struct *p; + short *kb; + + p = &ps[snum]; + kb = &p->kickback_pic; + + o = 0; + + looking_arc = klabs(p->look_ang)/9; + + gs = sprite[p->i].shade; + if(gs > 24) gs = 24; + + if(p->newowner >= 0 || ud.camerasprite >= 0 || p->over_shoulder_on > 0 || (sprite[p->i].pal != 1 && sprite[p->i].extra <= 0) || animatefist(gs,snum) || animateknuckles(gs,snum) || animatetip(gs,snum) || animateaccess(gs,snum) ) + return; + + animateknee(gs,snum); + + gun_pos = 80-(p->weapon_pos*p->weapon_pos); + + weapon_xoffset = (160)-90; + weapon_xoffset -= (sintable[((p->weapon_sway>>1)+512)&2047]/(1024+512)); + weapon_xoffset -= 58 + p->weapon_ang; + if( sprite[p->i].xrepeat < 32 ) + gun_pos -= klabs(sintable[(p->weapon_sway<<2)&2047]>>9); + else gun_pos -= klabs(sintable[(p->weapon_sway>>1)&2047]>>10); + + gun_pos -= (p->hard_landing<<3); + + if(p->last_weapon >= 0) + { + cw = aplWeaponWorksLike[p->last_weapon][snum]; + } + else + { + cw = aplWeaponWorksLike[p->curr_weapon][snum]; + } + + g_gun_pos=gun_pos; + g_looking_arc=looking_arc; + g_currentweapon=cw; + g_weapon_xoffset=weapon_xoffset; + g_gs=gs; + g_kb=*kb; + g_looking_angSR1=p->look_ang>>1; + + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_DISPLAYWEAPON, p->i, screenpeek, -1); + + if(GetGameVarID(g_iReturnVarID,p->i,snum) == 0) + { + j = 14-p->quick_kick; + if(j != 14) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + { + pal = sector[p->cursectnum].floorpal; + if(pal == 0) + pal = p->palookup; + } + + + if( j < 5 || j > 9 ) + myospal(weapon_xoffset+80-(p->look_ang>>1), + looking_arc+250-gun_pos,KNEE,gs,o|4,pal); + else myospal(weapon_xoffset+160-16-(p->look_ang>>1), + looking_arc+214-gun_pos,KNEE+1,gs,o|4,pal); + } + + if( sprite[p->i].xrepeat < 40 ) + { + if(p->jetpack_on == 0 ) + { + i = sprite[p->i].xvel; + looking_arc += 32-(i>>1); + fistsign += i>>1; + } + cw = weapon_xoffset; + weapon_xoffset += sintable[(fistsign)&2047]>>10; + myos(weapon_xoffset+250-(p->look_ang>>1), + looking_arc+258-(klabs(sintable[(fistsign)&2047]>>8)), + FIST,gs,o); + weapon_xoffset = cw; + weapon_xoffset -= sintable[(fistsign)&2047]>>10; + myos(weapon_xoffset+40-(p->look_ang>>1), + looking_arc+200+(klabs(sintable[(fistsign)&2047]>>8)), + FIST,gs,o|4); + } + else switch(cw) + + { + + case KNEE_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if( (*kb) > 0 ) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + { + pal = sector[p->cursectnum].floorpal; + if(pal == 0) + pal = p->palookup; + } + + if(*aplWeaponRenderSize[KNEE_WEAPON] == 0) + { + if( (*kb) < 5 || (*kb) > 9 ) + myospal(weapon_xoffset+220-(p->look_ang>>1), + looking_arc+250-gun_pos,KNEE,gs,o,pal); + else + myospal(weapon_xoffset+160-(p->look_ang>>1), + looking_arc+214-gun_pos,KNEE+1,gs,o,pal); + } + else + { + if( (*kb) < 5 || (*kb) > 9 ) + myospalx(weapon_xoffset+220-(p->look_ang>>1), + looking_arc+250-gun_pos,KNEE,gs,o,pal); + else + myospalx(weapon_xoffset+160-(p->look_ang>>1), + looking_arc+214-gun_pos,KNEE+1,gs,o,pal); + } + } + } + break; + + case TRIPBOMB_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + weapon_xoffset += 8; + gun_pos -= 10; + + if(*aplWeaponRenderSize[TRIPBOMB_WEAPON] == 0) + { + if((*kb) > 6) + looking_arc += ((*kb)<<3); + else if((*kb) < 4) + + myospal(weapon_xoffset+142-(p->look_ang>>1), + looking_arc+234-gun_pos,HANDHOLDINGLASER+3,gs,o,pal); + + myospal(weapon_xoffset+130-(p->look_ang>>1), + looking_arc+249-gun_pos, + HANDHOLDINGLASER+((*kb)>>2),gs,o,pal); + myospal(weapon_xoffset+152-(p->look_ang>>1), + looking_arc+249-gun_pos, + HANDHOLDINGLASER+((*kb)>>2),gs,o|4,pal); + } + else + { + if((*kb) > 6) + looking_arc += ((*kb)<<3); + else if((*kb) < 4) + + myospalx(weapon_xoffset+142-(p->look_ang>>1), + looking_arc+234-gun_pos,HANDHOLDINGLASER+3,gs,o,pal); + + myospalx(weapon_xoffset+130-(p->look_ang>>1), + looking_arc+249-gun_pos, + HANDHOLDINGLASER+((*kb)>>2),gs,o,pal); + myospalx(weapon_xoffset+152-(p->look_ang>>1), + looking_arc+249-gun_pos, + HANDHOLDINGLASER+((*kb)>>2),gs,o|4,pal); + } + } + break; + + case RPG_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else pal = sector[p->cursectnum].floorpal; + + weapon_xoffset -= sintable[(768+((*kb)<<7))&2047]>>11; + gun_pos += sintable[(768+((*kb)<<7))&2047]>>11; + + if(*aplWeaponRenderSize[RPG_WEAPON] == 0) + { + if(*kb > 0) + { + if(*kb < 8) + { + myospal(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos, + RPGGUN+((*kb)>>1),gs,o,pal); + } + } + + myospal(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos, + RPGGUN,gs,o,pal); + } + + else + + { + + if(*kb > 0) + { + if(*kb < 8) + { + myospalx(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos, + RPGGUN+((*kb)>>1),gs,o,pal); + } + } + + myospalx(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos, + RPGGUN,gs,o,pal); + } + } + break; + + case SHOTGUN_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + + weapon_xoffset -= 8; + + if(*aplWeaponRenderSize[SHOTGUN_WEAPON] == 0) + { + switch(*kb) + { + case 1: + case 2: + myospal(weapon_xoffset+168-(p->look_ang>>1),looking_arc+201-gun_pos, + SHOTGUN+2,-128,o,pal); + case 0: + case 6: + case 7: + case 8: + myospal(weapon_xoffset+146-(p->look_ang>>1),looking_arc+202-gun_pos, + SHOTGUN,gs,o,pal); + break; + case 3: + case 4: + case 5: + case 9: + case 10: + case 11: + case 12: + if( *kb > 1 && *kb < 5 ) + { + gun_pos -= 40; + weapon_xoffset += 20; + + myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+194-gun_pos, + SHOTGUN+1+((*(kb)-1)>>1),-128,o,pal); + } + + myospal(weapon_xoffset+158-(p->look_ang>>1),looking_arc+220-gun_pos, + SHOTGUN+3,gs,o,pal); + + break; + case 13: + case 14: + case 15: + myospal(32+weapon_xoffset+166-(p->look_ang>>1),looking_arc+210-gun_pos, + SHOTGUN+4,gs,o,pal); + break; + case 16: + case 17: + case 18: + case 19: + myospal(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+5,gs,o,pal); + break; + case 20: + case 21: + case 22: + case 23: + myospal(64+weapon_xoffset+176-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+6,gs,o,pal); + break; + case 24: + case 25: + case 26: + case 27: + myospal(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+5,gs,o,pal); + break; + case 28: + case 29: + case 30: + myospal(32+weapon_xoffset+156-(p->look_ang>>1),looking_arc+206-gun_pos, + SHOTGUN+4,gs,o,pal); + break; + } + } + else + + { + + switch(*kb) + { + case 1: + case 2: + myospalx(weapon_xoffset+168-(p->look_ang>>1),looking_arc+201-gun_pos, + SHOTGUN+2,-128,o,pal); + case 0: + case 6: + case 7: + case 8: + myospalx(weapon_xoffset+146-(p->look_ang>>1),looking_arc+202-gun_pos, + SHOTGUN,gs,o,pal); + break; + case 3: + case 4: + case 5: + case 9: + case 10: + case 11: + case 12: + if( *kb > 1 && *kb < 5 ) + { + gun_pos -= 40; + weapon_xoffset += 20; + + myospalx(weapon_xoffset+178-(p->look_ang>>1),looking_arc+194-gun_pos, + SHOTGUN+1+((*(kb)-1)>>1),-128,o,pal); + } + + myospalx(weapon_xoffset+158-(p->look_ang>>1),looking_arc+220-gun_pos, + SHOTGUN+3,gs,o,pal); + + break; + case 13: + case 14: + case 15: + myospalx(32+weapon_xoffset+166-(p->look_ang>>1),looking_arc+210-gun_pos, + SHOTGUN+4,gs,o,pal); + break; + case 16: + case 17: + case 18: + case 19: + myospalx(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+5,gs,o,pal); + break; + case 20: + case 21: + case 22: + case 23: + myospalx(64+weapon_xoffset+176-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+6,gs,o,pal); + break; + case 24: + case 25: + case 26: + case 27: + myospalx(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos, + SHOTGUN+5,gs,o,pal); + break; + case 28: + case 29: + case 30: + myospalx(32+weapon_xoffset+156-(p->look_ang>>1),looking_arc+206-gun_pos, + SHOTGUN+4,gs,o,pal); + break; + } + } + } + break; + + + case CHAINGUN_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + if(*kb > 0) + gun_pos -= sintable[(*kb)<<7]>>12; + + if(*kb > 0 && sprite[p->i].pal != 1) weapon_xoffset += 1-(rand()&3); + + if(*aplWeaponRenderSize[CHAINGUN_WEAPON] == 0) + { + + myospal(weapon_xoffset+168-(p->look_ang>>1),looking_arc+260-gun_pos, + CHAINGUN,gs,o,pal); + switch(*kb) + { + case 0: + myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1,gs,o,pal); + break; + default: + if(*kb > *aplWeaponFireDelay[CHAINGUN_WEAPON] && *kb < *aplWeaponTotalTime[CHAINGUN_WEAPON]) + { + i = 0; + if(sprite[p->i].pal != 1) i = rand()&7; + myospal(i+weapon_xoffset-4+140-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-4)/5),gs,o,pal); + if(sprite[p->i].pal != 1) i = rand()&7; + myospal(i+weapon_xoffset-4+184-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-4)/5),gs,o,pal); + } + if(*kb < *aplWeaponTotalTime[CHAINGUN_WEAPON]-2) + { + i = rand()&7; + myospal(i+weapon_xoffset-4+162-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-2)/5),gs,o,pal); + myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1+((*kb)>>1),gs,o,pal); + } + else myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1,gs,o,pal); + break; + } + } + else + { + + myospalx(weapon_xoffset+168-(p->look_ang>>1),looking_arc+260-gun_pos, + CHAINGUN,gs,o,pal); + switch(*kb) + { + case 0: + myospalx(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1,gs,o,pal); + break; + default: + if(*kb > *aplWeaponFireDelay[CHAINGUN_WEAPON] && *kb < *aplWeaponTotalTime[CHAINGUN_WEAPON]) + { + i = 0; + if(sprite[p->i].pal != 1) i = rand()&7; + myospalx(i+weapon_xoffset-4+140-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-4)/5),gs,o,pal); + if(sprite[p->i].pal != 1) i = rand()&7; + myospalx(i+weapon_xoffset-4+184-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-4)/5),gs,o,pal); + } + if(*kb < *aplWeaponTotalTime[CHAINGUN_WEAPON]-4) + { + i = rand()&7; + myospalx(i+weapon_xoffset-4+162-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos, + CHAINGUN+5+((*kb-2)/5),gs,o,pal); + myospalx(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1+((*kb)>>1),gs,o,pal); + } + else myospalx(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos, + CHAINGUN+1,gs,o,pal); + break; + } + } + } + break; + + case PISTOL_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + if(*aplWeaponRenderSize[PISTOL_WEAPON] == 0) + { + if( (*kb) < *aplWeaponTotalTime[PISTOL_WEAPON]+1) + { + short kb_frames[] = {0,1,2,0,0,0,0},l; + + l = 195-12+weapon_xoffset; + + if((*kb) == *aplWeaponFireDelay[PISTOL_WEAPON]) + l -= 3; + + myospal((l-(p->look_ang>>1)),(looking_arc+244-gun_pos),FIRSTGUN+kb_frames[*kb],gs,2,pal); + } + else + { + + if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-17) + myospal(194-(p->look_ang>>1),looking_arc+230-gun_pos,FIRSTGUN+4,gs,o,pal); + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-12) + { + myospal(244-((*kb)<<3)-(p->look_ang>>1),looking_arc+130-gun_pos+((*kb)<<4),FIRSTGUN+6,gs,o,pal); + myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-7) + { + myospal(124+((*kb)<<1)-(p->look_ang>>1),looking_arc+430-gun_pos-((*kb)<<3),FIRSTGUN+6,gs,o,pal); + myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-4) + { + myospal(184-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+8,gs,o,pal); + myospal(224-(p->look_ang>>1),looking_arc+210-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-2) + { + myospal(164-(p->look_ang>>1),looking_arc+245-gun_pos,FIRSTGUN+8,gs,o,pal); + myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]) + myospal(194-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+5,gs,o,pal); + + } + } + else + { + if( (*kb) < *aplWeaponTotalTime[PISTOL_WEAPON]+1) + { + short kb_frames[] = {0,1,2,0,0,0,0},l; + + l = 195-12+weapon_xoffset; + + if((*kb) == *aplWeaponFireDelay[PISTOL_WEAPON]) + l -= 3; + + myospalx((l-(p->look_ang>>1)),(looking_arc+244-gun_pos),FIRSTGUN+kb_frames[*kb],gs,2,pal); + } + else + { + + if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-17) + myospalx(194-(p->look_ang>>1),looking_arc+230-gun_pos,FIRSTGUN+4,gs,o,pal); + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-12) + { + myospalx(244-((*kb)<<3)-(p->look_ang>>1),looking_arc+130-gun_pos+((*kb)<<4),FIRSTGUN+6,gs,o,pal); + myospalx(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-7) + { + myospalx(124+((*kb)<<1)-(p->look_ang>>1),looking_arc+430-gun_pos-((*kb)<<3),FIRSTGUN+6,gs,o,pal); + myospalx(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-4) + { + myospalx(184-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+8,gs,o,pal); + myospalx(224-(p->look_ang>>1),looking_arc+210-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]-2) + { + myospalx(164-(p->look_ang>>1),looking_arc+245-gun_pos,FIRSTGUN+8,gs,o,pal); + myospalx(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal); + } + else if((*kb) < *aplWeaponReload[PISTOL_WEAPON]) + myospalx(194-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+5,gs,o,pal); + + } + } + } + + break; + case HANDBOMB_WEAPON: + { + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + if(*aplWeaponRenderSize[HANDBOMB_WEAPON] == 0) + { + + if((*kb)) + { + if((*kb) < (*aplWeaponTotalTime[p->curr_weapon])) + { + + char throw_frames[] + = {0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2}; + + if((*kb) < 7) + gun_pos -= 10*(*kb); //D + else if((*kb) < 12) + gun_pos += 20*((*kb)-10); //U + else if((*kb) < 20) + gun_pos -= 9*((*kb)-14); //D + + myospal(weapon_xoffset+190-(p->look_ang>>1),looking_arc+250-gun_pos,HANDTHROW+throw_frames[(*kb)],gs,o,pal); + } + } + else + myospal(weapon_xoffset+190-(p->look_ang>>1),looking_arc+260-gun_pos,HANDTHROW,gs,o,pal); + } + else + { + + if((*kb)) + { + char throw_frames[] + = {0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2}; + + if((*kb) < 7) + gun_pos -= 10*(*kb); //D + else if((*kb) < 12) + gun_pos += 20*((*kb)-10); //U + else if((*kb) < 20) + gun_pos -= 9*((*kb)-14); //D + + myospalx(weapon_xoffset+190-(p->look_ang>>1),looking_arc+250-gun_pos,HANDTHROW+throw_frames[(*kb)],gs,o,pal); + } + else + myospalx(weapon_xoffset+190-(p->look_ang>>1),looking_arc+260-gun_pos,HANDTHROW,gs,o,pal); + } + } + } + break; + + case HANDREMOTE_WEAPON: + { + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + signed char remote_frames[] = {0,1,1,2,1,1,0,0,0,0,0}; + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + weapon_xoffset = -48; + if(*aplWeaponRenderSize[HANDREMOTE_WEAPON] == 0) + { + if((*kb)) + myospal(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE+remote_frames[(*kb)],gs,o,pal); + else + myospal(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE,gs,o,pal); + } + else + { + if((*kb)) + myospalx(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE+remote_frames[(*kb)],gs,o,pal); + else + myospalx(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE,gs,o,pal); + } + } + } + break; + + case DEVISTATOR_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + if(*aplWeaponRenderSize[DEVISTATOR_WEAPON] == 0) + { + if((*kb) < (*aplWeaponTotalTime[DEVISTATOR_WEAPON]+1) && (*kb) > 0) + { + char cycloidy[] = {0,4,12,24,12,4,0}; + + i = ksgn((*kb)>>2); + + if(p->hbomb_hold_delay) + { + myospal( (cycloidy[*kb]>>1)+weapon_xoffset+268-(p->look_ang>>1),cycloidy[*kb]+looking_arc+238-gun_pos,DEVISTATOR+i,-32,o,pal); + myospal(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal); + } + else + { + myospal( -(cycloidy[*kb]>>1)+weapon_xoffset+30-(p->look_ang>>1),cycloidy[*kb]+looking_arc+240-gun_pos,DEVISTATOR+i,-32,o|4,pal); + myospal(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal); + } + } + else + { + myospal(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal); + myospal(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal); + } + } + else + { + if((*kb) < (*aplWeaponTotalTime[DEVISTATOR_WEAPON]+1) && (*kb) > 0) + { + char cycloidy[] = {0,4,12,24,12,4,0}; + + i = ksgn((*kb)>>2); + + if(p->hbomb_hold_delay) + { + myospalx( (cycloidy[*kb]>>1)+weapon_xoffset+268-(p->look_ang>>1),cycloidy[*kb]+looking_arc+238-gun_pos,DEVISTATOR+i,-32,o,pal); + myospalx(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal); + } + else + { + myospalx( -(cycloidy[*kb]>>1)+weapon_xoffset+30-(p->look_ang>>1),cycloidy[*kb]+looking_arc+240-gun_pos,DEVISTATOR+i,-32,o|4,pal); + myospalx(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal); + } + } + else + { + myospalx(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal); + myospalx(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal); + } + } + } + break; + + case FREEZE_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + + if(*aplWeaponRenderSize[FREEZE_WEAPON] == 0) + { + if((*kb) < (aplWeaponTotalTime[p->curr_weapon][snum]+1) && (*kb) > 0) + { + char cat_frames[] = { 0,0,1,1,2,2 }; + + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + looking_arc += rand()&3; + } + gun_pos -= 16; + myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE+2,-32,o,pal); + myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+235-gun_pos,FREEZE+3+cat_frames[*kb%6],-32,o,pal); + } + else myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE,gs,o,pal); + } + else + { + if((*kb) < (aplWeaponTotalTime[p->curr_weapon][snum]+1) && (*kb) > 0) + { + char cat_frames[] = { 0,0,1,1,2,2 }; + + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + looking_arc += rand()&3; + } + gun_pos -= 16; + myospalx(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE+2,-32,o,pal); + myospalx(weapon_xoffset+210-(p->look_ang>>1),looking_arc+235-gun_pos,FREEZE+3+cat_frames[*kb%6],-32,o,pal); + } + else myospalx(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE,gs,o,pal); + } + } + break; + + case GROW_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + weapon_xoffset += 28; + looking_arc += 18; + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + if(*aplWeaponRenderSize[GROW_WEAPON] == 0) + { + if((*kb) < aplWeaponTotalTime[p->curr_weapon][snum] && (*kb) > 0) + { + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + gun_pos += (rand()&3); + } + + myospal(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32, + o,2); + + myospal(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER-1,gs,o,pal); + } + else + { + myospal(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+2, + 16-(sintable[p->random_club_frame&2047]>>10), + o,2); + + myospal(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER-2,gs,o,pal); + } + } + else + { + if((*kb) < aplWeaponTotalTime[p->curr_weapon][snum] && (*kb) > 0) + { + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + gun_pos += (rand()&3); + } + + myospalx(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32, + o,2); + + myospalx(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER-1,gs,o,pal); + } + else + { + myospalx(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+2, + 16-(sintable[p->random_club_frame&2047]>>10), + o,2); + + myospalx(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER-2,gs,o,pal); + } + } + } + break; + + case SHRINKER_WEAPON: + + SetGameVarID(g_iReturnVarID,0,ps[screenpeek].i,screenpeek); + OnEvent(EVENT_DRAWWEAPON,ps[screenpeek].i,screenpeek, -1); + if(GetGameVarID(g_iReturnVarID,ps[screenpeek].i,screenpeek) == 0 && ud.drawweapon > 0) + { + weapon_xoffset += 28; + looking_arc += 18; + if(sprite[p->i].pal == 1) + pal = 1; + else + pal = sector[p->cursectnum].floorpal; + if(*aplWeaponRenderSize[SHRINKER_WEAPON] == 0) + { + if(((*kb) > 0) && ((*kb) < aplWeaponTotalTime[p->curr_weapon][snum])) + { + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + gun_pos += (rand()&3); + } + + myospal(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32, + o,0); + + myospal(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+1,gs,o,pal); + + } + else + { + myospal(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+2, + 16-(sintable[p->random_club_frame&2047]>>10), + o,0); + + myospal(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER,gs,o,pal); + } + } + else + { + if(((*kb) > 0) && ((*kb) < aplWeaponTotalTime[p->curr_weapon][snum])) + { + if(sprite[p->i].pal != 1) + { + weapon_xoffset += rand()&3; + gun_pos += (rand()&3); + } + + myospalx(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32, + o,0); + myospalx(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+1,gs,o,pal); + } + else + { + myospalx(weapon_xoffset+184-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER+2, + 16-(sintable[p->random_club_frame&2047]>>10), + o,0); + + myospalx(weapon_xoffset+188-(p->look_ang>>1), + looking_arc+240-gun_pos,SHRINKER,gs,o,pal); + } + } + } + break; + + } + } + displayloogie(snum); + +} + +#define TURBOTURNTIME (TICRATE/8) // 7 +#define NORMALTURN 15 +#define PREAMBLETURN 5 +#define NORMALKEYMOVE 40 +#define MAXVEL ((NORMALKEYMOVE*2)+10) +#define MAXSVEL ((NORMALKEYMOVE*2)+10) +#define MAXANGVEL 127 +#define MAXHORIZ 127 + +long myaimmode = 0, myaimstat = 0, omyaimstat = 0; + +static ControlInfo lastinfo = { 0,0,0,0,0,0 }; +void getinput(short snum) +{ + short j, daang; + // MED + ControlInfo info; + int32 tics; + boolean running; + int32 turnamount; + int32 keymove; + int32 momx,momy; + struct player_struct *p; + unsigned char tmpbuf[2048]; + + momx = momy = 0; + p = &ps[snum]; + + CONTROL_GetInput( &info ); + + info.dx += lastinfo.dx; + info.dy += lastinfo.dy; + info.dz += lastinfo.dz; + info.dyaw += lastinfo.dyaw; + info.dpitch += lastinfo.dpitch; + info.droll += lastinfo.droll; + memset(&lastinfo.dx, 0, sizeof(lastinfo)); + + if( (p->gm&MODE_MENU) || (p->gm&MODE_TYPE) || (ud.pause_on && !KB_KeyPressed(sc_Pause)) ) + { + loc.fvel = vel = 0; + loc.svel = svel = 0; + loc.avel = angvel = 0; + loc.horz = horiz = 0; + loc.bits = (((long)gamequit)<<26); + info.dz = info.dyaw = 0; + return; + } + + tics = totalclock-lastcontroltime; + lastcontroltime = totalclock; + + if (ud.mouseaiming) + myaimmode = BUTTON(gamefunc_Mouse_Aiming); + else + { + omyaimstat = myaimstat; myaimstat = BUTTON(gamefunc_Mouse_Aiming); + if (myaimstat > omyaimstat) + { + myaimmode ^= 1; + FTA(44+myaimmode,p); + } + } + + if(multiflag == 1) + { + loc.bits = 1<<17; + loc.bits |= multiwhat<<18; + loc.bits |= multipos<<19; + multiflag = 0; + return; + } + + loc.bits = BUTTON(gamefunc_Jump); + loc.bits |= BUTTON(gamefunc_Crouch)<<1; + loc.bits |= BUTTON(gamefunc_Fire)<<2; + loc.bits |= BUTTON(gamefunc_Aim_Up)<<3; + loc.bits |= BUTTON(gamefunc_Aim_Down)<<4; + if (ud.runkey_mode) loc.bits |= (ud.auto_run | BUTTON(gamefunc_Run))<<5; + else loc.bits |= (BUTTON(gamefunc_Run) ^ ud.auto_run)<<5; + loc.bits |= BUTTON(gamefunc_Look_Left)<<6; + loc.bits |= BUTTON(gamefunc_Look_Right)<<7; + + if ( aplWeaponFlags[ps[snum].curr_weapon][snum] & WEAPON_FLAG_SEMIAUTO && BUTTON( gamefunc_Fire ) ) + CONTROL_ClearButton(gamefunc_Fire); + + j=0; + + if (BUTTON(gamefunc_Weapon_1)) + j = 1; + if (BUTTON(gamefunc_Weapon_2)) + j = 2; + if (BUTTON(gamefunc_Weapon_3)) + j = 3; + if (BUTTON(gamefunc_Weapon_4)) + j = 4; + if (BUTTON(gamefunc_Weapon_5)) + j = 5; + if (BUTTON(gamefunc_Weapon_6)) + j = 6; + if (BUTTON(gamefunc_Weapon_7)) + j = 7; + if (BUTTON(gamefunc_Weapon_8)) + j = 8; + if (BUTTON(gamefunc_Weapon_9)) + j = 9; + if (BUTTON(gamefunc_Weapon_10)) + j = 10; + if (BUTTON(gamefunc_Previous_Weapon)) + j = 11; + if (BUTTON(gamefunc_Next_Weapon)) + j = 12; + + loc.bits |= j<<8; + loc.bits |= BUTTON(gamefunc_Steroids)<<12; + loc.bits |= BUTTON(gamefunc_Look_Up)<<13; + loc.bits |= BUTTON(gamefunc_Look_Down)<<14; + loc.bits |= BUTTON(gamefunc_NightVision)<<15; + loc.bits |= BUTTON(gamefunc_MedKit)<<16; + loc.bits |= BUTTON(gamefunc_Center_View)<<18; + loc.bits |= BUTTON(gamefunc_Holster_Weapon)<<19; + loc.bits |= BUTTON(gamefunc_Inventory_Left)<<20; + loc.bits |= KB_KeyPressed(sc_Pause)<<21; + loc.bits |= BUTTON(gamefunc_Quick_Kick)<<22; + loc.bits |= myaimmode<<23; + loc.bits |= BUTTON(gamefunc_Holo_Duke)<<24; + loc.bits |= BUTTON(gamefunc_Jetpack)<<25; + loc.bits |= (((long)gamequit)<<26); + loc.bits |= BUTTON(gamefunc_Inventory_Right)<<27; + loc.bits |= BUTTON(gamefunc_TurnAround)<<28; + loc.bits |= BUTTON(gamefunc_Open)<<29; + loc.bits |= BUTTON(gamefunc_Inventory)<<30; + loc.bits |= KB_KeyPressed(sc_Escape)<<31; + + // running = BUTTON(gamefunc_Run)|ud.auto_run; + // JBF: Run key behaviour is selectable + if (ud.runkey_mode) + running = BUTTON(gamefunc_Run)|ud.auto_run; // classic + else + running = ud.auto_run^BUTTON(gamefunc_Run); // modern + + svel = vel = angvel = horiz = 0; + + if( CONTROL_JoystickEnabled ) + if ( running ) info.dz *= 2; + + if( BUTTON(gamefunc_Strafe) ) { + lastinfo.dyaw = info.dyaw % 8; + svel = -info.dyaw/8; + } else { + lastinfo.dyaw = info.dyaw % 64; + angvel = info.dyaw/64; + } + + if( myaimmode ) + { + lastinfo.dz = info.dz % (314-128); + if(ud.mouseflip) + horiz -= info.dz/(314-128); + else horiz += info.dz/(314-128); + + info.dz = 0; + } else { + lastinfo.dz = info.dz % (1<<6); + } + + svel -= info.dx; + vel = -info.dz>>6; + + if (running) + { + turnamount = NORMALTURN<<1; + keymove = NORMALKEYMOVE<<1; + } + else + { + turnamount = NORMALTURN; + keymove = NORMALKEYMOVE; + } + + if (BUTTON(gamefunc_Strafe)) + { + if ( BUTTON(gamefunc_Turn_Left) && (ps[snum].movement_lock[3] == 0)) + { + svel -= -keymove; + } + if ( BUTTON(gamefunc_Turn_Right) && (ps[snum].movement_lock[4] == 0)) + { + svel -= keymove; + } + } + else + { + if ( BUTTON(gamefunc_Turn_Left)) + { + turnheldtime += tics; + if (turnheldtime>=TURBOTURNTIME) + { + angvel -= turnamount; + } + else + { + angvel -= PREAMBLETURN; + } + } + else if ( BUTTON(gamefunc_Turn_Right)) + { + turnheldtime += tics; + if (turnheldtime>=TURBOTURNTIME) + { + angvel += turnamount; + } + else + { + angvel += PREAMBLETURN; + } + } + else + { + turnheldtime=0; + } + } + + if ( BUTTON(gamefunc_Strafe_Left) && (ps[snum].movement_lock[3] == 0)) + svel += keymove; + if ( BUTTON(gamefunc_Strafe_Right) && (ps[snum].movement_lock[4] == 0)) + svel += -keymove; + if ( BUTTON(gamefunc_Move_Forward) && (ps[snum].movement_lock[1] == 0)) + vel += keymove; + if ( BUTTON(gamefunc_Move_Backward) && (ps[snum].movement_lock[2] == 0)) + vel += -keymove; + + if(vel < -MAXVEL) vel = -MAXVEL; + if(vel > MAXVEL) vel = MAXVEL; + if(svel < -MAXSVEL) svel = -MAXSVEL; + if(svel > MAXSVEL) svel = MAXSVEL; + if(angvel < -MAXANGVEL) angvel = -MAXANGVEL; + if(angvel > MAXANGVEL) angvel = MAXANGVEL; + if(horiz < -MAXHORIZ) horiz = -MAXHORIZ; + if(horiz > MAXHORIZ) horiz = MAXHORIZ; + + loc.bits2 = BUTTON(gamefunc_Move_Forward); + loc.bits2 |= BUTTON(gamefunc_Move_Backward)<<1; + loc.bits2 |= BUTTON(gamefunc_Strafe_Left)<<2; + loc.bits2 |= BUTTON(gamefunc_Strafe_Right)<<3; + loc.bits2 |= BUTTON(gamefunc_Turn_Left)<<4; + loc.bits2 |= BUTTON(gamefunc_Turn_Right)<<5; + + if(ud.scrollmode && ud.overhead_on) + { + ud.folfvel = vel; + ud.folavel = angvel; + loc.fvel = 0; + loc.svel = 0; + loc.avel = 0; + loc.horz = 0; + return; + } + + if( numplayers > 1 ) + daang = myang; + else daang = p->ang; + + momx = mulscale9(vel,sintable[(daang+2560)&2047]); + momy = mulscale9(vel,sintable[(daang+2048)&2047]); + + momx += mulscale9(svel,sintable[(daang+2048)&2047]); + momy += mulscale9(svel,sintable[(daang+1536)&2047]); + + momx += fricxv; + momy += fricyv; + + if (momx == 0) momx = 1; // HACK; the game seems to "forget" about the rest of the data if we aren't moving + if (momy == 0) momy = 1; + + loc.fvel = momx; + loc.svel = momy; + + loc.avel = angvel; + loc.horz = horiz; +} + +char doincrements(struct player_struct *p) +{ + long /*j,*/i,snum; + + snum = sprite[p->i].yvel; + // j = sync[snum].avel; + // p->weapon_ang = -(j/5); + + p->player_par++; + + if(p->invdisptime > 0) + p->invdisptime--; + + if(p->tipincs > 0) p->tipincs--; + + if(p->last_pissed_time > 0 ) + { + p->last_pissed_time--; + + if( p->last_pissed_time == (26*219) ) + { + spritesound(FLUSH_TOILET,p->i); + if(snum == screenpeek || (gametype_flags[ud.coop] & GAMETYPE_FLAG_COOPSOUND)) + spritesound(DUKE_PISSRELIEF,p->i); + } + + if( p->last_pissed_time == (26*218) ) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + } + } + + if(p->crack_time > 0) + { + p->crack_time--; + if(p->crack_time == 0) + { + p->knuckle_incs = 1; + p->crack_time = 777; + } + } + + if( p->steroids_amount > 0 && p->steroids_amount < 400) + { + p->steroids_amount--; + if(p->steroids_amount == 0) + checkavailinven(p); + if( !(p->steroids_amount&7) ) + if(snum == screenpeek || (gametype_flags[ud.coop] & GAMETYPE_FLAG_COOPSOUND)) + spritesound(DUKE_HARTBEAT,p->i); + } + + if(p->heat_on && p->heat_amount > 0) + { + p->heat_amount--; + if( p->heat_amount == 0 ) + { + p->heat_on = 0; + checkavailinven(p); + spritesound(NITEVISION_ONOFF,p->i); + setpal(p); + } + } + + if( p->holoduke_on >= 0 ) + { + p->holoduke_amount--; + if(p->holoduke_amount <= 0) + { + spritesound(TELEPORTER,p->i); + p->holoduke_on = -1; + checkavailinven(p); + } + } + + if( p->jetpack_on && p->jetpack_amount > 0 ) + { + p->jetpack_amount--; + if(p->jetpack_amount <= 0) + { + p->jetpack_on = 0; + checkavailinven(p); + spritesound(DUKE_JETPACK_OFF,p->i); + stopspritesound(DUKE_JETPACK_IDLE,p->i); + stopspritesound(DUKE_JETPACK_ON,p->i); + } + } + + if(p->quick_kick > 0 && sprite[p->i].pal != 1) + { + p->quick_kick--; + if( p->quick_kick == 8 ) + shoot(p->i,KNEE); + } + + if(p->access_incs && sprite[p->i].pal != 1) + { + p->access_incs++; + if(sprite[p->i].extra <= 0) + p->access_incs = 12; + if(p->access_incs == 12) + { + if(p->access_spritenum >= 0) + { + checkhitswitch(snum,p->access_spritenum,1); + switch(sprite[p->access_spritenum].pal) + { + case 0:p->got_access &= (0xffff-0x1);break; + case 21:p->got_access &= (0xffff-0x2);break; + case 23:p->got_access &= (0xffff-0x4);break; + } + p->access_spritenum = -1; + } + else + { + checkhitswitch(snum,p->access_wallnum,0); + switch(wall[p->access_wallnum].pal) + { + case 0:p->got_access &= (0xffff-0x1);break; + case 21:p->got_access &= (0xffff-0x2);break; + case 23:p->got_access &= (0xffff-0x4);break; + } + } + } + + if(p->access_incs > 20) + { + p->access_incs = 0; + p->weapon_pos = 10; + p->kickback_pic = 0; + } + } + + if(p->scuba_on == 0 && sector[p->cursectnum].lotag == 2) + { + if(p->scuba_amount > 0) + { + p->scuba_on = 1; + p->inven_icon = 6; + FTA(76,p); + } + else + { + if(p->airleft > 0) + p->airleft--; + else + { + p->extra_extra8 += 32; + if(p->last_extra < (max_player_health>>1) && (p->last_extra&3) == 0) + spritesound(DUKE_LONGTERM_PAIN,p->i); + } + } + } + else if(p->scuba_amount > 0 && p->scuba_on) + { + p->scuba_amount--; + if(p->scuba_amount == 0) + { + p->scuba_on = 0; + checkavailinven(p); + } + } + + if(p->knuckle_incs) + { + p->knuckle_incs ++; + if(p->knuckle_incs==10) + { + if(totalclock > 1024) + if(snum == screenpeek || (gametype_flags[ud.coop] & GAMETYPE_FLAG_COOPSOUND)) + { + + if(rand()&1) + spritesound(DUKE_CRACK,p->i); + else spritesound(DUKE_CRACK2,p->i); + + } + + spritesound(DUKE_CRACK_FIRST,p->i); + + } + else if( p->knuckle_incs == 22 || (sync[snum].bits&(1<<2))) + p->knuckle_incs=0; + + return 1; + } + return 0; +} + +short weapon_sprites[MAX_WEAPONS] = { KNEE__STATIC, FIRSTGUNSPRITE__STATIC, SHOTGUNSPRITE__STATIC, + CHAINGUNSPRITE__STATIC, RPGSPRITE__STATIC, HEAVYHBOMB__STATIC, SHRINKERSPRITE__STATIC, DEVISTATORSPRITE__STATIC, + TRIPBOMBSPRITE__STATIC, FREEZESPRITE__STATIC, HEAVYHBOMB__STATIC, SHRINKERSPRITE__STATIC}; + +void checkweapons(struct player_struct *p) +{ + short j,cw; + + long snum; + + snum = sprite[p->i].yvel; + + cw = aplWeaponWorksLike[p->curr_weapon][snum]; + + if(cw < 1 || cw >= MAX_WEAPONS) return; + + if(cw) + { + if(TRAND&1) + spawn(p->i,weapon_sprites[cw]); + else switch(cw) + { + case RPG_WEAPON: + case HANDBOMB_WEAPON: + spawn(p->i,EXPLOSION2); + break; + } + } +} + +void processinput(short snum) +{ + long j, i, k, doubvel, fz, cz, hz, lz, truefdist, x, y; + char shrunk; + unsigned long sb_snum; + short psect, psectlotag,*kb, tempsect, pi; + struct player_struct *p; + spritetype *s; + + p = &ps[snum]; + pi = p->i; + s = &sprite[pi]; + + kb = &p->kickback_pic; + + OnEvent(EVENT_PROCESSINPUT, pi, snum, -1); + + if(p->cheat_phase <= 0) sb_snum = sync[snum].bits; + else sb_snum = 0; + + if((sb_snum&(1<<2))) + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_PRESSEDFIRE, pi, snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) != 0) + sb_snum &= ~(1<<2); + } + + psect = p->cursectnum; + if(psect == -1) + { + if(s->extra > 0 && ud.clipping == 0) + { + quickkill(p); + spritesound(SQUISHED,pi); + } + psect = 0; + } + + psectlotag = sector[psect].lotag; + p->spritebridge = 0; + p->sbs = 0; + + shrunk = (s->yrepeat < 32); + getzrange(p->posx,p->posy,p->posz,psect,&cz,&hz,&fz,&lz,163L,CLIPMASK0); + + j = getflorzofslope(psect,p->posx,p->posy); + + p->truefz = j; + p->truecz = getceilzofslope(psect,p->posx,p->posy); + + truefdist = klabs(p->posz-j); + if( (lz&49152) == 16384 && psectlotag == 1 && truefdist > PHEIGHT+(16<<8) ) + psectlotag = 0; + + hittype[pi].floorz = fz; + hittype[pi].ceilingz = cz; + + p->ohoriz = p->horiz; + p->ohorizoff = p->horizoff; + + if( p->aim_mode == 0 && p->on_ground && psectlotag != 2 && (sector[psect].floorstat&2) ) + { + x = p->posx+(sintable[(p->ang+512)&2047]>>5); + y = p->posy+(sintable[p->ang&2047]>>5); + tempsect = psect; + updatesector(x,y,&tempsect); + if (tempsect >= 0) + { + k = getflorzofslope(psect,x,y); + if (psect == tempsect) + p->horizoff += mulscale16(j-k,160); + else if (klabs(getflorzofslope(tempsect,x,y)-k) <= (4<<8)) + p->horizoff += mulscale16(j-k,160); + } + } + + if (p->horizoff > 0) p->horizoff -= ((p->horizoff>>3)+1); + else if (p->horizoff < 0) p->horizoff += (((-p->horizoff)>>3)+1); + + if( hz >= 0 && (hz&49152) == 49152) + { + hz &= (MAXSPRITES-1); + + if(sprite[hz].statnum == 1 && sprite[hz].extra >= 0) + { + hz = 0; + cz = p->truecz; + } + } + + if(lz >= 0 && (lz&49152) == 49152) + { + j = lz&(MAXSPRITES-1); + + if( (sprite[j].cstat&33) == 33 ) + { + psectlotag = 0; + p->footprintcount = 0; + p->spritebridge = 1; + p->sbs = j; + } + else if(badguy(&sprite[j]) && sprite[j].xrepeat > 24 && klabs(s->z-sprite[j].z) < (84<<8) ) + { + j = getangle(sprite[j].x-p->posx,sprite[j].y-p->posy); + p->posxv -= sintable[(j+512)&2047]<<4; + p->posyv -= sintable[j&2047]<<4; + } + } + + + if ( s->extra > 0 ) incur_damage( snum ); + else + { + s->extra = 0; + p->shield_amount = 0; + } + + p->last_extra = s->extra; + + if(p->loogcnt > 0) p->loogcnt--; + else p->loogcnt = 0; + + if(p->fist_incs) + { + // the fist puching the end-of-level thing... + p->fist_incs++; + if(p->fist_incs == 28) + { + if(ud.recstat == 1) closedemowrite(); + sound(PIPEBOMB_EXPLODE); + p->pals[0] = 64; + p->pals[1] = 64; + p->pals[2] = 64; + p->pals_time = 48; + } + if(p->fist_incs > 42) + { + if(p->buttonpalette && ud.from_bonus == 0) + { + ud.from_bonus = ud.level_number+1; + if(ud.secretlevel > 0 && ud.secretlevel < 12) ud.level_number = ud.secretlevel-1; + ud.m_level_number = ud.level_number; + } + else + { + if(ud.from_bonus) + { + ud.level_number = ud.from_bonus; + ud.m_level_number = ud.level_number; + ud.from_bonus = 0; + } + else + { + if(ud.level_number == ud.secretlevel && ud.from_bonus > 0 ) + ud.level_number = ud.from_bonus; + else ud.level_number++; + + if(ud.level_number > 10) ud.level_number = 0; + ud.m_level_number = ud.level_number; + + } + } + for(i=connecthead;i>=0;i=connectpoint2[i]) + ps[i].gm = MODE_EOL; + p->fist_incs = 0; + + return; + } + } + + if(p->timebeforeexit > 1 && p->last_extra > 0) + { + p->timebeforeexit--; + if(p->timebeforeexit == 26*5) + { + FX_StopAllSounds(); + clearsoundlocks(); + if(p->customexitsound >= 0) + { + sound(p->customexitsound); + FTA(102,p); + } + } + else if(p->timebeforeexit == 1) + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + ps[i].gm = MODE_EOL; + if(ud.from_bonus) + { + ud.level_number = ud.from_bonus; + ud.m_level_number = ud.level_number; + ud.from_bonus = 0; + } + else + { + ud.level_number++; + ud.m_level_number = ud.level_number; + } + return; + } + } + /* + if(p->select_dir) + { + if(psectlotag != 15 || (sb_snum&(1<<31)) ) + p->select_dir = 0; + else + { + if(sync[snum].fvel > 127) + { + p->select_dir = 0; + activatewarpelevators(pi,-1); + } + else if(sync[snum].fvel <= -127) + { + p->select_dir = 0; + activatewarpelevators(pi,1); + } + return; + } + } + */ + + if(p->pals_time >= 0) + p->pals_time--; + + if(p->fta > 0) + { + p->fta--; + if(p->fta == 0) + { + pub = NUMPAGES; + pus = NUMPAGES; + p->ftq = 0; + } + } + + if( s->extra <= 0 ) + { + if(p->dead_flag == 0) + { + if(s->pal != 1) + { + p->pals[0] = 63; + p->pals[1] = 0; + p->pals[2] = 0; + p->pals_time = 63; + p->posz -= (16<<8); + s->z -= (16<<8); + } + + if(ud.recstat == 1 && ud.multimode < 2) + closedemowrite(); + + if(s->pal != 1) + p->dead_flag = (512-((TRAND&1)<<10)+(TRAND&255)-512)&2047; + + p->jetpack_on = 0; + p->holoduke_on = -1; + + stopspritesound(DUKE_JETPACK_IDLE,p->i); + if(p->scream_voice > FX_Ok) + { + FX_StopSound(p->scream_voice); + testcallback(DUKE_SCREAM); + p->scream_voice = FX_Ok; + } + + if( s->pal != 1 && (s->cstat&32768) == 0) s->cstat = 0; + + if( ud.multimode > 1 && ( s->pal != 1 || (s->cstat&32768) ) ) + { + if(p->frag_ps != snum) + { + ps[p->frag_ps].frag++; + frags[p->frag_ps][snum]++; + + if( ud.user_name[p->frag_ps][0] != 0) + { + if(snum == screenpeek) + { + Bsprintf(&fta_quotes[115][0],"KILLED BY %s",&ud.user_name[p->frag_ps][0]); + FTA(115,p); + } + else + { + Bsprintf(&fta_quotes[116][0],"KILLED %s",&ud.user_name[snum][0]); + FTA(116,&ps[p->frag_ps]); + } + } + else + { + if(snum == screenpeek) + { + Bsprintf(&fta_quotes[115][0],"KILLED BY PLAYER %d",1+p->frag_ps); + FTA(115,p); + } + else + { + Bsprintf(&fta_quotes[116][0],"KILLED PLAYER %d",1+snum); + FTA(116,&ps[p->frag_ps]); + } + } + } + else p->fraggedself++; + + if(myconnectindex == connecthead) + { + unsigned char tmpbuf[2048]; + Bsprintf(tmpbuf,"frag %d killed %d\n",p->frag_ps+1,snum+1); + sendscore(tmpbuf); + // printf(tempbuf); + } + + p->frag_ps = snum; + pus = NUMPAGES; + } + } + + if( psectlotag == 2 ) + { + if(p->on_warping_sector == 0) + { + if( klabs(p->posz-fz) > (PHEIGHT>>1)) + p->posz += 348; + } + else + { + s->z -= 512; + s->zvel = -348; + } + + clipmove(&p->posx,&p->posy, + &p->posz,&p->cursectnum, + 0,0,164L,(4L<<8),(4L<<8),CLIPMASK0); + // p->bobcounter += 32; + } + + p->oposx = p->posx; + p->oposy = p->posy; + p->oposz = p->posz; + p->oang = p->ang; + p->opyoff = p->pyoff; + + p->horiz = 100; + p->horizoff = 0; + + updatesector(p->posx,p->posy,&p->cursectnum); + + pushmove(&p->posx,&p->posy,&p->posz,&p->cursectnum,128L,(4L<<8),(20L<<8),CLIPMASK0); + + if( fz > cz+(16<<8) && s->pal != 1) + p->rotscrnang = (p->dead_flag + ( (fz+p->posz)>>7))&2047; + + p->on_warping_sector = 0; + + return; + } + + if(p->transporter_hold > 0) + { + p->transporter_hold--; + if(p->transporter_hold == 0 && p->on_warping_sector) + p->transporter_hold = 2; + } + if(p->transporter_hold < 0) + p->transporter_hold++; + + if(p->newowner >= 0) + { + i = p->newowner; + p->posx = SX; + p->posy = SY; + p->posz = SZ; + p->ang = SA; + p->posxv = p->posyv = s->xvel = 0; + p->look_ang = 0; + p->rotscrnang = 0; + + doincrements(p); + + if(*aplWeaponWorksLike[p->curr_weapon] == HANDREMOTE_WEAPON) + { + goto SHOOTINCODE; + } + + return; + } + + doubvel = TICSPERFRAME; + + if (p->rotscrnang > 0) p->rotscrnang -= ((p->rotscrnang>>1)+1); + else if (p->rotscrnang < 0) p->rotscrnang += (((-p->rotscrnang)>>1)+1); + + p->look_ang -= (p->look_ang>>2); + + if( sb_snum&(1<<6) ) + { + // look_left + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_LOOKLEFT,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->look_ang -= 152; + p->rotscrnang += 24; + } + } + + if( sb_snum&(1<<7) ) + { + // look_right + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_LOOKRIGHT,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->look_ang += 152; + p->rotscrnang -= 24; + } + } + + if(p->on_crane >= 0) + goto HORIZONLY; + + j = ksgn(sync[snum].avel); + /* + if( j && ud.screen_tilting == 2) + { + k = 4; + if(sb_snum&(1<<5)) k <<= 2; + p->rotscrnang -= k*j; + p->look_ang += k*j; + } + */ + + if( s->xvel < 32 || p->on_ground == 0 || p->bobcounter == 1024 ) + { + if( (p->weapon_sway&2047) > (1024+96) ) + p->weapon_sway -= 96; + else if( (p->weapon_sway&2047) < (1024-96) ) + p->weapon_sway += 96; + else p->weapon_sway = 1024; + } + else p->weapon_sway = p->bobcounter; + + s->xvel = + ksqrt( (p->posx-p->bobposx)*(p->posx-p->bobposx)+(p->posy-p->bobposy)*(p->posy-p->bobposy)); + if(p->on_ground) p->bobcounter += sprite[p->i].xvel>>1; + + if( ud.clipping == 0 && ( sector[p->cursectnum].floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS) ) + { + p->posx = p->oposx; + p->posy = p->oposy; + } + else + { + p->oposx = p->posx; + p->oposy = p->posy; + } + + p->bobposx = p->posx; + p->bobposy = p->posy; + + p->oposz = p->posz; + p->opyoff = p->pyoff; + p->oang = p->ang; + + if(p->one_eighty_count < 0) + { + p->one_eighty_count += 128; + p->ang += 128; + } + + // Shrinking code + + i = 40; + + if( psectlotag == 2) + { + // under water + p->jumping_counter = 0; + + p->pycount += 32; + p->pycount &= 2047; + p->pyoff = sintable[p->pycount]>>7; + + if(!isspritemakingsound(pi,DUKE_UNDERWATER)) + spritesound(DUKE_UNDERWATER,pi); + + if ( sb_snum&1 ) + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_SWIMUP,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + // jump + if(p->poszv > 0) p->poszv = 0; + p->poszv -= 348; + if(p->poszv < -(256*6)) p->poszv = -(256*6); + } + } + else if (sb_snum&(1<<1)) + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_SWIMDOWN,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + // crouch + if(p->poszv < 0) p->poszv = 0; + p->poszv += 348; + if(p->poszv > (256*6)) p->poszv = (256*6); + } + } + else + { + // normal view + if(p->poszv < 0) + { + p->poszv += 256; + if(p->poszv > 0) + p->poszv = 0; + } + if(p->poszv > 0) + { + p->poszv -= 256; + if(p->poszv < 0) + p->poszv = 0; + } + } + + if(p->poszv > 2048) + p->poszv >>= 1; + + p->posz += p->poszv; + + if(p->posz > (fz-(15<<8)) ) + p->posz += ((fz-(15<<8))-p->posz)>>1; + + if(p->posz < (cz+(4<<8)) ) + { + p->posz = cz+(4<<8); + p->poszv = 0; + } + + if( p->scuba_on && (TRAND&255) < 8 ) + { + j = spawn(pi,WATERBUBBLE); + sprite[j].x += + sintable[(p->ang+512+64-(global_random&128))&2047]>>6; + sprite[j].y += + sintable[(p->ang+64-(global_random&128))&2047]>>6; + sprite[j].xrepeat = 3; + sprite[j].yrepeat = 2; + sprite[j].z = p->posz+(8<<8); + } + } + + else if(p->jetpack_on) + { + p->on_ground = 0; + p->jumping_counter = 0; + p->hard_landing = 0; + p->falling_counter = 0; + + p->pycount += 32; + p->pycount &= 2047; + p->pyoff = sintable[p->pycount]>>7; + + if(p->jetpack_on < 11) + { + p->jetpack_on++; + p->posz -= (p->jetpack_on<<7); //Goin up + } + else if(p->jetpack_on == 11 && !isspritemakingsound(pi,DUKE_JETPACK_IDLE)) + spritesound(DUKE_JETPACK_IDLE,pi); + + if(shrunk) j = 512; + else j = 2048; + + if ( sb_snum&1 ) //A (soar high) + { + // jump + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_SOARUP,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->posz -= j; + p->crack_time = 777; + } + } + + if (sb_snum&(1<<1)) //Z (soar low) + { + // crouch + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_SOARDOWN,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->posz += j; + p->crack_time = 777; + } + } + + if( shrunk == 0 && (psectlotag == 0 || psectlotag == 2)) k = 32; + else k = 16; + + if( psectlotag != 2 && p->scuba_on == 1 ) + p->scuba_on = 0; + + if(p->posz > (fz-(k<<8)) ) + p->posz += ((fz-(k<<8))-p->posz)>>1; + if(p->posz < (hittype[pi].ceilingz+(18<<8)) ) + p->posz = hittype[pi].ceilingz+(18<<8); + + } + else if( psectlotag != 2 ) + { + if(p->airleft != 15*26) + p->airleft = 15*26; //Aprox twenty seconds. + + if(p->scuba_on == 1) + p->scuba_on = 0; + + if( psectlotag == 1 && p->spritebridge == 0) + { + if(shrunk == 0) + { + i = 34; + p->pycount += 32; + p->pycount &= 2047; + p->pyoff = sintable[p->pycount]>>6; + } + else i = 12; + + if(shrunk == 0 && truefdist <= PHEIGHT) + { + if(p->on_ground == 1) + { + if( p->dummyplayersprite == -1 ) + p->dummyplayersprite = + spawn(pi,PLAYERONWATER); + + p->footprintcount = 6; + if(sector[p->cursectnum].floorpicnum == FLOORSLIME) + p->footprintpal = 8; + else p->footprintpal = 0; + p->footprintshade = 0; + } + } + } + else + { + if(p->footprintcount > 0 && p->on_ground) + if( (sector[p->cursectnum].floorstat&2) != 2 ) + { + for(j=headspritesect[psect];j>=0;j=nextspritesect[j]) + if( sprite[j].picnum == FOOTPRINTS || sprite[j].picnum == FOOTPRINTS2 || sprite[j].picnum == FOOTPRINTS3 || sprite[j].picnum == FOOTPRINTS4 ) + if (klabs(sprite[j].x-p->posx) < 384) + if (klabs(sprite[j].y-p->posy) < 384) + break; + if(j < 0) + { + p->footprintcount--; + if( sector[p->cursectnum].lotag == 0 && sector[p->cursectnum].hitag == 0 ) + { + switch(TRAND&3) + { + case 0: j = spawn(pi,FOOTPRINTS); break; + case 1: j = spawn(pi,FOOTPRINTS2); break; + case 2: j = spawn(pi,FOOTPRINTS3); break; + default: j = spawn(pi,FOOTPRINTS4); break; + } + sprite[j].pal = p->footprintpal; + sprite[j].shade = p->footprintshade; + } + } + } + } + + if(p->posz < (fz-(i<<8)) ) //falling + { + + // not jumping or crouching + if( (sb_snum&3) == 0 && p->on_ground && (sector[psect].floorstat&2) && p->posz >= (fz-(i<<8)-(16<<8) ) ) + p->posz = fz-(i<<8); + else + { + p->on_ground = 0; + p->poszv += (gc+80); // (TICSPERFRAME<<6); + if(p->poszv >= (4096+2048)) p->poszv = (4096+2048); + if(p->poszv > 2400 && p->falling_counter < 255) + { + p->falling_counter++; + if( p->falling_counter == 38 ) + p->scream_voice = spritesound(DUKE_SCREAM,pi); + } + + if( (p->posz+p->poszv) >= (fz-(i<<8)) ) // hit the ground + if(sector[p->cursectnum].lotag != 1) + { + if( p->falling_counter > 62 ) quickkill(p); + + else if( p->falling_counter > 9 ) + { + j = p->falling_counter; + s->extra -= j-(TRAND&3); + if(s->extra <= 0) + { + spritesound(SQUISHED,pi); + p->pals[0] = 63; + p->pals[1] = 0; + p->pals[2] = 0; + p->pals_time = 63; + } + else + { + spritesound(DUKE_LAND,pi); + spritesound(DUKE_LAND_HURT,pi); + } + + p->pals[0] = 16; + p->pals[1] = 0; + p->pals[2] = 0; + p->pals_time = 32; + } + else if(p->poszv > 2048) spritesound(DUKE_LAND,pi); + } + } + } + + else + { + p->falling_counter = 0; + if(p->scream_voice > FX_Ok) + { + FX_StopSound(p->scream_voice); + p->scream_voice = FX_Ok; + } + + if(psectlotag != 1 && psectlotag != 2 && p->on_ground == 0 && p->poszv > (6144>>1)) + p->hard_landing = p->poszv>>10; + + p->on_ground = 1; + + if( i==40 ) + { + //Smooth on the ground + + k = ((fz-(i<<8))-p->posz)>>1; + if( klabs(k) < 256 ) k = 0; + p->posz += k; + p->poszv -= 768; + if(p->poszv < 0) p->poszv = 0; + } + else if(p->jumping_counter == 0) + { + p->posz += ((fz-(i<<7))-p->posz)>>1; //Smooth on the water + if(p->on_warping_sector == 0 && p->posz > fz-(16<<8)) + { + p->posz = fz-(16<<8); + p->poszv >>= 1; + } + } + + p->on_warping_sector = 0; + + if( (sb_snum&2) ) + { + // crouching + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_CROUCH,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->posz += (2048+768); + p->crack_time = 777; + } + } + + // jumping + if( (sb_snum&1) == 0 && p->jumping_toggle == 1) + p->jumping_toggle = 0; + + else if( (sb_snum&1) && p->jumping_toggle == 0 ) + { + if( p->jumping_counter == 0 ) + if( (fz-cz) > (56<<8) ) + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_JUMP,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->jumping_counter = 1; + p->jumping_toggle = 1; + } + } + } + + if( p->jumping_counter && (sb_snum&1) == 0 ) + p->jumping_toggle = 0; + } + + if(p->jumping_counter) + { + if( (sb_snum&1) == 0 && p->jumping_toggle == 1) + p->jumping_toggle = 0; + + if( p->jumping_counter < (1024+256) ) + { + if(psectlotag == 1 && p->jumping_counter > 768) + { + p->jumping_counter = 0; + p->poszv = -512; + } + else + { + p->poszv -= (sintable[(2048-128+p->jumping_counter)&2047])/12; + p->jumping_counter += 180; + p->on_ground = 0; + } + } + else + { + p->jumping_counter = 0; + p->poszv = 0; + } + } + + p->posz += p->poszv; + + if(p->posz < (cz+(4<<8))) + { + p->jumping_counter = 0; + if(p->poszv < 0) + p->posxv = p->posyv = 0; + p->poszv = 128; + p->posz = cz+(4<<8); + } + } + + //Do the quick lefts and rights + + if ( p->fist_incs || + p->transporter_hold > 2 || + p->hard_landing || + p->access_incs > 0 || + p->knee_incs > 0 || + (*aplWeaponWorksLike[p->curr_weapon] == TRIPBOMB_WEAPON && + *kb > 1 && + *kb < 4 ) ) + { + doubvel = 0; + p->posxv = 0; + p->posyv = 0; + } + else if ( sync[snum].avel ) //p->ang += syncangvel * constant + { //ENGINE calculates angvel for you + long tempang; + + tempang = sync[snum].avel<<1; + + if( psectlotag == 2 ) p->angvel =(tempang-(tempang>>3))*ksgn(doubvel); + else p->angvel = tempang*ksgn(doubvel); + + p->ang += p->angvel; + p->ang &= 2047; + p->crack_time = 777; + } + + if(p->spritebridge == 0) + { + j = sector[s->sectnum].floorpicnum; + + if( j == PURPLELAVA || sector[s->sectnum].ceilingpicnum == PURPLELAVA ) + { + if(p->boot_amount > 0) + { + p->boot_amount--; + p->inven_icon = 7; + if(p->boot_amount <= 0) + checkavailinven(p); + } + else + { + if(!isspritemakingsound(pi,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,pi); + p->pals[0] = 0; p->pals[1] = 8; p->pals[2] = 0; + p->pals_time = 32; + s->extra--; + } + } + + k = 0; + + if(p->on_ground && truefdist <= PHEIGHT+(16<<8)) + { + switch(dynamictostatic[j]) + { + case HURTRAIL__STATIC: + if( rnd(32) ) + { + if(p->boot_amount > 0) + k = 1; + else + { + if(!isspritemakingsound(pi,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,pi); + p->pals[0] = 64; p->pals[1] = 64; p->pals[2] = 64; + p->pals_time = 32; + s->extra -= 1+(TRAND&3); + if(!isspritemakingsound(pi,SHORT_CIRCUIT)) + spritesound(SHORT_CIRCUIT,pi); + } + } + break; + case FLOORSLIME__STATIC: + if( rnd(16) ) + { + if(p->boot_amount > 0) + k = 1; + else + { + if(!isspritemakingsound(pi,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,pi); + p->pals[0] = 0; p->pals[1] = 8; p->pals[2] = 0; + p->pals_time = 32; + s->extra -= 1+(TRAND&3); + } + } + break; + case FLOORPLASMA__STATIC: + if( rnd(32) ) + { + if( p->boot_amount > 0 ) + k = 1; + else + { + if(!isspritemakingsound(pi,DUKE_LONGTERM_PAIN)) + spritesound(DUKE_LONGTERM_PAIN,pi); + p->pals[0] = 8; p->pals[1] = 0; p->pals[2] = 0; + p->pals_time = 32; + s->extra -= 1+(TRAND&3); + } + } + break; + } + } + + if( k ) + { + FTA(75,p); + p->boot_amount -= 2; + if(p->boot_amount <= 0) + checkavailinven(p); + } + } + + if ( p->posxv || p->posyv || sync[snum].fvel || sync[snum].svel ) + { + p->crack_time = 777; + + k = sintable[p->bobcounter&2047]>>12; + + if((truefdist < PHEIGHT+(8<<8) ) && ( k == 1 || k == 3 )) + { + if(p->spritebridge == 0 && p->walking_snd_toggle == 0 && p->on_ground) + { + switch( psectlotag ) + { + case 0: + + if(lz >= 0 && (lz&(MAXSPRITES-1))==49152 ) + j = sprite[lz&(MAXSPRITES-1)].picnum; + else j = sector[psect].floorpicnum; + + switch(dynamictostatic[j]) + { + case PANNEL1__STATIC: + case PANNEL2__STATIC: + spritesound(DUKE_WALKINDUCTS,pi); + p->walking_snd_toggle = 1; + break; + } + break; + case 1: + if((TRAND&1) == 0) + spritesound(DUKE_ONWATER,pi); + p->walking_snd_toggle = 1; + break; + } + } + } + else if(p->walking_snd_toggle > 0) + p->walking_snd_toggle --; + + if(p->jetpack_on == 0 && p->steroids_amount > 0 && p->steroids_amount < 400) + doubvel <<= 1; + + /* + loc.bits2 = BUTTON(gamefunc_Move_Forward); + loc.bits2 |= BUTTON(gamefunc_Move_Backward)<<1; + loc.bits2 |= BUTTON(gamefunc_Strafe_Left)<<2; + loc.bits2 |= BUTTON(gamefunc_Strafe_Right)<<3; + loc.bits2 |= BUTTON(gamefunc_Turn_Left)<<4; + loc.bits2 |= BUTTON(gamefunc_Turn_Right)<<5; + */ + if (sync[snum].bits2&(1)) + OnEvent(EVENT_MOVEFORWARD,pi,snum, -1); + + if (sync[snum].bits2&(1<<1)) + OnEvent(EVENT_MOVEBACKWARD,pi,snum, -1); + + if (sync[snum].bits2&(1<<2)) + OnEvent(EVENT_STRAFELEFT,pi,snum, -1); + + if (sync[snum].bits2&(1<<3)) + OnEvent(EVENT_STRAFERIGHT,pi,snum, -1); + + if (sync[snum].bits2&(1<<4) || sync[snum].avel < 0) + OnEvent(EVENT_TURNLEFT,pi,snum, -1); + + if (sync[snum].bits2&(1<<5) || sync[snum].avel > 0) + OnEvent(EVENT_TURNRIGHT,pi,snum, -1); + + p->posxv += ((sync[snum].fvel*doubvel)<<6); + p->posyv += ((sync[snum].svel*doubvel)<<6); + + if( ( aplWeaponWorksLike[p->curr_weapon] == KNEE_WEAPON && *kb > 10 && p->on_ground ) || ( p->on_ground && (sb_snum&2) ) ) + { + p->posxv = mulscale(p->posxv,p->runspeed-0x2000,16); + p->posyv = mulscale(p->posyv,p->runspeed-0x2000,16); + } + else + { + if(psectlotag == 2) + { + p->posxv = mulscale(p->posxv,p->runspeed-0x1400,16); + p->posyv = mulscale(p->posyv,p->runspeed-0x1400,16); + } + else + { + p->posxv = mulscale(p->posxv,p->runspeed,16); + p->posyv = mulscale(p->posyv,p->runspeed,16); + } + } + + if( abs(p->posxv) < 2048 && abs(p->posyv) < 2048 ) + p->posxv = p->posyv = 0; + + if( shrunk ) + { + p->posxv = + mulscale16(p->posxv,p->runspeed-(p->runspeed>>1)+(p->runspeed>>2)); + p->posyv = + mulscale16(p->posyv,p->runspeed-(p->runspeed>>1)+(p->runspeed>>2)); + } + } + +HORIZONLY: + + if(psectlotag == 1 || p->spritebridge == 1) i = (4L<<8); + else i = (20L<<8); + + if(sector[p->cursectnum].lotag == 2) k = 0; + else k = 1; + + if(ud.clipping) + { + j = 0; + p->posx += p->posxv>>14; + p->posy += p->posyv>>14; + updatesector(p->posx,p->posy,&p->cursectnum); + changespritesect(pi,p->cursectnum); + } + else + j = clipmove(&p->posx,&p->posy, + &p->posz,&p->cursectnum, + p->posxv,p->posyv,164L,(4L<<8),i,CLIPMASK0); + + if(p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk) + p->posz += 32<<8; + + if(j) + checkplayerhurt(p,j); + + if(p->jetpack_on == 0) + { + if( s->xvel > 16 ) + { + if( psectlotag != 1 && psectlotag != 2 && p->on_ground ) + { + p->pycount += 52; + p->pycount &= 2047; + p->pyoff = + klabs(s->xvel*sintable[p->pycount])/1596; + } + } + else if( psectlotag != 2 && psectlotag != 1 ) + p->pyoff = 0; + } + + // RBG*** + setsprite(pi,p->posx,p->posy,p->posz+PHEIGHT); + + if( psectlotag < 3 ) + { + psect = s->sectnum; + if( ud.clipping == 0 && sector[psect].lotag == 31) + { + if( sprite[sector[psect].hitag].xvel && hittype[sector[psect].hitag].temp_data[0] == 0) + { + quickkill(p); + return; + } + } + } + + if(truefdist < PHEIGHT && p->on_ground && psectlotag != 1 && shrunk == 0 && sector[p->cursectnum].lotag == 1) + if(!isspritemakingsound(pi,DUKE_ONWATER)) + spritesound(DUKE_ONWATER,pi); + + if (p->cursectnum != s->sectnum) + changespritesect(pi,p->cursectnum); + + if(ud.clipping == 0) + j = ( pushmove(&p->posx,&p->posy,&p->posz,&p->cursectnum,164L,(4L<<8),(4L<<8),CLIPMASK0) < 0 && furthestangle(pi,8) < 512 ); + else j = 0; + + if(ud.clipping == 0) + { + if( klabs(hittype[pi].floorz-hittype[pi].ceilingz) < (48<<8) || j ) + { + if ( !(sector[s->sectnum].lotag&0x8000) && ( isanunderoperator(sector[s->sectnum].lotag) || + isanearoperator(sector[s->sectnum].lotag) ) ) + activatebysector(s->sectnum,pi); + if(j) + { + quickkill(p); + return; + } + } + else if( klabs(fz-cz) < (32<<8) && isanunderoperator(sector[psect].lotag) ) + activatebysector(psect,pi); + } + + // center_view + if( sb_snum&(1<<18) || p->hard_landing) + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_RETURNTOCENTER,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->return_to_center = 9; + } + } + + if( sb_snum&(1<<13) ) + { + // look_up + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_LOOKUP,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->return_to_center = 9; + if( sb_snum&(1<<5) ) p->horiz += 12; // running + p->horiz += 12; + } + } + + else if( sb_snum&(1<<14) ) + { + // look_down + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_LOOKDOWN,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + p->return_to_center = 9; + if( sb_snum&(1<<5) ) p->horiz -= 12; + p->horiz -= 12; + } + } + + else if( sb_snum&(1<<3) ) + { // aim_up + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_AIMUP,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + // running + if( sb_snum&(1<<5) ) p->horiz += 6; + p->horiz += 6; + } + } + + else if( sb_snum&(1<<4) ) + { // aim_down + SetGameVarID(g_iReturnVarID,0,pi,snum); + OnEvent(EVENT_AIMDOWN,pi,snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + // running + if( sb_snum&(1<<5) ) p->horiz -= 6; + p->horiz -= 6; + } + } + if(p->return_to_center > 0) + if( (sb_snum&(1<<13)) == 0 && (sb_snum&(1<<14)) == 0 ) + { + p->return_to_center--; + p->horiz += 33-(p->horiz/3); + } + + if(p->hard_landing > 0) + { + p->hard_landing--; + p->horiz -= (p->hard_landing<<4); + } + + if(p->aim_mode) + p->horiz += sync[snum].horz>>1; + else + { + if( p->horiz > 95 && p->horiz < 105) p->horiz = 100; + if( p->horizoff > -5 && p->horizoff < 5) p->horizoff = 0; + } + + if(p->horiz > 299) p->horiz = 299; + else if(p->horiz < -99) p->horiz = -99; + + //Shooting code/changes + + if(p->show_empty_weapon > 0) + { + p->show_empty_weapon--; + if(p->show_empty_weapon == 0 && (p->weaponswitch & 2)) + { + if(p->last_full_weapon == GROW_WEAPON) + p->subweapon |= (1<last_full_weapon == SHRINKER_WEAPON) + p->subweapon &= ~(1<last_full_weapon ); + return; + } + } + + if(p->knee_incs > 0) + { + p->knee_incs++; + p->horiz -= 48; + p->return_to_center = 9; + if(p->knee_incs > 15) + { + p->knee_incs = 0; + p->holster_weapon = 0; + if(p->weapon_pos < 0) + p->weapon_pos = -p->weapon_pos; + if(p->actorsqu >= 0 && dist(&sprite[pi],&sprite[p->actorsqu]) < 1400 ) + { + guts(&sprite[p->actorsqu],JIBS6,7,myconnectindex); + spawn(p->actorsqu,BLOODPOOL); + spritesound(SQUISHED,p->actorsqu); + switch(dynamictostatic[sprite[p->actorsqu].picnum]) + { + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case PODFEM1__STATIC: + case NAKED1__STATIC: + case STATUE__STATIC: + if(sprite[p->actorsqu].yvel) + operaterespawns(sprite[p->actorsqu].yvel); + break; + } + + if(sprite[p->actorsqu].picnum == APLAYER) + { + quickkill(&ps[sprite[p->actorsqu].yvel]); + ps[sprite[p->actorsqu].yvel].frag_ps = snum; + } + else if(badguy(&sprite[p->actorsqu])) + { + deletesprite(p->actorsqu); + p->actors_killed++; + } + else deletesprite(p->actorsqu); + } + p->actorsqu = -1; + } + else if(p->actorsqu >= 0) + p->ang += getincangle(p->ang,getangle(sprite[p->actorsqu].x-p->posx,sprite[p->actorsqu].y-p->posy))>>2; + } + + if( doincrements(p) ) return; + + if(p->weapon_pos != 0) + { + if(p->weapon_pos == -9) + { + if(p->last_weapon >= 0) + { + p->weapon_pos = 10; + // if(p->curr_weapon == KNEE_WEAPON) *kb = 1; + p->last_weapon = -1; + } + else if(p->holster_weapon == 0) + p->weapon_pos = 10; + } + else p->weapon_pos--; + } + + // HACKS + +SHOOTINCODE: + //#define WEAPON2_CLIP 20 + // reload clip + if( sb_snum & (1<<19) ) // 'Holster Weapon + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + SetGameVarID(g_iWeaponVarID,p->curr_weapon,pi,snum); + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum],pi,snum); + OnEvent(EVENT_HOLSTER, pi, snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + + // now it uses the game definitions... + if( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_HOLSTER_CLEARS_CLIP) + { + if( p->ammo_amount[p->curr_weapon] > aplWeaponClip[p->curr_weapon][snum] + && (p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum]) != 0 ) + { + // throw away the remaining clip + p->ammo_amount[p->curr_weapon]-= + p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum] ; + // (*kb) = aplWeaponFireDelay[p->curr_weapon][snum]+1; // animate, but don't shoot... + (*kb) = aplWeaponTotalTime[p->curr_weapon][snum]; // animate, but don't shoot... + sb_snum &= ~(1<<2); // not firing... + } + return; + } + } + } + + if( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_GLOWS) + //== SHRINKER_WEAPON || p->curr_weapon == GROW_WEAPON ) + p->random_club_frame += 64; // Glowing + + if(p->rapid_fire_hold == 1) + { + if( sb_snum&(1<<2) ) return; + p->rapid_fire_hold = 0; + } + if(shrunk || p->tipincs || p->access_incs) + sb_snum &= ~(1<<2); + else if ( shrunk == 0 && (sb_snum&(1<<2)) && (*kb) == 0 && p->fist_incs == 0 && + p->last_weapon == -1 && ( p->weapon_pos == 0 || p->holster_weapon == 1 ) ) + { + + p->crack_time = 777; + + if(p->holster_weapon == 1) + { + if( p->last_pissed_time <= (26*218) && p->weapon_pos == -9) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + FTA(74,p); + } + } + else + { + SetGameVarID(g_iReturnVarID,0,pi,snum); + SetGameVarID(g_iWeaponVarID,p->curr_weapon,pi,snum); + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum],pi,snum); + OnEvent(EVENT_FIRE, pi, snum, -1); + if(GetGameVarID(g_iReturnVarID,pi,snum) == 0) + { + + switch(aplWeaponWorksLike[p->curr_weapon][snum]) + { + case HANDBOMB_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + + p->hbomb_hold_delay = 0; + if( p->ammo_amount[p->curr_weapon] > 0 ) + { + (*kb)=1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + break; + + case HANDREMOTE_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + p->hbomb_hold_delay = 0; + (*kb) = 1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + break; + + case SHOTGUN_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + if( p->ammo_amount[p->curr_weapon] > 0 && p->random_club_frame == 0 ) + { + (*kb)=1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + break; + + case TRIPBOMB_WEAPON: + if ( p->ammo_amount[p->curr_weapon] > 0 ) + { + long sx,sy,sz; + short sect,hw,hitsp; + + hitscan( p->posx, p->posy, p->posz, + p->cursectnum, sintable[(p->ang+512)&2047], + sintable[p->ang&2047], (100-p->horiz-p->horizoff)*32, + §, &hw, &hitsp, &sx, &sy, &sz,CLIPMASK1); + + if(sect < 0 || hitsp >= 0) + break; + + if( hw >= 0 && sector[sect].lotag > 2 ) + break; + + if(hw >= 0 && wall[hw].overpicnum >= 0) + if(wall[hw].overpicnum == BIGFORCE) + break; + + j = headspritesect[sect]; + while(j >= 0) + { + if( sprite[j].picnum == TRIPBOMB && + klabs(sprite[j].z-sz) < (12<<8) && ((sprite[j].x-sx)*(sprite[j].x-sx)+(sprite[j].y-sy)*(sprite[j].y-sy)) < (290*290) ) + break; + j = nextspritesect[j]; + } + + if(j == -1 && hw >= 0 && (wall[hw].cstat&16) == 0 ) + if( ( wall[hw].nextsector >= 0 && sector[wall[hw].nextsector].lotag <= 2 ) || ( wall[hw].nextsector == -1 && sector[sect].lotag <= 2 ) ) + if( ( (sx-p->posx)*(sx-p->posx) + (sy-p->posy)*(sy-p->posy) ) < (290*290) ) + { + p->posz = p->oposz; + p->poszv = 0; + (*kb) = 1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + } + break; + + case PISTOL_WEAPON: + case CHAINGUN_WEAPON: + case SHRINKER_WEAPON: + case GROW_WEAPON: + case FREEZE_WEAPON: + case RPG_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + if ( p->ammo_amount[p->curr_weapon] > 0) + { + (*kb) = 1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + break; + + case DEVISTATOR_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + if( p->ammo_amount[p->curr_weapon] > 0 ) + { + (*kb) = 1; + p->hbomb_hold_delay = !p->hbomb_hold_delay; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + break; + + case KNEE_WEAPON: + OnEvent(EVENT_FIREWEAPON, p->i, snum, -1); + if(p->quick_kick == 0) + { + (*kb) = 1; + if(aplWeaponInitialSound[p->curr_weapon][snum]) + { + spritesound(aplWeaponInitialSound[p->curr_weapon][snum], pi); + } + } + break; + } + } + } + } + else if((*kb)) + { + // already firing... + + //Bsprintf(g_szBuf,"%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + if(aplWeaponWorksLike[p->curr_weapon][snum] == HANDBOMB_WEAPON) + { + if( aplWeaponHoldDelay[p->curr_weapon][snum] // there is a hold delay + && ((*kb) == aplWeaponFireDelay[p->curr_weapon][snum]) // and we are 'at' hold + && (sb_snum&(1<<2)) // and 'fire' button is still down + ) + // just hold here... + { + //AddLog("Holding HANDBOMB"); + p->rapid_fire_hold = 1; + return; + } + (*kb)++; + if((*kb)==aplWeaponHoldDelay[p->curr_weapon][snum]) + { + long lPipeBombControl; + + // AddLog("Releasing HANDBOMB"); + p->ammo_amount[p->curr_weapon]--; + + if(p->on_ground && (sb_snum&2) ) + { + k = 15; + i = ((p->horiz+p->horizoff-100)*20); + } + else + { + k = 140; + i = -512-((p->horiz+p->horizoff-100)*20); + } + + j = EGS(p->cursectnum, + p->posx+(sintable[(p->ang+512)&2047]>>6), + p->posy+(sintable[p->ang&2047]>>6), + p->posz,aplWeaponShoots[p->curr_weapon][snum],-16,9,9, + p->ang,(k+(p->hbomb_hold_delay<<5)),i,pi,1); + + lPipeBombControl=GetGameVar("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum); + + if(lPipeBombControl & PIPEBOMB_TIMER) + { + long lGrenadeLifetime=GetGameVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, -1, snum); + long lGrenadeLifetimeVar=GetGameVar("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, -1, snum); + //Bsprintf(g_szBuf,"Lifetime=%ld Var=%ld snum=%d",lGrenadeLifetime, lGrenadeLifetimeVar, snum); + //AddLog(g_szBuf); + // set timer. blows up when at zero.... + hittype[j].temp_data[7]=lGrenadeLifetime + + mulscale(krand(),lGrenadeLifetimeVar, 14) + - lGrenadeLifetimeVar; + hittype[j].temp_data[6]=1; + } + else + hittype[j].temp_data[6]=2; + + if(k == 15) + { + sprite[j].yvel = 3; + sprite[j].z += (8<<8); + } + + k = hits(pi); + if( k < 512 ) + { + sprite[j].ang += 1024; + sprite[j].zvel /= 3; + sprite[j].xvel /= 3; + } + + p->hbomb_on = 1; + + } + else if( (*kb) < aplWeaponHoldDelay[p->curr_weapon][snum] && (sb_snum&(1<<2)) ) + { + p->hbomb_hold_delay++; + } + else if( (*kb) > aplWeaponTotalTime[p->curr_weapon][snum] ) + { + long lPipeBombControl=GetGameVar("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum); + + (*kb) = 0; + + if(lPipeBombControl == PIPEBOMB_REMOTE) + { + p->curr_weapon = HANDREMOTE_WEAPON; + p->last_weapon = -1; + p->weapon_pos = 10; + } + else + checkavailweapon(p); + } + } + else if(aplWeaponWorksLike[p->curr_weapon][snum] == HANDREMOTE_WEAPON) + { + (*kb)++; + + if((*kb) == aplWeaponFireDelay[p->curr_weapon][snum]) + { + if( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_BOMB_TRIGGER) + { + p->hbomb_on = 0; + } + if(aplWeaponShoots[p->curr_weapon][snum] != 0) + { + if(! (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_NOVISIBLE )) + { + // make them visible if not set... + lastvisinc = totalclock+32; + p->visibility = 0; + } + SetGameVarID(g_iWeaponVarID,p->curr_weapon,p->i,snum); + SetGameVarID(g_iWorksLikeVarID,aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + shoot(pi, aplWeaponShoots[p->curr_weapon][snum]); + } + } + + if((*kb) >= aplWeaponTotalTime[p->curr_weapon][snum]) + { + long lPipeBombControl=GetGameVar("PIPEBOMB_CONTROL", PIPEBOMB_REMOTE, -1, snum); + (*kb) = 0; + /// WHAT THE HELL DOES THIS DO....????????????? + if((p->ammo_amount[HANDBOMB_WEAPON] > 0) && lPipeBombControl == PIPEBOMB_REMOTE) + addweapon(p,HANDBOMB_WEAPON); + else + checkavailweapon(p); + } + } + else + { + // the basic weapon... + (*kb)++; + + if(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_CHECKATRELOAD) + { + if (aplWeaponWorksLike[p->curr_weapon][snum] == TRIPBOMB_WEAPON) + { + if((*kb) >= aplWeaponTotalTime[p->curr_weapon][snum]) + { + (*kb) = 0; + checkavailweapon(p); + p->weapon_pos = -9; + } + } + else if(*kb >= aplWeaponReload[p->curr_weapon][snum]) + { + checkavailweapon(p); + } + } + + else if(aplWeaponWorksLike[p->curr_weapon][snum]!=KNEE_WEAPON && *kb >= aplWeaponFireDelay[p->curr_weapon][snum]) + { + checkavailweapon(p); + } + + if( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_STANDSTILL + && *kb < (aplWeaponFireDelay[p->curr_weapon][snum]+1) ) + { + p->posz = p->oposz; + p->poszv = 0; + } + if(*kb == aplWeaponSound2Time[p->curr_weapon][snum]) + { + //AddLog("Sound2Time"); + if(aplWeaponSound2Sound[p->curr_weapon][snum]) + { + spritesound(aplWeaponSound2Sound[p->curr_weapon][snum],pi); + } + } + if(*kb == aplWeaponSpawnTime[p->curr_weapon][snum]) + { + //AddLog("SpawnTime"); + DoSpawn(snum); + } + + if ( *kb > aplWeaponFireDelay[p->curr_weapon][snum] + && (*kb) < aplWeaponTotalTime[p->curr_weapon][snum] + && (aplWeaponWorksLike[p->curr_weapon][snum] & KNEE_WEAPON ? 1 : p->ammo_amount[p->curr_weapon] > 0)) + { + //Bsprintf(g_szBuf,"%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + // we are waiting for initial fire to complete + + if ( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_AUTOMATIC) + { // an 'automatic' + //Bsprintf(g_szBuf,"%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + if( ( sb_snum&(1<<2) ) == 0 ) + { + // 'fire' not still down... stop... + //Bsprintf(g_szBuf,"%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + // *kb = 0; + + // check for clip change... + *kb = aplWeaponTotalTime[p->curr_weapon][snum]; + // break; + } + + if ( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_FIREEVERYTHIRD) + { + if( ((*(kb))%3) == 0 ) + { + DoFire(snum); + DoSpawn(snum); + } + } + if( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_FIREEVERYOTHER) + { + // fire every other... + DoFire(snum); + DoSpawn(snum); + } + + } // 'automatic + } + else if(*kb == aplWeaponFireDelay[p->curr_weapon][snum] + && (aplWeaponWorksLike[p->curr_weapon][snum]==KNEE_WEAPON ? 1 : p->ammo_amount[p->curr_weapon] > 0)) + { + //Bsprintf(g_szBuf,"FireDelayTime:%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + //AddLog("FireDelay Time"); + DoFire(snum); + } + else if ((*kb) >= aplWeaponTotalTime[p->curr_weapon][snum]) + { + //Bsprintf(g_szBuf,"end of TotalTime(%ld) %s %ld, kb=%d %ld", + // aplWeaponTotalTime[p->curr_weapon][snum], + // __FILE__,__LINE__,*kb, + // aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + // we are >= total time... + if( //!(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_CHECKATRELOAD) && + (aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum] + && p->ammo_amount[p->curr_weapon] > 0 + && (aplWeaponClip[p->curr_weapon][snum]) + && (((p->ammo_amount[p->curr_weapon]%(aplWeaponClip[p->curr_weapon][snum]))==0))) || p->reloading == 1 ) + { + // reload in progress... + int i; + //Bsprintf(g_szBuf,"C %s %ld, kb=%d",__FILE__,__LINE__,*kb); + //AddLog(g_szBuf); + //Bsprintf(g_szBuf,"ammo=%d clip=%ld mod=%ld",p->ammo_amount[p->curr_weapon], + // aplWeaponClip[p->curr_weapon][snum], + // (p->ammo_amount[p->curr_weapon]%(aplWeaponClip[p->curr_weapon][snum])) + // ); + //AddLog(g_szBuf); + + i=aplWeaponReload[p->curr_weapon][snum] - aplWeaponTotalTime[p->curr_weapon][snum]; + // time for 'reload' + p->reloading = 1; + if( (*kb) == (aplWeaponTotalTime[p->curr_weapon][snum] + 1)) + { // eject shortly after 'total time' + if(aplWeaponReloadSound1[p->curr_weapon][snum]) + spritesound(aplWeaponReloadSound1[p->curr_weapon][snum],pi); + } + else if( ((*kb) == (aplWeaponReload[p->curr_weapon][snum] - (i/3)) && + !(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_RELOAD_TIMING)) || + ((*kb) == (aplWeaponReload[p->curr_weapon][snum] - i+4) && + (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_RELOAD_TIMING)) ) + { + // insert occurs 2/3 of way through reload delay + if(aplWeaponReloadSound2[p->curr_weapon][snum]) + spritesound(aplWeaponReloadSound2[p->curr_weapon][snum],pi); + } + + else if( (*kb) >= (aplWeaponReload[p->curr_weapon][snum]) ) + { + *kb=0; + p->reloading = 0; + } + + } + else + { + //Bsprintf(g_szBuf,"NC %s %ld, kb=%d",__FILE__,__LINE__,*kb); + //AddLog(g_szBuf); + // no clip reload going on... + if ( aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_AUTOMATIC + && (aplWeaponWorksLike[p->curr_weapon][snum]==KNEE_WEAPON ? 1 : p->ammo_amount[p->curr_weapon] > 0)) + { // an 'automatic' + if( sb_snum&(1<<2) ) + { + // we are an AUTOMATIC. Fire again... + if(aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_RANDOMRESTART) + { + *kb = 1+(TRAND&3); + } + else + { + *kb=1; + } + } + else + { + //Bsprintf(g_szBuf,"NC %s %ld, kb=%d",__FILE__,__LINE__,*kb); + //AddLog(g_szBuf); + // time to recycle automatic fire + *kb = 0; + } + } + else + { // not 'automatic' and >totaltime + //Bsprintf(g_szBuf,"NA %s %ld, kb=%d",__FILE__,__LINE__,*kb); + //AddLog(g_szBuf); + *kb=0; + } + } + } + } + + //Bsprintf(g_szBuf,"%s %ld, kb=%d %ld",__FILE__,__LINE__,*kb,aplWeaponWorksLike[p->curr_weapon][snum]); + //AddLog(g_szBuf); + + } + +} + +//UPDATE THIS FILE OVER THE OLD GETSPRITESCORE/COMPUTERGETINPUT FUNCTIONS +int getspritescore(long snum, long dapicnum) +{ + switch(dynamictostatic[dapicnum]) + { + case FIRSTGUNSPRITE__STATIC: return(20); + case CHAINGUNSPRITE__STATIC: return(50); + case RPGSPRITE__STATIC: return(200); + case FREEZESPRITE__STATIC: return(25); + case SHRINKERSPRITE__STATIC: return(80); + case HEAVYHBOMB__STATIC: return(60); + case TRIPBOMBSPRITE__STATIC: return(50); + case SHOTGUNSPRITE__STATIC: return(120); + case DEVISTATORSPRITE__STATIC: return(120); + + case FREEZEAMMO__STATIC: if (ps[snum].ammo_amount[FREEZE_WEAPON] < max_ammo_amount[FREEZE_WEAPON]) return(10); else return(0); + case AMMO__STATIC: if (ps[snum].ammo_amount[PISTOL_WEAPON] < max_ammo_amount[PISTOL_WEAPON]) return(10); else return(0); + case BATTERYAMMO__STATIC: if (ps[snum].ammo_amount[CHAINGUN_WEAPON] < max_ammo_amount[CHAINGUN_WEAPON]) return(20); else return(0); + case DEVISTATORAMMO__STATIC: if (ps[snum].ammo_amount[DEVISTATOR_WEAPON] < max_ammo_amount[DEVISTATOR_WEAPON]) return(25); else return(0); + case RPGAMMO__STATIC: if (ps[snum].ammo_amount[RPG_WEAPON] < max_ammo_amount[RPG_WEAPON]) return(50); else return(0); + case CRYSTALAMMO__STATIC: if (ps[snum].ammo_amount[SHRINKER_WEAPON] < max_ammo_amount[SHRINKER_WEAPON]) return(10); else return(0); + case HBOMBAMMO__STATIC: if (ps[snum].ammo_amount[HANDBOMB_WEAPON] < max_ammo_amount[HANDBOMB_WEAPON]) return(30); else return(0); + case SHOTGUNAMMO__STATIC: if (ps[snum].ammo_amount[SHOTGUN_WEAPON] < max_ammo_amount[SHOTGUN_WEAPON]) return(25); else return(0); + + case COLA__STATIC: if (sprite[ps[snum].i].extra < 100) return(10); else return(0); + case SIXPAK__STATIC: if (sprite[ps[snum].i].extra < 100) return(30); else return(0); + case FIRSTAID__STATIC: if (ps[snum].firstaid_amount < 100) return(100); else return(0); + case SHIELD__STATIC: if (ps[snum].shield_amount < 100) return(50); else return(0); + case STEROIDS__STATIC: if (ps[snum].steroids_amount < 400) return(30); else return(0); + case AIRTANK__STATIC: if (ps[snum].scuba_amount < 6400) return(30); else return(0); + case JETPACK__STATIC: if (ps[snum].jetpack_amount < 1600) return(100); else return(0); + case HEATSENSOR__STATIC: if (ps[snum].heat_amount < 1200) return(5); else return(0); + case ACCESSCARD__STATIC: return(1); + case BOOTS__STATIC: if (ps[snum].boot_amount < 200) return(15); else return(0); + case ATOMICHEALTH__STATIC: if (sprite[ps[snum].i].extra < max_player_health<<1) return(50); else return(0); + case HOLODUKE__STATIC: if (ps[snum].holoduke_amount < 2400) return(5); else return(0); + + case SECTOREFFECTOR__STATIC: return(1); + case TOUCHPLATE__STATIC: return(1); + case MUSICANDSFX__STATIC: return(1); + } + return(0); +} + +static long fdmatrix[12][12] = + { + //KNEE PIST SHOT CHAIN RPG PIPE SHRI DEVI WALL FREE HAND EXPA + { 128, -1, -1, -1, 128, -1, -1, -1, 128, -1, 128, -1 }, //KNEE + { 1024,1024,1024,1024,2560, 128,2560,2560,1024,2560,2560,2560 }, //PIST + { 512, 512, 512, 512,2560, 128,2560,2560,1024,2560,2560,2560 }, //SHOT + { 512, 512, 512, 512,2560, 128,2560,2560,1024,2560,2560,2560 }, //CHAIN + { 2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560 }, //RPG + { 512, 512, 512, 512,2048, 512,2560,2560, 512,2560,2560,2560 }, //PIPE + { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 }, //SHRI + { 1536,1536,1536,1536,2560,1536,1536,1536,1536,1536,1536,1536 }, //DEVI + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, //WALL + { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 }, //FREE + { 2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560 }, //HAND + { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 } //EXPA + }; + +static long goalx[MAXPLAYERS], goaly[MAXPLAYERS], goalz[MAXPLAYERS]; +static long goalsect[MAXPLAYERS], goalwall[MAXPLAYERS], goalsprite[MAXPLAYERS]; +static long goalplayer[MAXPLAYERS], clipmovecount[MAXPLAYERS]; +short searchsect[MAXSECTORS], searchparent[MAXSECTORS]; +char dashow2dsector[(MAXSECTORS+7)>>3]; +void computergetinput(long snum, input *syn) +{ + long i, j, k, l, x1, y1, z1, x2, y2, z2, x3, y3, z3, dx, dy; + long dist, daang, zang, fightdist, damyang, damysect; + long startsect, endsect, splc, send, startwall, endwall; + short dasect, dawall, daspr; + struct player_struct *p; + walltype *wal; + + p = &ps[snum]; + syn->fvel = 0; + syn->svel = 0; + syn->avel = 0; + syn->horz = 0; + syn->bits = 0; + + x1 = sprite[p->i].x; + y1 = sprite[p->i].y; + z1 = sprite[p->i].z; + damyang = sprite[p->i].ang; + damysect = sprite[p->i].sectnum; + if ((numplayers >= 2) && (snum == myconnectindex)) + { x1 = myx; y1 = myy; z1 = myz+PHEIGHT; damyang = myang; damysect = mycursectnum; } + + if (!(numframes&7)) + { + x2 = sprite[ps[goalplayer[snum]].i].x; + y2 = sprite[ps[goalplayer[snum]].i].y; + z2 = sprite[ps[goalplayer[snum]].i].z; + + if (!cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[goalplayer[snum]].i].sectnum)) + goalplayer[snum] = snum; + } + + if ((goalplayer[snum] == snum) || (ps[goalplayer[snum]].dead_flag != 0)) + { + j = 0x7fffffff; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != snum) + { + dist = ksqrt((sprite[ps[i].i].x-x1)*(sprite[ps[i].i].x-x1)+(sprite[ps[i].i].y-y1)*(sprite[ps[i].i].y-y1)); + + x2 = sprite[ps[i].i].x; + y2 = sprite[ps[i].i].y; + z2 = sprite[ps[i].i].z; + if (!cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[i].i].sectnum)) + dist <<= 1; + + if (dist < j) { j = dist; goalplayer[snum] = i; } + } + } + + x2 = sprite[ps[goalplayer[snum]].i].x; + y2 = sprite[ps[goalplayer[snum]].i].y; + z2 = sprite[ps[goalplayer[snum]].i].z; + + if (p->dead_flag) syn->bits |= (1<<29); + if ((p->firstaid_amount > 0) && (p->last_extra < 100)) + syn->bits |= (1<<16); + + for(j=headspritestat[4];j>=0;j=nextspritestat[j]) + { + switch (dynamictostatic[sprite[j].picnum]) + { + case TONGUE__STATIC: k = 4; break; + case FREEZEBLAST__STATIC: k = 4; break; + case SHRINKSPARK__STATIC: k = 16; break; + case RPG__STATIC: k = 16; break; + default: k = 0; break; + } + if (k) + { + x3 = sprite[j].x; + y3 = sprite[j].y; + z3 = sprite[j].z; + for(l=0;l<=8;l++) + { + if (tmulscale11(x3-x1,x3-x1,y3-y1,y3-y1,(z3-z1)>>4,(z3-z1)>>4) < 3072) + { + dx = sintable[(sprite[j].ang+512)&2047]; + dy = sintable[sprite[j].ang&2047]; + if ((x1-x3)*dy > (y1-y3)*dx) i = -k*512; else i = k*512; + syn->fvel -= mulscale17(dy,i); + syn->svel += mulscale17(dx,i); + } + if (l < 7) + { + x3 += (mulscale14(sprite[j].xvel,sintable[(sprite[j].ang+512)&2047])<<2); + y3 += (mulscale14(sprite[j].xvel,sintable[sprite[j].ang&2047])<<2); + z3 += (sprite[j].zvel<<2); + } + else + { + hitscan(sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum, + mulscale14(sprite[j].xvel,sintable[(sprite[j].ang+512)&2047]), + mulscale14(sprite[j].xvel,sintable[sprite[j].ang&2047]), + (long)sprite[j].zvel, + &dasect,&dawall,&daspr,&x3,&y3,&z3,CLIPMASK1); + } + } + } + } + + if ((ps[goalplayer[snum]].dead_flag == 0) && + ((cansee(x1,y1,z1,damysect,x2,y2,z2,sprite[ps[goalplayer[snum]].i].sectnum)) || + (cansee(x1,y1,z1-(24<<8),damysect,x2,y2,z2-(24<<8),sprite[ps[goalplayer[snum]].i].sectnum)) || + (cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[goalplayer[snum]].i].sectnum)))) + { + syn->bits |= (1<<2); + + if ((p->curr_weapon == HANDBOMB_WEAPON) && (!(rand()&7))) + syn->bits &= ~(1<<2); + + if (p->curr_weapon == TRIPBOMB_WEAPON) + syn->bits |= ((rand()%MAX_WEAPONS)<<8); + + if (p->curr_weapon == RPG_WEAPON) + { + hitscan(x1,y1,z1-PHEIGHT,damysect,sintable[(damyang+512)&2047],sintable[damyang&2047], + (100-p->horiz-p->horizoff)*32,&dasect,&dawall,&daspr,&x3,&y3,&z3,CLIPMASK1); + if ((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1) < 2560*2560) syn->bits &= ~(1<<2); + } + + + fightdist = fdmatrix[p->curr_weapon][ps[goalplayer[snum]].curr_weapon]; + if (fightdist < 128) fightdist = 128; + dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (dist == 0) dist = 1; + daang = getangle(x2+(ps[goalplayer[snum]].posxv>>14)-x1,y2+(ps[goalplayer[snum]].posyv>>14)-y1); + zang = 100-((z2-z1)*8)/dist; + fightdist = max(fightdist,(klabs(z2-z1)>>4)); + + if (sprite[ps[goalplayer[snum]].i].yrepeat < 32) + { fightdist = 0; syn->bits &= ~(1<<2); } + if (sprite[ps[goalplayer[snum]].i].pal == 1) + { fightdist = 0; syn->bits &= ~(1<<2); } + + if (dist < 256) syn->bits |= (1<<22); + + x3 = x2+((x1-x2)*fightdist/dist); + y3 = y2+((y1-y2)*fightdist/dist); + syn->fvel += (x3-x1)*2047/dist; + syn->svel += (y3-y1)*2047/dist; + + //Strafe attack + if (fightdist) + { + j = totalclock+snum*13468; + i = sintable[(j<<6)&2047]; + i += sintable[((j+4245)<<5)&2047]; + i += sintable[((j+6745)<<4)&2047]; + i += sintable[((j+15685)<<3)&2047]; + dx = sintable[(sprite[ps[goalplayer[snum]].i].ang+512)&2047]; + dy = sintable[sprite[ps[goalplayer[snum]].i].ang&2047]; + if ((x1-x2)*dy > (y1-y2)*dx) i += 8192; else i -= 8192; + syn->fvel += ((sintable[(daang+1024)&2047]*i)>>17); + syn->svel += ((sintable[(daang+512)&2047]*i)>>17); + } + + syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>1,-127),127); + syn->horz = min(max((zang-p->horiz)>>1,-MAXHORIZ),MAXHORIZ); + syn->bits |= (1<<23); + return; + } + + goalsect[snum] = -1; + if (goalsect[snum] < 0) + { + goalwall[snum] = -1; + startsect = sprite[p->i].sectnum; + endsect = sprite[ps[goalplayer[snum]].i].sectnum; + + clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L); + searchsect[0] = startsect; + searchparent[0] = -1; + dashow2dsector[startsect>>3] |= (1<<(startsect&7)); + for(splc=0,send=1;splcnextsector; if (j < 0) continue; + + dx = ((wall[wal->point2].x+wal->x)>>1); + dy = ((wall[wal->point2].y+wal->y)>>1); + if ((getceilzofslope(j,dx,dy) > getflorzofslope(j,dx,dy)-(28<<8)) && ((sector[j].lotag < 15) || (sector[j].lotag > 22))) + continue; + if (getflorzofslope(j,dx,dy) < getflorzofslope(searchsect[splc],dx,dy)-(72<<8)) + continue; + if ((dashow2dsector[j>>3]&(1<<(j&7))) == 0) + { + dashow2dsector[j>>3] |= (1<<(j&7)); + searchsect[send] = (short)j; + searchparent[send] = (short)splc; + send++; + if (j == endsect) + { + clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L); + for(k=send-1;k>=0;k=searchparent[k]) + dashow2dsector[searchsect[k]>>3] |= (1<<(searchsect[k]&7)); + + for(k=send-1;k>=0;k=searchparent[k]) + if (!searchparent[k]) break; + + goalsect[snum] = searchsect[k]; + startwall = sector[goalsect[snum]].wallptr; + endwall = startwall+sector[goalsect[snum]].wallnum; + x3 = y3 = 0; + for(i=startwall;i= dy*(x2-wall[i].x)) + if ((x3-x1)*(wall[i].y-y1) <= (y3-y1)*(wall[i].x-x1)) + if ((x3-x1)*(wall[wall[i].point2].y-y1) >= (y3-y1)*(wall[wall[i].point2].x-x1)) + { k = i; break; } + + dist = ksqrt(dx*dx+dy*dy); + if (dist > l) { l = dist; k = i; } + } + goalwall[snum] = k; + daang = ((getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y)+1536)&2047); + goalx[snum] = ((wall[k].x+wall[wall[k].point2].x)>>1)+(sintable[(daang+512)&2047]>>8); + goaly[snum] = ((wall[k].y+wall[wall[k].point2].y)>>1)+(sintable[daang&2047]>>8); + goalz[snum] = sector[goalsect[snum]].floorz-(32<<8); + break; + } + } + } + + for(i=headspritesect[searchsect[splc]];i>=0;i=nextspritesect[i]) + if (sprite[i].lotag == 7) + { + j = sprite[sprite[i].owner].sectnum; + if ((dashow2dsector[j>>3]&(1<<(j&7))) == 0) + { + dashow2dsector[j>>3] |= (1<<(j&7)); + searchsect[send] = (short)j; + searchparent[send] = (short)splc; + send++; + if (j == endsect) + { + clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L); + for(k=send-1;k>=0;k=searchparent[k]) + dashow2dsector[searchsect[k]>>3] |= (1<<(searchsect[k]&7)); + + for(k=send-1;k>=0;k=searchparent[k]) + if (!searchparent[k]) break; + + goalsect[snum] = searchsect[k]; + startwall = sector[startsect].wallptr; + endwall = startwall+sector[startsect].wallnum; + l = 0; k = startwall; + for(i=startwall;i l)) + { l = dist; k = i; } + } + goalwall[snum] = k; + daang = ((getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y)+1536)&2047); + goalx[snum] = ((wall[k].x+wall[wall[k].point2].x)>>1)+(sintable[(daang+512)&2047]>>8); + goaly[snum] = ((wall[k].y+wall[wall[k].point2].y)>>1)+(sintable[daang&2047]>>8); + goalz[snum] = sector[goalsect[snum]].floorz-(32<<8); + break; + } + } + } + if (goalwall[snum] >= 0) break; + } + } + + if ((goalsect[snum] < 0) || (goalwall[snum] < 0)) + { + if (goalsprite[snum] < 0) + { + for(k=0;k<4;k++) + { + i = (rand()%numsectors); + for(j=headspritesect[i];j>=0;j=nextspritesect[j]) + { + if ((sprite[j].xrepeat <= 0) || (sprite[j].yrepeat <= 0)) continue; + if (getspritescore(snum,sprite[j].picnum) <= 0) continue; + if (cansee(x1,y1,z1-(32<<8),damysect,sprite[j].x,sprite[j].y,sprite[j].z-(4<<8),i)) + { goalx[snum] = sprite[j].x; goaly[snum] = sprite[j].y; goalz[snum] = sprite[j].z; goalsprite[snum] = j; break; } + } + } + } + x2 = goalx[snum]; + y2 = goaly[snum]; + dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (!dist) return; + daang = getangle(x2-x1,y2-y1); + syn->fvel += (x2-x1)*2047/dist; + syn->svel += (y2-y1)*2047/dist; + syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>3,-127),127); + } + else + goalsprite[snum] = -1; + + x3 = p->posx; y3 = p->posy; z3 = p->posz; dasect = p->cursectnum; + i = clipmove(&x3,&y3,&z3,&dasect,p->posxv,p->posyv,164L,4L<<8,4L<<8,CLIPMASK0); + if (!i) + { + x3 = p->posx; y3 = p->posy; z3 = p->posz+(24<<8); dasect = p->cursectnum; + i = clipmove(&x3,&y3,&z3,&dasect,p->posxv,p->posyv,164L,4L<<8,4L<<8,CLIPMASK0); + } + if (i) + { + clipmovecount[snum]++; + + j = 0; + if ((i&0xc000) == 32768) //Hit a wall (49152 for sprite) + if (wall[i&(MAXWALLS-1)].nextsector >= 0) + { + if (getflorzofslope(wall[i&(MAXWALLS-1)].nextsector,p->posx,p->posy) <= p->posz+(24<<8)) j |= 1; + if (getceilzofslope(wall[i&(MAXWALLS-1)].nextsector,p->posx,p->posy) >= p->posz-(24<<8)) j |= 2; + } + if ((i&0xc000) == 49152) j = 1; + if (j&1) if (clipmovecount[snum] == 4) syn->bits |= (1<<0); + if (j&2) syn->bits |= (1<<1); + + //Strafe attack + daang = getangle(x2-x1,y2-y1); + if ((i&0xc000) == 32768) + daang = getangle(wall[wall[i&(MAXWALLS-1)].point2].x-wall[i&(MAXWALLS-1)].x,wall[wall[i&(MAXWALLS-1)].point2].y-wall[i&(MAXWALLS-1)].y); + j = totalclock+snum*13468; + i = sintable[(j<<6)&2047]; + i += sintable[((j+4245)<<5)&2047]; + i += sintable[((j+6745)<<4)&2047]; + i += sintable[((j+15685)<<3)&2047]; + syn->fvel += ((sintable[(daang+1024)&2047]*i)>>17); + syn->svel += ((sintable[(daang+512)&2047]*i)>>17); + + if ((clipmovecount[snum]&31) == 2) syn->bits |= (1<<29); + if ((clipmovecount[snum]&31) == 17) syn->bits |= (1<<22); + if (clipmovecount[snum] > 32) { goalsect[snum] = -1; goalwall[snum] = -1; clipmovecount[snum] = 0; } + + goalsprite[snum] = -1; + } + else + clipmovecount[snum] = 0; + + if ((goalsect[snum] >= 0) && (goalwall[snum] >= 0)) + { + x2 = goalx[snum]; + y2 = goaly[snum]; + dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (!dist) return; + daang = getangle(x2-x1,y2-y1); + if ((goalwall[snum] >= 0) && (dist < 4096)) + daang = ((getangle(wall[wall[goalwall[snum]].point2].x-wall[goalwall[snum]].x,wall[wall[goalwall[snum]].point2].y-wall[goalwall[snum]].y)+1536)&2047); + syn->fvel += (x2-x1)*2047/dist; + syn->svel += (y2-y1)*2047/dist; + syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>3,-127),127); + } +} + diff --git a/polymer/eduke32/source/premap.c b/polymer/eduke32/source/premap.c new file mode 100644 index 000000000..cd64deee3 --- /dev/null +++ b/polymer/eduke32/source/premap.c @@ -0,0 +1,1685 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "osd.h" + +extern char pow2char[]; + +extern char everyothertime; +static short which_palookup = 9; +char numl, useprecache = 1; +short spritecache[MAXTILES][3]; + +static char precachehightile[2][MAXTILES>>3]; +static int precachecount; + +static void tloadtile(short tilenume, char type) +{ + if ((picanm[tilenume]&63) > 0) { + int i,j; + + if ((picanm[tilenume]&192)==192) { + i = tilenume - (picanm[tilenume]&63); + j = tilenume; + } else { + i = tilenume; + j = tilenume + (picanm[tilenume]&63); + } + for (;i<=j;i++) { + if (!(gotpic[i>>3] & pow2char[i&7])) precachecount++; + gotpic[i>>3] |= pow2char[i&7]; + precachehightile[type][i>>3] |= pow2char[i&7]; + } + } else { + if (!(gotpic[tilenume>>3] & pow2char[tilenume&7])) precachecount++; + gotpic[tilenume>>3] |= pow2char[tilenume&7]; + precachehightile[type][tilenume>>3] |= pow2char[tilenume&7]; + } +} + +void cachespritenum(short i) +{ + char maxc; + short j; + + if(ud.monsters_off && badguy(&sprite[i])) return; + + maxc = 1; + + if(spritecache[PN][0] == PN) + for(j = PN; j <= spritecache[PN][1]; j++) + tloadtile(j,1); + + switch(dynamictostatic[PN]) + { + case HYDRENT__STATIC: + tloadtile(BROKEFIREHYDRENT,1); + for(j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); + break; + case TOILET__STATIC: + tloadtile(TOILETBROKE,1); + for(j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); + break; + case STALL__STATIC: + tloadtile(STALLBROKE,1); + for(j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); + break; + case RUBBERCAN__STATIC: + maxc = 2; + break; + case TOILETWATER__STATIC: + maxc = 4; + break; + case FEMPIC1__STATIC: + maxc = 44; + break; + case LIZTROOP__STATIC: + case LIZTROOPRUNNING__STATIC: + case LIZTROOPSHOOT__STATIC: + case LIZTROOPJETPACK__STATIC: + case LIZTROOPONTOILET__STATIC: + case LIZTROOPDUCKING__STATIC: + for(j = LIZTROOP; j < (LIZTROOP+72); j++) tloadtile(j,1); + for(j=HEADJIB1;j 1) + { + maxc = 5; + for(j = 1420;j < 1420+106; j++) tloadtile(j,1); + } + break; + case ATOMICHEALTH__STATIC: + maxc = 14; + break; + case DRONE__STATIC: + maxc = 10; + break; + case EXPLODINGBARREL__STATIC: + case SEENINE__STATIC: + case OOZFILTER__STATIC: + maxc = 3; + break; + case NUKEBARREL__STATIC: + case CAMERA1__STATIC: + maxc = 5; + break; + // caching of HUD sprites for weapons that may be in the level + case CHAINGUNSPRITE__STATIC: for (j=CHAINGUN; j<=CHAINGUN+7; j++) tloadtile(j,1); break; + case RPGSPRITE__STATIC: for (j=RPGGUN; j<=RPGGUN+2; j++) tloadtile(j,1); break; + case FREEZESPRITE__STATIC: for (j=FREEZE; j<=FREEZE+5; j++) tloadtile(j,1); break; + case GROWSPRITEICON__STATIC: + case SHRINKERSPRITE__STATIC: for (j=SHRINKER-2; j<=SHRINKER+5; j++) tloadtile(j,1); break; + case HBOMBAMMO__STATIC: + case HEAVYHBOMB__STATIC: for (j=HANDREMOTE; j<=HANDREMOTE+5; j++) tloadtile(j,1); break; + case TRIPBOMBSPRITE__STATIC: for (j=HANDHOLDINGLASER; j<=HANDHOLDINGLASER+4; j++) tloadtile(j,1); break; + case SHOTGUNSPRITE__STATIC: tloadtile(SHOTGUNSHELL,1); for (j=SHOTGUN; j<=SHOTGUN+6; j++) tloadtile(j,1); break; + case DEVISTATORSPRITE__STATIC: for (j=DEVISTATOR; j<=DEVISTATOR+1; j++) tloadtile(j,1); break; + + } + + for(j = PN; j < (PN+maxc); j++) tloadtile(j,1); +} + +void cachegoodsprites(void) +{ + short i,j; + + for(i=0;i 1) + tloadtile(FRAGBAR,1); + + tloadtile(VIEWSCREEN,1); + + for(i=STARTALPHANUM;i= NUM_SOUNDS || SoundToggle == 0) return 0; + if (FXDevice < 0) return 0; + + if (!sounds[num][0]) return 0; + fp = kopen4load(sounds[num],loadfromgrouponly); + if(fp == -1) return 0; + + l = kfilelength( fp ); + soundsiz[num] = l; + + if( (ud.level_number == 0 && ud.volume_number == 0 && (num == 189 || num == 232 || num == 99 || num == 233 || num == 17 ) ) || + ( l < 12288 ) ) + { + Sound[num].lock = 199; + allocache((long *)&Sound[num].ptr,l,(char *)&Sound[num].lock); + if(Sound[num].ptr != NULL) + kread( fp, Sound[num].ptr , l); + } + kclose( fp ); + return 1; +} + +void precachenecessarysounds(void) +{ + short i, j; + + if (FXDevice < 0) return; + j = 0; + + for(i=0;i= 0) { + tloadtile(wall[i].overpicnum, 0); + } + } + + for(i=0;i= 0) + { + if(sprite[j].xrepeat != 0 && sprite[j].yrepeat != 0 && (sprite[j].cstat&32768) == 0) + cachespritenum(j); + j = nextspritesect[j]; + } + } + + tc = totalclock; + j = 0; + + for(i=0;i>3]) { + i+=7; + continue; + } + if(gotpic[i>>3] & pow2char[i&7]) { + if (waloff[i] == 0) + loadtile((short)i); + + if (useprecache) { + if (precachehightile[0][i>>3] & pow2char[i&7]) + for (k=0; k>3] & pow2char[i&7]) + for (k=0; k TICRATE/4) { + sprintf(tempbuf,"Loading textures ... %ld%%\n",min(100,100*pc/precachecount)); + dofrontscreens(tempbuf); + tc = totalclock; + } + } + + clearbufbyte(gotpic,sizeof(gotpic),0L); + + endtime = getticks(); + OSD_Printf("Cache time: %dms\n", endtime-starttime); +} + +void xyzmirror(short i,short wn) +{ + //if (waloff[wn] == 0) loadtile(wn); + setviewtotile(wn,tilesizy[wn],tilesizx[wn]); + + drawrooms(SX,SY,SZ,SA,100+sprite[i].shade,SECT); + display_mirror = 1; animatesprites(SX,SY,SA,65536L); display_mirror = 0; + drawmasks(); + + setviewback(); + squarerotatetile(wn); + invalidatetile(wn,-1,255); +} + +void vscrn(void) +{ + long i, j, ss, x1, x2, y1, y2; + + if(ud.screen_size < 0) ud.screen_size = 0; + else if(ud.screen_size > 63) ud.screen_size = 64; + + if(ud.screen_size == 0) flushperms(); + + ss = max(ud.screen_size-8,0); + + x1 = scale(ss,xdim,160); + x2 = xdim-x1; + + y1 = ss; y2 = 200; + if ( ud.screen_size > 0 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_FRAGBAR) && ud.multimode > 1) + { + j = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if(i > j) j = i; + + if (j >= 1) y1 += 8; + if (j >= 4) y1 += 8; + if (j >= 8) y1 += 8; + if (j >= 12) y1 += 8; + } + + if (ud.screen_size >= 8) y2 -= (ss+scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100)); + + y1 = scale(y1,ydim,200); + y2 = scale(y2,ydim,200); + + setview(x1,y1,x2-1,y2-1); + + pub = NUMPAGES; + pus = NUMPAGES; +} + +void pickrandomspot(short snum) +{ + struct player_struct *p; + short i; + + p = &ps[snum]; + + if( ud.multimode > 1 && !(gametype_flags[ud.coop] & GAMETYPE_FLAG_FIXEDRESPAWN)) + i = TRAND%numplayersprites; + else i = snum; + + p->bobposx = p->oposx = p->posx = po[i].ox; + p->bobposy = p->oposy = p->posy = po[i].oy; + p->oposz = p->posz = po[i].oz; + p->ang = po[i].oa; + p->cursectnum = po[i].os; +} + +void resetplayerstats(short snum) +{ + struct player_struct *p; + short i; + + p = &ps[snum]; + + ud.show_help = 0; + ud.showallmap = 0; + p->dead_flag = 0; + p->wackedbyactor = -1; + p->falling_counter = 0; + p->quick_kick = 0; + p->subweapon = 0; + p->last_full_weapon = 0; + p->ftq = 0; + p->fta = 0; + p->tipincs = 0; + p->buttonpalette = 0; + p->actorsqu =-1; + p->invdisptime = 0; + p->refresh_inventory= 0; + p->last_pissed_time = 0; + p->holster_weapon = 0; + p->pycount = 0; + p->pyoff = 0; + p->opyoff = 0; + p->loogcnt = 0; + p->angvel = 0; + p->weapon_sway = 0; + // p->select_dir = 0; + p->extra_extra8 = 0; + p->show_empty_weapon= 0; + p->dummyplayersprite=-1; + p->crack_time = 0; + p->hbomb_hold_delay = 0; + p->transporter_hold = 0; + p->wantweaponfire = -1; + p->hurt_delay = 0; + p->footprintcount = 0; + p->footprintpal = 0; + p->footprintshade = 0; + p->jumping_toggle = 0; + p->ohoriz = p->horiz= 140; + p->horizoff = 0; + p->bobcounter = 0; + p->on_ground = 0; + p->player_par = 0; + p->return_to_center = 9; + p->airleft = 15*26; + p->rapid_fire_hold = 0; + p->toggle_key_flag = 0; + p->access_spritenum = -1; + if(ud.multimode > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_ACCESSATSTART)) + p->got_access = 7; + else p->got_access = 0; + p->random_club_frame= 0; + pus = 1; + p->on_warping_sector = 0; + p->spritebridge = 0; + p->sbs = 0; + p->palette = (char *) &palette[0]; + + if(p->steroids_amount < 400 ) + { + p->steroids_amount = 0; + p->inven_icon = 0; + } + p->heat_on = 0; + p->jetpack_on = 0; + p->holoduke_on = -1; + + p->look_ang = 512 - ((ud.level_number&1)<<10); + + p->rotscrnang = 0; + p->orotscrnang = 1; // JBF 20031220 + p->newowner =-1; + p->jumping_counter = 0; + p->hard_landing = 0; + p->posxv = 0; + p->posyv = 0; + p->poszv = 0; + fricxv = 0; + fricyv = 0; + p->somethingonplayer =-1; + p->one_eighty_count = 0; + p->cheat_phase = 0; + + p->on_crane = -1; + + if( (aplWeaponWorksLike[p->curr_weapon][snum] == PISTOL_WEAPON) && + (aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum]) ) + p->kickback_pic = aplWeaponTotalTime[p->curr_weapon][snum]+1; + else p->kickback_pic = 0; + + p->weapon_pos = 6; + p->walking_snd_toggle= 0; + p->weapon_ang = 0; + + p->knuckle_incs = 1; + p->fist_incs = 0; + p->knee_incs = 0; + p->jetpack_on = 0; + p->reloading = 0; + + p->movement_lock[1] = 0; + p->movement_lock[2] = 0; + p->movement_lock[3] = 0; + p->movement_lock[4] = 0; + + setpal(p); + OnEvent(EVENT_RESETPLAYER, p->i, snum, -1); +} + +void resetweapons(short snum) +{ + short weapon; + struct player_struct *p; + + p = &ps[snum]; + + for ( weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++ ) + p->gotweapon[weapon] = 0; + for ( weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++ ) + p->ammo_amount[weapon] = 0; + + p->weapon_pos = 6; + p->kickback_pic = 5; + p->curr_weapon = PISTOL_WEAPON; + p->gotweapon[PISTOL_WEAPON] = 1; + p->gotweapon[KNEE_WEAPON] = 1; + p->ammo_amount[PISTOL_WEAPON] = 48; + p->gotweapon[HANDREMOTE_WEAPON] = 1; + p->last_weapon = -1; + + p->show_empty_weapon= 0; + p->last_pissed_time = 0; + p->holster_weapon = 0; + OnEvent(EVENT_RESETWEAPONS, p->i, snum, -1); +} + +void resetinventory(short snum) +{ + struct player_struct *p; + short i; + + p = &ps[snum]; + + p->inven_icon = 0; + p->boot_amount = 0; + p->scuba_on = 0;p->scuba_amount = 0; + p->heat_amount = 0;p->heat_on = 0; + p->jetpack_on = 0;p->jetpack_amount = 0; + p->shield_amount = max_armour_amount; + p->holoduke_on = -1; + p->holoduke_amount = 0; + p->firstaid_amount = 0; + p->steroids_amount = 0; + p->inven_icon = 0; + OnEvent(EVENT_RESETINVENTORY, p->i, snum, -1); +} + +void resetprestat(short snum,char g) +{ + struct player_struct *p; + short i; + + p = &ps[snum]; + + spriteqloc = 0; + for(i=0;ihbomb_on = 0; + p->cheat_phase = 0; + p->pals_time = 0; + p->toggle_key_flag = 0; + p->secret_rooms = 0; + p->max_secret_rooms = 0; + p->actors_killed = 0; + p->max_actors_killed = 0; + p->lastrandomspot = 0; + p->weapon_pos = 6; + p->kickback_pic = 5; + p->last_weapon = -1; + p->weapreccnt = 0; + p->interface_toggle_flag = 0; + p->show_empty_weapon= 0; + p->holster_weapon = 0; + p->last_pissed_time = 0; + + p->one_parallax_sectnum = -1; + p->visibility = ud.const_visibility; + + screenpeek = myconnectindex; + numanimwalls = 0; + numcyclers = 0; + animatecnt = 0; + parallaxtype = 0; + randomseed = 17L; + ud.pause_on = 0; + ud.camerasprite =-1; + ud.eog = 0; + tempwallptr = 0; + camsprite =-1; + earthquaketime = 0; + + numinterpolations = 0; + startofdynamicinterpolations = 0; + + if( ( (g&MODE_EOL) != MODE_EOL && numplayers < 2) || (!(gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && numplayers > 1) ) + { + resetweapons(snum); + resetinventory(snum); + } + else if(p->curr_weapon == HANDREMOTE_WEAPON) + { + p->ammo_amount[HANDBOMB_WEAPON]++; + p->curr_weapon = HANDBOMB_WEAPON; + } + + p->timebeforeexit = 0; + p->customexitsound = 0; + +} + +void setupbackdrop(short sky) +{ + short i; + + for(i=0;i sector[i].ceilingz) + sector[i].lotag |= 32768; + continue; + } + + if(sector[i].ceilingstat&1) + { + if(waloff[sector[i].ceilingpicnum] == 0) + { + if(sector[i].ceilingpicnum == LA) + for(j=0;j<5;j++) + tloadtile(sector[i].ceilingpicnum+j, 0); + } + setupbackdrop(sector[i].ceilingpicnum); + + if(sector[i].ceilingpicnum == CLOUDYSKIES && numclouds < 127) + clouds[numclouds++] = i; + + if(ps[0].one_parallax_sectnum == -1) + ps[0].one_parallax_sectnum = i; + } + + if(sector[i].lotag == 32767) //Found a secret room + { + ps[0].max_secret_rooms++; + continue; + } + + if(sector[i].lotag == -1) + { + ps[0].exitx = wall[sector[i].wallptr].x; + ps[0].exity = wall[sector[i].wallptr].y; + continue; + } + } + + i = headspritestat[0]; + while(i >= 0) + { + nexti = nextspritestat[i]; + LoadActor(i, -1, -1); + if(sprite[i].lotag == -1 && (sprite[i].cstat&16) ) + { + ps[0].exitx = SX; + ps[0].exity = SY; + } + else switch(dynamictostatic[PN]) + { + case GPSPEED__STATIC: + sector[SECT].extra = SLT; + deletesprite(i); + break; + + case CYCLER__STATIC: + if(numcyclers >= MAXCYCLERS) + { + Bsprintf(tempbuf,"\nToo many cycling sectors (%d max).",MAXCYCLERS); + gameexit(tempbuf); + } + cyclers[numcyclers][0] = SECT; + cyclers[numcyclers][1] = SLT; + cyclers[numcyclers][2] = SS; + cyclers[numcyclers][3] = sector[SECT].floorshade; + cyclers[numcyclers][4] = SHT; + cyclers[numcyclers][5] = (SA == 1536); + numcyclers++; + deletesprite(i); + break; + + case SECTOREFFECTOR__STATIC: + case ACTIVATOR__STATIC: + case TOUCHPLATE__STATIC: + case ACTIVATORLOCKED__STATIC: + case MUSICANDSFX__STATIC: + case LOCATORS__STATIC: + case MASTERSWITCH__STATIC: + case RESPAWN__STATIC: + sprite[i].cstat = 0; + break; + } + i = nexti; + } + + for(i=0;i < MAXSPRITES;i++) + { + if(sprite[i].statnum < MAXSTATUS) + { + if(PN == SECTOREFFECTOR && SLT == 14) + continue; + spawn(-1,i); + } + } + + for(i=0;i < MAXSPRITES;i++) + if(sprite[i].statnum < MAXSTATUS) + { + if( PN == SECTOREFFECTOR && SLT == 14 ) + spawn(-1,i); + } + + lotaglist = 0; + + i = headspritestat[0]; + while(i >= 0) + { + switch(dynamictostatic[PN-1]) + { + case DIPSWITCH__STATIC: + case DIPSWITCH2__STATIC: + case PULLSWITCH__STATIC: + case HANDSWITCH__STATIC: + case SLOTDOOR__STATIC: + case LIGHTSWITCH__STATIC: + case SPACELIGHTSWITCH__STATIC: + case SPACEDOORSWITCH__STATIC: + case FRANKENSTINESWITCH__STATIC: + case LIGHTSWITCH2__STATIC: + case POWERSWITCH1__STATIC: + case LOCKSWITCH1__STATIC: + case POWERSWITCH2__STATIC: + for(j=0;j 64) + gameexit("\nToo many switches (64 max)."); + + j = headspritestat[3]; + while(j >= 0) + { + if(sprite[j].lotag == 12 && sprite[j].hitag == SLT) + hittype[j].temp_data[0] = 1; + j = nextspritestat[j]; + } + } + break; + } + i = nextspritestat[i]; + } + + mirrorcnt = 0; + + for( i = 0; i < numwalls; i++ ) + { + walltype *wal; + wal = &wall[i]; + + if(wal->overpicnum == MIRROR && (wal->cstat&32) != 0) + { + j = wal->nextsector; + + if(mirrorcnt > 63) + gameexit("\nToo many mirrors (64 max.)"); + if ( (j >= 0) && sector[j].ceilingpicnum != MIRROR ) + { + sector[j].ceilingpicnum = MIRROR; + sector[j].floorpicnum = MIRROR; + mirrorwall[mirrorcnt] = i; + mirrorsector[mirrorcnt] = j; + mirrorcnt++; + continue; + } + } + + if(numanimwalls >= MAXANIMWALLS) + { + Bsprintf(tempbuf,"\nToo many 'anim' walls (%d max).",MAXANIMWALLS); + gameexit(tempbuf); + } + + animwall[numanimwalls].tag = 0; + animwall[numanimwalls].wallnum = 0; + switchpicnum = wal->overpicnum; + if ((wal->overpicnum > W_FORCEFIELD)&&(wal->overpicnum <= W_FORCEFIELD+2)) { + switchpicnum = W_FORCEFIELD; + } + switch(dynamictostatic[switchpicnum]) + { + case FANSHADOW__STATIC: + case FANSPRITE__STATIC: + wall->cstat |= 65; + animwall[numanimwalls].wallnum = i; + numanimwalls++; + break; + + case W_FORCEFIELD__STATIC: + if (wal->overpicnum==W_FORCEFIELD__STATIC) + for(j=0;j<3;j++) + tloadtile(W_FORCEFIELD+j, 0); + if(wal->shade > 31) + wal->cstat = 0; + else wal->cstat |= 85+256; + + + if(wal->lotag && wal->nextwall >= 0) + wall[wal->nextwall].lotag = + wal->lotag; + + case BIGFORCE__STATIC: + + animwall[numanimwalls].wallnum = i; + numanimwalls++; + + continue; + } + + wal->extra = -1; + + switch(dynamictostatic[wal->picnum]) + { + case WATERTILE2__STATIC: + for(j=0;j<3;j++) + tloadtile(wal->picnum+j, 0); + break; + + case TECHLIGHT2__STATIC: + case TECHLIGHT4__STATIC: + tloadtile(wal->picnum, 0); + break; + case W_TECHWALL1__STATIC: + case W_TECHWALL2__STATIC: + case W_TECHWALL3__STATIC: + case W_TECHWALL4__STATIC: + animwall[numanimwalls].wallnum = i; + // animwall[numanimwalls].tag = -1; + numanimwalls++; + break; + case SCREENBREAK6__STATIC: + case SCREENBREAK7__STATIC: + case SCREENBREAK8__STATIC: + for(j=SCREENBREAK6;jextra = wal->picnum; + animwall[numanimwalls].tag = -1; + if(ud.lockout) + { + if(wal->picnum == FEMPIC1) + wal->picnum = BLANKSCREEN; + else wal->picnum = SCREENBREAK6; + } + + animwall[numanimwalls].wallnum = i; + animwall[numanimwalls].tag = wal->picnum; + numanimwalls++; + break; + + case SCREENBREAK1__STATIC: + case SCREENBREAK2__STATIC: + case SCREENBREAK3__STATIC: + case SCREENBREAK4__STATIC: + case SCREENBREAK5__STATIC: + + case SCREENBREAK9__STATIC: + case SCREENBREAK10__STATIC: + case SCREENBREAK11__STATIC: + case SCREENBREAK12__STATIC: + case SCREENBREAK13__STATIC: + case SCREENBREAK14__STATIC: + case SCREENBREAK15__STATIC: + case SCREENBREAK16__STATIC: + case SCREENBREAK17__STATIC: + case SCREENBREAK18__STATIC: + case SCREENBREAK19__STATIC: + + animwall[numanimwalls].wallnum = i; + animwall[numanimwalls].tag = wal->picnum; + numanimwalls++; + break; + } + } + + //Invalidate textures in sector behind mirror + for(i=0;i= 0) + while(issoundplaying(globalskillsound)) { handleevents(); getpackets(); } + globalskillsound = -1; + + waitforeverybody(); + ready2send = 0; + + if( ud.m_recstat != 2 && ud.last_level >= 0 && ud.multimode > 1 && (ud.coop&GAMETYPE_FLAG_SCORESHEET)) + dobonus(1); + + if( ln == 0 && vn == 3 && ud.multimode < 2 && ud.lockout == 0) + { + playmusic(&env_music_fn[1][0]); + + flushperms(); + setview(0,0,xdim-1,ydim-1); + clearview(0L); + nextpage(); + + playanm("vol41a.anm",6); + clearview(0L); + nextpage(); + + playanm("vol42a.anm",7); + playanm("vol43a.anm",9); + clearview(0L); + nextpage(); + + FX_StopAllSounds(); + } + + show_shareware = 26*34; + + ud.level_number = ln; + ud.volume_number = vn; + ud.player_skill = sk; + ud.secretlevel = 0; + ud.from_bonus = 0; + parallaxyscale = 0; + + ud.last_level = -1; + lastsavedpos = -1; + p->zoom = 768; + p->gm = 0; + + { + int j; + //AddLog("Newgame"); + ResetGameVars(); + + InitGameVarPointers(); + + ResetSystemDefaults(); + + if(ud.m_coop != 1) + { + for(i=0;icurr_weapon = i; + p->gotweapon[i] = 1; + p->ammo_amount[i] = 48; + + } + else if(aplWeaponWorksLike[i][0]==KNEE_WEAPON) + { + p->gotweapon[i] = 1; + } + else if(aplWeaponWorksLike[i][0]==HANDREMOTE_WEAPON) + { + p->gotweapon[i] = 1; + } + } + p->last_weapon = -1; + } + } + display_mirror = 0; + + if(ud.multimode > 1 ) + { + if(numplayers < 2) + { + connecthead = 0; + for(i=0;i 1 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && ud.last_level >= 0) + { + for(j=0;j 1 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && ud.last_level >= 0) + { + for(j=0;j= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + if( numplayersprites == MAXPLAYERS) + gameexit("\nToo many player sprites (max 16.)"); + + if(numplayersprites == 0) + { + firstx = ps[0].posx; + firsty = ps[0].posy; + } + + po[numplayersprites].ox = s->x; + po[numplayersprites].oy = s->y; + po[numplayersprites].oz = s->z; + po[numplayersprites].oa = s->ang; + po[numplayersprites].os = s->sectnum; + + numplayersprites++; + if(j >= 0) + { + s->owner = i; + s->shade = 0; + s->xrepeat = 42; + s->yrepeat = 36; + s->cstat = 1+256; + s->xoffset = 0; + s->clipdist = 64; + + if( (g&MODE_EOL) != MODE_EOL || ps[j].last_extra == 0) + { + ps[j].last_extra = max_player_health; + s->extra = max_player_health; + ps[j].runspeed = dukefriction; + } + else s->extra = ps[j].last_extra; + + s->yvel = j; + + if(s->pal == 0) + { + s->pal = ps[j].palookup = which_palookup; + which_palookup++; + if( which_palookup >= 17 ) which_palookup = 9; + } + else ps[j].palookup = s->pal; + + ps[j].i = i; + ps[j].frag_ps = j; + hittype[i].owner = i; + + hittype[i].bposx = ps[j].bobposx = ps[j].oposx = ps[j].posx = s->x; + hittype[i].bposy = ps[j].bobposy = ps[j].oposy = ps[j].posy = s->y; + hittype[i].bposz = ps[j].oposz = ps[j].posz = s->z; + ps[j].oang = ps[j].ang = s->ang; + + updatesector(s->x,s->y,&ps[j].cursectnum); + + j = connectpoint2[j]; + + } + else deletesprite(i); + i = nexti; + } +} + +void clearfrags(void) +{ + short i; + + for(i = 0;i=0;i=connectpoint2[i]) + { + if (i != myconnectindex) sendpacket(i,packbuf,1); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + playerreadyflag[myconnectindex]++; + + while (1) + { + handleevents(); + AudioUpdate(); + + if (quitevent || keystatus[1]) gameexit(""); + + getpackets(); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerreadyflag[i] < playerreadyflag[myconnectindex]) break; + if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master + } + if (i < 0) return; + } +} + +void dofrontscreens(char *statustext) +{ + long tincs,i=0,j; + + if(ud.recstat != 2) + { + if (!statustext) { + //ps[myconnectindex].palette = palette; + setgamepalette(&ps[myconnectindex], palette, 1); // JBF 20040308 + fadepal(0,0,0, 0,64,7); + i = ud.screen_size; + ud.screen_size = 0; + vscrn(); + clearview(0L); + } + + SetGameVarID(g_iReturnVarID,LOADSCREEN, -1, -1); + OnEvent(EVENT_GETLOADTILE, -1, -1, -1); + rotatesprite(320<<15,200<<15,65536L,0,GetGameVarID(g_iReturnVarID, -1, -1),0,0,2+8+64,0,0,xdim-1,ydim-1); + if( boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0 ) + { + menutext(160,90,0,0,"ENTERING USER MAP"); + gametextpal(160,90+10,boardfilename,14,2); + } + else + { + menutext(160,90,0,0,"ENTERING"); + menutext(160,90+16+8,0,0,level_names[(ud.volume_number*11) + ud.level_number]); + } + + if (statustext) gametext(160,180,statustext,0,2+8+16); + + nextpage(); + + if (!statustext) + { + fadepal(0,0,0, 63,0,-7); + + KB_FlushKeyboardQueue(); + ud.screen_size = i; + } + } + else + { + if (!statustext) + { + clearview(0L); + //ps[myconnectindex].palette = palette; + //palto(0,0,0,0); + setgamepalette(&ps[myconnectindex], palette, 0); // JBF 20040308 + } + SetGameVarID(g_iReturnVarID,LOADSCREEN, -1, -1); + OnEvent(EVENT_GETLOADTILE, -1, -1, -1); + rotatesprite(320<<15,200<<15,65536L,0,GetGameVarID(g_iReturnVarID, -1, -1),0,0,2+8+64,0,0,xdim-1,ydim-1); + menutext(160,105,0,0,"LOADING..."); + if (statustext) gametext(160,180,statustext,0,2+8+16); + nextpage(); + } +} + +void clearfifo(void) +{ + syncvaltail = 0L; + syncvaltottail = 0L; + syncstat = 0; + bufferjitter = 1; + mymaxlag = otherminlag = 0; + + movefifoplc = movefifosendplc = fakemovefifoplc = 0; + avgfvel = avgsvel = avgavel = avghorz = avgbits = 0; + otherminlag = mymaxlag = 0; + + clearbufbyte(myminlag,MAXPLAYERS<<2,0L); + clearbufbyte(&loc,sizeof(input),0L); + clearbufbyte(&sync[0],sizeof(sync),0L); + clearbufbyte(inputfifo,sizeof(input)*MOVEFIFOSIZ*MAXPLAYERS,0L); + + clearbuf(movefifoend,MAXPLAYERS,0L); + clearbuf(syncvalhead,MAXPLAYERS,0L); + clearbuf(myminlag,MAXPLAYERS,0L); + + // clearbufbyte(playerquitflag,MAXPLAYERS,0x01); +} + +void resetmys(void) +{ + myx = omyx = ps[myconnectindex].posx; + myy = omyy = ps[myconnectindex].posy; + myz = omyz = ps[myconnectindex].posz; + myxvel = myyvel = myzvel = 0; + myang = omyang = ps[myconnectindex].ang; + myhoriz = omyhoriz = ps[myconnectindex].horiz; + myhorizoff = omyhorizoff = ps[myconnectindex].horizoff; + mycursectnum = ps[myconnectindex].cursectnum; + myjumpingcounter = ps[myconnectindex].jumping_counter; + myjumpingtoggle = ps[myconnectindex].jumping_toggle; + myonground = ps[myconnectindex].on_ground; + myhardlanding = ps[myconnectindex].hard_landing; + myreturntocenter = ps[myconnectindex].return_to_center; +} + +extern void adduserquote(char *daquote); + +int enterlevel(char g) +{ + short i,j; + long l; + char levname[BMAX_PATH]; + + if( (g&MODE_DEMO) != MODE_DEMO ) ud.recstat = ud.m_recstat; + ud.respawn_monsters = ud.m_respawn_monsters; + ud.respawn_items = ud.m_respawn_items; + ud.respawn_inventory = ud.m_respawn_inventory; + ud.monsters_off = ud.m_monsters_off; + ud.coop = ud.m_coop; + ud.marker = ud.m_marker; + ud.ffire = ud.m_ffire; + + if( (g&MODE_DEMO) == 0 && ud.recstat == 2) + ud.recstat = 0; + + FX_StopAllSounds(); + clearsoundlocks(); + FX_SetReverb(0); + + i = ud.screen_size; + ud.screen_size = 0; + dofrontscreens(NULL); + vscrn(); + ud.screen_size = i; + + if (!VOLUMEONE) { + + if( boardfilename[0] != 0 && ud.m_level_number == 7 && ud.m_volume_number == 0 ) + { + if ( loadboard( boardfilename,0,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1 ) + { + initprintf("Map %s not found!\n",boardfilename); + //gameexit(tempbuf); + return 1; + } else { + char *p; + strcpy(levname, boardfilename); + p = Bstrrchr(levname,'.'); + if (!p) strcat(levname,".mhk"); + else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } + if (!loadmaphack(levname)) initprintf("Loaded map hack file %s\n",levname); + } + } + else if ( loadboard( level_file_names[ (ud.volume_number*11)+ud.level_number],0,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1) + { + initprintf("Map %s not found!\n",level_file_names[(ud.volume_number*11)+ud.level_number]); + //gameexit(tempbuf); + return 1; + } else { + char *p; + strcpy(levname, level_file_names[ (ud.volume_number*11)+ud.level_number]); + p = Bstrrchr(levname,'.'); + if (!p) strcat(levname,".mhk"); + else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } + if (!loadmaphack(levname)) initprintf("Loaded map hack file %s\n",levname); + } + + } else { + + l = strlen(level_file_names[ (ud.volume_number*11)+ud.level_number]); + copybufbyte( level_file_names[ (ud.volume_number*11)+ud.level_number],&levname[0],l); + levname[l] = 255; + levname[l+1] = 0; + + if ( loadboard( levname,1,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1) + { + initprintf("Map %s not found!\n",level_file_names[(ud.volume_number*11)+ud.level_number]); + //gameexit(tempbuf); + return 1; + } else { + char *p; + p = Bstrrchr(levname,'.'); + if (!p) strcat(levname,".mhk"); + else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } + if (!loadmaphack(levname)) initprintf("Loaded map hack file %s\n",levname); + } + } + + precachecount = 0; + clearbufbyte(gotpic,sizeof(gotpic),0L); + clearbufbyte(precachehightile, sizeof(precachehightile), 0l); + //clearbufbyte(hittype,sizeof(hittype),0l); // JBF 20040531: yes? no? + + prelevel(g); + + allignwarpelevators(); + resetpspritevars(g); + + cachedebug = 0; + automapping = 0; + + if(ud.recstat != 2) MUSIC_StopSong(); + + cacheit(); + + if(ud.recstat != 2) + { + music_select = (ud.volume_number*11) + ud.level_number; + playmusic(&music_fn[0][music_select][0]); + } + + if( (g&MODE_GAME) || (g&MODE_EOL) ) + ps[myconnectindex].gm = MODE_GAME; + else if(g&MODE_RESTART) + { + if(ud.recstat == 2) + ps[myconnectindex].gm = MODE_DEMO; + else ps[myconnectindex].gm = MODE_GAME; + } + + if( (ud.recstat == 1) && (g&MODE_RESTART) != MODE_RESTART ) + opendemowrite(); + + if (VOLUMEONE) { + if(ud.level_number == 0 && ud.recstat != 2) FTA(40,&ps[myconnectindex]); + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + switch(dynamictostatic[sector[sprite[ps[i].i].sectnum].floorpicnum]) + { + case HURTRAIL__STATIC: + case FLOORSLIME__STATIC: + case FLOORPLASMA__STATIC: + resetweapons(i); + resetinventory(i); + ps[i].gotweapon[PISTOL_WEAPON] = 0; + ps[i].ammo_amount[PISTOL_WEAPON] = 0; + ps[i].curr_weapon = KNEE_WEAPON; + ps[i].kickback_pic = 0; + break; + } + + //PREMAP.C - replace near the my's at the end of the file + + resetmys(); + + //ps[myconnectindex].palette = palette; + //palto(0,0,0,0); + setgamepalette(&ps[myconnectindex], palette, 0); // JBF 20040308 + + setpal(&ps[myconnectindex]); + flushperms(); + + everyothertime = 0; + global_random = 0; + + ud.last_level = ud.level_number+1; + + clearfifo(); + + for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i]; + + restorepalette = 1; + + flushpackets(); + waitforeverybody(); + + palto(0,0,0,0); + vscrn(); + clearview(0L); + drawbackground(); + displayrooms(myconnectindex,65536); + + clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101); + ps[myconnectindex].over_shoulder_on = 0; + + clearfrags(); + + resettimevars(); // Here we go + + //Bsprintf(g_szBuf,"ENTERLEVEL L=%d V=%d",ud.level_number, ud.volume_number); + //AddLog(g_szBuf); + // variables are set by pointer... + OnEvent(EVENT_ENTERLEVEL, -1, -1, -1); + return 0; +} + +/* +Duke Nukem V + +Layout: + + Settings: + Suburbs + Duke inflitrating neighborhoods inf. by aliens + Death Valley: + Sorta like a western. Bull-skulls halb buried in the sand + Military compound: Aliens take over nuke-missle silo, duke + must destroy. + Abondend Aircraft field + Vegas: + Blast anything bright! Alien lights camoflauged. + Alien Drug factory. The Blue Liquid + Mountainal Cave: + Interior cave battles. + Jungle: + Trees, canopee, animals, a mysterious hole in the earth + Penetencury: + Good use of spotlights: + Inventory: + Wood, + Metal, + Torch, + Rope, + Plastique, + Cloth, + Wiring, + Glue, + Cigars, + Food, + Duck Tape, + Nails, + Piping, + Petrol, + Uranium, + Gold, + Prism, + Power Cell, + + Hand spikes (Limited usage, they become dull) + Oxygent (Oxygen mixed with stimulant) + + + Player Skills: + R-Left,R-Right,Foward,Back + Strafe, Jump, Double Flip Jump for distance + Help, Escape + Fire/Use + Use Menu + +Programming: + Images: Polys + Actors: + Multi-Object sections for change (head,arms,legs,torsoe,all change) + Facial expressions. Pal lookup per poly? + + struct imagetype + { + int *itable; // AngX,AngY,AngZ,Xoff,Yoff,Zoff; + int *idata; + struct imagetype *prev, *next; + } + +*/ diff --git a/polymer/eduke32/source/rts.c b/polymer/eduke32/source/rts.c new file mode 100644 index 000000000..2386d3461 --- /dev/null +++ b/polymer/eduke32/source/rts.c @@ -0,0 +1,260 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" + +//============= +// STATICS +//============= + +int32 numlumps; +static void **lumpcache; +static lumpinfo_t *lumpinfo; // location of each lump on disk +static boolean RTS_Started = false; + +char lumplockbyte[11]; + +/* +============================================================================ + + LUMP BASED ROUTINES + +============================================================================ +*/ + +/* +==================== += += RTS_AddFile += += All files are optional, but at least one file must be found += Files with a .rts extension are wadlink files with multiple lumps += Other files are single lumps with the base filename for the lump name += +==================== +*/ + +int32 RTS_AddFile (char *filename) +{ + wadinfo_t header; + lumpinfo_t *lump_p; + uint32 i; + int32 handle, length; + int32 startlump; + filelump_t *fileinfo, *fileinfoo; + + // + // read the entire file in + // FIXME: shared opens + + handle = kopen4load(filename, 0); + if (handle < 0) { + initprintf("RTS file %s was not found\n",filename); + return -1; + } + + startlump = numlumps; + + // WAD file + initprintf(" Adding %s.\n",filename); + kread( handle, &header, sizeof( header ) ); + if (strncmp(header.identification,"IWAD",4)) { + initprintf("RTS file %s doesn't have IWAD id\n",filename); + kclose(handle); + return -1; + } + header.numlumps = IntelLong(header.numlumps); + header.infotableofs = IntelLong(header.infotableofs); + length = header.numlumps*sizeof(filelump_t); + fileinfo = fileinfoo = (filelump_t*)malloc (length); + if (!fileinfo) { + initprintf("RTS file could not allocate header info\n"); + kclose(handle); + return -1; + } + klseek (handle, header.infotableofs, SEEK_SET); + kread(handle, fileinfo, length); + + // + // Fill in lumpinfo + // + lump_p = realloc(lumpinfo, (numlumps + header.numlumps)*sizeof(lumpinfo_t)); + if (!lump_p) { + kclose(handle); + return -1; + } + lumpinfo = lump_p; + + numlumps += header.numlumps; + + lump_p = &lumpinfo[startlump]; + + for (i=startlump ; i<(uint32)numlumps ; i++,lump_p++, fileinfo++) + { + lump_p->handle = handle; + lump_p->position = IntelLong(fileinfo->filepos); + lump_p->size = IntelLong(fileinfo->size); + strncpy (lump_p->name, fileinfo->name, 8); + } + + free(fileinfoo); + + return 0; +} + +/* +==================== += += RTS_Init += += Files with a .rts extension are idlink files with multiple lumps += +==================== +*/ + +void RTS_Init (char *filename) +{ + int32 length; + // + // open all the files, load headers, and count lumps + // + numlumps = 0; + lumpinfo = NULL; // will be realloced as lumps are added + + initprintf("RTS Manager Started.\n"); + if (RTS_AddFile (filename)) return; + + if (!numlumps) return; + + // + // set up caching + // + length = (numlumps) * sizeof( *lumpcache ); + lumpcache = SafeMalloc(length); + memset(lumpcache,0,length); + RTS_Started = true; +} + + +/* +==================== += += RTS_NumSounds += +==================== +*/ + +int32 RTS_NumSounds (void) +{ + return numlumps-1; +} + +/* +==================== += += RTS_SoundLength += += Returns the buffer size needed to load the given lump += +==================== +*/ + +int32 RTS_SoundLength (int32 lump) +{ + lump++; + if (lump >= numlumps) + Error ("RTS_SoundLength: %i >= numlumps",lump); + return lumpinfo[lump].size; +} + +/* +==================== += += RTS_GetSoundName += +==================== +*/ + +char * RTS_GetSoundName (int32 i) +{ + i++; + if (i>=numlumps) + Error ("RTS_GetSoundName: %i >= numlumps",i); + return &(lumpinfo[i].name[0]); +} + +/* +==================== += += RTS_ReadLump += += Loads the lump into the given buffer, which must be >= RTS_SoundLength() += +==================== +*/ +void RTS_ReadLump (int32 lump, void *dest) +{ + lumpinfo_t *l; + + if (lump >= numlumps) + Error ("RTS_ReadLump: %i >= numlumps",lump); + if (lump < 0) + Error ("RTS_ReadLump: %i < 0",lump); + l = lumpinfo+lump; + klseek (l->handle, l->position, SEEK_SET); + kread(l->handle,dest,l->size); +} + +/* +==================== += += RTS_GetSound += +==================== +*/ +void *RTS_GetSound (int32 lump) +{ + lump++; + if ((uint32)lump >= (uint32)numlumps) + Error ("RTS_GetSound: %i >= %i\n",lump,numlumps); + + if (lumpcache[lump] == NULL) + { + lumplockbyte[lump] = 200; + allocache((long *)&lumpcache[lump],(long)RTS_SoundLength(lump-1),&lumplockbyte[lump]); // JBF 20030910: char * => long * + RTS_ReadLump(lump, lumpcache[lump]); + } + else + { + if (lumplockbyte[lump] < 200) + lumplockbyte[lump] = 200; + else + lumplockbyte[lump]++; + } + return lumpcache[lump]; +} + diff --git a/polymer/eduke32/source/rts.h b/polymer/eduke32/source/rts.h new file mode 100644 index 000000000..588c29ee4 --- /dev/null +++ b/polymer/eduke32/source/rts.h @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +//*************************************************************************** +// +// RTS.H +// +//*************************************************************************** + +#ifndef __rts_public__ +#define __rts_public__ + +/* +==================== += += RTS_Init += += Files with a .rts extension are idlink files with multiple lumps += +==================== +*/ + +void RTS_Init (char *filename); +/* +==================== += += RTS_NumSounds += +==================== +*/ + +int32 RTS_NumSounds (void); +/* +==================== += += RTS_SoundLength += += Returns the buffer size needed to load the given lump += +==================== +*/ + +int32 RTS_SoundLength (int32 lump); +/* +==================== += += RTS_GetSoundName += +==================== +*/ + +char * RTS_GetSoundName (int32 i); +/* +==================== += += RTS_GetSound += +==================== +*/ +void *RTS_GetSound (int32 lump); +#endif diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c new file mode 100644 index 000000000..ce5387255 --- /dev/null +++ b/polymer/eduke32/source/savegame.c @@ -0,0 +1,646 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" + +int loadpheader(char spot,struct savehead *saveh) +{ + long i; + char fn[13]; + long fil; + long bv; + + strcpy(fn, "egam0.sav"); + fn[4] = spot+'0'; + + if ((fil = kopen4load(fn,0)) == -1) return(-1); + + walock[TILE_LOADSHOT] = 255; + + if (kdfread(&bv,4,1,fil) != 1) goto corrupt; + if(bv != BYTEVERSION) { + FTA(114,&ps[myconnectindex]); + kclose(fil); + return 1; + } + + if (kdfread(&saveh->numplr,sizeof(int32),1,fil) != 1) goto corrupt; + + if (kdfread(saveh->name,19,1,fil) != 1) goto corrupt; + if (kdfread(&saveh->volnum,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(&saveh->levnum,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(&saveh->plrskl,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(saveh->boardfn,BMAX_PATH,1,fil) != 1) goto corrupt; + + if (waloff[TILE_LOADSHOT] == 0) allocache(&waloff[TILE_LOADSHOT],320*200,&walock[TILE_LOADSHOT]); + tilesizx[TILE_LOADSHOT] = 200; tilesizy[TILE_LOADSHOT] = 320; + if (kdfread((char *)waloff[TILE_LOADSHOT],320,200,fil) != 200) goto corrupt; + invalidatetile(TILE_LOADSHOT,0,255); + + kclose(fil); + + return(0); +corrupt: + kclose(fil); + return 1; +} + +int loadplayer(signed char spot) +{ + short k; + char fn[13]; + char mpfn[13]; + char *fnptr, scriptptrs[MAXSCRIPTSIZE]; + long fil, bv, i, j, x; + int32 nump; + + strcpy(fn, "egam0.sav"); + strcpy(mpfn, "egamA_00.sav"); + + if(spot < 0) + { + multiflag = 1; + multiwhat = 0; + multipos = -spot-1; + return -1; + } + + if( multiflag == 2 && multiwho != myconnectindex ) + { + fnptr = mpfn; + mpfn[4] = spot + 'A'; + + if(ud.multimode > 9) + { + mpfn[6] = (multiwho/10) + '0'; + mpfn[7] = (multiwho%10) + '0'; + } + else mpfn[7] = multiwho + '0'; + } + else + { + fnptr = fn; + fn[4] = spot + '0'; + } + + if ((fil = kopen4load(fnptr,0)) == -1) return(-1); + + ready2send = 0; + + if (kdfread(&bv,4,1,fil) != 1) return -1; + if(bv != BYTEVERSION) + { + FTA(114,&ps[myconnectindex]); + kclose(fil); + ototalclock = totalclock; + ready2send = 1; + return 1; + } + + if (kdfread(&nump,sizeof(nump),1,fil) != 1) return -1; + if(nump != numplayers) + { + kclose(fil); + ototalclock = totalclock; + ready2send = 1; + FTA(124,&ps[myconnectindex]); + return 1; + } + + if(numplayers > 1) + { + pub = NUMPAGES; + pus = NUMPAGES; + vscrn(); + drawbackground(); + menutext(160,100,0,0,"LOADING..."); + nextpage(); + } + + waitforeverybody(); + + FX_StopAllSounds(); + clearsoundlocks(); + MUSIC_StopSong(); + + if(numplayers > 1) { + if (kdfread(&buf,19,1,fil) != 1) goto corrupt; + } else { + if (kdfread(&ud.savegame[spot][0],19,1,fil) != 1) goto corrupt; + } + + + if (kdfread(&ud.volume_number,sizeof(ud.volume_number),1,fil) != 1) goto corrupt; + if (kdfread(&ud.level_number,sizeof(ud.level_number),1,fil) != 1) goto corrupt; + if (kdfread(&ud.player_skill,sizeof(ud.player_skill),1,fil) != 1) goto corrupt; + if (kdfread(&boardfilename[0],BMAX_PATH,1,fil) != 1) goto corrupt; + + ud.m_level_number = ud.level_number; + ud.m_volume_number = ud.volume_number; + ud.m_player_skill = ud.player_skill; + + //Fake read because lseek won't work with compression + walock[TILE_LOADSHOT] = 1; + if (waloff[TILE_LOADSHOT] == 0) allocache(&waloff[TILE_LOADSHOT],320*200,&walock[TILE_LOADSHOT]); + tilesizx[TILE_LOADSHOT] = 200; tilesizy[TILE_LOADSHOT] = 320; + if (kdfread((char *)waloff[TILE_LOADSHOT],320,200,fil) != 200) goto corrupt; + invalidatetile(TILE_LOADSHOT,0,255); + + if (kdfread(&numwalls,2,1,fil) != 1) goto corrupt; + if (kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil) != MAXWALLS) goto corrupt; + if (kdfread(&numsectors,2,1,fil) != 1) goto corrupt; + if (kdfread(§or[0],sizeof(sectortype),MAXSECTORS,fil) != MAXSECTORS) goto corrupt; + if (kdfread(&sprite[0],sizeof(spritetype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&spriteext[0],sizeof(spriteexttype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&headspritesect[0],2,MAXSECTORS+1,fil) != MAXSECTORS+1) goto corrupt; + if (kdfread(&prevspritesect[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&nextspritesect[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&headspritestat[0],2,MAXSTATUS+1,fil) != MAXSTATUS+1) goto corrupt; + if (kdfread(&prevspritestat[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&nextspritestat[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&numcyclers,sizeof(numcyclers),1,fil) != 1) goto corrupt; + if (kdfread(&cyclers[0][0],12,MAXCYCLERS,fil) != MAXCYCLERS) goto corrupt; + if (kdfread(ps,sizeof(ps),1,fil) != 1) goto corrupt; + if (kdfread(po,sizeof(po),1,fil) != 1) goto corrupt; + if (kdfread(&numanimwalls,sizeof(numanimwalls),1,fil) != 1) goto corrupt; + if (kdfread(&animwall,sizeof(animwall),1,fil) != 1) goto corrupt; + if (kdfread(&msx[0],sizeof(long),sizeof(msx)/sizeof(long),fil) != sizeof(msx)/sizeof(long)) goto corrupt; + if (kdfread(&msy[0],sizeof(long),sizeof(msy)/sizeof(long),fil) != sizeof(msy)/sizeof(long)) goto corrupt; + if (kdfread((short *)&spriteqloc,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread((short *)&spriteqamount,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread((short *)&spriteq[0],sizeof(short),spriteqamount,fil) != spriteqamount) goto corrupt; + if (kdfread(&mirrorcnt,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread(&mirrorwall[0],sizeof(short),64,fil) != 64) goto corrupt; + if (kdfread(&mirrorsector[0],sizeof(short),64,fil) != 64) goto corrupt; + if (kdfread(&show2dsector[0],sizeof(char),MAXSECTORS>>3,fil) != (MAXSECTORS>>3)) goto corrupt; + if (kdfread(&actortype[0],sizeof(char),MAXTILES,fil) != MAXTILES) goto corrupt; + + if (kdfread(&numclouds,sizeof(numclouds),1,fil) != 1) goto corrupt; + if (kdfread(&clouds[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + if (kdfread(&cloudx[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + if (kdfread(&cloudy[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + + if (kdfread(&scriptptrs[0],1,MAXSCRIPTSIZE,fil) != MAXSCRIPTSIZE) goto corrupt; + if (kdfread(&script[0],4,MAXSCRIPTSIZE,fil) != MAXSCRIPTSIZE) goto corrupt; + for(i=0;i=0;i--) animateptr[i] = (long *)((long)animateptr[i]+(long)(§or[0])); + if (kdfread(&animategoal[0],4,MAXANIMATES,fil) != MAXANIMATES) goto corrupt; + if (kdfread(&animatevel[0],4,MAXANIMATES,fil) != MAXANIMATES) goto corrupt; + + if (kdfread(&earthquaketime,sizeof(earthquaketime),1,fil) != 1) goto corrupt; + if (kdfread(&ud.from_bonus,sizeof(ud.from_bonus),1,fil) != 1) goto corrupt; + if (kdfread(&ud.secretlevel,sizeof(ud.secretlevel),1,fil) != 1) goto corrupt; + if (kdfread(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil) != 1) goto corrupt; + ud.m_respawn_monsters = ud.respawn_monsters; + if (kdfread(&ud.respawn_items,sizeof(ud.respawn_items),1,fil) != 1) goto corrupt; + ud.m_respawn_items = ud.respawn_items; + if (kdfread(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil) != 1) goto corrupt; + ud.m_respawn_inventory = ud.respawn_inventory; + + if (kdfread(&ud.god,sizeof(ud.god),1,fil) != 1) goto corrupt; + if (kdfread(&ud.auto_run,sizeof(ud.auto_run),1,fil) != 1) goto corrupt; + if (kdfread(&ud.crosshair,sizeof(ud.crosshair),1,fil) != 1) goto corrupt; + if (kdfread(&ud.monsters_off,sizeof(ud.monsters_off),1,fil) != 1) goto corrupt; + ud.m_monsters_off = ud.monsters_off; + if (kdfread(&ud.last_level,sizeof(ud.last_level),1,fil) != 1) goto corrupt; + if (kdfread(&ud.eog,sizeof(ud.eog),1,fil) != 1) goto corrupt; + + if (kdfread(&ud.coop,sizeof(ud.coop),1,fil) != 1) goto corrupt; + ud.m_coop = ud.coop; + if (kdfread(&ud.marker,sizeof(ud.marker),1,fil) != 1) goto corrupt; + ud.m_marker = ud.marker; + if (kdfread(&ud.ffire,sizeof(ud.ffire),1,fil) != 1) goto corrupt; + ud.m_ffire = ud.ffire; + + if (kdfread(&camsprite,sizeof(camsprite),1,fil) != 1) goto corrupt; + if (kdfread(&connecthead,sizeof(connecthead),1,fil) != 1) goto corrupt; + if (kdfread(connectpoint2,sizeof(connectpoint2),1,fil) != 1) goto corrupt; + if (kdfread(&numplayersprites,sizeof(numplayersprites),1,fil) != 1) goto corrupt; + if (kdfread((short *)&frags[0][0],sizeof(frags),1,fil) != 1) goto corrupt; + + if (kdfread(&randomseed,sizeof(randomseed),1,fil) != 1) goto corrupt; + if (kdfread(&global_random,sizeof(global_random),1,fil) != 1) goto corrupt; + if (kdfread(¶llaxyscale,sizeof(parallaxyscale),1,fil) != 1) goto corrupt; + + if (kdfread(&projectile[0],sizeof(proj_struct),MAXTILES,fil) != MAXTILES) goto corrupt; + if (kdfread(&defaultprojectile[0],sizeof(proj_struct),MAXTILES,fil) != MAXTILES) goto corrupt; + if (kdfread(&thisprojectile[0],sizeof(proj_struct),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + + ReadGameVars(fil); + + kclose(fil); + + if(ps[myconnectindex].over_shoulder_on != 0) + { + cameradist = 0; + cameraclock = 0; + ps[myconnectindex].over_shoulder_on = 1; + } + + screenpeek = myconnectindex; + + clearbufbyte(gotpic,sizeof(gotpic),0L); + clearsoundlocks(); + cacheit(); + + music_select = (ud.volume_number*11) + ud.level_number; + playmusic(&music_fn[0][music_select][0]); + + ps[myconnectindex].gm = MODE_GAME; + ud.recstat = 0; + + if(ps[myconnectindex].jetpack_on) + spritesound(DUKE_JETPACK_IDLE,ps[myconnectindex].i); + + restorepalette = 1; + setpal(&ps[myconnectindex]); + vscrn(); + + FX_SetReverb(0); + + if(ud.lockout == 0) + { + for(x=0;x= 0 ) + wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra; + } + else + { + for(x=0;x= 0) + { + switch(sprite[k].lotag) + { + case 31: + setinterpolation(§or[sprite[k].sectnum].floorz); + break; + case 32: + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 25: + setinterpolation(§or[sprite[k].sectnum].floorz); + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 17: + setinterpolation(§or[sprite[k].sectnum].floorz); + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 0: + case 5: + case 6: + case 11: + case 14: + case 15: + case 16: + case 26: + case 30: + setsectinterpolate(k); + break; + } + + k = nextspritestat[k]; + } + + for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i]; + for(i = animatecnt-1;i>=0;i--) + setinterpolation(animateptr[i]); + + show_shareware = 0; + everyothertime = 0; + + clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101); + + resetmys(); + + ready2send = 1; + + flushpackets(); + clearfifo(); + waitforeverybody(); + + resettimevars(); + + return(0); +corrupt: + Bsprintf(tempbuf,"Save game file \"%s\" is corrupt.",fnptr); + gameexit(tempbuf); + return -1; +} + +int saveplayer(signed char spot) +{ + long i, j; + char fn[13]; + char mpfn[13]; + char *fnptr,scriptptrs[MAXSCRIPTSIZE]; + FILE *fil; + long bv = BYTEVERSION; + + strcpy(fn, "egam0.sav"); + strcpy(mpfn, "egamA_00.sav"); + + if(spot < 0) + { + multiflag = 1; + multiwhat = 1; + multipos = -spot-1; + return -1; + } + + waitforeverybody(); + + if( multiflag == 2 && multiwho != myconnectindex ) + { + fnptr = mpfn; + mpfn[4] = spot + 'A'; + + if(ud.multimode > 9) + { + mpfn[6] = (multiwho/10) + '0'; + mpfn[7] = multiwho + '0'; + } + else mpfn[7] = multiwho + '0'; + } + else + { + fnptr = fn; + fn[4] = spot + '0'; + } + + if ((fil = fopen(fnptr,"wb")) == 0) return(-1); + + ready2send = 0; + + dfwrite(&bv,4,1,fil); + dfwrite(&ud.multimode,sizeof(ud.multimode),1,fil); + + dfwrite(&ud.savegame[spot][0],19,1,fil); + dfwrite(&ud.volume_number,sizeof(ud.volume_number),1,fil); + dfwrite(&ud.level_number,sizeof(ud.level_number),1,fil); + dfwrite(&ud.player_skill,sizeof(ud.player_skill),1,fil); + dfwrite(&boardfilename[0],BMAX_PATH,1,fil); + if (!waloff[TILE_SAVESHOT]) { + walock[TILE_SAVESHOT] = 254; + allocache((long *)&waloff[TILE_SAVESHOT],200*320,&walock[TILE_SAVESHOT]); + clearbuf((void*)waloff[TILE_SAVESHOT],(200*320)/4,0); + walock[TILE_SAVESHOT] = 1; + } + dfwrite((char *)waloff[TILE_SAVESHOT],320,200,fil); + + dfwrite(&numwalls,2,1,fil); + dfwrite(&wall[0],sizeof(walltype),MAXWALLS,fil); + dfwrite(&numsectors,2,1,fil); + dfwrite(§or[0],sizeof(sectortype),MAXSECTORS,fil); + dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil); + dfwrite(&spriteext[0],sizeof(spriteexttype),MAXSPRITES,fil); + dfwrite(&headspritesect[0],2,MAXSECTORS+1,fil); + dfwrite(&prevspritesect[0],2,MAXSPRITES,fil); + dfwrite(&nextspritesect[0],2,MAXSPRITES,fil); + dfwrite(&headspritestat[0],2,MAXSTATUS+1,fil); + dfwrite(&prevspritestat[0],2,MAXSPRITES,fil); + dfwrite(&nextspritestat[0],2,MAXSPRITES,fil); + dfwrite(&numcyclers,sizeof(numcyclers),1,fil); + dfwrite(&cyclers[0][0],12,MAXCYCLERS,fil); + dfwrite(ps,sizeof(ps),1,fil); + dfwrite(po,sizeof(po),1,fil); + dfwrite(&numanimwalls,sizeof(numanimwalls),1,fil); + dfwrite(&animwall,sizeof(animwall),1,fil); + dfwrite(&msx[0],sizeof(long),sizeof(msx)/sizeof(long),fil); + dfwrite(&msy[0],sizeof(long),sizeof(msy)/sizeof(long),fil); + dfwrite(&spriteqloc,sizeof(short),1,fil); + dfwrite(&spriteqamount,sizeof(short),1,fil); + dfwrite(&spriteq[0],sizeof(short),spriteqamount,fil); + dfwrite(&mirrorcnt,sizeof(short),1,fil); + dfwrite(&mirrorwall[0],sizeof(short),64,fil); + dfwrite(&mirrorsector[0],sizeof(short),64,fil); + dfwrite(&show2dsector[0],sizeof(char),MAXSECTORS>>3,fil); + dfwrite(&actortype[0],sizeof(char),MAXTILES,fil); + + dfwrite(&numclouds,sizeof(numclouds),1,fil); + dfwrite(&clouds[0],sizeof(short)<<7,1,fil); + dfwrite(&cloudx[0],sizeof(short)<<7,1,fil); + dfwrite(&cloudy[0],sizeof(short)<<7,1,fil); + + for(i=0;i= (long)(&script[0]) && (long)script[i] < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] = 1; + j = (long)script[i] - (long)&script[0]; + script[i] = j; + } + else scriptptrs[i] = 0; + } + + dfwrite(&scriptptrs[0],1,MAXSCRIPTSIZE,fil); + dfwrite(&script[0],4,MAXSCRIPTSIZE,fil); + + for(i=0;i= j && T2 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 1; + T2 -= j; + } + if(T5 >= j && T5 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 2; + T5 -= j; + } + if(T6 >= j && T6 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 4; + T6 -= j; + } + } + + dfwrite(&scriptptrs[0],1,MAXSPRITES,fil); + dfwrite(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil); + + for(i=0;i=0;i--) animateptr[i] = (long *)((long)animateptr[i]-(long)(§or[0])); + dfwrite(&animateptr[0],4,MAXANIMATES,fil); + for(i = animatecnt-1;i>=0;i--) animateptr[i] = (long *)((long)animateptr[i]+(long)(§or[0])); + dfwrite(&animategoal[0],4,MAXANIMATES,fil); + dfwrite(&animatevel[0],4,MAXANIMATES,fil); + + dfwrite(&earthquaketime,sizeof(earthquaketime),1,fil); + dfwrite(&ud.from_bonus,sizeof(ud.from_bonus),1,fil); + dfwrite(&ud.secretlevel,sizeof(ud.secretlevel),1,fil); + dfwrite(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil); + dfwrite(&ud.respawn_items,sizeof(ud.respawn_items),1,fil); + dfwrite(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil); + dfwrite(&ud.god,sizeof(ud.god),1,fil); + dfwrite(&ud.auto_run,sizeof(ud.auto_run),1,fil); + dfwrite(&ud.crosshair,sizeof(ud.crosshair),1,fil); + dfwrite(&ud.monsters_off,sizeof(ud.monsters_off),1,fil); + dfwrite(&ud.last_level,sizeof(ud.last_level),1,fil); + dfwrite(&ud.eog,sizeof(ud.eog),1,fil); + dfwrite(&ud.coop,sizeof(ud.coop),1,fil); + dfwrite(&ud.marker,sizeof(ud.marker),1,fil); + dfwrite(&ud.ffire,sizeof(ud.ffire),1,fil); + dfwrite(&camsprite,sizeof(camsprite),1,fil); + dfwrite(&connecthead,sizeof(connecthead),1,fil); + dfwrite(connectpoint2,sizeof(connectpoint2),1,fil); + dfwrite(&numplayersprites,sizeof(numplayersprites),1,fil); + dfwrite((short *)&frags[0][0],sizeof(frags),1,fil); + + dfwrite(&randomseed,sizeof(randomseed),1,fil); + dfwrite(&global_random,sizeof(global_random),1,fil); + dfwrite(¶llaxyscale,sizeof(parallaxyscale),1,fil); + + dfwrite(&projectile[0],sizeof(proj_struct),MAXTILES,fil); + dfwrite(&defaultprojectile[0],sizeof(proj_struct),MAXTILES,fil); + dfwrite(&thisprojectile[0],sizeof(proj_struct),MAXSPRITES,fil); + + SaveGameVars(fil); + + fclose(fil); + + if(ud.multimode < 2) + { + strcpy(fta_quotes[122],"GAME SAVED"); + FTA(122,&ps[myconnectindex]); + } + + ready2send = 1; + + waitforeverybody(); + + ototalclock = totalclock; + + return(0); +} diff --git a/polymer/eduke32/source/savegame.what b/polymer/eduke32/source/savegame.what new file mode 100644 index 000000000..bba994335 --- /dev/null +++ b/polymer/eduke32/source/savegame.what @@ -0,0 +1,615 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" + +int loadpheader(char spot,struct savehead *saveh) +{ + long i; + char fn[13]; + long fil; + long bv; + + strcpy(fn, "game0.sav"); + fn[4] = spot+'0'; + + if ((fil = kopen4load(fn,0)) == -1) return(-1); + + walock[TILE_LOADSHOT] = 255; + + if (kdfread(&bv,4,1,fil) != 1) goto corrupt; + if(bv != BYTEVERSION) { + FTA(114,&ps[myconnectindex]); + kclose(fil); + return 1; + } + + if (kdfread(&saveh->numplr,sizeof(int32),1,fil) != 1) goto corrupt; + + if (kdfread(saveh->name,19,1,fil) != 1) goto corrupt; + if (kdfread(&saveh->volnum,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(&saveh->levnum,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(&saveh->plrskl,sizeof(int32),1,fil) != 1) goto corrupt; + if (kdfread(saveh->boardfn,BMAX_PATH,1,fil) != 1) goto corrupt; + + if (waloff[TILE_LOADSHOT] == 0) allocache(&waloff[TILE_LOADSHOT],320*200,&walock[TILE_LOADSHOT]); + tilesizx[TILE_LOADSHOT] = 200; tilesizy[TILE_LOADSHOT] = 320; + if (kdfread((char *)waloff[TILE_LOADSHOT],320,200,fil) != 200) goto corrupt; + invalidatetile(TILE_LOADSHOT,0,255); + + kclose(fil); + + return(0); +corrupt: + kclose(fil); + return 1; +} + + +int loadplayer(signed char spot) +{ + short k; + char fn[13]; + char mpfn[13]; + char *fnptr, scriptptrs[MAXSCRIPTSIZE]; + long fil, bv, i, j, x; + int32 nump; + + strcpy(fn, "game0.sav"); + strcpy(mpfn, "gameA_00.sav"); + + if(spot < 0) + { + multiflag = 1; + multiwhat = 0; + multipos = -spot-1; + return -1; + } + + if( multiflag == 2 && multiwho != myconnectindex ) + { + fnptr = mpfn; + mpfn[4] = spot + 'A'; + + if(ud.multimode > 9) + { + mpfn[6] = (multiwho/10) + '0'; + mpfn[7] = (multiwho%10) + '0'; + } + else mpfn[7] = multiwho + '0'; + } + else + { + fnptr = fn; + fn[4] = spot + '0'; + } + + if ((fil = kopen4load(fnptr,0)) == -1) return(-1); + + ready2send = 0; + + if (kdfread(&bv,4,1,fil) != 1) return -1; + if(bv != BYTEVERSION) + { + FTA(114,&ps[myconnectindex]); + kclose(fil); + ototalclock = totalclock; + ready2send = 1; + return 1; + } + + if (kdfread(&nump,sizeof(nump),1,fil) != 1) return -1; + if(nump != numplayers) + { + kclose(fil); + ototalclock = totalclock; + ready2send = 1; + FTA(124,&ps[myconnectindex]); + return 1; + } + + if(numplayers > 1) + { + pub = NUMPAGES; + pus = NUMPAGES; + vscrn(); + drawbackground(); + menutext(160,100,0,0,"LOADING..."); + nextpage(); + } + + waitforeverybody(); + + FX_StopAllSounds(); + clearsoundlocks(); + MUSIC_StopSong(); + + if(numplayers > 1) { + if (kdfread(&buf,19,1,fil) != 1) goto corrupt; + } else { + if (kdfread(&ud.savegame[spot][0],19,1,fil) != 1) goto corrupt; + } + +// music_changed = (music_select != (ud.volume_number*11) + ud.level_number); + + if (kdfread(&ud.volume_number,sizeof(ud.volume_number),1,fil) != 1) goto corrupt; + if (kdfread(&ud.level_number,sizeof(ud.level_number),1,fil) != 1) goto corrupt; + if (kdfread(&ud.player_skill,sizeof(ud.player_skill),1,fil) != 1) goto corrupt; + if (kdfread(&boardfilename[0],BMAX_PATH,1,fil) != 1) goto corrupt; + + ud.m_level_number = ud.level_number; + ud.m_volume_number = ud.volume_number; + ud.m_player_skill = ud.player_skill; + + //Fake read because lseek won't work with compression + walock[TILE_LOADSHOT] = 1; + if (waloff[TILE_LOADSHOT] == 0) allocache(&waloff[TILE_LOADSHOT],320*200,&walock[TILE_LOADSHOT]); + tilesizx[TILE_LOADSHOT] = 200; tilesizy[TILE_LOADSHOT] = 320; + if (kdfread((char *)waloff[TILE_LOADSHOT],320,200,fil) != 200) goto corrupt; + invalidatetile(TILE_LOADSHOT,0,255); + + if (kdfread(&numwalls,2,1,fil) != 1) goto corrupt; + if (kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil) != MAXWALLS) goto corrupt; + if (kdfread(&numsectors,2,1,fil) != 1) goto corrupt; + if (kdfread(§or[0],sizeof(sectortype),MAXSECTORS,fil) != MAXSECTORS) goto corrupt; + if (kdfread(&sprite[0],sizeof(spritetype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&spriteext[0],sizeof(spriteexttype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&headspritesect[0],2,MAXSECTORS+1,fil) != MAXSECTORS+1) goto corrupt; + if (kdfread(&prevspritesect[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&nextspritesect[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&headspritestat[0],2,MAXSTATUS+1,fil) != MAXSTATUS+1) goto corrupt; + if (kdfread(&prevspritestat[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&nextspritestat[0],2,MAXSPRITES,fil) != MAXSPRITES) goto corrupt; + if (kdfread(&numcyclers,sizeof(numcyclers),1,fil) != 1) goto corrupt; + if (kdfread(&cyclers[0][0],12,MAXCYCLERS,fil) != MAXCYCLERS) goto corrupt; + if (kdfread(ps,sizeof(ps),1,fil) != 1) goto corrupt; + if (kdfread(po,sizeof(po),1,fil) != 1) goto corrupt; + if (kdfread(&numanimwalls,sizeof(numanimwalls),1,fil) != 1) goto corrupt; + if (kdfread(&animwall,sizeof(animwall),1,fil) != 1) goto corrupt; + if (kdfread(&msx[0],sizeof(long),sizeof(msx)/sizeof(long),fil) != sizeof(msx)/sizeof(long)) goto corrupt; + if (kdfread(&msy[0],sizeof(long),sizeof(msy)/sizeof(long),fil) != sizeof(msy)/sizeof(long)) goto corrupt; + if (kdfread((short *)&spriteqloc,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread((short *)&spriteqamount,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread((short *)&spriteq[0],sizeof(short),spriteqamount,fil) != spriteqamount) goto corrupt; + if (kdfread(&mirrorcnt,sizeof(short),1,fil) != 1) goto corrupt; + if (kdfread(&mirrorwall[0],sizeof(short),64,fil) != 64) goto corrupt; + if (kdfread(&mirrorsector[0],sizeof(short),64,fil) != 64) goto corrupt; + if (kdfread(&show2dsector[0],sizeof(char),MAXSECTORS>>3,fil) != (MAXSECTORS>>3)) goto corrupt; + if (kdfread(&actortype[0],sizeof(char),MAXTILES,fil) != MAXTILES) goto corrupt; + + if (kdfread(&numclouds,sizeof(numclouds),1,fil) != 1) goto corrupt; + if (kdfread(&clouds[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + if (kdfread(&cloudx[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + if (kdfread(&cloudy[0],sizeof(short)<<7,1,fil) != 1) goto corrupt; + + if (kdfread(&scriptptrs[0],1,MAXSCRIPTSIZE,fil) != MAXSCRIPTSIZE) goto corrupt; + if (kdfread(&script[0],4,MAXSCRIPTSIZE,fil) != MAXSCRIPTSIZE) goto corrupt; + for(i=0;i=0;i--) animateptr[i] = (long *)((long)animateptr[i]+(long)(§or[0])); + if (kdfread(&animategoal[0],4,MAXANIMATES,fil) != MAXANIMATES) goto corrupt; + if (kdfread(&animatevel[0],4,MAXANIMATES,fil) != MAXANIMATES) goto corrupt; + + if (kdfread(&earthquaketime,sizeof(earthquaketime),1,fil) != 1) goto corrupt; + if (kdfread(&ud.from_bonus,sizeof(ud.from_bonus),1,fil) != 1) goto corrupt; + if (kdfread(&ud.secretlevel,sizeof(ud.secretlevel),1,fil) != 1) goto corrupt; + if (kdfread(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil) != 1) goto corrupt; + ud.m_respawn_monsters = ud.respawn_monsters; + if (kdfread(&ud.respawn_items,sizeof(ud.respawn_items),1,fil) != 1) goto corrupt; + ud.m_respawn_items = ud.respawn_items; + if (kdfread(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil) != 1) goto corrupt; + ud.m_respawn_inventory = ud.respawn_inventory; + + if (kdfread(&ud.god,sizeof(ud.god),1,fil) != 1) goto corrupt; + if (kdfread(&ud.auto_run,sizeof(ud.auto_run),1,fil) != 1) goto corrupt; + if (kdfread(&ud.crosshair,sizeof(ud.crosshair),1,fil) != 1) goto corrupt; + if (kdfread(&ud.monsters_off,sizeof(ud.monsters_off),1,fil) != 1) goto corrupt; + ud.m_monsters_off = ud.monsters_off; + if (kdfread(&ud.last_level,sizeof(ud.last_level),1,fil) != 1) goto corrupt; + if (kdfread(&ud.eog,sizeof(ud.eog),1,fil) != 1) goto corrupt; + + if (kdfread(&ud.coop,sizeof(ud.coop),1,fil) != 1) goto corrupt; + ud.m_coop = ud.coop; + if (kdfread(&ud.marker,sizeof(ud.marker),1,fil) != 1) goto corrupt; + ud.m_marker = ud.marker; + if (kdfread(&ud.ffire,sizeof(ud.ffire),1,fil) != 1) goto corrupt; + ud.m_ffire = ud.ffire; + + if (kdfread(&camsprite,sizeof(camsprite),1,fil) != 1) goto corrupt; + if (kdfread(&connecthead,sizeof(connecthead),1,fil) != 1) goto corrupt; + if (kdfread(connectpoint2,sizeof(connectpoint2),1,fil) != 1) goto corrupt; + if (kdfread(&numplayersprites,sizeof(numplayersprites),1,fil) != 1) goto corrupt; + if (kdfread((short *)&frags[0][0],sizeof(frags),1,fil) != 1) goto corrupt; + + if (kdfread(&randomseed,sizeof(randomseed),1,fil) != 1) goto corrupt; + if (kdfread(&global_random,sizeof(global_random),1,fil) != 1) goto corrupt; + if (kdfread(¶llaxyscale,sizeof(parallaxyscale),1,fil) != 1) goto corrupt; + + kclose(fil); + + if(ps[myconnectindex].over_shoulder_on != 0) + { + cameradist = 0; + cameraclock = 0; + ps[myconnectindex].over_shoulder_on = 1; + } + + screenpeek = myconnectindex; + + clearbufbyte(gotpic,sizeof(gotpic),0L); + clearsoundlocks(); + cacheit(); + + music_select = (ud.volume_number*11) + ud.level_number; + playmusic(&music_fn[0][music_select][0]); + + ps[myconnectindex].gm = MODE_GAME; + ud.recstat = 0; + + if(ps[myconnectindex].jetpack_on) + spritesound(DUKE_JETPACK_IDLE,ps[myconnectindex].i); + + restorepalette = 1; + setpal(&ps[myconnectindex]); + vscrn(); + + FX_SetReverb(0); + + if(ud.lockout == 0) + { + for(x=0;x= 0 ) + wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra; + } + else + { + for(x=0;x= 0) + { + switch(sprite[k].lotag) + { + case 31: + setinterpolation(§or[sprite[k].sectnum].floorz); + break; + case 32: + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 25: + setinterpolation(§or[sprite[k].sectnum].floorz); + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 17: + setinterpolation(§or[sprite[k].sectnum].floorz); + setinterpolation(§or[sprite[k].sectnum].ceilingz); + break; + case 0: + case 5: + case 6: + case 11: + case 14: + case 15: + case 16: + case 26: + case 30: + setsectinterpolate(k); + break; + } + + k = nextspritestat[k]; + } + + for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i]; + for(i = animatecnt-1;i>=0;i--) + setinterpolation(animateptr[i]); + + show_shareware = 0; + everyothertime = 0; + + clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101); + + resetmys(); + + ready2send = 1; + + flushpackets(); + clearfifo(); + waitforeverybody(); + + resettimevars(); + + return(0); +corrupt: + Bsprintf(tempbuf,"Save game file \"%s\" is corrupt.",fnptr); + gameexit(tempbuf); + return -1; +} + +int saveplayer(signed char spot) +{ + long i, j; + char fn[13]; + char mpfn[13]; + char *fnptr,scriptptrs[MAXSCRIPTSIZE]; + FILE *fil; + long bv = BYTEVERSION; + + strcpy(fn, "game0.sav"); + strcpy(mpfn, "gameA_00.sav"); + + if(spot < 0) + { + multiflag = 1; + multiwhat = 1; + multipos = -spot-1; + return -1; + } + + waitforeverybody(); + + if( multiflag == 2 && multiwho != myconnectindex ) + { + fnptr = mpfn; + mpfn[4] = spot + 'A'; + + if(ud.multimode > 9) + { + mpfn[6] = (multiwho/10) + '0'; + mpfn[7] = multiwho + '0'; + } + else mpfn[7] = multiwho + '0'; + } + else + { + fnptr = fn; + fn[4] = spot + '0'; + } + + if ((fil = fopen(fnptr,"wb")) == 0) return(-1); + + ready2send = 0; + + dfwrite(&bv,4,1,fil); + dfwrite(&ud.multimode,sizeof(ud.multimode),1,fil); + + dfwrite(&ud.savegame[spot][0],19,1,fil); + dfwrite(&ud.volume_number,sizeof(ud.volume_number),1,fil); + dfwrite(&ud.level_number,sizeof(ud.level_number),1,fil); + dfwrite(&ud.player_skill,sizeof(ud.player_skill),1,fil); + dfwrite(&boardfilename[0],BMAX_PATH,1,fil); + + if (!waloff[TILE_SAVESHOT]) { + walock[TILE_SAVESHOT] = 254; + allocache((long *)&waloff[TILE_SAVESHOT],200*320,&walock[TILE_SAVESHOT]); + clearbuf((void*)waloff[TILE_SAVESHOT],(200*320)/4,0); + walock[TILE_SAVESHOT] = 1; + } + dfwrite((char *)waloff[TILE_SAVESHOT],320,200,fil); + + dfwrite(&numwalls,2,1,fil); + dfwrite(&wall[0],sizeof(walltype),MAXWALLS,fil); + dfwrite(&numsectors,2,1,fil); + dfwrite(§or[0],sizeof(sectortype),MAXSECTORS,fil); + dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil); + dfwrite(&spriteext[0],sizeof(spriteexttype),MAXSPRITES,fil); + dfwrite(&headspritesect[0],2,MAXSECTORS+1,fil); + dfwrite(&prevspritesect[0],2,MAXSPRITES,fil); + dfwrite(&nextspritesect[0],2,MAXSPRITES,fil); + dfwrite(&headspritestat[0],2,MAXSTATUS+1,fil); + dfwrite(&prevspritestat[0],2,MAXSPRITES,fil); + dfwrite(&nextspritestat[0],2,MAXSPRITES,fil); + dfwrite(&numcyclers,sizeof(numcyclers),1,fil); + dfwrite(&cyclers[0][0],12,MAXCYCLERS,fil); + dfwrite(ps,sizeof(ps),1,fil); + dfwrite(po,sizeof(po),1,fil); + dfwrite(&numanimwalls,sizeof(numanimwalls),1,fil); + dfwrite(&animwall,sizeof(animwall),1,fil); + dfwrite(&msx[0],sizeof(long),sizeof(msx)/sizeof(long),fil); + dfwrite(&msy[0],sizeof(long),sizeof(msy)/sizeof(long),fil); + dfwrite(&spriteqloc,sizeof(short),1,fil); + dfwrite(&spriteqamount,sizeof(short),1,fil); + dfwrite(&spriteq[0],sizeof(short),spriteqamount,fil); + dfwrite(&mirrorcnt,sizeof(short),1,fil); + dfwrite(&mirrorwall[0],sizeof(short),64,fil); + dfwrite(&mirrorsector[0],sizeof(short),64,fil); + dfwrite(&show2dsector[0],sizeof(char),MAXSECTORS>>3,fil); + dfwrite(&actortype[0],sizeof(char),MAXTILES,fil); + + dfwrite(&numclouds,sizeof(numclouds),1,fil); + dfwrite(&clouds[0],sizeof(short)<<7,1,fil); + dfwrite(&cloudx[0],sizeof(short)<<7,1,fil); + dfwrite(&cloudy[0],sizeof(short)<<7,1,fil); + + for(i=0;i= (long)(&script[0]) && (long)script[i] < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] = 1; + j = (long)script[i] - (long)&script[0]; + script[i] = j; + } + else scriptptrs[i] = 0; + } + + dfwrite(&scriptptrs[0],1,MAXSCRIPTSIZE,fil); + dfwrite(&script[0],4,MAXSCRIPTSIZE,fil); + + for(i=0;i= j && T2 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 1; + T2 -= j; + } + if(T5 >= j && T5 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 2; + T5 -= j; + } + if(T6 >= j && T6 < (long)(&script[MAXSCRIPTSIZE]) ) + { + scriptptrs[i] |= 4; + T6 -= j; + } + } + + dfwrite(&scriptptrs[0],1,MAXSPRITES,fil); + dfwrite(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil); + + for(i=0;i=0;i--) animateptr[i] = (long *)((long)animateptr[i]-(long)(§or[0])); + dfwrite(&animateptr[0],4,MAXANIMATES,fil); + for(i = animatecnt-1;i>=0;i--) animateptr[i] = (long *)((long)animateptr[i]+(long)(§or[0])); + dfwrite(&animategoal[0],4,MAXANIMATES,fil); + dfwrite(&animatevel[0],4,MAXANIMATES,fil); + + dfwrite(&earthquaketime,sizeof(earthquaketime),1,fil); + dfwrite(&ud.from_bonus,sizeof(ud.from_bonus),1,fil); + dfwrite(&ud.secretlevel,sizeof(ud.secretlevel),1,fil); + dfwrite(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil); + dfwrite(&ud.respawn_items,sizeof(ud.respawn_items),1,fil); + dfwrite(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil); + dfwrite(&ud.god,sizeof(ud.god),1,fil); + dfwrite(&ud.auto_run,sizeof(ud.auto_run),1,fil); + dfwrite(&ud.crosshair,sizeof(ud.crosshair),1,fil); + dfwrite(&ud.monsters_off,sizeof(ud.monsters_off),1,fil); + dfwrite(&ud.last_level,sizeof(ud.last_level),1,fil); + dfwrite(&ud.eog,sizeof(ud.eog),1,fil); + dfwrite(&ud.coop,sizeof(ud.coop),1,fil); + dfwrite(&ud.marker,sizeof(ud.marker),1,fil); + dfwrite(&ud.ffire,sizeof(ud.ffire),1,fil); + dfwrite(&camsprite,sizeof(camsprite),1,fil); + dfwrite(&connecthead,sizeof(connecthead),1,fil); + dfwrite(connectpoint2,sizeof(connectpoint2),1,fil); + dfwrite(&numplayersprites,sizeof(numplayersprites),1,fil); + dfwrite((short *)&frags[0][0],sizeof(frags),1,fil); + + dfwrite(&randomseed,sizeof(randomseed),1,fil); + dfwrite(&global_random,sizeof(global_random),1,fil); + dfwrite(¶llaxyscale,sizeof(parallaxyscale),1,fil); + + fclose(fil); + + if(ud.multimode < 2) + { + strcpy(fta_quotes[122],"GAME SAVED"); + FTA(122,&ps[myconnectindex]); + } + + ready2send = 1; + + waitforeverybody(); + + ototalclock = totalclock; + + return(0); +} diff --git a/polymer/eduke32/source/sector.c b/polymer/eduke32/source/sector.c new file mode 100644 index 000000000..56f6e3459 --- /dev/null +++ b/polymer/eduke32/source/sector.c @@ -0,0 +1,3522 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "osd.h" + +// PRIMITIVE + +char haltsoundhack; +short callsound(short sn,short whatsprite) +{ + short i; + + if(haltsoundhack) + { + haltsoundhack = 0; + return -1; + } + + i = headspritesect[sn]; + while(i >= 0) + { + if( PN == MUSICANDSFX && SLT < 1000 ) + { + if(whatsprite == -1) whatsprite = i; + + if(T1 == 0) + { + if( (soundm[SLT]&16) == 0) + { + if(SLT) + { + spritesound(SLT,whatsprite); + if(SHT && SLT != SHT && SHT < NUM_SOUNDS) + stopspritesound(SHT,whatsprite); + } + + if( (sector[SECT].lotag&0xff) != 22) + T1 = 1; + } + } + else if(SHT < NUM_SOUNDS) + { + if(SHT) spritesound(SHT,whatsprite); + if( (soundm[SLT]&1) || ( SHT && SHT != SLT ) ) + stopspritesound(SLT,whatsprite); + T1 = 0; + } + return SLT; + } + i = nextspritesect[i]; + } + return -1; +} + +short check_activator_motion( short lotag ) +{ + short i, j; + spritetype *s; + + i = headspritestat[8]; + while ( i >= 0 ) + { + if ( sprite[i].lotag == lotag ) + { + s = &sprite[i]; + + for ( j = animatecnt-1; j >= 0; j-- ) + if ( s->sectnum == animatesect[j] ) + return( 1 ); + + j = headspritestat[3]; + while ( j >= 0 ) + { + if(s->sectnum == sprite[j].sectnum) + switch(sprite[j].lotag) + { + case 11: + case 30: + if ( hittype[j].temp_data[4] ) + return( 1 ); + break; + case 20: + case 31: + case 32: + case 18: + if ( hittype[j].temp_data[0] ) + return( 1 ); + break; + } + + j = nextspritestat[j]; + } + } + i = nextspritestat[i]; + } + return( 0 ); +} + +char isadoorwall(short dapic) +{ + switch(dynamictostatic[dapic]) + { + case DOORTILE1__STATIC: + case DOORTILE2__STATIC: + case DOORTILE3__STATIC: + case DOORTILE4__STATIC: + case DOORTILE5__STATIC: + case DOORTILE6__STATIC: + case DOORTILE7__STATIC: + case DOORTILE8__STATIC: + case DOORTILE9__STATIC: + case DOORTILE10__STATIC: + case DOORTILE11__STATIC: + case DOORTILE12__STATIC: + case DOORTILE14__STATIC: + case DOORTILE15__STATIC: + case DOORTILE16__STATIC: + case DOORTILE17__STATIC: + case DOORTILE18__STATIC: + case DOORTILE19__STATIC: + case DOORTILE20__STATIC: + case DOORTILE21__STATIC: + case DOORTILE22__STATIC: + case DOORTILE23__STATIC: + return 1; + } + return 0; +} + +char isanunderoperator(short lotag) +{ + switch(lotag&0xff) + { + case 15: + case 16: + case 17: + case 18: + case 19: + case 22: + case 26: + return 1; + } + return 0; +} + +char isanearoperator(short lotag) +{ + switch(lotag&0xff) + { + case 9: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 25: + case 26: + case 29://Toothed door + return 1; + } + return 0; +} + +short checkcursectnums(short sect) +{ + short i; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if( sprite[ps[i].i].sectnum == sect ) return i; + return -1; +} + +long ldist(spritetype *s1,spritetype *s2) +{ + long vx,vy; + vx = s1->x - s2->x; + vy = s1->y - s2->y; + return(FindDistance2D(vx,vy) + 1); +} + +long dist(spritetype *s1,spritetype *s2) +{ + long vx,vy,vz; + vx = s1->x - s2->x; + vy = s1->y - s2->y; + vz = s1->z - s2->z; + return(FindDistance3D(vx,vy,vz>>4)); +} + +long txdist(spritetype *s1,spritetype *s2) +{ + long vx,vy,vz; + vx = s1->x - s2->x; + vy = s1->y - s2->y; + vz = s1->z - s2->z - s2->yrepeat; + return(FindDistance3D(vx,vy,vz>>4)); +} + +short findplayer(spritetype *s,long *d) +{ + short j, closest_player; + long x, closest; + + if(ud.multimode < 2) + { + *d = klabs(ps[myconnectindex].oposx-s->x) + klabs(ps[myconnectindex].oposy-s->y) + ((klabs(ps[myconnectindex].oposz-s->z+(28<<8)))>>4); + return myconnectindex; + } + + closest = 0x7fffffff; + closest_player = 0; + + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + x = klabs(ps[j].oposx-s->x) + klabs(ps[j].oposy-s->y) + ((klabs(ps[j].oposz-s->z+(28<<8)))>>4); + if( x < closest && sprite[ps[j].i].extra > 0 ) + { + closest_player = j; + closest = x; + } + } + + *d = closest; + return closest_player; +} + +short findotherplayer(short p,long *d) +{ + short j, closest_player; + long x, closest; + + closest = 0x7fffffff; + closest_player = p; + + for(j=connecthead;j>=0;j=connectpoint2[j]) + if(p != j && sprite[ps[j].i].extra > 0) + { + x = klabs(ps[j].oposx-ps[p].posx) + klabs(ps[j].oposy-ps[p].posy) + (klabs(ps[j].oposz-ps[p].posz)>>4); + + if( x < closest ) + { + closest_player = j; + closest = x; + } + } + + *d = closest; + return closest_player; +} + +void doanimations(void) +{ + long i, j, a, p, v, dasect; + + for(i=animatecnt-1;i>=0;i--) + { + a = *animateptr[i]; + v = animatevel[i]*TICSPERFRAME; + dasect = animatesect[i]; + + if (a == animategoal[i]) + { + stopinterpolation(animateptr[i]); + + animatecnt--; + animateptr[i] = animateptr[animatecnt]; + animategoal[i] = animategoal[animatecnt]; + animatevel[i] = animatevel[animatecnt]; + animatesect[i] = animatesect[animatecnt]; + if( sector[animatesect[i]].lotag == 18 || sector[animatesect[i]].lotag == 19 ) + if(animateptr[i] == §or[animatesect[i]].ceilingz) + continue; + + if( (sector[dasect].lotag&0xff) != 22 ) + callsound(dasect,-1); + + continue; + } + + if (v > 0) { a = min(a+v,animategoal[i]); } + else { a = max(a+v,animategoal[i]); } + + if( animateptr[i] == §or[animatesect[i]].floorz) + { + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (ps[p].cursectnum == dasect) + if ((sector[dasect].floorz-ps[p].posz) < (64<<8)) + if (sprite[ps[p].i].owner >= 0) + { + ps[p].posz += v; + ps[p].poszv = 0; + if (p == myconnectindex) + { + myz += v; + myzvel = 0; + myzbak[((movefifoplc-1)&(MOVEFIFOSIZ-1))] = ps[p].posz; + } + } + + for(j=headspritesect[dasect];j>=0;j=nextspritesect[j]) + if (sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z; + sprite[j].z += v; + hittype[j].floorz = sector[dasect].floorz+v; + } + } + + *animateptr[i] = a; + } +} + +int getanimationgoal(long *animptr) +{ + long i, j; + + j = -1; + for(i=animatecnt-1;i>=0;i--) + if (animptr == (long *)animateptr[i]) + { + j = i; + break; + } + return(j); +} + +int setanimation(short animsect,long *animptr, long thegoal, long thevel) +{ + long i, j; + + if (animatecnt >= MAXANIMATES-1) + return(-1); + + j = animatecnt; + for(i=0;i= *animptr) + animatevel[j] = thevel; + else + animatevel[j] = -thevel; + + if (j == animatecnt) animatecnt++; + + setinterpolation(animptr); + + return(j); +} + +void animatecamsprite(void) +{ + short i; + + if(camsprite <= 0) return; + + i = camsprite; + + if(T1 >= 11) + { + T1 = 0; + + if(ps[screenpeek].newowner >= 0) + OW = ps[screenpeek].newowner; + + else if(OW >= 0 && dist(&sprite[ps[screenpeek].i],&sprite[i]) < 2048) + { + if (waloff[TILE_VIEWSCR] == 0) + allocatepermanenttile(TILE_VIEWSCR,tilesizx[PN],tilesizy[PN]); + else walock[TILE_VIEWSCR] = 255; + xyzmirror(OW,/*PN*/TILE_VIEWSCR); + } + } + else T1++; +} + +void animatewalls(void) +{ + long i, j, p, t; + + for(p=0;p < numanimwalls ;p++) + // for(p=numanimwalls-1;p>=0;p--) + { + i = animwall[p].wallnum; + j = wall[i].picnum; + + switch(dynamictostatic[j]) + { + case SCREENBREAK1__STATIC: + case SCREENBREAK2__STATIC: + case SCREENBREAK3__STATIC: + case SCREENBREAK4__STATIC: + case SCREENBREAK5__STATIC: + + case SCREENBREAK9__STATIC: + case SCREENBREAK10__STATIC: + case SCREENBREAK11__STATIC: + case SCREENBREAK12__STATIC: + case SCREENBREAK13__STATIC: + case SCREENBREAK14__STATIC: + case SCREENBREAK15__STATIC: + case SCREENBREAK16__STATIC: + case SCREENBREAK17__STATIC: + case SCREENBREAK18__STATIC: + case SCREENBREAK19__STATIC: + + if( (TRAND&255) < 16) + { + animwall[p].tag = wall[i].picnum; + wall[i].picnum = SCREENBREAK6; + } + + continue; + + case SCREENBREAK6__STATIC: + case SCREENBREAK7__STATIC: + case SCREENBREAK8__STATIC: + + if(animwall[p].tag >= 0 && wall[i].extra != FEMPIC2 && wall[i].extra != FEMPIC3 ) + wall[i].picnum = animwall[p].tag; + else + { + wall[i].picnum++; + if(wall[i].picnum == (SCREENBREAK6+3) ) + wall[i].picnum = SCREENBREAK6; + } + continue; + + } + + if(wall[i].cstat&16) + if ((wall[i].overpicnum >= W_FORCEFIELD)&&(wall[i].overpicnum <= W_FORCEFIELD+2)) + { + + t = animwall[p].tag; + + if(wall[i].cstat&254) + { + wall[i].xpanning -= t>>10; // sintable[(t+512)&2047]>>12; + wall[i].ypanning -= t>>10; // sintable[t&2047]>>12; + + if(wall[i].extra == 1) + { + wall[i].extra = 0; + animwall[p].tag = 0; + } + else + animwall[p].tag+=128; + + if( animwall[p].tag < (128<<4) ) + { + if( animwall[p].tag&128 ) + wall[i].overpicnum = W_FORCEFIELD; + else wall[i].overpicnum = W_FORCEFIELD+1; + } + else + { + if( (TRAND&255) < 32 ) + animwall[p].tag = 128<<(TRAND&3); + else wall[i].overpicnum = W_FORCEFIELD+1; + } + } + + } + } +} + +char activatewarpelevators(short s,short d) //Parm = sectoreffectornum +{ + short i, sn; + + sn = sprite[s].sectnum; + + // See if the sector exists + + i = headspritestat[3]; + while(i >= 0) + { + if( SLT == 17 ) + if( SHT == sprite[s].hitag ) + if( (klabs(sector[sn].floorz-hittype[s].temp_data[2]) > SP) || + (sector[SECT].hitag == (sector[sn].hitag-d) ) ) + break; + i = nextspritestat[i]; + } + + if(i==-1) + { + d = 0; + return 1; // No find + } + else + { + if(d == 0) + spritesound(ELEVATOR_OFF,s); + else spritesound(ELEVATOR_ON,s); + } + + + i = headspritestat[3]; + while(i >= 0) + { + if( SLT == 17 ) + if( SHT == sprite[s].hitag ) + { + T1 = d; + T2 = d; //Make all check warp + } + i = nextspritestat[i]; + } + return 0; +} + +void operatesectors(short sn,short ii) +{ + long j=0, l, q, startwall, endwall; + short i; + char sect_error; + sectortype *sptr; + + sect_error = 0; + sptr = §or[sn]; + + switch(sptr->lotag&(0xffff-49152)) + { + + case 30: + j = sector[sn].hitag; + if( hittype[j].tempang == 0 || + hittype[j].tempang == 256) + callsound(sn,ii); + if(sprite[j].extra == 1) + sprite[j].extra = 3; + else sprite[j].extra = 1; + break; + + case 31: + + j = sector[sn].hitag; + if(hittype[j].temp_data[4] == 0) + hittype[j].temp_data[4] = 1; + + callsound(sn,ii); + break; + + case 26: //The split doors + i = getanimationgoal(&sptr->ceilingz); + if(i == -1) //if the door has stopped + { + haltsoundhack = 1; + sptr->lotag &= 0xff00; + sptr->lotag |= 22; + operatesectors(sn,ii); + sptr->lotag &= 0xff00; + sptr->lotag |= 9; + operatesectors(sn,ii); + sptr->lotag &= 0xff00; + sptr->lotag |= 26; + } + return; + + case 9: + { + long dax,day,dax2,day2,sp; + long wallfind[2]; + + startwall = sptr->wallptr; + endwall = startwall+sptr->wallnum-1; + + sp = sptr->extra>>4; + + //first find center point by averaging all points + dax = 0L, day = 0L; + for(i=startwall;i<=endwall;i++) + { + dax += wall[i].x; + day += wall[i].y; + } + dax /= (endwall-startwall+1); + day /= (endwall-startwall+1); + + //find any points with either same x or same y coordinate + // as center (dax, day) - should be 2 points found. + wallfind[0] = -1; + wallfind[1] = -1; + for(i=startwall;i<=endwall;i++) + if ((wall[i].x == dax) || (wall[i].y == day)) + { + if (wallfind[0] == -1) + wallfind[0] = i; + else wallfind[1] = i; + } + + for(j=0;j<2;j++) + { + if ((wall[wallfind[j]].x == dax) && (wall[wallfind[j]].y == day)) + { + //find what direction door should open by averaging the + // 2 neighboring points of wallfind[0] & wallfind[1]. + i = wallfind[j]-1; if (i < startwall) i = endwall; + dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + dax2 = wall[wall[wall[wallfind[j]].point2].point2].x; + dax2 -= wall[wall[wallfind[j]].point2].x; + setanimation(sn,&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,sp); + setanimation(sn,&wall[i].x,wall[i].x+dax2,sp); + setanimation(sn,&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,sp); + callsound(sn,ii); + } + else if (day2 != 0) + { + day2 = wall[wall[wall[wallfind[j]].point2].point2].y; + day2 -= wall[wall[wallfind[j]].point2].y; + setanimation(sn,&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,sp); + setanimation(sn,&wall[i].y,wall[i].y+day2,sp); + setanimation(sn,&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,sp); + callsound(sn,ii); + } + } + else + { + i = wallfind[j]-1; if (i < startwall) i = endwall; + dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + setanimation(sn,&wall[wallfind[j]].x,dax,sp); + setanimation(sn,&wall[i].x,dax+dax2,sp); + setanimation(sn,&wall[wall[wallfind[j]].point2].x,dax+dax2,sp); + callsound(sn,ii); + } + else if (day2 != 0) + { + setanimation(sn,&wall[wallfind[j]].y,day,sp); + setanimation(sn,&wall[i].y,day+day2,sp); + setanimation(sn,&wall[wall[wallfind[j]].point2].y,day+day2,sp); + callsound(sn,ii); + } + } + } + + } + return; + + case 15://Warping elevators + + if(sprite[ii].picnum != APLAYER) return; + // if(ps[sprite[ii].yvel].select_dir == 1) return; + + i = headspritesect[sn]; + while(i >= 0) + { + if(PN==SECTOREFFECTOR && SLT == 17 ) break; + i = nextspritesect[i]; + } + + if(sprite[ii].sectnum == sn) + { + if( activatewarpelevators(i,-1) ) + activatewarpelevators(i,1); + else if( activatewarpelevators(i,1) ) + activatewarpelevators(i,-1); + return; + } + else + { + if(sptr->floorz > SZ) + activatewarpelevators(i,-1); + else + activatewarpelevators(i,1); + } + + return; + + case 16: + case 17: + + i = getanimationgoal(&sptr->floorz); + + if(i == -1) + { + i = nextsectorneighborz(sn,sptr->floorz,1,1); + if( i == -1 ) + { + i = nextsectorneighborz(sn,sptr->floorz,1,-1); + if( i == -1 ) return; + j = sector[i].floorz; + setanimation(sn,&sptr->floorz,j,sptr->extra); + } + else + { + j = sector[i].floorz; + setanimation(sn,&sptr->floorz,j,sptr->extra); + } + callsound(sn,ii); + } + + return; + + case 18: + case 19: + + i = getanimationgoal(&sptr->floorz); + + if(i==-1) + { + i = nextsectorneighborz(sn,sptr->floorz,1,-1); + if(i==-1) i = nextsectorneighborz(sn,sptr->floorz,1,1); + if(i==-1) return; + j = sector[i].floorz; + q = sptr->extra; + l = sptr->ceilingz-sptr->floorz; + setanimation(sn,&sptr->floorz,j,q); + setanimation(sn,&sptr->ceilingz,j+l,q); + callsound(sn,ii); + } + return; + + case 29: + + if(sptr->lotag&0x8000) + j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz; + else + j = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz; + + i = headspritestat[3]; //Effectors + while(i >= 0) + { + if( (SLT == 22) && + (SHT == sptr->hitag) ) + { + sector[SECT].extra = -sector[SECT].extra; + + T1 = sn; + T2 = 1; + } + i = nextspritestat[i]; + } + + sptr->lotag ^= 0x8000; + + setanimation(sn,&sptr->ceilingz,j,sptr->extra); + + callsound(sn,ii); + + return; + + case 20: + +REDODOOR: + + if(sptr->lotag&0x8000) + { + i = headspritesect[sn]; + while(i >= 0) + { + if(sprite[i].statnum == 3 && SLT==9) + { + j = SZ; + break; + } + i = nextspritesect[i]; + } + if(i==-1) + j = sptr->floorz; + } + else + { + j = nextsectorneighborz(sn,sptr->ceilingz,-1,-1); + + if(j >= 0) j = sector[j].ceilingz; + else + { + sptr->lotag |= 32768; + goto REDODOOR; + } + } + + sptr->lotag ^= 0x8000; + + setanimation(sn,&sptr->ceilingz,j,sptr->extra); + callsound(sn,ii); + + return; + + case 21: + i = getanimationgoal(&sptr->floorz); + if (i >= 0) + { + if (animategoal[sn] == sptr->ceilingz) + animategoal[i] = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz; + else animategoal[i] = sptr->ceilingz; + j = animategoal[i]; + } + else + { + if (sptr->ceilingz == sptr->floorz) + j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz; + else j = sptr->ceilingz; + + sptr->lotag ^= 0x8000; + + if(setanimation(sn,&sptr->floorz,j,sptr->extra) >= 0) + callsound(sn,ii); + } + return; + + case 22: + + // REDODOOR22: + + if ( (sptr->lotag&0x8000) ) + { + q = (sptr->ceilingz+sptr->floorz)>>1; + j = setanimation(sn,&sptr->floorz,q,sptr->extra); + j = setanimation(sn,&sptr->ceilingz,q,sptr->extra); + } + else + { + q = sector[nextsectorneighborz(sn,sptr->floorz,1,1)].floorz; + j = setanimation(sn,&sptr->floorz,q,sptr->extra); + q = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz; + j = setanimation(sn,&sptr->ceilingz,q,sptr->extra); + } + + sptr->lotag ^= 0x8000; + + callsound(sn,ii); + + return; + + case 23: //Swingdoor + + j = -1; + q = 0; + + i = headspritestat[3]; + while(i >= 0) + { + if( SLT == 11 && SECT == sn && !T5) + { + j = i; + break; + } + i = nextspritestat[i]; + } + if (i<0) { OSD_Printf("WARNING: SE23 i<0!\n"); return; } // JBF + l = sector[SECT].lotag&0x8000; + + if(j >= 0) + { + i = headspritestat[3]; + while(i >= 0) + { + if( l == (sector[SECT].lotag&0x8000) && SLT == 11 && sprite[j].hitag == SHT && !T5 ) + { + if(sector[SECT].lotag&0x8000) sector[SECT].lotag &= 0x7fff; + else sector[SECT].lotag |= 0x8000; + T5 = 1; + T4 = -T4; + if(q == 0) + { + callsound(sn,i); + q = 1; + } + } + i = nextspritestat[i]; + } + } + return; + + case 25: //Subway type sliding doors + + j = headspritestat[3]; + while(j >= 0)//Find the sprite + { + if( (sprite[j].lotag) == 15 && sprite[j].sectnum == sn ) + break; //Found the sectoreffector. + j = nextspritestat[j]; + } + + if(j < 0) + return; + + i = headspritestat[3]; + while(i >= 0) + { + if( SHT==sprite[j].hitag ) + { + if( SLT == 15 ) + { + sector[SECT].lotag ^= 0x8000; // Toggle the open or close + SA += 1024; + if(T5) callsound(SECT,i); + callsound(SECT,i); + if(sector[SECT].lotag&0x8000) T5 = 1; + else T5 = 2; + } + } + i = nextspritestat[i]; + } + return; + + case 27: //Extended bridge + + j = headspritestat[3]; + while(j >= 0) + { + if( (sprite[j].lotag&0xff)==20 && sprite[j].sectnum == sn) //Bridge + { + + sector[sn].lotag ^= 0x8000; + if(sector[sn].lotag&0x8000) //OPENING + hittype[j].temp_data[0] = 1; + else hittype[j].temp_data[0] = 2; + callsound(sn,ii); + break; + } + j = nextspritestat[j]; + } + return; + + + case 28: + //activate the rest of them + + j = headspritesect[sn]; + while(j >= 0) + { + if(sprite[j].statnum==3 && (sprite[j].lotag&0xff)==21) + break; //Found it + j = nextspritesect[j]; + } + + j = sprite[j].hitag; + + l = headspritestat[3]; + while(l >= 0) + { + if( (sprite[l].lotag&0xff)==21 && !hittype[l].temp_data[0] && + (sprite[l].hitag) == j ) + hittype[l].temp_data[0] = 1; + l = nextspritestat[l]; + } + callsound(sn,ii); + + return; + } +} + +void operaterespawns(short low) +{ + short i, j, nexti; + + i = headspritestat[11]; + while(i >= 0) + { + nexti = nextspritestat[i]; + if ((SLT == low) && (PN == RESPAWN)) + { + if( badguypic(SHT) && ud.monsters_off ) break; + + j = spawn(i,TRANSPORTERSTAR); + sprite[j].z -= (32<<8); + + sprite[i].extra = 66-12; // Just a way to killit + } + i = nexti; + } +} + +void operateactivators(short low,short snum) +{ + short i, j, k, *p, nexti; + walltype *wal; + + for(i=numcyclers-1;i>=0;i--) + { + p = &cyclers[i][0]; + + if(p[4] == low) + { + p[5] = !p[5]; + + sector[p[0]].floorshade = sector[p[0]].ceilingshade = p[3]; + wal = &wall[sector[p[0]].wallptr]; + for(j=sector[p[0]].wallnum;j > 0;j--,wal++) + wal->shade = p[3]; + } + } + + i = headspritestat[8]; + k = -1; + while(i >= 0) + { + if(sprite[i].lotag == low) + { + if( sprite[i].picnum == ACTIVATORLOCKED ) + { + if(sector[SECT].lotag&16384) + sector[SECT].lotag &= 65535-16384; + else + sector[SECT].lotag |= 16384; + + if(snum >= 0) + { + if(sector[SECT].lotag&16384) + FTA(4,&ps[snum]); + else FTA(8,&ps[snum]); + } + } + else + { + switch(SHT) + { + case 0: + break; + case 1: + if(sector[SECT].floorz != sector[SECT].ceilingz) + { + i = nextspritestat[i]; + continue; + } + break; + case 2: + if(sector[SECT].floorz == sector[SECT].ceilingz) + { + i = nextspritestat[i]; + continue; + } + break; + } + + if( sector[sprite[i].sectnum].lotag < 3 ) + { + j = headspritesect[sprite[i].sectnum]; + while(j >= 0) + { + if( sprite[j].statnum == 3 ) switch(sprite[j].lotag) + { + case 36: + case 31: + case 32: + case 18: + hittype[j].temp_data[0] = 1-hittype[j].temp_data[0]; + callsound(SECT,j); + break; + } + j = nextspritesect[j]; + } + } + + if( k == -1 && (sector[SECT].lotag&0xff) == 22 ) + k = callsound(SECT,i); + + operatesectors(SECT,i); + } + } + i = nextspritestat[i]; + } + + operaterespawns(low); +} + +void operatemasterswitches(short low) +{ + short i; + + i = headspritestat[6]; + while(i >= 0) + { + if( PN == MASTERSWITCH && SLT == low && SP == 0 ) + SP = 1; + i = nextspritestat[i]; + } +} + +void operateforcefields(short s, short low) +{ + short i, p; + + for(p=numanimwalls;p>=0;p--) + { + i = animwall[p].wallnum; + + if(low == wall[i].lotag || low == -1) + if (((wall[i].overpicnum >= W_FORCEFIELD)&&(wall[i].overpicnum <= W_FORCEFIELD+2))||(wall[i].overpicnum == BIGFORCE)) { + + + animwall[p].tag = 0; + + if( wall[i].cstat ) + { + wall[i].cstat = 0; + + if( s >= 0 && sprite[s].picnum == SECTOREFFECTOR && + sprite[s].lotag == 30) + wall[i].lotag = 0; + } + else + wall[i].cstat = 85; + } + } +} + +char checkhitswitch(short snum,long w,char switchtype) +{ + char switchpal; + short i, x, lotag,hitag,picnum,correctdips,numdips; + long sx,sy; + int switchpicnum; + + if(w < 0) return 0; + correctdips = 1; + numdips = 0; + + if(switchtype == 1) // A wall sprite + { + lotag = sprite[w].lotag; if(lotag == 0) return 0; + hitag = sprite[w].hitag; + sx = sprite[w].x; + sy = sprite[w].y; + picnum = sprite[w].picnum; + switchpal = sprite[w].pal; + } + else + { + lotag = wall[w].lotag; if(lotag == 0) return 0; + hitag = wall[w].hitag; + sx = wall[w].x; + sy = wall[w].y; + picnum = wall[w].picnum; + switchpal = wall[w].pal; + } + // initprintf("checkhitswitch called picnum=%i switchtype=%i\n",picnum,switchtype); + switchpicnum = picnum; + if ( (picnum==DIPSWITCH+1) + || (picnum==TECHSWITCH+1) + || (picnum==ALIENSWITCH+1) + || (picnum==DIPSWITCH2+1) + || (picnum==DIPSWITCH3+1) + || (picnum==PULLSWITCH+1) + || (picnum==HANDSWITCH+1) + || (picnum==SLOTDOOR+1) + || (picnum==LIGHTSWITCH+1) + || (picnum==SPACELIGHTSWITCH+1) + || (picnum==SPACEDOORSWITCH+1) + || (picnum==FRANKENSTINESWITCH+1) + || (picnum==LIGHTSWITCH2+1) + || (picnum==POWERSWITCH1+1) + || (picnum==LOCKSWITCH1+1) + || (picnum==POWERSWITCH2+1) + || (picnum==LIGHTSWITCH+1) + ) { + switchpicnum--; + } + if ((picnum > MULTISWITCH)&&(picnum <= MULTISWITCH+3)) { + switchpicnum = MULTISWITCH; + } + + switch(dynamictostatic[switchpicnum]) + { + case DIPSWITCH__STATIC: + // case DIPSWITCH+1: + case TECHSWITCH__STATIC: + // case TECHSWITCH+1: + case ALIENSWITCH__STATIC: + // case ALIENSWITCH+1: + break; + case ACCESSSWITCH__STATIC: + case ACCESSSWITCH2__STATIC: + if(ps[snum].access_incs == 0) + { + if( switchpal == 0 ) + { + if( (ps[snum].got_access&1) ) + ps[snum].access_incs = 1; + else FTA(70,&ps[snum]); + } + + else if( switchpal == 21 ) + { + if( ps[snum].got_access&2 ) + ps[snum].access_incs = 1; + else FTA(71,&ps[snum]); + } + + else if( switchpal == 23 ) + { + if( ps[snum].got_access&4 ) + ps[snum].access_incs = 1; + else FTA(72,&ps[snum]); + } + + if( ps[snum].access_incs == 1 ) + { + if(switchtype == 0) + ps[snum].access_wallnum = w; + else + ps[snum].access_spritenum = w; + } + + return 0; + } + case DIPSWITCH2__STATIC: + //case DIPSWITCH2+1: + case DIPSWITCH3__STATIC: + //case DIPSWITCH3+1: + case MULTISWITCH__STATIC: + //case MULTISWITCH+1: + //case MULTISWITCH+2: + //case MULTISWITCH+3: + case PULLSWITCH__STATIC: + //case PULLSWITCH+1: + case HANDSWITCH__STATIC: + //case HANDSWITCH+1: + case SLOTDOOR__STATIC: + //case SLOTDOOR+1: + case LIGHTSWITCH__STATIC: + //case LIGHTSWITCH+1: + case SPACELIGHTSWITCH__STATIC: + //case SPACELIGHTSWITCH+1: + case SPACEDOORSWITCH__STATIC: + //case SPACEDOORSWITCH+1: + case FRANKENSTINESWITCH__STATIC: + //case FRANKENSTINESWITCH+1: + case LIGHTSWITCH2__STATIC: + //case LIGHTSWITCH2+1: + case POWERSWITCH1__STATIC: + //case POWERSWITCH1+1: + case LOCKSWITCH1__STATIC: + //case LOCKSWITCH1+1: + case POWERSWITCH2__STATIC: + //case POWERSWITCH2+1: + if( check_activator_motion( lotag ) ) return 0; + break; + default: + if( isadoorwall(picnum) == 0 ) return 0; + break; + } + + i = headspritestat[0]; + while(i >= 0) + { + + if ( lotag == SLT ) { + int switchpicnum=PN; // put it in a variable so later switches don't trigger on the result of changes + if ((switchpicnum >= MULTISWITCH) && (switchpicnum <=MULTISWITCH+3)) { + sprite[i].picnum++; + if( sprite[i].picnum > (MULTISWITCH+3) ) + sprite[i].picnum = MULTISWITCH; + + } + switch(dynamictostatic[switchpicnum]) { + + case DIPSWITCH__STATIC: + case TECHSWITCH__STATIC: + case ALIENSWITCH__STATIC: + if( switchtype == 1 && w == i ) PN++; + else if( SHT == 0 ) correctdips++; + numdips++; + break; + case ACCESSSWITCH__STATIC: + case ACCESSSWITCH2__STATIC: + case SLOTDOOR__STATIC: + case LIGHTSWITCH__STATIC: + case SPACELIGHTSWITCH__STATIC: + case SPACEDOORSWITCH__STATIC: + case FRANKENSTINESWITCH__STATIC: + case LIGHTSWITCH2__STATIC: + case POWERSWITCH1__STATIC: + case LOCKSWITCH1__STATIC: + case POWERSWITCH2__STATIC: + case HANDSWITCH__STATIC: + case PULLSWITCH__STATIC: + case DIPSWITCH2__STATIC: + case DIPSWITCH3__STATIC: + sprite[i].picnum++; + break; + default: + switch(dynamictostatic[switchpicnum-1]) { + + case TECHSWITCH__STATIC: + case DIPSWITCH__STATIC: + case ALIENSWITCH__STATIC: + if( switchtype == 1 && w == i ) PN--; + else if( SHT == 1 ) correctdips++; + numdips++; + break; + case PULLSWITCH__STATIC: + case HANDSWITCH__STATIC: + case LIGHTSWITCH2__STATIC: + case POWERSWITCH1__STATIC: + case LOCKSWITCH1__STATIC: + case POWERSWITCH2__STATIC: + case SLOTDOOR__STATIC: + case LIGHTSWITCH__STATIC: + case SPACELIGHTSWITCH__STATIC: + case SPACEDOORSWITCH__STATIC: + case FRANKENSTINESWITCH__STATIC: + case DIPSWITCH2__STATIC: + case DIPSWITCH3__STATIC: + sprite[i].picnum--; + break; + } + break; + } + } + i = nextspritestat[i]; + } + + for(i=0;i= MULTISWITCH) && (wall[x].picnum <=MULTISWITCH+3)) { + wall[x].picnum++; + if(wall[x].picnum > (MULTISWITCH+3) ) + wall[x].picnum = MULTISWITCH; + + } + switch(dynamictostatic[wall[x].picnum]) { + + case DIPSWITCH__STATIC: + case TECHSWITCH__STATIC: + case ALIENSWITCH__STATIC: + if( switchtype == 0 && i == w ) wall[x].picnum++; + else if( wall[x].hitag == 0 ) correctdips++; + numdips++; + break; + case ACCESSSWITCH__STATIC: + case ACCESSSWITCH2__STATIC: + case SLOTDOOR__STATIC: + case LIGHTSWITCH__STATIC: + case SPACELIGHTSWITCH__STATIC: + case SPACEDOORSWITCH__STATIC: + case FRANKENSTINESWITCH__STATIC: + case LIGHTSWITCH2__STATIC: + case POWERSWITCH1__STATIC: + case LOCKSWITCH1__STATIC: + case POWERSWITCH2__STATIC: + case HANDSWITCH__STATIC: + case PULLSWITCH__STATIC: + case DIPSWITCH2__STATIC: + case DIPSWITCH3__STATIC: + wall[x].picnum++; + break; + default: + switch(dynamictostatic[wall[x].picnum-1]) { + + case TECHSWITCH__STATIC: + case DIPSWITCH__STATIC: + case ALIENSWITCH__STATIC: + if( switchtype == 0 && i == w ) wall[x].picnum--; + else if( wall[x].hitag == 1 ) correctdips++; + numdips++; + break; + case PULLSWITCH__STATIC: + case HANDSWITCH__STATIC: + case LIGHTSWITCH2__STATIC: + case POWERSWITCH1__STATIC: + case LOCKSWITCH1__STATIC: + case POWERSWITCH2__STATIC: + case SLOTDOOR__STATIC: + case LIGHTSWITCH__STATIC: + case SPACELIGHTSWITCH__STATIC: + case SPACEDOORSWITCH__STATIC: + case FRANKENSTINESWITCH__STATIC: + case DIPSWITCH2__STATIC: + case DIPSWITCH3__STATIC: + wall[x].picnum--; + break; + } + break; + } + } + } + + if(lotag == (short) 65535) + { + + ps[myconnectindex].gm = MODE_EOL; + if(ud.from_bonus) + { + ud.level_number = ud.from_bonus; + ud.m_level_number = ud.level_number; + ud.from_bonus = 0; + } + else + { + ud.level_number++; + if( (ud.volume_number && ud.level_number > 10 ) || ( ud.volume_number == 0 && ud.level_number > 5 ) ) + ud.level_number = 0; + ud.m_level_number = ud.level_number; + } + return 1; + + } + + switchpicnum = picnum; + + if ( (picnum==DIPSWITCH+1) + || (picnum==TECHSWITCH+1) + || (picnum==ALIENSWITCH+1) + || (picnum==DIPSWITCH2+1) + || (picnum==DIPSWITCH3+1) + || (picnum==PULLSWITCH+1) + || (picnum==HANDSWITCH+1) + || (picnum==SLOTDOOR+1) + || (picnum==LIGHTSWITCH+1) + || (picnum==SPACELIGHTSWITCH+1) + || (picnum==SPACEDOORSWITCH+1) + || (picnum==FRANKENSTINESWITCH+1) + || (picnum==LIGHTSWITCH2+1) + || (picnum==POWERSWITCH1+1) + || (picnum==LOCKSWITCH1+1) + || (picnum==POWERSWITCH2+1) + || (picnum==LIGHTSWITCH+1) + ) { + switchpicnum--; + } + if ((picnum > MULTISWITCH)&&(picnum <= MULTISWITCH+3)) { + switchpicnum = MULTISWITCH; + } + + switch(dynamictostatic[switchpicnum]) + { + default: + if(isadoorwall(picnum) == 0) break; + case DIPSWITCH__STATIC: + //case DIPSWITCH+1: + case TECHSWITCH__STATIC: + //case TECHSWITCH+1: + case ALIENSWITCH__STATIC: + //case ALIENSWITCH+1: + if( picnum == DIPSWITCH || picnum == DIPSWITCH+1 || + picnum == ALIENSWITCH || picnum == ALIENSWITCH+1 || + picnum == TECHSWITCH || picnum == TECHSWITCH+1 ) + { + if( picnum == ALIENSWITCH || picnum == ALIENSWITCH+1) + { + if(switchtype == 1) + xyzsound(ALIEN_SWITCH1,w,sx,sy,ps[snum].posz); + else xyzsound(ALIEN_SWITCH1,ps[snum].i,sx,sy,ps[snum].posz); + } + else + { + if(switchtype == 1) + xyzsound(SWITCH_ON,w,sx,sy,ps[snum].posz); + else xyzsound(SWITCH_ON,ps[snum].i,sx,sy,ps[snum].posz); + } + if(numdips != correctdips) break; + xyzsound(END_OF_LEVEL_WARN,ps[snum].i,sx,sy,ps[snum].posz); + } + case DIPSWITCH2__STATIC: + //case DIPSWITCH2+1: + case DIPSWITCH3__STATIC: + //case DIPSWITCH3+1: + case MULTISWITCH__STATIC: + //case MULTISWITCH+1: + //case MULTISWITCH+2: + //case MULTISWITCH+3: + case ACCESSSWITCH__STATIC: + case ACCESSSWITCH2__STATIC: + case SLOTDOOR__STATIC: + //case SLOTDOOR+1: + case LIGHTSWITCH__STATIC: + //case LIGHTSWITCH+1: + case SPACELIGHTSWITCH__STATIC: + //case SPACELIGHTSWITCH+1: + case SPACEDOORSWITCH__STATIC: + //case SPACEDOORSWITCH+1: + case FRANKENSTINESWITCH__STATIC: + //case FRANKENSTINESWITCH+1: + case LIGHTSWITCH2__STATIC: + //case LIGHTSWITCH2+1: + case POWERSWITCH1__STATIC: + //case POWERSWITCH1+1: + case LOCKSWITCH1__STATIC: + //case LOCKSWITCH1+1: + case POWERSWITCH2__STATIC: + //case POWERSWITCH2+1: + case HANDSWITCH__STATIC: + //case HANDSWITCH+1: + case PULLSWITCH__STATIC: + //case PULLSWITCH+1: + + if( picnum == MULTISWITCH || picnum == (MULTISWITCH+1) || + picnum == (MULTISWITCH+2) || picnum == (MULTISWITCH+3) ) + lotag += picnum-MULTISWITCH; + + x = headspritestat[3]; + while(x >= 0) + { + if( ((sprite[x].hitag) == lotag) ) + { + switch(sprite[x].lotag) + { + case 12: + sector[sprite[x].sectnum].floorpal = 0; + hittype[x].temp_data[0]++; + if(hittype[x].temp_data[0] == 2) + hittype[x].temp_data[0]++; + + break; + case 24: + case 34: + case 25: + hittype[x].temp_data[4] = !hittype[x].temp_data[4]; + if(hittype[x].temp_data[4]) + FTA(15,&ps[snum]); + else FTA(2,&ps[snum]); + break; + case 21: + FTA(2,&ps[screenpeek]); + break; + } + } + x = nextspritestat[x]; + } + + operateactivators(lotag,snum); + operateforcefields(ps[snum].i,lotag); + operatemasterswitches(lotag); + + if( picnum == DIPSWITCH || picnum == DIPSWITCH+1 || + picnum == ALIENSWITCH || picnum == ALIENSWITCH+1 || + picnum == TECHSWITCH || picnum == TECHSWITCH+1 ) return 1; + + if( hitag == 0 && isadoorwall(picnum) == 0 ) + { + if(switchtype == 1) + xyzsound(SWITCH_ON,w,sx,sy,ps[snum].posz); + else xyzsound(SWITCH_ON,ps[snum].i,sx,sy,ps[snum].posz); + } + else if(hitag != 0) + { + if(switchtype == 1 && (soundm[hitag]&4) == 0) + xyzsound(hitag,w,sx,sy,ps[snum].posz); + else spritesound(hitag,ps[snum].i); + } + + return 1; + } + return 0; + +} + +void activatebysector(short sect,short j) +{ + short i,didit; + + didit = 0; + + i = headspritesect[sect]; + while(i >= 0) + { + if(PN == ACTIVATOR) + { + operateactivators(SLT,-1); + didit = 1; + // return; + } + i = nextspritesect[i]; + } + + if(didit == 0) + operatesectors(sect,j); +} + +void breakwall(short newpn,short spr,short dawallnum) +{ + wall[dawallnum].picnum = newpn; + spritesound(VENT_BUST,spr); + spritesound(GLASS_HEAVYBREAK,spr); + lotsofglass(spr,dawallnum,10); +} + +void checkhitwall(short spr,short dawallnum,long x,long y,long z,short atwith) +{ + short j, i, sn = -1, darkestwall; + signed char nfloors,nceilings; + short nextj; + walltype *wal; + spritetype *s; + + wal = &wall[dawallnum]; + + if(wal->overpicnum == MIRROR && checkspriteflagsp(atwith,SPRITE_FLAG_PROJECTILE) && (thisprojectile[spr].workslike & PROJECTILE_FLAG_RPG)) + { + lotsofglass(spr,dawallnum,70); + wal->cstat &= ~16; + wal->overpicnum = MIRRORBROKE; + spritesound(GLASS_HEAVYBREAK,spr); + } + + if(wal->overpicnum == MIRROR) + { + switch(dynamictostatic[atwith]) + { + case HEAVYHBOMB__STATIC: + case RADIUSEXPLOSION__STATIC: + case RPG__STATIC: + case HYDRENT__STATIC: + case SEENINE__STATIC: + case OOZFILTER__STATIC: + case EXPLODINGBARREL__STATIC: + lotsofglass(spr,dawallnum,70); + wal->cstat &= ~16; + wal->overpicnum = MIRRORBROKE; + spritesound(GLASS_HEAVYBREAK,spr); + return; + } + } + + if( ( (wal->cstat&16) || wal->overpicnum == BIGFORCE ) && wal->nextsector >= 0 ) + if( sector[wal->nextsector].floorz > z ) + if( sector[wal->nextsector].floorz-sector[wal->nextsector].ceilingz ) + { + int switchpicnum = wal->overpicnum; + if ((switchpicnum > W_FORCEFIELD)&&(switchpicnum <= W_FORCEFIELD+2)) + switchpicnum = W_FORCEFIELD; + switch(dynamictostatic[switchpicnum]) + { + case W_FORCEFIELD__STATIC: + //case W_FORCEFIELD+1: + //case W_FORCEFIELD+2: + wal->extra = 1; // tell the forces to animate + case BIGFORCE__STATIC: + updatesector(x,y,&sn); + if( sn < 0 ) return; + + if(atwith == -1) + i = EGS(sn,x,y,z,FORCERIPPLE,-127,8,8,0,0,0,spr,5); + else + { + if(atwith == CHAINGUN) + i = EGS(sn,x,y,z,FORCERIPPLE,-127,16+sprite[spr].xrepeat,16+sprite[spr].yrepeat,0,0,0,spr,5); + else i = EGS(sn,x,y,z,FORCERIPPLE,-127,32,32,0,0,0,spr,5); + } + + CS |= 18+128; + SA = getangle(wal->x-wall[wal->point2].x, + wal->y-wall[wal->point2].y)-512; + + spritesound(SOMETHINGHITFORCE,i); + + return; + + case FANSPRITE__STATIC: + wal->overpicnum = FANSPRITEBROKE; + wal->cstat &= 65535-65; + if(wal->nextwall >= 0) + { + wall[wal->nextwall].overpicnum = FANSPRITEBROKE; + wall[wal->nextwall].cstat &= 65535-65; + } + spritesound(VENT_BUST,spr); + spritesound(GLASS_BREAKING,spr); + return; + + case GLASS__STATIC: + updatesector(x,y,&sn); if( sn < 0 ) return; + wal->overpicnum=GLASS2; + lotsofglass(spr,dawallnum,10); + wal->cstat = 0; + + if(wal->nextwall >= 0) + wall[wal->nextwall].cstat = 0; + + i = EGS(sn,x,y,z,SECTOREFFECTOR,0,0,0,ps[0].ang,0,0,spr,3); + SLT = 128; T2 = 5; T3 = dawallnum; + spritesound(GLASS_BREAKING,i); + return; + case STAINGLASS1__STATIC: + updatesector(x,y,&sn); if( sn < 0 ) return; + lotsofcolourglass(spr,dawallnum,80); + wal->cstat = 0; + if(wal->nextwall >= 0) + wall[wal->nextwall].cstat = 0; + spritesound(VENT_BUST,spr); + spritesound(GLASS_BREAKING,spr); + return; + } + } + + switch(dynamictostatic[wal->picnum]) + { + case COLAMACHINE__STATIC: + case VENDMACHINE__STATIC: + breakwall(wal->picnum+2,spr,dawallnum); + spritesound(VENT_BUST,spr); + return; + + case OJ__STATIC: + case FEMPIC2__STATIC: + case FEMPIC3__STATIC: + + case SCREENBREAK6__STATIC: + case SCREENBREAK7__STATIC: + case SCREENBREAK8__STATIC: + + case SCREENBREAK1__STATIC: + case SCREENBREAK2__STATIC: + case SCREENBREAK3__STATIC: + case SCREENBREAK4__STATIC: + case SCREENBREAK5__STATIC: + + case SCREENBREAK9__STATIC: + case SCREENBREAK10__STATIC: + case SCREENBREAK11__STATIC: + case SCREENBREAK12__STATIC: + case SCREENBREAK13__STATIC: + case SCREENBREAK14__STATIC: + case SCREENBREAK15__STATIC: + case SCREENBREAK16__STATIC: + case SCREENBREAK17__STATIC: + case SCREENBREAK18__STATIC: + case SCREENBREAK19__STATIC: + case BORNTOBEWILDSCREEN__STATIC: + + lotsofglass(spr,dawallnum,30); + wal->picnum=W_SCREENBREAK+(TRAND%3); + spritesound(GLASS_HEAVYBREAK,spr); + return; + + case W_TECHWALL5__STATIC: + case W_TECHWALL6__STATIC: + case W_TECHWALL7__STATIC: + case W_TECHWALL8__STATIC: + case W_TECHWALL9__STATIC: + breakwall(wal->picnum+1,spr,dawallnum); + return; + case W_MILKSHELF__STATIC: + breakwall(W_MILKSHELFBROKE,spr,dawallnum); + return; + + case W_TECHWALL10__STATIC: + breakwall(W_HITTECHWALL10,spr,dawallnum); + return; + + case W_TECHWALL1__STATIC: + case W_TECHWALL11__STATIC: + case W_TECHWALL12__STATIC: + case W_TECHWALL13__STATIC: + case W_TECHWALL14__STATIC: + breakwall(W_HITTECHWALL1,spr,dawallnum); + return; + + case W_TECHWALL15__STATIC: + breakwall(W_HITTECHWALL15,spr,dawallnum); + return; + + case W_TECHWALL16__STATIC: + breakwall(W_HITTECHWALL16,spr,dawallnum); + return; + + case W_TECHWALL2__STATIC: + breakwall(W_HITTECHWALL2,spr,dawallnum); + return; + + case W_TECHWALL3__STATIC: + breakwall(W_HITTECHWALL3,spr,dawallnum); + return; + + case W_TECHWALL4__STATIC: + breakwall(W_HITTECHWALL4,spr,dawallnum); + return; + + case ATM__STATIC: + wal->picnum = ATMBROKE; + lotsofmoney(&sprite[spr],1+(TRAND&7)); + spritesound(GLASS_HEAVYBREAK,spr); + break; + + case WALLLIGHT1__STATIC: + case WALLLIGHT2__STATIC: + case WALLLIGHT3__STATIC: + case WALLLIGHT4__STATIC: + case TECHLIGHT2__STATIC: + case TECHLIGHT4__STATIC: + + if( rnd(128) ) + spritesound(GLASS_HEAVYBREAK,spr); + else spritesound(GLASS_BREAKING,spr); + lotsofglass(spr,dawallnum,30); + + if(wal->picnum == WALLLIGHT1) + wal->picnum = WALLLIGHTBUST1; + + if(wal->picnum == WALLLIGHT2) + wal->picnum = WALLLIGHTBUST2; + + if(wal->picnum == WALLLIGHT3) + wal->picnum = WALLLIGHTBUST3; + + if(wal->picnum == WALLLIGHT4) + wal->picnum = WALLLIGHTBUST4; + + if(wal->picnum == TECHLIGHT2) + wal->picnum = TECHLIGHTBUST2; + + if(wal->picnum == TECHLIGHT4) + wal->picnum = TECHLIGHTBUST4; + + if(!wal->lotag) return; + + sn = wal->nextsector; + if(sn < 0) return; + darkestwall = 0; + + wal = &wall[sector[sn].wallptr]; + for(i=sector[sn].wallnum;i > 0;i--,wal++) + if(wal->shade > darkestwall) + darkestwall=wal->shade; + + j = TRAND&1; + i= headspritestat[3]; + while(i >= 0) + { + if(SHT == wall[dawallnum].lotag && SLT == 3 ) + { + T3 = j; + T4 = darkestwall; + T5 = 1; + } + i = nextspritestat[i]; + } + break; + } +} + +void checkplayerhurt(struct player_struct *p,short j) +{ + if( (j&49152) == 49152 ) + { + j &= (MAXSPRITES-1); + + if(sprite[j].picnum==CACTUS){ + + if(p->hurt_delay < 8 ) + { + sprite[p->i].extra -= 5; + + p->hurt_delay = 16; + p->pals_time = 32; + p->pals[0] = 32; + p->pals[1] = 0; + p->pals[2] = 0; + spritesound(DUKE_LONGTERM_PAIN,p->i); + } + + } + return; + } + + if( (j&49152) != 32768) return; + j &= (MAXWALLS-1); + + if( p->hurt_delay > 0 ) p->hurt_delay--; + else if( wall[j].cstat&85 ) { + int switchpicnum = wall[j].overpicnum; + if ((switchpicnum>W_FORCEFIELD)&&(switchpicnum<=W_FORCEFIELD+2)) + switchpicnum=W_FORCEFIELD; + + switch(dynamictostatic[switchpicnum]) + { + case W_FORCEFIELD__STATIC: + // case W_FORCEFIELD+1: + // case W_FORCEFIELD+2: + sprite[p->i].extra -= 5; + + p->hurt_delay = 16; + p->pals_time = 32; + p->pals[0] = 32; + p->pals[1] = 0; + p->pals[2] = 0; + + p->posxv = -(sintable[(p->ang+512)&2047]<<8); + p->posyv = -(sintable[(p->ang)&2047]<<8); + spritesound(DUKE_LONGTERM_PAIN,p->i); + + checkhitwall(p->i,j, + p->posx+(sintable[(p->ang+512)&2047]>>9), + p->posy+(sintable[p->ang&2047]>>9), + p->posz,-1); + + break; + + case BIGFORCE__STATIC: + p->hurt_delay = 26; + checkhitwall(p->i,j, + p->posx+(sintable[(p->ang+512)&2047]>>9), + p->posy+(sintable[p->ang&2047]>>9), + p->posz,-1); + break; + + } + } +} + +char checkhitceiling(short sn) +{ + short i, j, q, darkestwall, darkestceiling; + signed char nfloors,nceilings; + walltype *wal; + + switch(dynamictostatic[sector[sn].ceilingpicnum]) + { + case WALLLIGHT1__STATIC: + case WALLLIGHT2__STATIC: + case WALLLIGHT3__STATIC: + case WALLLIGHT4__STATIC: + case TECHLIGHT2__STATIC: + case TECHLIGHT4__STATIC: + + ceilingglass(ps[myconnectindex].i,sn,10); + spritesound(GLASS_BREAKING,ps[screenpeek].i); + + if(sector[sn].ceilingpicnum == WALLLIGHT1) + sector[sn].ceilingpicnum = WALLLIGHTBUST1; + + if(sector[sn].ceilingpicnum == WALLLIGHT2) + sector[sn].ceilingpicnum = WALLLIGHTBUST2; + + if(sector[sn].ceilingpicnum == WALLLIGHT3) + sector[sn].ceilingpicnum = WALLLIGHTBUST3; + + if(sector[sn].ceilingpicnum == WALLLIGHT4) + sector[sn].ceilingpicnum = WALLLIGHTBUST4; + + if(sector[sn].ceilingpicnum == TECHLIGHT2) + sector[sn].ceilingpicnum = TECHLIGHTBUST2; + + if(sector[sn].ceilingpicnum == TECHLIGHT4) + sector[sn].ceilingpicnum = TECHLIGHTBUST4; + + + if(!sector[sn].hitag) + { + i = headspritesect[sn]; + while(i >= 0) + { + if( PN == SECTOREFFECTOR && SLT == 12 ) + { + j = headspritestat[3]; + while(j >= 0) + { + if( sprite[j].hitag == SHT ) + hittype[j].temp_data[3] = 1; + j = nextspritestat[j]; + } + break; + } + i = nextspritesect[i]; + } + } + + i = headspritestat[3]; + j = TRAND&1; + while(i >= 0) + { + if(SHT == (sector[sn].hitag) && SLT == 3 ) + { + T3 = j; + T5 = 1; + } + i = nextspritestat[i]; + } + + return 1; + } + + return 0; +} + +void checkhitsprite(short i,short sn) +{ + short j, k, l, nextj, p, rpg=0; + spritetype *s; + int switchpicnum; + + i &= (MAXSPRITES-1); + + if(checkspriteflags(sn,SPRITE_FLAG_PROJECTILE)) + if(thisprojectile[sn].workslike & PROJECTILE_FLAG_RPG) + rpg = 1; + switchpicnum = PN; + if ((PN > WATERFOUNTAIN)&&(PN < WATERFOUNTAIN+3)) { + switchpicnum = WATERFOUNTAIN; + } + switch(dynamictostatic[PN]) + { + case OCEANSPRITE1__STATIC: + case OCEANSPRITE2__STATIC: + case OCEANSPRITE3__STATIC: + case OCEANSPRITE4__STATIC: + case OCEANSPRITE5__STATIC: + spawn(i,SMALLSMOKE); + deletesprite(i); + break; + case QUEBALL__STATIC: + case STRIPEBALL__STATIC: + if(sprite[sn].picnum == QUEBALL || sprite[sn].picnum == STRIPEBALL) + { + sprite[sn].xvel = (sprite[i].xvel>>1)+(sprite[i].xvel>>2); + sprite[sn].ang -= (SA<<1)+1024; + SA = getangle(SX-sprite[sn].x,SY-sprite[sn].y)-512; + if(issoundplaying(POOLBALLHIT) < 2) + spritesound(POOLBALLHIT,i); + } + else + { + if( TRAND&3 ) + { + sprite[i].xvel = 164; + sprite[i].ang = sprite[sn].ang; + } + else + { + lotsofglass(i,-1,3); + deletesprite(i); + } + } + break; + case TREE1__STATIC: + case TREE2__STATIC: + case TIRE__STATIC: + case CONE__STATIC: + case BOX__STATIC: + { + if (rpg == 1) + if(T1 == 0) + { + CS &= ~257; + T1 = 1; + spawn(i,BURNING); + } + switch(dynamictostatic[sprite[sn].picnum]) + { + case RADIUSEXPLOSION__STATIC: + case RPG__STATIC: + case FIRELASER__STATIC: + case HYDRENT__STATIC: + case HEAVYHBOMB__STATIC: + if(T1 == 0) + { + CS &= ~257; + T1 = 1; + spawn(i,BURNING); + } + break; + } + break; + } + case CACTUS__STATIC: + { + if (rpg == 1) + for(k=0;k<64;k++) + { + j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5); + sprite[j].pal = 8; + } + // case CACTUSBROKE: + switch(dynamictostatic[sprite[sn].picnum]) + { + case RADIUSEXPLOSION__STATIC: + case RPG__STATIC: + case FIRELASER__STATIC: + case HYDRENT__STATIC: + case HEAVYHBOMB__STATIC: + for(k=0;k<64;k++) + { + j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5); + sprite[j].pal = 8; + } + + if(PN == CACTUS) + PN = CACTUSBROKE; + CS &= ~257; + // else deletesprite(i); + break; + } + break; + } + case HANGLIGHT__STATIC: + case GENERICPOLE2__STATIC: + for(k=0;k<6;k++) + EGS(SECT,SX,SY,SZ-(8<<8),SCRAP1+(TRAND&15),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5); + spritesound(GLASS_HEAVYBREAK,i); + deletesprite(i); + break; + + + case FANSPRITE__STATIC: + PN = FANSPRITEBROKE; + CS &= (65535-257); + if( sector[SECT].floorpicnum == FANSHADOW ) + sector[SECT].floorpicnum = FANSHADOWBROKE; + + spritesound(GLASS_HEAVYBREAK,i); + s = &sprite[i]; + for(j=0;j<16;j++) RANDOMSCRAP; + + break; + case WATERFOUNTAIN__STATIC: + // case WATERFOUNTAIN+1: + // case WATERFOUNTAIN+2: + // case __STATIC: + PN = WATERFOUNTAINBROKE; + spawn(i,TOILETWATER); + break; + case SATELITE__STATIC: + case FUELPOD__STATIC: + case SOLARPANNEL__STATIC: + case ANTENNA__STATIC: + if(sprite[sn].extra != *actorscrptr[SHOTSPARK1] ) + { + for(j=0;j<15;j++) + EGS(SECT,SX,SY,sector[SECT].floorz-(12<<8)-(j<<9),SCRAP1+(TRAND&15),-8,64,64, + TRAND&2047,(TRAND&127)+64,-(TRAND&511)-256,i,5); + spawn(i,EXPLOSION2); + deletesprite(i); + } + break; + case BOTTLE1__STATIC: + case BOTTLE2__STATIC: + case BOTTLE3__STATIC: + case BOTTLE4__STATIC: + case BOTTLE5__STATIC: + case BOTTLE6__STATIC: + case BOTTLE8__STATIC: + case BOTTLE10__STATIC: + case BOTTLE11__STATIC: + case BOTTLE12__STATIC: + case BOTTLE13__STATIC: + case BOTTLE14__STATIC: + case BOTTLE15__STATIC: + case BOTTLE16__STATIC: + case BOTTLE17__STATIC: + case BOTTLE18__STATIC: + case BOTTLE19__STATIC: + case WATERFOUNTAINBROKE__STATIC: + case DOMELITE__STATIC: + case SUSHIPLATE1__STATIC: + case SUSHIPLATE2__STATIC: + case SUSHIPLATE3__STATIC: + case SUSHIPLATE4__STATIC: + case SUSHIPLATE5__STATIC: + case WAITTOBESEATED__STATIC: + case VASE__STATIC: + case STATUEFLASH__STATIC: + case STATUE__STATIC: + if(PN == BOTTLE10) + lotsofmoney(&sprite[i],4+(TRAND&3)); + else if(PN == STATUE || PN == STATUEFLASH) + { + lotsofcolourglass(i,-1,40); + spritesound(GLASS_HEAVYBREAK,i); + } + else if(PN == VASE) + lotsofglass(i,-1,40); + + spritesound(GLASS_BREAKING,i); + SA = TRAND&2047; + lotsofglass(i,-1,8); + deletesprite(i); + break; + case FETUS__STATIC: + PN = FETUSBROKE; + spritesound(GLASS_BREAKING,i); + lotsofglass(i,-1,10); + break; + case FETUSBROKE__STATIC: + for(j=0;j<48;j++) + { + shoot(i,BLOODSPLAT1); + SA += 333; + } + spritesound(GLASS_HEAVYBREAK,i); + spritesound(SQUISHED,i); + case BOTTLE7__STATIC: + spritesound(GLASS_BREAKING,i); + lotsofglass(i,-1,10); + deletesprite(i); + break; + case HYDROPLANT__STATIC: + PN = BROKEHYDROPLANT; + spritesound(GLASS_BREAKING,i); + lotsofglass(i,-1,10); + break; + + case FORCESPHERE__STATIC: + sprite[i].xrepeat = 0; + hittype[OW].temp_data[0] = 32; + hittype[OW].temp_data[1] = !hittype[OW].temp_data[1]; + hittype[OW].temp_data[2] ++; + spawn(i,EXPLOSION2); + break; + + case BROKEHYDROPLANT__STATIC: + if(CS&1) + { + spritesound(GLASS_BREAKING,i); + SZ += 16<<8; + CS = 0; + lotsofglass(i,-1,5); + } + break; + + case TOILET__STATIC: + PN = TOILETBROKE; + CS |= (TRAND&1)<<2; + CS &= ~257; + spawn(i,TOILETWATER); + spritesound(GLASS_BREAKING,i); + break; + + case STALL__STATIC: + PN = STALLBROKE; + CS |= (TRAND&1)<<2; + CS &= ~257; + spawn(i,TOILETWATER); + spritesound(GLASS_HEAVYBREAK,i); + break; + + case HYDRENT__STATIC: + PN = BROKEFIREHYDRENT; + spawn(i,TOILETWATER); + + // for(k=0;k<5;k++) + // { + // j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5); + // sprite[j].pal = 2; + // } + spritesound(GLASS_HEAVYBREAK,i); + break; + + case GRATE1__STATIC: + PN = BGRATE1; + CS &= (65535-256-1); + spritesound(VENT_BUST,i); + break; + + case CIRCLEPANNEL__STATIC: + PN = CIRCLEPANNELBROKE; + CS &= (65535-256-1); + spritesound(VENT_BUST,i); + break; + case PANNEL1__STATIC: + case PANNEL2__STATIC: + PN = BPANNEL1; + CS &= (65535-256-1); + spritesound(VENT_BUST,i); + break; + case PANNEL3__STATIC: + PN = BPANNEL3; + CS &= (65535-256-1); + spritesound(VENT_BUST,i); + break; + case PIPE1__STATIC: + case PIPE2__STATIC: + case PIPE3__STATIC: + case PIPE4__STATIC: + case PIPE5__STATIC: + case PIPE6__STATIC: + switch(dynamictostatic[PN]) + { + case PIPE1__STATIC:PN=PIPE1B;break; + case PIPE2__STATIC:PN=PIPE2B;break; + case PIPE3__STATIC:PN=PIPE3B;break; + case PIPE4__STATIC:PN=PIPE4B;break; + case PIPE5__STATIC:PN=PIPE5B;break; + case PIPE6__STATIC:PN=PIPE6B;break; + } + + j = spawn(i,STEAM); + sprite[j].z = sector[SECT].floorz-(32<<8); + break; + + case MONK__STATIC: + case LUKE__STATIC: + case INDY__STATIC: + case JURYGUY__STATIC: + spritesound(SLT,i); + spawn(i,SHT); + case SPACEMARINE__STATIC: + sprite[i].extra -= sprite[sn].extra; + if(sprite[i].extra > 0) break; + SA = TRAND&2047; + shoot(i,BLOODSPLAT1); + SA = TRAND&2047; + shoot(i,BLOODSPLAT2); + SA = TRAND&2047; + shoot(i,BLOODSPLAT3); + SA = TRAND&2047; + shoot(i,BLOODSPLAT4); + SA = TRAND&2047; + shoot(i,BLOODSPLAT1); + SA = TRAND&2047; + shoot(i,BLOODSPLAT2); + SA = TRAND&2047; + shoot(i,BLOODSPLAT3); + SA = TRAND&2047; + shoot(i,BLOODSPLAT4); + guts(&sprite[i],JIBS1,1,myconnectindex); + guts(&sprite[i],JIBS2,2,myconnectindex); + guts(&sprite[i],JIBS3,3,myconnectindex); + guts(&sprite[i],JIBS4,4,myconnectindex); + guts(&sprite[i],JIBS5,1,myconnectindex); + guts(&sprite[i],JIBS3,6,myconnectindex); + sound(SQUISHED); + deletesprite(i); + break; + case CHAIR1__STATIC: + case CHAIR2__STATIC: + PN = BROKENCHAIR; + CS = 0; + break; + case CHAIR3__STATIC: + case MOVIECAMERA__STATIC: + case SCALE__STATIC: + case VACUUM__STATIC: + case CAMERALIGHT__STATIC: + case IVUNIT__STATIC: + case POT1__STATIC: + case POT2__STATIC: + case POT3__STATIC: + case TRIPODCAMERA__STATIC: + spritesound(GLASS_HEAVYBREAK,i); + s = &sprite[i]; + for(j=0;j<16;j++) RANDOMSCRAP; + deletesprite(i); + break; + case PLAYERONWATER__STATIC: + i = OW; + default: + if( (sprite[i].cstat&16) && SHT == 0 && SLT == 0 && sprite[i].statnum == 0) + break; + + if( ( sprite[sn].picnum == FREEZEBLAST || sprite[sn].owner != i ) && sprite[i].statnum != 4) + { + if( badguy(&sprite[i]) == 1) + { + if(sprite[sn].picnum == RPG) sprite[sn].extra <<= 1; + + if( (PN != DRONE) && (PN != ROTATEGUN) && (PN != COMMANDER) && (PN < GREENSLIME || PN > GREENSLIME+7) ) + if(sprite[sn].picnum != FREEZEBLAST ) + if( actortype[PN] == 0 ) + { + j = spawn(sn,JIBS6); + if(sprite[sn].pal == 6) + sprite[j].pal = 6; + sprite[j].z += (4<<8); + sprite[j].xvel = 16; + sprite[j].xrepeat = sprite[j].yrepeat = 24; + sprite[j].ang += 32-(TRAND&63); + } + + j = sprite[sn].owner; + + if( j >= 0 && sprite[j].picnum == APLAYER && PN != ROTATEGUN && PN != DRONE ) + if( ps[sprite[j].yvel].curr_weapon == SHOTGUN_WEAPON ) + { + shoot(i,BLOODSPLAT3); + shoot(i,BLOODSPLAT1); + shoot(i,BLOODSPLAT2); + shoot(i,BLOODSPLAT4); + } + + if( PN != TANK && PN != BOSS1 && PN != BOSS4 && PN != BOSS2 && PN != BOSS3 && PN != RECON && PN != ROTATEGUN ) + { + if( (sprite[i].cstat&48) == 0 ) + SA = (sprite[sn].ang+1024)&2047; + sprite[i].xvel = -(sprite[sn].extra<<2); + j = SECT; + pushmove(&SX,&SY,&SZ,&j,128L,(4L<<8),(4L<<8),CLIPMASK0); + if(j != SECT && j >= 0 && j < MAXSECTORS) + changespritesect(i,j); + } + + if(sprite[i].statnum == 2) + { + changespritestat(i,1); + hittype[i].timetosleep = SLEEPTIME; + } + if( ( RX < 24 || PN == SHARK) && sprite[sn].picnum == SHRINKSPARK) return; + } + + if( sprite[i].statnum != 2 ) + { + if( sprite[sn].picnum == FREEZEBLAST && ( (PN == APLAYER && sprite[i].pal == 1 ) || ( freezerhurtowner == 0 && sprite[sn].owner == i ) ) ) + return; + + hittype[i].picnum = sprite[sn].picnum; + hittype[i].extra += sprite[sn].extra; + hittype[i].ang = sprite[sn].ang; + hittype[i].owner = sprite[sn].owner; + } + + if(sprite[i].statnum == 10) + { + p = sprite[i].yvel; + if(ps[p].newowner >= 0) + { + ps[p].newowner = -1; + ps[p].posx = ps[p].oposx; + ps[p].posy = ps[p].oposy; + ps[p].posz = ps[p].oposz; + ps[p].ang = ps[p].oang; + + updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum); + setpal(&ps[p]); + + j = headspritestat[1]; + while(j >= 0) + { + if(sprite[j].picnum==CAMERA1) sprite[j].yvel = 0; + j = nextspritestat[j]; + } + } + + if( RX < 24 && sprite[sn].picnum == SHRINKSPARK) + return; + + if( sprite[hittype[i].owner].picnum != APLAYER) + if(ud.player_skill >= 3) + sprite[sn].extra += (sprite[sn].extra>>1); + } + + } + break; + } +} + +void allignwarpelevators(void) +{ + short i, j; + + i = headspritestat[3]; + while(i >= 0) + { + if( SLT == 17 && SS > 16) + { + j = headspritestat[3]; + while(j >= 0) + { + if( (sprite[j].lotag) == 17 && i != j && + (SHT) == (sprite[j].hitag) ) + { + sector[sprite[j].sectnum].floorz = + sector[SECT].floorz; + sector[sprite[j].sectnum].ceilingz = + sector[SECT].ceilingz; + } + + j = nextspritestat[j]; + } + } + i = nextspritestat[i]; + } +} + +void cheatkeys(short snum) +{ + short i, k; + char dainv; + unsigned long sb_snum, j; + struct player_struct *p; + + sb_snum = sync[snum].bits; + p = &ps[snum]; + + if(p->cheat_phase == 1) return; + + // 1<<0 = jump + // 1<<1 = crouch + // 1<<2 = fire + // 1<<3 = aim up + // 1<<4 = aim down + // 1<<5 = run + // 1<<6 = look left + // 1<<7 = look right + // 15<<8 = !weapon selection (bits 8-11) + // 1<<12 = !steroids + // 1<<13 = look up + // 1<<14 = look down + // 1<<15 = !nightvis + // 1<<16 = !medkit + // 1<<17 = (multiflag==1) ? changes meaning of bits 18 and 19 + // 1<<18 = centre view + // 1<<19 = !holster weapon + // 1<<20 = !inventory left + // 1<<21 = !pause + // 1<<22 = !quick kick + // 1<<23 = aim mode + // 1<<24 = !holoduke + // 1<<25 = !jetpack + // 1<<26 = gamequit + // 1<<27 = !inventory right + // 1<<28 = !turn around + // 1<<29 = !open + // 1<<30 = !inventory + // 1<<31 = !escape + + i = p->aim_mode; + p->aim_mode = (sb_snum>>23)&1; + if(p->aim_mode < i) + p->return_to_center = 9; + + if( (sb_snum&(1<<22)) && p->quick_kick == 0) + if( p->curr_weapon != KNEE_WEAPON || p->kickback_pic == 0 ) + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_QUICKKICK,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0 ) + { + p->quick_kick = 14; + FTA(80,p); + } + } + + j = sb_snum & ((15<<8)|(1<<12)|(1<<15)|(1<<16)|(1<<22)|(1<<19)|(1<<20)|(1<<21)|(1<<24)|(1<<25)|(1<<27)|(1<<28)|(1<<29)|(1<<30)|(1<<31)); + sb_snum = j & ~p->interface_toggle_flag; + p->interface_toggle_flag |= sb_snum | ((sb_snum&0xf00)?0xf00:0); + p->interface_toggle_flag &= j | ((j&0xf00)?0xf00:0); + + if(sb_snum && ( sb_snum&(1<<17) ) == 0) + { + if( sb_snum&(1<<21) ) + { + KB_ClearKeyDown( sc_Pause ); + ud.pause_on = !ud.pause_on; + if( ud.pause_on == 1 && sb_snum&(1<<5) ) ud.pause_on = 2; + if(ud.pause_on) + { + MUSIC_Pause(); + FX_StopAllSounds(); + clearsoundlocks(); + } + else + { + if(MusicToggle) MUSIC_Continue(); + pub = NUMPAGES; + pus = NUMPAGES; + } + } + + if(ud.pause_on) return; + + if(sprite[p->i].extra <= 0) return; // if dead... + + if( sb_snum&(1<<30) && p->newowner == -1 ) // inventory button generates event for selected item + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_INVENTORY,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0 ) + { + switch(p->inven_icon) + { + case 4: sb_snum |= (1<<25);break; + case 3: sb_snum |= (1<<24);break; + case 5: sb_snum |= (1<<15);break; + case 1: sb_snum |= (1<<16);break; + case 2: sb_snum |= (1<<12);break; + } + } + } + + if( sb_snum&(1<<15) ) + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_USENIGHTVISION,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0 + && p->heat_amount > 0) + { + p->heat_on = !p->heat_on; + setpal(p); + p->inven_icon = 5; + spritesound(NITEVISION_ONOFF,p->i); + FTA(106+(!p->heat_on),p); + } + } + + if( (sb_snum&(1<<12)) ) + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_USESTEROIDS,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0) + { + if(p->steroids_amount == 400 ) + { + p->steroids_amount--; + spritesound(DUKE_TAKEPILLS,p->i); + p->inven_icon = 2; + FTA(12,p); + } + } + return; // is there significance to returning? + } + if(p->refresh_inventory) + { + sb_snum|=(1<<20); // emulate move left... + } + if(p->newowner == -1) + if( sb_snum&(1<<20) || sb_snum&(1<<27)) + { + p->invdisptime = 26*2; + + if( sb_snum&(1<<27) ) k = 1; + else k = 0; + + if(p->refresh_inventory) p->refresh_inventory = 0; + dainv = p->inven_icon; + + i = 0; +CHECKINV1: + + if(i < 9) + { + i++; + + switch(dainv) + { + case 4: + if(p->jetpack_amount > 0 && i > 1) + break; + if(k) dainv = 5; + else dainv = 3; + goto CHECKINV1; + case 6: + if(p->scuba_amount > 0 && i > 1) + break; + if(k) dainv = 7; + else dainv = 5; + goto CHECKINV1; + case 2: + if(p->steroids_amount > 0 && i > 1) + break; + if(k) dainv = 3; + else dainv = 1; + goto CHECKINV1; + case 3: + if(p->holoduke_amount > 0 && i > 1) + break; + if(k) dainv = 4; + else dainv = 2; + goto CHECKINV1; + case 0: + case 1: + if(p->firstaid_amount > 0 && i > 1) + break; + if(k) dainv = 2; + else dainv = 7; + goto CHECKINV1; + case 5: + if(p->heat_amount > 0 && i > 1) + break; + if(k) dainv = 6; + else dainv = 4; + goto CHECKINV1; + case 7: + if(p->boot_amount > 0 && i > 1) + break; + if(k) dainv = 1; + else dainv = 6; + goto CHECKINV1; + } + } + else dainv = 0; + + if( sb_snum&(1<<20) ) // Inventory_Left + { + SetGameVarID(g_iReturnVarID,dainv,ps[snum].i,snum); + OnEvent(EVENT_INVENTORYLEFT,ps[snum].i,snum, -1); + dainv=GetGameVarID(g_iReturnVarID,ps[snum].i,snum); + } + if( sb_snum&(1<<27) ) // Inventory_Right + { + SetGameVarID(g_iReturnVarID,dainv,ps[snum].i,snum); + OnEvent(EVENT_INVENTORYRIGHT,ps[snum].i,snum, -1); + dainv=GetGameVarID(g_iReturnVarID,ps[snum].i,snum); + } + + p->inven_icon = dainv; + + switch(dainv) + { + case 1: FTA(3,p);break; + case 2: FTA(90,p);break; + case 3: FTA(91,p);break; + case 4: FTA(88,p);break; + case 5: FTA(101,p);break; + case 6: FTA(89,p);break; + case 7: FTA(6,p);break; + } + } + + j = ( (sb_snum&(15<<8))>>8 ) - 1; + + if (j == 0) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY1,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 1) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY2,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 2) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY3,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 3) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY4,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 4) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY5,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 5) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY6,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 6) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY7,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 7) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY8,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 8) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY9,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 9) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_WEAPKEY10,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 10) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_PREVIOUSWEAPON,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (j == 11) + { + SetGameVarID(g_iReturnVarID,j,p->i,snum); + OnEvent(EVENT_NEXTWEAPON,p->i,snum, -1); + if((unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum) != j) + j = (unsigned long) GetGameVarID(g_iReturnVarID,p->i,snum); + } + + if (p->reloading == 1) + j = -1; + else if( j > 0 && p->kickback_pic == 1 && p->weapon_pos == 1) + { + p->wantweaponfire = j; + p->kickback_pic = 0; + } + if(p->last_pissed_time <= (26*218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 32 && p->access_incs == 0 && p->knee_incs == 0 ) + { + if( ( p->weapon_pos == 0 || ( p->holster_weapon && p->weapon_pos == -9 ) )) + { + if(j == 10 || j == 11) + { + k = p->curr_weapon; + j = ( j == 10 ? -1 : 1 ); // JBF: prev (-1) or next (1) weapon choice + i = 0; + + while( ( k >= 0 && k < 10 ) || ( PLUTOPAK && k == GROW_WEAPON && (p->subweapon&(1<subweapon&(1<gotweapon[k] && p->ammo_amount[k] > 0 ) + { + if (PLUTOPAK) // JBF 20040116: so we don't select grower with v1.3d + if( k == SHRINKER_WEAPON && (p->subweapon&(1<ammo_amount[GROW_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[SHRINKER_WEAPON] > 0) // JBF 20040116: added PLUTOPAK so we don't select grower with v1.3d + { + j = SHRINKER_WEAPON; + p->subweapon &= ~(1<ammo_amount[SHRINKER_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[GROW_WEAPON] > 0) // JBF 20040116: added PLUTOPAK so we don't select grower with v1.3d + { + j = GROW_WEAPON; + p->subweapon |= (1<i, snum); + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_SELECTWEAPON,p->i,snum, -1); + if(GetGameVarID(g_iReturnVarID,p->i,snum) == 0) + { + if( j == HANDBOMB_WEAPON && p->ammo_amount[HANDBOMB_WEAPON] == 0 ) + { + k = headspritestat[1]; + while(k >= 0) + { + if( sprite[k].picnum == HEAVYHBOMB && sprite[k].owner == p->i ) + { + p->gotweapon[HANDBOMB_WEAPON] = 1; + j = HANDREMOTE_WEAPON; + break; + } + k = nextspritestat[k]; + } + } + + if(j == SHRINKER_WEAPON && PLUTOPAK) // JBF 20040116: so we don't select the grower with v1.3d + { + if(screenpeek == snum) pus = NUMPAGES; + + if( p->curr_weapon != GROW_WEAPON && p->curr_weapon != SHRINKER_WEAPON ) + { + if( p->ammo_amount[GROW_WEAPON] > 0 ) + { + if( (p->subweapon&(1<ammo_amount[SHRINKER_WEAPON] == 0) + { + j = GROW_WEAPON; + p->subweapon |= (1<ammo_amount[SHRINKER_WEAPON] > 0 ) + p->subweapon &= ~(1<curr_weapon == SHRINKER_WEAPON ) + { + p->subweapon |= (1<subweapon &= ~(1<holster_weapon) + { + sb_snum |= 1<<19; + p->weapon_pos = -9; + } + else if( (long)j >= 0 && p->gotweapon[j] && (unsigned long)p->curr_weapon != j ) + switch(j) + { + case KNEE_WEAPON: + addweapon( p, KNEE_WEAPON ); + break; + case PISTOL_WEAPON: + if ( p->ammo_amount[PISTOL_WEAPON] == 0 ) + if(p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, PISTOL_WEAPON ); + break; + case SHOTGUN_WEAPON: + if( p->ammo_amount[SHOTGUN_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, SHOTGUN_WEAPON); + break; + case CHAINGUN_WEAPON: + if( p->ammo_amount[CHAINGUN_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, CHAINGUN_WEAPON); + break; + case RPG_WEAPON: + if( p->ammo_amount[RPG_WEAPON] == 0 ) + if(p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, RPG_WEAPON ); + break; + case DEVISTATOR_WEAPON: + if( p->ammo_amount[DEVISTATOR_WEAPON] == 0 && p->show_empty_weapon == 0 ) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, DEVISTATOR_WEAPON ); + break; + case FREEZE_WEAPON: + if( p->ammo_amount[FREEZE_WEAPON] == 0 && p->show_empty_weapon == 0) + { + p->last_full_weapon = p->curr_weapon; + p->show_empty_weapon = 32; + } + addweapon( p, FREEZE_WEAPON ); + break; + case GROW_WEAPON: + case SHRINKER_WEAPON: + + if( p->ammo_amount[j] == 0 && p->show_empty_weapon == 0) + { + p->show_empty_weapon = 32; + p->last_full_weapon = p->curr_weapon; + } + + addweapon(p, j); + break; + case HANDREMOTE_WEAPON: + if(k >= 0) // Found in list of [1]'s + { + p->curr_weapon = HANDREMOTE_WEAPON; + p->last_weapon = -1; + p->weapon_pos = 10; + } + break; + case HANDBOMB_WEAPON: + if( p->ammo_amount[HANDBOMB_WEAPON] > 0 && p->gotweapon[HANDBOMB_WEAPON] ) + addweapon( p, HANDBOMB_WEAPON ); + break; + case TRIPBOMB_WEAPON: + if( p->ammo_amount[TRIPBOMB_WEAPON] > 0 && p->gotweapon[TRIPBOMB_WEAPON] ) + addweapon( p, TRIPBOMB_WEAPON ); + break; + } + } + + } + if( sb_snum&(1<<19) ) + { + if( p->curr_weapon > KNEE_WEAPON ) + { + if(p->holster_weapon == 0 && p->weapon_pos == 0) + { + p->holster_weapon = 1; + p->weapon_pos = -1; + FTA(73,p); + } + else if(p->holster_weapon == 1 && p->weapon_pos == -9) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + FTA(74,p); + } + } + } + } + + if( sb_snum&(1<<24) && p->newowner == -1 ) + { + + if( p->holoduke_on == -1 ) + { + + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_HOLODUKEON,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0) + { + if( p->holoduke_amount > 0 ) + { + p->inven_icon = 3; + + p->holoduke_on = i = + EGS(p->cursectnum, + p->posx, + p->posy, + p->posz+(30<<8),APLAYER,-64,0,0,p->ang,0,0,-1,10); + T4 = T5 = 0; + SP = snum; + sprite[i].extra = 0; + FTA(47,p); + } + else FTA(49,p); + spritesound(TELEPORTER,p->holoduke_on); + } + + } + else + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_HOLODUKEOFF,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0) + { + spritesound(TELEPORTER,p->holoduke_on); + p->holoduke_on = -1; + FTA(48,p); + } + } + } + + if( sb_snum&(1<<16) ) + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_USEMEDKIT,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0) + { + if( p->firstaid_amount > 0 && sprite[p->i].extra < max_player_health ) + { + j = max_player_health-sprite[p->i].extra; + + if((unsigned long)p->firstaid_amount > j) + { + p->firstaid_amount -= j; + sprite[p->i].extra = max_player_health; + p->inven_icon = 1; + } + else + { + sprite[p->i].extra += p->firstaid_amount; + p->firstaid_amount = 0; + checkavailinven(p); + } + spritesound(DUKE_USEMEDKIT,p->i); + } + } + } + + if( sb_snum&(1<<25) && p->newowner == -1) + { + SetGameVarID(g_iReturnVarID,0,ps[snum].i,snum); + OnEvent(EVENT_USEJETPACK,ps[snum].i,snum, -1); + if(GetGameVarID(g_iReturnVarID,ps[snum].i,snum) == 0) + { + if( p->jetpack_amount > 0 ) + { + p->jetpack_on = !p->jetpack_on; + if(p->jetpack_on) + { + p->inven_icon = 4; + if(p->scream_voice > FX_Ok) + { + FX_StopSound(p->scream_voice); + testcallback(DUKE_SCREAM); + p->scream_voice = FX_Ok; + } + + spritesound(DUKE_JETPACK_ON,p->i); + + FTA(52,p); + } + else + { + p->hard_landing = 0; + p->poszv = 0; + spritesound(DUKE_JETPACK_OFF,p->i); + stopspritesound(DUKE_JETPACK_IDLE,p->i); + stopspritesound(DUKE_JETPACK_ON,p->i); + FTA(53,p); + } + } + else FTA(50,p); + } + } + + if(sb_snum&(1<<28) && p->one_eighty_count == 0) + { + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_TURNAROUND,p->i,snum, -1); + if(GetGameVarID(g_iReturnVarID,p->i,snum) == 0) + { + p->one_eighty_count = -1024; + } + } + } +} + +void checksectors(short snum) +{ + long i = -1,oldz; + struct player_struct *p; + short j,hitscanwall; + + p = &ps[snum]; + + switch(sector[p->cursectnum].lotag) + { + + case 32767: + sector[p->cursectnum].lotag = 0; + FTA(9,p); + p->secret_rooms++; + return; + case -1: + for(i=connecthead;i>=0;i=connectpoint2[i]) + ps[i].gm = MODE_EOL; + sector[p->cursectnum].lotag = 0; + if(ud.from_bonus) + { + ud.level_number = ud.from_bonus; + ud.m_level_number = ud.level_number; + ud.from_bonus = 0; + } + else + { + ud.level_number++; + if( (ud.volume_number && ud.level_number > 10 ) || ud.level_number > 5 ) + ud.level_number = 0; + ud.m_level_number = ud.level_number; + } + return; + case -2: + sector[p->cursectnum].lotag = 0; + p->timebeforeexit = 26*8; + p->customexitsound = sector[p->cursectnum].hitag; + return; + default: + if(sector[p->cursectnum].lotag >= 10000 && sector[p->cursectnum].lotag < 16383) + { + if(snum == screenpeek || (gametype_flags[ud.coop]&GAMETYPE_FLAG_COOPSOUND)) + spritesound(sector[p->cursectnum].lotag-10000,p->i); + sector[p->cursectnum].lotag = 0; + } + break; + + } + + //After this point the the player effects the map with space + + if(p->gm&MODE_TYPE || sprite[p->i].extra <= 0) return; + + if((sync[snum].bits&(1<<29))) + { + SetGameVarID(g_iReturnVarID,0,p->i,snum); + OnEvent(EVENT_USE, p->i, snum, -1); + if(GetGameVarID(g_iReturnVarID,p->i,snum) != 0) + sync[snum].bits &= ~(1<<29); + } + + if( ud.cashman && sync[snum].bits&(1<<29) ) + lotsofmoney(&sprite[p->i],2); + + if(p->newowner >= 0) + { + if( klabs(sync[snum].svel) > 768 || klabs(sync[snum].fvel) > 768 ) + { + i = -1; + goto CLEARCAMERAS; + } + } + + if( !(sync[snum].bits&(1<<29)) && !(sync[snum].bits&(1<<31))) + p->toggle_key_flag = 0; + + else if(!p->toggle_key_flag) + { + + if( (sync[snum].bits&(1<<31)) ) + { + if( p->newowner >= 0 ) + { + i = -1; + goto CLEARCAMERAS; + } + return; + } + + neartagsprite = -1; + p->toggle_key_flag = 1; + hitscanwall = -1; + + i = hitawall(p,&hitscanwall); + + if(i < 1280 && hitscanwall >= 0 && wall[hitscanwall].overpicnum == MIRROR) + if( wall[hitscanwall].lotag > 0 && !isspritemakingsound(p->i,wall[hitscanwall].lotag) && snum == screenpeek) + { + spritesound(wall[hitscanwall].lotag,p->i); + return; + } + + if(hitscanwall >= 0 && (wall[hitscanwall].cstat&16) ) + switch(wall[hitscanwall].overpicnum) + { + default: + if(wall[hitscanwall].lotag) + return; + } + + if(p->newowner >= 0) + neartag(p->oposx,p->oposy,p->oposz,sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1); + else + { + neartag(p->posx,p->posy,p->posz,sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1); + if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) + neartag(p->posx,p->posy,p->posz+(8<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1); + if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) + neartag(p->posx,p->posy,p->posz+(16<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1); + if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) + { + neartag(p->posx,p->posy,p->posz+(16<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,3); + if(neartagsprite >= 0) + { + switch(dynamictostatic[sprite[neartagsprite].picnum]) + { + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case PODFEM1__STATIC: + case NAKED1__STATIC: + case STATUE__STATIC: + case TOUGHGAL__STATIC: + return; + } + } + + neartagsprite = -1; + neartagwall = -1; + neartagsector = -1; + } + } + + if(p->newowner == -1 && neartagsprite == -1 && neartagsector == -1 && neartagwall == -1 ) + if( isanunderoperator(sector[sprite[p->i].sectnum].lotag) ) + neartagsector = sprite[p->i].sectnum; + + if( neartagsector >= 0 && (sector[neartagsector].lotag&16384) ) + return; + + if( neartagsprite == -1 && neartagwall == -1) + if(sector[p->cursectnum].lotag == 2 ) + { + oldz = hitasprite(p->i,&neartagsprite); + if(oldz > 1280) neartagsprite = -1; + } + + if(neartagsprite >= 0) + { + if( checkhitswitch(snum,neartagsprite,1) ) return; + + switch(dynamictostatic[sprite[neartagsprite].picnum]) + { + case TOILET__STATIC: + case STALL__STATIC: + if(p->last_pissed_time == 0) + { + if(ud.lockout == 0) spritesound(DUKE_URINATE,p->i); + + p->last_pissed_time = 26*220; + p->transporter_hold = 29*2; + if(p->holster_weapon == 0) + { + p->holster_weapon = 1; + p->weapon_pos = -1; + } + if(sprite[p->i].extra <= (max_player_health-(max_player_health/10) ) ) + { + sprite[p->i].extra += max_player_health/10; + p->last_extra = sprite[p->i].extra; + } + else if(sprite[p->i].extra < max_player_health ) + sprite[p->i].extra = max_player_health; + } + else if(!isspritemakingsound(neartagsprite,FLUSH_TOILET)) + spritesound(FLUSH_TOILET,neartagsprite); + return; + + case NUKEBUTTON__STATIC: + + hitawall(p,&j); + if(j >= 0 && wall[j].overpicnum == 0) + if(hittype[neartagsprite].temp_data[0] == 0) + { + hittype[neartagsprite].temp_data[0] = 1; + sprite[neartagsprite].owner = p->i; + p->buttonpalette = sprite[neartagsprite].pal; + if(p->buttonpalette) + ud.secretlevel = sprite[neartagsprite].lotag; + else ud.secretlevel = 0; + } + return; + case WATERFOUNTAIN__STATIC: + if(hittype[neartagsprite].temp_data[0] != 1) + { + hittype[neartagsprite].temp_data[0] = 1; + sprite[neartagsprite].owner = p->i; + + if(sprite[p->i].extra < max_player_health) + { + sprite[p->i].extra++; + spritesound(DUKE_DRINKING,p->i); + } + } + return; + case PLUG__STATIC: + spritesound(SHORT_CIRCUIT,p->i); + sprite[p->i].extra -= 2+(TRAND&3); + p->pals[0] = 48; + p->pals[1] = 48; + p->pals[2] = 64; + p->pals_time = 32; + break; + case VIEWSCREEN__STATIC: + case VIEWSCREEN2__STATIC: + { + i = headspritestat[1]; + + while(i >= 0) + { + if( PN == CAMERA1 && SP == 0 && sprite[neartagsprite].hitag == SLT ) + { + SP = 1; //Using this camera + spritesound(MONITOR_ACTIVE,neartagsprite); + + sprite[neartagsprite].owner = i; + sprite[neartagsprite].yvel = 1; + + + j = p->cursectnum; + p->cursectnum = SECT; + setpal(p); + p->cursectnum = j; + + // parallaxtype = 2; + p->newowner = i; + return; + } + i = nextspritestat[i]; + } + } + +CLEARCAMERAS: + + if(i < 0) + { + p->posx = p->oposx; + p->posy = p->oposy; + p->posz = p->oposz; + p->ang = p->oang; + p->newowner = -1; + + updatesector(p->posx,p->posy,&p->cursectnum); + setpal(p); + + + i = headspritestat[1]; + while(i >= 0) + { + if(PN==CAMERA1) SP = 0; + i = nextspritestat[i]; + } + } + else if(p->newowner >= 0) + p->newowner = -1; + + if( KB_KeyPressed(sc_Escape) ) + KB_ClearKeyDown(sc_Escape); + + return; + } + } + + if( (sync[snum].bits&(1<<29)) == 0 ) return; + else if(p->newowner >= 0) { i = -1; goto CLEARCAMERAS; } + + if(neartagwall == -1 && neartagsector == -1 && neartagsprite == -1) + if( klabs(hits(p->i)) < 512 ) + { + if( (TRAND&255) < 16 ) + spritesound(DUKE_SEARCH2,p->i); + else spritesound(DUKE_SEARCH,p->i); + return; + } + + if( neartagwall >= 0 ) + { + if( wall[neartagwall].lotag > 0 && isadoorwall(wall[neartagwall].picnum) ) + { + if(hitscanwall == neartagwall || hitscanwall == -1) + checkhitswitch(snum,neartagwall,0); + return; + } + else if(p->newowner >= 0) + { + i = -1; + goto CLEARCAMERAS; + } + } + + if( neartagsector >= 0 && (sector[neartagsector].lotag&16384) == 0 && isanearoperator(sector[neartagsector].lotag) ) + { + i = headspritesect[neartagsector]; + while(i >= 0) + { + if( PN == ACTIVATOR || PN == MASTERSWITCH ) + return; + i = nextspritesect[i]; + } + operatesectors(neartagsector,p->i); + } + else if( (sector[sprite[p->i].sectnum].lotag&16384) == 0 ) + { + if( isanunderoperator(sector[sprite[p->i].sectnum].lotag) ) + { + i = headspritesect[sprite[p->i].sectnum]; + while(i >= 0) + { + if(PN == ACTIVATOR || PN == MASTERSWITCH) return; + i = nextspritesect[i]; + } + operatesectors(sprite[p->i].sectnum,p->i); + } + else checkhitswitch(snum,neartagwall,0); + } + } +} + diff --git a/polymer/eduke32/source/soundefs.h b/polymer/eduke32/source/soundefs.h new file mode 100644 index 000000000..806e7050e --- /dev/null +++ b/polymer/eduke32/source/soundefs.h @@ -0,0 +1,417 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +#define KICK_HIT 0 +#define PISTOL_RICOCHET 1 +#define PISTOL_BODYHIT 2 +#define PISTOL_FIRE 3 +#define EJECT_CLIP 4 +#define INSERT_CLIP 5 +#define CHAINGUN_FIRE 6 +#define RPG_SHOOT 7 +#define POOLBALLHIT 8 +#define RPG_EXPLODE 9 +#define CAT_FIRE 10 +#define SHRINKER_FIRE 11 +#define ACTOR_SHRINKING 12 +#define PIPEBOMB_BOUNCE 13 +#define PIPEBOMB_EXPLODE 14 +#define LASERTRIP_ONWALL 15 +#define LASERTRIP_ARMING 16 +#define LASERTRIP_EXPLODE 17 +#define VENT_BUST 18 +#define GLASS_BREAKING 19 +#define GLASS_HEAVYBREAK 20 +#define SHORT_CIRCUIT 21 +#define ITEM_SPLASH 22 +#define DUKE_BREATHING 23 +#define DUKE_EXHALING 24 +#define DUKE_GASP 25 +#define SLIM_RECOG 26 +// #define ENDSEQVOL3SND1 27 +#define DUKE_URINATE 28 +#define ENDSEQVOL3SND2 29 +#define ENDSEQVOL3SND3 30 +#define DUKE_PASSWIND 32 +#define DUKE_CRACK 33 +#define SLIM_ATTACK 34 +#define SOMETHINGHITFORCE 35 +#define DUKE_DRINKING 36 +#define DUKE_KILLED1 37 +#define DUKE_GRUNT 38 +#define DUKE_HARTBEAT 39 +#define DUKE_ONWATER 40 +#define DUKE_DEAD 41 +#define DUKE_LAND 42 +#define DUKE_WALKINDUCTS 43 +#define DUKE_GLAD 44 +#define DUKE_YES 45 +#define DUKE_HEHE 46 +#define DUKE_SHUCKS 47 +#define DUKE_UNDERWATER 48 +#define DUKE_JETPACK_ON 49 +#define DUKE_JETPACK_IDLE 50 +#define DUKE_JETPACK_OFF 51 +#define LIZTROOP_GROWL 52 +#define LIZTROOP_TALK1 53 +#define LIZTROOP_TALK2 54 +#define LIZTROOP_TALK3 55 +#define DUKETALKTOBOSS 56 +#define LIZCAPT_GROWL 57 +#define LIZCAPT_TALK1 58 +#define LIZCAPT_TALK2 59 +#define LIZCAPT_TALK3 60 +#define LIZARD_BEG 61 +#define LIZARD_PAIN 62 +#define LIZARD_DEATH 63 +#define LIZARD_SPIT 64 +#define DRONE1_HISSRATTLE 65 +#define DRONE1_HISSSCREECH 66 +#define DUKE_TIP2 67 +#define FLESH_BURNING 68 +#define SQUISHED 69 +#define TELEPORTER 70 +#define ELEVATOR_ON 71 +#define DUKE_KILLED3 72 +#define ELEVATOR_OFF 73 +#define DOOR_OPERATE1 74 +#define SUBWAY 75 +#define SWITCH_ON 76 +#define FAN 77 +#define DUKE_GETWEAPON3 78 +#define FLUSH_TOILET 79 +#define HOVER_CRAFT 80 +#define EARTHQUAKE 81 +#define INTRUDER_ALERT 82 +#define END_OF_LEVEL_WARN 83 +#define ENGINE_OPERATING 84 +#define REACTOR_ON 85 +#define COMPUTER_AMBIENCE 86 +#define GEARS_GRINDING 87 +#define BUBBLE_AMBIENCE 88 +#define MACHINE_AMBIENCE 89 +#define SEWER_AMBIENCE 90 +#define WIND_AMBIENCE 91 +#define SOMETHING_DRIPPING 92 +#define STEAM_HISSING 93 +#define THEATER_BREATH 94 +#define BAR_MUSIC 95 +#define BOS1_ROAM 96 +#define BOS1_RECOG 97 +#define BOS1_ATTACK1 98 +#define BOS1_PAIN 99 +#define BOS1_DYING 100 +#define BOS2_ROAM 101 +#define BOS2_RECOG 102 +#define BOS2_ATTACK 103 +#define BOS2_PAIN 104 +#define BOS2_DYING 105 +#define GETATOMICHEALTH 106 +#define DUKE_GETWEAPON2 107 +#define BOS3_DYING 108 +#define SHOTGUN_FIRE 109 +#define PRED_ROAM 110 +#define PRED_RECOG 111 +#define PRED_ATTACK 112 +#define PRED_PAIN 113 +#define PRED_DYING 114 +#define CAPT_ROAM 115 +#define CAPT_ATTACK 116 +#define CAPT_RECOG 117 +#define CAPT_PAIN 118 +#define CAPT_DYING 119 +#define PIG_ROAM 120 +#define PIG_RECOG 121 +#define PIG_ATTACK 122 +#define PIG_PAIN 123 +#define PIG_DYING 124 +#define RECO_ROAM 125 +#define RECO_RECOG 126 +#define RECO_ATTACK 127 +#define RECO_PAIN 128 +#define RECO_DYING 129 +#define DRON_ROAM 130 +#define DRON_RECOG 131 +#define DRON_ATTACK1 132 +#define DRON_PAIN 133 +#define DRON_DYING 134 +#define COMM_ROAM 135 +#define COMM_RECOG 136 +#define COMM_ATTACK 137 +#define COMM_PAIN 138 +#define COMM_DYING 139 +#define OCTA_ROAM 140 +#define OCTA_RECOG 141 +#define OCTA_ATTACK1 142 +#define OCTA_PAIN 143 +#define OCTA_DYING 144 +#define TURR_ROAM 145 +#define TURR_RECOG 146 +#define TURR_ATTACK 147 +#define DUMPSTER_MOVE 148 +#define SLIM_DYING 149 +#define BOS3_ROAM 150 +#define BOS3_RECOG 151 +#define BOS3_ATTACK1 152 +#define BOS3_PAIN 153 +#define BOS1_ATTACK2 154 +#define COMM_SPIN 155 +#define BOS1_WALK 156 +#define DRON_ATTACK2 157 +#define THUD 158 +#define OCTA_ATTACK2 159 +#define WIERDSHOT_FLY 160 +#define TURR_PAIN 161 +#define TURR_DYING 162 +#define SLIM_ROAM 163 +#define LADY_SCREAM 164 +#define DOOR_OPERATE2 165 +#define DOOR_OPERATE3 166 +#define DOOR_OPERATE4 167 +#define BORNTOBEWILDSND 168 +#define SHOTGUN_COCK 169 +#define GENERIC_AMBIENCE1 170 +#define GENERIC_AMBIENCE2 171 +#define GENERIC_AMBIENCE3 172 +#define GENERIC_AMBIENCE4 173 +#define GENERIC_AMBIENCE5 174 +#define GENERIC_AMBIENCE6 175 +#define BOS3_ATTACK2 176 +#define GENERIC_AMBIENCE17 177 +#define GENERIC_AMBIENCE18 178 +#define GENERIC_AMBIENCE19 179 +#define GENERIC_AMBIENCE20 180 +#define GENERIC_AMBIENCE21 181 +#define GENERIC_AMBIENCE22 182 +#define SECRETLEVELSND 183 +#define GENERIC_AMBIENCE8 184 +#define GENERIC_AMBIENCE9 185 +#define GENERIC_AMBIENCE10 186 +#define GENERIC_AMBIENCE11 187 +#define GENERIC_AMBIENCE12 188 +#define GENERIC_AMBIENCE13 189 +#define GENERIC_AMBIENCE14 190 +#define GENERIC_AMBIENCE15 192 +#define GENERIC_AMBIENCE16 193 +#define FIRE_CRACKLE 194 +#define BONUS_SPEECH1 195 +#define BONUS_SPEECH2 196 +#define BONUS_SPEECH3 197 +#define PIG_CAPTURE_DUKE 198 +#define BONUS_SPEECH4 199 +#define DUKE_LAND_HURT 200 +#define DUKE_HIT_STRIPPER1 201 +#define DUKE_TIP1 202 +#define DUKE_KILLED2 203 +#define PRED_ROAM2 204 +#define PIG_ROAM2 205 +#define DUKE_GETWEAPON1 206 +#define DUKE_SEARCH2 207 +#define DUKE_CRACK2 208 +#define DUKE_SEARCH 209 +#define DUKE_GET 210 +#define DUKE_LONGTERM_PAIN 211 +#define MONITOR_ACTIVE 212 +#define NITEVISION_ONOFF 213 +#define DUKE_HIT_STRIPPER2 214 +#define DUKE_CRACK_FIRST 215 +#define DUKE_USEMEDKIT 216 +#define DUKE_TAKEPILLS 217 +#define DUKE_PISSRELIEF 218 +#define SELECT_WEAPON 219 +#define WATER_GURGLE 220 +#define DUKE_GETWEAPON4 221 +#define JIBBED_ACTOR1 222 +#define JIBBED_ACTOR2 223 +#define JIBBED_ACTOR3 224 +#define JIBBED_ACTOR4 225 +#define JIBBED_ACTOR5 226 +#define JIBBED_ACTOR6 227 +#define JIBBED_ACTOR7 228 +#define DUKE_GOTHEALTHATLOW 229 +#define BOSSTALKTODUKE 230 +#define WAR_AMBIENCE1 231 +#define WAR_AMBIENCE2 232 +#define WAR_AMBIENCE3 233 +#define WAR_AMBIENCE4 234 +#define WAR_AMBIENCE5 235 +#define WAR_AMBIENCE6 236 +#define WAR_AMBIENCE7 237 +#define WAR_AMBIENCE8 238 +#define WAR_AMBIENCE9 239 +#define WAR_AMBIENCE10 240 +#define ALIEN_TALK1 241 +#define ALIEN_TALK2 242 +#define EXITMENUSOUND 243 +#define FLY_BY 244 +#define DUKE_SCREAM 245 +#define SHRINKER_HIT 246 +#define RATTY 247 +#define INTO_MENU 248 +#define BONUSMUSIC 249 +#define DUKE_BOOBY 250 +#define DUKE_TALKTOBOSSFALL 251 +#define DUKE_LOOKINTOMIRROR 252 +#define PIG_ROAM3 253 +#define KILLME 254 +#define DRON_JETSND 255 +#define SPACE_DOOR1 256 +#define SPACE_DOOR2 257 +#define SPACE_DOOR3 258 +#define SPACE_DOOR4 259 +#define SPACE_DOOR5 260 +#define ALIEN_ELEVATOR1 261 +#define VAULT_DOOR 262 +#define JIBBED_ACTOR13 263 +#define DUKE_GETWEAPON6 264 +#define JIBBED_ACTOR8 265 +#define JIBBED_ACTOR9 266 +#define JIBBED_ACTOR10 267 +#define JIBBED_ACTOR11 268 +#define JIBBED_ACTOR12 269 +#define DUKE_KILLED4 270 +#define DUKE_KILLED5 271 +#define ALIEN_SWITCH1 272 +#define DUKE_STEPONFECES 273 +#define DUKE_LONGTERM_PAIN2 274 +#define DUKE_LONGTERM_PAIN3 275 +#define DUKE_LONGTERM_PAIN4 276 +#define COMPANB2 277 +#define KTIT 278 +#define HELICOP_IDLE 279 +#define STEPNIT 280 +#define SPACE_AMBIENCE1 281 +#define SPACE_AMBIENCE2 282 +#define SLIM_HATCH 283 +#define RIPHEADNECK 284 +#define FOUNDJONES 285 +#define ALIEN_DOOR1 286 +#define ALIEN_DOOR2 287 +#define ENDSEQVOL3SND4 288 +#define ENDSEQVOL3SND5 289 +#define ENDSEQVOL3SND6 290 +#define ENDSEQVOL3SND7 291 +#define ENDSEQVOL3SND8 292 +#define ENDSEQVOL3SND9 293 +#define WHIPYOURASS 294 +#define ENDSEQVOL2SND1 295 +#define ENDSEQVOL2SND2 296 +#define ENDSEQVOL2SND3 297 +#define ENDSEQVOL2SND4 298 +#define ENDSEQVOL2SND5 299 +#define ENDSEQVOL2SND6 300 +#define ENDSEQVOL2SND7 301 +#define GENERIC_AMBIENCE23 302 +#define SOMETHINGFROZE 303 +#define DUKE_LONGTERM_PAIN5 304 +#define DUKE_LONGTERM_PAIN6 305 +#define DUKE_LONGTERM_PAIN7 306 +#define DUKE_LONGTERM_PAIN8 307 +#define WIND_REPEAT 308 +#define MYENEMY_ROAM 309 +#define MYENEMY_HURT 310 +#define MYENEMY_DEAD 311 +#define MYENEMY_SHOOT 312 +#define STORE_MUSIC 313 +#define STORE_MUSIC_BROKE 314 +#define ACTOR_GROWING 315 +#define NEWBEAST_ROAM 316 +#define NEWBEAST_RECOG 317 +#define NEWBEAST_ATTACK 318 +#define NEWBEAST_PAIN 319 +#define NEWBEAST_DYING 320 +#define NEWBEAST_SPIT 321 +#define VOL4_1 322 +#define SUPERMARKET 323 +#define MOUSEANNOY 324 +#define BOOKEM 325 +#define SUPERMARKETCRY 326 +#define DESTRUCT 327 +#define EATFOOD 328 +#define MAKEMYDAY 329 +#define WITNESSSTAND 330 +#define VACATIONSPEECH 331 +#define YIPPEE1 332 +#define YOHOO1 333 +#define YOHOO2 334 +#define DOLPHINSND 335 +#define TOUGHGALSND1 336 +#define TOUGHGALSND2 337 +#define TOUGHGALSND3 338 +#define TOUGHGALSND4 339 +#define TANK_ROAM 340 +#define BOS4_ROAM 341 +#define BOS4_RECOG 342 +#define BOS4_ATTACK 343 +#define BOS4_PAIN 344 +#define BOS4_DYING 345 +#define NEWBEAST_ATTACKMISS 346 +#define VOL4_2 347 +#define COOKINGDEEPFRIER 348 +#define WHINING_DOG 349 +#define DEAD_DOG 350 +#define LIGHTNING_SLAP 351 +#define THUNDER 352 +#define HAPPYMOUSESND1 353 +#define HAPPYMOUSESND2 354 +#define HAPPYMOUSESND3 355 +#define HAPPYMOUSESND4 356 +#define ALARM 357 +#define RAIN 358 +#define DTAG_GREENRUN 359 +#define DTAG_BROWNRUN 360 +#define DTAG_GREENSCORE 361 +#define DTAG_BROWNSCORE 362 +#define INTRO4_1 363 +#define INTRO4_2 364 +#define INTRO4_3 365 +#define INTRO4_4 366 +#define INTRO4_5 367 +#define INTRO4_6 368 +#define SCREECH 369 +#define BOSS4_DEADSPEECH 370 +#define BOSS4_FIRSTSEE 371 +#define PARTY_SPEECH 372 +#define POSTAL_SPEECH 373 +#define TGSPEECH 374 +#define DOGROOMSPEECH 375 +#define SMACKED 376 +#define MDEVSPEECH 377 +#define AREA51SPEECH 378 +#define JEEPSOUND 379 +#define BIGDOORSLAM 380 +#define BOS4_LAY 381 +#define WAVESOUND 382 +#define ILLBEBACK 383 +#define VOL4ENDSND1 384 +#define VOL4ENDSND2 385 +#define EXPANDERHIT 386 +#define SNAKESPEECH 387 +#define EXPANDERSHOOT 388 +#define GETBACKTOWORK 389 +#define JIBBED_ACTOR14 390 +#define JIBBED_ACTOR15 391 +#define INTRO4_B 392 +#define BIGBANG 393 +#define SMACKIT 394 +#define BELLSND 395 +// MAXIMUM NUMBER OF SOUNDS: 450 ( 0-449 ) diff --git a/polymer/eduke32/source/sounds.c b/polymer/eduke32/source/sounds.c new file mode 100644 index 000000000..693ba9701 --- /dev/null +++ b/polymer/eduke32/source/sounds.c @@ -0,0 +1,632 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2005 - EDuke32 team + +This file is part of EDuke32 + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//------------------------------------------------------------------------- + +//#include +#include +#include +#include "types.h" +#include "fx_man.h" +#include "music.h" +#include "duke3d.h" +#include "util_lib.h" + + +#define LOUDESTVOLUME 150 + +long backflag,numenvsnds; + +/* +=================== += += SoundStartup += +=================== +*/ + +void SoundStartup( void ) +{ + int32 status; + + // if they chose None lets return + if (FXDevice < 0) return; + + status = FX_Init( FXDevice, NumVoices, NumChannels, NumBits, MixRate ); + if ( status == FX_Ok ) { + FX_SetVolume( FXVolume ); + if (ReverseStereo == 1) { + FX_SetReverseStereo(!FX_GetReverseStereo()); + } + status = FX_SetCallBack( testcallback ); + } + + if ( status != FX_Ok ) { + sprintf(tempbuf, "Sound startup error: %s", FX_ErrorString( FX_Error )); + gameexit(tempbuf); + } +} + +/* +=================== += += SoundShutdown += +=================== +*/ + +void SoundShutdown( void ) +{ + int32 status; + + // if they chose None lets return + if (FXDevice < 0) + return; + + status = FX_Shutdown(); + if ( status != FX_Ok ) { + sprintf(tempbuf, "Sound shutdown error: %s", FX_ErrorString( FX_Error )); + gameexit(tempbuf); + } +} + +/* +=================== += += MusicStartup += +=================== +*/ + +void MusicStartup( void ) +{ + int32 status; + + // if they chose None lets return + if (MusicDevice < 0) + return; + + status = MUSIC_Init( MusicDevice, 0 ); + + if ( status == MUSIC_Ok ) + { + MUSIC_SetVolume( MusicVolume ); + } + else + { + initprintf("Couldn't find selected sound card, or, error w/ sound card itself.\n"); + + SoundShutdown(); + uninittimer(); + uninitengine(); + CONTROL_Shutdown(); + CONFIG_WriteSetup(); + KB_Shutdown(); + uninitgroupfile(); + //unlink("duke3d.tmp"); + exit(-1); + } +} + +/* +=================== += += MusicShutdown += +=================== +*/ + +void MusicShutdown( void ) +{ + int32 status; + + // if they chose None lets return + if (MusicDevice < 0) + return; + + status = MUSIC_Shutdown(); + if ( status != MUSIC_Ok ) + { + Error( MUSIC_ErrorString( MUSIC_ErrorCode )); + } +} + +void MusicUpdate(void) +{ + MUSIC_Update(); +} + +int USRHOOKS_GetMem(char **ptr, unsigned long size ) +{ + *ptr = malloc(size); + + if (*ptr == NULL) + return(USRHOOKS_Error); + + return( USRHOOKS_Ok); + +} + +int USRHOOKS_FreeMem(char *ptr) +{ + free(ptr); + return( USRHOOKS_Ok); +} + +char menunum=0; + +void intomenusounds(void) +{ + short i; + short menusnds[] = + { + LASERTRIP_EXPLODE, + DUKE_GRUNT, + DUKE_LAND_HURT, + CHAINGUN_FIRE, + SQUISHED, + KICK_HIT, + PISTOL_RICOCHET, + PISTOL_BODYHIT, + PISTOL_FIRE, + SHOTGUN_FIRE, + BOS1_WALK, + RPG_EXPLODE, + PIPEBOMB_BOUNCE, + PIPEBOMB_EXPLODE, + NITEVISION_ONOFF, + RPG_SHOOT, + SELECT_WEAPON + }; + sound(menusnds[menunum++]); + menunum %= 17; +} + +void playmusic(char *fn) +{ + short fp; + long l; + + if(MusicToggle == 0) return; + if(MusicDevice < 0) return; + + fp = kopen4load(fn,0); + + if(fp == -1) return; + + l = kfilelength( fp ); + if(l >= (signed long)sizeof(MusicPtr)) + { + kclose(fp); + return; + } + + kread( fp, MusicPtr, l); + kclose( fp ); + MUSIC_PlaySong( MusicPtr, MUSIC_LoopSong ); +} + +char loadsound(unsigned short num) +{ + long fp, l; + + if(num >= NUM_SOUNDS || SoundToggle == 0) return 0; + if (FXDevice < 0) return 0; + + fp = kopen4load(sounds[num],loadfromgrouponly); + if(fp == -1) + { + sprintf(&fta_quotes[113][0],"Sound %s(#%d) not found.",sounds[num],num); + FTA(113,&ps[myconnectindex]); + return 0; + } + + l = kfilelength( fp ); + soundsiz[num] = l; + + Sound[num].lock = 200; + + allocache((long *)&Sound[num].ptr,l,(char *)&Sound[num].lock); + kread( fp, Sound[num].ptr , l); + kclose( fp ); + return 1; +} + +int xyzsound(short num,short i,long x,long y,long z) +{ + long sndist, cx, cy, cz, j,k; + short pitche,pitchs,cs; + int voice, sndang, ca, pitch; + + // if(num != 358) return 0; + + if( num >= NUM_SOUNDS || + FXDevice < 0 || + ( (soundm[num]&8) && ud.lockout ) || + SoundToggle == 0 || + Sound[num].num > 3 || + FX_VoiceAvailable(soundpr[num]) == 0 || + (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3) || + ps[myconnectindex].gm&MODE_MENU) return -1; + + if( soundm[num]&128 ) + { + sound(num); + return 0; + } + + if( soundm[num]&4 ) + { + if(VoiceToggle==0 || (ud.multimode > 1 && PN == APLAYER && sprite[i].yvel != screenpeek && !(gametype_flags[ud.coop]&GAMETYPE_FLAG_COOPSOUND)) ) return -1; + + for(j=0;j 0) && (soundm[j]&4) ) + return -1; + } + + cx = ps[screenpeek].oposx; + cy = ps[screenpeek].oposy; + cz = ps[screenpeek].oposz; + cs = ps[screenpeek].cursectnum; + ca = ps[screenpeek].ang+ps[screenpeek].look_ang; + + sndist = FindDistance3D((cx-x),(cy-y),(cz-z)>>4); + + if( i >= 0 && (soundm[num]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 ) + sndist = divscale14(sndist,(SHT+1)); + + pitchs = soundps[num]; + pitche = soundpe[num]; + cx = klabs(pitche-pitchs); + + if(cx) + { + if( pitchs < pitche ) + pitch = pitchs + ( rand()%cx ); + else pitch = pitche + ( rand()%cx ); + } + else pitch = pitchs; + + sndist += soundvo[num]; + if(sndist < 0) sndist = 0; + if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX,SY,SZ-(24<<8),SECT) ) + sndist += sndist>>5; + + switch(num) + { + case PIPEBOMB_EXPLODE: + case LASERTRIP_EXPLODE: + case RPG_EXPLODE: + if(sndist > (6144) ) + sndist = 6144; + if(sector[ps[screenpeek].cursectnum].lotag == 2) + pitch -= 1024; + break; + default: + if(sector[ps[screenpeek].cursectnum].lotag == 2 && (soundm[num]&4) == 0) + pitch = -768; + if( sndist > 31444 && PN != MUSICANDSFX) + return -1; + break; + } + + if (ps[screenpeek].sound_pitch) pitch = ps[screenpeek].sound_pitch; + + if( Sound[num].num > 0 && PN != MUSICANDSFX ) + { + if( SoundOwner[num][0].i == i ) stopsound(num); + else if( Sound[num].num > 1 ) stopsound(num); + else if( badguy(&sprite[i]) && sprite[i].extra <= 0 ) stopsound(num); + } + + if( PN == APLAYER && sprite[i].yvel == screenpeek ) + { + sndang = 0; + sndist = 0; + } + else + { + sndang = 2048 + ca - getangle(cx-x,cy-y); + sndang &= 2047; + } + + if(Sound[num].ptr == 0) { if( loadsound(num) == 0 ) return 0; } + else + { + if (Sound[num].lock < 200) + Sound[num].lock = 200; + else Sound[num].lock++; + } + + if( soundm[num]&16 ) sndist = 0; + + if(sndist < ((255-LOUDESTVOLUME)<<6) ) + sndist = ((255-LOUDESTVOLUME)<<6); + + if( soundm[num]&1 ) + { + unsigned short start; + + if(Sound[num].num > 0) return -1; + + start = *(unsigned short *)(Sound[num].ptr + 0x14); + + if(*Sound[num].ptr == 'C') + voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num], + pitch,sndist>>6,sndist>>6,0,soundpr[num],num); + else + voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num], + pitch,sndist>>6,sndist>>6,0,soundpr[num],num); + } + else + { + if( *Sound[num].ptr == 'C') + voice = FX_PlayVOC3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num ); + else + voice = FX_PlayWAV3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num ); + } + + if ( voice > FX_Ok ) + { + SoundOwner[num][Sound[num].num].i = i; + SoundOwner[num][Sound[num].num].voice = voice; + Sound[num].num++; + } + else Sound[num].lock--; + return (voice); +} + +void sound(short num) +{ + short pitch,pitche,pitchs,cx; + int voice; + long start; + + if (FXDevice < 0) return; + if(SoundToggle==0) return; + if(VoiceToggle==0 && (soundm[num]&4) ) return; + if( (soundm[num]&8) && ud.lockout ) return; + if(FX_VoiceAvailable(soundpr[num]) == 0) return; + + pitchs = soundps[num]; + pitche = soundpe[num]; + cx = klabs(pitche-pitchs); + + if(cx) + { + if( pitchs < pitche ) + pitch = pitchs + ( rand()%cx ); + else pitch = pitche + ( rand()%cx ); + } + else pitch = pitchs; + +if(Sound[num].ptr == 0) { if( loadsound(num) == 0 ) return; } + else + { + if (Sound[num].lock < 200) + Sound[num].lock = 200; + else Sound[num].lock++; + } + + if( soundm[num]&1 ) + { + if(*Sound[num].ptr == 'C') + { + start = (long)*(unsigned short *)(Sound[num].ptr + 0x14); + voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num], + pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num); + } + else + { + start = (long)*(unsigned short *)(Sound[num].ptr + 0x14); + voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num], + pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num); + } + } + else + { + if(*Sound[num].ptr == 'C') + voice = FX_PlayVOC3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num ); + else + voice = FX_PlayWAV3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num ); + } + + if(voice > FX_Ok) return; + Sound[num].lock--; +} + +int spritesound(unsigned short num, short i) +{ + if(num >= NUM_SOUNDS) return -1; + return xyzsound(num,i,SX,SY,SZ); +} + +void stopspritesound(short num, short i) +{ + stopsound(num); +} + +void stopsound(short num) +{ + if(Sound[num].num > 0) + { + FX_StopSound(SoundOwner[num][Sound[num].num-1].voice); + testcallback(num); + } +} + +void stopenvsound(short num,short i) +{ + short j, k; + + if(Sound[num].num > 0) + { + k = Sound[num].num; + for(j=0;j>4); + if( i >= 0 && (soundm[j]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 ) + sndist = divscale14(sndist,(SHT+1)); + } + + sndist += soundvo[j]; + if(sndist < 0) sndist = 0; + + if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,sx,sy,sz-(24<<8),SECT) ) + sndist += sndist>>5; + + if(PN == MUSICANDSFX && SLT < 999) + numenvsnds++; + + switch(j) + { + case PIPEBOMB_EXPLODE: + case LASERTRIP_EXPLODE: + case RPG_EXPLODE: + if(sndist > (6144)) sndist = (6144); + break; + default: + if( sndist > 31444 && PN != MUSICANDSFX) + { + stopsound(j); + continue; + } + } + + if(Sound[j].ptr == 0 && loadsound(j) == 0 ) continue; + if( soundm[j]&16 ) sndist = 0; + + if(sndist < ((255-LOUDESTVOLUME)<<6) ) + sndist = ((255-LOUDESTVOLUME)<<6); + + FX_Pan3D(SoundOwner[j][k].voice,sndang>>6,sndist>>6); + } +} + +void testcallback(unsigned long num) +{ + short tempi,tempj,tempk; + + if((long)num < 0) + { + if(lumplockbyte[-num] >= 200) + lumplockbyte[-num]--; + return; + } + + tempk = Sound[num].num; + + if(tempk > 0) + { + if( (soundm[num]&16) == 0) + for(tempj=0;tempj= 200) + Sound[i].lock = 199; + + for(i=0;i<11;i++) + if(lumplockbyte[i] >= 200) + lumplockbyte[i] = 199; +} + +int isspritemakingsound(short i, int num) +{ + if (num < 0) num=0; // FIXME + return issoundplaying(num) > 0; +} + +int issoundplaying(int num) +{ + return Sound[num].num; +} diff --git a/polymer/eduke32/source/sounds.h b/polymer/eduke32/source/sounds.h new file mode 100644 index 000000000..d7a26ee42 --- /dev/null +++ b/polymer/eduke32/source/sounds.h @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com) +*/ +//------------------------------------------------------------------------- + +//**************************************************************************** +// +// sounds.h +// +//**************************************************************************** + +#ifndef _sounds_public_ +#define _sounds_public_ + +extern int32 FXDevice; +extern int32 MusicDevice; +extern int32 FXVolume; +extern int32 MusicVolume; +//extern fx_blaster_config BlasterConfig; +extern int32 NumVoices; +extern int32 NumChannels; +extern int32 NumBits; +extern int32 MixRate; +//extern int32 MidiPort; +extern int32 ReverseStereo; + +void SoundStartup( void ); +void SoundShutdown( void ); +void MusicStartup( void ); +void MusicShutdown( void ); +void AudioUpdate(void); + +#endif diff --git a/polymer/eduke32/source/testcd.c b/polymer/eduke32/source/testcd.c new file mode 100644 index 000000000..e4988e402 --- /dev/null +++ b/polymer/eduke32/source/testcd.c @@ -0,0 +1,75 @@ +//------------------------------------------------------------------------- +/* +Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Replacement cd-auth routine by Jonathon Fowler. +*/ +//------------------------------------------------------------------------- + +#if (defined(RENDERTYPEWIN) || defined(WIN32)) && !defined(NOCOPYPROTECT) +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "compat.h" +#include "baselayer.h" + +/* + * Why even bother doing this? Because I can. Because it proves the futility + * of it all. Because it's amusing. Who cares? + */ + +char testcd( char *fn, long testsiz ) +{ + DWORD driveletters; + int i, fil, dalen; + char name[32]="x:\\SUPPORT\\",driv[4]="x:\\"; + + strcat(name,fn); + + driveletters = GetLogicalDrives(); + for (i=2; i<26; i++) { + if (!(driveletters & (1ul< +#include +#include +#include + +#include "winlayer.h" + + +int Win_YesNoBox(char *name, char *fmt, ...) +{ + char buf[1000]; + va_list va; + int r; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + + r = MessageBox((HWND)win_gethwnd(),buf,name,MB_YESNO|MB_TASKMODAL); + if (r==IDYES) return 'y'; + return 'n'; +} + +int Win_MsgBox(char *name, char *fmt, ...) +{ + char buf[1000]; + va_list va; + + va_start(va,fmt); + vsprintf(buf,fmt,va); + va_end(va); + + MessageBox((HWND)win_gethwnd(),buf,name,MB_OK|MB_TASKMODAL); + return 'y'; +} + + +// this replaces the Error() function in jmact/util_lib.c +extern void Shutdown(void ); // game.c +void Error(char *error, ...) +{ + char buf[1000]; + va_list va; + + Shutdown(); + + if (error) { + va_start(va, error); + vsprintf(buf, error, va); + va_end(va); + + MessageBox((HWND)win_gethwnd(),buf,"Fatal Error",MB_OK|MB_TASKMODAL); + } + + exit((error != NULL)); +} + + +#endif
  • 3qO=Ae)^>&MygY2>k*|f3L zpLdc2RIL(zD2X^U>Fl|caga7Mb(()jOGz{r%i^){dqNw9RD4xwuHF8*N~uu_^Wab>%1?fl$nKb_ylZTwngWD5 zKbsh~6Hk&I>~TOep$KFR6(?VB9s;qt(urZyS$>f;FnvnoPgo0XlUNhd3HKiF+z#C5z^q9q*M}Akn z%7mEmwZm-qbV^6$2sHy@CL;j`ZL$yS#6@>-^~+HW;^knMvwqgp40NAUi{aTcyLLt% zDSh2pcV!STRpP8WJ-RKE)GY-1rw``FD^77@Q@M%>fa2UE#XF+OG~-Z@BI6~Qd?|l0 z$pABgFZmjt!OHt?`b>KN=d2qw9kwud`EtB4%)y0ORko2gx$_0(Xn4-2v;?1aAL$m` z6`g6f-)7NKBuKY?ncO(0MY@WlJ~2TMN~gPFnTyz`F{XzQ=S}w`-B;Q1PTyZou(T~T z4&5WH(E2&MatKge8cT=-*(NJAgibLS2AGHRcb{^IQd;uDfwBPvxFYUS`GY_ zDv|MV*3lmwT1Tf7(wERaTymJRRx^>ZlP%WMDy!!+ccQSWp?&=5n3YZ5lrDY;SC8j! zq%u7r$4vD&bhb!#(zC*6?|~XObl+@1F}^$law>9hmm%+Jl|ygZcKLX26yKQx3AbTI z5f6lpVoaD!y(6|4<(-&1bymi6nkWuSj7+*iK&5T02b{1 zM+_a9btUy!NJ}m=Vl^i$I5Y5d+H3JXKQ2b zpO2!1XXUl{GpRO;M;~(2IB!Zm_`vaJ+VTe&UOxzAs6 zKN12LKW_Qe^f9{w;b*Z~{v-9e77rKF*5#ijG%T=nz{{%fuZWMRrCUbyN!ydo@@>RE z0r;TLTb3A3{934J3HL?5j@mC+LPM`lDCGn6x_1P7<_`790Az%M>Ji)C z<+*|z>JizadHE7qaO8Y{slV#DJ#yo*JtFpv&r*NL&S0){`vs!=arjp+BYm(xM(}Up z2>v}F62QO5>yNAPPnqUlJCfWaU9vAZ)g;u79oZWzJVXDr@bBNJf8Gb^pKa)`ecsXZ zN2ezGd!a{>){+Xt^#7Hizab>swjugw6MgiEC?e+AF|hnuXgky?%N{x|{g)Aoz>`eV zeDo4TWg=IQQKKIey4mOh%^|Er)q6idbyI*WR^ZPB(&B>P0i|hrlkyvt>03;JS|{tG ze&Yowwb6H5DOOcuxvFZ0)kjp-wyYGpRLyExV}571w3^>J@bAki0g1qyb#p}@DWfPg z*-mw?j`^IXPg9lKRob0={Uwy4g@lf`9i6V+;Cq0wl9`E-Oe&$6TJWX_rak&j_jkdA z*ilq)e@Sq50iL>F?$7a5(x3e6-PAov3tx9%>P7M~z@)>TJv`ntl^?gKwb4>Mme41s>8Wa$K2aTdiA`K`YKaBHlTg!pnOa{@FLP z(tZt=qtE(gdPeS{+Z{NtnfePtjL%)=ug8I!XGb9Z8z_} zj5WUT5E?E;o{A##J&RS#8hev_@>4Ql_BI{{^9?GFo1x)%JlTf+V|BJl|5xS3 zVXWDuWr>(p=Biizawjy^II*j)2x~RJh0%f0*PrIwc6`*{`%kBE{XdC?M?2U5OWWRl z(8mNj4pp;_*~&T?@@HQs{w%}55EPSeQNM# z5Lso?DW(}P%M8n`2cyc$;;u?IpzQ;WpPamxZ0>dg#ru28URjNgc&s_w2OYl;o#sci zl4Yq)Q&cxcA0h3px?Px1N^VBM1RWmP9842W=az1P>#Cak|TnvQ+mN2@S|zFfM8x3Qws%Aa22*MYb#_kHW3+uk&aR?B6Ub;pRa&MyHd^}0A(5> zfwX3)D=jH{k#-URHd%6n5D%TqLwYIs6@`G037TElp%oy{+zH?YoQEy+DLm4xbJ%OIIB#e)qu?xqW-=}bv6K? zEuV^`BeGlT1%O;ne)HIrmFbikrNEm*nN-kc6)9bo6#axhX|t#Gb7lpH`pOhNnlv+E zS*3;5R6!v}1c-$n02lH1dmv>Y&=kbNricaMY&J;o>Pm7Quo~50zrYXboK%c3ExsL5rs>6sve9a#t>k~Ga}r^!A^8pvI9B1*+3@!i zPOFxKjOJaCLE&@n}`P^S!AF3MaCTIBz z6cUexll;)F*Y?eX`n07v;r1AL*#0-H$j5|!8UKFJZl?t47tMW~LBr`Vks6Sk+Q~Sx z3{W#v$KvmU^0lqms%TZZqHLe7e4a{v{yLPH>mLih22_76{02XIu;SWy;pd&E?}&zl zRy`EYJ1@DDYErX^gpay_BrP=tL14E@mVkB@$9kPs>14@}f+dy67d)J%-ZB{+m_7hR zO-OgevYRFSmKoAX4E=N&Qpx99ICefm1wnK#E+;)BYn|ACA(X7Voq@c~S!0yXeYqwI zE99x$Lo2{|usqT5S~`wiS}-PO#R$pVw|+<{eo8g^s~(m+Hw`U!zI^=U4ys){*O#~V zeZtE3yUgq{&&_L2%lGDtsqE3T3v1Yq;-Z<4%iQN#+&p+`-zuAFXi_*P(=wCEiv848 zEZLxrA%0FcwM>HD>I+4z?|K+@)G6*RE1A(sU8%TlD9+!^GmNJZHzeC9DbU5}OPwqz ztMX9KzJuOsh$>DRN@5^`097=C86z&$2_U6EpdhI)-^M5-f1efpCK^PZAv(=`p#BW0 zN8cY<^4e<}!jFXy@Pp3fkV31%`}Ol=_+|YZf_6zhl82r*D}zshuF`=vnJgG5umW1L zMdj&MB+FN3n&hS5N6v3Y-8NXio%Ot#RpK(iNh{kvy%2y3bQ==1_C8N?+YgzB0Ge`f zb?s*&h5Grd6RQkrTdGaLa}n}%rLKd;{DnyCwIYP(p-+nvM!y%ibbBV}mx0z3{`g7W zEy`}KwlLXodIc;6uF}^0z~~qirTXelVDA+pkR3S@k|teO^Du9cH$m^al#e%U5jXmp zSwP%M6Ia96&&}5izE+qo+0dAi(Yq;w7ns=RKAfHfu_&6Mp1aW`%_8ZFAu>=vs|rwi z9)~`9zu|iYTreOe+pC%lphJK1Y8^P%5{eNf-KTcGjKANU(6?u-|1 z)rW{*BJ>QrW_UR$Lr|JkflzqkU&z~}r8lWf%Sol9nk4<0dZkdYHTyL!R837rLl&yk z9>lKQI&M`JLQz!|sgQ2jB~sCNSXc)lh2C$Jjn&`n^4gU;4Ip3s;=u>g_~~;HZxe$% z-05?Xxn)>zOuyE0v?l{$AAvusyJUB!UYtJEi{ohpAVcugqHuDP1)gYu=cLPccfrxX zraO{%TVUN9q2#$~;NKntJj0Yc-vY~^7~pHuz%2mlL7MzEOo>)$Ypfr=>GKD%J`B=- z+=D61q=DmgA!b4O-6D#!d@LjxqBN;R3{pBNJ~5ZZT1Ne=n#f9TgV+h8W>aZ$f-1an zwtyg*tgf$|r9eFIOES-zh2h`V=9oJT)!y_O+)R2Y6y#3^g-!5 zG3_s8a&G{`>P(s?)9vZpq?}&EVm`Qua0P-hxvz=tp3YEonl514i(;&v$v$CxeKDxB z^xxy#+1eI))tR%gw{;msOUNj|MXz{<#W15<=(94Z-%_z9h*-2WZqnVHn#G6Tr3O4r z=7Var;aQ)}i`6jkdZmi+i;n!qNIoC+JuXWZ%QlLd-icvedke++rE`jvmKDoYcGV0q zw)z%9;B(&A?~*Wc24qD_H0=|P^hW%#@Is9!_7Hce?l-+)v^^AGG5G%b?;q|wbJLO+ zxwg|7NgdwQ*vMV(QM_Ew%jy8Sb?g!!pQkIu9i)vCHXz7uU%{&k=v;v=6-0%$ zwhz&0GshTdkh~KTNjY#}lx_OZ7})t85-zROQSc}=zK02ydD}d{q6JythOR@wm&D!b#K0FL81#``SCSAAPLKRxq8McI+6*i>X zmr1h7KVHt}_ zS!;hDfqOJFt z#DV?0@bI$AoTTEiWj8KgR+$4e`Z~6viY~5MLSCMUrH#Yb5S;6kC3G=@Y^v-FkyC~R`RpWh| z_RmryI=XN`)4QwpEzr-JZDJA!a5wbU$cne98rwLNVO99|wA0Hd-r?W(2bEUAWX+)j z5LBRdYhrhokkr&o?%npsggQtN+FL}oRpCyRHZ7FMnoIWLq+jTM;nvY*kDz@@thI%- z*&h?44@_BYwyZ9Gy0ae0C=2%XC9BLFVgoGQ&h| zp6k~$+$z6R(P75_g5`Edo|o2+A;U8tsnWm#O42bw3MR zdUi9Vu*J4HhWK8i9DoSPF=H%3pv(l!_}>Kz6%@?YpX}Uz8!mGpP-?qqyw;X7pRQbp z8!a?5{N;etqAMg!tE@<&u(^gIm8&PK*)X}O(hRg+UF}AKC>3^m!}w~Wu$2_%+;Tm- z+r~)v^Q>yZH|WpgMyi|0#|4e^4sQ#D2t`c(xvHG|eEh30T(M9Qj79siLd7**OL6R| zvZ-q@zZPE?K0Y`r!{MuS6SuTK%en*RU}rG@ka1L@Gqh@K9R~B);(!QH!db|y!TbY5 zVL8{Z>CXB|MQ_dwdie*C!T>V|zekPE#^1WTy!ue^$j}>X<udO~l?R?pK1-`XA*u8@H{=h+NjcCBtc2NZVUC|8@KY5SI&FF|LW?l1Z*SUL0zE z-!y0A)DxX`dywFP72s|3yZ)rr+n&0K6;P|ccu{s!RNa$9WfVbDyZV4O=9N5HN>iX& z@x-6hy8#-prblTYt6uXNGeh~kxBml)u=8mMY9yUcT*iSJEjt-Hb7-7D>Z@&0mG)_$;7+N_@aW3FcASZV)IYbPY19I^`XRC63wWLg}W4Y zfc1{XWqNFuDN@6E27ry}Kn(#SOeA8e)5ElKcA|0?BU)3^ZmQu@QFmo+*VqQSS_8VP zat<^Ma9Mz9jjP%kkX;XjSEy8GDgAJt7U84uJKK!kImA>Fnnhu=Oe%L%`JTf%OtS>W z(v0{ylya9X#r)VjwY{5q+eukzQ}lxyH#;2Sws%-}t|A%^MIp6JUyp?w?9T!No(s6; z?crhI&9D5jWpuM7VAk$^6Z~JMKfRi2G0tRvAixR%m1eIKpvBTC>awQt)MV0P#=$lD z4=8_Co)=o7o#H91BG@eCY7d~@D>`mg@;vWdp*8yFIe76d&9j)fp*tWe>kXPW7m=U~ zJR$#}fE}AXm+-mFn_r0DW%>1BWfT?@RxqRvsb;$}2FJe;DxY%)tL$^Z!CzlLEftNY zn{ihcutDaAb8VipK0Ej<$BnO%MEGOQ`kD+Aku(uCAtDRnB_|!N|8v$?Wv87?Su=dP z6VR$r!?7Y|q7aw)2k`0VtpBLFlJuqE9!vGfciAdewRMGWEp1B&f7aF&A}C7II%oaN zjFCAEPQy7&a5%@yHb-bENBKca@8aM`f~kdwpS49dpFkb#<)|b{3hZR1=jD!T-dnTE zdB3AkSxguY-3>vj3Z2{UVE2!Jg{9~(D~%;e=q>yl(Q&?X>z_83>wTk5`3oU{IcZz6 z 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 Hq1PSRA0JrUPk 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ூ&j(Og-vuq?Yl&2ZDZwaQn#FJneO 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 M+1 +// { +// ... actions +// } +// endevent + +// Internal event IDs + +/* +enum events { + EVENT_INIT, + EVENT_ENTERLEVEL, + EVENT_RESETWEAPONS, + EVENT_RESETINVENTORY, + EVENT_HOLSTER, + EVENT_LOOKLEFT, + EVENT_LOOKRIGHT, + EVENT_SOARUP, + EVENT_SOARDOWN, + EVENT_CROUCH, + EVENT_JUMP, + EVENT_RETURNTOCENTER, + EVENT_LOOKUP, + EVENT_LOOKDOWN, + EVENT_AIMUP, + EVENT_FIRE, + EVENT_CHANGEWEAPON, + EVENT_GETSHOTRANGE, + EVENT_GETAUTOAIMANGLE, + EVENT_GETLOADTILE, + EVENT_CHEATGETSTEROIDS, + EVENT_CHEATGETHEAT, + EVENT_CHEATGETBOOT, + EVENT_CHEATGETSHIELD, + EVENT_CHEATGETSCUBA, + EVENT_CHEATGETHOLODUKE, + EVENT_CHEATGETJETPACK, + EVENT_CHEATGETFIRSTAID, + EVENT_QUICKKICK, + EVENT_INVENTORY, + EVENT_USENIGHTVISION, + EVENT_USESTEROIDS, + EVENT_INVENTORYLEFT, + EVENT_INVENTORYRIGHT, + EVENT_HOLODUKEON, + EVENT_HOLODUKEOFF, + EVENT_USEMEDKIT, + EVENT_USEJETPACK, + EVENT_TURNAROUND, + EVENT_DISPLAYWEAPON, + EVENT_FIREWEAPON, + EVENT_SELECTWEAPON, + EVENT_MOVEFORWARD, + EVENT_MOVEBACKWARD, + EVENT_TURNLEFT, + EVENT_TURNRIGHT, + EVENT_STRAFELEFT, + EVENT_STRAFERIGHT, + EVENT_WEAPKEY1, + EVENT_WEAPKEY2, + EVENT_WEAPKEY3, + EVENT_WEAPKEY4, + EVENT_WEAPKEY5, + EVENT_WEAPKEY6, + EVENT_WEAPKEY7, + EVENT_WEAPKEY8, + EVENT_WEAPKEY9, + EVENT_WEAPKEY10, + EVENT_DRAWWEAPON, + EVENT_DISPLAYCROSSHAIR, + EVENT_DISPLAYREST, + EVENT_RESETPLAYER, + EVENT_INCURDAMAGE, + EVENT_AIMDOWN, + EVENT_GAME, + EVENT_PREVIOUSWEAPON, + EVENT_NEXTWEAPON, + EVENT_SWIMUP, + EVENT_SWIMDOWN, + EVENT_GETMENUTILE, + EVENT_SPAWN, + EVENT_LOGO, + EVENT_EGS +}; +*/ + +// Internal projectile stuff + +/* +enum projectilelabels { + PROJ_WORKSLIKE, + PROJ_SPAWNS, + PROJ_SXREPEAT, + PROJ_SYREPEAT, + PROJ_SOUND, + PROJ_ISOUND, + PROJ_VEL, + PROJ_EXTRA, + PROJ_DECAL, + PROJ_TRAIL, + PROJ_TXREPEAT, + PROJ_TYREPEAT, + PROJ_TOFFSET, + PROJ_TNUM, + PROJ_DROP, + PROJ_CSTAT, + PROJ_CLIPDIST, + PROJ_SHADE, + PROJ_XREPEAT, + PROJ_YREPEAT, + PROJ_PAL, + PROJ_EXTRA_RAND, + PROJ_HITRADIUS, + PROJ_VEL_MULT, + PROJ_OFFSET, + PROJ_BOUNCES, + PROJ_BSOUND, + PROJ_RANGE +}; +*/ + +// Variable definition Flags + +#define GAMEVAR_FLAG_GLOBAL 0 // global variable (default) +#define GAMEVAR_FLAG_PERPLAYER 1 // per-player variable +#define GAMEVAR_FLAG_PERACTOR 2 // per-actor variable + +// Weapon Flags +// 1 Holstering Clears Clip +// 2 Glows +// 4 Automatic +// 8 Fire Every other frame +// 16 Fire Every third frame +// 32 Random restart on automatic +// 64 Use Ammo per burst +// 128 Is a Bomb trigger +// 256 Using does NOT cause player to become 'visible' +// 512 Use 'throws' the 'shoots' item +// 1024 Check weapon availability at 'reload' time +// 2048 player should stop jumping +// 0 Spawn Type 1 (pistol shells) +// 4096 Spawn Type 2 (Shotgun shells) +// 8192 Spawn Type 3 (CHAINGUN shells) +// 16384 Semi-automatic + +// TRIPBOMB_CONTROL +// 1 Tripwire. Trip Bomb works with tripwire. +// 2 On timer. Trip Bomb works on timer + +// PIPEBOMB_CONTROL +// 1 Detonator. Pipe Bomb works with detonator. +// 2 On timer. Pipe Bomb works on timer + +gamevar WEAPON0_WORKSLIKE 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_FIREDELAY 7 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_TOTALTIME 14 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_FLAGS 288 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SHOOTS 2521 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON0_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON1_WORKSLIKE 1 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_CLIP 12 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_RELOAD 27 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_FIREDELAY 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_TOTALTIME 6 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_FLAGS 4 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SHOOTS 2595 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SPAWNTIME 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SPAWN 2533 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_FIRESOUND 3 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON1_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON2_WORKSLIKE 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_RELOAD 13 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_FIREDELAY 4 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_TOTALTIME 31 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_FLAGS 1024 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SHOOTS 2613 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SPAWNTIME 24 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SPAWN 2535 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SHOTSPERBURST 7 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_FIRESOUND 109 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SOUND2TIME 15 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_SOUND2SOUND 169 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON2_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON3_WORKSLIKE 3 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_FIREDELAY 4 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_TOTALTIME 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_FLAGS 8276 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SHOOTS 2536 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SPAWNTIME 1 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SPAWN 2533 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_FIRESOUND 6 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON3_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON4_WORKSLIKE 4 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_FIREDELAY 4 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_TOTALTIME 20 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_FLAGS 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SHOOTS 2605 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON4_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON5_WORKSLIKE 5 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_RELOAD 30 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_FIREDELAY 6 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_TOTALTIME 19 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_HOLDDELAY 12 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_FLAGS 512 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SHOOTS 26 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON5_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON6_WORKSLIKE 6 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_FIREDELAY 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_TOTALTIME 12 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_FLAGS 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SHOOTS 2556 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_INITIALSOUND 11 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON6_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON7_WORKSLIKE 7 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_FIREDELAY 3 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_TOTALTIME 5 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_HOLDDELAY 5 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_FLAGS 72 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SHOOTS 2605 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SHOTSPERBURST 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_INITIALSOUND 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON7_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON8_WORKSLIKE 8 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_RELOAD 16 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_FIREDELAY 3 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_TOTALTIME 40 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_HOLDDELAY 7 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_FLAGS 3072 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SHOOTS 2563 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON8_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON9_WORKSLIKE 9 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_FIREDELAY 3 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_TOTALTIME 8 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_FLAGS 20 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SHOOTS 1641 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_INITIALSOUND 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_FIRESOUND 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON9_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON10_WORKSLIKE 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_RELOAD 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_FIREDELAY 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_TOTALTIME 10 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_FLAGS 384 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SHOOTS 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_FIRESOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON10_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar WEAPON11_WORKSLIKE 11 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_CLIP 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_RELOAD 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_FIREDELAY 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_TOTALTIME 5 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_HOLDDELAY 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_FLAGS 2 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SHOOTS 2448 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SPAWNTIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SPAWN 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SHOTSPERBURST 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_INITIALSOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_FIRESOUND 388 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SOUND2TIME 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_SOUND2SOUND 0 GAMEVAR_FLAG_PERPLAYER +gamevar WEAPON11_RENDERSIZE 0 GAMEVAR_FLAG_PERPLAYER + +gamevar GRENADE_LIFETIME 120 GAMEVAR_FLAG_PERPLAYER +gamevar GRENADE_LIFETIME_VAR 30 GAMEVAR_FLAG_PERPLAYER +gamevar STICKYBOMB_LIFETIME 120 GAMEVAR_FLAG_PERPLAYER +gamevar STICKYBOMB_LIFETIME_VAR 30 GAMEVAR_FLAG_PERPLAYER +gamevar TRIPBOMB_CONTROL 1 GAMEVAR_FLAG_PERPLAYER // set value to 2 for timed bomb +gamevar PIPEBOMB_CONTROL 1 GAMEVAR_FLAG_PERPLAYER // set value to 2 for grenade behavior diff --git a/polymer/eduke32/eobj/libbuild.a b/polymer/eduke32/eobj/libbuild.a new file mode 100644 index 0000000000000000000000000000000000000000..3c9d48ce19961efc8180ac77ba5e35a4b67d7fce GIT binary patch literal 173342 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%0D{WwF9y*K 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