diff --git a/.github/workflows/windows_ci.yml b/.github/workflows/windows_ci.yml index ef35263d6..66af72a54 100644 --- a/.github/workflows/windows_ci.yml +++ b/.github/workflows/windows_ci.yml @@ -10,6 +10,20 @@ jobs: platform: [x64, Win32] steps: - uses: actions/checkout@v3 + - name: Set environment variables + run: | + $gitrev = $(git describe --always) + $gitbranch = $(git branch --show-current) + $ver_suffix = ("$gitbranch" -eq "master" -Or "$gitbranch" -eq "main") ? "-$gitrev" : "-$gitbranch-$gitrev" + $platform_alt = ("${{matrix.platform}}" -eq "x64") ? "win64" : "win32" + $platform_short = ("${{matrix.platform}}" -eq "Win32") ? "x86" : "${{matrix.platform}}" + $build_artifact = "ironwail${ver_suffix}-${platform_alt}" + echo "VER_SUFFIX=$ver_suffix" >> ${env:GITHUB_ENV} + echo "BUILD_ARTIFACT=$build_artifact" >> ${env:GITHUB_ENV} + echo "BUILD_DIR=$build_artifact" >> ${env:GITHUB_ENV} + echo "PLATFORM_ALT=$platform_alt" >> ${env:GITHUB_ENV} + echo "PLATFORM_SHORT=$platform_short" >> ${env:GITHUB_ENV} + echo "ForceImportBeforeCppTargets=${env:GITHUB_WORKSPACE}\Windows\VisualStudio\custom_build.props" >> ${env:GITHUB_ENV} - name: Build run: | $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" @@ -22,3 +36,20 @@ jobs: ) & $msbuild Windows\VisualStudio\ironwail.sln $options if (-not $?) { throw "Build failed" } + - name: Prepare archive + run: | + $compiledir = "Windows\VisualStudio\${env:BUILD_DIR}" + $zipdir = "artifact\${env:BUILD_ARTIFACT}" + mkdir $zipdir | out-null + copy ${compiledir}\*.exe $zipdir + copy ${compiledir}\*.dll $zipdir + copy Quake\ironwail.pak $zipdir + copy Quakespasm.html $zipdir + copy Quakespasm.txt $zipdir + copy Quakespasm-Music.txt $zipdir + copy LICENSE.txt $zipdir + - name: Upload archive + uses: actions/upload-artifact@v3 + with: + name: ${{ env.BUILD_ARTIFACT }} + path: artifact/* diff --git a/Linux/sgml/Quakespasm.sgml b/Linux/sgml/Quakespasm.sgml index 3e95450a4..1f930a59e 100644 --- a/Linux/sgml/Quakespasm.sgml +++ b/Linux/sgml/Quakespasm.sgml @@ -3,7 +3,7 @@ QuakeSpasm <toc> -<em>Page last edited: October 2022.</em> +<em>Page last edited: September 2023.</em> <sect>About<p> @@ -24,7 +24,6 @@ but no CD-ROM support. <item><url url="https://github.com/sezero/quakespasm" name="Github mirror."> </itemize> - <sect>Hints<p> <em>Visit the <url url="https://celephais.net/fitzquake/" name="FitzQuake homepage"> for a full run-down of the engine's commands and variables.</em> <itemize> @@ -64,13 +63,17 @@ If your controller doesn't work you can try placing <url url="https://raw.github <sect2>Cvars<p> <itemize> -<item>joy_deadzone - Fraction of the stick travel to be deadzone, between 0 and 1. Default 0.175. +<item>joy_deadzone_look - Fraction of look stick travel to be deadzone, between 0 and 1. Default is 0.175. +<item>joy_deadzone_move - Same as above, but for the move stick. Default is 0.175. <item>joy_deadzone_trigger - Fraction of trigger range required to register a button press on the analog triggers, between 0 and 1. Default 0.2. -<item>joy_sensitivity_yaw/pitch - Max angular speed in degrees/second when looking. Defaults are 300 for yaw (turning left/right) and 150 for pitch (up/down). -<item>joy_exponent - For the look stick, the stick displacement (between 0 and 1) is raised to this power. Default is 3. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed. +<item>joy_outer_threshold_look - Outer deadzone for the look stick, between 0 and 1. Default 0.02. +<item>joy_outer_threshold_move - Outer deadzone for the move stick, between 0 and 1. Default 0.02. +<item>joy_sensitivity_yaw/pitch - Max angular speed in degrees/second when looking. Defaults are 240 for yaw (turning left/right) and 130 for pitch (up/down). +<item>joy_exponent - For the look stick, the stick displacement (between 0 and 1) is raised to this power. Default is 2. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed. +<item>joy_exponent_move - Same as joy_exponent but for the move stick. Default is 2. <item>joy_invert - Set to 1 to invert the vertical axis of the look stick. -<item>joy_swapmovelook - Set to 1 to swap the left and right analog stick functions. Default 0, move on the left stick, look on the right stick. -<item>joy_enable - Set to 0 to disable controller support. Default 1. +<item>joy_swapmovelook - Set to 1 to swap the left and right analog stick functions. Default is 0, move on the left stick, look on the right stick. +<item>joy_enable - Set to 0 to disable controller support. Default is 1. </itemize> <sect2>Buttons<p> @@ -136,6 +139,49 @@ QuakeSpasm 0.94 has support for playing the 2021 re-release content: Copy the qu <sect>Changes<p> +<sect1>Changes in 0.96.1<p> +<itemize> +<item> Fix demo recording as client-only after connection to server (was broken by signon changes in 0.96.0. Thanks to Jozsef Szalontai for issue report.) +<item> Fix potential buffer overflow in COM_Parse(), e.g. with maps with oversized 'wad' fields. (Thanks to Andrei Drexler.) +<item> Minor code cleanups. +</itemize> +</p> + +<sect1>Changes in 0.96.0<p> +<itemize> +<item> <url url="https://github.com/sezero/quakespasm/pull/51" name="Adjustments"> to joystick defaults and behaviour. See the "Controller support / Cvars" section above. +<item> Fix for a mouse grabbing issue on macOS. +<item> Add missing support for <em>-ip</em> command line option on unix / macOS. +<item> Backport angled sprites code from FTEQW (spriteframetype: 2, must have 8 frames per group.) +<item> Bump the progs execution runaway loop limit to 16M. +<item> Add signon buffer fragmentation to fix SZ_GetSpace errors on certain maps when using protocol 999. +<item> Increased MAX_DATAGRAM to 64000 to overcome packet overflows. +<item> Bump the MAXALIASFRAMES limit to 1024. +<item> Fix arrays to have proper sizes in gl mesh code, reflecting MAXALIASTRIS and MAXALIASVERTS correctly. (fixes SIGSEGV in mj4m4/mj4m5.) +<item> Increased default value of gl_farclip to 65536. +<item> Increase chase cam target trace distance to allow for chasecam to function in large open maps (useful e.g. for the func_vehicle mod.) +<item> Raised default maximum number of particles to 16384 (can be set up to 32768 with -particles on the command line.) +<item> Fix on-screen keyboard showing up suddenly on Steam Deck when starting a map. +<item> Fix viewmodel interpolation with >10Hz animations. +<item> Fix a memory leak when exiting game in SDL2 builds. +<item> Fix a possible crash when handling clipboard data on macOS. +<item> Fix a potential crash after loading of saved game. +<item> Fix possible out-of-bound reads when handling progs type sizes. +<item> Fix Dutch angle VP_PARALLEL_UPRIGHT sprites. +<item> Fix an issue with lights blending by using 10 bit color depth for lightmaps. (For GLSL mode only.) Disable with "-nopackedpixels", if necessary. +<item> No relative motions when the window is not focused. +<item> Status bar and intermission screen tweaks. +<item> Properly display monster counts > 3 digits. +<item> Fix console animation with scr_conspeed <= 0. +<item> Fix mouselook not working upon game quickload during a demo play. +<item> Haiku operating system support. +<item> Fix console when server is run noninteractively with stdin redirected from /dev/null. +<item> Updated Visual Studio project files. +<item> Minor code cleanups. Updated third party code, e.g. SDL, music codecs, etc. +<item> Thanks to Andrei Drexler, Alexey Lysiuk, Andrey Budko, Boris I. Bendovsky, Chris Cowan, Maciej Olędzki, Simon McVittie, OscarL, Eric Wasylishen, Jaycie Ewald and Spike for patches. +</itemize> +</p> + <sect1>Changes in 0.95.1<p> <itemize> <item> Allow mixing lit and unlit textures in the same map. diff --git a/Misc/quake_retexturing_project.patch b/Misc/fix_externaltex.patch similarity index 84% rename from Misc/quake_retexturing_project.patch rename to Misc/fix_externaltex.patch index 907a5ca4b..4da5489f7 100644 --- a/Misc/quake_retexturing_project.patch +++ b/Misc/fix_externaltex.patch @@ -1,5 +1,7 @@ +-- from quake retexturing project + diff --git a/Quake/gl_model.c b/Quake/gl_model.c -index d193051..783dc4d 100644 +index 239d361..80948f1 100644 --- a/Quake/gl_model.c +++ b/Quake/gl_model.c @@ -39,6 +39,8 @@ static void Mod_Print (void); @@ -11,7 +13,7 @@ index d193051..783dc4d 100644 static byte *mod_novis; static int mod_novis_capacity; -@@ -542,6 +544,13 @@ static void Mod_LoadTextures (lump_t *l) +@@ -549,6 +551,13 @@ static void Mod_LoadTextures (lump_t *l) { if (!q_strncasecmp(tx->name,"sky",3)) //sky texture //also note -- was Q_strncmp, changed to match qbsp { @@ -25,7 +27,7 @@ index d193051..783dc4d 100644 if (loadmodel->bspversion == BSPVERSION_QUAKE64) Sky_LoadTextureQ64 (loadmodel, tx); else -@@ -596,6 +605,50 @@ static void Mod_LoadTextures (lump_t *l) +@@ -606,6 +615,50 @@ static void Mod_LoadTextures (lump_t *l) //external textures -- first look in "textures/mapname/" then look in "textures/" mark = Hunk_LowMark (); COM_StripExtension (loadmodel->name + 5, mapname, sizeof(mapname)); @@ -77,10 +79,10 @@ index d193051..783dc4d 100644 data = Image_LoadImage (filename, &fwidth, &fheight); if (!data) diff --git a/Quake/gl_rmain.c b/Quake/gl_rmain.c -index 332ab1e..783a9d6 100644 +index 6883161..4a8a745 100644 --- a/Quake/gl_rmain.c +++ b/Quake/gl_rmain.c -@@ -99,6 +99,8 @@ cvar_t r_noshadow_list = {"r_noshadow_list", "progs/flame2.mdl,progs/flame.mdl,p +@@ -100,6 +100,8 @@ cvar_t r_noshadow_list = {"r_noshadow_list", "progs/flame2.mdl,progs/flame.mdl,p extern cvar_t r_vfog; //johnfitz @@ -90,7 +92,7 @@ index 332ab1e..783a9d6 100644 cvar_t r_lavaalpha = {"r_lavaalpha","0",CVAR_NONE}; diff --git a/Quake/gl_rmisc.c b/Quake/gl_rmisc.c -index dc3dff0..dbfe922 100644 +index 93791f6..4006c5d 100644 --- a/Quake/gl_rmisc.c +++ b/Quake/gl_rmisc.c @@ -47,6 +47,7 @@ extern cvar_t r_nolerp_list; @@ -101,11 +103,11 @@ index dc3dff0..dbfe922 100644 extern gltexture_t *playertextures[MAX_SCOREBOARD]; //johnfitz -@@ -218,6 +219,7 @@ void R_Init (void) - Cvar_RegisterVariable (&r_noshadow_list); - Cvar_SetCallback (&r_noshadow_list, R_Model_ExtraFlags_List_f); - //johnfitz -+ Cvar_RegisterVariable (&r_externaltexture_fix); //mk +@@ -231,6 +232,7 @@ void R_Init (void) + Cvar_SetCallback (&r_lavaalpha, R_SetLavaalpha_f); + Cvar_SetCallback (&r_telealpha, R_SetTelealpha_f); + Cvar_SetCallback (&r_slimealpha, R_SetSlimealpha_f); ++ Cvar_RegisterVariable (&r_externaltexture_fix);//mk - Cvar_RegisterVariable (&gl_zfix); // QuakeSpasm z-fighting fix - Cvar_RegisterVariable (&r_lavaalpha); + R_InitParticles (); + R_SetClearColor_f (&r_clearcolor); //johnfitz diff --git a/Misc/fs_search_order.patch b/Misc/fs_search_order.patch index 0fba6a55d..781807937 100644 --- a/Misc/fs_search_order.patch +++ b/Misc/fs_search_order.patch @@ -1,10 +1,10 @@ -allow plain files to override files inside a PAK file -- Sander van Dijk. +allow plain files to override files inside a PAK -- Sander van Dijk. diff --git a/Quake/common.c b/Quake/common.c -index eff4c30..1478d77 100644 +index c80450f..6074711 100644 --- a/Quake/common.c +++ b/Quake/common.c -@@ -2030,13 +2030,6 @@ static void COM_AddGameDirectory (const char *base, const char *dir) +@@ -2107,13 +2107,6 @@ static void COM_AddGameDirectory (const char *base, const char *dir) else path_id = 1U; _add_path: @@ -18,7 +18,7 @@ index eff4c30..1478d77 100644 // add any pak files in the format pak0.pak pak1.pak, ... for (i = 0; ; i++) { -@@ -2068,6 +2061,13 @@ _add_path: +@@ -2145,6 +2138,13 @@ _add_path: if (!pak) break; } @@ -32,4 +32,3 @@ index eff4c30..1478d77 100644 if (!been_here && host_parms->userdir != host_parms->basedir) { been_here = true; - diff --git a/Misc/pak/default.cfg.diff b/Misc/pak/default.cfg.diff new file mode 100644 index 000000000..085513ff6 --- /dev/null +++ b/Misc/pak/default.cfg.diff @@ -0,0 +1,76 @@ +--- default.cfg~ ++++ default.cfg +@@ -12,24 +12,26 @@ + bind ALT +strafe + + bind , +moveleft ++bind a +moveleft + bind . +moveright ++bind d +moveright + bind DEL +lookdown + bind PGDN +lookup + bind END centerview +-bind z +lookdown +-bind a +lookup + +-bind d +moveup ++bind e +moveup + bind c +movedown + bind SHIFT +speed + bind CTRL +attack + bind UPARROW +forward ++bind w +forward + bind DOWNARROW +back ++bind s +back + bind LEFTARROW +left + bind RIGHTARROW +right + + bind SPACE +jump +-bind ENTER +jump ++//bind ENTER +jump + + bind TAB +showscores + +@@ -45,6 +47,8 @@ + bind 0 "impulse 0" + + bind / "impulse 10" // change weapon ++bind MWHEELDOWN "impulse 10" ++bind MWHEELUP "impulse 12" + + // zoom + alias zoom_in "sensitivity 2;fov 90;wait;fov 70;wait;fov 50;wait;fov 30;wait;fov 10;wait;fov 5;bind F11 zoom_out" +@@ -85,14 +89,30 @@ + // mouse buttons + // + bind MOUSE1 +attack +-bind MOUSE2 +forward +-bind MOUSE3 +mlook ++//bind MOUSE2 +forward ++bind MOUSE2 +jump ++//bind MOUSE3 +mlook ++ ++// ++// game controller ++// ++bind LSHOULDER "impulse 12" ++bind RSHOULDER "impulse 10" ++bind LTRIGGER +jump ++bind RTRIGGER +attack + + // + // default cvars + // +-viewsize 100 + gamma 1.0 + volume 0.7 + sensitivity 3 + ++//viewsize 100 ++viewsize 110 ++scr_conscale 1.6 ++scr_menuscale 1.6 ++scr_sbarscale 1.6 ++ ++// default to mouse-look enabled +++mlook diff --git a/Misc/pak/default.cfg.orig b/Misc/pak/default.cfg.orig deleted file mode 100644 index c4510501f..000000000 --- a/Misc/pak/default.cfg.orig +++ /dev/null @@ -1,98 +0,0 @@ -// -// load keybindings -// -// commands with a leading + will also be called for key up events with -// the + changed to a - -unbindall - -// -// character controls -// - -bind ALT +strafe - -bind , +moveleft -bind . +moveright -bind DEL +lookdown -bind PGDN +lookup -bind END centerview -bind z +lookdown -bind a +lookup - -bind d +moveup -bind c +movedown -bind SHIFT +speed -bind CTRL +attack -bind UPARROW +forward -bind DOWNARROW +back -bind LEFTARROW +left -bind RIGHTARROW +right - -bind SPACE +jump -bind ENTER +jump - -bind TAB +showscores - -bind 1 "impulse 1" -bind 2 "impulse 2" -bind 3 "impulse 3" -bind 4 "impulse 4" -bind 5 "impulse 5" -bind 6 "impulse 6" -bind 7 "impulse 7" -bind 8 "impulse 8" - -bind 0 "impulse 0" - -bind / "impulse 10" // change weapon - -// zoom -alias zoom_in "sensitivity 2;fov 90;wait;fov 70;wait;fov 50;wait;fov 30;wait;fov 10;wait;fov 5;bind F11 zoom_out" -alias zoom_out "sensitivity 4;fov 5;wait;fov 10;wait;fov 30;wait;fov 50;wait;fov 70;wait;fov 90;bind F11 zoom_in; sensitivity 3" -bind F11 zoom_in - -// Function keys -bind F1 "help" -bind F2 "menu_save" -bind F3 "menu_load" -bind F4 "menu_options" -bind F5 "menu_multiplayer" -bind F6 "echo Quicksaving...; wait; save quick" -bind F9 "echo Quickloading...; wait; load quick" -bind F10 "quit" -bind F12 "screenshot" - -// mouse options -bind \ +mlook - -// -// client environment commands -// -bind PAUSE "pause" -bind ESCAPE "togglemenu" -bind ~ "toggleconsole" -bind ` "toggleconsole" - -bind t "messagemode" - -bind + "sizeup" -bind = "sizeup" -bind - "sizedown" - -bind INS +klook - -// -// mouse buttons -// -bind MOUSE1 +attack -bind MOUSE2 +forward -bind MOUSE3 +mlook - -// -// default cvars -// -viewsize 100 -gamma 1.0 -volume 0.7 -sensitivity 3 - diff --git a/Misc/pak/maps/e1m1.diff b/Misc/pak/maps/e1m1.diff new file mode 100644 index 000000000..f834b9cca --- /dev/null +++ b/Misc/pak/maps/e1m1.diff @@ -0,0 +1,18 @@ +--- e1m1.ent ++++ e1m1@c49d.ent +@@ -715,14 +715,15 @@ + { + "classname" "func_door" + "targetname" "t4" + "angle" "-2" + "spawnflags" "1" + "sounds" "2" + "model" "*15" ++"lip" "7" // svdijk -- added to prevent z-fighting + } + { + "classname" "trigger_multiple" + "target" "t4" + "health" "1" + "model" "*16" + } diff --git a/Misc/pak/maps/e1m1.ent.orig b/Misc/pak/maps/e1m1.ent.orig deleted file mode 100644 index 7796105e7..000000000 --- a/Misc/pak/maps/e1m1.ent.orig +++ /dev/null @@ -1,1969 +0,0 @@ -{ -"worldtype" "2" -"sounds" "6" -"classname" "worldspawn" -"wad" "gfx/base.wad" -"message" "the Slipgate Complex" -} -{ -"classname" "info_player_start" -"origin" "480 -352 88" -"angle" "90" -} -{ -"classname" "light" -"origin" "480 96 168" -"light" "250" -} -{ -"classname" "light" -"origin" "480 288 168" -"light" "250" -} -{ -"classname" "light" -"origin" "272 96 80" -} -{ -"origin" "272 288 80" -"classname" "light" -} -{ -"classname" "light" -"origin" "272 192 80" -} -{ -"origin" "688 192 80" -"classname" "light_fluorospark" -"style" "10" -} -{ -"style" "10" -"classname" "light" -"origin" "688 288 80" -} -{ -"origin" "688 96 80" -"classname" "light" -"style" "10" -} -{ -"classname" "light" -"origin" "480 -280 168" -"light" "200" -} -{ -"origin" "480 -144 168" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "480 -376 120" -"light" "200" -} -{ -"light" "160" -"origin" "480 -40 168" -"classname" "light" -} -{ -"speed" "400" -"sounds" "2" -"angle" "270" -"classname" "func_door" -"model" "*1" -} -{ -"speed" "400" -"angle" "90" -"classname" "func_door" -"model" "*2" -} -{ -"light" "250" -"origin" "592 544 88" -"classname" "light_fluoro" -} -{ -"origin" "456 600 104" -"classname" "light" -} -{ -"light" "180" -"origin" "688 648 136" -"classname" "light" -} -{ -"classname" "light" -"origin" "688 520 136" -"light" "180" -} -{ -"origin" "688 480 80" -"classname" "item_armor1" -} -{ -"angle" "180" -"spawnflags" "768" -"origin" "616 72 40" -"classname" "monster_army" -} -{ -"light" "250" -"origin" "0 576 120" -"classname" "light" -} -{ -"light" "180" -"origin" "160 576 72" -"classname" "light" -} -{ -"light" "200" -"origin" "560 -32 72" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "400 -32 72" -} -{ -"light" "200" -"origin" "0 712 72" -"classname" "light" -} -{ -"classname" "light" -"origin" "0 728 -136" -"light" "200" -} -{ -"light" "200" -"origin" "0 592 -136" -"classname" "light" -} -{ -"wait" "5" -"angle" "-2" -"sounds" "2" -"targetname" "t1" -"classname" "func_door" -"dmg" "10" -"model" "*3" -} -{ -"sounds" "1" -"target" "t1" -"angle" "180" -"classname" "func_button" -"model" "*4" -} -{ -"light" "200" -"origin" "412 780 136" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "328 904 72" -} -{ -"light" "200" -"origin" "168 800 72" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "-72 864 72" -} -{ -"origin" "264 888 -136" -"classname" "light" -} -{ -"classname" "light" -"origin" "-8 992 -136" -"light" "200" -} -{ -"light" "250" -"classname" "light" -"origin" "272 1064 -136" -} -{ -"light" "250" -"origin" "-8 1232 -136" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "256 1272 -136" -} -{ -"light" "250" -"origin" "312 1464 -136" -"classname" "light" -} -{ -"light" "200" -"origin" "128 968 72" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "-48 1168 72" -} -{ -"light" "250" -"origin" "312 1168 72" -"classname" "light" -} -{ -"light" "220" -"classname" "light" -"origin" "128 1504 -120" -} -{ -"light" "250" -"classname" "light" -"origin" "-56 1464 -136" -} -{ -"sounds" "2" -"classname" "func_door" -"angle" "180" -"speed" "400" -"model" "*5" -} -{ -"classname" "func_door" -"angle" "0" -"speed" "400" -"model" "*6" -} -{ -"classname" "light_fluoro" -"origin" "176 1744 -152" -} -{ -"origin" "80 1744 -152" -"classname" "light_fluoro" -} -{ -"light" "250" -"origin" "-232 1600 -136" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "488 1600 -136" -} -{ -"origin" "-56 1448 72" -"classname" "light" -"light" "250" -} -{ -"light" "250" -"classname" "light" -"origin" "312 1448 72" -} -{ -"light" "260" -"classname" "light_fluoro" -"origin" "416 2064 -112" -} -{ -"light" "260" -"origin" "416 1968 -112" -"classname" "light_fluoro" -} -{ -"light" "250" -"origin" "128 1880 -112" -"classname" "light" -} -{ -"origin" "616 1944 -88" -"classname" "light" -} -{ -"style" "10" -"classname" "light_fluorospark" -"origin" "344 2216 -88" -} -{ -"light" "180" -"origin" "352 2016 -112" -"classname" "light" -} -{ -"classname" "light" -"origin" "128 2056 -112" -"light" "250" -} -{ -"light" "250" -"origin" "-112 1984 -112" -"classname" "light" -} -{ -"light" "350" -"origin" "-472 2064 -88" -"classname" "light_fluoro" -} -{ -"classname" "light" -"origin" "-192 2208 8" -"light" "250" -} -{ -"light" "250" -"origin" "-424 2208 8" -"classname" "light" -} -{ -"light" "250" -"origin" "-248 2088 -96" -"classname" "light" -} -{ -"origin" "-200 2384 -72" -"classname" "light" -} -{ -"classname" "light" -"origin" "-424 2384 -72" -} -{ -"light" "200" -"origin" "-448 2408 -128" -"classname" "light" -} -{ -"classname" "light" -"origin" "-176 2408 -128" -"light" "200" -} -{ -"sounds" "1" -"classname" "func_plat" -"model" "*7" -} -{ -"light" "350" -"origin" "-352 2656 184" -"classname" "light" -} -{ -"light" "350" -"classname" "light" -"origin" "-352 2464 184" -} -{ -"origin" "-576 2800 -40" -"classname" "light" -} -{ -"light" "500" -"origin" "160 2920 232" -"classname" "light" -} -{ -"classname" "light" -"origin" "160 2720 232" -"light" "500" -} -{ -"origin" "-288 2992 8" -"classname" "light" -} -{ -"classname" "light" -"origin" "-168 2776 -40" -} -{ -"classname" "light" -"origin" "160 2824 104" -"light" "200" -} -{ -"light" "150" -"origin" "-64 2760 136" -"classname" "light" -} -{ -"light" "200" -"origin" "16 2832 -152" -"classname" "light" -} -{ -"classname" "light" -"origin" "304 2832 -152" -"light" "200" -} -{ -"origin" "504 2816 16" -"classname" "light" -} -{ -"sounds" "3" -"wait" "-1" -"speed" "600" -"targetname" "t2" -"spawnflags" "1" -"angle" "270" -"classname" "func_door" -"model" "*8" -} -{ -"classname" "light" -"origin" "160 2840 -152" -"light" "200" -} -{ -"light" "80" -"origin" "16 2904 -88" -"classname" "light" -} -{ -"classname" "light" -"origin" "304 2904 -88" -"light" "80" -} -{ -"classname" "light" -"origin" "160 2904 -88" -"light" "80" -} -{ -"wait" "-1" -"sounds" "1" -"target" "t2" -"speed" "50" -"angle" "270" -"classname" "func_button" -"model" "*9" -} -{ -"light" "100" -"origin" "0 1800 -32" -"classname" "light" -} -{ -"classname" "light" -"origin" "248 1800 -32" -"light" "100" -} -{ -"style" "32" -"targetname" "t3" -"origin" "8 2352 200" -"classname" "light" -} -{ -"style" "32" -"targetname" "t3" -"classname" "light" -"origin" "32 2392 200" -} -{ -"style" "32" -"targetname" "t3" -"origin" "56 2352 200" -"classname" "light" -} -{ -"style" "32" -"targetname" "t3" -"classname" "light" -"origin" "32 2312 200" -} -{ -"style" "32" -"targetname" "t3" -"light" "200" -"origin" "32 2352 88" -"classname" "light" -} -{ -"spawnflags" "2048" -"origin" "112 2352 16" -"classname" "weapon_nailgun" -} -{ -"sounds" "3" -"targetname" "t3" -"spawnflags" "3" -"angle" "270" -"classname" "func_door_secret" -"model" "*10" -} -{ -"style" "32" -"sounds" "3" -"target" "t3" -"classname" "trigger_once" -"model" "*11" -} -{ -"origin" "304 2368 96" -"classname" "light" -} -{ -"angle" "180" -"origin" "248 2392 40" -"classname" "monster_army" -} -{ -"origin" "272 2352 64" -"classname" "item_spikes" -} -{ -"style" "32" -"sounds" "3" -"target" "t3" -"classname" "trigger_once" -"model" "*12" -} -{ -"origin" "832 2608 16" -"classname" "light" -"light" "220" -} -{ -"light" "220" -"classname" "light" -"origin" "832 2480 0" -} -{ -"light" "240" -"origin" "800 2816 24" -"classname" "light" -} -{ -"style" "33" -"targetname" "t11" -"spawnflags" "1" -"classname" "light" -"origin" "752 2000 -88" -"light" "400" -} -{ -"style" "34" -"spawnflags" "1" -"targetname" "t12" -"origin" "1280 2000 -152" -"classname" "light" -"light" "400" -} -{ -"style" "35" -"spawnflags" "1" -"targetname" "t13" -"classname" "light" -"origin" "1280 2496 -216" -"light" "400" -} -{ -"style" "36" -"spawnflags" "1" -"targetname" "t14" -"origin" "784 2496 -280" -"classname" "light" -} -{ -"classname" "light" -"origin" "1368 2584 -488" -"light" "200" -} -{ -"origin" "1368 1944 -488" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "696 2584 -488" -"light" "150" -} -{ -"origin" "1016 2584 -488" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "1016 1944 -488" -"light" "200" -} -{ -"origin" "1368 2272 -488" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "696 2272 -488" -"light" "200" -} -{ -"classname" "light" -"origin" "960 2296 -488" -"light" "200" -} -{ -"light" "200" -"origin" "1032 2352 -488" -"classname" "light" -} -{ -"classname" "light" -"origin" "888 2352 -488" -"light" "200" -} -{ -"light" "200" -"origin" "960 2408 -488" -"classname" "light" -} -{ -"light" "100" -"classname" "light" -"origin" "984 2448 -304" -} -{ -"classname" "light" -"origin" "832 2360 112" -"light" "400" -} -{ -"classname" "light" -"origin" "1144 2448 -488" -} -{ -"origin" "1232 2360 -488" -"classname" "light" -} -{ -"classname" "light" -"origin" "1320 2448 -488" -"light" "200" -} -{ -"light" "200" -"origin" "1232 2536 -488" -"classname" "light" -} -{ -"classname" "light" -"origin" "1232 2136 -488" -} -{ -"origin" "1144 2048 -488" -"classname" "light" -} -{ -"classname" "light" -"origin" "1232 1960 -488" -"light" "200" -} -{ -"light" "200" -"origin" "1320 2048 -488" -"classname" "light" -} -{ -"classname" "light" -"origin" "832 2336 -200" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "2" -"sounds" "3" -"model" "*13" -} -{ -"classname" "func_door_secret" -"angle" "180" -"sounds" "3" -"model" "*14" -} -{ -"classname" "light" -"origin" "552 2480 -56" -"light" "200" -} -{ -"light" "200" -"origin" "544 2296 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "664 2480 -56" -"light" "200" -} -{ -"classname" "func_door" -"targetname" "t4" -"angle" "-2" -"spawnflags" "1" -"sounds" "2" -"model" "*15" -} -{ -"classname" "trigger_multiple" -"target" "t4" -"health" "1" -"model" "*16" -} -{ -"spawnflags" "2048" -"classname" "func_door" -"angle" "90" -"targetname" "t5" -"wait" "-1" -"sounds" "2" -"model" "*17" -} -{ -"spawnflags" "2048" -"classname" "trigger_once" -"target" "t5" -"model" "*18" -} -{ -"classname" "item_artifact_super_damage" -"origin" "544 2480 -88" -} -{ -"classname" "light" -"origin" "832 2104 -208" -} -{ -"classname" "light" -"origin" "832 2048 -368" -"light" "150" -} -{ -"classname" "light" -"origin" "1120 2464 112" -} -{ -"origin" "1120 2080 112" -"classname" "light" -} -{ -"classname" "light" -"origin" "752 2080 112" -"light" "200" -} -{ -"classname" "light" -"origin" "1048 2280 -72" -} -{ -"classname" "func_button" -"angle" "270" -"target" "t1" -"model" "*19" -} -{ -"classname" "light" -"origin" "1136 1848 -504" -"light" "220" -} -{ -"origin" "1136 1672 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1008 1672 -504" -"light" "220" -} -{ -"origin" "1008 1848 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1288 1848 -504" -"light" "220" -} -{ -"origin" "1400 1584 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1224 1584 -504" -"light" "220" -} -{ -"origin" "1400 1736 -504" -"classname" "light" -"light" "220" -} -{ -"origin" "880 1672 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "744 1672 -504" -"light" "220" -} -{ -"classname" "light" -"origin" "1312 1648 -392" -"light" "220" -} -{ -"light" "170" -"origin" "1312 1520 -392" -"classname" "light" -} -{ -"classname" "light" -"origin" "1200 1760 -392" -"light" "220" -} -{ -"light" "170" -"origin" "1072 1760 -392" -"classname" "light" -} -{ -"classname" "light" -"origin" "944 1760 -392" -"light" "170" -} -{ -"origin" "832 1992 -208" -"classname" "light" -"light" "220" -} -{ -"origin" "744 1832 -504" -"classname" "light" -} -{ -"light" "170" -"origin" "832 1760 -392" -"classname" "light" -} -{ -"light" "220" -"origin" "680 1936 -504" -"classname" "light" -} -{ -"classname" "light" -"origin" "1312 1392 -352" -"light" "170" -} -{ -"light" "170" -"origin" "1312 1264 -288" -"classname" "light" -} -{ -"classname" "light" -"origin" "1312 1136 -232" -} -{ -"origin" "1224 1456 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1400 1456 -504" -"light" "220" -} -{ -"origin" "1400 1328 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1224 1328 -504" -"light" "220" -} -{ -"origin" "1224 1200 -504" -"classname" "light" -"light" "220" -} -{ -"classname" "light" -"origin" "1400 1200 -504" -"light" "220" -} -{ -"origin" "1312 960 -208" -"classname" "light" -} -{ -"classname" "trigger_teleport" -"target" "t6" -"model" "*20" -} -{ -"classname" "light" -"origin" "1312 912 -472" -} -{ -"classname" "light" -"origin" "1312 1080 -368" -} -{ -"classname" "light" -"origin" "1128 1064 -504" -"light" "170" -} -{ -"origin" "1128 856 -504" -"classname" "light" -"light" "170" -} -{ -"classname" "light" -"origin" "1496 856 -504" -"light" "170" -} -{ -"origin" "1496 1064 -504" -"classname" "light" -"light" "170" -} -{ -"classname" "light" -"origin" "1312 776 -504" -"light" "170" -} -{ -"spawnflags" "2" -"angle" "90" -"classname" "func_door_secret" -"model" "*21" -} -{ -"origin" "1072 1024 -168" -"classname" "light" -} -{ -"spawnflags" "1" -"height" "400" -"angle" "-1" -"sounds" "1" -"classname" "func_plat" -"model" "*22" -} -{ -"targetname" "t8" -"spawnflags" "2" -"angle" "90" -"classname" "func_door_secret" -"model" "*23" -} -{ -"target" "t8" -"classname" "trigger_multiple" -"model" "*24" -} -{ -"light" "220" -"origin" "792 888 -248" -"classname" "light" -} -{ -"light" "180" -"classname" "light" -"origin" "944 608 -248" -} -{ -"light" "150" -"origin" "792 512 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "792 512 -56" -"light" "150" -} -{ -"classname" "light" -"origin" "624 928 -240" -"light" "220" -} -{ -"light" "220" -"origin" "504 1200 -248" -"classname" "light" -} -{ -"origin" "936 800 -248" -"classname" "light" -"light" "180" -} -{ -"light" "180" -"classname" "light" -"origin" "960 984 -208" -} -{ -"classname" "light" -"origin" "792 512 128" -"light" "150" -} -{ -"spawnflags" "2" -"origin" "944 1008 -272" -"classname" "item_health" -} -{ -"spawnflags" "1792" -"origin" "144 2352 16" -"classname" "weapon_rocketlauncher" -} -{ -"spawnflags" "1792" -"origin" "1216 1040 -432" -"classname" "weapon_grenadelauncher" -} -{ -"spawnflags" "1793" -"origin" "1392 1024 -432" -"classname" "item_rockets" -} -{ -"targetname" "t6" -"origin" "-32 1800 -56" -"classname" "info_teleport_destination" -} -{ -"spawnflags" "1792" -"origin" "832 2448 -368" -"classname" "weapon_supernailgun" -} -{ -"spawnflags" "1792" -"origin" "128 1216 -208" -"classname" "weapon_supershotgun" -} -{ -"origin" "296 2136 -192" -"classname" "item_shells" -} -{ -"spawnflags" "1" -"origin" "1424 904 -432" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1376 808 -432" -} -{ -"origin" "1176 936 -432" -"classname" "item_health" -} -{ -"spawnflags" "2048" -"target" "t9" -"wait" "-1" -"angle" "0" -"classname" "func_button" -"model" "*25" -} -{ -"spawnflags" "2048" -"target" "t9" -"wait" "-1" -"angle" "90" -"classname" "func_button" -"model" "*26" -} -{ -"spawnflags" "2048" -"target" "t9" -"wait" "-1" -"angle" "270" -"classname" "func_button" -"model" "*27" -} -{ -"target" "t10" -"targetname" "t9" -"count" "3" -"classname" "trigger_counter" -"model" "*28" -} -{ -"message" "You must press the three buttons..." -"spawnflags" "2048" -"sounds" "2" -"wait" "-1" -"targetname" "t10" -"angle" "180" -"classname" "func_door" -"model" "*29" -} -{ -"light" "150" -"origin" "832 1928 -384" -"classname" "light" -} -{ -"style" "33" -"sounds" "3" -"target" "t11" -"classname" "trigger_once" -"model" "*30" -} -{ -"style" "34" -"sounds" "3" -"target" "t12" -"classname" "trigger_once" -"model" "*31" -} -{ -"style" "35" -"sounds" "3" -"target" "t13" -"classname" "trigger_once" -"model" "*32" -} -{ -"style" "36" -"sounds" "3" -"target" "t14" -"classname" "trigger_once" -"model" "*33" -} -{ -"sounds" "1" -"wait" "-1" -"targetname" "t11" -"spawnflags" "1" -"angle" "-2" -"classname" "func_door" -"model" "*34" -} -{ -"targetname" "t12" -"classname" "func_door" -"angle" "-2" -"spawnflags" "1" -"wait" "-1" -"sounds" "1" -"model" "*35" -} -{ -"targetname" "t13" -"sounds" "1" -"wait" "-1" -"spawnflags" "1" -"angle" "-2" -"classname" "func_door" -"model" "*36" -} -{ -"targetname" "t14" -"classname" "func_door" -"angle" "-2" -"spawnflags" "1" -"wait" "-1" -"sounds" "1" -"model" "*37" -} -{ -"angle" "90" -"origin" "1312 880 -248" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1" -"origin" "1376 1024 -272" -"classname" "item_spikes" -} -{ -"origin" "1184 992 -272" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "1376 856 -272" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "1256 1704 -432" -"classname" "item_health" -} -{ -"angle" "90" -"origin" "480 48 24" -"classname" "info_player_deathmatch" -} -{ -"angle" "180" -"origin" "528 1888 -168" -"classname" "info_player_deathmatch" -} -{ -"angle" "0" -"origin" "-272 2928 -56" -"classname" "info_player_deathmatch" -} -{ -"angle" "0" -"origin" "832 2048 -152" -"classname" "info_player_deathmatch" -} -{ -"speed" "300" -"message" "This door opens elsewhere..." -"spawnflags" "2048" -"targetname" "t15" -"angle" "270" -"classname" "func_door" -"wait" "-1" -"model" "*38" -} -{ -"spawnflags" "2048" -"target" "t15" -"classname" "trigger_once" -"model" "*39" -} -{ -"spawnflags" "1792" -"origin" "480 576 0" -"classname" "weapon_nailgun" -} -{ -"spawnflags" "1793" -"origin" "464 728 64" -"classname" "item_spikes" -} -{ -"origin" "328 848 -224" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "344 920 -224" -} -{ -"spawnflags" "1" -"origin" "-16 2064 -208" -"classname" "item_health" -} -{ -"spawnflags" "1792" -"origin" "-480 2240 -160" -"classname" "item_rockets" -} -{ -"spawnflags" "1793" -"origin" "-96 2456 16" -"classname" "item_shells" -} -{ -"classname" "item_rockets" -"origin" "-104 2216 16" -"spawnflags" "1793" -} -{ -"classname" "item_artifact_invulnerability" -"origin" "256 1808 -40" -"spawnflags" "1792" -} -{ -"classname" "monster_army" -"origin" "0 576 24" -"angle" "0" -"spawnflags" "256" -} -{ -"classname" "monster_army" -"origin" "8 1520 -200" -"angle" "270" -} -{ -"classname" "monster_dog" -"origin" "88 1520 -200" -"angle" "270" -} -{ -"classname" "monster_army" -"origin" "224 1552 -200" -"angle" "270" -"spawnflags" "768" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "-8 936 -200" -"classname" "monster_army" -} -{ -"classname" "monster_army" -"origin" "648 736 104" -"spawnflags" "768" -"angle" "180" -} -{ -"classname" "item_artifact_envirosuit" -"origin" "712 2040 -408" -"angle" "90" -} -{ -"classname" "light" -"origin" "712 2040 -360" -"light" "100" -} -{ -"classname" "item_rockets" -"origin" "1328 2536 -528" -"spawnflags" "1793" -} -{ -"classname" "item_health" -"origin" "916 2416 -136" -"spawnflags" "2" -} -{ -"spawnflags" "1" -"classname" "monster_army" -"origin" "1312 936 -248" -"angle" "90" -} -{ -"classname" "monster_dog" -"origin" "1336 1784 -408" -"angle" "180" -"spawnflags" "257" -} -{ -"spawnflags" "257" -"angle" "90" -"origin" "1392 928 -248" -"classname" "monster_army" -} -{ -"classname" "monster_army" -"origin" "1384 1008 -248" -"angle" "90" -"spawnflags" "768" -} -{ -"spawnflags" "768" -"angle" "90" -"origin" "1240 1008 -248" -"classname" "monster_army" -} -{ -"classname" "monster_army" -"origin" "1256 1760 -408" -"angle" "180" -"spawnflags" "257" -} -{ -"classname" "monster_army" -"origin" "824 1784 -408" -"spawnflags" "257" -"angle" "90" -} -{ -"classname" "monster_dog" -"origin" "1128 1760 -408" -"angle" "180" -"spawnflags" "769" -} -{ -"classname" "path_corner" -"origin" "880 2048 -168" -"target" "t16" -"targetname" "t17" -} -{ -"origin" "1232 2048 -232" -"classname" "path_corner" -"targetname" "t16" -"target" "t17" -} -{ -"classname" "monster_army" -"origin" "1232 2088 -216" -"target" "t16" -} -{ -"classname" "monster_army" -"origin" "1232 2448 -280" -"angle" "270" -"spawnflags" "256" -} -{ -"classname" "monster_army" -"origin" "832 2464 -344" -"angle" "0" -"spawnflags" "256" -} -{ -"classname" "monster_army" -"origin" "832 2072 -408" -"angle" "90" -} -{ -"classname" "monster_dog" -"origin" "840 1960 -408" -"angle" "90" -"spawnflags" "768" -} -{ -"classname" "trigger_multiple" -"target" "t18" -"health" "1" -"model" "*40" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "2" -"targetname" "t18" -"model" "*41" -} -{ -"classname" "weapon_supershotgun" -"origin" "-360 2912 -80" -} -{ -"classname" "trigger_multiple" -"target" "t18" -"model" "*42" -} -{ -"classname" "light" -"origin" "-352 2912 -24" -"light" "120" -} -{ -"classname" "light" -"origin" "160 3024 0" -"light" "120" -} -{ -"classname" "item_shells" -"origin" "528 720 80" -} -{ -"classname" "monster_army" -"origin" "416 1912 -168" -"angle" "180" -"spawnflags" "768" -} -{ -"classname" "monster_dog" -"origin" "432 2120 -168" -"angle" "180" -"spawnflags" "256" -} -{ -"classname" "path_corner" -"origin" "248 1992 -200" -"targetname" "t19" -"target" "t20" -} -{ -"origin" "-200 1992 -200" -"classname" "path_corner" -"targetname" "t20" -"target" "t21" -} -{ -"classname" "path_corner" -"origin" "-136 1912 -200" -"targetname" "t21" -"target" "t22" -} -{ -"origin" "248 1912 -200" -"classname" "path_corner" -"target" "t19" -"targetname" "t22" -} -{ -"classname" "monster_army" -"origin" "80 2024 -184" -"target" "t20" -} -{ -"classname" "monster_army" -"origin" "-16 1888 -184" -"spawnflags" "256" -"target" "t22" -} -{ -"classname" "monster_dog" -"origin" "-248 2144 -136" -"spawnflags" "768" -"angle" "315" -} -{ -"classname" "path_corner" -"origin" "-560 2352 40" -"targetname" "t23" -"target" "t24" -} -{ -"origin" "-104 2352 40" -"classname" "path_corner" -"target" "t23" -"targetname" "t24" -} -{ -"classname" "monster_army" -"origin" "-432 2352 56" -"spawnflags" "768" -"target" "t23" -} -{ -"angle" "0" -"classname" "monster_dog" -"origin" "-544 2584 56" -"spawnflags" "256" -} -{ -"classname" "monster_army" -"origin" "-344 2656 -104" -"angle" "270" -} -{ -"classname" "monster_dog" -"origin" "-72 2896 -56" -"spawnflags" "256" -"angle" "225" -} -{ -"classname" "monster_army" -"origin" "432 2920 -56" -"target" "t25" -} -{ -"classname" "monster_army" -"origin" "424 2832 -56" -"spawnflags" "256" -"angle" "180" -} -{ -"classname" "path_corner" -"origin" "368 2936 -72" -"targetname" "t25" -"target" "t26" -} -{ -"origin" "368 2696 -72" -"classname" "path_corner" -"targetname" "t26" -"target" "t27" -} -{ -"classname" "path_corner" -"origin" "480 2696 -72" -"targetname" "t27" -"target" "t28" -} -{ -"origin" "480 2936 -72" -"classname" "path_corner" -"target" "t25" -"targetname" "t28" -} -{ -"classname" "monster_army" -"origin" "424 2672 -56" -"target" "t27" -} -{ -"classname" "monster_army" -"origin" "424 2880 -56" -"angle" "180" -"spawnflags" "768" -} -{ -"classname" "monster_army" -"origin" "424 2760 -56" -"spawnflags" "768" -"angle" "180" -} -{ -"classname" "path_corner" -"origin" "832 2712 -88" -"targetname" "t29" -"target" "t30" -} -{ -"origin" "832 2416 -104" -"classname" "path_corner" -"target" "t29" -"targetname" "t30" -} -{ -"classname" "monster_army" -"origin" "848 2584 -72" -"spawnflags" "257" -"target" "t29" -} -{ -"classname" "monster_army" -"origin" "824 2008 -152" -"angle" "90" -"spawnflags" "768" -} -{ -"classname" "item_health" -"origin" "-376 1704 -224" -"spawnflags" "1" -} -{ -"angle" "180" -"spawnflags" "768" -"origin" "248 2352 40" -"classname" "monster_army" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "-72 2464 40" -"classname" "monster_army" -} -{ -"spawnflags" "768" -"angle" "225" -"origin" "904 1024 -248" -"classname" "monster_army" -} -{ -"light" "100" -"style" "10" -"classname" "light" -"origin" "688 0 80" -} -{ -"message" "Shoot this secret door..." -"spawnflags" "1" -"angle" "0" -"classname" "func_door_secret" -"model" "*43" -} -{ -"origin" "672 -40 48" -"classname" "item_shells" -} -{ -"classname" "trigger_secret" -"model" "*44" -} -{ -"classname" "trigger_secret" -"model" "*45" -} -{ -"classname" "trigger_secret" -"model" "*46" -} -{ -"classname" "trigger_secret" -"model" "*47" -} -{ -"classname" "trigger_secret" -"model" "*48" -} -{ -"classname" "trigger_secret" -"model" "*49" -} -{ -"light" "100" -"origin" "0 632 -88" -"classname" "light" -} -{ -"classname" "item_health" -"origin" "600 2200 -128" -"spawnflags" "1" -} -{ -"light" "220" -"classname" "light" -"origin" "832 1880 -504" -} -{ -"origin" "72 2056 -208" -"classname" "misc_explobox" -} -{ -"light" "200" -"origin" "-128 584 72" -"classname" "light" -} -{ -"light" "200" -"origin" "-128 568 -136" -"classname" "light" -} -{ -"light" "100" -"origin" "-56 632 -168" -"classname" "light" -} -{ -"light" "200" -"origin" "-56 864 -136" -"classname" "light" -} -{ -"light" "200" -"origin" "40 1672 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "216 1672 -40" -"light" "200" -} -{ -"classname" "light" -"origin" "128 1080 -152" -"light" "200" -} -{ -"light" "200" -"origin" "128 1096 72" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "-352 1656 72" -} -{ -"origin" "608 1640 72" -"classname" "light" -"light" "250" -} -{ -"origin" "-48 1144 -320" -"classname" "light" -"light" "170" -} -{ -"light" "170" -"classname" "light" -"origin" "-48 1256 -320" -} -{ -"origin" "320 1256 -320" -"classname" "light" -"light" "170" -} -{ -"light" "170" -"classname" "light" -"origin" "312 1128 -320" -} -{ -"origin" "136 1128 -320" -"classname" "light" -"light" "170" -} -{ -"light" "170" -"classname" "light" -"origin" "136 1272 -320" -} -{ -"spawnflags" "3072" -"wait" "5" -"sounds" "2" -"message" "You can jump across..." -"classname" "trigger_multiple" -"targetname" "t32" -"model" "*50" -} -{ -"spawnflags" "3072" -"wait" "5" -"message" "You can jump up here..." -"sounds" "2" -"classname" "trigger_multiple" -"targetname" "t31" -"model" "*51" -} -{ -"light" "150" -"origin" "1008 2128 -408" -"classname" "light" -} -{ -"light" "250" -"origin" "1312 544 -184" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "1208 456 -184" -} -{ -"origin" "1416 456 -184" -"classname" "light" -"light" "200" -} -{ -"light" "170" -"origin" "1312 728 -56" -"classname" "light" -} -{ -"map" "e1m2" -"classname" "trigger_changelevel" -"model" "*52" -} -{ -"classname" "item_health" -"origin" "1224 2464 -304" -"spawnflags" "1" -} -{ -"classname" "light" -"origin" "688 1680 -160" -"light" "160" -} -{ -"light" "160" -"origin" "-392 1688 -160" -"classname" "light" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "288 1536 -200" -"classname" "monster_army" -} -{ -"spawnflags" "768" -"origin" "968 2432 -112" -"classname" "monster_army" -} -{ -"wait" "5" -"message" "Walk into the slipgate to exit." -"classname" "trigger_multiple" -"sounds" "2" -"angle" "270" -"model" "*53" -} -{ -"classname" "trigger_once" -"killtarget" "t31" -"target" "t31" -"spawnflags" "3072" -"model" "*54" -} -{ -"classname" "trigger_once" -"spawnflags" "3072" -"target" "t32" -"killtarget" "t32" -"model" "*55" -} -{ -"classname" "item_armor2" -"origin" "1312 1048 -432" -} -{ -"classname" "ambient_comp_hum" -"origin" "250 194 72" -} -{ -"origin" "714 194 72" -"classname" "ambient_comp_hum" -} -{ -"classname" "ambient_comp_hum" -"origin" "626 2058 -104" -} -{ -"origin" "466 2226 -104" -"classname" "ambient_comp_hum" -} -{ -"classname" "info_intermission" -"origin" "-112 704 56" -"mangle" "20 45 0" -} -{ -"classname" "info_intermission" -"origin" "-208 2736 192" -"mangle" "20 225 0" -} -{ -"classname" "info_intermission" -"origin" "240 2664 104" -"mangle" "20 120 0" -} -{ -"classname" "info_intermission" -"origin" "1376 1936 64" -"mangle" "20 135 0" -} -{ -"angle" "90" -"origin" "528 -296 72" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "432 -296 72" -"angle" "90" -} -{ -"angle" "90" -"origin" "480 -240 72" -"classname" "info_player_coop" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*56" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*57" -} -{ -"classname" "ambient_drone" -"origin" "1314 450 -200" -} diff --git a/Misc/pak/maps/e1m2.diff b/Misc/pak/maps/e1m2.diff new file mode 100644 index 000000000..408089893 --- /dev/null +++ b/Misc/pak/maps/e1m2.diff @@ -0,0 +1,28 @@ +--- e1m2.ent ++++ e1m2@0caa.ent +@@ -1567,23 +1567,23 @@ + { + "light" "200" + "origin" "-612 -500 548" + "classname" "light" + } + { + "classname" "func_door" +-"angle" "90" ++"angle" "91" // svdijk -- changed to prevent z-fighting (was "90") + "targetname" "t110" + "wait" "-1" + "model" "*33" + } + { + "sounds" "3" + "classname" "func_door" +-"angle" "270" ++"angle" "269" // svdijk -- changed to prevent z-fighting (was "270") + "wait" "-1" + "model" "*34" + } + { + "classname" "trigger_once" + "target" "t110" + "model" "*35" diff --git a/Misc/pak/maps/e1m2.ent.orig b/Misc/pak/maps/e1m2.ent.orig deleted file mode 100644 index 942ae608b..000000000 --- a/Misc/pak/maps/e1m2.ent.orig +++ /dev/null @@ -1,3019 +0,0 @@ -{ -"message" "Castle of the Damned" -"wad" "gfx/wizard.wad" -"classname" "worldspawn" -"worldtype" "0" -"sounds" "8" -} -{ -"angle" "270" -"origin" "1496 1664 296" -"classname" "info_player_start" -} -{ -"origin" "1432 672 336" -"classname" "light" -"light" "250" -} -{ -"light" "200" -"origin" "1496 888 272" -"classname" "light" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "932 640 340" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1104 812 340" -} -{ -"classname" "light" -"origin" "1104 640 544" -"light" "300" -} -{ -"light" "175" -"origin" "1216 536 353" -"classname" "light" -} -{ -"light" "250" -"origin" "1816 328 448" -"classname" "light" -} -{ -"light" "200" -"origin" "1632 472 208" -"classname" "light" -} -{ -"light" "200" -"origin" "1792 -392 240" -"classname" "light" -} -{ -"light" "200" -"origin" "1452 -124 508" -"classname" "light" -} -{ -"light" "150" -"origin" "1196 -124 508" -"classname" "light" -} -{ -"light" "150" -"origin" "1044 -124 508" -"classname" "light" -} -{ -"light" "200" -"origin" "756 -124 508" -"classname" "light" -} -{ -"light" "250" -"origin" "744 336 145" -"classname" "light" -} -{ -"light" "200" -"origin" "1176 -912 672" -"classname" "light" -} -{ -"origin" "1328 -544 552" -"classname" "light" -} -{ -"classname" "light" -"origin" "1528 -912 640" -"light" "200" -} -{ -"light" "200" -"classname" "light" -"origin" "880 -648 672" -} -{ -"origin" "240 -264 392" -"classname" "light" -"light" "250" -} -{ -"classname" "light" -"origin" "-352 -504 464" -"light" "200" -} -{ -"origin" "-448 -608 804" -"classname" "light" -"light" "450" -} -{ -"light" "250" -"origin" "776 -912 472" -"classname" "light" -} -{ -"light" "300" -"origin" "1630 -806 428" -"classname" "light_torch_small_walltorch" -} -{ -"light" "150" -"origin" "1528 -912 464" -"classname" "light" -} -{ -"classname" "light" -"origin" "1180 -484 560" -} -{ -"classname" "light" -"origin" "1184 -612 560" -} -{ -"classname" "light" -"origin" "1016 -368 472" -"light" "100" -} -{ -"classname" "light" -"origin" "1016 -464 472" -"light" "100" -} -{ -"classname" "light" -"origin" "1020 -560 472" -"light" "100" -} -{ -"classname" "light" -"origin" "1208 -776 472" -"light" "100" -} -{ -"classname" "light" -"origin" "1288 -776 472" -"light" "100" -} -{ -"classname" "light" -"origin" "1360 -776 472" -"light" "100" -} -{ -"light" "200" -"origin" "1792 120 376" -"classname" "light" -} -{ -"origin" "1538 182 356" -"classname" "light_torch_small_walltorch" -} -{ -"light" "200" -"origin" "1640 80 360" -"classname" "light" -} -{ -"light" "200" -"origin" "1928 80 360" -"classname" "light" -} -{ -"light" "250" -"origin" "1792 296 208" -"classname" "light" -} -{ -"light" "150" -"origin" "1800 40 160" -"classname" "light" -} -{ -"light" "200" -"origin" "1776 -392 160" -"classname" "light" -} -{ -"light" "200" -"origin" "1304 -392 152" -"classname" "light" -} -{ -"light" "250" -"origin" "1632 112 136" -"classname" "light" -} -{ -"light" "250" -"origin" "1432 312 136" -"classname" "light" -} -{ -"light" "200" -"origin" "1136 -656 160" -"classname" "light" -} -{ -"light" "200" -"origin" "1136 -416 160" -"classname" "light" -} -{ -"light" "250" -"origin" "1448 -552 160" -"classname" "light" -} -{ -"light" "200" -"origin" "1920 440 136" -"classname" "light" -} -{ -"light" "200" -"origin" "968 88 177" -"classname" "light" -} -{ -"light" "300" -"origin" "1088 312 129" -"classname" "light" -} -{ -"light" "150" -"origin" "1376 168 129" -"classname" "light" -} -{ -"light" "250" -"origin" "112 -384 392" -"classname" "light" -} -{ -"origin" "300 -1004 508" -"classname" "light" -} -{ -"origin" "296 -812 505" -"classname" "light" -} -{ -"origin" "300 -1204 505" -"classname" "light" -} -{ -"light" "150" -"origin" "470 -1006 468" -"classname" "light_torch_small_walltorch" -} -{ -"light" "250" -"origin" "984 -1216 496" -"classname" "light" -} -{ -"light" "250" -"origin" "888 -1128 552" -"classname" "light" -} -{ -"light" "200" -"origin" "800 -1216 592" -"classname" "light" -} -{ -"light" "200" -"origin" "664 -1216 592" -"classname" "light" -} -{ -"light" "200" -"origin" "584 -1136 592" -"classname" "light" -} -{ -"light" "200" -"origin" "584 -968 592" -"classname" "light" -} -{ -"light" "250" -"origin" "584 -744 592" -"classname" "light" -} -{ -"light" "200" -"origin" "528 -1144 464" -"classname" "light" -} -{ -"light" "200" -"origin" "528 -856 464" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "1496 1544 440" -} -{ -"origin" "1384 1392 440" -"classname" "light" -"light" "250" -} -{ -"origin" "1496 1104 520" -"classname" "light" -} -{ -"origin" "1608 1400 440" -"classname" "light" -"light" "250" -} -{ -"light" "250" -"origin" "1240 1712 360" -"classname" "light" -} -{ -"light" "250" -"origin" "1744 1696 360" -"classname" "light" -} -{ -"classname" "light" -"origin" "1384 1136 440" -"light" "250" -} -{ -"classname" "light" -"origin" "1608 1144 440" -"light" "250" -} -{ -"classname" "path_corner" -"origin" "1168 736 296" -"targetname" "t5" -"target" "t6" -} -{ -"classname" "path_corner" -"origin" "992 744 296" -"targetname" "t6" -"target" "t7" -} -{ -"classname" "path_corner" -"origin" "1000 544 296" -"targetname" "t7" -"target" "t34" -} -{ -"classname" "item_health" -"origin" "960 704 288" -} -{ -"classname" "item_shells" -"origin" "952 512 288" -} -{ -"classname" "path_corner" -"origin" "1344 -128 304" -"targetname" "t9" -"target" "t8" -} -{ -"classname" "path_corner" -"origin" "898 -128 304" -"targetname" "t8" -"target" "t9" -} -{ -"spawnflags" "1" -"classname" "monster_ogre" -"origin" "1018 -126 320" -"angle" "0" -"target" "t8" -} -{ -"classname" "item_health" -"origin" "1344 -224 296" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "1400 -224 296" -"spawnflags" "1" -} -{ -"origin" "1528 192 296" -"classname" "item_shells" -} -{ -"classname" "path_corner" -"origin" "1496 1040 184" -"targetname" "t22" -"target" "t23" -} -{ -"classname" "path_corner" -"origin" "1496 840 248" -"targetname" "t23" -"target" "t33" -} -{ -"spawnflags" "1" -"classname" "item_shells" -"origin" "1056 -648 288" -} -{ -"classname" "item_health" -"origin" "1184 -736 288" -} -{ -"spawnflags" "257" -"classname" "monster_army" -"origin" "1646 -698 360" -"angle" "180" -"targetname" "t89" -} -{ -"classname" "path_corner" -"origin" "1400 640 272" -"targetname" "t30" -"target" "t79" -} -{ -"classname" "path_corner" -"origin" "1496 752 232" -"targetname" "t33" -"target" "t77" -} -{ -"classname" "path_corner" -"origin" "1192 560 296" -"targetname" "t34" -"target" "t80" -} -{ -"classname" "item_shells" -"origin" "1616 1280 176" -} -{ -"classname" "item_health" -"origin" "1056 -840 416" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "1104 -840 416" -"spawnflags" "1" -} -{ -"spawnflags" "1" -"classname" "monster_army" -"origin" "262 -458 320" -"angle" "0" -"target" "t96" -} -{ -"spawnflags" "1024" -"classname" "item_health" -"origin" "136 -296 296" -} -{ -"classname" "path_corner" -"origin" "-536 -704 472" -"targetname" "t42" -"target" "t41" -} -{ -"classname" "path_corner" -"origin" "-576 -416 472" -"targetname" "t41" -"target" "t42" -} -{ -"classname" "monster_knight" -"origin" "-578 -654 480" -"target" "t41" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "-368 -752 456" -} -{ -"classname" "item_health" -"origin" "-16 -520 360" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "-16 -576 360" -"spawnflags" "1" -} -{ -"classname" "light" -"origin" "1848 -568 320" -"light" "200" -} -{ -"classname" "light" -"origin" "1760 -560 408" -"light" "200" -} -{ -"classname" "light" -"origin" "1624 -560 352" -"light" "150" -} -{ -"targetname" "t43" -"angle" "270" -"origin" "800 368 312" -"classname" "info_teleport_destination" -} -{ -"origin" "752 168 296" -"classname" "item_health" -} -{ -"target" "t43" -"classname" "trigger_teleport" -"model" "*1" -} -{ -"origin" "1712 -568 256" -"classname" "item_health" -} -{ -"classname" "monster_ogre" -"origin" "1494 1134 208" -"angle" "270" -"target" "t22" -} -{ -"light" "300" -"origin" "1856 1288 384" -"classname" "light" -} -{ -"classname" "light" -"origin" "1136 1288 384" -} -{ -"light" "200" -"origin" "1920 328 380" -"classname" "light" -} -{ -"target" "t122" -"spawnflags" "2048" -"sounds" "1" -"classname" "item_key1" -"origin" "880 -300 464" -} -{ -"light" "300" -"origin" "648 -384 430" -"classname" "light_flame_small_yellow" -} -{ -"light" "250" -"classname" "light_flame_small_yellow" -"origin" "1104 -224 406" -} -{ -"light" "250" -"origin" "1456 -128 406" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light" -"origin" "988 532 353" -"light" "175" -} -{ -"light" "125" -"origin" "1100 648 328" -"classname" "light" -} -{ -"origin" "1616 936 310" -"classname" "light_flame_small_yellow" -"light" "300" -} -{ -"light" "300" -"classname" "light_flame_small_yellow" -"origin" "1360 936 310" -} -{ -"origin" "1792 504 390" -"classname" "light_flame_small_yellow" -"light" "300" -} -{ -"origin" "1972 -252 332" -"classname" "info_null" -"targetname" "t47" -} -{ -"light" "800" -"origin" "1992 -252 336" -"classname" "light" -"target" "t47" -} -{ -"classname" "info_null" -"origin" "1948 -292 332" -"targetname" "t48" -} -{ -"light" "800" -"classname" "light" -"origin" "1948 -312 336" -"target" "t48" -} -{ -"origin" "880 -328 562" -"classname" "light_flame_small_yellow" -"light" "300" -} -{ -"classname" "light" -"origin" "1056 -1288 504" -} -{ -"origin" "1184 -1288 504" -"classname" "light" -} -{ -"classname" "light" -"origin" "1312 -1288 504" -} -{ -"origin" "1440 -1288 504" -"classname" "light" -} -{ -"sounds" "1" -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"targetname" "t50" -"model" "*2" -} -{ -"sounds" "1" -"classname" "func_door" -"wait" "-1" -"angle" "-2" -"targetname" "t50" -"model" "*3" -} -{ -"classname" "trigger_once" -"target" "t50" -"model" "*4" -} -{ -"classname" "light" -"origin" "1368 -1016 504" -"light" "200" -} -{ -"light" "200" -"origin" "1120 -1024 504" -"classname" "light" -} -{ -"classname" "light" -"origin" "1248 -1184 464" -"light" "175" -} -{ -"classname" "light" -"origin" "776 -480 480" -"light" "225" -} -{ -"classname" "light" -"origin" "1904 -144 168" -"light" "200" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1706 -206 316" -"light" "300" -} -{ -"light" "300" -"origin" "2134 -34 316" -"classname" "light_torch_small_walltorch" -} -{ -"origin" "1152 -296 422" -"classname" "light_flame_small_yellow" -"light" "250" -} -{ -"light" "250" -"classname" "light_flame_small_yellow" -"origin" "1152 -760 422" -} -{ -"origin" "1528 -556 478" -"classname" "light_flame_small_yellow" -"light" "250" -} -{ -"targetname" "t52" -"origin" "1532 -552 328" -"classname" "info_null" -} -{ -"origin" "1340 -544 384" -"classname" "item_armor2" -} -{ -"sounds" "1" -"targetname" "t53" -"lip" "64" -"wait" "-1" -"angle" "-1" -"classname" "func_door" -"model" "*5" -} -{ -"sounds" "1" -"targetname" "t53" -"classname" "func_door" -"angle" "-1" -"wait" "-1" -"lip" "64" -"model" "*6" -} -{ -"targetname" "t53" -"target" "t54" -"classname" "trigger_teleport" -"spawnflags" "2" -"model" "*7" -} -{ -"targetname" "t54" -"angle" "180" -"origin" "1408 -688 449" -"classname" "info_teleport_destination" -} -{ -"targetname" "t53" -"target" "t57" -"classname" "trigger_teleport" -"spawnflags" "2" -"model" "*8" -} -{ -"targetname" "t57" -"angle" "180" -"origin" "1408 -400 361" -"classname" "info_teleport_destination" -} -{ -"spawnflags" "768" -"targetname" "t53" -"angle" "180" -"origin" "1912 -856 217" -"classname" "monster_wizard" -} -{ -"spawnflags" "768" -"targetname" "t53" -"classname" "monster_wizard" -"origin" "1912 -936 217" -"angle" "180" -} -{ -"targetname" "t50" -"angle" "90" -"origin" "1320 -1112 441" -"classname" "monster_knight" -} -{ -"spawnflags" "256" -"targetname" "t50" -"angle" "0" -"origin" "1056 -1144 441" -"classname" "monster_knight" -} -{ -"sounds" "1" -"targetname" "t61" -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"model" "*9" -} -{ -"sounds" "3" -"lip" "64" -"spawnflags" "1" -"targetname" "t58" -"angle" "270" -"wait" "-1" -"classname" "func_door" -"model" "*10" -} -{ -"sounds" "1" -"wait" "-1" -"angle" "270" -"target" "t58" -"classname" "func_button" -"model" "*11" -} -{ -"target" "t61" -"classname" "trigger_once" -"model" "*12" -} -{ -"light" "225" -"origin" "984 -480 480" -"classname" "light" -} -{ -"light" "175" -"origin" "880 -368 176" -"classname" "light" -} -{ -"classname" "light" -"origin" "880 -592 240" -"light" "175" -} -{ -"light" "200" -"origin" "880 -488 184" -"classname" "light" -} -{ -"light" "150" -"origin" "880 -304 472" -"classname" "light" -} -{ -"classname" "light" -"origin" "-96 308 864" -"light" "850" -} -{ -"origin" "-32 -440 624" -"classname" "light" -} -{ -"sounds" "1" -"targetname" "t73" -"wait" "-1" -"lip" "196" -"angle" "-1" -"classname" "func_door" -"model" "*13" -} -{ -"light" "300" -"origin" "104 144 688" -"classname" "light" -} -{ -"classname" "light" -"origin" "-264 144 688" -"light" "300" -} -{ -"sounds" "1" -"targetname" "t73" -"wait" "-1" -"classname" "func_door" -"angle" "-1" -"lip" "196" -"model" "*14" -} -{ -"classname" "light_flame_small_yellow" -"origin" "-24 -232 414" -"light" "250" -} -{ -"lip" "-2" -"sounds" "3" -"speed" "350" -"targetname" "t73" -"angle" "180" -"wait" "-1" -"classname" "func_door" -"model" "*15" -} -{ -"target" "t63" -"targetname" "t62" -"origin" "-12 312 264" -"classname" "path_corner" -} -{ -"target" "t64" -"targetname" "t63" -"origin" "-12 312 356" -"classname" "path_corner" -} -{ -"wait" "-1" -"target" "t66" -"targetname" "t64" -"classname" "path_corner" -"origin" "-13 440 355" -} -{ -"sounds" "1" -"targetname" "t71" -"wait" "-1" -"target" "t65" -"angle" "-2" -"classname" "func_button" -"model" "*16" -} -{ -"target" "t64" -"targetname" "t66" -"origin" "-13 440 355" -"classname" "path_corner" -} -{ -"light" "200" -"origin" "-96 440 376" -"classname" "light" -} -{ -"light" "150" -"origin" "8 456 376" -"classname" "light" -} -{ -"targetname" "t70" -"target" "t67" -"classname" "path_corner" -"origin" "-220 312 264" -} -{ -"target" "t68" -"targetname" "t67" -"classname" "path_corner" -"origin" "-220 312 356" -} -{ -"wait" "-1" -"target" "t69" -"targetname" "t68" -"origin" "-221 440 355" -"classname" "path_corner" -} -{ -"target" "t68" -"targetname" "t69" -"classname" "path_corner" -"origin" "-221 440 355" -} -{ -"classname" "light" -"origin" "-200 456 376" -"light" "150" -} -{ -"targetname" "t65" -"target" "t62" -"classname" "func_train" -"speed" "50" -"sounds" "1" -"model" "*17" -} -{ -"light" "250" -"origin" "-96 632 406" -"classname" "light_flame_small_yellow" -} -{ -"targetname" "t72" -"origin" "-96 288 304" -"classname" "info_null" -} -{ -"light" "450" -"target" "t72" -"origin" "-96 288 368" -"classname" "light" -} -{ -"target" "t70" -"targetname" "t65" -"speed" "50" -"classname" "func_train" -"sounds" "1" -"model" "*18" -} -{ -"lip" "-2" -"sounds" "0" -"speed" "350" -"classname" "func_door" -"wait" "-1" -"angle" "0" -"model" "*19" -} -{ -"targetname" "t65" -"delay" "4.7" -"target" "t73" -"classname" "trigger_once" -"model" "*20" -} -{ -"targetname" "t73" -"angle" "270" -"origin" "-96 552 320" -"classname" "monster_demon1" -"spawnflags" "1024" -} -{ -"targetname" "t74" -"angle" "90" -"origin" "132 -192 476" -"classname" "info_teleport_destination" -} -{ -"targetname" "t75" -"classname" "info_teleport_destination" -"origin" "-328 -196 476" -"angle" "90" -} -{ -"target" "t75" -"classname" "trigger_teleport" -"spawnflags" "1" -"model" "*21" -} -{ -"target" "t74" -"classname" "trigger_teleport" -"spawnflags" "1" -"model" "*22" -} -{ -"light" "200" -"origin" "-418 306 356" -"classname" "light" -} -{ -"classname" "light" -"origin" "260 308 356" -"light" "200" -} -{ -"sounds" "0" -"targetname" "t73" -"wait" "-1" -"angle" "180" -"classname" "func_door" -"model" "*23" -} -{ -"sounds" "0" -"targetname" "t73" -"wait" "-1" -"angle" "0" -"classname" "func_door" -"model" "*24" -} -{ -"sounds" "0" -"wait" "-1" -"angle" "0" -"targetname" "t73" -"classname" "func_door" -"model" "*25" -} -{ -"sounds" "0" -"targetname" "t73" -"angle" "180" -"wait" "-1" -"classname" "func_door" -"model" "*26" -} -{ -"sounds" "3" -"wait" "-1" -"angle" "-2" -"targetname" "t73" -"classname" "func_door" -"model" "*27" -} -{ -"classname" "light" -"origin" "-96 24 360" -"light" "100" -} -{ -"light" "100" -"origin" "-96 -40 360" -"classname" "light" -} -{ -"classname" "light" -"origin" "-160 -568 624" -} -{ -"origin" "-160 -440 624" -"classname" "light" -} -{ -"classname" "light" -"origin" "-32 -568 624" -} -{ -"classname" "light" -"origin" "-96 -88 484" -"light" "150" -} -{ -"classname" "light" -"origin" "-440 -408 804" -"light" "450" -} -{ -"classname" "light" -"origin" "600 -128 352" -"light" "200" -} -{ -"classname" "light" -"origin" "576 -608 504" -"light" "250" -} -{ -"classname" "light" -"origin" "384 -504 392" -"light" "250" -} -{ -"classname" "light" -"origin" "1264 240 295" -"light" "250" -} -{ -"light" "250" -"origin" "944 240 295" -"classname" "light" -} -{ -"classname" "path_corner" -"origin" "1480 704 264" -"targetname" "t77" -"target" "t78" -} -{ -"classname" "path_corner" -"origin" "1448 656 264" -"targetname" "t78" -"target" "t30" -} -{ -"classname" "path_corner" -"origin" "1264 640 304" -"targetname" "t80" -"target" "t5" -} -{ -"classname" "path_corner" -"origin" "1328 640 304" -"targetname" "t79" -"target" "t80" -} -{ -"light" "200" -"origin" "1488 -392 216" -"classname" "light" -} -{ -"classname" "path_corner" -"origin" "816 80 304" -"targetname" "t83" -"target" "t82" -"spawnflags" "256" -} -{ -"origin" "816 312 304" -"classname" "path_corner" -"targetname" "t82" -"target" "t83" -"spawnflags" "256" -} -{ -"classname" "monster_army" -"origin" "806 206 320" -"angle" "90" -"target" "t82" -"spawnflags" "256" -} -{ -"classname" "trigger_once" -"target" "t84" -"model" "*28" -} -{ -"classname" "monster_ogre" -"origin" "1790 -146 312" -"angle" "90" -"targetname" "t84" -} -{ -"classname" "path_corner" -"origin" "1088 -672 296" -"target" "t85" -"targetname" "t88" -} -{ -"origin" "1088 -376 296" -"classname" "path_corner" -"targetname" "t85" -"target" "t86" -} -{ -"classname" "path_corner" -"origin" "1088 -376 296" -"targetname" "t87" -"target" "t88" -} -{ -"origin" "1448 -376 296" -"classname" "path_corner" -"targetname" "t86" -"target" "t87" -} -{ -"spawnflags" "1" -"classname" "monster_ogre" -"origin" "1086 -498 312" -"angle" "270" -"target" "t88" -} -{ -"spawnflags" "256" -"classname" "trigger_once" -"target" "t89" -"model" "*29" -} -{ -"classname" "item_health" -"origin" "352 -752 408" -"spawnflags" "1025" -} -{ -"spawnflags" "1025" -"origin" "352 -792 408" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "352 -832 408" -"spawnflags" "1" -} -{ -"classname" "path_corner" -"origin" "408 -776 416" -"targetname" "t94" -"target" "t95" -} -{ -"origin" "400 -1088 416" -"classname" "path_corner" -"targetname" "t95" -"target" "t94" -} -{ -"classname" "path_corner" -"origin" "584 -1096 416" -"targetname" "t92" -"target" "t93" -} -{ -"origin" "584 -792 416" -"classname" "path_corner" -"targetname" "t93" -"target" "t92" -} -{ -"classname" "monster_army" -"origin" "390 -970 432" -"angle" "0" -"target" "t94" -} -{ -"classname" "monster_army" -"origin" "566 -970 432" -"angle" "270" -"target" "t92" -} -{ -"classname" "path_corner" -"origin" "208 -304 304" -"targetname" "t97" -"target" "t96" -} -{ -"classname" "path_corner" -"origin" "208 -464 304" -"targetname" "t96" -"target" "t97" -} -{ -"spawnflags" "1280" -"classname" "path_corner" -"origin" "-344 160 304" -"targetname" "t100" -"target" "t99" -} -{ -"spawnflags" "1280" -"origin" "168 152 304" -"classname" "path_corner" -"targetname" "t99" -"target" "t100" -} -{ -"spawnflags" "1280" -"classname" "monster_ogre" -"origin" "240 152 320" -"angle" "180" -"target" "t99" -} -{ -"spawnflags" "768" -"classname" "monster_ogre" -"origin" "-392 80 320" -"angle" "0" -"targetname" "t101" -} -{ -"spawnflags" "768" -"classname" "trigger_once" -"target" "t101" -"model" "*30" -} -{ -"classname" "item_health" -"origin" "40 -16 464" -} -{ -"origin" "80 -48 464" -"classname" "item_health" -} -{ -"origin" "520 -72 296" -"classname" "item_shells" -} -{ -"spawnflags" "1" -"origin" "-424 -216 296" -"classname" "item_shells" -} -{ -"spawnflags" "769" -"angle" "270" -"origin" "880 -400 568" -"classname" "monster_wizard" -} -{ -"light" "200" -"origin" "432 176 152" -"classname" "light" -} -{ -"light" "150" -"origin" "432 -56 256" -"classname" "light" -} -{ -"origin" "264 -96 300" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "264 -140 300" -} -{ -"spawnflags" "1" -"origin" "1184 1568 240" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1184 1616 240" -"spawnflags" "1" -} -{ -"light" "150" -"origin" "1496 1112 108" -"classname" "light" -} -{ -"light" "200" -"origin" "1120 1152 96" -"classname" "light" -} -{ -"light" "200" -"origin" "1080 692 184" -"classname" "light" -} -{ -"light" "300" -"classname" "light_flame_small_yellow" -"origin" "832 1184 294" -} -{ -"origin" "464 536 358" -"classname" "light_flame_small_yellow" -"light" "300" -} -{ -"light" "300" -"classname" "light_flame_small_yellow" -"origin" "600 704 334" -} -{ -"light" "150" -"origin" "1736 1096 110" -"classname" "light" -} -{ -"light" "100" -"origin" "832 1056 134" -"classname" "light" -} -{ -"light" "150" -"origin" "784 704 294" -"classname" "light" -} -{ -"origin" "856 592 182" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "824 552 182" -} -{ -"classname" "info_player_deathmatch" -"origin" "-416 -144 320" -"angle" "90" -} -{ -"classname" "info_player_deathmatch" -"origin" "168 -480 320" -"angle" "45" -} -{ -"classname" "info_player_deathmatch" -"origin" "1496 1328 200" -"angle" "270" -} -{ -"classname" "info_player_deathmatch" -"origin" "1936 -136 312" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "936 -1216 432" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "792 -992 440" -"angle" "45" -} -{ -"classname" "info_player_deathmatch" -"origin" "1080 -720 312" -"angle" "0" -} -{ -"classname" "info_player_deathmatch" -"origin" "408 -752 432" -"angle" "270" -} -{ -"classname" "info_player_deathmatch" -"origin" "792 -208 320" -"angle" "45" -} -{ -"classname" "info_player_deathmatch" -"origin" "784 808 206" -"angle" "225" -} -{ -"sounds" "3" -"wait" "3" -"angle" "90" -"classname" "func_door" -"model" "*31" -} -{ -"sounds" "0" -"wait" "3" -"angle" "270" -"classname" "func_door" -"model" "*32" -} -{ -"spawnflags" "1" -"origin" "680 832 182" -"classname" "item_shells" -} -{ -"origin" "1392 240 300" -"classname" "weapon_supershotgun" -} -{ -"spawnflags" "769" -"angle" "270" -"origin" "954 -754 444" -"classname" "monster_ogre" -} -{ -"spawnflags" "1" -"origin" "520 -1280 408" -"classname" "item_shells" -} -{ -"light" "200" -"origin" "-612 -500 548" -"classname" "light" -} -{ -"classname" "func_door" -"angle" "90" -"targetname" "t110" -"wait" "-1" -"model" "*33" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "270" -"wait" "-1" -"model" "*34" -} -{ -"classname" "trigger_once" -"target" "t110" -"model" "*35" -} -{ -"classname" "trigger_changelevel" -"map" "e1m3" -"model" "*36" -} -{ -"spawnflags" "1792" -"origin" "680 728 184" -"classname" "weapon_rocketlauncher" -} -{ -"spawnflags" "1792" -"origin" "1496 1256 176" -"classname" "weapon_nailgun" -} -{ -"angle" "180" -"spawnflags" "1792" -"origin" "-96 -496 360" -"classname" "weapon_supernailgun" -} -{ -"spawnflags" "1794" -"origin" "-112 -8 464" -"classname" "item_health" -} -{ -"spawnflags" "1793" -"origin" "-112 -568 360" -"classname" "item_spikes" -} -{ -"spawnflags" "1792" -"origin" "1616 1424 176" -"classname" "item_spikes" -} -{ -"spawnflags" "1792" -"classname" "item_spikes" -"origin" "1656 1424 176" -} -{ -"spawnflags" "1792" -"origin" "1696 1424 176" -"classname" "item_spikes" -} -{ -"spawnflags" "768" -"target" "t34" -"angle" "315" -"origin" "1070 646 312" -"classname" "monster_ogre" -} -{ -"spawnflags" "768" -"targetname" "t84" -"angle" "90" -"origin" "1624 88 376" -"classname" "monster_wizard" -} -{ -"spawnflags" "768" -"angle" "90" -"targetname" "t84" -"origin" "1866 -378 312" -"classname" "monster_ogre" -} -{ -"angle" "45" -"origin" "1088 -1096 440" -"classname" "monster_knight" -"targetname" "t50" -} -{ -"spawnflags" "768" -"classname" "monster_knight" -"origin" "1400 -1144 440" -"angle" "90" -"targetname" "t50" -} -{ -"spawnflags" "256" -"target" "t111" -"targetname" "t112" -"origin" "896 -1216 416" -"classname" "path_corner" -} -{ -"spawnflags" "256" -"target" "t112" -"targetname" "t111" -"classname" "path_corner" -"origin" "704 -1216 416" -} -{ -"spawnflags" "257" -"target" "t111" -"angle" "180" -"origin" "758 -1218 432" -"classname" "monster_army" -} -{ -"spawnflags" "768" -"target" "t114" -"targetname" "t113" -"origin" "-96 -520 368" -"classname" "path_corner" -} -{ -"spawnflags" "768" -"target" "t113" -"targetname" "t114" -"origin" "-96 -152 304" -"classname" "path_corner" -} -{ -"targetname" "t116" -"spawnflags" "769" -"target" "t113" -"angle" "270" -"origin" "-98 -194 320" -"classname" "monster_ogre" -} -{ -"spawnflags" "1536" -"origin" "1936 -96 289" -"classname" "item_health" -} -{ -"spawnflags" "1025" -"origin" "1040 -1200 417" -"classname" "item_health" -} -{ -"spawnflags" "769" -"target" "t117" -"angle" "315" -"origin" "-560 -312 592" -"classname" "monster_wizard" -} -{ -"spawnflags" "768" -"target" "t118" -"targetname" "t117" -"origin" "-528 -344 576" -"classname" "path_corner" -} -{ -"spawnflags" "768" -"target" "t117" -"targetname" "t118" -"origin" "-352 -656 576" -"classname" "path_corner" -} -{ -"classname" "light" -"origin" "1360 976 224" -"light" "150" -} -{ -"light" "150" -"origin" "1616 976 224" -"classname" "light" -} -{ -"classname" "light" -"origin" "1208 1296 368" -"light" "250" -} -{ -"origin" "1784 1288 368" -"classname" "light" -"light" "250" -} -{ -"classname" "light" -"origin" "1496 1664 336" -"light" "250" -} -{ -"classname" "light" -"origin" "1752 1176 112" -"light" "150" -} -{ -"light" "200" -"origin" "1776 976 112" -"classname" "light" -} -{ -"classname" "light" -"origin" "1216 976 112" -"light" "200" -} -{ -"light" "150" -"origin" "1224 1176 112" -"classname" "light" -} -{ -"classname" "light" -"origin" "1496 1432 520" -"light" "250" -} -{ -"classname" "light" -"origin" "1496 1304 264" -"light" "200" -} -{ -"classname" "light" -"origin" "1496 1432 288" -"light" "200" -} -{ -"classname" "light" -"origin" "1608 1120 88" -"light" "150" -} -{ -"light" "150" -"origin" "1384 1120 88" -"classname" "light" -} -{ -"classname" "light" -"origin" "1496 864 368" -"light" "150" -} -{ -"light" "175" -"origin" "980 764 353" -"classname" "light" -} -{ -"classname" "light" -"origin" "1228 764 353" -"light" "175" -} -{ -"classname" "light" -"origin" "1104 464 353" -"light" "200" -} -{ -"classname" "light" -"origin" "1104 -40 423" -"light" "200" -} -{ -"light" "150" -"origin" "1416 -128 367" -"classname" "light" -} -{ -"classname" "light" -"origin" "1104 -184 367" -"light" "200" -} -{ -"classname" "light" -"origin" "1184 56 423" -"light" "150" -} -{ -"light" "150" -"origin" "1024 56 423" -"classname" "light" -} -{ -"classname" "light" -"origin" "1272 -64 399" -"light" "150" -} -{ -"light" "150" -"origin" "888 -64 399" -"classname" "light" -} -{ -"classname" "light" -"origin" "1104 152 129" -"light" "300" -} -{ -"classname" "light" -"origin" "976 392 129" -"light" "200" -} -{ -"classname" "light" -"origin" "1104 656 120" -} -{ -"classname" "light" -"origin" "896 712 144" -"light" "200" -} -{ -"classname" "light" -"origin" "640 704 280" -"light" "200" -} -{ -"classname" "light" -"origin" "464 496 296" -"light" "150" -} -{ -"classname" "light" -"origin" "888 1152 96" -"light" "200" -} -{ -"classname" "light" -"origin" "840 880 240" -"light" "200" -} -{ -"classname" "light" -"origin" "848 584 240" -"light" "150" -} -{ -"classname" "light" -"origin" "784 160 144" -"light" "200" -} -{ -"classname" "light" -"origin" "440 336 144" -"light" "150" -} -{ -"light" "150" -"origin" "584 336 144" -"classname" "light" -} -{ -"classname" "light" -"origin" "432 24 136" -"light" "150" -} -{ -"classname" "light" -"origin" "656 328 224" -"light" "200" -} -{ -"classname" "light" -"origin" "432 -128 312" -"light" "200" -} -{ -"classname" "light" -"origin" "600 -384 360" -"light" "200" -} -{ -"origin" "520 -128 406" -"classname" "light_flame_small_yellow" -"light" "250" -} -{ -"classname" "light" -"origin" "424 -320 352" -"light" "200" -} -{ -"classname" "light" -"origin" "664 -1216 472" -"light" "150" -} -{ -"classname" "light" -"origin" "336 -1208 504" -"light" "150" -} -{ -"light" "150" -"origin" "336 -1008 504" -"classname" "light" -} -{ -"classname" "light" -"origin" "336 -816 504" -"light" "150" -} -{ -"classname" "light" -"origin" "880 -1000 496" -"light" "200" -} -{ -"classname" "light" -"origin" "880 -792 496" -"light" "200" -} -{ -"classname" "light" -"origin" "880 -376 304" -"light" "200" -} -{ -"classname" "light" -"origin" "1048 -912 480" -"light" "225" -} -{ -"classname" "light" -"origin" "1120 -1192 468" -"light" "150" -} -{ -"light" "150" -"origin" "1376 -1192 468" -"classname" "light" -} -{ -"classname" "light" -"origin" "1472 -912 464" -"light" "175" -} -{ -"classname" "light" -"origin" "880 -304 480" -"light" "100" -} -{ -"classname" "light" -"origin" "880 -680 480" -"light" "175" -} -{ -"classname" "light" -"origin" "1600 -704 484" -"light" "150" -} -{ -"classname" "light" -"origin" "1504 -704 348" -"light" "175" -} -{ -"light" "175" -"origin" "1336 -704 348" -"classname" "light" -} -{ -"classname" "light" -"origin" "1152 -640 332" -"light" "200" -} -{ -"classname" "light" -"origin" "1096 -552 348" -"light" "150" -} -{ -"light" "200" -"origin" "1160 -456 332" -"classname" "light" -} -{ -"light" "150" -"origin" "1216 -384 348" -"classname" "light" -} -{ -"classname" "light" -"origin" "1344 -384 348" -"light" "150" -} -{ -"classname" "light" -"origin" "1544 392 156" -"light" "225" -} -{ -"light" "225" -"origin" "1848 248 156" -"classname" "light" -} -{ -"classname" "light" -"origin" "1936 136 156" -"light" "225" -} -{ -"light" "200" -"origin" "2096 -80 156" -"classname" "light" -} -{ -"light" "200" -"origin" "2048 -408 156" -"classname" "light" -} -{ -"classname" "light" -"origin" "1456 -392 444" -"light" "225" -} -{ -"classname" "light" -"origin" "1640 -384 352" -"light" "225" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "2134 -474 316" -"light" "250" -} -{ -"light" "200" -"origin" "168 216 496" -"classname" "light" -} -{ -"classname" "light" -"origin" "-328 208 496" -"light" "200" -} -{ -"light" "200" -"origin" "-96 360 432" -"classname" "light" -} -{ -"classname" "light" -"origin" "-96 144 432" -"light" "200" -} -{ -"light" "200" -"origin" "-376 32 432" -"classname" "light" -} -{ -"light" "200" -"origin" "208 -72 432" -"classname" "light" -} -{ -"light" "150" -"origin" "-96 72 360" -"classname" "light" -} -{ -"light" "150" -"origin" "-64 -232 368" -"classname" "light" -} -{ -"light" "150" -"origin" "-96 -320 560" -"classname" "light" -} -{ -"light" "250" -"origin" "-96 -496 448" -"classname" "light" -} -{ -"light" "150" -"origin" "-416 -104 392" -"classname" "light" -} -{ -"light" "150" -"origin" "-344 -152 528" -"classname" "light" -} -{ -"classname" "light" -"origin" "160 -152 528" -"light" "150" -} -{ -"light" "150" -"origin" "-96 8 528" -"classname" "light" -} -{ -"light" "200" -"origin" "-560 -504 688" -"classname" "light" -} -{ -"classname" "light" -"origin" "-440 -368 688" -"light" "200" -} -{ -"light" "200" -"origin" "-440 -656 688" -"classname" "light" -} -{ -"classname" "light" -"origin" "-336 -504 688" -"light" "200" -} -{ -"classname" "light" -"origin" "2084 -208 336" -"light" "100" -} -{ -"light" "100" -"origin" "2012 -252 332" -"classname" "light" -} -{ -"classname" "light" -"origin" "1948 -328 332" -"light" "100" -} -{ -"light" "150" -"origin" "1892 -452 332" -"classname" "light" -} -{ -"sounds" "1" -"targetname" "t120" -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"lip" "4" -"model" "*37" -} -{ -"target" "t120" -"classname" "trigger_once" -"model" "*38" -} -{ -"light" "100" -"origin" "2076 -312 336" -"classname" "light" -} -{ -"sounds" "3" -"spawnflags" "2064" -"angle" "0" -"wait" "-1" -"classname" "func_door" -"model" "*39" -} -{ -"spawnflags" "2064" -"wait" "-1" -"angle" "180" -"classname" "func_door" -"model" "*40" -} -{ -"light" "100" -"origin" "332 -264 356" -"classname" "light" -} -{ -"classname" "light" -"origin" "144 -264 356" -"light" "100" -} -{ -"light" "100" -"origin" "1104 572 316" -"classname" "light" -} -{ -"target" "t121" -"wait" ".8" -"classname" "trigger_multiple" -"model" "*41" -} -{ -"targetname" "t121" -"angle" "180" -"origin" "2120 -256 332" -"classname" "trap_spikeshooter" -"spawnflags" "1024" -} -{ -"targetname" "t121" -"angle" "90" -"origin" "1944 -456 332" -"classname" "trap_spikeshooter" -"spawnflags" "1024" -} -{ -"light" "150" -"origin" "1312 -856 472" -"classname" "light" -} -{ -"classname" "light" -"origin" "1184 -856 472" -"light" "175" -} -{ -"classname" "light" -"origin" "1560 -568 224" -"light" "200" -} -{ -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"speed" "50" -"sounds" "1" -"targetname" "t123" -"lip" "6" -"model" "*42" -} -{ -"classname" "trigger_once" -"target" "t123" -"model" "*43" -} -{ -"classname" "light" -"origin" "1496 -552 330" -"light" "700" -"target" "t52" -} -{ -"classname" "light" -"origin" "1288 80 140" -"light" "250" -} -{ -"classname" "light" -"origin" "1288 400 80" -"light" "200" -} -{ -"classname" "light" -"origin" "1328 -664 160" -"light" "200" -} -{ -"classname" "item_armor1" -"origin" "784 56 304" -} -{ -"classname" "light" -"origin" "1544 464 352" -"light" "75" -} -{ -"classname" "func_plat" -"model" "*44" -} -{ -"classname" "light" -"origin" "1496 1192 280" -"light" "200" -} -{ -"classname" "light" -"origin" "1608 1192 136" -"light" "100" -} -{ -"light" "100" -"origin" "1384 1184 136" -"classname" "light" -} -{ -"light" "100" -"origin" "1608 1048 136" -"classname" "light" -} -{ -"classname" "light" -"origin" "1384 1048 136" -"light" "100" -} -{ -"classname" "light" -"origin" "1200 1148 92" -"light" "150" -} -{ -"light" "150" -"origin" "876 -184 367" -"classname" "light" -} -{ -"classname" "light" -"origin" "768 -128 384" -"light" "200" -} -{ -"classname" "light" -"origin" "1104 388 552" -"light" "250" -} -{ -"light" "200" -"origin" "1392 240 384" -"classname" "light" -} -{ -"classname" "light" -"origin" "1392 80 368" -"light" "200" -} -{ -"classname" "light" -"origin" "1272 400 367" -"light" "150" -} -{ -"light" "150" -"origin" "920 400 367" -"classname" "light" -} -{ -"classname" "light" -"origin" "816 208 368" -"light" "200" -} -{ -"classname" "light" -"origin" "800 24 368" -"light" "200" -} -{ -"classname" "light" -"origin" "800 376 385" -"light" "150" -} -{ -"light" "150" -"origin" "1400 400 385" -"classname" "light" -} -{ -"classname" "path_corner" -"origin" "1104 336 300" -"target" "t126" -"targetname" "t127" -} -{ -"origin" "1104 24 300" -"classname" "path_corner" -"targetname" "t126" -"target" "t127" -} -{ -"classname" "monster_army" -"origin" "1104 424 316" -"angle" "270" -"target" "t127" -} -{ -"targetname" "t128" -"origin" "1392 240 308" -"classname" "info_null" -} -{ -"light" "300" -"target" "t128" -"origin" "1392 240 376" -"classname" "light" -} -{ -"targetname" "t129" -"angle" "0" -"origin" "552 -128 320" -"classname" "monster_army" -} -{ -"target" "t129" -"classname" "trigger_once" -"model" "*45" -} -{ -"sounds" "1" -"classname" "trigger_secret" -"model" "*46" -} -{ -"sounds" "1" -"classname" "trigger_secret" -"model" "*47" -} -{ -"classname" "light" -"origin" "1104 24 536" -"light" "350" -} -{ -"spawnflags" "1" -"classname" "func_door_secret" -"angle" "270" -"model" "*48" -} -{ -"light" "200" -"origin" "1680 1552 320" -"classname" "light" -} -{ -"classname" "light" -"origin" "1312 1552 320" -"light" "200" -} -{ -"classname" "item_spikes" -"origin" "1480 1104 68" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "1760 -568 256" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "1232 -1200 416" -} -{ -"message" "This door is opened elsewhere..." -"classname" "func_door" -"sounds" "3" -"angle" "180" -"wait" "-1" -"targetname" "t122" -"speed" "35" -"spawnflags" "2048" -"model" "*49" -} -{ -"classname" "func_door" -"angle" "0" -"wait" "-1" -"speed" "30" -"spawnflags" "2048" -"model" "*50" -} -{ -"classname" "light" -"origin" "1496 1600 296" -"light" "150 " -} -{ -"light" "150" -"origin" "1568 1664 296" -"classname" "light" -} -{ -"classname" "light" -"origin" "1424 1664 296" -"light" "150" -} -{ -"classname" "light" -"origin" "1328 1424 296" -"light" "200" -} -{ -"light" "250" -"origin" "1696 1416 296" -"classname" "light" -} -{ -"classname" "monster_army" -"origin" "1592 1296 200" -"angle" "270" -} -{ -"spawnflags" "768" -"classname" "monster_demon1" -"origin" "-96 576 320" -"angle" "270" -"targetname" "t73" -"target" "t143" -} -{ -"classname" "path_corner" -"origin" "1392 416 304" -"targetname" "t131" -"target" "t130" -"spawnflags" "768" -} -{ -"origin" "1392 296 304" -"classname" "path_corner" -"targetname" "t130" -"target" "t131" -"spawnflags" "768" -} -{ -"classname" "monster_army" -"origin" "1392 352 320" -"angle" "270" -"target" "t130" -"spawnflags" "768" -} -{ -"target" "t132" -"targetname" "t133" -"origin" "296 -328 304" -"classname" "path_corner" -} -{ -"target" "t133" -"targetname" "t132" -"classname" "path_corner" -"origin" "472 -416 304" -} -{ -"spawnflags" "1" -"target" "t132" -"angle" "90" -"origin" "472 -456 320" -"classname" "monster_army" -} -{ -"spawnflags" "1" -"targetname" "t89" -"angle" "135" -"origin" "1712 -784 376" -"classname" "monster_army" -} -{ -"target" "t135" -"spawnflags" "256" -"targetname" "t134" -"origin" "400 -1128 416" -"classname" "path_corner" -} -{ -"target" "t134" -"spawnflags" "256" -"targetname" "t135" -"classname" "path_corner" -"origin" "400 -1248 416" -} -{ -"target" "t134" -"spawnflags" "257" -"angle" "90" -"origin" "408 -1208 432" -"classname" "monster_army" -} -{ -"targetname" "t101" -"angle" "90" -"origin" "-288 -24 488" -"classname" "monster_army" -"spawnflags" "768" -} -{ -"spawnflags" "768" -"targetname" "t101" -"classname" "monster_army" -"origin" "136 -128 488" -"angle" "90" -} -{ -"spawnflags" "1792" -"origin" "-264 -24 464" -"classname" "item_rockets" -} -{ -"spawnflags" "2048" -"origin" "-240 -8 464" -"classname" "item_spikes" -} -{ -"classname" "monster_ogre" -"origin" "-304 -304 488" -"angle" "225" -"spawnflags" "769" -} -{ -"classname" "func_wall" -"spawnflags" "768" -"model" "*51" -} -{ -"classname" "trap_spikeshooter" -"origin" "2048 -48 332" -"angle" "270" -"spawnflags" "769" -"targetname" "t121" -} -{ -"origin" "2048 -476 332" -"classname" "info_null" -"targetname" "t136" -} -{ -"style" "32" -"origin" "2048 -456 336" -"classname" "light" -"light" "800" -"spawnflags" "1" -"target" "t136" -"targetname" "t137" -} -{ -"style" "32" -"classname" "trigger_once" -"spawnflags" "768" -"target" "t137" -"model" "*52" -} -{ -"classname" "monster_wizard" -"origin" "672 328 384" -"angle" "180" -"spawnflags" "768" -"targetname" "t138" -} -{ -"classname" "trigger_once" -"target" "t138" -"model" "*53" -} -{ -"style" "32" -"classname" "light" -"origin" "2004 -52 332" -"light" "100" -"spawnflags" "1" -"targetname" "t137" -} -{ -"classname" "item_shells" -"origin" "1416 224 300" -"spawnflags" "768" -} -{ -"classname" "path_corner" -"origin" "-344 136 304" -"targetname" "t139" -"target" "t140" -"spawnflags" "768" -} -{ -"origin" "168 128 304" -"classname" "path_corner" -"target" "t139" -"targetname" "t140" -"spawnflags" "768" -} -{ -"classname" "monster_ogre" -"origin" "-400 168 320" -"spawnflags" "768" -"target" "t139" -} -{ -"classname" "trap_spikeshooter" -"origin" "2120 -256 332" -"angle" "180" -"spawnflags" "769" -"targetname" "t121" -} -{ -"classname" "trap_spikeshooter" -"origin" "1944 -456 332" -"targetname" "t121" -"angle" "90" -"spawnflags" "769" -} -{ -"classname" "item_spikes" -"origin" "-336 -80 470" -"spawnflags" "768" -} -{ -"targetname" "t143" -"classname" "trigger_teleport" -"target" "t142" -"spawnflags" "2" -"model" "*54" -} -{ -"targetname" "t143" -"classname" "trigger_teleport" -"target" "t141" -"spawnflags" "2" -"model" "*55" -} -{ -"classname" "monster_demon1" -"origin" "32 840 359" -"angle" "270" -"targetname" "t143" -"spawnflags" "768" -} -{ -"angle" "270" -"origin" "-192 840 359" -"classname" "monster_demon1" -"targetname" "t143" -"spawnflags" "768" -} -{ -"classname" "info_teleport_destination" -"origin" "80 216 303" -"angle" "270" -"targetname" "t141" -} -{ -"angle" "270" -"origin" "-264 224 303" -"classname" "info_teleport_destination" -"targetname" "t142" -} -{ -"wait" "-1" -"target" "t53" -"health" "1" -"classname" "func_button" -"model" "*56" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "1408 1296 200" -"classname" "monster_army" -} -{ -"classname" "item_shells" -"origin" "772 -856 420" -"spawnflags" "768" -} -{ -"spawnflags" "1792" -"origin" "1248 -1128 420" -"classname" "weapon_grenadelauncher" -} -{ -"spawnflags" "1793" -"origin" "864 -312 440" -"classname" "item_rockets" -} -{ -"classname" "trigger_once" -"message" "Pass through the arch to exit..." -"model" "*57" -} -{ -"mangle" "20 300 0" -"classname" "info_intermission" -"origin" "-224 424 512" -} -{ -"mangle" "20 45 0" -"origin" "1048 -744 488" -"classname" "info_intermission" -} -{ -"mangle" "20 270 0" -"origin" "1104 424 528" -"classname" "info_intermission" -} -{ -"mangle" "20 45 0" -"origin" "1240 984 416" -"classname" "info_intermission" -} -{ -"sounds" "1" -"speed" "20" -"classname" "func_button" -"angle" "0" -"wait" "-1" -"target" "t144" -"model" "*58" -} -{ -"classname" "light" -"origin" "400 -1392 480" -"light" "150" -} -{ -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"speed" "20" -"sounds" "1" -"targetname" "t144" -"model" "*59" -} -{ -"classname" "trigger_secret" -"model" "*60" -} -{ -"classname" "item_artifact_super_damage" -"origin" "400 -1360 432" -} -{ -"classname" "item_spikes" -"origin" "808 -632 192" -"spawnflags" "2049" -} -{ -"classname" "item_health" -"origin" "924 -632 192" -"spawnflags" "2048" -} -{ -"classname" "weapon_supernailgun" -"origin" "880 -616 192" -"spawnflags" "1792" -} -{ -"classname" "ambient_drip" -"origin" "842 978 344" -} -{ -"classname" "ambient_drip" -"origin" "546 330 400" -} -{ -"classname" "info_player_coop" -"origin" "1608 1664 264" -"angle" "270" -} -{ -"angle" "270" -"origin" "1392 1664 264" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "1496 1560 264" -"angle" "270" -} -{ -"spawnflags" "256" -"angle" "270" -"origin" "232 -176 320" -"classname" "monster_ogre" -} -{ -"spawnflags" "1280" -"angle" "225" -"origin" "-368 -312 480" -"classname" "monster_knight" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*61" -} -{ -"origin" "1810 274 200" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "1802 -102 200" -} -{ -"origin" "2050 -214 200" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "2002 -390 200" -} -{ -"origin" "1738 -398 200" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "1346 -398 200" -} -{ -"origin" "1138 -542 200" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "882 -494 200" -} -{ -"classname" "ambient_swamp1" -"origin" "1722 1090 176" -} -{ -"origin" "1242 1090 176" -"classname" "ambient_swamp1" -} -{ -"classname" "ambient_swamp2" -"origin" "1106 642 192" -} -{ -"origin" "1346 242 192" -"classname" "ambient_swamp2" -} -{ -"classname" "ambient_swamp1" -"origin" "866 210 192" -} -{ -"classname" "ambient_swamp1" -"origin" "1802 90 192" -} -{ -"origin" "1546 -398 192" -"classname" "ambient_swamp1" -} -{ -"classname" "ambient_swamp2" -"origin" "2042 -310 192" -} -{ -"origin" "1178 -398 192" -"classname" "ambient_swamp2" -} -{ -"classname" "ambient_swamp2" -"origin" "1202 -678 192" -} diff --git a/Misc/pak/maps/e1m4.diff b/Misc/pak/maps/e1m4.diff new file mode 100644 index 000000000..7e420ff89 --- /dev/null +++ b/Misc/pak/maps/e1m4.diff @@ -0,0 +1,30 @@ +--- e1m4.ent ++++ e1m4@958e.ent +@@ -2143,12 +2143,13 @@ + { + "classname" "func_door_secret" + "angle" "0" + "spawnflags" "1" + "targetname" "t91" + "model" "*53" ++"t_length" "73" // svdijk -- added to prevent z-fighting + } + { + "classname" "func_button" + "angle" "-2" + "wait" "-1" + "target" "t92" +@@ -2202,12 +2203,13 @@ + { + "spawnflags" "3" + "angle" "0" + "classname" "func_door_secret" + "targetname" "t91" + "model" "*60" ++"t_length" "73" // svdijk -- added to prevent z-fighting + } + { + "light" "150" + "origin" "680 -256 1144" + "classname" "light" + } diff --git a/Misc/pak/maps/e1m4.ent.orig b/Misc/pak/maps/e1m4.ent.orig deleted file mode 100644 index a710d6c76..000000000 --- a/Misc/pak/maps/e1m4.ent.orig +++ /dev/null @@ -1,3169 +0,0 @@ -{ -"message" "the Grisly Grotto" -"worldtype" "0" -"classname" "worldspawn" -"wad" "gfx/wizard.wad" -"sounds" "5" -} -{ -"classname" "light" -"origin" "464 480 1656" -"light" "300" -} -{ -"light" "400" -"origin" "712 296 1512" -"classname" "light" -} -{ -"sounds" "3" -"angle" "180" -"classname" "func_door" -"model" "*1" -} -{ -"angle" "0" -"classname" "func_door" -"model" "*2" -} -{ -"classname" "light_flame_small_yellow" -"origin" "560 -112 1374" -} -{ -"origin" "848 -112 1374" -"classname" "light_flame_small_yellow" -} -{ -"origin" "760 656 1536" -"classname" "light" -} -{ -"light" "400" -"origin" "834 498 1040" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "944 728 1456" -} -{ -"classname" "light_flame_small_yellow" -"origin" "1016 80 998" -} -{ -"origin" "392 80 998" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light" -"origin" "680 1224 516" -"light" "200" -} -{ -"light" "200" -"origin" "704 992 516" -"classname" "light" -} -{ -"light" "200" -"origin" "696 1608 628" -"classname" "light" -} -{ -"origin" "704 1368 588" -"classname" "light" -} -{ -"origin" "816 1616 444" -"classname" "light" -} -{ -"classname" "light" -"origin" "712 1728 444" -} -{ -"origin" "592 1608 444" -"classname" "light" -} -{ -"classname" "light" -"origin" "624 1096 444" -} -{ -"light" "300" -"origin" "432 1328 816" -"classname" "light" -} -{ -"classname" "light" -"origin" "696 1112 816" -"light" "300" -} -{ -"classname" "light" -"origin" "704 -80 960" -"light" "200" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "818 18 948" -"light" "200" -} -{ -"origin" "586 18 948" -"classname" "light_torch_small_walltorch" -"light" "200" -} -{ -"light" "200" -"origin" "688 496 880" -"classname" "light" -} -{ -"origin" "489 483 1356" -"classname" "light_flame_large_yellow" -} -{ -"light" "200" -"origin" "704 -120 1360" -"classname" "light" -} -{ -"classname" "light" -"origin" "1216 936 1560" -"light" "200" -} -{ -"origin" "1294 826 1576" -"classname" "light_flame_large_yellow" -} -{ -"sounds" "1" -"targetname" "t1" -"wait" "-1" -"angle" "180" -"classname" "func_door" -"model" "*3" -} -{ -"angle" "0" -"wait" "-1" -"classname" "func_door" -"model" "*4" -} -{ -"target" "t1" -"classname" "trigger_once" -"model" "*5" -} -{ -"map" "e1m5" -"classname" "trigger_changelevel" -"model" "*6" -} -{ -"wait" "-1" -"angle" "0" -"classname" "func_door" -"speed" "50" -"model" "*7" -} -{ -"classname" "info_player_start" -"origin" "-256 2272 1240" -"angle" "270" -} -{ -"targetname" "t23" -"classname" "func_door" -"angle" "180" -"wait" "-1" -"speed" "50" -"sounds" "3" -"model" "*8" -} -{ -"classname" "light" -"origin" "696 704 820" -} -{ -"classname" "light" -"origin" "704 776 672" -"light" "200" -} -{ -"classname" "light" -"origin" "360 904 520" -"light" "200" -} -{ -"origin" "704 856 400" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "944 880 416" -"light" "150" -} -{ -"origin" "1056 1176 424" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "1096 1408 360" -} -{ -"classname" "light" -"origin" "416 1696 360" -} -{ -"origin" "328 1368 360" -"classname" "light" -"light" "200" -} -{ -"light" "200 " -"classname" "light" -"origin" "696 752 896" -} -{ -"light" "250" -"origin" "798 1850 1024" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "642 1850 1024" -"light" "250" -} -{ -"light" "200 " -"origin" "700 1364 952" -"classname" "light" -} -{ -"classname" "light_flame_large_yellow" -"origin" "1094 1494 1064" -} -{ -"origin" "324 1104 1064" -"classname" "light_flame_large_yellow" -} -{ -"light" "200 " -"origin" "704 1660 952" -"classname" "light" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "180" -"wait" "-1" -"targetname" "t2" -"model" "*9" -} -{ -"sounds" "3" -"classname" "func_door" -"wait" "-1" -"angle" "0" -"targetname" "t4" -"model" "*10" -} -{ -"classname" "trigger_once" -"targetname" "t4" -"target" "t7" -"model" "*11" -} -{ -"classname" "trigger_once" -"targetname" "t2" -"target" "t7" -"model" "*12" -} -{ -"dmg" "90" -"speed" "200" -"classname" "func_train" -"target" "t5" -"targetname" "t8" -"model" "*13" -} -{ -"classname" "path_corner" -"origin" "-359 1528 1316" -"targetname" "t5" -"target" "t6" -} -{ -"classname" "path_corner" -"origin" "-359 1528 880" -"targetname" "t6" -"target" "t5" -"wait" "-1" -} -{ -"classname" "trigger_counter" -"targetname" "t7" -"target" "t8" -"count" "2" -"model" "*14" -} -{ -"targetname" "t11" -"origin" "-96 1640 1256" -"classname" "info_null" -} -{ -"targetname" "t9" -"origin" "-416 1640 1256" -"classname" "info_null" -} -{ -"light" "400" -"target" "t9" -"origin" "-396 1640 1256" -"classname" "light" -} -{ -"light" "400" -"target" "t11" -"origin" "-116 1640 1256" -"classname" "light" -} -{ -"classname" "light" -"origin" "-328 1564 1532" -} -{ -"classname" "light_flame_small_yellow" -"origin" "-88 1640 1514" -} -{ -"origin" "-424 1640 1514" -"classname" "light_flame_small_yellow" -} -{ -"origin" "-248 1464 1154" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light_flame_small_yellow" -"origin" "-256 1808 1046" -} -{ -"light" "200" -"origin" "-164 1732 1268" -"classname" "light" -} -{ -"classname" "light" -"origin" "-348 1732 1268" -"light" "200" -} -{ -"light" "150" -"origin" "-248 1500 1056" -"classname" "light" -} -{ -"light" "150" -"origin" "-256 1772 956" -"classname" "light" -} -{ -"classname" "light" -"origin" "-128 1636 920" -"light" "150" -} -{ -"light" "150" -"origin" "-124 1640 920" -"classname" "light" -} -{ -"classname" "light" -"origin" "-172 1524 920" -"light" "150" -} -{ -"light" "150" -"origin" "-284 1516 920" -"classname" "light" -} -{ -"classname" "light" -"origin" "-360 1580 920" -"light" "150" -} -{ -"light" "75" -"origin" "-360 1700 920" -"classname" "light" -} -{ -"classname" "light" -"origin" "72 1632 928" -"light" "125" -} -{ -"light" "150" -"origin" "80 1488 928" -"classname" "light" -} -{ -"classname" "light_flame_large_yellow" -"origin" "158 1308 1064" -} -{ -"classname" "light" -"origin" "-192 1688 1380" -"light" "100" -} -{ -"light" "100" -"origin" "-192 1592 1380" -"classname" "light" -} -{ -"classname" "light" -"origin" "-320 1592 1380" -"light" "100" -} -{ -"light" "100" -"origin" "-320 1688 1380" -"classname" "light" -} -{ -"classname" "light" -"origin" "-384 1640 1452" -"light" "125" -} -{ -"classname" "light" -"origin" "-112 1640 1452" -"light" "125" -} -{ -"light" "200" -"origin" "-248 1504 1336" -"classname" "light" -} -{ -"classname" "light" -"origin" "-128 1640 1336" -"light" "200" -} -{ -"light" "200" -"origin" "-384 1640 1336" -"classname" "light" -} -{ -"classname" "light" -"origin" "696 1608 816" -"light" "300" -} -{ -"light" "200" -"classname" "light" -"origin" "888 1328 424" -} -{ -"classname" "light" -"origin" "160 1352 960" -"light" "150" -} -{ -"light" "150" -"origin" "368 1104 1000" -"classname" "light" -} -{ -"classname" "light" -"origin" "1048 1504 1000" -"light" "150" -} -{ -"classname" "light" -"origin" "992 992 1048" -"light" "150" -} -{ -"classname" "light" -"origin" "48 1384 1008" -"light" "100" -} -{ -"light" "150" -"origin" "1080 1144 1048" -"classname" "light" -} -{ -"classname" "light" -"origin" "968 824 976" -"light" "150" -} -{ -"classname" "light" -"origin" "896 1328 1000" -"light" "150" -} -{ -"classname" "light" -"origin" "368 1616 1000" -"light" "175" -} -{ -"classname" "light" -"origin" "256 1496 824" -"light" "150" -} -{ -"light" "150" -"origin" "256 1352 824" -"classname" "light" -} -{ -"classname" "light" -"origin" "856 1368 536" -"light" "200" -} -{ -"light" "150" -"origin" "552 1360 536" -"classname" "light" -} -{ -"classname" "light" -"origin" "872 1552 1056" -"light" "150" -} -{ -"classname" "light" -"origin" "1032 1056 904" -"light" "150" -} -{ -"light" "150" -"origin" "1080 1184 904" -"classname" "light" -} -{ -"classname" "light" -"origin" "864 848 904" -"light" "150" -} -{ -"classname" "light" -"origin" "312 1496 1016" -"light" "175" -} -{ -"light" "200" -"origin" "704 1368 808" -"classname" "light" -} -{ -"light" "150" -"origin" "464 816 904" -"classname" "light" -} -{ -"light" "200" -"origin" "944 888 800" -"classname" "light" -} -{ -"light" "150" -"origin" "888 1112 728" -"classname" "light" -} -{ -"light" "175" -"origin" "1008 1504 728" -"classname" "light" -} -{ -"light" "200" -"origin" "720 1848 1200" -"classname" "light" -} -{ -"light" "200" -"origin" "704 888 672" -"classname" "light" -} -{ -"light" "175" -"origin" "512 1456 1040" -"classname" "light" -} -{ -"light" "150" -"origin" "440 840 380" -"classname" "light" -} -{ -"light" "150" -"origin" "720 1848 1028" -"classname" "light" -} -{ -"light" "150" -"origin" "720 1936 1024" -"classname" "light" -} -{ -"origin" "544 2128 984" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"origin" "712 1912 576" -"classname" "light" -} -{ -"light" "300" -"origin" "720 2544 856" -"classname" "light" -} -{ -"light" "200" -"origin" "888 2048 592" -"classname" "light" -} -{ -"origin" "704 2496 1128" -"classname" "light" -} -{ -"origin" "512 2048 976" -"classname" "light" -"light" "150" -} -{ -"origin" "952 2328 528" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "700 2760 808" -"light" "200" -} -{ -"classname" "light" -"origin" "700 2800 616" -"light" "200" -} -{ -"classname" "light" -"origin" "584 2780 584" -"light" "175" -} -{ -"light" "175" -"origin" "808 2780 584" -"classname" "light" -} -{ -"sounds" "3" -"wait" "-1" -"targetname" "t29" -"classname" "func_door" -"angle" "270" -"model" "*15" -} -{ -"message" "This door is opened elsewhere..." -"wait" "-1" -"classname" "func_door" -"angle" "90" -"model" "*16" -} -{ -"classname" "light" -"origin" "424 2304 1000" -"light" "200" -} -{ -"light" "300" -"origin" "696 2880 1062" -"classname" "light_flame_small_yellow" -} -{ -"light" "200" -"classname" "light" -"origin" "864 2128 984" -} -{ -"classname" "light_flame_large_yellow" -"origin" "702 2154 1228" -"light" "0" -} -{ -"classname" "light" -"origin" "832 2008 1136" -"light" "200" -} -{ -"classname" "light" -"origin" "584 2008 1136" -"light" "200" -} -{ -"light" "200" -"origin" "272 2016 1136" -"classname" "light" -} -{ -"classname" "light" -"origin" "272 2320 1136" -"light" "150" -} -{ -"light" "150" -"origin" "1104 2408 984" -"classname" "light" -} -{ -"sounds" "2" -"classname" "func_plat" -"wait" "4" -"model" "*17" -} -{ -"classname" "light" -"origin" "700 2844 996" -"light" "200" -} -{ -"classname" "light" -"origin" "704 2216 1252" -} -{ -"origin" "936 2304 1252" -"classname" "light" -} -{ -"classname" "light" -"origin" "936 2536 1252" -} -{ -"light" "300" -"classname" "light" -"origin" "488 2536 1252" -} -{ -"origin" "488 2304 1252" -"classname" "light" -"light" "300" -} -{ -"light" "0" -"origin" "998 2306 1228" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "998 2534 1228" -"light" "0" -} -{ -"light" "0" -"origin" "426 2534 1228" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "426 2306 1228" -"light" "0" -} -{ -"classname" "light" -"origin" "704 2152 984" -"light" "200" -} -{ -"classname" "light_flame_small_yellow" -"origin" "1160 2400 1038" -"light" "250" -} -{ -"origin" "840 2536 630" -"classname" "light_flame_small_yellow" -"light" "250" -} -{ -"classname" "light_flame_small_yellow" -"origin" "584 2544 630" -"light" "250" -} -{ -"light" "250" -"origin" "408 2304 694" -"classname" "light_flame_small_yellow" -} -{ -"light" "200" -"classname" "light" -"origin" "960 2632 528" -} -{ -"classname" "light" -"origin" "960 2480 528" -"light" "150" -} -{ -"classname" "light" -"origin" "456 2304 624" -"light" "175" -} -{ -"classname" "light" -"origin" "704 2416 576" -"light" "250" -} -{ -"light" "150" -"origin" "728 2184 528" -"classname" "light" -} -{ -"classname" "light" -"origin" "512 2176 528" -"light" "150" -} -{ -"classname" "light" -"origin" "832 2336 656" -"light" "175" -} -{ -"light" "175" -"origin" "592 2336 656" -"classname" "light" -} -{ -"classname" "light" -"origin" "808 2584 576" -"light" "150" -} -{ -"light" "150" -"origin" "616 2576 576" -"classname" "light" -} -{ -"classname" "light_flame_small_yellow" -"origin" "488 2712 694" -"light" "250" -} -{ -"classname" "light" -"origin" "488 2624 608" -"light" "175" -} -{ -"classname" "light" -"origin" "480 2464 608" -"light" "175" -} -{ -"light" "250" -"origin" "184 2184 1038" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light_flame_small_yellow" -"origin" "512 2096 1038" -"light" "250" -} -{ -"classname" "light" -"origin" "224 2184 976" -"light" "150" -} -{ -"classname" "light" -"origin" "848 2024 992" -"light" "200" -} -{ -"classname" "light" -"origin" "256 1992 1000" -"light" "150" -} -{ -"classname" "light" -"origin" "272 2376 1000" -"light" "200" -} -{ -"classname" "light" -"origin" "1112 2208 1032" -"light" "150" -} -{ -"light" "0" -"origin" "698 2860 1228" -"classname" "light_flame_large_yellow" -} -{ -"origin" "700 2808 1252" -"classname" "light" -} -{ -"light" "250" -"origin" "472 2632 1062" -"classname" "light" -} -{ -"classname" "light" -"origin" "952 2632 1062" -"light" "250" -} -{ -"light" "150" -"origin" "952 2424 894" -"classname" "light" -} -{ -"classname" "light" -"origin" "480 2424 894" -"light" "150" -} -{ -"light" "150" -"origin" "896 2296 966" -"classname" "light" -} -{ -"classname" "light" -"origin" "704 2304 966" -"light" "150" -} -{ -"light" "150" -"origin" "552 2304 966" -"classname" "light" -} -{ -"light" "250" -"origin" "704 2184 406" -"classname" "light" -} -{ -"light" "150" -"origin" "712 2000 406" -"classname" "light" -} -{ -"light" "200" -"origin" "504 2224 400" -"classname" "light" -} -{ -"light" "200" -"origin" "960 2576 400" -"classname" "light" -} -{ -"light" "150" -"origin" "960 2400 400" -"classname" "light" -} -{ -"light" "150" -"origin" "808 1112 592" -"classname" "light" -} -{ -"classname" "light" -"origin" "600 1112 592" -"light" "150" -} -{ -"light" "175" -"origin" "1016 128 936" -"classname" "light" -} -{ -"classname" "light" -"origin" "392 128 936" -"light" "175" -} -{ -"light" "150" -"origin" "848 -64 1304" -"classname" "light" -} -{ -"classname" "light" -"origin" "560 -64 1304" -"light" "150" -} -{ -"light" "175" -"origin" "1248 832 1496" -"classname" "light" -} -{ -"light" "150" -"origin" "1096 872 1496" -"classname" "light" -} -{ -"light" "150" -"origin" "896 2208 976" -"classname" "light" -} -{ -"classname" "light" -"origin" "1096 200 1512" -"light" "350" -} -{ -"light" "350" -"origin" "264 192 1512" -"classname" "light" -} -{ -"light" "175" -"origin" "488 448 1264" -"classname" "light" -} -{ -"origin" "1048 728 1456" -"classname" "light" -"light" "200" -} -{ -"light" "125" -"origin" "1328 928 1448" -"classname" "light" -} -{ -"light" "225" -"origin" "696 672 1320" -"classname" "light" -} -{ -"origin" "816 -56 1640" -"classname" "light" -} -{ -"classname" "light" -"origin" "584 -56 1640" -} -{ -"light" "175" -"origin" "880 96 1376" -"classname" "light" -} -{ -"classname" "light" -"origin" "528 96 1376" -"light" "175" -} -{ -"light" "200" -"origin" "960 344 1072" -"classname" "light" -} -{ -"classname" "light" -"origin" "1120 264 1072" -"light" "200" -} -{ -"light" "175" -"origin" "1208 96 1016" -"classname" "light" -} -{ -"light" "175" -"origin" "1024 360 968" -"classname" "light" -} -{ -"classname" "light" -"origin" "328 336 968" -"light" "150" -} -{ -"classname" "light" -"origin" "416 424 1072" -"light" "200" -} -{ -"light" "200" -"origin" "296 256 1072" -"classname" "light" -} -{ -"light" "150" -"origin" "704 48 1040" -"classname" "light" -} -{ -"light" "175" -"origin" "384 464 976" -"classname" "light" -} -{ -"classname" "light" -"origin" "224 264 976" -"light" "150" -} -{ -"light" "150" -"origin" "952 2192 416" -"classname" "light" -} -{ -"classname" "light" -"origin" "1040 -464 1016" -"light" "150" -} -{ -"sounds" "2" -"spawnflags" "1" -"classname" "func_plat" -"model" "*18" -} -{ -"light" "250" -"origin" "1072 -272 1262" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light" -"origin" "1024 -272 1200" -"light" "150" -} -{ -"light" "200" -"origin" "624 -240 1328" -"classname" "light" -} -{ -"light" "175" -"origin" "1080 -624 1168" -"classname" "light" -} -{ -"origin" "456 -576 1230" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light" -"origin" "504 -576 1168" -"light" "175" -} -{ -"origin" "624 -448 924" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "624 -704 924" -} -{ -"light" "125" -"origin" "664 -448 880" -"classname" "light" -} -{ -"classname" "light" -"origin" "624 -488 880" -"light" "125" -} -{ -"light" "125" -"origin" "584 -448 880" -"classname" "light" -} -{ -"classname" "light" -"origin" "624 -408 880" -"light" "125" -} -{ -"light" "125" -"origin" "624 -664 880" -"classname" "light" -} -{ -"classname" "light" -"origin" "664 -704 880" -"light" "125" -} -{ -"light" "125" -"origin" "624 -744 880" -"classname" "light" -} -{ -"classname" "light" -"origin" "584 -704 880" -"light" "125" -} -{ -"light" "250" -"origin" "296 -96 968" -"classname" "light" -} -{ -"light" "250" -"origin" "1112 -96 968" -"classname" "light" -} -{ -"light" "175" -"origin" "1056 -224 968" -"classname" "light" -} -{ -"light" "500" -"origin" "-264 2120 1504" -"classname" "light" -} -{ -"spawnflags" "2064" -"angle" "0" -"classname" "func_door" -"wait" "-1" -"model" "*19" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "180" -"spawnflags" "2064" -"wait" "-1" -"model" "*20" -} -{ -"light" "200" -"origin" "704 32 952" -"classname" "light" -} -{ -"target" "t101" -"spawnflags" "256" -"targetname" "t23" -"angle" "90" -"origin" "-248 1560 1224" -"classname" "monster_wizard" -} -{ -"target" "t23" -"classname" "trigger_once" -"model" "*21" -} -{ -"origin" "-280 1560 1348" -"classname" "item_armor2" -} -{ -"origin" "-488 2112 1220" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "-488 2064 1220" -} -{ -"spawnflags" "1536" -"origin" "-272 1784 1156" -"classname" "item_shells" -} -{ -"spawnflags" "256" -"target" "t25" -"targetname" "t24" -"origin" "888 1640 1028" -"classname" "path_corner" -} -{ -"spawnflags" "256" -"target" "t24" -"targetname" "t25" -"classname" "path_corner" -"origin" "624 1264 1028" -} -{ -"spawnflags" "256" -"target" "t24" -"origin" "928 1672 1028" -"classname" "monster_wizard" -} -{ -"spawnflags" "2304" -"target" "t26" -"classname" "trigger_once" -"model" "*22" -} -{ -"target" "t27" -"targetname" "t28" -"origin" "568 2040 928" -"classname" "path_corner" -} -{ -"target" "t28" -"targetname" "t27" -"classname" "path_corner" -"origin" "368 2044 928" -} -{ -"target" "t27" -"origin" "472 2040 944" -"classname" "monster_ogre" -"spawnflags" "1" -} -{ -"sounds" "2" -"target" "t29" -"wait" "-1" -"angle" "90" -"classname" "func_button" -"model" "*23" -} -{ -"sounds" "3" -"angle" "180" -"classname" "func_door" -"model" "*24" -} -{ -"angle" "0" -"classname" "func_door" -"model" "*25" -} -{ -"light" "175" -"origin" "1112 2520 964" -"classname" "light" -} -{ -"origin" "104 1308 892" -"classname" "item_health" -} -{ -"spawnflags" "2048" -"origin" "704 1344 936" -"classname" "item_key1" -"sounds" "1" -} -{ -"target" "t34" -"angle" "180" -"origin" "920 2040 544" -"classname" "monster_ogre" -"spawnflags" "1" -} -{ -"target" "t35" -"targetname" "t34" -"origin" "864 2044 528" -"classname" "path_corner" -} -{ -"target" "t37" -"targetname" "t35" -"classname" "path_corner" -"origin" "704 2048 528" -} -{ -"target" "t34" -"targetname" "t36" -"origin" "704 2048 528" -"classname" "path_corner" -} -{ -"target" "t36" -"targetname" "t37" -"classname" "path_corner" -"origin" "704 1808 528" -} -{ -"targetname" "t38" -"angle" "270" -"origin" "456 2476 544" -"classname" "monster_ogre" -} -{ -"target" "t38" -"classname" "trigger_once" -"model" "*26" -} -{ -"targetname" "t29" -"angle" "0" -"origin" "336 2272 952" -"classname" "monster_knight" -"spawnflags" "768" -} -{ -"targetname" "t39" -"spawnflags" "1" -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"sounds" "1" -"model" "*27" -} -{ -"targetname" "t39" -"angle" "270" -"origin" "712 2540 448" -"classname" "monster_ogre" -} -{ -"target" "t39" -"classname" "trigger_once" -"model" "*28" -} -{ -"classname" "light" -"origin" "712 2544 440" -"light" "200" -} -{ -"classname" "item_health" -"origin" "1064 2184 920" -"spawnflags" "1024" -} -{ -"spawnflags" "1" -"origin" "1128 2184 920" -"classname" "item_health" -} -{ -"classname" "item_spikes" -"origin" "816 2840 920" -} -{ -"origin" "816 2800 920" -"classname" "item_spikes" -} -{ -"spawnflags" "256" -"classname" "monster_wizard" -"origin" "1656 1496 968" -"angle" "180" -"target" "t41" -} -{ -"spawnflags" "2" -"classname" "trigger_teleport" -"target" "t40" -"targetname" "t39" -"model" "*29" -} -{ -"classname" "info_teleport_destination" -"origin" "984 1496 1000" -"angle" "180" -"targetname" "t40" -} -{ -"spawnflags" "256" -"classname" "path_corner" -"origin" "912 1496 1000" -"targetname" "t41" -"target" "t42" -} -{ -"spawnflags" "256" -"origin" "528 1368 1000" -"classname" "path_corner" -"targetname" "t42" -"target" "t41" -} -{ -"classname" "item_health" -"origin" "408 2640 520" -} -{ -"classname" "item_shells" -"origin" "456 2672 520" -"spawnflags" "1" -} -{ -"angle" "0" -"origin" "80 864 968" -"classname" "monster_wizard" -"target" "t44" -} -{ -"targetname" "t119" -"spawnflags" "2" -"classname" "trigger_teleport" -"target" "t45" -"model" "*30" -} -{ -"classname" "info_teleport_destination" -"origin" "432 856 952" -"angle" "45" -"targetname" "t45" -} -{ -"classname" "path_corner" -"origin" "496 872 952" -"target" "t43" -"targetname" "t44" -} -{ -"origin" "872 1056 952" -"classname" "path_corner" -"targetname" "t43" -"target" "t44" -} -{ -"classname" "trigger_once" -"spawnflags" "1792" -"target" "t39" -"model" "*31" -} -{ -"spawnflags" "1024" -"classname" "monster_knight" -"origin" "1168 56 904" -"angle" "135" -"target" "t49" -"targetname" "t67" -} -{ -"classname" "monster_ogre" -"origin" "1800 224 920" -"angle" "180" -"target" "t116" -"spawnflags" "256" -} -{ -"classname" "func_door" -"angle" "-1" -"wait" "-1" -"targetname" "t49" -"lip" "-24" -"model" "*32" -} -{ -"wait" "-1" -"angle" "-1" -"classname" "func_door" -"spawnflags" "1" -"targetname" "t39" -"lip" "-24" -"model" "*33" -} -{ -"classname" "func_door" -"angle" "-1" -"wait" "-1" -"targetname" "t29" -"lip" "-24" -"model" "*34" -} -{ -"spawnflags" "2" -"classname" "trigger_teleport" -"target" "t46" -"model" "*35" -} -{ -"classname" "info_teleport_destination" -"origin" "1104 232 880" -"angle" "180" -"targetname" "t46" -} -{ -"classname" "path_corner" -"origin" "1064 256 880" -"target" "t47" -"targetname" "t48" -"spawnflags" "256" -} -{ -"origin" "312 232 880" -"classname" "path_corner" -"targetname" "t47" -"target" "t48" -"spawnflags" "256" -} -{ -"classname" "info_teleport_destination" -"origin" "704 -40 1256" -"angle" "90" -"targetname" "t50" -} -{ -"classname" "trigger_once" -"target" "t52" -"model" "*36" -} -{ -"spawnflags" "2" -"classname" "trigger_teleport" -"target" "t50" -"targetname" "t52" -"model" "*37" -} -{ -"angle" "90" -"origin" "570 -898 1300" -"classname" "monster_wizard" -"targetname" "t52" -} -{ -"classname" "item_shells" -"origin" "216 120 880" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "192 232 880" -} -{ -"origin" "192 192 880" -"classname" "item_health" -"spawnflags" "1024" -} -{ -"classname" "item_shells" -"origin" "-216 1464 888" -} -{ -"classname" "item_health" -"origin" "816 1160 512" -"spawnflags" "1024" -} -{ -"spawnflags" "1" -"origin" "816 1120 512" -"classname" "item_health" -} -{ -"classname" "monster_wizard" -"origin" "944 840 956" -"angle" "135" -"target" "t53" -"targetname" "t64" -} -{ -"classname" "trigger_once" -"target" "t64" -"model" "*38" -} -{ -"classname" "monster_knight" -"origin" "704 392 1280" -"angle" "270" -"target" "t65" -"spawnflags" "1" -} -{ -"classname" "path_corner" -"origin" "704 208 1264" -"targetname" "t65" -"target" "t66" -} -{ -"origin" "704 496 1264" -"classname" "path_corner" -"targetname" "t66" -"target" "t65" -} -{ -"classname" "trigger_once" -"target" "t67" -"model" "*39" -} -{ -"sounds" "1" -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"targetname" "t72" -"model" "*40" -} -{ -"sounds" "1" -"classname" "func_door" -"wait" "-1" -"angle" "-2" -"targetname" "t72" -"model" "*41" -} -{ -"classname" "trigger_once" -"target" "t72" -"model" "*42" -} -{ -"classname" "info_null" -"origin" "852 -580 820" -"targetname" "t73" -} -{ -"classname" "light" -"origin" "856 -584 936" -"light" "400" -"target" "t73" -} -{ -"classname" "light" -"origin" "920 -448 744" -"light" "150" -} -{ -"light" "150" -"origin" "760 -448 744" -"classname" "light" -} -{ -"classname" "light" -"origin" "552 -424 744" -"light" "150" -} -{ -"light" "150" -"origin" "560 -728 744" -"classname" "light" -} -{ -"classname" "light" -"origin" "776 -712 744" -"light" "150" -} -{ -"light" "150" -"origin" "936 -712 744" -"classname" "light" -} -{ -"classname" "path_corner" -"origin" "652 -576 952" -"targetname" "t75" -"target" "t74" -} -{ -"origin" "908 -576 952" -"classname" "path_corner" -"targetname" "t74" -"target" "t75" -} -{ -"classname" "monster_ogre" -"origin" "816 -260 952" -"angle" "270" -"targetname" "t72" -} -{ -"classname" "monster_ogre" -"origin" "724 -260 952" -"angle" "270" -"targetname" "t72" -"spawnflags" "256" -} -{ -"classname" "item_health" -"origin" "632 -548 820" -"spawnflags" "3072" -} -{ -"origin" "672 -548 820" -"classname" "item_health" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t76" -"model" "*43" -} -{ -"sounds" "1" -"classname" "func_door" -"angle" "-1" -"wait" "-1" -"targetname" "t76" -"model" "*44" -} -{ -"light" "150" -"origin" "1040 -712 1016" -"classname" "light" -} -{ -"origin" "1112 -576 942" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light" -"origin" "1064 -576 896" -"light" "150" -} -{ -"classname" "light" -"origin" "888 -80 968" -"light" "175" -} -{ -"light" "175" -"origin" "512 -80 968" -"classname" "light" -} -{ -"classname" "item_armor2" -"origin" "1184 -96 920" -} -{ -"classname" "monster_ogre" -"origin" "392 8 912" -"angle" "315" -"targetname" "t77" -"spawnflags" "256" -} -{ -"classname" "trigger_once" -"target" "t77" -"model" "*45" -} -{ -"classname" "item_health" -"origin" "336 -224 888" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "968 16 888" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "560 2808 516" -"spawnflags" "1" -} -{ -"classname" "path_corner" -"origin" "1056 -384 824" -"targetname" "t78" -"target" "t79" -"spawnflags" "256" -} -{ -"origin" "1056 -736 824" -"classname" "path_corner" -"targetname" "t79" -"target" "t78" -"spawnflags" "256" -} -{ -"classname" "monster_ogre" -"origin" "1064 -656 840" -"angle" "90" -"target" "t78" -"spawnflags" "257" -} -{ -"angle" "90" -"origin" "848 -880 952" -"classname" "monster_ogre" -"targetname" "t72" -} -{ -"classname" "item_shells" -"origin" "1160 16 1248" -} -{ -"classname" "item_health" -"origin" "280 64 1248" -} -{ -"classname" "item_rockets" -"origin" "648 -256 928" -"spawnflags" "1025" -} -{ -"classname" "item_spikes" -"origin" "648 -304 1248" -} -{ -"origin" "696 -304 1248" -"classname" "item_spikes" -} -{ -"classname" "light_flame_small_yellow" -"origin" "768 -352 1230" -} -{ -"target" "t83" -"wait" ".8" -"classname" "trigger_multiple" -"model" "*46" -} -{ -"target" "t83" -"classname" "trigger_multiple" -"wait" ".8" -"model" "*47" -} -{ -"target" "t83" -"wait" ".8" -"classname" "trigger_multiple" -"model" "*48" -} -{ -"target" "t83" -"classname" "trigger_multiple" -"wait" ".8" -"model" "*49" -} -{ -"target" "t83" -"wait" ".8" -"classname" "trigger_multiple" -"model" "*50" -} -{ -"targetname" "t83" -"classname" "trap_spikeshooter" -"origin" "1108 -576 1140" -"spawnflags" "1" -"angle" "180" -} -{ -"targetname" "t83" -"angle" "90" -"spawnflags" "1" -"origin" "768 -796 1140" -"classname" "trap_spikeshooter" -} -{ -"origin" "1112 -576 1230" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light_flame_small_yellow" -"origin" "768 -800 1230" -} -{ -"classname" "light" -"origin" "712 -756 1168" -"light" "175" -} -{ -"light" "175" -"origin" "768 -424 1168" -"classname" "light" -} -{ -"light" "175" -"origin" "888 -744 956" -"classname" "light" -} -{ -"classname" "light" -"origin" "888 -408 956" -"light" "175" -} -{ -"origin" "384 -224 888" -"classname" "item_shells" -} -{ -"origin" "584 1784 920" -"classname" "item_health" -} -{ -"origin" "832 2064 920" -"classname" "item_shells" -} -{ -"target" "t72" -"classname" "trigger_once" -"model" "*51" -} -{ -"target" "t85" -"targetname" "t84" -"origin" "1560 216 896" -"classname" "path_corner" -} -{ -"target" "t48" -"targetname" "t85" -"classname" "path_corner" -"origin" "1456 216 896" -} -{ -"origin" "704 1368 516" -"classname" "weapon_supernailgun" -} -{ -"spawnflags" "1" -"origin" "184 1928 920" -"classname" "item_spikes" -} -{ -"classname" "item_spikes" -"origin" "656 1816 528" -"spawnflags" "768" -} -{ -"classname" "item_shells" -"origin" "1072 -800 820" -"spawnflags" "1024" -} -{ -"classname" "monster_ogre" -"origin" "840 -40 1276" -"angle" "180" -"targetname" "t86" -"spawnflags" "768" -} -{ -"classname" "trigger_once" -"target" "t86" -"model" "*52" -} -{ -"classname" "light" -"origin" "472 -576 876" -"light" "150" -} -{ -"classname" "item_shells" -"origin" "656 680 1256" -"spawnflags" "1536" -} -{ -"angle" "270" -"origin" "880 2224 536" -"classname" "monster_knight" -"spawnflags" "256" -} -{ -"angle" "180" -"origin" "1112 2424 944" -"classname" "monster_ogre" -"spawnflags" "1281" -} -{ -"targetname" "t88" -"target" "t87" -"origin" "360 384 880" -"classname" "path_corner" -"spawnflags" "1280" -} -{ -"target" "t88" -"targetname" "t87" -"classname" "path_corner" -"origin" "504 160 880" -"spawnflags" "1280" -} -{ -"target" "t87" -"angle" "315" -"origin" "384 320 896" -"classname" "monster_knight" -"spawnflags" "1280" -} -{ -"spawnflags" "257" -"targetname" "t86" -"angle" "0" -"origin" "376 120 1272" -"classname" "monster_ogre" -} -{ -"origin" "776 1368 916" -"classname" "item_shells" -"spawnflags" "1024" -} -{ -"classname" "item_spikes" -"origin" "184 1968 920" -"spawnflags" "1" -} -{ -"classname" "monster_wizard" -"origin" "312 936 944" -"angle" "45" -"spawnflags" "769" -} -{ -"classname" "monster_knight" -"origin" "704 -80 908" -"angle" "90" -} -{ -"angle" "0" -"origin" "568 -56 1276" -"classname" "monster_ogre" -"targetname" "t86" -"spawnflags" "768" -} -{ -"spawnflags" "1536" -"targetname" "t90" -"target" "t89" -"origin" "720 1696 924" -"classname" "path_corner" -} -{ -"spawnflags" "1536" -"target" "t90" -"targetname" "t89" -"classname" "path_corner" -"origin" "720 1416 924" -} -{ -"spawnflags" "1537" -"target" "t90" -"origin" "704 1784 948" -"classname" "monster_ogre" -} -{ -"classname" "func_door_secret" -"angle" "0" -"spawnflags" "1" -"targetname" "t91" -"model" "*53" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t92" -"model" "*54" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t92" -"model" "*55" -} -{ -"classname" "func_button" -"wait" "-1" -"angle" "-2" -"target" "t92" -"model" "*56" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t92" -"model" "*57" -} -{ -"classname" "func_button" -"wait" "-1" -"angle" "-2" -"target" "t92" -"model" "*58" -} -{ -"classname" "trigger_counter" -"count" "5" -"target" "t91" -"targetname" "t92" -"model" "*59" -} -{ -"classname" "light" -"origin" "680 -920 1144" -"light" "150" -} -{ -"classname" "item_spikes" -"origin" "752 -876 928" -"spawnflags" "1" -} -{ -"spawnflags" "3" -"angle" "0" -"classname" "func_door_secret" -"targetname" "t91" -"model" "*60" -} -{ -"light" "150" -"origin" "680 -256 1144" -"classname" "light" -} -{ -"classname" "trigger_once" -"spawnflags" "1792" -"target" "t72" -"model" "*61" -} -{ -"classname" "trigger_secret" -"sounds" "1" -"targetname" "t8" -"model" "*62" -} -{ -"angle" "270" -"origin" "704 624 1280" -"classname" "monster_knight" -"spawnflags" "1" -} -{ -"angle" "225" -"origin" "1016 -440 1128" -"classname" "monster_knight" -} -{ -"angle" "180" -"origin" "1024 -728 1128" -"classname" "monster_knight" -} -{ -"spawnflags" "256" -"angle" "180" -"origin" "1008 -568 1128" -"classname" "monster_knight" -} -{ -"spawnflags" "256" -"classname" "monster_knight" -"origin" "304 2312 952" -"angle" "0" -"targetname" "t29" -} -{ -"spawnflags" "1025" -"classname" "monster_knight" -"origin" "272 136 896" -"angle" "45" -} -{ -"classname" "monster_wizard" -"origin" "784 -576 960" -"angle" "0" -"target" "t74" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "732 -936 928" -} -{ -"origin" "772 -936 928" -"classname" "item_health" -} -{ -"spawnflags" "256" -"classname" "monster_knight" -"origin" "704 -248 1272" -"angle" "0" -} -{ -"classname" "path_corner" -"origin" "1328 928 1396" -"targetname" "t93" -"target" "t94" -"spawnflags" "512" -} -{ -"origin" "1176 928 1396" -"classname" "path_corner" -"target" "t93" -"targetname" "t94" -"spawnflags" "512" -} -{ -"classname" "monster_knight" -"origin" "1192 884 1412" -"angle" "0" -"target" "t93" -"spawnflags" "513" -} -{ -"classname" "monster_knight" -"origin" "704 2376 944" -"angle" "90" -} -{ -"classname" "monster_knight" -"origin" "888 2312 944" -"angle" "180" -"targetname" "t95" -} -{ -"angle" "0" -"origin" "512 2304 944" -"classname" "monster_knight" -"targetname" "t95" -"spawnflags" "768" -} -{ -"classname" "trigger_once" -"target" "t95" -"model" "*63" -} -{ -"spawnflags" "256" -"angle" "315" -"origin" "728 2312 536" -"classname" "monster_knight" -} -{ -"light" "200" -"origin" "1296 1528 936" -"classname" "light" -} -{ -"light" "250" -"origin" "1432 1360 982" -"classname" "light_flame_small_yellow" -} -{ -"light" "150" -"origin" "1400 1360 920" -"classname" "light" -} -{ -"light" "200" -"origin" "1248 1344 680" -"classname" "light" -} -{ -"lip" "-384" -"wait" "-1" -"angle" "90" -"classname" "func_door" -"targetname" "t98" -"model" "*64" -} -{ -"light" "150" -"origin" "1152 1328 584" -"classname" "light" -} -{ -"origin" "1376 1480 864" -"classname" "item_health" -} -{ -"sounds" "1" -"classname" "trigger_secret" -"model" "*65" -} -{ -"classname" "func_button" -"sounds" "1" -"angle" "0" -"wait" "-1" -"target" "t97" -"model" "*66" -} -{ -"classname" "func_button" -"wait" "-1" -"angle" "0" -"sounds" "1" -"target" "t97" -"model" "*67" -} -{ -"classname" "trigger_counter" -"targetname" "t97" -"target" "t98" -"model" "*68" -} -{ -"classname" "light" -"origin" "880 -888 968" -"light" "150" -} -{ -"light" "150" -"origin" "880 -264 968" -"classname" "light" -} -{ -"angle" "180" -"origin" "1112 2344 944" -"classname" "monster_ogre" -"spawnflags" "769" -} -{ -"angle" "270" -"origin" "1120 880 1412" -"classname" "monster_ogre" -"spawnflags" "257" -} -{ -"map" "e1m8" -"classname" "trigger_changelevel" -"model" "*69" -} -{ -"light" "175" -"origin" "824 -756 1168" -"classname" "light" -} -{ -"classname" "light" -"origin" "1080 -528 1168" -"light" "175" -} -{ -"classname" "monster_wizard" -"origin" "672 -392 1024" -"angle" "315" -"spawnflags" "257" -} -{ -"classname" "monster_knight" -"origin" "1008 -656 1128" -"angle" "180" -"spawnflags" "768" -} -{ -"origin" "520 1064 440" -"classname" "air_bubbles" -} -{ -"classname" "item_spikes" -"origin" "16 1432 892" -} -{ -"classname" "trigger_once" -"message" "A secret cave has opened..." -"targetname" "t98" -"model" "*70" -} -{ -"target" "t4" -"health" "1" -"wait" "-1" -"angle" "0" -"classname" "func_button" -"model" "*71" -} -{ -"target" "t2" -"health" "1" -"wait" "-1" -"angle" "180" -"classname" "func_button" -"model" "*72" -} -{ -"target" "t49" -"spawnflags" "769" -"angle" "135" -"origin" "1208 128 904" -"classname" "monster_demon1" -} -{ -"spawnflags" "769" -"angle" "45" -"origin" "288 160 896" -"classname" "monster_demon1" -} -{ -"spawnflags" "768" -"classname" "monster_ogre" -"origin" "692 -884 952" -"angle" "90" -} -{ -"classname" "monster_ogre" -"origin" "-312 1648 1372" -"angle" "90" -"targetname" "t23" -"spawnflags" "768" -} -{ -"angle" "90" -"origin" "-192 1648 1372" -"classname" "monster_ogre" -"targetname" "t23" -"spawnflags" "768" -} -{ -"classname" "monster_ogre" -"origin" "704 1288 540" -"angle" "270" -"spawnflags" "768" -} -{ -"targetname" "t101" -"target" "t106" -"spawnflags" "770" -"classname" "trigger_teleport" -"model" "*73" -} -{ -"spawnflags" "768" -"targetname" "t101" -"angle" "270" -"origin" "-256 2424 1288" -"classname" "monster_wizard" -} -{ -"targetname" "t101" -"origin" "-248 2440 1280" -"classname" "trigger_relay" -} -{ -"targetname" "t29" -"spawnflags" "256" -"angle" "0" -"origin" "144 2648 1024" -"classname" "monster_wizard" -} -{ -"targetname" "t29" -"spawnflags" "768" -"classname" "monster_wizard" -"origin" "144 2592 1024" -"angle" "0" -} -{ -"targetname" "t29" -"spawnflags" "768" -"angle" "0" -"origin" "144 2536 1024" -"classname" "monster_wizard" -} -{ -"targetname" "t29" -"target" "t102" -"spawnflags" "258" -"classname" "trigger_teleport" -"model" "*74" -} -{ -"targetname" "t29" -"target" "t103" -"spawnflags" "770" -"classname" "trigger_teleport" -"model" "*75" -} -{ -"targetname" "t29" -"target" "t104" -"spawnflags" "770" -"classname" "trigger_teleport" -"model" "*76" -} -{ -"angle" "270" -"targetname" "t102" -"spawnflags" "256" -"origin" "704 2656 1008" -"classname" "info_teleport_destination" -} -{ -"angle" "270" -"targetname" "t103" -"spawnflags" "768" -"classname" "info_teleport_destination" -"origin" "920 2520 1008" -} -{ -"angle" "0" -"targetname" "t104" -"spawnflags" "768" -"origin" "592 2192 1008" -"classname" "info_teleport_destination" -} -{ -"sounds" "1" -"classname" "func_door" -"angle" "0" -"wait" "-1" -"speed" "150" -"targetname" "t105" -"model" "*77" -} -{ -"classname" "monster_demon1" -"origin" "1056 -880 1128" -"angle" "90" -"spawnflags" "768" -"targetname" "t105" -} -{ -"classname" "trigger_once" -"spawnflags" "768" -"target" "t105" -"model" "*78" -} -{ -"classname" "light" -"origin" "1056 -920 1184" -"light" "125" -} -{ -"classname" "trigger_relay" -"origin" "1104 -864 1120" -"target" "t105" -} -{ -"classname" "monster_ogre" -"origin" "1120 768 1416" -"angle" "180" -"spawnflags" "769" -} -{ -"classname" "air_bubbles" -"origin" "884 1616 440" -} -{ -"targetname" "t106" -"spawnflags" "768" -"angle" "270" -"origin" "-264 2232 1296" -"classname" "info_teleport_destination" -} -{ -"classname" "path_corner" -"origin" "568 1984 928" -"targetname" "t107" -"target" "t108" -"spawnflags" "256" -} -{ -"origin" "424 1960 928" -"classname" "path_corner" -"target" "t107" -"spawnflags" "256" -"targetname" "t111" -} -{ -"classname" "path_corner" -"origin" "704 2024 928" -"targetname" "t108" -"target" "t109" -"spawnflags" "256" -} -{ -"origin" "712 1712 928" -"classname" "path_corner" -"targetname" "t109" -"target" "t110" -"spawnflags" "256" -} -{ -"classname" "path_corner" -"origin" "712 1416 928" -"targetname" "t110" -"target" "t109" -"spawnflags" "256" -} -{ -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"lip" "-24" -"targetname" "t26" -"spawnflags" "2304" -"model" "*79" -} -{ -"classname" "monster_ogre" -"origin" "240 2048 944" -"angle" "0" -"spawnflags" "257" -"target" "t111" -} -{ -"target" "t23" -"spawnflags" "1792" -"classname" "trigger_once" -"model" "*80" -} -{ -"classname" "monster_knight" -"origin" "576 2768 536" -"angle" "0" -"spawnflags" "256" -} -{ -"spawnflags" "256" -"angle" "180" -"origin" "824 2776 536" -"classname" "monster_knight" -} -{ -"classname" "monster_wizard" -"origin" "704 -1032 1024" -"angle" "90" -"spawnflags" "256" -"targetname" "t52" -} -{ -"angle" "90" -"origin" "760 -1032 1024" -"classname" "monster_wizard" -"spawnflags" "768" -"targetname" "t114" -} -{ -"classname" "monster_wizard" -"origin" "816 -1032 1024" -"angle" "90" -"spawnflags" "768" -"targetname" "t114" -} -{ -"targetname" "t52" -"classname" "trigger_teleport" -"spawnflags" "258" -"target" "t112" -"model" "*81" -} -{ -"classname" "trigger_teleport" -"spawnflags" "770" -"target" "t113" -"targetname" "t114" -"model" "*82" -} -{ -"targetname" "t114" -"classname" "trigger_teleport" -"spawnflags" "770" -"target" "t115" -"model" "*83" -} -{ -"classname" "info_teleport_destination" -"origin" "896 224 1352" -"angle" "135" -"spawnflags" "256" -"targetname" "t112" -} -{ -"classname" "info_teleport_destination" -"origin" "488 1648 1016" -"angle" "315" -"spawnflags" "768" -"targetname" "t113" -} -{ -"classname" "trigger_once" -"spawnflags" "768" -"target" "t114" -"model" "*84" -} -{ -"classname" "info_teleport_destination" -"origin" "800 904 928" -"angle" "90" -"spawnflags" "768" -"targetname" "t115" -} -{ -"angle" "270" -"origin" "-256 2232 1242" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1792" -"origin" "-256 2096 1218" -"classname" "weapon_supershotgun" -} -{ -"angle" "270" -"origin" "704 424 1266" -"classname" "info_player_deathmatch" -} -{ -"angle" "270" -"origin" "704 2488 946" -"classname" "info_player_deathmatch" -} -{ -"angle" "270" -"origin" "704 1968 546" -"classname" "info_player_deathmatch" -} -{ -"angle" "90" -"origin" "704 104 898" -"classname" "info_player_deathmatch" -} -{ -"angle" "270" -"origin" "704 1568 938" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1792" -"origin" "704 1344 912" -"classname" "weapon_rocketlauncher" -} -{ -"angle" "0" -"origin" "712 -576 840" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1792" -"origin" "944 -576 816" -"classname" "weapon_nailgun" -} -{ -"angle" "180" -"origin" "1064 -576 1128" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1792" -"origin" "696 584 1256" -"classname" "weapon_grenadelauncher" -} -{ -"classname" "light" -"origin" "316 804 780" -"light" "150" -} -{ -"classname" "light" -"origin" "316 804 644" -"light" "75" -} -{ -"classname" "item_rockets" -"origin" "298 710 706" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "988 -928 1104" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "-56 2112 1220" -"spawnflags" "3584" -} -{ -"classname" "item_health" -"origin" "-56 2072 1220" -"spawnflags" "2305" -} -{ -"spawnflags" "1" -"origin" "584 2416 512" -"classname" "item_spikes" -} -{ -"origin" "688 1392 516" -"classname" "item_spikes" -} -{ -"classname" "item_artifact_invulnerability" -"origin" "712 2312 948" -"spawnflags" "1792" -} -{ -"origin" "32 1392 916" -"classname" "item_artifact_envirosuit" -} -{ -"mangle" "26 310 0" -"origin" "384 488 1552" -"classname" "info_intermission" -} -{ -"light" "100" -"origin" "800 1160 464" -"classname" "light" -} -{ -"classname" "light" -"origin" "608 1160 464" -"light" "100" -} -{ -"light" "100" -"origin" "604 1472 464" -"classname" "light" -} -{ -"target" "t40" -"classname" "trigger_teleport" -"model" "*85" -} -{ -"mangle" "-20 75 0" -"origin" "456 2144 568" -"classname" "info_intermission" -} -{ -"mangle" "10 80 0" -"origin" "464 1032 1000" -"classname" "info_intermission" -} -{ -"mangle" "20 135 0" -"origin" "1080 -752 1008" -"classname" "info_intermission" -} -{ -"classname" "trigger_secret" -"model" "*86" -} -{ -"classname" "path_corner" -"origin" "1632 216 896" -"targetname" "t116" -"target" "t84" -} -{ -"classname" "item_spikes" -"origin" "1200 48 872" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "928 2664 320" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "1240 768 1384" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "-88 2160 1224" -"spawnflags" "2049" -} -{ -"classname" "info_player_coop" -"origin" "-208 2272 1240" -"angle" "270" -} -{ -"angle" "270" -"origin" "-304 2272 1240" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "-352 2272 1240" -"angle" "270" -} -{ -"light" "200" -"origin" "1288 1648 956" -"classname" "light" -} -{ -"classname" "item_spikes" -"origin" "-264 1464 888" -} -{ -"spawnflags" "1792" -"origin" "1296 1488 888" -"classname" "item_artifact_invisibility" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*87" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*88" -} -{ -"target" "t118" -"targetname" "t117" -"origin" "-176 1640 888" -"classname" "path_corner" -} -{ -"targetname" "t118" -"target" "t117" -"classname" "path_corner" -"origin" "-320 1640 888" -} -{ -"target" "t117" -"origin" "-256 1632 904" -"classname" "monster_knight" -"spawnflags" "1" -} -{ -"origin" "1376 1424 864" -"classname" "weapon_grenadelauncher" -} -{ -"spawnflags" "1" -"targetname" "t120" -"target" "t119" -"classname" "trigger_counter" -"model" "*89" -} -{ -"target" "t120" -"targetname" "t53" -"classname" "trigger_once" -"model" "*90" -} -{ -"target" "t120" -"targetname" "t39" -"classname" "trigger_once" -"model" "*91" -} -{ -"classname" "light" -"origin" "480 2568 568" -"light" "125" -} -{ -"origin" "162 1482 976" -"classname" "ambient_drip" -} -{ -"origin" "786 1010 584" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "778 1210 584" -} -{ -"origin" "594 1202 584" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "602 1010 584" -} -{ -"origin" "786 1514 584" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "794 1698 584" -} -{ -"origin" "618 1690 584" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "618 1522 584" -} -{ -"origin" "698 1362 584" -"classname" "ambient_drip" -} -{ -"origin" "714 1970 592" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "898 2170 592" -} -{ -"origin" "938 2346 592" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "682 2298 592" -} -{ -"origin" "458 2306 592" -"classname" "ambient_drip" -} -{ -"origin" "458 1690 880" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "322 1506 880" -} -{ -"origin" "338 1226 880" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "466 1090 880" -} -{ -"origin" "394 882 880" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "674 810 880" -} -{ -"origin" "914 818 880" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "922 1034 880" -} -{ -"origin" "1082 1266 880" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "994 1442 880" -} -{ -"origin" "898 1714 880" -"classname" "ambient_drip" -} -{ -"origin" "706 1362 1080" -"classname" "ambient_drip" -} -{ -"origin" "1194 1522 1032" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "1314 1354 1032" -} -{ -"origin" "442 354 920" -"classname" "ambient_swamp1" -} -{ -"origin" "978 314 920" -"classname" "ambient_swamp2" -} diff --git a/Misc/pak/maps/e2m2.diff b/Misc/pak/maps/e2m2.diff new file mode 100644 index 000000000..4dbf2dc5b --- /dev/null +++ b/Misc/pak/maps/e2m2.diff @@ -0,0 +1,54 @@ +--- e2m2.ent ++++ e2m2@fbfe.ent +@@ -908,20 +908,21 @@ + { + "classname" "func_door" + "angle" "-2" + "spawnflags" "33" + "speed" "10" + "sounds" "3" + "wait" "-1" + "targetname" "t16" + "dmg" "100" + "model" "*13" ++"lip" "7" // svdijk -- added to prevent z-fighting + } + { + "sounds" "3" + "classname" "func_door" + "angle" "90" + "spawnflags" "2056" + "wait" "-1" + "model" "*14" + } + { +@@ -1423,27 +1424,27 @@ + { + "target" "t39" + "targetname" "t40" + "origin" "-216 280 104" + "classname" "path_corner" + } + { + "target" "t40" + "targetname" "t38" + "classname" "path_corner" +-"origin" "-16 280 104" ++"origin" "-15 280 104" // svdijk -- changed to prevent z-fighting (was "-16 280 104") + } + { + "target" "t38" + "wait" "-1" + "targetname" "t39" +-"origin" "-16 280 104" ++"origin" "-15 280 104" // svdijk -- changed to prevent z-fighting (was "-16 280 104") + "classname" "path_corner" + } + { + "angle" "180" + "origin" "680 1472 24" + "classname" "monster_ogre" + "spawnflags" "256" + } + { + "spawnflags" "256" diff --git a/Misc/pak/maps/e2m2.ent.orig b/Misc/pak/maps/e2m2.ent.orig deleted file mode 100644 index 1a92a2471..000000000 --- a/Misc/pak/maps/e2m2.ent.orig +++ /dev/null @@ -1,2004 +0,0 @@ -{ -"message" "the Ogre Citadel" -"sounds" "8" -"wad" "gfx/wizard.wad" -"classname" "worldspawn" -"worldtype" "0" -} -{ -"origin" "160 -160 120" -"classname" "light" -} -{ -"angle" "90" -"origin" "-256 -1952 280" -"classname" "info_player_start" -} -{ -"classname" "light" -"origin" "160 -392 248" -"light" "200" -} -{ -"classname" "light" -"origin" "160 -648 184" -} -{ -"classname" "light" -"origin" "-56 -392 248" -"light" "200" -} -{ -"classname" "light" -"origin" "376 -392 248" -"light" "200" -} -{ -"classname" "light" -"origin" "288 -416 -72" -"light" "200" -} -{ -"classname" "light" -"origin" "32 -416 -72" -"light" "200" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "10 -270 148" -"light" "250" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "314 -270 148" -"light" "250" -} -{ -"classname" "light" -"origin" "-264 -440 248" -"light" "200" -} -{ -"classname" "light" -"origin" "584 -440 248" -"light" "200" -} -{ -"classname" "light" -"origin" "544 -648 248" -} -{ -"light" "150" -"origin" "648 -456 -184" -"classname" "light" -} -{ -"origin" "376 -800 184" -"classname" "light" -} -{ -"classname" "light" -"origin" "-152 -752 184" -"light" "250" -} -{ -"classname" "light" -"origin" "-232 -592 184" -"light" "250" -} -{ -"classname" "light" -"origin" "160 112 184" -} -{ -"classname" "light" -"origin" "160 352 120" -} -{ -"classname" "light" -"origin" "160 216 -48" -"light" "120" -} -{ -"classname" "light" -"origin" "160 16 -48" -"light" "120" -} -{ -"classname" "light" -"origin" "160 544 144" -"light" "225" -} -{ -"classname" "light" -"origin" "480 576 88" -} -{ -"classname" "light" -"origin" "480 448 88" -} -{ -"classname" "light" -"origin" "480 576 168" -"light" "250" -} -{ -"classname" "light" -"origin" "480 448 168" -"light" "250" -} -{ -"classname" "light" -"origin" "160 896 312" -"light" "350" -} -{ -"classname" "light" -"origin" "288 896 312" -"light" "100" -} -{ -"classname" "light" -"origin" "32 896 312" -"light" "100" -} -{ -"classname" "light" -"origin" "160 1008 312" -"light" "100" -} -{ -"classname" "light" -"origin" "160 784 312" -"light" "100" -} -{ -"classname" "light" -"origin" "392 120 184" -"light" "350" -} -{ -"classname" "light" -"origin" "568 208 184" -"light" "350" -} -{ -"classname" "light" -"origin" "720 480 184" -} -{ -"classname" "light" -"origin" "640 632 184" -} -{ -"classname" "light" -"origin" "472 1152 56" -} -{ -"classname" "light" -"origin" "512 896 152" -} -{ -"origin" "800 800 184" -"classname" "light" -} -{ -"light" "200" -"origin" "632 1264 -40" -"classname" "light" -} -{ -"origin" "800 1032 184" -"classname" "light" -} -{ -"origin" "760 1472 64" -"classname" "light" -} -{ -"light" "200" -"origin" "544 1416 56" -"classname" "light" -} -{ -"origin" "672 1256 184" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"origin" "1024 1272 184" -"classname" "light" -} -{ -"light" "200" -"origin" "992 1440 184" -"classname" "light" -} -{ -"origin" "1240 488 184" -"classname" "light" -} -{ -"origin" "1280 136 176" -"classname" "light" -} -{ -"origin" "160 1304 136" -"classname" "light" -} -{ -"origin" "160 1648 256" -"classname" "light" -"light" "200" -} -{ -"origin" "240 1600 256" -"classname" "light" -"light" "200" -} -{ -"origin" "16 1616 168" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"origin" "-120 1304 40" -"classname" "light" -} -{ -"origin" "-352 1144 16" -"classname" "light" -"light" "250" -} -{ -"origin" "-56 1096 64" -"classname" "light" -} -{ -"light" "200" -"origin" "-56 1152 280" -"classname" "light" -} -{ -"light" "350" -"origin" "-440 1144 200" -"classname" "light" -} -{ -"light" "200" -"origin" "-352 1336 -72" -"classname" "light" -} -{ -"origin" "-488 368 56" -"classname" "light" -"light" "250" -} -{ -"light" "350" -"origin" "-488 896 136" -"classname" "light" -} -{ -"origin" "-216 896 184" -"classname" "light" -"light" "250" -} -{ -"origin" "-128 536 168" -"classname" "light" -"light" "200" -} -{ -"light" "150" -"origin" "-104 480 32" -"classname" "light" -} -{ -"light" "150" -"origin" "-208 936 56" -"classname" "light" -} -{ -"light" "150" -"origin" "-208 736 32" -"classname" "light" -} -{ -"origin" "-344 64 184" -"classname" "light" -} -{ -"light" "350" -"origin" "-648 384 184" -"classname" "light" -} -{ -"light" "350" -"origin" "-488 688 184" -"classname" "light" -} -{ -"light" "150" -"origin" "-680 496 -36" -"classname" "light" -} -{ -"light" "350" -"origin" "-600 1104 96" -"classname" "light" -} -{ -"origin" "-824 896 168" -"classname" "light" -} -{ -"origin" "-896 600 160" -"classname" "light" -} -{ -"target" "t1" -"classname" "trigger_teleport" -"model" "*1" -} -{ -"spawnflags" "1792" -"targetname" "t1" -"origin" "-448 264 -56" -"classname" "info_teleport_destination" -"angle" "45" -} -{ -"light" "250" -"origin" "-168 1320 160" -"classname" "light" -} -{ -"origin" "-24 896 184" -"classname" "light" -} -{ -"origin" "-104 896 184" -"classname" "light" -"light" "250" -} -{ -"spawnflags" "2" -"origin" "-680 880 48" -"classname" "item_health" -} -{ -"angle" "90" -"origin" "-896 512 24" -"classname" "info_player_deathmatch" -} -{ -"angle" "90" -"origin" "-184 560 128" -"classname" "info_player_deathmatch" -} -{ -"angle" "270" -"origin" "160 1640 160" -"classname" "info_player_deathmatch" -} -{ -"angle" "90" -"origin" "1272 112 80" -"classname" "info_player_deathmatch" -} -{ -"angle" "90" -"origin" "176 -784 24" -"classname" "info_player_deathmatch" -} -{ -"spawnflags" "1" -"origin" "208 -160 0" -"classname" "item_rockets" -} -{ -"origin" "64 464 0" -"classname" "item_health" -} -{ -"origin" "120 464 0" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "-8 840 64" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "-8 952 64" -"classname" "item_health" -} -{ -"spawnflags" "9" -"origin" "568 880 0" -"classname" "item_weapon" -} -{ -"origin" "456 1104 -88" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "664 1272 -88" -"classname" "item_shells" -} -{ -"angle" "225" -"origin" "888 1312 120" -"classname" "info_player_deathmatch" -} -{ -"origin" "1328 168 56" -"classname" "item_health" -} -{ -"origin" "1328 128 56" -"classname" "item_health" -} -{ -"origin" "1328 208 56" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "816 1472 0" -"classname" "item_shells" -} -{ -"light" "200" -"origin" "-64 -120 -56" -"classname" "light" -} -{ -"light" "200" -"origin" "-296 -160 -56" -"classname" "light" -} -{ -"light" "200" -"origin" "-296 -208 -272" -"classname" "light" -} -{ -"classname" "func_plat" -"model" "*2" -} -{ -"spawnflags" "2" -"origin" "-192 -176 -80" -"classname" "item_health" -} -{ -"light" "350" -"origin" "-816 128 184" -"classname" "light" -} -{ -"light" "350" -"origin" "-664 -80 184" -"classname" "light" -} -{ -"light" "250" -"origin" "-656 112 32" -"classname" "light" -} -{ -"origin" "-352 208 56" -"classname" "light" -"light" "250" -} -{ -"origin" "-184 504 24" -"classname" "light" -"light" "250" -} -{ -"classname" "item_armor1" -"origin" "400 -888 0" -} -{ -"spawnflags" "1792" -"classname" "item_armorInv" -"origin" "-104 448 104" -} -{ -"classname" "item_armor2" -"origin" "-680 496 32" -} -{ -"classname" "weapon_grenadelauncher" -"origin" "168 1608 136" -"spawnflags" "1792" -} -{ -"classname" "weapon_rocketlauncher" -"origin" "1232 176 56" -"spawnflags" "1792" -} -{ -"classname" "weapon_supernailgun" -"origin" "-960 944 40" -"spawnflags" "1792" -} -{ -"classname" "weapon_supershotgun" -"origin" "752 1464 0" -"spawnflags" "1792" -} -{ -"classname" "weapon_nailgun" -"origin" "160 120 24" -"spawnflags" "1792" -} -{ -"classname" "item_rockets" -"origin" "-224 792 104" -"spawnflags" "1792" -} -{ -"classname" "item_rockets" -"origin" "-640 120 -56" -"spawnflags" "1792" -} -{ -"light" "200" -"origin" "-70 -1126 212" -"classname" "light_torch_small_walltorch" -} -{ -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "186 -1134 148" -} -{ -"light" "200" -"origin" "138 -966 100" -"classname" "light_torch_small_walltorch" -} -{ -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "-150 -1318 260" -} -{ -"light" "150" -"origin" "184 -880 72" -"classname" "light" -} -{ -"style" "6" -"light" "200" -"origin" "-46 -1742 340" -"classname" "light_torch_small_walltorch" -} -{ -"style" "1" -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "-486 -1726 340" -} -{ -"origin" "-272 -1544 384" -"classname" "light" -"light" "200" -} -{ -"style" "6" -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "-414 -2006 340" -} -{ -"style" "1" -"light" "200" -"origin" "-134 -1958 340" -"classname" "light_torch_small_walltorch" -} -{ -"light" "150" -"origin" "-472 -1840 328" -"classname" "light" -} -{ -"classname" "light" -"origin" "-72 -1592 328" -"light" "150" -} -{ -"light" "150" -"origin" "-320 -1424 264" -"classname" "light" -} -{ -"light" "150" -"origin" "-256 -1952 280" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "-272 -1720 312" -} -{ -"origin" "-232 -1280 168" -"classname" "path_corner" -"targetname" "t5" -"target" "t6" -} -{ -"classname" "path_corner" -"origin" "-64 -1176 120" -"targetname" "t6" -"target" "t7" -} -{ -"origin" "152 -1104 56" -"classname" "path_corner" -"targetname" "t7" -"target" "t8" -} -{ -"classname" "path_corner" -"origin" "192 -952 8" -"targetname" "t8" -"target" "t9" -} -{ -"origin" "184 -808 8" -"classname" "path_corner" -"target" "t3" -"targetname" "t9" -} -{ -"classname" "path_corner" -"origin" "512 -776 8" -"targetname" "t3" -"target" "t10" -} -{ -"origin" "-200 -648 8" -"classname" "path_corner" -"targetname" "t4" -"target" "t11" -} -{ -"classname" "monster_knight" -"origin" "-360 -1616 232" -"target" "t5" -"angle" "90" -} -{ -"origin" "512 -648 8" -"classname" "path_corner" -"targetname" "t10" -"target" "t4" -} -{ -"classname" "path_corner" -"origin" "-200 -776 8" -"targetname" "t11" -"target" "t3" -} -{ -"classname" "monster_knight" -"origin" "24 -632 24" -"spawnflags" "256" -"target" "t4" -} -{ -"classname" "monster_knight" -"origin" "336 -752 24" -"spawnflags" "256" -"target" "t3" -} -{ -"classname" "monster_knight" -"origin" "56 -712 24" -"angle" "270" -"spawnflags" "768" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "160 -712 24" -"classname" "monster_knight" -} -{ -"classname" "monster_knight" -"origin" "264 -712 24" -"angle" "270" -"spawnflags" "768" -} -{ -"classname" "item_health" -"origin" "-432 -1640 208" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "-352 -592 0" -} -{ -"classname" "func_door" -"angle" "90" -"spawnflags" "1" -"targetname" "t13" -"wait" "-1" -"sounds" "3" -"dmg" "100" -"model" "*3" -} -{ -"health" "1" -"angle" "90" -"classname" "func_button" -"target" "t12" -"wait" "-1" -"sounds" "1" -"model" "*4" -} -{ -"classname" "func_button" -"angle" "90" -"health" "1" -"target" "t12" -"wait" "-1" -"sounds" "1" -"model" "*5" -} -{ -"classname" "trigger_counter" -"targetname" "t12" -"count" "2" -"target" "t13" -"model" "*6" -} -{ -"classname" "monster_demon1" -"origin" "160 -128 24" -"angle" "270" -"targetname" "t12" -} -{ -"classname" "light" -"origin" "-8 -288 64" -"light" "200" -} -{ -"light" "200" -"origin" "328 -288 64" -"classname" "light" -} -{ -"light" "200" -"origin" "-296 -448 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "160 -368 -248" -"light" "200" -} -{ -"light" "200" -"origin" "616 -448 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "408 -456 -248" -"light" "200" -} -{ -"light" "200" -"origin" "-40 -424 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-280 -448 32" -"light" "200" -} -{ -"light" "200" -"origin" "632 -424 32" -"classname" "light" -} -{ -"classname" "light" -"origin" "160 -480 8" -"light" "150" -} -{ -"classname" "func_door" -"angle" "180" -"targetname" "t12" -"sounds" "3" -"speed" "200" -"wait" "-1" -"lip" "-2" -"model" "*7" -} -{ -"classname" "func_door" -"angle" "0" -"speed" "200" -"wait" "-1" -"lip" "-2" -"model" "*8" -} -{ -"classname" "light" -"origin" "160 -304 112" -"light" "170" -} -{ -"classname" "light" -"origin" "160 640 104" -"light" "200" -} -{ -"classname" "func_door" -"angle" "-1" -"targetname" "t14" -"sounds" "1" -"model" "*9" -} -{ -"classname" "trigger_multiple" -"target" "t14" -"wait" "10" -"model" "*10" -} -{ -"targetname" "t28" -"classname" "func_door" -"angle" "-1" -"wait" "-1" -"sounds" "1" -"speed" "200" -"spawnflags" "2048" -"model" "*11" -} -{ -"angle" "270" -"classname" "func_button" -"target" "t15" -"wait" "-1" -"lip" "2" -"sounds" "1" -"spawnflags" "2048" -"model" "*12" -} -{ -"classname" "light" -"origin" "-296 432 0" -"light" "200" -} -{ -"light" "200" -"origin" "-312 416 152" -"classname" "light" -} -{ -"classname" "light" -"origin" "-184 320 146" -"light" "200" -} -{ -"classname" "item_key2" -"origin" "-552 192 -40" -"sounds" "1" -"spawnflags" "2048" -} -{ -"classname" "item_spikes" -"origin" "-680 88 -48" -} -{ -"classname" "func_door" -"angle" "-2" -"spawnflags" "33" -"speed" "10" -"sounds" "3" -"wait" "-1" -"targetname" "t16" -"dmg" "100" -"model" "*13" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "90" -"spawnflags" "2056" -"wait" "-1" -"model" "*14" -} -{ -"spawnflags" "2056" -"angle" "270" -"classname" "func_door" -"wait" "-1" -"model" "*15" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t16" -"lip" "12" -"model" "*16" -} -{ -"classname" "light" -"origin" "888 1080 -104" -"light" "160" -} -{ -"light" "160" -"origin" "888 888 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "880 696 -104" -"light" "160" -} -{ -"light" "160" -"origin" "696 888 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "696 1080 -104" -"light" "160" -} -{ -"light" "200" -"origin" "696 672 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "568 512 -104" -"light" "200" -} -{ -"light" "160" -"origin" "840 504 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "832 328 -104" -"light" "160" -} -{ -"classname" "light" -"origin" "936 512 96" -"light" "200" -} -{ -"classname" "light" -"origin" "-248 1080 56" -"light" "150" -} -{ -"classname" "light" -"origin" "888 1264 176" -"light" "170" -} -{ -"classname" "func_door" -"angle" "-2" -"targetname" "t17" -"sounds" "1" -"model" "*17" -} -{ -"classname" "trigger_multiple" -"target" "t17" -"wait" "5" -"model" "*18" -} -{ -"classname" "light" -"origin" "160 120 -24" -"light" "160" -} -{ -"spawnflags" "256" -"classname" "trigger_multiple" -"target" "t18" -"targetname" "t23" -"model" "*19" -} -{ -"wait" "0.5" -"classname" "trap_spikeshooter" -"origin" "88 368 40" -"angle" "0" -"targetname" "t18" -} -{ -"classname" "func_wall" -"spawnflags" "2048" -"model" "*20" -} -{ -"classname" "monster_demon1" -"origin" "-160 608 128" -"targetname" "t19" -} -{ -"classname" "trigger_once" -"target" "t19" -"model" "*21" -} -{ -"classname" "light" -"origin" "-528 512 -104" -"light" "200" -} -{ -"light" "200" -"origin" "-344 592 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "-336 760 -104" -"light" "200" -} -{ -"light" "200" -"origin" "-432 856 -104" -"classname" "light" -} -{ -"classname" "monster_ogre" -"origin" "-416 440 -40" -"spawnflags" "1536" -"target" "t20" -} -{ -"classname" "monster_shambler" -"origin" "-272 296 -40" -"spawnflags" "256" -"target" "t20" -} -{ -"classname" "path_corner" -"origin" "-328 272 -56" -"targetname" "t20" -"target" "t21" -} -{ -"origin" "-400 480 -56" -"classname" "path_corner" -"target" "t20" -"targetname" "t21" -} -{ -"classname" "item_health" -"origin" "-600 144 -64" -} -{ -"classname" "weapon_supershotgun" -"origin" "440 512 0" -"spawnflags" "2048" -} -{ -"classname" "light" -"origin" "-120 176 184" -"light" "250" -} -{ -"origin" "-96 0 184" -"classname" "light" -"light" "200" -} -{ -"classname" "light" -"origin" "312 116 -48" -"light" "200" -} -{ -"classname" "path_corner" -"origin" "8 112 32" -"target" "t25" -"targetname" "t24" -} -{ -"origin" "312 112 32" -"classname" "path_corner" -"targetname" "t25" -"target" "t24" -} -{ -"classname" "monster_ogre" -"origin" "112 112 48" -"target" "t24" -"spawnflags" "256" -} -{ -"classname" "item_shells" -"origin" "88 -160 0" -"spawnflags" "1" -} -{ -"light" "250" -"classname" "light" -"origin" "-352 144 56" -} -{ -"classname" "monster_demon1" -"origin" "-80 -440 -296" -"spawnflags" "256" -"target" "t26" -} -{ -"classname" "path_corner" -"origin" "-216 -456 -312" -"targetname" "t26" -"target" "t27" -} -{ -"origin" "536 -448 -312" -"classname" "path_corner" -"target" "t26" -"targetname" "t27" -} -{ -"light" "200" -"origin" "320 232 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "312 0 -104" -"light" "200" -} -{ -"light" "160" -"origin" "-8 0 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "-8 232 -104" -"light" "200" -} -{ -"light" "200" -"origin" "-16 112 -104" -"classname" "light" -} -{ -"classname" "light" -"origin" "-248 -8 -104" -"light" "200" -} -{ -"light" "200" -"origin" "-472 120 -104" -"classname" "light" -} -{ -"wait" "-1" -"classname" "func_door" -"angle" "-1" -"targetname" "t15" -"sounds" "1" -"spawnflags" "2048" -"model" "*22" -} -{ -"classname" "func_door" -"angle" "-2" -"spawnflags" "2081" -"targetname" "t28" -"wait" "10" -"speed" "200" -"sounds" "1" -"model" "*23" -} -{ -"classname" "trigger_once" -"target" "t28" -"model" "*24" -} -{ -"classname" "trigger_once" -"target" "t12" -"model" "*25" -} -{ -"classname" "monster_ogre" -"origin" "160 1432 128" -"angle" "270" -} -{ -"classname" "monster_ogre" -"origin" "-216 784 128" -"angle" "90" -} -{ -"classname" "info_teleport_destination" -"origin" "-360 888 24" -"spawnflags" "2048" -"targetname" "t1" -} -{ -"classname" "monster_zombie" -"origin" "-288 -232 -296" -"angle" "270" -} -{ -"classname" "monster_zombie" -"origin" "168 -8 -104" -"angle" "90" -} -{ -"classname" "monster_ogre" -"origin" "648 1232 -64" -"angle" "180" -} -{ -"sounds" "1" -"classname" "func_door" -"angle" "-2" -"targetname" "t29" -"model" "*26" -} -{ -"classname" "monster_ogre" -"origin" "520 752 24" -"angle" "90" -"spawnflags" "256" -"targetname" "t29" -} -{ -"classname" "trigger_once" -"target" "t29" -"model" "*27" -} -{ -"classname" "weapon_nailgun" -"origin" "152 1608 136" -"spawnflags" "2048" -} -{ -"classname" "path_corner" -"origin" "544 896 8" -"targetname" "t30" -"target" "t31" -} -{ -"origin" "56 896 72" -"classname" "path_corner" -"target" "t30" -"targetname" "t31" -} -{ -"classname" "path_corner" -"origin" "168 552 8" -"targetname" "t32" -"target" "t33" -} -{ -"origin" "168 1392 8" -"classname" "path_corner" -"target" "t32" -"targetname" "t33" -} -{ -"classname" "monster_knight" -"origin" "240 584 24" -"target" "t32" -} -{ -"classname" "monster_knight" -"origin" "504 960 24" -"target" "t30" -"spawnflags" "256" -} -{ -"classname" "monster_knight" -"origin" "-16 896 88" -"angle" "0" -} -{ -"classname" "monster_knight" -"origin" "256 1224 24" -"angle" "225" -"spawnflags" "256" -} -{ -"target" "t49" -"origin" "-24 1064 16" -"classname" "monster_ogre" -} -{ -"spawnflags" "256" -"angle" "45" -"origin" "-184 1080 128" -"classname" "monster_ogre" -} -{ -"angle" "45" -"origin" "-256 1216 128" -"classname" "monster_knight" -} -{ -"targetname" "t16" -"angle" "270" -"origin" "784 520 56" -"classname" "monster_demon1" -} -{ -"classname" "path_corner" -"origin" "-352 888 16" -"targetname" "t34" -"target" "t35" -} -{ -"origin" "-120 888 8" -"classname" "path_corner" -"target" "t34" -"targetname" "t35" -} -{ -"classname" "monster_ogre" -"origin" "-184 912 24" -"target" "t34" -"spawnflags" "256" -} -{ -"classname" "monster_ogre" -"origin" "-720 896 64" -} -{ -"classname" "monster_knight" -"origin" "-344 760 24" -"angle" "135" -"spawnflags" "256" -} -{ -"classname" "monster_knight" -"origin" "-392 584 24" -"angle" "90" -"spawnflags" "256" -} -{ -"angle" "90" -"classname" "monster_knight" -"origin" "-528 528 24" -"spawnflags" "768" -} -{ -"targetname" "t37" -"target" "t36" -"origin" "-896 968 48" -"classname" "path_corner" -} -{ -"target" "t37" -"targetname" "t36" -"classname" "path_corner" -"origin" "-896 568 48" -} -{ -"spawnflags" "256" -"target" "t36" -"origin" "-840 600 24" -"classname" "monster_ogre" -} -{ -"style" "32" -"targetname" "t15" -"light" "200" -"origin" "-56 304 152" -"classname" "light" -} -{ -"dmg" "100" -"speed" "200" -"targetname" "t15" -"target" "t38" -"classname" "func_train" -"model" "*28" -} -{ -"target" "t39" -"targetname" "t40" -"origin" "-216 280 104" -"classname" "path_corner" -} -{ -"target" "t40" -"targetname" "t38" -"classname" "path_corner" -"origin" "-16 280 104" -} -{ -"target" "t38" -"wait" "-1" -"targetname" "t39" -"origin" "-16 280 104" -"classname" "path_corner" -} -{ -"angle" "180" -"origin" "680 1472 24" -"classname" "monster_ogre" -"spawnflags" "256" -} -{ -"spawnflags" "256" -"angle" "180" -"origin" "864 1448 24" -"classname" "monster_knight" -} -{ -"target" "t42" -"targetname" "t41" -"origin" "1024 1264 104" -"classname" "path_corner" -} -{ -"targetname" "t42" -"target" "t41" -"classname" "path_corner" -"origin" "704 1264 104" -} -{ -"target" "t41" -"origin" "1056 1320 120" -"classname" "monster_knight" -} -{ -"spawnflags" "257" -"origin" "552 1280 128" -"classname" "monster_knight" -} -{ -"spawnflags" "1" -"origin" "432 1280 128" -"classname" "monster_knight" -} -{ -"spawnflags" "2048" -"angle" "0" -"wait" "-1" -"sounds" "0" -"health" "1" -"target" "t28" -"classname" "func_button" -"model" "*29" -} -{ -"origin" "-72 296 104" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "-64 504 104" -} -{ -"origin" "-312 192 -64" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "-80 384 -64" -"classname" "item_spikes" -} -{ -"origin" "-224 976 104" -"classname" "item_shells" -} -{ -"target" "t666" -"classname" "trigger_multiple" -"wait" "10" -"model" "*30" -} -{ -"target" "t45" -"targetname" "t44" -"origin" "984 568 8" -"classname" "path_corner" -} -{ -"target" "t46" -"targetname" "t45" -"classname" "path_corner" -"origin" "976 464 8" -} -{ -"target" "t47" -"targetname" "t46" -"origin" "1224 448 40" -"classname" "path_corner" -} -{ -"target" "t44" -"targetname" "t43" -"classname" "path_corner" -"origin" "1272 520 40" -} -{ -"target" "t48" -"targetname" "t47" -"classname" "path_corner" -"origin" "1224 144 64" -} -{ -"targetname" "t48" -"target" "t43" -"origin" "1344 120 64" -"classname" "path_corner" -} -{ -"target" "t45" -"origin" "968 520 24" -"classname" "monster_ogre" -} -{ -"spawnflags" "256" -"target" "t43" -"origin" "1312 328 80" -"classname" "monster_knight" -} -{ -"spawnflags" "768" -"target" "t47" -"origin" "1240 296 80" -"classname" "monster_ogre" -} -{ -"origin" "-360 1064 -8" -"classname" "weapon_grenadelauncher" -} -{ -"target" "t50" -"targetname" "t49" -"origin" "-16 1168 0" -"classname" "path_corner" -} -{ -"targetname" "t50" -"target" "t49" -"classname" "path_corner" -"origin" "-232 1168 0" -} -{ -"origin" "1448 -128 -56" -"classname" "light" -} -{ -"wait" "-1" -"classname" "func_door" -"angle" "270" -"model" "*31" -} -{ -"wait" "-1" -"targetname" "t52" -"sounds" "3" -"classname" "func_door" -"angle" "90" -"model" "*32" -} -{ -"classname" "light" -"origin" "1984 -184 288" -"light" "350" -} -{ -"classname" "light" -"origin" "1760 -312 -184" -"light" "200" -} -{ -"origin" "1832 -64 -184" -"classname" "light" -"light" "200" -} -{ -"light" "160" -"origin" "1808 -296 -24" -"classname" "light" -} -{ -"classname" "light" -"origin" "1224 -8 -184" -"light" "160" -} -{ -"light" "160" -"origin" "1240 -208 -184" -"classname" "light" -} -{ -"classname" "light" -"origin" "1680 -104 -184" -"light" "160" -} -{ -"light" "160" -"origin" "1584 -304 -184" -"classname" "light" -} -{ -"origin" "1592 -72 288" -"classname" "light" -} -{ -"classname" "light" -"origin" "1328 -232 288" -} -{ -"classname" "light" -"origin" "1280 -16 327" -"light" "250" -} -{ -"classname" "light" -"origin" "1792 -152 88" -"light" "160" -} -{ -"light" "160" -"origin" "1632 -296 88" -"classname" "light" -} -{ -"origin" "1696 -280 288" -"classname" "light" -} -{ -"classname" "light" -"origin" "1240 -224 -8" -"light" "200" -} -{ -"classname" "func_wall" -"spawnflags" "3072" -"model" "*33" -} -{ -"classname" "func_wall" -"spawnflags" "3072" -"model" "*34" -} -{ -"classname" "func_wall" -"spawnflags" "3072" -"model" "*35" -} -{ -"classname" "func_wall" -"spawnflags" "3072" -"model" "*36" -} -{ -"classname" "func_wall" -"spawnflags" "3072" -"model" "*37" -} -{ -"classname" "monster_ogre" -"origin" "1992 -192 200" -"angle" "180" -"spawnflags" "256" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "2" -"targetname" "t51" -"model" "*38" -} -{ -"classname" "trigger_multiple" -"target" "t51" -"model" "*39" -} -{ -"classname" "func_plat" -"model" "*40" -} -{ -"classname" "light" -"origin" "1480 56 -168" -"light" "160" -} -{ -"origin" "1432 280 -64" -"classname" "light" -"light" "160" -} -{ -"light" "160" -"classname" "light" -"origin" "1424 280 96" -} -{ -"light" "160" -"origin" "1472 232 -168" -"classname" "light" -} -{ -"classname" "monster_zombie" -"origin" "1592 -24 160" -"angle" "180" -} -{ -"classname" "monster_zombie" -"origin" "1432 -304 112" -"angle" "135" -"spawnflags" "256" -} -{ -"classname" "monster_zombie" -"origin" "1304 -288 112" -"angle" "90" -"spawnflags" "256" -} -{ -"classname" "monster_zombie" -"origin" "1576 -216 136" -"angle" "180" -"spawnflags" "768" -} -{ -"classname" "monster_zombie" -"origin" "1928 -80 200" -"spawnflags" "768" -"angle" "180" -} -{ -"angle" "180" -"spawnflags" "768" -"origin" "1928 -280 200" -"classname" "monster_zombie" -} -{ -"classname" "trigger_changelevel" -"map" "e2m3" -"model" "*41" -} -{ -"classname" "light" -"origin" "80 1544 40" -"light" "160" -} -{ -"light" "160" -"origin" "-112 1544 40" -"classname" "light" -} -{ -"classname" "item_shells" -"origin" "1056 552 8" -} -{ -"classname" "light" -"origin" "-112 1672 40" -"light" "160" -} -{ -"light" "160" -"origin" "88 1680 40" -"classname" "light" -} -{ -"classname" "item_health" -"origin" "-168 1688 -8" -"spawnflags" "1" -} -{ -"classname" "monster_knight" -"origin" "-112 1616 16" -"angle" "45" -"spawnflags" "768" -} -{ -"classname" "monster_demon1" -"origin" "1760 -208 -216" -"angle" "180" -} -{ -"classname" "trigger_secret" -"model" "*42" -} -{ -"classname" "trigger_secret" -"model" "*43" -} -{ -"classname" "trigger_secret" -"model" "*44" -} -{ -"classname" "trigger_multiple" -"target" "t29" -"model" "*45" -} -{ -"classname" "item_shells" -"origin" "-144 -1728 288" -"spawnflags" "768" -} -{ -"classname" "item_rockets" -"origin" "2000 -304 176" -"spawnflags" "1793" -} -{ -"classname" "item_rockets" -"origin" "2000 -112 176" -"spawnflags" "1793" -} -{ -"origin" "-62 -702 72" -"classname" "ambient_swamp1" -} -{ -"classname" "ambient_swamp2" -"origin" "386 -702 72" -} -{ -"origin" "-246 -470 -264" -"classname" "ambient_swamp2" -} -{ -"classname" "ambient_swamp1" -"origin" "554 -454 -264" -} -{ -"origin" "162 -430 -264" -"classname" "ambient_swamp1" -} -{ -"spawnflags" "1" -"origin" "-72 576 104" -"classname" "item_shells" -} -{ -"spawnflags" "2048" -"wait" "10" -"target" "t16" -"classname" "trigger_multiple" -"model" "*46" -} -{ -"targetname" "t16" -"sounds" "4" -"wait" "-1" -"angle" "-1" -"classname" "func_door" -"model" "*47" -} -{ -"origin" "-184 1480 168" -"classname" "light" -"light" "160" -} -{ -"classname" "light" -"origin" "-224 1592 168" -"light" "100" -} -{ -"target" "t52" -"classname" "trigger_once" -"model" "*48" -} -{ -"mangle" "20 30 0" -"origin" "1224 -288 336" -"classname" "info_intermission" -} -{ -"mangle" "20 180 0" -"origin" "-352 760 240" -"classname" "info_intermission" -} -{ -"mangle" "20 135 0" -"origin" "480 -440 208" -"classname" "info_intermission" -} -{ -"angle" "90" -"origin" "-176 -1904 264" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "-128 -1848 264" -"angle" "90" -} -{ -"angle" "90" -"origin" "-192 -1808 264" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "-320 -1824 264" -"angle" "90" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*49" -} -{ -"spawnflags" "1792" -"origin" "200 -664 0" -"classname" "weapon_lightning" -} -{ -"origin" "-184 1512 144" -"classname" "item_artifact_super_damage" -} -{ -"classname" "item_cells" -"origin" "240 -664 0" -"spawnflags" "1793" -} -{ -"classname" "item_cells" -"origin" "392 640 0" -"spawnflags" "1793" -} -{ -"classname" "item_cells" -"origin" "-168 456 104" -"spawnflags" "1793" -} -{ -"classname" "func_door" -"angle" "-1" -"spawnflags" "1" -"wait" "6" -"speed" "1000" -"sounds" "3" -"targetname" "t15" -"model" "*50" -} -{ -"classname" "weapon_grenadelauncher" -"origin" "1312 280 56" -"spawnflags" "3584" -} -{ -"sounds" "2" -"wait" "5" -"message" "Shoot the buttons..." -"spawnflags" "3584" -"classname" "trigger_multiple" -"targetname" "t53" -"model" "*51" -} -{ -"classname" "trigger_relay" -"origin" "-72 -320 48" -"targetname" "t13" -"killtarget" "t53" -} diff --git a/Misc/pak/maps/e2m3.diff b/Misc/pak/maps/e2m3.diff new file mode 100644 index 000000000..4d51967d7 --- /dev/null +++ b/Misc/pak/maps/e2m3.diff @@ -0,0 +1,74 @@ +--- e2m3.ent ++++ e2m3@237a.ent +@@ -1226,21 +1226,23 @@ + { + "classname" "func_door" + "angle" "-2" + "spawnflags" "1" + "targetname" "t11" + "wait" "10" + "model" "*25" ++"lip" "7" // svdijk -- added to prevent z-fighting + } + { + "classname" "func_door_secret" + "angle" "90" + "spawnflags" "8" + "targetname" "t11" + "model" "*26" ++"t_length" "65" // svdijk -- added to prevent z-fighting + } + { + "classname" "light" + "origin" "1248 -288 312" + "light" "150" + } + { +@@ -1907,14 +1909,15 @@ + } + { + "classname" "func_door_secret" + "spawnflags" "2051" + "targetname" "t36" + "angle" "90" + "model" "*37" ++"t_length" "65" // svdijk -- added to prevent z-fighting + } + { + "classname" "light" + "origin" "-1288 640 -80" + "light" "160" + } + { +@@ -1939,14 +1942,15 @@ + } + { + "classname" "func_door_secret" + "targetname" "t36" + "angle" "270" + "spawnflags" "2049" + "model" "*38" ++"t_length" "65" // svdijk -- added to prevent z-fighting + } + { + "classname" "item_armor2" + "origin" "1128 600 -176" + "spawnflags" "1024" + } + { +@@ -2643,14 +2647,15 @@ + } + { + "classname" "func_door_secret" + "angle" "180" + "spawnflags" "2" + "targetname" "t41" + "model" "*66" ++"t_length" "65" // svdijk -- added to prevent z-fighting + } + { + "classname" "trigger_multiple" + "target" "t41" + "model" "*67" + } + { diff --git a/Misc/pak/maps/e2m3.ent.orig b/Misc/pak/maps/e2m3.ent.orig deleted file mode 100644 index 3ff5bd575..000000000 --- a/Misc/pak/maps/e2m3.ent.orig +++ /dev/null @@ -1,2860 +0,0 @@ -{ -"classname" "worldspawn" -"wad" "gfx/jr_med.wad" -"worldtype" "0" -"sounds" "9" -"message" "the Crypt of Decay" -} -{ -"classname" "light" -"origin" "192 -648 128" -} -{ -"classname" "info_player_start" -"origin" "688 -1600 -312" -"angle" "180" -} -{ -"classname" "light_flame_large_yellow" -"origin" "650 -438 4" -} -{ -"origin" "386 -438 4" -"classname" "light_flame_large_yellow" -} -{ -"origin" "66 -886 4" -"classname" "light_flame_large_yellow" -} -{ -"origin" "322 -886 4" -"classname" "light_flame_large_yellow" -} -{ -"light" "250" -"origin" "192 -1408 288" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "192 -1088 288" -} -{ -"light" "250" -"origin" "112 -1248 272" -"classname" "light" -} -{ -"light" "250" -"classname" "light" -"origin" "272 -1248 272" -} -{ -"light" "200" -"origin" "192 -1056 32" -"classname" "light" -} -{ -"light" "150" -"origin" "192 -1248 24" -"classname" "light" -} -{ -"origin" "194 -1462 108" -"classname" "light_flame_large_yellow" -} -{ -"origin" "194 -1030 164" -"classname" "light_torch_small_walltorch" -} -{ -"light" "150" -"origin" "192 -1440 32" -"classname" "light" -} -{ -"sounds" "2" -"classname" "func_plat" -"spawnflags" "1" -"model" "*1" -} -{ -"origin" "226 -1670 -212" -"classname" "light_flame_large_yellow" -} -{ -"light" "150" -"origin" "88 -1552 -184" -"classname" "light" -} -{ -"origin" "-22 -1374 -212" -"classname" "light_flame_large_yellow" -} -{ -"light" "150" -"origin" "328 -1256 -184" -"classname" "light" -} -{ -"light" "150" -"classname" "light" -"origin" "56 -1256 -184" -} -{ -"classname" "light" -"origin" "248 -1480 -184" -"light" "150" -} -{ -"light" "250" -"origin" "552 -1608 -72" -"classname" "light" -} -{ -"light" "150" -"origin" "432 -1656 -224" -"classname" "light" -} -{ -"light" "150" -"origin" "432 -1496 -224" -"classname" "light" -} -{ -"light" "100" -"origin" "192 -1248 -40" -"classname" "light" -} -{ -"origin" "10 -438 4" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "-254 -438 4" -} -{ -"light" "150" -"origin" "192 -704 -136" -"classname" "light" -} -{ -"light" "250" -"origin" "192 -512 -136" -"classname" "light" -} -{ -"classname" "light" -"origin" "416 -512 -136" -"light" "150" -} -{ -"light" "150" -"origin" "-32 -512 -136" -"classname" "light" -} -{ -"classname" "light" -"origin" "-208 -512 -136" -"light" "150" -} -{ -"light" "150" -"origin" "592 -512 -136" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 -840 -136" -"light" "150" -} -{ -"light" "150" -"origin" "-352 -672 -168" -"classname" "light" -} -{ -"classname" "light" -"origin" "-320 -832 -168" -"light" "150" -} -{ -"light" "150" -"origin" "-320 -512 -168" -"classname" "light" -} -{ -"classname" "light" -"origin" "696 -512 -168" -"light" "150" -} -{ -"light" "150" -"origin" "736 -672 -168" -"classname" "light" -} -{ -"classname" "light" -"origin" "704 -832 -168" -"light" "150" -} -{ -"light" "150" -"origin" "512 -864 -168" -"classname" "light" -} -{ -"classname" "light" -"origin" "-128 -864 -168" -"light" "150" -} -{ -"light" "200" -"origin" "-128 -320 8" -"classname" "light" -} -{ -"classname" "light" -"origin" "512 -320 8" -"light" "200" -} -{ -"origin" "384 -24 32" -"classname" "light" -} -{ -"classname" "light" -"origin" "0 -24 32" -} -{ -"light" "200" -"origin" "416 -192 -8" -"classname" "light" -} -{ -"classname" "light" -"origin" "-32 -192 -8" -"light" "200" -} -{ -"light" "200" -"origin" "840 48 72" -"classname" "light" -} -{ -"light" "150" -"origin" "576 -24 -56" -"classname" "light" -} -{ -"light" "200" -"origin" "624 -24 72" -"classname" "light" -} -{ -"origin" "1002 354 -60" -"classname" "light_flame_large_yellow" -} -{ -"light" "100" -"origin" "1000 352 -128" -"classname" "light" -} -{ -"classname" "light" -"origin" "736 8 72" -"light" "200" -} -{ -"light" "200" -"origin" "936 88 72" -"classname" "light" -} -{ -"light" "150" -"origin" "688 -8 -32" -"classname" "light" -} -{ -"classname" "light" -"origin" "784 24 -104" -"light" "150" -} -{ -"light" "150" -"origin" "888 72 -32" -"classname" "light" -} -{ -"light" "200" -"origin" "872 208 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "872 400 -56" -"light" "200" -} -{ -"light" "200" -"origin" "872 592 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "744 568 88" -"light" "150" -} -{ -"light" "150" -"origin" "744 648 88" -"classname" "light" -} -{ -"classname" "light" -"origin" "704 608 -80" -"light" "150" -} -{ -"origin" "866 730 -60" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light" -"origin" "864 728 -128" -"light" "100" -} -{ -"sounds" "3" -"wait" "-1" -"targetname" "t8" -"spawnflags" "2049" -"angle" "0" -"classname" "func_door" -"model" "*2" -} -{ -"spawnflags" "2048" -"angle" "90" -"target" "t8" -"classname" "func_button" -"wait" "-1" -"model" "*3" -} -{ -"origin" "520 608 -64" -"classname" "light" -} -{ -"light" "400" -"origin" "192 608 -24" -"classname" "light" -} -{ -"sounds" "1" -"wait" "-1" -"angle" "270" -"spawnflags" "2058" -"classname" "func_door_secret" -"targetname" "t9" -"model" "*4" -} -{ -"light" "150" -"origin" "1064 640 -112" -"classname" "light" -} -{ -"targetname" "t9" -"angle" "180" -"origin" "1024 640 -152" -"classname" "monster_zombie" -} -{ -"targetname" "t9" -"angle" "180" -"origin" "1120 672 -152" -"classname" "monster_zombie" -} -{ -"targetname" "t9" -"angle" "180" -"origin" "1088 600 -152" -"classname" "monster_zombie" -} -{ -"origin" "976 336 -176" -"classname" "item_health" -} -{ -"light" "150" -"origin" "192 608 -104" -"classname" "light" -} -{ -"origin" "192 288 -64" -"classname" "light" -} -{ -"classname" "light_flame_large_yellow" -"origin" "66 106 4" -"light" "200" -} -{ -"light" "200" -"origin" "-30 106 4" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light" -"origin" "504 120 -248" -"light" "200" -} -{ -"light" "200" -"origin" "704 224 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "704 472 -248" -"light" "200" -} -{ -"light" "200" -"origin" "304 112 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "80 112 -248" -"light" "200" -} -{ -"light" "200" -"origin" "720 608 -248" -"classname" "light" -} -{ -"spawnflags" "2048" -"sounds" "1" -"wait" "-1" -"targetname" "t3" -"classname" "func_door" -"angle" "90" -"model" "*5" -} -{ -"spawnflags" "2048" -"wait" "-1" -"angle" "270" -"classname" "func_door" -"message" "This door opens nearby..." -"model" "*6" -} -{ -"spawnflags" "2048" -"target" "t3" -"wait" "-1" -"classname" "func_button" -"angle" "180" -"model" "*7" -} -{ -"light" "250" -"origin" "-448 184 0" -"classname" "light" -} -{ -"light" "150" -"origin" "-552 280 -224" -"classname" "light" -} -{ -"classname" "light" -"origin" "-392 280 -224" -"light" "150" -} -{ -"light" "150" -"origin" "-416 -32 104" -"classname" "light" -} -{ -"classname" "light" -"origin" "-320 -32 104" -"light" "150" -} -{ -"light" "150" -"origin" "-224 -32 104" -"classname" "light" -} -{ -"light" "250" -"origin" "-352 -32 -32" -"classname" "light" -} -{ -"light" "200" -"origin" "-1160 88 -248" -"classname" "light" -} -{ -"light" "200" -"origin" "-1048 88 -32" -"classname" "light" -} -{ -"light" "200" -"classname" "light" -"origin" "-1160 224 -32" -} -{ -"origin" "-742 658 -44" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "-926 658 -44" -} -{ -"light" "200" -"origin" "-736 632 -96" -"classname" "light" -} -{ -"classname" "light" -"origin" "-928 632 -96" -"light" "200" -} -{ -"light" "150" -"origin" "-600 104 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-696 424 -248" -"light" "150" -} -{ -"light" "150" -"origin" "-1152 408 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-944 432 -248" -"light" "150" -} -{ -"light" "150" -"origin" "-856 64 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-160 152 -248" -"light" "150" -} -{ -"light" "150" -"origin" "-160 448 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-328 464 -248" -"light" "150" -} -{ -"light" "150" -"origin" "-256 176 -248" -"classname" "light" -} -{ -"origin" "-574 410 -172" -"classname" "light_flame_large_yellow" -} -{ -"classname" "light_flame_large_yellow" -"origin" "-470 410 -172" -} -{ -"target" "t4" -"classname" "trigger_teleport" -"model" "*8" -} -{ -"light" "200" -"style" "2" -"origin" "-760 576 -216" -"classname" "light" -} -{ -"targetname" "t4" -"angle" "180" -"origin" "120 -32 -112" -"classname" "info_teleport_destination" -} -{ -"light" "200" -"origin" "-264 384 112" -"classname" "light" -} -{ -"classname" "light" -"origin" "-264 288 112" -"light" "200" -} -{ -"light" "200" -"origin" "-264 192 112" -"classname" "light" -} -{ -"classname" "light" -"origin" "-264 480 112" -"light" "200" -} -{ -"light" "250" -"origin" "-264 304 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "-520 424 0" -"light" "250" -} -{ -"light" "200" -"origin" "-1120 608 72" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1024 584 72" -"light" "200" -} -{ -"light" "200" -"origin" "-928 584 72" -"classname" "light" -} -{ -"classname" "light" -"origin" "-832 584 72" -"light" "200" -} -{ -"light" "200" -"origin" "-544 584 72" -"classname" "light" -} -{ -"classname" "light" -"origin" "-640 584 72" -"light" "200" -} -{ -"light" "150" -"origin" "-480 768 56" -"classname" "light" -} -{ -"classname" "light" -"origin" "-384 768 56" -"light" "150" -} -{ -"classname" "light" -"origin" "-712 120 -32" -"light" "200" -} -{ -"sounds" "3" -"wait" "-1" -"targetname" "t5" -"spawnflags" "2049" -"angle" "180" -"classname" "func_door" -"model" "*9" -} -{ -"spawnflags" "2048" -"angle" "270" -"target" "t5" -"wait" "-1" -"classname" "func_button" -"model" "*10" -} -{ -"style" "32" -"targetname" "t5" -"light" "200" -"origin" "-352 552 -56" -"classname" "light" -} -{ -"light" "150" -"origin" "-432 768 -56" -"classname" "light" -} -{ -"light" "150" -"origin" "-520 680 -56" -"classname" "light" -} -{ -"spawnflags" "2048" -"sounds" "3" -"targetname" "t5" -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"model" "*11" -} -{ -"sounds" "3" -"targetname" "t5" -"spawnflags" "2049" -"wait" "-1" -"angle" "90" -"classname" "func_door" -"model" "*12" -} -{ -"origin" "-72 848 -56" -"classname" "light" -} -{ -"origin" "-120 600 -8" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 904 -8" -} -{ -"light" "200" -"origin" "192 888 -248" -"classname" "light" -} -{ -"classname" "light" -"origin" "-104 600 -248" -"light" "200" -} -{ -"light" "200" -"origin" "376 984 -120" -"classname" "light" -} -{ -"classname" "light" -"origin" "504 760 -120" -"light" "200" -} -{ -"light" "200" -"origin" "-32 608 200" -"classname" "light" -} -{ -"spawnflags" "2048" -"sounds" "3" -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"model" "*13" -} -{ -"origin" "-16 1456 16" -"classname" "light" -} -{ -"light" "200" -"origin" "384 1248 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "384 1440 -56" -"light" "200" -} -{ -"light" "150" -"origin" "256 1440 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 1248 -56" -"light" "200" -} -{ -"light" "200" -"origin" "384 1344 -88" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 1152 -88" -"light" "200" -} -{ -"classname" "light" -"origin" "8 1456 -120" -"light" "200" -} -{ -"spawnflags" "2048" -"sounds" "1" -"classname" "item_key2" -"origin" "-16 1456 -152" -} -{ -"classname" "func_door" -"angle" "-1" -"targetname" "t6" -"speed" "400" -"wait" "-1" -"sounds" "4" -"model" "*14" -} -{ -"classname" "func_door" -"angle" "-1" -"targetname" "t6" -"speed" "400" -"wait" "-1" -"sounds" "4" -"model" "*15" -} -{ -"classname" "func_door" -"angle" "-1" -"targetname" "t6" -"speed" "400" -"wait" "-1" -"sounds" "4" -"spawnflags" "2048" -"model" "*16" -} -{ -"classname" "trigger_once" -"target" "t6" -"model" "*17" -} -{ -"classname" "light" -"origin" "-192 1456 -136" -"light" "80" -} -{ -"classname" "light" -"origin" "-16 1280 -136" -"light" "80" -} -{ -"spawnflags" "768" -"classname" "monster_hell_knight" -"origin" "-16 1280 -168" -"angle" "90" -"targetname" "t6" -} -{ -"spawnflags" "256" -"angle" "270" -"origin" "-16 1632 -168" -"classname" "monster_hell_knight" -"targetname" "t6" -} -{ -"classname" "monster_hell_knight" -"origin" "-192 1456 -168" -"angle" "0" -"targetname" "t6" -} -{ -"classname" "light" -"origin" "152 1440 -56" -"light" "150" -} -{ -"classname" "item_shells" -"origin" "-104 1512 -192" -"spawnflags" "1" -} -{ -"wait" "-1" -"classname" "func_door" -"angle" "0" -"spawnflags" "2056" -"model" "*18" -} -{ -"wait" "-1" -"classname" "func_door" -"angle" "180" -"spawnflags" "2056" -"model" "*19" -} -{ -"classname" "light" -"origin" "-1120 832 -48" -"light" "250" -} -{ -"classname" "light" -"origin" "-1120 976 -24" -"light" "250" -} -{ -"classname" "light" -"origin" "-1240 1296 216" -"light" "200" -} -{ -"light" "200" -"origin" "-1240 1416 216" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1240 1176 216" -"light" "200" -} -{ -"classname" "light" -"origin" "-712 1416 216" -"light" "200" -} -{ -"light" "200" -"origin" "-712 1296 216" -"classname" "light" -} -{ -"classname" "light" -"origin" "-712 1176 216" -"light" "200" -} -{ -"light" "200" -"origin" "-856 1296 216" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1096 1296 216" -"light" "200" -} -{ -"light" "200" -"origin" "-976 1296 216" -"classname" "light" -} -{ -"classname" "light_flame_small_white" -"origin" "-1318 1514 -8" -} -{ -"origin" "-1318 1514 64" -"classname" "light_flame_small_white" -} -{ -"classname" "light_flame_small_white" -"origin" "-1318 1514 144" -} -{ -"origin" "-634 1078 -8" -"classname" "light_flame_small_white" -} -{ -"classname" "light_flame_small_white" -"origin" "-634 1078 64" -} -{ -"origin" "-634 1078 144" -"classname" "light_flame_small_white" -} -{ -"classname" "func_plat" -"spawnflags" "1" -"model" "*20" -} -{ -"classname" "light" -"origin" "-320 1536 184" -"light" "250" -} -{ -"classname" "light" -"origin" "-376 1312 120" -"light" "250" -} -{ -"classname" "light" -"origin" "-16 1536 184" -"light" "200" -} -{ -"light" "200" -"origin" "-560 1312 56" -"classname" "light" -} -{ -"classname" "light" -"origin" "24 1120 216" -"light" "150" -} -{ -"classname" "light" -"origin" "192 608 176" -"light" "200" -} -{ -"wait" "-1" -"classname" "func_door" -"angle" "90" -"spawnflags" "2049" -"targetname" "t7" -"sounds" "1" -"model" "*21" -} -{ -"light" "150" -"origin" "400 1104 224" -"classname" "light" -} -{ -"light" "150" -"origin" "-200 1056 224" -"classname" "light" -} -{ -"light" "200" -"origin" "192 960 224" -"classname" "light" -} -{ -"light" "200" -"origin" "192 784 224" -"classname" "light" -} -{ -"classname" "light" -"origin" "672 264 184" -"light" "200" -} -{ -"light" "200" -"origin" "384 184 184" -"classname" "light" -} -{ -"classname" "light" -"origin" "512 256 8" -"light" "200" -} -{ -"classname" "light" -"origin" "8 184 200" -"light" "200" -} -{ -"classname" "light" -"origin" "584 744 200" -"light" "200" -} -{ -"classname" "light" -"origin" "0 432 200" -"light" "200" -} -{ -"classname" "trigger_once" -"targetname" "t8" -"target" "t9" -"delay" "10" -"model" "*22" -} -{ -"classname" "light" -"origin" "192 -72 216" -"light" "250" -} -{ -"classname" "light" -"origin" "360 -168 360" -"light" "200" -} -{ -"classname" "light" -"origin" "296 -168 360" -"light" "200" -} -{ -"origin" "472 -168 368" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"classname" "light" -"origin" "408 -168 360" -} -{ -"classname" "light" -"origin" "384 -168 248" -"light" "200" -} -{ -"classname" "light" -"origin" "936 -304 328" -"light" "200" -} -{ -"light" "200" -"origin" "1000 -232 360" -"classname" "light" -} -{ -"classname" "light" -"origin" "864 -232 360" -"light" "200" -} -{ -"light" "200" -"origin" "864 -368 360" -"classname" "light" -} -{ -"classname" "light" -"origin" "1000 -368 360" -"light" "200" -} -{ -"classname" "light" -"origin" "736 -248 280" -"light" "200" -} -{ -"light" "200" -"origin" "552 -216 280" -"classname" "light" -} -{ -"classname" "light" -"origin" "16 144 -32" -"light" "200" -} -{ -"classname" "light" -"origin" "0 432 -136" -"light" "200" -} -{ -"classname" "light" -"origin" "192 384 184" -"light" "200" -} -{ -"light" "200" -"origin" "192 192 184" -"classname" "light" -} -{ -"spawnflags" "2048" -"classname" "func_button" -"wait" "-1" -"target" "t7" -"model" "*23" -} -{ -"style" "33" -"targetname" "t7" -"classname" "light" -"origin" "176 1152 200" -"target" "t10" -} -{ -"classname" "info_null" -"origin" "292 1152 180" -"targetname" "t10" -} -{ -"classname" "light" -"origin" "192 1224 200" -"light" "150" -} -{ -"light" "150" -"origin" "192 1376 200" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 1536 200" -"light" "200" -} -{ -"light" "150" -"origin" "192 1080 200" -"classname" "light" -} -{ -"classname" "weapon_nailgun" -"origin" "184 -1520 -272" -} -{ -"classname" "func_button" -"target" "t11" -"angle" "-1" -"targetname" "t12" -"lip" "4" -"wait" "0.1" -"speed" "300" -"health" "1" -"model" "*24" -} -{ -"classname" "func_door" -"angle" "-2" -"spawnflags" "1" -"targetname" "t11" -"wait" "10" -"model" "*25" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "8" -"targetname" "t11" -"model" "*26" -} -{ -"classname" "light" -"origin" "1248 -288 312" -"light" "150" -} -{ -"light" "200" -"origin" "1176 -400 352" -"classname" "light" -} -{ -"classname" "item_health" -"origin" "1336 -536 256" -"spawnflags" "2" -} -{ -"classname" "light" -"origin" "1320 -488 352" -"light" "200" -} -{ -"classname" "trigger_multiple" -"target" "t11" -"wait" "10" -"model" "*27" -} -{ -"classname" "item_armor1" -"origin" "192 -592 -64" -} -{ -"classname" "item_shells" -"origin" "176 592 -160" -"spawnflags" "1" -} -{ -"classname" "weapon_nailgun" -"origin" "-80 1456 -192" -"spawnflags" "1792" -} -{ -"classname" "weapon_rocketlauncher" -"origin" "56 1144 128" -"spawnflags" "1792" -} -{ -"classname" "weapon_grenadelauncher" -"origin" "-736 608 -280" -"spawnflags" "1792" -} -{ -"classname" "item_spikes" -"origin" "1120 -384 256" -"spawnflags" "1" -} -{ -"classname" "item_rockets" -"origin" "840 -432 192" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "-456 312 -80" -} -{ -"classname" "monster_zombie" -"origin" "-1152 96 -88" -"spawnflags" "256" -"target" "t36" -} -{ -"origin" "-1120 32 -88" -"classname" "monster_zombie" -"spawnflags" "768" -"target" "t36" -} -{ -"classname" "monster_zombie" -"origin" "-1192 168 -88" -"target" "t36" -} -{ -"classname" "monster_shambler" -"origin" "-1120 1104 -56" -"angle" "270" -} -{ -"classname" "monster_hell_knight" -"origin" "-336 1312 8" -"angle" "180" -} -{ -"classname" "monster_ogre" -"origin" "-698 1446 -56" -"angle" "270" -"spawnflags" "256" -} -{ -"classname" "monster_hell_knight" -"origin" "-888 1128 8" -"angle" "90" -"spawnflags" "256" -} -{ -"classname" "item_health" -"origin" "-336 784 -128" -} -{ -"origin" "-408 608 -128" -"classname" "item_health" -} -{ -"classname" "path_corner" -"origin" "-1096 584 -120" -"targetname" "t13" -"target" "t14" -} -{ -"origin" "-496 584 -120" -"classname" "path_corner" -"targetname" "t14" -"target" "t13" -} -{ -"classname" "monster_demon1" -"origin" "-712 576 -104" -"angle" "180" -"target" "t13" -} -{ -"classname" "path_corner" -"origin" "-528 472 -96" -"targetname" "t15" -"target" "t16" -} -{ -"origin" "-368 -32 -96" -"classname" "path_corner" -"target" "t15" -"targetname" "t16" -} -{ -"classname" "monster_ogre" -"origin" "-466 262 -56" -"target" "t16" -"spawnflags" "256" -} -{ -"target" "t22" -"targetname" "t21" -"origin" "56 -184 -120" -"classname" "path_corner" -} -{ -"target" "t21" -"targetname" "t20" -"classname" "path_corner" -"origin" "-128 -224 -120" -} -{ -"target" "t20" -"targetname" "t19" -"origin" "-128 -504 -56" -"classname" "path_corner" -} -{ -"target" "t19" -"targetname" "t18" -"classname" "path_corner" -"origin" "512 -504 -56" -} -{ -"target" "t18" -"targetname" "t17" -"origin" "512 -224 -120" -"classname" "path_corner" -} -{ -"targetname" "t26" -"target" "t17" -"classname" "path_corner" -"origin" "328 -184 -120" -} -{ -"target" "t23" -"targetname" "t22" -"classname" "path_corner" -"origin" "-128 -200 -120" -} -{ -"target" "t24" -"targetname" "t23" -"classname" "path_corner" -"origin" "-128 -552 -56" -} -{ -"target" "t25" -"targetname" "t24" -"origin" "512 -552 -56" -"classname" "path_corner" -} -{ -"target" "t26" -"targetname" "t25" -"classname" "path_corner" -"origin" "512 -200 -120" -} -{ -"spawnflags" "256" -"target" "t21" -"origin" "0 -184 -104" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "1" -"origin" "376 -160 -104" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "190 -706 -40" -"classname" "monster_ogre" -} -{ -"spawnflags" "768" -"angle" "90" -"origin" "192 -1408 24" -"classname" "monster_hell_knight" -} -{ -"origin" "40 -1424 0" -"classname" "item_shells" -"spawnflags" "1" -} -{ -"spawnflags" "1" -"origin" "304 -1096 0" -"classname" "item_health" -} -{ -"origin" "328 -1280 -272" -"classname" "item_health" -} -{ -"origin" "40 -1256 -272" -"classname" "item_spikes" -} -{ -"target" "t28" -"targetname" "t27" -"origin" "864 176 -168" -"classname" "path_corner" -} -{ -"target" "t27" -"targetname" "t28" -"classname" "path_corner" -"origin" "864 616 -168" -} -{ -"target" "t27" -"origin" "862 446 -152" -"classname" "monster_ogre" -} -{ -"spawnflags" "768" -"angle" "180" -"origin" "526 -26 -104" -"classname" "monster_ogre" -} -{ -"spawnflags" "256" -"angle" "0" -"origin" "-72 -24 -104" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "256" -"origin" "-274 -34 -104" -"classname" "monster_ogre" -} -{ -"spawnflags" "768" -"angle" "270" -"origin" "-512 760 -104" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "1793" -"origin" "336 1104 128" -"classname" "item_rockets" -} -{ -"angle" "45" -"spawnflags" "256" -"origin" "104 256 -136" -"classname" "monster_zombie" -} -{ -"spawnflags" "769" -"angle" "90" -"origin" "192 488 -136" -"classname" "monster_hell_knight" -} -{ -"wait" "1" -"speed" "250" -"lip" "16" -"spawnflags" "5" -"targetname" "t29" -"dmg" "20" -"angle" "180" -"classname" "func_door" -"model" "*28" -} -{ -"wait" "1" -"targetname" "t29" -"speed" "250" -"dmg" "20" -"lip" "16" -"spawnflags" "5" -"classname" "func_door" -"sounds" "1" -"model" "*29" -} -{ -"wait" "2" -"target" "t29" -"classname" "trigger_multiple" -"model" "*30" -} -{ -"origin" "506 1762 -124" -"classname" "light_torch_small_walltorch" -"style" "1" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "274 2010 -124" -} -{ -"light" "200" -"origin" "152 1824 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "288 1824 -40" -"light" "200" -} -{ -"light" "200" -"origin" "288 1696 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "152 1704 -40" -"light" "200" -} -{ -"light" "220" -"origin" "0 1704 -40" -"classname" "light" -} -{ -"angle" "180" -"classname" "func_door_secret" -"targetname" "t35" -"spawnflags" "16" -"sounds" "1" -"model" "*31" -} -{ -"spawnflags" "2" -"origin" "-16 1816 -192" -"classname" "item_health" -} -{ -"origin" "432 1672 -320" -"classname" "light" -"light" "220" -} -{ -"spawnflags" "1792" -"origin" "-16 1752 -192" -"classname" "item_rockets" -} -{ -"angle" "270" -"origin" "-192 1580 168" -"classname" "trap_spikeshooter" -"targetname" "t32" -} -{ -"spawnflags" "256" -"classname" "trap_spikeshooter" -"origin" "236 1536 168" -"angle" "180" -"targetname" "t32" -} -{ -"classname" "trap_spikeshooter" -"origin" "0 1580 168" -"angle" "270" -"targetname" "t32" -} -{ -"angle" "90" -"origin" "-96 1492 168" -"classname" "trap_spikeshooter" -"targetname" "t32" -} -{ -"classname" "trap_spikeshooter" -"origin" "148 1376 168" -"angle" "0" -"targetname" "t33" -} -{ -"angle" "180" -"origin" "236 1256 168" -"classname" "trap_spikeshooter" -"targetname" "t33" -} -{ -"spawnflags" "256" -"classname" "trap_spikeshooter" -"origin" "192 1580 168" -"angle" "270" -"targetname" "t33" -} -{ -"spawnflags" "257" -"angle" "90" -"origin" "192 -16 153" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "257" -"angle" "180" -"origin" "864 -248 217" -"classname" "monster_shambler" -} -{ -"angle" "180" -"origin" "464 -184 185" -"classname" "monster_hell_knight" -} -{ -"classname" "monster_hell_knight" -"origin" "192 -176 153" -"angle" "90" -"spawnflags" "1" -"target" "t31" -} -{ -"spawnflags" "769" -"angle" "90" -"origin" "190 1166 153" -"classname" "monster_ogre" -} -{ -"spawnflags" "2048" -"origin" "48 1456 -192" -"classname" "weapon_grenadelauncher" -} -{ -"spawnflags" "1" -"origin" "-96 1376 -192" -"classname" "item_rockets" -} -{ -"angle" "270" -"spawnflags" "768" -"classname" "monster_ogre" -"origin" "862 662 -152" -} -{ -"light" "120" -"origin" "192 -352 -264" -"classname" "light" -} -{ -"spawnflags" "768" -"origin" "326 -1490 -248" -"classname" "monster_ogre" -"angle" "180" -"target" "t42" -} -{ -"origin" "192 552 128" -"classname" "item_health" -} -{ -"spawnflags" "1024" -"classname" "item_health" -"origin" "176 672 128" -} -{ -"spawnflags" "1025" -"origin" "184 1312 128" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "-16 1480 128" -"spawnflags" "1025" -} -{ -"origin" "672 -328 176" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "776 -192 176" -} -{ -"origin" "784 312 -176" -"classname" "item_shells" -} -{ -"spawnflags" "256" -"angle" "315" -"origin" "-26 1094 152" -"classname" "monster_ogre" -} -{ -"classname" "monster_ogre" -"origin" "406 1094 152" -"angle" "225" -"spawnflags" "768" -} -{ -"spawnflags" "1" -"origin" "-200 1128 128" -"classname" "item_rockets" -} -{ -"origin" "-550 -478 212" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "-550 -166 212" -} -{ -"origin" "-214 -326 252" -"classname" "light_torch_small_walltorch" -} -{ -"light" "150" -"origin" "-120 -176 192" -"classname" "light" -} -{ -"classname" "light" -"origin" "56 -176 192" -"light" "150" -} -{ -"origin" "-816 1488 -80" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "-752 1488 -80" -} -{ -"spawnflags" "1536" -"origin" "-688 1488 -80" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "176 1264 -160" -"classname" "item_shells" -} -{ -"classname" "func_door" -"angle" "270" -"targetname" "t31" -"wait" "-1" -"spawnflags" "2048" -"model" "*32" -} -{ -"wait" "-1" -"sounds" "1" -"speed" "300" -"classname" "func_door" -"angle" "90" -"model" "*33" -} -{ -"speed" "300" -"classname" "func_door" -"angle" "270" -"wait" "-1" -"model" "*34" -} -{ -"classname" "item_health" -"origin" "400 1464 -160" -"spawnflags" "1024" -} -{ -"classname" "item_health" -"origin" "-1136 528 -128" -} -{ -"classname" "monster_ogre" -"origin" "-370 -218 88" -"targetname" "t31" -"spawnflags" "1" -} -{ -"classname" "monster_hell_knight" -"origin" "-64 -176 152" -"angle" "0" -"spawnflags" "768" -"targetname" "t31" -} -{ -"classname" "item_health" -"origin" "-488 -480 64" -} -{ -"classname" "light" -"origin" "680 -1600 -160" -} -{ -"classname" "item_spikes" -"origin" "984 -192 192" -"spawnflags" "1" -} -{ -"classname" "monster_ogre" -"origin" "-490 -410 88" -"angle" "45" -} -{ -"classname" "trigger_multiple" -"target" "t32" -"wait" "1" -"spawnflags" "1024" -"targetname" "t44" -"model" "*35" -} -{ -"classname" "trigger_multiple" -"target" "t33" -"wait" "1" -"spawnflags" "1024" -"model" "*36" -} -{ -"classname" "item_rockets" -"origin" "-96 272 -384" -} -{ -"classname" "weapon_supernailgun" -"origin" "-1200 208 -112" -"spawnflags" "1792" -} -{ -"classname" "func_door_secret" -"spawnflags" "2051" -"targetname" "t36" -"angle" "90" -"model" "*37" -} -{ -"classname" "light" -"origin" "-1288 640 -80" -"light" "160" -} -{ -"light" "160" -"origin" "-1288 128 -80" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1288 264 -80" -"light" "160" -} -{ -"light" "160" -"origin" "-1288 392 -80" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1288 520 -80" -"light" "160" -} -{ -"classname" "func_door_secret" -"targetname" "t36" -"angle" "270" -"spawnflags" "2049" -"model" "*38" -} -{ -"classname" "item_armor2" -"origin" "1128 600 -176" -"spawnflags" "1024" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "11" -"targetname" "t34" -"model" "*39" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "-246 -1310 -204" -"light" "250" -} -{ -"classname" "trigger_once" -"target" "t34" -"model" "*40" -} -{ -"classname" "item_spikes" -"origin" "-240 -1288 -312" -"spawnflags" "1" -} -{ -"spawnflags" "1" -"origin" "-240 -1368 -312" -"classname" "item_spikes" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "-2" -"spawnflags" "3585" -"wait" "90" -"targetname" "t6" -"model" "*41" -} -{ -"sounds" "3" -"classname" "func_door" -"targetname" "t6" -"spawnflags" "3585" -"angle" "-2" -"wait" "90" -"model" "*42" -} -{ -"sounds" "3" -"classname" "func_door" -"angle" "0" -"spawnflags" "1537" -"targetname" "t6" -"wait" "90" -"model" "*43" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "-42 1642 -108" -"light" "200" -} -{ -"classname" "item_health" -"origin" "-72 560 -384" -} -{ -"origin" "-152 560 -384" -"classname" "item_health" -} -{ -"targetname" "t31" -"spawnflags" "513" -"angle" "90" -"origin" "848 -376 216" -"classname" "monster_hell_knight" -} -{ -"targetname" "t31" -"spawnflags" "768" -"origin" "-512 -248 88" -"classname" "monster_shambler" -} -{ -"spawnflags" "768" -"angle" "180" -"origin" "382 1246 -136" -"classname" "monster_ogre" -} -{ -"spawnflags" "768" -"classname" "monster_ogre" -"origin" "190 1438 -136" -"angle" "0" -} -{ -"classname" "info_player_deathmatch" -"origin" "640 -1664 -312" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "-400 -240 88" -"angle" "0" -} -{ -"classname" "info_player_deathmatch" -"origin" "-216 1088 152" -"angle" "0" -} -{ -"classname" "info_player_deathmatch" -"origin" "-512 792 -104" -"angle" "270" -} -{ -"classname" "info_player_deathmatch" -"origin" "888 624 -152" -"angle" "270" -} -{ -"classname" "info_player_deathmatch" -"origin" "-96 1456 -168" -"angle" "0" -} -{ -"spawnflags" "2048" -"classname" "func_wall" -"model" "*44" -} -{ -"spawnflags" "2048" -"classname" "func_wall" -"model" "*45" -} -{ -"classname" "func_plat" -"height" "192" -"sounds" "2" -"model" "*46" -} -{ -"classname" "item_health" -"origin" "-1184 72 -352" -} -{ -"classname" "light" -"origin" "-952 1408 80" -"light" "200" -} -{ -"classname" "light" -"origin" "-1120 1176 48" -"light" "250" -} -{ -"classname" "light" -"origin" "-104 288 -344" -"light" "200" -} -{ -"classname" "light" -"origin" "-512 376 -304" -"light" "200" -} -{ -"classname" "trigger_multiple" -"target" "t35" -"model" "*47" -} -{ -"classname" "light" -"origin" "192 -376 -16" -"light" "150" -} -{ -"classname" "light" -"origin" "192 -328 176" -"light" "150" -} -{ -"classname" "trigger_multiple" -"target" "t32" -"spawnflags" "768" -"wait" "0.5" -"model" "*48" -} -{ -"classname" "trigger_multiple" -"spawnflags" "768" -"wait" "0.5" -"target" "t33" -"targetname" "t44" -"model" "*49" -} -{ -"origin" "-1176 112 -112" -"classname" "item_rockets" -} -{ -"origin" "-736 544 -280" -"classname" "item_armorInv" -} -{ -"classname" "func_button" -"angle" "180" -"target" "t36" -"model" "*50" -} -{ -"classname" "info_null" -"origin" "-1332 1116 -36" -"targetname" "t37" -} -{ -"classname" "light" -"origin" "-1296 1120 -32" -"target" "t37" -"angle" "60" -} -{ -"spawnflags" "2048" -"classname" "func_wall" -"model" "*51" -} -{ -"spawnflags" "2048" -"classname" "func_wall" -"model" "*52" -} -{ -"classname" "light" -"origin" "192 -152 -344" -"light" "160" -} -{ -"classname" "light" -"origin" "192 32 -344" -"light" "160" -} -{ -"classname" "light" -"origin" "32 168 -344" -"light" "140" -} -{ -"light" "160" -"origin" "-16 408 -344" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 368 -344" -"light" "140" -} -{ -"light" "140" -"origin" "448 368 -344" -"classname" "light" -} -{ -"classname" "light" -"origin" "528 592 -344" -"light" "200" -} -{ -"light" "200" -"origin" "408 808 -344" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 832 -344" -"light" "200" -} -{ -"light" "200" -"origin" "-40 728 -344" -"classname" "light" -} -{ -"classname" "light" -"origin" "-168 632 -344" -"light" "200" -} -{ -"light" "200" -"origin" "-160 976 -344" -"classname" "light" -} -{ -"classname" "light" -"origin" "592 456 -344" -"light" "200" -} -{ -"classname" "light" -"origin" "192 352 -232" -"light" "200" -} -{ -"light" "200" -"origin" "32 264 -232" -"classname" "light" -} -{ -"classname" "light" -"origin" "-184 432 -336" -"light" "160" -} -{ -"light" "160" -"origin" "-192 144 -336" -"classname" "light" -} -{ -"classname" "light" -"origin" "-776 280 -312" -"light" "200" -} -{ -"light" "200" -"origin" "-864 432 -312" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1096 432 -312" -"light" "200" -} -{ -"light" "200" -"origin" "-1168 272 -312" -"classname" "light" -} -{ -"classname" "light" -"origin" "-944 64 -312" -"light" "200" -} -{ -"light" "200" -"origin" "-664 136 -312" -"classname" "light" -} -{ -"light" "200" -"origin" "-1112 592 -96" -"classname" "light" -} -{ -"classname" "light" -"origin" "-1040 1256 -32" -"light" "150" -} -{ -"light" "200" -"origin" "-880 1128 80" -"classname" "light" -} -{ -"classname" "light" -"origin" "-712 1400 -16" -"light" "200" -} -{ -"classname" "light" -"origin" "104 -600 -224" -"light" "200" -} -{ -"light" "200" -"origin" "280 -600 -224" -"classname" "light" -} -{ -"classname" "trigger_changelevel" -"map" "e2m4" -"model" "*53" -} -{ -"light" "160" -"origin" "-312 808 -72" -"classname" "light" -} -{ -"light" "200" -"origin" "192 1776 -312" -"classname" "light" -} -{ -"classname" "light" -"origin" "-392 568 -56" -"light" "160" -} -{ -"classname" "light" -"origin" "-1224 1504 8" -"light" "170" -} -{ -"light" "170" -"origin" "-1304 1392 8" -"classname" "light" -} -{ -"classname" "light" -"origin" "-640 1168 -8" -"light" "170" -} -{ -"light" "160" -"origin" "352 -1248 56" -"classname" "light" -} -{ -"classname" "light" -"origin" "40 -1248 56" -"light" "160" -} -{ -"light" "160" -"origin" "192 -1216 -176" -"classname" "light" -} -{ -"classname" "light" -"origin" "24 -1376 -232" -"light" "160" -} -{ -"light" "160" -"origin" "224 -1624 -232" -"classname" "light" -} -{ -"classname" "light" -"origin" "368 -1392 -232" -"light" "160" -} -{ -"classname" "light" -"origin" "8 -464 -40" -"light" "140" -} -{ -"light" "140" -"origin" "384 -464 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "-544 800 -56" -"light" "140" -} -{ -"classname" "trigger_secret" -"model" "*54" -} -{ -"classname" "trigger_secret" -"model" "*55" -} -{ -"light" "200" -"origin" "760 1856 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "760 1664 -40" -"light" "200" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "538 1762 -124" -"style" "1" -"light" "200" -} -{ -"style" "1" -"classname" "light_torch_small_walltorch" -"origin" "850 1930 -124" -"light" "200" -} -{ -"origin" "850 1618 -124" -"classname" "light_torch_small_walltorch" -"style" "1" -"light" "200" -} -{ -"classname" "light" -"origin" "912 1856 -40" -"light" "200" -} -{ -"light" "200" -"origin" "912 1664 -40" -"classname" "light" -} -{ -"light" "200" -"origin" "1064 1776 -172" -"classname" "light" -} -{ -"light" "200" -"origin" "1080 1856 -40" -"classname" "light" -} -{ -"classname" "light" -"origin" "1080 1664 -40" -"light" "200" -} -{ -"classname" "light" -"origin" "1176 1776 -172" -"light" "200" -} -{ -"light" "170" -"origin" "672 1768 -296" -"classname" "light" -} -{ -"target" "t38" -"classname" "trigger_teleport" -"model" "*56" -} -{ -"targetname" "t38" -"origin" "1144 1776 -88" -"classname" "info_teleport_destination" -} -{ -"map" "e2m7" -"classname" "trigger_changelevel" -"model" "*57" -} -{ -"light" "160" -"origin" "840 1768 -200" -"classname" "light" -} -{ -"light" "140" -"origin" "408 608 -344" -"classname" "light" -} -{ -"classname" "item_spikes" -"origin" "-16 240 -160" -"spawnflags" "2048" -} -{ -"classname" "weapon_supernailgun" -"origin" "-1256 1448 -80" -} -{ -"origin" "432 1160 152" -"classname" "item_artifact_super_damage" -} -{ -"message" "The portal lies beyond..." -"targetname" "t40" -"wait" "-1" -"speed" "20" -"sounds" "4" -"angle" "-2" -"classname" "func_door" -"model" "*58" -} -{ -"origin" "432 1672 -368" -"classname" "item_armor2" -} -{ -"target" "t39" -"sounds" "1" -"wait" "-1" -"classname" "func_button" -"model" "*59" -} -{ -"message" "The underwater barrier is lowered..." -"target" "t40" -"targetname" "t39" -"spawnflags" "1" -"classname" "trigger_once" -"model" "*60" -} -{ -"classname" "trigger_secret" -"model" "*61" -} -{ -"light" "200" -"origin" "-128 -704 -224" -"classname" "light" -} -{ -"classname" "light" -"origin" "512 -704 -224" -"light" "200" -} -{ -"light" "200" -"origin" "192 -832 -224" -"classname" "light" -} -{ -"mangle" "20 240 0" -"origin" "400 1048 240" -"classname" "info_intermission" -} -{ -"mangle" "20 145 0" -"origin" "-160 144 64" -"classname" "info_intermission" -} -{ -"mangle" "-20 45 0" -"origin" "-320 -824 -144" -"classname" "info_intermission" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*62" -} -{ -"classname" "item_artifact_super_damage" -"origin" "928 1768 -240" -"spawnflags" "1792" -} -{ -"classname" "light" -"origin" "8 1800 -120" -"light" "220" -} -{ -"classname" "weapon_lightning" -"origin" "1216 1784 -264" -"spawnflags" "1792" -} -{ -"classname" "item_cells" -"origin" "880 1648 -264" -"spawnflags" "1793" -} -{ -"spawnflags" "1793" -"origin" "880 1864 -264" -"classname" "item_cells" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*63" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*64" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*65" -} -{ -"classname" "info_player_coop" -"origin" "664 -1520 -312" -"angle" "180" -} -{ -"angle" "180" -"origin" "592 -1600 -312" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "680 -1712 -312" -"angle" "180" -} -{ -"classname" "air_bubbles" -"origin" "720 1384 -320" -} -{ -"classname" "light" -"origin" "680 1376 -312" -} -{ -"classname" "func_door_secret" -"angle" "180" -"spawnflags" "2" -"targetname" "t41" -"model" "*66" -} -{ -"classname" "trigger_multiple" -"target" "t41" -"model" "*67" -} -{ -"origin" "688 1176 -312" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"classname" "light" -"origin" "480 1408 -312" -} -{ -"origin" "448 1552 -312" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"classname" "light" -"origin" "840 1080 -312" -} -{ -"origin" "840 1080 -160" -"classname" "light" -"light" "200" -} -{ -"light" "200" -"classname" "light" -"origin" "840 1080 0" -} -{ -"classname" "light" -"origin" "840 1080 232" -"light" "200" -} -{ -"classname" "item_artifact_envirosuit" -"origin" "576 1440 -344" -} -{ -"classname" "item_artifact_invulnerability" -"origin" "544 1248 -344" -} -{ -"light" "200" -"origin" "840 936 232" -"classname" "light" -} -{ -"classname" "light" -"origin" "840 760 232" -"light" "150" -} -{ -"light" "120" -"origin" "808 600 232" -"classname" "light" -} -{ -"classname" "item_health" -"origin" "824 960 152" -} -{ -"origin" "848 880 152" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "808 768 152" -} -{ -"classname" "trigger_multiple" -"message" "Welcome to the Well of Wishes!" -"wait" "5" -"sounds" "1" -"model" "*68" -} -{ -"classname" "trigger_multiple" -"sounds" "1" -"wait" "3" -"message" "The Dopefish Lives!" -"model" "*69" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*70" -} -{ -"classname" "trigger_secret" -"model" "*71" -} -{ -"spawnflags" "1" -"origin" "-1312 1392 -80" -"classname" "item_spikes" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*72" -} -{ -"classname" "light" -"origin" "-544 600 -248" -"light" "200" -} -{ -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "194 -214 196" -"spawnflags" "2048" -} -{ -"light" "200" -"origin" "352 984 -328" -"classname" "light" -} -{ -"classname" "light" -"origin" "96 976 -328" -"light" "200" -} -{ -"classname" "light" -"origin" "640 776 -336" -"light" "200" -} -{ -"classname" "func_plat" -"spawnflags" "1" -"model" "*73" -} -{ -"classname" "monster_fish" -"origin" "656 352 -336" -"spawnflags" "256" -} -{ -"spawnflags" "256" -"origin" "432 424 -336" -"classname" "monster_fish" -} -{ -"classname" "monster_fish" -"origin" "296 968 -336" -"spawnflags" "256" -} -{ -"origin" "-48 800 -336" -"classname" "monster_fish" -} -{ -"classname" "monster_fish" -"origin" "-896 248 -312" -} -{ -"origin" "-744 328 -312" -"classname" "monster_fish" -} -{ -"classname" "path_corner" -"origin" "272 -1504 -264" -"targetname" "t42" -"target" "t43" -} -{ -"origin" "56 -1352 -264" -"classname" "path_corner" -"target" "t42" -"targetname" "t43" -} -{ -"classname" "item_health" -"origin" "312 -1336 -272" -} -{ -"origin" "544 -1488 -336" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "312 1464 -160" -} -{ -"origin" "56 1488 -192" -"classname" "item_health" -} -{ -"classname" "trigger_once" -"killtarget" "t44" -"spawnflags" "3072" -"model" "*74" -} -{ -"classname" "item_rockets" -"origin" "216 648 120" -"spawnflags" "1" -} -{ -"classname" "item_shells" -"origin" "136 648 120" -"spawnflags" "1" -} diff --git a/Misc/pak/maps/e2m7.diff b/Misc/pak/maps/e2m7.diff new file mode 100644 index 000000000..badaf2ef8 --- /dev/null +++ b/Misc/pak/maps/e2m7.diff @@ -0,0 +1,22 @@ +--- e2m7.ent ++++ e2m7@10a8.ent +@@ -1449,18 +1449,19 @@ + { + "targetname" "t119" + "classname" "func_door" + "wait" "-1" + "angle" "-1" + "speed" "30" + "message" "Go for a swim first..." + "sounds" "3" + "model" "*40" ++"origin" "-1 0 0" // svdijk -- added to prevent z-fighting + } + { + "classname" "func_button" + "angle" "0" + "wait" "-1" + "target" "t45" + "model" "*41" + } + { diff --git a/Misc/pak/maps/e2m7.ent.orig b/Misc/pak/maps/e2m7.ent.orig deleted file mode 100644 index d4bec275b..000000000 --- a/Misc/pak/maps/e2m7.ent.orig +++ /dev/null @@ -1,3632 +0,0 @@ -{ -"wad" "gfx/tim.wad" -"classname" "worldspawn" -"sounds" "7" -"worldtype" "0" -"message" "the Underearth" -} -{ -"angle" "90" -"origin" "1136 -1100 -72" -"classname" "info_player_start" -} -{ -"origin" "1184 -776 -152" -"classname" "light" -"light" "150" -} -{ -"classname" "light" -"origin" "1704 -584 -184" -"light" "150" -} -{ -"classname" "light" -"origin" "1640 -688 -184" -"light" "150" -} -{ -"classname" "light" -"origin" "1696 -888 -192" -"light" "150" -} -{ -"classname" "light" -"origin" "1088 -960 -152" -"light" "150" -} -{ -"classname" "light" -"origin" "1248 -960 -152" -"light" "150" -} -{ -"classname" "light" -"origin" "1016 -768 -152" -"light" "100" -} -{ -"classname" "light" -"origin" "896 -920 -152" -"light" "150" -} -{ -"light" "100" -"origin" "1584 -208 -112" -"classname" "light" -} -{ -"light" "100" -"origin" "1776 -208 -112" -"classname" "light" -} -{ -"light" "150" -"origin" "1584 -88 -112" -"classname" "light" -} -{ -"origin" "1774 58 -76" -"classname" "light_torch_small_walltorch" -} -{ -"light" "100" -"origin" "1584 -488 -232" -"classname" "light" -} -{ -"light" "100" -"origin" "1768 -480 -232" -"classname" "light" -} -{ -"light" "150" -"origin" "1752 -112 -176" -"classname" "light" -} -{ -"light" "150" -"origin" "1592 -120 -176" -"classname" "light" -} -{ -"light" "150" -"origin" "1592 -248 -192" -"classname" "light" -} -{ -"light" "200" -"origin" "1768 -240 -192" -"classname" "light" -} -{ -"light" "150" -"origin" "1676 -220 -188" -"classname" "light" -} -{ -"light" "150" -"origin" "1672 -40 -136" -"classname" "light" -} -{ -"light" "150" -"origin" "1676 -376 -252" -"classname" "light" -} -{ -"light" "250" -"origin" "1112 952 -92" -"classname" "light" -} -{ -"light" "200" -"origin" "1280 928 -152" -"classname" "light" -} -{ -"classname" "light" -"origin" "704 952 -92" -"light" "250" -} -{ -"classname" "light" -"origin" "824 1112 -92" -"light" "200" -} -{ -"classname" "light" -"origin" "952 760 -92" -"light" "200" -} -{ -"classname" "light" -"origin" "824 760 -92" -"light" "200" -} -{ -"light" "250" -"origin" "952 1112 -92" -"classname" "light" -} -{ -"classname" "light" -"origin" "1128 -848 288" -"light" "500" -} -{ -"classname" "light" -"origin" "1144 -432 288" -} -{ -"classname" "light" -"origin" "864 -552 272" -"light" "200" -} -{ -"classname" "light" -"origin" "1392 -568 168" -"light" "200" -} -{ -"classname" "light" -"origin" "1416 -592 -24" -"light" "150" -} -{ -"classname" "light" -"origin" "888 -584 -24" -"light" "150" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1058 -466 -24" -"light" "225" -} -{ -"origin" "1214 -466 -24" -"classname" "light_torch_small_walltorch" -"light" "225" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1198 -66 40" -"light" "300" -} -{ -"classname" "light" -"origin" "1144 -204 172" -"light" "150" -} -{ -"classname" "light" -"origin" "1144 -292 -32" -"light" "150" -} -{ -"classname" "item_spikes" -"origin" "880 -592 -96" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "1068 -944 -96" -} -{ -"classname" "light" -"origin" "1128 -1084 96" -"light" "300" -} -{ -"classname" "light" -"origin" "888 -848 248" -"light" "150" -} -{ -"light" "150" -"origin" "1504 -896 248" -"classname" "light" -} -{ -"classname" "light" -"origin" "1304 -1048 24" -"light" "225" -} -{ -"classname" "light" -"origin" "1520 -872 -192" -"light" "150" -} -{ -"light" "100" -"origin" "1384 -776 -184" -"classname" "light" -} -{ -"classname" "light" -"origin" "1368 -912 -184" -"light" "100" -} -{ -"classname" "light" -"origin" "1584 496 148" -"light" "200" -} -{ -"light" "200" -"origin" "1488 496 148" -"classname" "light" -} -{ -"classname" "light" -"origin" "1688 164 148" -"light" "200" -} -{ -"light" "200" -"origin" "1352 496 148" -"classname" "light" -} -{ -"classname" "light" -"origin" "1608 496 -36" -"light" "200" -} -{ -"light" "200" -"origin" "1456 496 -36" -"classname" "light" -} -{ -"classname" "light" -"origin" "1692 600 -12" -"light" "200" -} -{ -"light" "200" -"origin" "1274 618 -64" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1274 378 -64" -"light" "200" -} -{ -"classname" "light" -"origin" "1256 496 -40" -"light" "200" -} -{ -"spawnflags" "2056" -"wait" "-1" -"classname" "func_door" -"angle" "270" -"model" "*1" -} -{ -"wait" "-1" -"spawnflags" "2056" -"sounds" "3" -"angle" "90" -"classname" "func_door" -"model" "*2" -} -{ -"light" "200" -"origin" "1968 1792 -257" -"classname" "light" -} -{ -"light" "250" -"origin" "1880 1792 -105" -"classname" "light" -} -{ -"classname" "light" -"origin" "1976 1944 56" -"light" "150" -} -{ -"light" "150" -"origin" "1992 1624 64" -"classname" "light" -} -{ -"classname" "light" -"origin" "1944 1736 64" -"light" "150" -} -{ -"light" "150" -"origin" "1944 1832 64" -"classname" "light" -} -{ -"classname" "light" -"origin" "1128 496 -24" -"light" "250" -} -{ -"light" "150" -"origin" "1120 632 -24" -"classname" "light" -} -{ -"light" "200" -"origin" "928 544 -24" -"classname" "light" -} -{ -"classname" "light" -"origin" "640 664 -8" -"light" "200" -} -{ -"light" "200" -"origin" "848 672 -8" -"classname" "light" -} -{ -"classname" "light" -"origin" "1024 544 -188" -"light" "175" -} -{ -"light" "250" -"origin" "64 192 136" -"classname" "light" -} -{ -"classname" "light" -"origin" "528 184 136" -"light" "250" -} -{ -"light" "200" -"origin" "72 408 8" -"classname" "light" -} -{ -"classname" "light" -"origin" "80 -48 8" -"light" "200" -} -{ -"light" "250" -"origin" "400 384 80" -"classname" "light" -} -{ -"classname" "light" -"origin" "392 -16 80" -"light" "250" -} -{ -"classname" "light" -"origin" "312 184 -80" -"light" "200" -} -{ -"light" "200" -"origin" "440 184 -80" -"classname" "light" -} -{ -"classname" "light" -"origin" "504 368 -120" -"light" "250" -} -{ -"light" "150" -"origin" "632 192 -120" -"classname" "light" -} -{ -"classname" "light" -"origin" "504 -16 -120" -"light" "250" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "774 446 -172" -"light" "250" -} -{ -"origin" "774 -70 -172" -"classname" "light_torch_small_walltorch" -"light" "250" -} -{ -"light" "250" -"origin" "896 -128 152" -"classname" "light" -} -{ -"classname" "light" -"origin" "896 184 152" -"light" "250" -} -{ -"light" "150" -"origin" "656 184 216" -"classname" "light" -} -{ -"classname" "light" -"origin" "304 368 -152" -"light" "200" -} -{ -"light" "200" -"origin" "0 480 -168" -"classname" "light" -} -{ -"classname" "light" -"origin" "96 376 -168" -"light" "200" -} -{ -"classname" "light" -"origin" "16 1480 -96" -"light" "200" -} -{ -"light" "200" -"origin" "1280 1824 -120" -"classname" "light" -} -{ -"light" "200" -"origin" "504 1816 -120" -"classname" "light" -} -{ -"classname" "light" -"origin" "712 1808 -120" -"light" "200" -} -{ -"light" "200" -"origin" "1064 1808 -120" -"classname" "light" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "858 1950 -172" -"light" "250" -} -{ -"origin" "658 1950 -172" -"classname" "light_torch_small_walltorch" -"light" "250" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "666 1682 -172" -"light" "250" -} -{ -"origin" "858 1682 -172" -"classname" "light_torch_small_walltorch" -"light" "250" -} -{ -"classname" "light" -"origin" "1248 1384 -32" -"light" "200" -} -{ -"classname" "light" -"origin" "1688 936 -136" -"light" "200" -} -{ -"light" "250" -"origin" "1856 1444 -52" -"classname" "light" -} -{ -"light" "150" -"origin" "1864 1316 -192" -"classname" "light" -} -{ -"classname" "light" -"origin" "1776 1212 -192" -"light" "150" -} -{ -"light" "150" -"origin" "1696 1076 -192" -"classname" "light" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1770 730 -64" -"light" "250" -} -{ -"classname" "light" -"origin" "1760 1720 -201" -"light" "250" -} -{ -"classname" "light" -"origin" "1632 1520 -201" -"light" "200" -} -{ -"classname" "light" -"origin" "1984 1504 -201" -"light" "200" -} -{ -"light" "250" -"classname" "light_torch_small_walltorch" -"origin" "1874 2104 -300" -} -{ -"light" "250" -"origin" "1712 2104 -300" -"classname" "light_torch_small_walltorch" -} -{ -"light" "200" -"classname" "light" -"origin" "1792 2048 48" -} -{ -"classname" "light_flame_large_yellow" -"origin" "1362 1778 0" -} -{ -"classname" "light" -"origin" "1408 1776 -124" -"light" "200" -} -{ -"classname" "light" -"origin" "1520 1880 -84" -"light" "175" -} -{ -"light" "175" -"origin" "1416 1512 -84" -"classname" "light" -} -{ -"classname" "light" -"origin" "1376 1568 -164" -"light" "150" -} -{ -"light" "150" -"origin" "1416 1888 -164" -"classname" "light" -} -{ -"classname" "light" -"origin" "1544 2072 -164" -"light" "150" -} -{ -"classname" "light" -"origin" "1552 1968 36" -"light" "250" -} -{ -"classname" "light" -"origin" "1416 1968 -16" -"light" "175" -} -{ -"light" "175" -"origin" "1416 2176 -16" -"classname" "light" -} -{ -"classname" "light" -"origin" "1240 2176 -16" -"light" "175" -} -{ -"light" "175" -"origin" "1240 2000 -16" -"classname" "light" -} -{ -"classname" "light" -"origin" "1264 1576 -72" -"light" "200" -} -{ -"light" "200" -"origin" "992 1480 -40" -"classname" "light" -} -{ -"light" "200" -"classname" "light_torch_small_walltorch" -"origin" "968 1632 -132" -} -{ -"light" "200" -"origin" "968 1328 -132" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1474 2234 -133" -"light" "200" -} -{ -"origin" "1182 2234 -133" -"classname" "light_torch_small_walltorch" -"light" "200" -} -{ -"classname" "light" -"origin" "1936 1480 48" -"light" "150" -} -{ -"light" "150" -"origin" "1544 1528 64" -"classname" "light" -} -{ -"classname" "light" -"origin" "1472 1488 24" -"light" "150" -} -{ -"classname" "light" -"origin" "1400 1664 96" -"light" "150" -} -{ -"light" "200" -"origin" "1792 2176 -221" -"classname" "light" -} -{ -"classname" "light" -"origin" "1880 2288 -221" -"light" "200" -} -{ -"light" "200" -"origin" "2048 2288 -221" -"classname" "light" -} -{ -"classname" "light" -"origin" "2128 2208 -221" -"light" "200" -} -{ -"light" "200" -"origin" "2160 1992 -205" -"classname" "light" -} -{ -"origin" "2288 1952 -29" -"classname" "light" -} -{ -"light" "250" -"origin" "2274 1738 -172" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "2274 1682 -172" -"light" "250" -} -{ -"light" "200" -"origin" "2376 2184 -152" -"classname" "light" -} -{ -"light" "200" -"origin" "2618 1658 -169" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "2618 1368 -169" -"light" "200" -} -{ -"light" "200" -"origin" "2176 1488 -169" -"classname" "light_torch_small_walltorch" -} -{ -"light" "200" -"origin" "2298 626 24" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1930 738 24" -"light" "200" -} -{ -"light" "200" -"origin" "2050 394 24" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "func_plat" -"model" "*3" -} -{ -"light" "150" -"origin" "2152 1784 -312" -"classname" "light" -} -{ -"classname" "light" -"origin" "2232 936 -4" -"light" "200" -} -{ -"classname" "light" -"origin" "2232 1040 48" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "2034 1034 -164" -"light" "200" -} -{ -"classname" "light" -"origin" "2304 1040 280" -"light" "200" -} -{ -"light" "200" -"origin" "2168 1040 280" -"classname" "light" -} -{ -"origin" "2130 2452 -112" -"classname" "light_flame_large_yellow" -"light" "250" -} -{ -"classname" "light_flame_large_yellow" -"origin" "1858 2452 -112" -"light" "250" -} -{ -"classname" "light" -"origin" "2132 2416 -188" -"light" "150" -} -{ -"light" "150" -"origin" "1860 2416 -188" -"classname" "light" -} -{ -"light" "200" -"origin" "2256 1968 -453" -"classname" "light" -} -{ -"classname" "light" -"origin" "2256 2184 -453" -"light" "200" -} -{ -"light" "200" -"origin" "2216 2384 -453" -"classname" "light" -} -{ -"classname" "light" -"origin" "1792 2400 -453" -"light" "200" -} -{ -"light" "175" -"origin" "1984 2400 -453" -"classname" "light" -} -{ -"light" "150" -"origin" "2168 1608 -9" -"classname" "light" -} -{ -"classname" "light" -"origin" "2368 1600 -9" -"light" "150" -} -{ -"light" "150" -"origin" "2240 1424 44" -"classname" "light" -} -{ -"classname" "light" -"origin" "2400 1424 44" -"light" "150" -} -{ -"light" "150" -"origin" "2560 1424 44" -"classname" "light" -} -{ -"classname" "light" -"origin" "2560 1560 44" -"light" "175" -} -{ -"light" "150" -"origin" "2232 1288 44" -"classname" "light" -} -{ -"light" "175" -"origin" "2384 1424 -160" -"classname" "light" -} -{ -"classname" "light" -"origin" "2232 1288 -160" -"light" "175" -} -{ -"light" "150" -"origin" "2164 932 -172" -"classname" "light" -} -{ -"classname" "light" -"origin" "2308 932 -172" -"light" "150" -} -{ -"light" "150" -"origin" "2232 776 24" -"classname" "light" -} -{ -"classname" "light" -"origin" "2192 664 24" -"light" "150" -} -{ -"light" "150" -"origin" "2016 696 24" -"classname" "light" -} -{ -"classname" "light" -"origin" "1912 496 24" -"light" "150" -} -{ -"light" "175" -"origin" "80 1616 -120" -"classname" "light" -} -{ -"classname" "light" -"origin" "72 1888 -120" -"light" "175" -} -{ -"light" "175" -"origin" "296 1616 -120" -"classname" "light" -} -{ -"light" "175" -"origin" "304 1888 -120" -"classname" "light" -} -{ -"targetname" "t20" -"angle" "90" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t21" -"angle" "120" -"classname" "trap_spikeshooter" -"origin" "192 1752 -208" -"spawnflags" "1" -} -{ -"targetname" "t22" -"angle" "150" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t19" -"angle" "60" -"classname" "trap_spikeshooter" -"origin" "192 1752 -208" -"spawnflags" "1" -} -{ -"targetname" "t18" -"angle" "30" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t17" -"angle" "0" -"classname" "trap_spikeshooter" -"origin" "192 1752 -208" -"spawnflags" "1" -} -{ -"targetname" "t24" -"angle" "210" -"classname" "trap_spikeshooter" -"origin" "192 1752 -208" -"spawnflags" "1" -} -{ -"targetname" "t23" -"angle" "180" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t25" -"angle" "240" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t26" -"angle" "270" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t27" -"angle" "300" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t28" -"angle" "330" -"spawnflags" "1" -"origin" "192 1752 -208" -"classname" "trap_spikeshooter" -} -{ -"delay" ".1" -"targetname" "t29" -"target" "t17" -"classname" "trigger_multiple" -"model" "*4" -} -{ -"delay" ".1" -"targetname" "t17" -"target" "t18" -"classname" "trigger_multiple" -"model" "*5" -} -{ -"delay" ".1" -"targetname" "t18" -"target" "t19" -"classname" "trigger_multiple" -"model" "*6" -} -{ -"delay" ".1" -"targetname" "t19" -"target" "t20" -"classname" "trigger_multiple" -"model" "*7" -} -{ -"delay" ".1" -"targetname" "t20" -"target" "t21" -"classname" "trigger_multiple" -"model" "*8" -} -{ -"delay" ".1" -"targetname" "t21" -"target" "t22" -"classname" "trigger_multiple" -"model" "*9" -} -{ -"delay" ".1" -"targetname" "t22" -"target" "t23" -"classname" "trigger_multiple" -"model" "*10" -} -{ -"delay" ".1" -"targetname" "t23" -"target" "t24" -"classname" "trigger_multiple" -"model" "*11" -} -{ -"delay" ".1" -"targetname" "t24" -"target" "t25" -"classname" "trigger_multiple" -"model" "*12" -} -{ -"delay" ".1" -"targetname" "t25" -"target" "t26" -"classname" "trigger_multiple" -"model" "*13" -} -{ -"delay" ".1" -"targetname" "t26" -"target" "t27" -"classname" "trigger_multiple" -"model" "*14" -} -{ -"delay" ".1" -"targetname" "t27" -"target" "t28" -"classname" "trigger_multiple" -"model" "*15" -} -{ -"target" "t29" -"wait" "1.3" -"classname" "trigger_multiple" -"model" "*16" -} -{ -"origin" "192 1750 -188" -"classname" "light_flame_large_yellow" -} -{ -"light" "125" -"origin" "214 1752 -166" -"classname" "light" -} -{ -"classname" "light" -"origin" "192 1774 -166" -"light" "125" -} -{ -"light" "125" -"origin" "170 1750 -166" -"classname" "light" -} -{ -"classname" "light" -"origin" "194 1726 -166" -"light" "125" -} -{ -"target" "t31" -"wait" "-1" -"angle" "0" -"classname" "func_button" -"model" "*17" -} -{ -"target" "t31" -"angle" "180" -"wait" "-1" -"classname" "func_button" -"model" "*18" -} -{ -"target" "t31" -"wait" "-1" -"angle" "180" -"classname" "func_button" -"model" "*19" -} -{ -"target" "t31" -"angle" "90" -"wait" "-1" -"classname" "func_button" -"model" "*20" -} -{ -"wait" "-1" -"targetname" "t30" -"sounds" "4" -"speed" "50" -"angle" "-1" -"classname" "func_door" -"model" "*21" -} -{ -"count" "4" -"targetname" "t31" -"target" "t30" -"classname" "trigger_counter" -"model" "*22" -} -{ -"light" "150" -"origin" "2424 1080 -176" -"classname" "light" -} -{ -"classname" "light" -"origin" "2424 992 -176" -"light" "150" -} -{ -"targetname" "t40" -"angle" "180" -"spawnflags" "1" -"origin" "2434 1036 -192" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t40" -"classname" "trap_spikeshooter" -"origin" "2434 1036 -192" -"spawnflags" "1" -"angle" "160" -} -{ -"targetname" "t40" -"angle" "140" -"spawnflags" "1" -"origin" "2434 1036 -192" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t40" -"classname" "trap_spikeshooter" -"origin" "2434 1036 -192" -"spawnflags" "1" -"angle" "120" -} -{ -"targetname" "t40" -"angle" "200" -"spawnflags" "1" -"origin" "2434 1036 -192" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t40" -"classname" "trap_spikeshooter" -"origin" "2434 1036 -192" -"spawnflags" "1" -"angle" "220" -} -{ -"targetname" "t40" -"angle" "240" -"spawnflags" "1" -"origin" "2434 1036 -192" -"classname" "trap_spikeshooter" -} -{ -"targetname" "t41" -"target" "t40" -"wait" ".5" -"classname" "trigger_multiple" -"model" "*23" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*24" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*25" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*26" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*27" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*28" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*29" -} -{ -"target" "t41" -"classname" "trigger_multiple" -"model" "*30" -} -{ -"light" "125" -"origin" "2196 1200 -204" -"classname" "light" -} -{ -"classname" "light" -"origin" "2284 1200 -204" -"light" "125" -} -{ -"light" "125" -"origin" "2284 1112 -204" -"classname" "light" -} -{ -"classname" "light" -"origin" "2388 1104 -204" -"light" "125" -} -{ -"light" "125" -"origin" "2284 1000 -204" -"classname" "light" -} -{ -"classname" "light" -"origin" "2140 1008 -204" -"light" "125" -} -{ -"light" "125" -"origin" "2132 1096 -204" -"classname" "light" -} -{ -"classname" "light" -"origin" "2132 1160 -204" -"light" "125" -} -{ -"light" "200" -"origin" "528 1816 -392" -"classname" "light" -} -{ -"classname" "light" -"origin" "736 1808 -392" -"light" "200" -} -{ -"light" "200" -"origin" "1040 1808 -392" -"classname" "light" -} -{ -"classname" "light" -"origin" "744 1424 -392" -"light" "200" -} -{ -"light" "200" -"origin" "752 1288 -416" -"classname" "light" -} -{ -"light" "200" -"origin" "760 1064 -376" -"classname" "light" -} -{ -"classname" "func_train" -"spawnflags" "33" -"targetname" "t42" -"dmg" "1000" -"sounds" "1" -"target" "t124" -"speed" "250" -"model" "*31" -} -{ -"classname" "func_door" -"angle" "-2" -"wait" "-1" -"targetname" "t43" -"speed" "50" -"sounds" "3" -"model" "*32" -} -{ -"classname" "func_button" -"angle" "-2" -"wait" "-1" -"target" "t42" -"sounds" "1" -"model" "*33" -} -{ -"classname" "trigger_once" -"target" "t43" -"targetname" "t42" -"delay" "2" -"model" "*34" -} -{ -"classname" "light" -"origin" "1936 1784 -288" -"light" "125" -} -{ -"classname" "monster_ogre" -"origin" "1976 1784 -328" -"angle" "180" -} -{ -"classname" "func_door" -"angle" "90" -"wait" "-1" -"sounds" "1" -"model" "*35" -} -{ -"classname" "func_door" -"angle" "270" -"targetname" "t44" -"wait" "-1" -"model" "*36" -} -{ -"classname" "light" -"origin" "64 264 8" -"light" "125" -} -{ -"light" "125" -"origin" "64 120 8" -"classname" "light" -} -{ -"classname" "light" -"origin" "64 192 8" -"light" "100" -} -{ -"classname" "trigger_once" -"target" "t44" -"model" "*37" -} -{ -"classname" "light" -"origin" "512 184 -8" -"light" "175" -} -{ -"targetname" "t119" -"classname" "func_door" -"angle" "90" -"wait" "-1" -"speed" "40" -"model" "*38" -} -{ -"targetname" "t119" -"classname" "func_door" -"wait" "-1" -"angle" "270" -"speed" "40" -"sounds" "4" -"model" "*39" -} -{ -"targetname" "t119" -"classname" "func_door" -"wait" "-1" -"angle" "-1" -"speed" "30" -"message" "Go for a swim first..." -"sounds" "3" -"model" "*40" -} -{ -"classname" "func_button" -"angle" "0" -"wait" "-1" -"target" "t45" -"model" "*41" -} -{ -"classname" "light" -"origin" "36 184 84" -"light" "75" -} -{ -"classname" "light" -"origin" "752 184 -192" -"light" "150" -} -{ -"classname" "light" -"origin" "544 536 -152" -"light" "125" -} -{ -"classname" "func_door" -"angle" "-2" -"sounds" "1" -"wait" "-1" -"targetname" "t45" -"model" "*42" -} -{ -"wait" "-1" -"sounds" "1" -"angle" "-2" -"classname" "func_door" -"targetname" "t45" -"model" "*43" -} -{ -"light" "125" -"origin" "544 -152 -152" -"classname" "light" -} -{ -"classname" "item_artifact_envirosuit" -"origin" "1024 492 -232" -} -{ -"classname" "item_armor1" -"origin" "2128 1752 -352" -} -{ -"classname" "light_flame_small_yellow" -"origin" "1024 368 -4" -"light" "250" -} -{ -"classname" "light" -"origin" "1024 400 -64" -"light" "150" -} -{ -"wait" "5" -"sounds" "1" -"classname" "func_door" -"angle" "-2" -"spawnflags" "1" -"targetname" "t51" -"model" "*44" -} -{ -"wait" "5" -"sounds" "1" -"classname" "func_door" -"angle" "-2" -"spawnflags" "1" -"targetname" "t51" -"model" "*45" -} -{ -"sounds" "3" -"classname" "func_button" -"angle" "270" -"wait" "3" -"target" "t51" -"model" "*46" -} -{ -"classname" "light" -"origin" "1224 712 -216" -"light" "100" -} -{ -"classname" "light" -"origin" "1232 768 -192" -"light" "100" -} -{ -"light" "75" -"origin" "1168 760 -232" -"classname" "light" -} -{ -"light" "100" -"origin" "1232 800 -208" -"classname" "light" -} -{ -"sounds" "1" -"origin" "1860 472 -8" -"classname" "item_key2" -"spawnflags" "2048" -} -{ -"classname" "light" -"origin" "1112 1568 -40" -"light" "200" -} -{ -"light" "150" -"origin" "-96 1440 -160" -"classname" "light" -} -{ -"classname" "light" -"origin" "384 1440 -160" -"light" "150" -} -{ -"light" "200" -"origin" "248 1408 -96" -"classname" "light" -} -{ -"light" "150" -"origin" "968 1480 -128" -"classname" "light" -} -{ -"light" "150" -"origin" "1008 -592 -32" -"classname" "light" -} -{ -"classname" "light" -"origin" "1264 -592 -32" -"light" "150" -} -{ -"light" "200" -"origin" "880 -840 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "1376 -856 -56" -"light" "200" -} -{ -"light" "175" -"origin" "264 184 -8" -"classname" "light" -} -{ -"light" "175" -"origin" "1464 -864 -208" -"classname" "light" -} -{ -"light" "175" -"origin" "1816 160 -56" -"classname" "light" -} -{ -"classname" "light" -"origin" "1560 160 -56" -"light" "175" -} -{ -"light" "175" -"origin" "1544 1632 104" -"classname" "light" -} -{ -"classname" "light" -"origin" "1792 1624 128" -"light" "175" -} -{ -"classname" "item_health" -"origin" "1068 -980 -104" -} -{ -"spawnflags" "1" -"classname" "item_shells" -"origin" "1344 -1160 -96" -} -{ -"classname" "monster_ogre" -"origin" "1008 -128 40" -"angle" "315" -"targetname" "t59" -"spawnflags" "1" -} -{ -"classname" "trigger_once" -"target" "t59" -"model" "*47" -} -{ -"classname" "monster_ogre" -"origin" "896 96 56" -"angle" "270" -"target" "t60" -"spawnflags" "1" -} -{ -"classname" "path_corner" -"origin" "896 208 40" -"target" "t60" -"targetname" "t61" -} -{ -"origin" "896 -16 40" -"classname" "path_corner" -"targetname" "t60" -"target" "t61" -} -{ -"classname" "path_corner" -"origin" "168 392 -56" -"target" "t62" -"targetname" "t63" -} -{ -"origin" "168 -16 -56" -"classname" "path_corner" -"targetname" "t62" -"target" "t63" -} -{ -"classname" "path_corner" -"origin" "88 344 -56" -"targetname" "t64" -"target" "t65" -"spawnflags" "256" -} -{ -"origin" "88 72 -56" -"classname" "path_corner" -"target" "t64" -"targetname" "t65" -"spawnflags" "256" -} -{ -"classname" "monster_hell_knight" -"origin" "88 224 -40" -"angle" "90" -"target" "t64" -"spawnflags" "257" -} -{ -"classname" "monster_hell_knight" -"origin" "168 232 -40" -"angle" "270" -"target" "t62" -"spawnflags" "1" -} -{ -"classname" "monster_zombie" -"origin" "544 -120 -208" -"angle" "90" -"targetname" "t45" -} -{ -"classname" "monster_zombie" -"origin" "544 496 -208" -"angle" "270" -"targetname" "t45" -} -{ -"classname" "monster_wizard" -"origin" "664 428 216" -"angle" "225" -"spawnflags" "1" -} -{ -"angle" "135" -"origin" "664 -56 216" -"classname" "monster_wizard" -"spawnflags" "257" -} -{ -"classname" "light" -"origin" "1736 88 -40" -"light" "100" -} -{ -"classname" "monster_ogre" -"origin" "904 -120 56" -"angle" "0" -"targetname" "t66" -"spawnflags" "1281" -} -{ -"classname" "trigger_once" -"target" "t66" -"spawnflags" "256" -"model" "*48" -} -{ -"classname" "item_health" -"origin" "1168 -408 -80" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "1168 -104 -16" -} -{ -"classname" "item_spikes" -"origin" "928 216 32" -} -{ -"classname" "item_rockets" -"origin" "632 -48 32" -} -{ -"classname" "item_health" -"origin" "32 392 -64" -} -{ -"light" "200" -"origin" "1688 288 148" -"classname" "light" -} -{ -"classname" "light" -"origin" "1688 464 148" -"light" "200" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "1814 622 -64" -"light" "250" -} -{ -"classname" "light" -"origin" "1768 344 -72" -"light" "200" -} -{ -"classname" "trigger_monsterjump" -"angle" "0" -"model" "*49" -} -{ -"targetname" "t100" -"classname" "monster_ogre" -"origin" "1504 272 24" -"angle" "0" -"spawnflags" "256" -} -{ -"targetname" "t68" -"target" "t67" -"origin" "1352 576 -120" -"classname" "path_corner" -"spawnflags" "256" -} -{ -"target" "t68" -"targetname" "t67" -"classname" "path_corner" -"origin" "1352 416 -120" -"spawnflags" "256" -} -{ -"target" "t68" -"angle" "90" -"origin" "1360 480 -104" -"classname" "monster_demon1" -"spawnflags" "257" -} -{ -"targetname" "t70" -"target" "t69" -"origin" "1472 496 -120" -"classname" "path_corner" -} -{ -"target" "t70" -"targetname" "t69" -"classname" "path_corner" -"origin" "1688 496 -120" -} -{ -"target" "t69" -"angle" "270" -"origin" "1648 544 -104" -"classname" "monster_ogre" -"spawnflags" "1" -} -{ -"target" "t71" -"targetname" "t72" -"origin" "1984 688 -24" -"classname" "path_corner" -"spawnflags" "256" -} -{ -"target" "t72" -"targetname" "t71" -"classname" "path_corner" -"origin" "1984 448 -24" -"spawnflags" "256" -} -{ -"target" "t71" -"angle" "270" -"origin" "1992 536 -8" -"classname" "monster_ogre" -"spawnflags" "257" -} -{ -"target" "t74" -"targetname" "t73" -"origin" "2120 680 -24" -"classname" "path_corner" -} -{ -"targetname" "t74" -"target" "t73" -"classname" "path_corner" -"origin" "2240 680 -24" -} -{ -"target" "t74" -"angle" "225" -"origin" "2256 736 -8" -"classname" "monster_ogre" -"spawnflags" "1" -} -{ -"targetname" "t78" -"angle" "90" -"origin" "2232 1312 -8" -"classname" "monster_ogre" -"spawnflags" "256" -} -{ -"target" "t76" -"angle" "90" -"origin" "2232 1008 -200" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"targetname" "t76" -"target" "t75" -"origin" "2120 968 -216" -"classname" "path_corner" -} -{ -"target" "t76" -"targetname" "t75" -"classname" "path_corner" -"origin" "2336 968 -216" -} -{ -"classname" "light" -"origin" "2384 2400 -152" -"light" "200" -} -{ -"targetname" "t77" -"wait" "-1" -"sounds" "1" -"speed" "300" -"angle" "-2" -"classname" "func_door" -"model" "*50" -} -{ -"targetname" "t77" -"angle" "180" -"origin" "2512 2312 -200" -"classname" "monster_demon1" -"spawnflags" "256" -} -{ -"targetname" "t77" -"classname" "monster_demon1" -"origin" "2512 2160 -200" -"angle" "180" -} -{ -"classname" "item_health" -"origin" "2504 2200 -224" -} -{ -"light" "150" -"origin" "2536 2312 -128" -"classname" "light" -} -{ -"classname" "light" -"origin" "2536 2160 -128" -"light" "150" -} -{ -"target" "t77" -"classname" "trigger_once" -"model" "*51" -} -{ -"spawnflags" "2" -"origin" "2368 2336 -224" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "2504 2240 -224" -"classname" "item_spikes" -} -{ -"origin" "2408 2072 -224" -"classname" "item_shells" -} -{ -"target" "t78" -"classname" "trigger_once" -"model" "*52" -} -{ -"targetname" "t78" -"angle" "90" -"origin" "2240 1272 -200" -"classname" "monster_demon1" -} -{ -"light" "150" -"origin" "1120 1384 -40" -"classname" "light" -} -{ -"light" "200" -"origin" "1200 1248 -104" -"classname" "light" -} -{ -"light" "250" -"origin" "1288 1032 -4" -"classname" "light_flame_small_yellow" -} -{ -"light" "150" -"origin" "1256 1032 -64" -"classname" "light" -} -{ -"classname" "light_flame_small_yellow" -"origin" "568 1032 -4" -"light" "250" -} -{ -"classname" "light" -"origin" "600 1032 -64" -"light" "150" -} -{ -"light" "250" -"origin" "888 1272 -4" -"classname" "light_flame_small_yellow" -} -{ -"light" "150" -"origin" "888 1240 -64" -"classname" "light" -} -{ -"light" "200" -"origin" "608 1232 -108" -"classname" "light" -} -{ -"target" "t79" -"wait" "-1" -"angle" "180" -"classname" "func_button" -"model" "*53" -} -{ -"targetname" "t79" -"message" "This door is opened near by..." -"sounds" "3" -"speed" "35" -"angle" "-1" -"wait" "-1" -"classname" "func_door" -"model" "*54" -} -{ -"light" "100" -"origin" "580 1208 -148" -"classname" "light" -} -{ -"light" "200" -"origin" "1224 736 -8" -"classname" "light" -} -{ -"target" "t80" -"classname" "trigger_once" -"model" "*55" -} -{ -"targetname" "t80" -"angle" "315" -"origin" "640 1088 128" -"classname" "monster_wizard" -} -{ -"targetname" "t80" -"classname" "monster_wizard" -"origin" "616 720 128" -"angle" "0" -} -{ -"targetname" "t80" -"angle" "180" -"origin" "1280 680 128" -"classname" "monster_wizard" -"spawnflags" "256" -} -{ -"target" "t82" -"origin" "1248 1080 24" -"classname" "monster_wizard" -"spawnflags" "1" -} -{ -"targetname" "t82" -"target" "t81" -"origin" "1168 1064 8" -"classname" "path_corner" -} -{ -"target" "t82" -"targetname" "t81" -"classname" "path_corner" -"origin" "720 1064 8" -} -{ -"targetname" "t80" -"classname" "monster_wizard" -"origin" "584 1112 128" -"angle" "315" -"spawnflags" "256" -} -{ -"origin" "1256 944 -184" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "1116 584 -256" -"classname" "item_spikes" -} -{ -"targetname" "t79" -"angle" "315" -"origin" "1000 1464 -168" -"classname" "monster_ogre" -} -{ -"target" "t85" -"targetname" "t86" -"origin" "1456 1824 -192" -"classname" "path_corner" -"spawnflags" "256" -} -{ -"target" "t86" -"targetname" "t85" -"classname" "path_corner" -"origin" "1456 1560 -192" -"spawnflags" "256" -} -{ -"target" "t85" -"angle" "270" -"origin" "1456 1664 -176" -"classname" "monster_ogre" -"spawnflags" "256" -} -{ -"targetname" "t91" -"angle" "270" -"origin" "1560 1944 -320" -"classname" "monster_zombie" -"spawnflags" "256" -} -{ -"targetname" "t91" -"classname" "monster_zombie" -"origin" "1600 1912 -320" -"angle" "270" -} -{ -"angle" "225" -"origin" "1960 1984 -320" -"classname" "monster_zombie" -} -{ -"targetname" "t91" -"classname" "monster_zombie" -"origin" "1904 1928 -320" -"angle" "225" -} -{ -"targetname" "t91" -"angle" "270" -"origin" "1624 1768 -320" -"classname" "monster_zombie" -} -{ -"target" "t87" -"classname" "monster_zombie" -"origin" "1696 1912 -320" -"angle" "0" -} -{ -"target" "t89" -"angle" "270" -"origin" "1704 1800 -320" -"classname" "monster_zombie" -} -{ -"target" "t87" -"targetname" "t88" -"origin" "1648 1912 -336" -"classname" "path_corner" -} -{ -"target" "t88" -"targetname" "t87" -"classname" "path_corner" -"origin" "1848 1904 -336" -} -{ -"targetname" "t90" -"target" "t89" -"origin" "1648 1824 -336" -"classname" "path_corner" -} -{ -"target" "t90" -"targetname" "t89" -"classname" "path_corner" -"origin" "1768 1752 -336" -} -{ -"target" "t91" -"classname" "trigger_once" -"model" "*56" -} -{ -"spawnflags" "1" -"origin" "1496 1808 -200" -"classname" "item_health" -} -{ -"spawnflags" "1" -"origin" "1184 2176 -192" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1184 2128 -192" -"spawnflags" "1" -} -{ -"spawnflags" "1" -"origin" "1264 1680 -192" -"classname" "item_health" -} -{ -"target" "t92" -"targetname" "t93" -"origin" "2376 2304 -216" -"classname" "path_corner" -} -{ -"target" "t93" -"targetname" "t92" -"classname" "path_corner" -"origin" "2376 1984 -216" -} -{ -"target" "t95" -"targetname" "t94" -"origin" "2144 1608 -216" -"classname" "path_corner" -} -{ -"target" "t94" -"targetname" "t95" -"classname" "path_corner" -"origin" "2376 1608 -216" -} -{ -"target" "t92" -"angle" "270" -"origin" "2376 2176 -200" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"angle" "135" -"origin" "2416 1760 -200" -"classname" "monster_hell_knight" -"spawnflags" "257" -} -{ -"target" "t94" -"angle" "180" -"origin" "2320 1608 -200" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"angle" "90" -"origin" "2152 1840 -200" -"classname" "monster_ogre" -"spawnflags" "257" -} -{ -"target" "t97" -"targetname" "t96" -"origin" "2096 2376 -216" -"classname" "path_corner" -"spawnflags" "256" -} -{ -"target" "t96" -"targetname" "t97" -"classname" "path_corner" -"origin" "2232 2208 -216" -"spawnflags" "256" -} -{ -"target" "t96" -"angle" "135" -"origin" "2200 2264 -200" -"classname" "monster_wizard" -"spawnflags" "257" -} -{ -"origin" "2104 1544 -224" -"classname" "item_shells" -} -{ -"origin" "2176 1240 -32" -"classname" "item_spikes" -} -{ -"classname" "item_spikes" -"origin" "2256 1240 -32" -} -{ -"origin" "1928 584 -32" -"classname" "item_shells" -} -{ -"spawnflags" "1" -"origin" "2040 1072 -32" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "2040 1024 -32" -"spawnflags" "1" -} -{ -"angle" "225" -"origin" "2352 1160 -200" -"classname" "monster_hell_knight" -"spawnflags" "256" -} -{ -"angle" "180" -"origin" "1864 1192 -216" -"classname" "monster_zombie" -} -{ -"classname" "monster_zombie" -"origin" "1776 1192 -216" -"angle" "180" -} -{ -"target" "t99" -"targetname" "t98" -"origin" "1688 1192 -232" -"classname" "path_corner" -} -{ -"target" "t98" -"targetname" "t99" -"classname" "path_corner" -"origin" "1688 1048 -232" -} -{ -"target" "t98" -"angle" "90" -"origin" "1688 1112 -216" -"classname" "monster_zombie" -} -{ -"origin" "536 416 32" -"classname" "item_shells" -} -{ -"target" "t100" -"classname" "trigger_once" -"spawnflags" "256" -"model" "*57" -} -{ -"origin" "1784 408 -128" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1784 448 -128" -} -{ -"origin" "1736 728 -128" -"classname" "item_rockets" -} -{ -"target" "t101" -"sounds" "1" -"wait" "-1" -"angle" "270" -"classname" "func_button" -"model" "*58" -} -{ -"light" "250" -"origin" "1418 234 52" -"classname" "light_torch_small_walltorch" -} -{ -"targetname" "t101" -"classname" "trigger_secret" -"model" "*59" -} -{ -"targetname" "t102" -"angle" "180" -"classname" "trigger_monsterjump" -"model" "*60" -} -{ -"target" "t102" -"killtarget" "t102" -"classname" "trigger_once" -"model" "*61" -} -{ -"origin" "1568 1968 -352" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1608 1968 -352" -} -{ -"origin" "2112 1776 -352" -"classname" "item_shells" -"spawnflags" "2048" -} -{ -"origin" "1920 2232 -352" -"classname" "item_spikes" -} -{ -"classname" "item_spikes" -"origin" "2008 2232 -352" -} -{ -"classname" "item_shells" -"origin" "2176 1440 -224" -} -{ -"target" "t66" -"classname" "trigger_once" -"model" "*62" -} -{ -"origin" "1744 0 -128" -"classname" "item_spikes" -"spawnflags" "1" -} -{ -"target" "t103" -"targetname" "t104" -"origin" "-56 1432 -224" -"classname" "path_corner" -"spawnflags" "256" -} -{ -"target" "t104" -"targetname" "t103" -"classname" "path_corner" -"origin" "312 1432 -224" -"spawnflags" "256" -} -{ -"target" "t103" -"origin" "40 1440 -208" -"classname" "monster_ogre" -"spawnflags" "257" -} -{ -"angle" "45" -"origin" "56 1616 -208" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"target" "t105" -"targetname" "t106" -"origin" "520 1816 -232" -"classname" "path_corner" -} -{ -"target" "t106" -"targetname" "t105" -"classname" "path_corner" -"origin" "920 1816 -232" -} -{ -"target" "t105" -"origin" "624 1800 -216" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"angle" "0" -"origin" "480 1824 64" -"classname" "monster_wizard" -"spawnflags" "257" -} -{ -"targetname" "t107" -"classname" "monster_wizard" -"origin" "656 1816 64" -"angle" "0" -"spawnflags" "1" -} -{ -"targetname" "t107" -"angle" "0" -"origin" "840 1816 64" -"classname" "monster_wizard" -"spawnflags" "257" -} -{ -"target" "t107" -"classname" "trigger_once" -"model" "*63" -} -{ -"origin" "1440 2200 -192" -"classname" "item_shells" -} -{ -"classname" "item_shells" -"origin" "1440 2160 -192" -} -{ -"spawnflags" "1" -"origin" "1184 1976 -192" -"classname" "item_spikes" -} -{ -"target" "t109" -"targetname" "t108" -"origin" "1240 2000 -184" -"classname" "path_corner" -} -{ -"target" "t108" -"targetname" "t109" -"classname" "path_corner" -"origin" "1240 1760 -184" -} -{ -"target" "t108" -"angle" "90" -"origin" "1240 1904 -168" -"classname" "monster_ogre" -"spawnflags" "1" -} -{ -"target" "t110" -"classname" "trigger_once" -"spawnflags" "256" -"model" "*64" -} -{ -"targetname" "t110" -"angle" "45" -"origin" "1216 2088 -168" -"classname" "monster_ogre" -"spawnflags" "1281" -} -{ -"classname" "item_health" -"origin" "1496 1768 -200" -} -{ -"target" "t111" -"classname" "trigger_once" -"model" "*65" -} -{ -"targetname" "t111" -"angle" "315" -"origin" "764 -60 -208" -"classname" "monster_zombie" -} -{ -"targetname" "t111" -"angle" "45" -"origin" "764 436 -208" -"classname" "monster_zombie" -} -{ -"targetname" "t111" -"angle" "225" -"origin" "284 -56 -208" -"classname" "monster_zombie" -"spawnflags" "256" -} -{ -"targetname" "t119" -"wait" "-1" -"speed" "40" -"angle" "90" -"classname" "func_door" -"model" "*66" -} -{ -"origin" "1280 592 -128" -"classname" "item_shells" -} -{ -"classname" "item_shells" -"origin" "576 416 32" -} -{ -"classname" "item_spikes" -"origin" "904 504 -128" -"spawnflags" "1" -} -{ -"origin" "904 464 -128" -"classname" "item_spikes" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "1024 912 -152" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "720 848 -184" -"spawnflags" "1" -} -{ -"classname" "path_corner" -"origin" "1224 1192 -176" -"targetname" "t112" -"target" "t113" -} -{ -"origin" "1216 896 -176" -"classname" "path_corner" -"targetname" "t113" -"target" "t112" -} -{ -"classname" "monster_ogre" -"origin" "1224 992 -160" -"angle" "90" -"target" "t112" -} -{ -"classname" "item_shells" -"origin" "968 1600 -184" -} -{ -"classname" "item_artifact_super_damage" -"origin" "1444 308 -104" -} -{ -"classname" "light" -"origin" "992 -128 72" -"light" "100" -} -{ -"classname" "item_shells" -"origin" "1672 1008 -240" -} -{ -"classname" "item_health" -"origin" "2264 1320 -224" -} -{ -"classname" "monster_wizard" -"origin" "2120 1664 -72" -"angle" "315" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "2016 392 -32" -} -{ -"classname" "monster_hell_knight" -"origin" "360 1744 -208" -"angle" "90" -"targetname" "t114" -"spawnflags" "257" -} -{ -"classname" "trigger_once" -"target" "t114" -"spawnflags" "256" -"model" "*67" -} -{ -"classname" "item_health" -"origin" "352 1464 -232" -} -{ -"spawnflags" "1" -"origin" "352 1392 -232" -"classname" "item_health" -} -{ -"classname" "item_armorInv" -"origin" "744 1424 -448" -} -{ -"classname" "item_health" -"origin" "-56 320 -232" -} -{ -"origin" "-16 320 -232" -"classname" "item_health" -} -{ -"targetname" "t117" -"classname" "trigger_teleport" -"target" "t115" -"spawnflags" "2" -"model" "*68" -} -{ -"delay" ".5" -"targetname" "t117" -"classname" "trigger_teleport" -"target" "t116" -"spawnflags" "2" -"model" "*69" -} -{ -"classname" "monster_wizard" -"origin" "2928 1816 -152" -"angle" "180" -"targetname" "t117" -} -{ -"angle" "180" -"origin" "2928 1768 -152" -"classname" "monster_wizard" -"targetname" "t117" -} -{ -"classname" "info_teleport_destination" -"origin" "1824 1920 -184" -"angle" "225" -"targetname" "t115" -} -{ -"classname" "info_teleport_destination" -"origin" "1880 1544 -184" -"angle" "180" -"targetname" "t116" -} -{ -"classname" "trigger_once" -"target" "t117" -"model" "*70" -} -{ -"classname" "monster_zombie" -"origin" "764 388 -208" -"angle" "0" -"targetname" "t111" -} -{ -"angle" "0" -"origin" "764 -12 -208" -"classname" "monster_zombie" -"targetname" "t111" -} -{ -"classname" "monster_zombie" -"origin" "408 -56 -208" -"angle" "270" -"targetname" "t111" -} -{ -"classname" "light" -"origin" "1200 672 -240" -"light" "125" -} -{ -"classname" "item_spikes" -"origin" "72 392 -64" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "2368 920 -224" -} -{ -"origin" "2032 976 -224" -"classname" "item_spikes" -} -{ -"classname" "light" -"origin" "1416 2096 -112" -"light" "150" -} -{ -"light" "150" -"origin" "1240 2096 -112" -"classname" "light" -} -{ -"classname" "item_spikes" -"origin" "464 1824 -240" -} -{ -"origin" "504 1824 -240" -"classname" "item_spikes" -} -{ -"classname" "item_shells" -"origin" "-96 1472 -232" -"spawnflags" "1" -} -{ -"classname" "item_health" -"origin" "528 -172 -232" -} -{ -"classname" "item_health" -"origin" "40 -64 -64" -} -{ -"light" "225" -"classname" "light_torch_small_walltorch" -"origin" "122 -86 -8" -} -{ -"origin" "134 462 -8" -"classname" "light_torch_small_walltorch" -"light" "225" -} -{ -"light" "250" -"origin" "678 446 92" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light_torch_small_walltorch" -"origin" "678 -70 92" -"light" "250" -} -{ -"light" "150" -"origin" "120 -56 -16" -"classname" "light" -} -{ -"classname" "light" -"origin" "136 424 -16" -"light" "150" -} -{ -"light" "150" -"origin" "600 184 296" -"classname" "light" -} -{ -"classname" "light" -"origin" "152 184 296" -"light" "150" -} -{ -"light" "150" -"origin" "368 376 296" -"classname" "light" -} -{ -"classname" "light" -"origin" "368 0 296" -"light" "150" -} -{ -"light" "150" -"origin" "352 192 232" -"classname" "light" -} -{ -"light" "200" -"origin" "64 408 168" -"classname" "light" -} -{ -"classname" "light" -"origin" "56 -48 168" -"light" "200" -} -{ -"light" "125" -"origin" "1520 1880 24" -"classname" "light" -} -{ -"origin" "272 272 -232" -"classname" "item_rockets" -} -{ -"targetname" "t45" -"classname" "func_door" -"angle" "-2" -"sounds" "1" -"wait" "-1" -"model" "*71" -} -{ -"classname" "light" -"origin" "416 -152 -152" -"light" "125" -} -{ -"targetname" "t45" -"angle" "90" -"origin" "416 -120 -208" -"classname" "monster_zombie" -"spawnflags" "256" -} -{ -"origin" "400 524 -232" -"classname" "item_health" -} -{ -"light" "125" -"origin" "416 536 -152" -"classname" "light" -} -{ -"targetname" "t45" -"wait" "-1" -"sounds" "1" -"angle" "-2" -"classname" "func_door" -"model" "*72" -} -{ -"targetname" "t45" -"angle" "270" -"origin" "416 496 -208" -"classname" "monster_zombie" -"spawnflags" "256" -} -{ -"target" "t120" -"wait" "-1" -"angle" "270" -"classname" "func_button" -"model" "*73" -} -{ -"target" "t120" -"wait" "-1" -"angle" "90" -"classname" "func_button" -"model" "*74" -} -{ -"targetname" "t120" -"target" "t119" -"classname" "trigger_counter" -"model" "*75" -} -{ -"light" "125" -"origin" "1792 840 -112" -"classname" "light" -} -{ -"classname" "light" -"origin" "1584 840 -112" -"light" "125" -} -{ -"light" "125" -"origin" "1792 2280 -480" -"classname" "light" -} -{ -"classname" "light" -"origin" "1792 2144 -480" -"light" "125" -} -{ -"origin" "1776 2232 -508" -"classname" "item_health" -} -{ -"classname" "item_health" -"origin" "1776 2192 -508" -} -{ -"light" "150" -"origin" "1016 1696 -336" -"classname" "light" -} -{ -"light" "125" -"origin" "1080 1696 -280" -"classname" "light" -} -{ -"light" "125" -"origin" "1152 1696 -200" -"classname" "light" -} -{ -"light" "150" -"origin" "1096 1696 -352" -"classname" "light" -} -{ -"classname" "trigger_secret" -"model" "*76" -} -{ -"target" "t116" -"classname" "trigger_teleport" -"model" "*77" -} -{ -"spawnflags" "768" -"angle" "315" -"origin" "1400 1856 -176" -"classname" "monster_ogre" -} -{ -"target" "t121" -"targetname" "t122" -"spawnflags" "768" -"origin" "1824 2280 -344" -"classname" "path_corner" -} -{ -"target" "t122" -"targetname" "t121" -"spawnflags" "768" -"classname" "path_corner" -"origin" "2080 2280 -344" -} -{ -"target" "t121" -"spawnflags" "769" -"angle" "180" -"origin" "2128 2272 -328" -"classname" "monster_demon1" -} -{ -"spawnflags" "2816" -"origin" "1824 2072 -352" -"classname" "item_shells" -} -{ -"spawnflags" "769" -"angle" "90" -"origin" "1792 2176 -144" -"classname" "monster_wizard" -} -{ -"spawnflags" "769" -"angle" "180" -"origin" "2600 1640 -200" -"classname" "monster_hell_knight" -} -{ -"spawnflags" "2816" -"origin" "2096 1136 -32" -"classname" "item_shells" -} -{ -"classname" "monster_wizard" -"origin" "1872 1432 -72" -"angle" "90" -"spawnflags" "769" -} -{ -"classname" "monster_hell_knight" -"origin" "2400 1032 -8" -"angle" "180" -"spawnflags" "769" -} -{ -"classname" "monster_demon1" -"origin" "1000 496 -104" -"angle" "0" -"spawnflags" "768" -} -{ -"classname" "monster_demon1" -"origin" "1240 2088 -168" -"angle" "45" -"spawnflags" "769" -"targetname" "t110" -} -{ -"classname" "monster_hell_knight" -"origin" "360 1936 -208" -"angle" "270" -"spawnflags" "769" -"targetname" "t114" -} -{ -"classname" "item_shells" -"origin" "16 1768 -232" -"spawnflags" "2560" -} -{ -"spawnflags" "2560" -"origin" "344 1576 -232" -"classname" "item_shells" -} -{ -"classname" "trigger_changelevel" -"map" "e2m4" -"model" "*78" -} -{ -"classname" "light" -"origin" "1136 -1144 264" -"light" "250" -} -{ -"light" "250" -"origin" "1264 -552 44" -"classname" "light_flame_small_yellow" -} -{ -"classname" "light_flame_small_yellow" -"origin" "1008 -552 44" -"light" "250" -} -{ -"classname" "monster_demon1" -"origin" "888 -120 56" -"angle" "0" -"spawnflags" "769" -"targetname" "t66" -} -{ -"classname" "monster_hell_knight" -"origin" "616 184 56" -"angle" "0" -"spawnflags" "768" -} -{ -"classname" "item_spikes" -"origin" "880 216 32" -"spawnflags" "2816" -} -{ -"classname" "monster_hell_knight" -"origin" "1944 728 -8" -"angle" "0" -"spawnflags" "769" -} -{ -"classname" "light" -"origin" "-48 1184 -156" -"light" "200" -"style" "10" -} -{ -"style" "10" -"light" "200" -"origin" "0 1024 -120" -"classname" "light" -} -{ -"classname" "light" -"origin" "48 800 -120" -"light" "200" -"style" "10" -} -{ -"style" "10" -"light" "200" -"origin" "0 600 -120" -"classname" "light" -} -{ -"classname" "monster_hell_knight" -"origin" "128 1088 -208" -"angle" "225" -"spawnflags" "1" -} -{ -"angle" "315" -"origin" "-104 760 -208" -"classname" "monster_hell_knight" -"spawnflags" "1" -} -{ -"classname" "item_spikes" -"origin" "-56 592 -232" -} -{ -"classname" "item_health" -"origin" "-56 920 -232" -} -{ -"classname" "monster_demon1" -"origin" "0 544 -208" -"angle" "90" -"target" "t123" -"spawnflags" "769" -} -{ -"mangle" "20 315 0" -"origin" "1568 2040 -88" -"classname" "info_intermission" -} -{ -"classname" "item_shells" -"origin" "1528 1968 -352" -"spawnflags" "3584" -} -{ -"origin" "-88 1376 -232" -"classname" "item_health" -"spawnflags" "3585" -} -{ -"classname" "item_artifact_envirosuit" -"origin" "1216 1696 -168" -"spawnflags" "3584" -} -{ -"classname" "monster_demon1" -"origin" "144 372 -208" -"angle" "180" -"spawnflags" "768" -"targetname" "t123" -} -{ -"classname" "monster_demon1" -"origin" "0 528 -208" -"angle" "90" -"spawnflags" "1025" -} -{ -"classname" "info_player_deathmatch" -"origin" "1128 -840 -80" -"angle" "90" -} -{ -"classname" "info_player_deathmatch" -"origin" "656 184 -208" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "-24 1440 -208" -"angle" "0" -} -{ -"classname" "info_player_deathmatch" -"origin" "1240 1816 -168" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "1032 1568 -168" -"angle" "0" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*79" -} -{ -"classname" "weapon_rocketlauncher" -"origin" "184 1440 -232" -"spawnflags" "1792" -} -{ -"classname" "info_player_deathmatch" -"origin" "1424 608 -104" -"angle" "270" -} -{ -"classname" "info_player_deathmatch" -"origin" "2272 680 -8" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "2240 1472 -200" -"angle" "270" -} -{ -"classname" "weapon_supernailgun" -"origin" "2236 1184 -32" -"spawnflags" "1792" -} -{ -"classname" "info_player_deathmatch" -"origin" "2424 1824 -200" -"angle" "180" -} -{ -"classname" "info_player_deathmatch" -"origin" "1792 2072 -328" -"angle" "270" -} -{ -"classname" "weapon_supershotgun" -"origin" "1488 1584 -200" -"spawnflags" "1792" -} -{ -"classname" "weapon_grenadelauncher" -"origin" "88 184 -64" -"spawnflags" "1792" -} -{ -"classname" "info_player_deathmatch" -"origin" "1224 840 -168" -"angle" "90" -} -{ -"classname" "weapon_nailgun" -"origin" "1024 872 -152" -"spawnflags" "1792" -} -{ -"classname" "weapon_supershotgun" -"origin" "136 1760 -232" -"spawnflags" "1792" -} -{ -"classname" "weapon_nailgun" -"origin" "1976 2288 -352" -"spawnflags" "1792" -} -{ -"classname" "weapon_lightning" -"origin" "2128 1792 -352" -"spawnflags" "1792" -} -{ -"classname" "item_cells" -"origin" "1608 728 -128" -"spawnflags" "1792" -} -{ -"spawnflags" "1792" -"classname" "item_cells" -"origin" "72 1032 -232" -} -{ -"classname" "item_cells" -"origin" "1008 1328 -192" -"spawnflags" "1792" -} -{ -"classname" "item_cells" -"origin" "1304 -1160 -96" -"spawnflags" "1792" -} -{ -"origin" "2272 1440 -224" -"classname" "item_shells" -"spawnflags" "2816" -} -{ -"origin" "224 1736 -232" -"classname" "item_health" -} -{ -"classname" "info_intermission" -"origin" "1328 -1168 192" -"mangle" "20 120 0" -} -{ -"classname" "info_intermission" -"origin" "1248 680 8" -"mangle" "20 130 0" -} -{ -"classname" "info_intermission" -"origin" "1280 1824 -104" -"mangle" "10 180 0" -} -{ -"classname" "light" -"origin" "-304 888 -80" -"light" "150" -} -{ -"light" "150" -"origin" "-304 712 -80" -"classname" "light" -} -{ -"classname" "light" -"origin" "-224 872 -8" -"light" "125" -} -{ -"classname" "light" -"origin" "-224 728 -8" -"light" "125" -} -{ -"light" "150" -"origin" "-178 706 -156" -"classname" "light_torch_small_walltorch" -} -{ -"classname" "light" -"origin" "-320 838 -138" -"light" "100" -} -{ -"light" "100" -"origin" "-320 774 -138" -"classname" "light" -} -{ -"classname" "info_player_coop" -"origin" "1192 -1088 -72" -"angle" "90" -} -{ -"angle" "90" -"origin" "1080 -1088 -72" -"classname" "info_player_coop" -} -{ -"classname" "info_player_coop" -"origin" "1008 -1112 -72" -"angle" "90" -} -{ -"angle" "90" -"origin" "1264 -1112 -72" -"classname" "info_player_coop" -} -{ -"classname" "item_armor1" -"origin" "784 1816 -232" -} -{ -"classname" "item_spikes" -"origin" "-56 1472 -232" -"spawnflags" "1" -} -{ -"classname" "item_rockets" -"origin" "400 -172 -232" -} -{ -"classname" "func_wall" -"spawnflags" "1792" -"model" "*80" -} -{ -"spawnflags" "1792" -"classname" "func_wall" -"model" "*81" -} -{ -"classname" "path_corner" -"origin" "1954 1770 -96" -"targetname" "t124" -"target" "t125" -} -{ -"classname" "path_corner" -"origin" "1954 1770 -320" -"targetname" "t125" -"target" "t124" -} -{ -"classname" "weapon_grenadelauncher" -"origin" "1688 720 -128" -"spawnflags" "2048" -} -{ -"wait" "-1" -"angle" "-2" -"classname" "func_door" -"targetname" "t126" -"lip" "-8" -"model" "*82" -} -{ -"classname" "func_door_secret" -"angle" "90" -"spawnflags" "2" -"model" "*83" -} -{ -"classname" "light" -"origin" "-224 832 -152" -"light" "125" -} -{ -"classname" "trigger_counter" -"target" "t126" -"targetname" "t127" -"spawnflags" "1" -"count" "7" -"model" "*84" -} -{ -"classname" "trigger_once" -"health" "1" -"target" "t127" -"model" "*85" -} -{ -"health" "1" -"classname" "trigger_once" -"target" "t127" -"model" "*86" -} -{ -"classname" "trigger_once" -"health" "1" -"target" "t127" -"model" "*87" -} -{ -"health" "1" -"classname" "trigger_once" -"target" "t127" -"model" "*88" -} -{ -"classname" "trigger_once" -"health" "1" -"target" "t127" -"model" "*89" -} -{ -"health" "1" -"classname" "trigger_once" -"target" "t127" -"model" "*90" -} -{ -"classname" "trigger_once" -"health" "1" -"target" "t127" -"model" "*91" -} -{ -"classname" "ambient_swamp1" -"origin" "1338 -854 -104" -} -{ -"classname" "ambient_swamp2" -"origin" "938 -854 -104" -} -{ -"classname" "ambient_drip" -"origin" "1138 -854 -176" -} -{ -"classname" "ambient_drip" -"origin" "1650 -862 -192" -} -{ -"classname" "ambient_drip" -"origin" "1674 -438 -192" -} -{ -"classname" "ambient_drip" -"origin" "1682 2 -48" -} -{ -"classname" "ambient_swamp1" -"origin" "1674 1986 -280" -} -{ -"classname" "ambient_swamp2" -"origin" "1826 2378 -280" -} -{ -"classname" "ambient_swamp1" -"origin" "2258 2058 -280" -} -{ -"classname" "ambient_drip" -"origin" "746 1370 -376" -} -{ -"classname" "ambient_drip" -"origin" "762 906 -240" -} -{ -"origin" "1034 722 -240" -"classname" "ambient_drip" -} -{ -"classname" "ambient_drip" -"origin" "554 1818 -352" -} -{ -"origin" "1002 1810 -352" -"classname" "ambient_drip" -} -{ -"speed" "35" -"classname" "func_door" -"wait" "-1" -"angle" "-2" -"sounds" "1" -"targetname" "t101" -"model" "*92" -} -{ -"classname" "light" -"origin" "1440 296 -80" -"light" "125" -} -{ -"origin" "1792 792 -240" -"classname" "item_spikes" -} diff --git a/Quake/Makefile b/Quake/Makefile index e0eabc087..bc8ad966e 100644 --- a/Quake/Makefile +++ b/Quake/Makefile @@ -10,6 +10,9 @@ DO_USERDIRS=0 ### Enable/Disable SDL2 USE_SDL2=1 +### Enable/Disable Curl +USE_CURL=1 + ### Enable/Disable codecs for streaming music support USE_CODEC_WAVE=1 USE_CODEC_FLAC=0 @@ -35,9 +38,9 @@ check_gcc = $(shell if echo | $(CC) $(1) -Werror -S -o /dev/null -xc - > /dev/nu # --------------------------- -HOST_OS := $(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]') +HOST_OS = $(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]') -DEBUG ?= 0 +DEBUG ?= 0 # --------------------------- # build variables @@ -50,7 +53,7 @@ STRIP ?= strip PKG_CONFIG ?= pkg-config CPUFLAGS= -LDFLAGS = +LDFLAGS?= DFLAGS ?= CFLAGS ?= -Wall -Wno-trigraphs CFLAGS += $(call check_gcc,-std=gnu11,) @@ -76,26 +79,6 @@ ifeq ($(DO_USERDIRS),1) CFLAGS += -DDO_USERDIRS=1 endif -### X11BASE only gets used if its in an unusual place - -X11DIRS := /usr/X11R7 /usr/local/X11R7 /usr/X11R6 /usr/local/X11R6 -X11BASE_GUESS := $(shell \ - if [ -e /usr/include/X11/Xlib.h ] && \ - [ -e /usr/lib/libX11.a ]; then exit 0; fi; \ - if [ -e /usr/local/include/X11/Xlib.h ] && \ - [ -e /usr/local/lib/libX11.a ]; then exit 0; fi; \ - for DIR in $(X11DIRS); do \ - if [ -e $$DIR/include/X11/Xlib.h ] && \ - [ -e $$DIR/lib/libX11.a ]; then echo $$DIR; break; fi; \ - done ) - -X11BASE ?= $(X11BASE_GUESS) - -ifneq ($(X11BASE),) -LDFLAGS+= -L$(X11BASE)/lib -CFLAGS += -I$(X11BASE)/include -endif - ifeq ($(USE_SDL2),1) CFLAGS += -DUSE_SDL2 endif @@ -105,17 +88,23 @@ SDL_CONFIG ?= sdl2-config else SDL_CONFIG ?= sdl-config endif -SDL_CFLAGS := $(shell $(SDL_CONFIG) --cflags) -SDL_LIBS := $(shell $(SDL_CONFIG) --libs) +SDL_CFLAGS = $(shell $(SDL_CONFIG) --cflags) +SDL_LIBS = $(shell $(SDL_CONFIG) --libs) +NET_LIBS = ifeq ($(HOST_OS),sunos) -NET_LIBS :=-lsocket -lnsl -lresolv -else -NET_LIBS := +NET_LIBS =-lsocket -lnsl -lresolv +endif +ifeq ($(HOST_OS),haiku) +NET_LIBS =-lnetwork endif +ifeq ($(USE_CURL),1) NET_LIBS += -lcurl CFLAGS += $(shell $(PKG_CONFIG) --cflags libcurl) +else +CFLAGS += -DWITHOUT_CURL +endif ifneq ($(VORBISLIB),vorbis) ifneq ($(VORBISLIB),tremor) @@ -144,7 +133,7 @@ cpp_vorbisdec=-DVORBIS_USE_TREMOR lib_vorbisdec=-lvorbisidec -logg endif -CODECLIBS := +CODECLIBS = ifeq ($(USE_CODEC_WAVE),1) CFLAGS+= -DUSE_CODEC_WAVE endif @@ -184,9 +173,13 @@ ifeq ($(USE_CODEC_UMX),1) CFLAGS+= -DUSE_CODEC_UMX endif -COMMON_LIBS:= -lm -lGL +ifeq ($(HOST_OS),haiku) +COMMON_LIBS= -lGL +else +COMMON_LIBS= -lGL -lm +endif -LIBS := $(COMMON_LIBS) $(NET_LIBS) $(CODECLIBS) +LIBS = $(COMMON_LIBS) $(NET_LIBS) $(CODECLIBS) # name of this makefile, so we can use it as a dependency MAKEFILE := $(lastword $(MAKEFILE_LIST)) @@ -195,7 +188,7 @@ MAKEFILE := $(lastword $(MAKEFILE_LIST)) # objects # --------------------------- -MUSIC_OBJS:= bgmusic.o \ +MUSIC_OBJS= bgmusic.o \ snd_codec.o \ snd_flac.o \ snd_wave.o \ @@ -207,14 +200,14 @@ MUSIC_OBJS:= bgmusic.o \ snd_modplug.o \ snd_xmp.o \ snd_umx.o -COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) -SYSOBJ_SND := snd_sdl.o -SYSOBJ_CDA := cd_sdl.o -SYSOBJ_INPUT := in_sdl.o -SYSOBJ_GL_VID:= gl_vidsdl.o -SYSOBJ_NET := net_bsd.o net_udp.o -SYSOBJ_SYS := pl_linux.o sys_sdl_unix.o -SYSOBJ_MAIN:= main_sdl.o +COMOBJ_SND = snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) +SYSOBJ_SND = snd_sdl.o +SYSOBJ_CDA = cd_sdl.o +SYSOBJ_INPUT = in_sdl.o +SYSOBJ_GL_VID= gl_vidsdl.o +SYSOBJ_NET = net_bsd.o net_udp.o +SYSOBJ_SYS = pl_linux.o sys_sdl_unix.o +SYSOBJ_MAIN= main_sdl.o GLOBJS = \ gl_refrag.o \ @@ -238,7 +231,7 @@ GLOBJS = \ r_brush.o \ gl_model.o -OBJS := strlcat.o \ +OBJS = strlcat.o \ strlcpy.o \ $(GLOBJS) \ $(SYSOBJ_INPUT) \ @@ -292,7 +285,7 @@ OBJS += $(SYSOBJ_RES) .PHONY: clean debug release -DEFAULT_TARGET := ironwail +DEFAULT_TARGET = ironwail all: $(DEFAULT_TARGET) %.d: %.c $(MAKEFILE) @@ -314,9 +307,17 @@ debug: clean: $(MAKEFILE) $(RM) *.o *.d $(DEFAULT_TARGET) +ifeq ($(HOST_OS),haiku) +IW_APP_DIR=$(shell finddir B_APPS_DIRECTORY)/ironwail/ +install: ironwail + mkdir -p $(IW_APP_DIR) + cp ironwail $(IW_APP_DIR) + cp ironwail.pak $(IW_APP_DIR) +else install: ironwail cp ironwail /usr/local/games/quake cp ironwail.pak /usr/local/games/quake +endif #--------------------------------------------------------------- # include dependencies (if not running 'clean' target) diff --git a/Quake/Makefile.w32 b/Quake/Makefile.w32 index 379f2a844..7668d5082 100644 --- a/Quake/Makefile.w32 +++ b/Quake/Makefile.w32 @@ -1,4 +1,4 @@ -# GNU Makefile for compiling Win32 ironwail.exe using MinGW or MinGW-w64. +# GNU Makefile for compiling x86-Windows ironwail.exe using MinGW or MinGW-w64. # Usage: "make -f Makefile.w32" # To cross-compile on Linux hosts, see the build_cross_win32*.sh scripts. # "make DEBUG=1" to build a debug client. @@ -8,6 +8,9 @@ ### Enable/disable SDL2 USE_SDL2=1 +### Enable/Disable Curl +USE_CURL=1 + ### Enable/disable codecs for streaming music support USE_CODEC_WAVE=1 USE_CODEC_FLAC=1 @@ -33,8 +36,8 @@ check_gcc = $(shell if echo | $(CC) $(1) -Werror -S -o /dev/null -xc - > /dev/nu # --------------------------- -DEBUG ?= 0 -WINSOCK2?= 0 +DEBUG ?= 0 +WINSOCK2 ?= 0 # --------------------------- # build variables @@ -47,7 +50,7 @@ WINDRES = windres STRIP = strip CPUFLAGS= -LDFLAGS = -m32 -mwindows -static-libgcc +LDFLAGS?= -m32 -mwindows -static-libgcc DFLAGS ?= CFLAGS ?= -m32 -Wall -Wno-trigraphs CFLAGS += $(call check_gcc,-std=gnu11,) @@ -79,23 +82,27 @@ SDL_CONFIG ?=../Windows/SDL2/bin/sdl2-config --prefix=../Windows/SDL2 else SDL_CONFIG ?=../Windows/SDL/bin/sdl-config --prefix=../Windows/SDL endif -SDL_CFLAGS := $(shell $(SDL_CONFIG) --cflags) -SDL_LIBS := $(shell $(SDL_CONFIG) --libs) +SDL_CFLAGS = $(shell $(SDL_CONFIG) --cflags) +SDL_LIBS = $(shell $(SDL_CONFIG) --libs) ifeq ($(WINSOCK2),1) -DEFWINSOCK :=-D_USE_WINSOCK2 -LIBWINSOCK := -lws2_32 +DEFWINSOCK =-D_USE_WINSOCK2 +LIBWINSOCK = -lws2_32 else -DEFWINSOCK := -LIBWINSOCK := -lwsock32 +DEFWINSOCK = +LIBWINSOCK = -lwsock32 endif -CFLAGS += $(DEFWINSOCK) -NET_LIBS := $(LIBWINSOCK) +CFLAGS += $(DEFWINSOCK) +NET_LIBS = $(LIBWINSOCK) +ifeq ($(USE_CURL),1) NET_LIBS += -lcurl CFLAGS += -I../Windows/curl/include LDFLAGS += -L../Windows/curl/lib/x86 +else +CFLAGS += -DWITHOUT_CURL +endif ifneq ($(VORBISLIB),vorbis) ifneq ($(VORBISLIB),tremor) @@ -124,7 +131,7 @@ cpp_vorbisdec=-DVORBIS_USE_TREMOR lib_vorbisdec=-lvorbisidec -logg endif -CODECLIBS := +CODECLIBS = ifeq ($(USE_CODEC_WAVE),1) CFLAGS+= -DUSE_CODEC_WAVE endif @@ -175,9 +182,9 @@ CFLAGS+= -DUSE_CODEC_UMX endif CFLAGS+= $(CODEC_INC) -COMMON_LIBS:= -lopengl32 -lwinmm -luuid -lole32 +COMMON_LIBS= -lopengl32 -lwinmm -luuid -lole32 -LIBS := $(COMMON_LIBS) $(NET_LIBS) $(CODEC_LINK) $(CODECLIBS) +LIBS = $(COMMON_LIBS) $(NET_LIBS) $(CODEC_LINK) $(CODECLIBS) # name of this makefile, so we can use it as a dependency MAKEFILE := $(lastword $(MAKEFILE_LIST)) @@ -186,7 +193,7 @@ MAKEFILE := $(lastword $(MAKEFILE_LIST)) # objects # --------------------------- -MUSIC_OBJS:= bgmusic.o \ +MUSIC_OBJS= bgmusic.o \ snd_codec.o \ snd_flac.o \ snd_wave.o \ @@ -198,15 +205,15 @@ MUSIC_OBJS:= bgmusic.o \ snd_modplug.o \ snd_xmp.o \ snd_umx.o -COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) -SYSOBJ_SND := snd_sdl.o -SYSOBJ_CDA := cd_sdl.o -SYSOBJ_INPUT := in_sdl.o -SYSOBJ_GL_VID:= gl_vidsdl.o -SYSOBJ_NET := net_win.o net_wins.o net_wipx.o -SYSOBJ_SYS := pl_win.o sys_sdl_win.o -SYSOBJ_MAIN:= main_sdl.o -SYSOBJ_RES := QuakeSpasm.res +COMOBJ_SND = snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) +SYSOBJ_SND = snd_sdl.o +SYSOBJ_CDA = cd_sdl.o +SYSOBJ_INPUT = in_sdl.o +SYSOBJ_GL_VID= gl_vidsdl.o +SYSOBJ_NET = net_win.o net_wins.o net_wipx.o +SYSOBJ_SYS = pl_win.o sys_sdl_win.o +SYSOBJ_MAIN= main_sdl.o +SYSOBJ_RES = QuakeSpasm.res GLOBJS = \ gl_refrag.o \ @@ -230,7 +237,7 @@ GLOBJS = \ r_brush.o \ gl_model.o -OBJS := strlcat.o \ +OBJS = strlcat.o \ strlcpy.o \ $(GLOBJS) \ $(SYSOBJ_INPUT) \ @@ -284,7 +291,7 @@ OBJS += $(SYSOBJ_RES) .PHONY: clean debug release -DEFAULT_TARGET := ironwail.exe +DEFAULT_TARGET = ironwail.exe all: $(DEFAULT_TARGET) %.d: %.c $(MAKEFILE) diff --git a/Quake/Makefile.w64 b/Quake/Makefile.w64 index 1a4b09a53..2723244a4 100644 --- a/Quake/Makefile.w64 +++ b/Quake/Makefile.w64 @@ -1,4 +1,4 @@ -# GNU Makefile for compiling Win64 ironwail.exe using MinGW-w64. +# GNU Makefile for compiling x64-Windows ironwail.exe using MinGW-w64. # Usage: "make -f Makefile.w64" # To cross-compile on Linux hosts, see the build_cross_win32*.sh scripts. # "make DEBUG=1" to build a debug client. @@ -7,6 +7,9 @@ ### Enable/disable SDL2 USE_SDL2=1 +### Enable/Disable Curl +USE_CURL=1 + ### Enable/disable codecs for streaming music support USE_CODEC_WAVE=1 USE_CODEC_FLAC=1 @@ -32,7 +35,7 @@ check_gcc = $(shell if echo | $(CC) $(1) -Werror -S -o /dev/null -xc - > /dev/nu # --------------------------- -DEBUG ?= 0 +DEBUG ?= 0 # --------------------------- # build variables @@ -45,7 +48,7 @@ WINDRES = windres STRIP = strip CPUFLAGS= -LDFLAGS = -m64 -mwindows -static-libgcc +LDFLAGS?= -m64 -mwindows -static-libgcc DFLAGS ?= CFLAGS ?= -m64 -Wall -Wno-trigraphs CFLAGS += $(call check_gcc,-std=gnu11,) @@ -77,18 +80,22 @@ SDL_CONFIG ?=../Windows/SDL2/bin/sdl2-config --prefix=../Windows/SDL2 --lib-suff else SDL_CONFIG ?=../Windows/SDL/bin/sdl-config --prefix=../Windows/SDL --lib-suffix=64 endif -SDL_CFLAGS := $(shell $(SDL_CONFIG) --cflags) -SDL_LIBS := $(shell $(SDL_CONFIG) --libs) +SDL_CFLAGS = $(shell $(SDL_CONFIG) --cflags) +SDL_LIBS = $(shell $(SDL_CONFIG) --libs) -DEFWINSOCK :=-D_USE_WINSOCK2 -LIBWINSOCK := -lws2_32 +DEFWINSOCK =-D_USE_WINSOCK2 +LIBWINSOCK = -lws2_32 -CFLAGS += $(DEFWINSOCK) -NET_LIBS := $(LIBWINSOCK) +CFLAGS += $(DEFWINSOCK) +NET_LIBS = $(LIBWINSOCK) +ifeq ($(USE_CURL),1) NET_LIBS += -lcurl CFLAGS += -I../Windows/curl/include LDFLAGS += -L../Windows/curl/lib/x64 +else +CFLAGS += -DWITHOUT_CURL +endif ifneq ($(VORBISLIB),vorbis) ifneq ($(VORBISLIB),tremor) @@ -117,7 +124,7 @@ cpp_vorbisdec=-DVORBIS_USE_TREMOR lib_vorbisdec=-lvorbisidec -logg endif -CODECLIBS := +CODECLIBS = ifeq ($(USE_CODEC_WAVE),1) CFLAGS+= -DUSE_CODEC_WAVE endif @@ -168,9 +175,9 @@ CFLAGS+= -DUSE_CODEC_UMX endif CFLAGS+= $(CODEC_INC) -COMMON_LIBS:= -lopengl32 -lwinmm -luuid -lole32 +COMMON_LIBS= -lopengl32 -lwinmm -luuid -lole32 -LIBS := $(COMMON_LIBS) $(NET_LIBS) $(CODEC_LINK) $(CODECLIBS) +LIBS = $(COMMON_LIBS) $(NET_LIBS) $(CODEC_LINK) $(CODECLIBS) # name of this makefile, so we can use it as a dependency MAKEFILE := $(lastword $(MAKEFILE_LIST)) @@ -179,7 +186,7 @@ MAKEFILE := $(lastword $(MAKEFILE_LIST)) # objects # --------------------------- -MUSIC_OBJS:= bgmusic.o \ +MUSIC_OBJS= bgmusic.o \ snd_codec.o \ snd_flac.o \ snd_wave.o \ @@ -191,15 +198,15 @@ MUSIC_OBJS:= bgmusic.o \ snd_modplug.o \ snd_xmp.o \ snd_umx.o -COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) -SYSOBJ_SND := snd_sdl.o -SYSOBJ_CDA := cd_sdl.o -SYSOBJ_INPUT := in_sdl.o -SYSOBJ_GL_VID:= gl_vidsdl.o -SYSOBJ_NET := net_win.o net_wins.o net_wipx.o -SYSOBJ_SYS := pl_win.o sys_sdl_win.o -SYSOBJ_MAIN:= main_sdl.o -SYSOBJ_RES := QuakeSpasm.res +COMOBJ_SND = snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS) +SYSOBJ_SND = snd_sdl.o +SYSOBJ_CDA = cd_sdl.o +SYSOBJ_INPUT = in_sdl.o +SYSOBJ_GL_VID= gl_vidsdl.o +SYSOBJ_NET = net_win.o net_wins.o net_wipx.o +SYSOBJ_SYS = pl_win.o sys_sdl_win.o +SYSOBJ_MAIN= main_sdl.o +SYSOBJ_RES = QuakeSpasm.res GLOBJS = \ gl_refrag.o \ @@ -223,7 +230,7 @@ GLOBJS = \ r_brush.o \ gl_model.o -OBJS := strlcat.o \ +OBJS = strlcat.o \ strlcpy.o \ $(GLOBJS) \ $(SYSOBJ_INPUT) \ @@ -277,7 +284,7 @@ OBJS += $(SYSOBJ_RES) .PHONY: clean debug release -DEFAULT_TARGET := ironwail.exe +DEFAULT_TARGET = ironwail.exe all: $(DEFAULT_TARGET) %.d: %.c $(MAKEFILE) diff --git a/Quake/arch_def.h b/Quake/arch_def.h index 4a27d9ad3..8dd5b86dd 100644 --- a/Quake/arch_def.h +++ b/Quake/arch_def.h @@ -72,6 +72,12 @@ # define PLATFORM_RISCOS 1 # endif +#elif defined(__HAIKU__) + +# if !defined(PLATFORM_HAIKU) +# define PLATFORM_HAIKU 1 +# endif + #else /* here goes the unix platforms */ #if defined(__unix) || defined(__unix__) || defined(unix) || \ @@ -159,6 +165,8 @@ # define PLATFORM_STRING "RiscOS" #elif defined(__GNU__) # define PLATFORM_STRING "GNU/Hurd" +#elif defined(PLATFORM_HAIKU) +# define PLATFORM_STRING "Haiku" #elif defined(PLATFORM_UNIX) # define PLATFORM_STRING "Unix" #else diff --git a/Quake/build_cross_haiku32-sdl2.sh b/Quake/build_cross_haiku32-sdl2.sh new file mode 100755 index 000000000..d6c5e559c --- /dev/null +++ b/Quake/build_cross_haiku32-sdl2.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Change this script to meet your needs and/or environment. + +TARGET=i586-pc-haiku + +MAKE_CMD=make + +CC="$TARGET-gcc" +AS="$TARGET-as" +RANLIB="$TARGET-ranlib" +AR="$TARGET-ar" +STRIP="$TARGET-strip" +LDFLAGS=-L/usr/lib32 # hack +export CC AS AR RANLIB STRIP LDFLAGS + +exec $MAKE_CMD HOST_OS=haiku USE_SDL2=1 LDFLAGS=$LDFLAGS CC=$CC AS=$AS RANLIB=$RANLIB AR=$AR STRIP=$STRIP -f Makefile $* diff --git a/Quake/build_cross_haiku64-sdl2.sh b/Quake/build_cross_haiku64-sdl2.sh new file mode 100755 index 000000000..809052833 --- /dev/null +++ b/Quake/build_cross_haiku64-sdl2.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# Change this script to meet your needs and/or environment. + +TARGET=x86_64-unknown-haiku + +MAKE_CMD=make + +CC="$TARGET-gcc" +AS="$TARGET-as" +RANLIB="$TARGET-ranlib" +AR="$TARGET-ar" +STRIP="$TARGET-strip" +export CC AS AR RANLIB STRIP + +exec $MAKE_CMD HOST_OS=haiku USE_SDL2=1 CC=$CC AS=$AS RANLIB=$RANLIB AR=$AR STRIP=$STRIP -f Makefile $* diff --git a/Quake/cl_input.c b/Quake/cl_input.c index 7fc54e8fa..5a0327bf7 100644 --- a/Quake/cl_input.c +++ b/Quake/cl_input.c @@ -248,6 +248,16 @@ cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5",CVAR_NONE}; cvar_t cl_alwaysrun = {"cl_alwaysrun","1",CVAR_ARCHIVE}; // QuakeSpasm -- new always run +/* +================ +CL_InCutscene +================ +*/ +qboolean CL_InCutscene (void) +{ + return cl.fixangle && !cl.viewent.model; +} + /* ================ CL_AdjustAngles @@ -260,7 +270,7 @@ void CL_AdjustAngles (void) float speed; float up, down; - if (cl.fixangle) + if (CL_InCutscene ()) return; if ((in_speed.state & 1) ^ (cl_alwaysrun.value != 0.0)) diff --git a/Quake/cl_main.c b/Quake/cl_main.c index 313c8e8b9..ced627c9a 100644 --- a/Quake/cl_main.c +++ b/Quake/cl_main.c @@ -240,6 +240,7 @@ void CL_SignonReply (void) break; case 4: + cl.spawntime = cl.mtime[0]; SCR_EndLoadingPlaque (); // allow normal screen updates break; } @@ -853,22 +854,22 @@ void CL_Viewpos_f (void) //camera position q_snprintf (buf, sizeof (buf), "(%i %i %i) %i %i %i", - (int)r_refdef.vieworg[0], - (int)r_refdef.vieworg[1], - (int)r_refdef.vieworg[2], - (int)r_refdef.viewangles[PITCH], - (int)r_refdef.viewangles[YAW], - (int)r_refdef.viewangles[ROLL]); + Q_rint (r_refdef.vieworg[0]), + Q_rint (r_refdef.vieworg[1]), + Q_rint (r_refdef.vieworg[2]), + Q_rint (r_refdef.viewangles[PITCH]), + Q_rint (r_refdef.viewangles[YAW]), + Q_rint (r_refdef.viewangles[ROLL])); #else //player position q_snprintf (buf, sizeof (buf), "(%i %i %i) %i %i %i", - (int)cl_entities[cl.viewentity].origin[0], - (int)cl_entities[cl.viewentity].origin[1], - (int)cl_entities[cl.viewentity].origin[2], - (int)cl.viewangles[PITCH], - (int)cl.viewangles[YAW], - (int)cl.viewangles[ROLL] + Q_rint (cl_entities[cl.viewentity].origin[0]), + Q_rint (cl_entities[cl.viewentity].origin[1]), + Q_rint (cl_entities[cl.viewentity].origin[2]), + Q_rint (cl.viewangles[PITCH]), + Q_rint (cl.viewangles[YAW]), + Q_rint (cl.viewangles[ROLL]) ); #endif Con_Printf ("Viewpos: %s\n", buf); @@ -878,6 +879,18 @@ void CL_Viewpos_f (void) Con_Printf ("Clipboard copy failed: %s\n", SDL_GetError ()); } +/* +=============== +CL_Viewpos_Completion_f -- tab completion for the viewpos command +=============== +*/ +static void CL_Viewpos_Completion_f (const char *partial) +{ + if (Cmd_Argc () != 2) + return; + Con_AddToTabList ("copy", partial, NULL); +} + /* ============= CL_SetStat_f @@ -939,6 +952,8 @@ CL_Init */ void CL_Init (void) { + cmd_function_t *cmd; + SZ_Alloc (&cls.message, 1024); CL_InitInput (); @@ -986,7 +1001,9 @@ void CL_Init (void) Cmd_AddCommand ("timedemo", CL_TimeDemo_f); Cmd_AddCommand ("tracepos", CL_Tracepos_f); //johnfitz - Cmd_AddCommand ("viewpos", CL_Viewpos_f); //johnfitz + cmd = Cmd_AddCommand ("viewpos", CL_Viewpos_f); //johnfitz + if (cmd) + cmd->completion = CL_Viewpos_Completion_f; Cmd_AddCommand_ServerCommand ("st", CL_SetStat_f); Cmd_AddCommand_ServerCommand ("sts", CL_SetStatString_f); diff --git a/Quake/cl_parse.c b/Quake/cl_parse.c index 1be598644..171cafb77 100644 --- a/Quake/cl_parse.c +++ b/Quake/cl_parse.c @@ -97,7 +97,7 @@ const char *svc_strings[] = "svc_backtolobby", // 55 "svc_localsound" // 56 }; -#define NUM_SVC_STRINGS (sizeof(svc_strings) / sizeof(svc_strings[0])) +#define NUM_SVC_STRINGS Q_COUNTOF(svc_strings) qboolean warn_about_nehahra_protocol; //johnfitz diff --git a/Quake/client.h b/Quake/client.h index 9aa0090c6..46a8d4403 100644 --- a/Quake/client.h +++ b/Quake/client.h @@ -204,6 +204,7 @@ typedef struct float last_received_message; // (realtime) for net trouble icon + float spawntime; // time when signon 4 was received // // information that is static for the entire time connected to a server @@ -341,6 +342,7 @@ void CL_SendMove (const usercmd_t *cmd); int CL_ReadFromServer (void); void CL_AdjustAngles (void); void CL_BaseMove (usercmd_t *cmd); +qboolean CL_InCutscene (void); void CL_ParseTEnt (void); void CL_UpdateTEnts (void); diff --git a/Quake/cmd.c b/Quake/cmd.c index 97f272860..05b3d1314 100644 --- a/Quake/cmd.c +++ b/Quake/cmd.c @@ -286,7 +286,7 @@ Cmd_Exec_f void Cmd_Exec_f (void) { const char *path; - char *f; + const char *f; int mark; if (Cmd_Argc () < 2) @@ -303,7 +303,7 @@ void Cmd_Exec_f (void) // "exec config.cfg pls" will execute config.cfg if (Cmd_Argc () == 2 && !strcmp (path, "config.cfg")) { - f = (char *)COM_LoadHunkFile (CONFIG_NAME, NULL); + f = (const char *)COM_LoadHunkFile (CONFIG_NAME, NULL); if (f) { path = CONFIG_NAME; @@ -311,7 +311,7 @@ void Cmd_Exec_f (void) } } - f = (char *)COM_LoadHunkFile (path, NULL); + f = (const char *)COM_LoadHunkFile (path, NULL); if (!f && !strcmp(Cmd_Argv(1), "default.cfg")) { f = default_cfg; /* see above.. */ } diff --git a/Quake/common.c b/Quake/common.c index d1a9e5553..dd74723db 100644 --- a/Quake/common.c +++ b/Quake/common.c @@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "miniz.h" #include "unicode_translit.h" -static char *largv[MAX_NUM_ARGVS + 1]; +static const char *largv[MAX_NUM_ARGVS + 1]; static char argvdummy[] = " "; int safemode; @@ -55,8 +55,8 @@ static void COM_Path_f (void); #define PAK0_CRC_V091 28804 /* id1/pak0.pak - v0.91/0.92, not supported */ THREAD_LOCAL char com_token[1024]; -int com_argc; -char **com_argv; +int com_argc; +const char **com_argv; #define CMDLINE_LENGTH 256 /* johnfitz -- mirrored in cmd.c */ char com_cmdline[CMDLINE_LENGTH]; @@ -304,44 +304,22 @@ int q_strncasecmp(const char *s1, const char *s2, size_t n) return (int)(c1 - c2); } -//spike -- grabbed this from fte, because its useful to me char *q_strcasestr(const char *haystack, const char *needle) { - int c1, c2, c2f; - int i; - c2f = *needle; - if (c2f >= 'a' && c2f <= 'z') - c2f -= ('a' - 'A'); - if (!c2f) - return (char*)haystack; - while (1) + const size_t len = strlen(needle); + + if (!len) + return (char *)haystack; + + while (*haystack) { - c1 = *haystack; - if (!c1) - return NULL; - if (c1 >= 'a' && c1 <= 'z') - c1 -= ('a' - 'A'); - if (c1 == c2f) - { - for (i = 1; ; i++) - { - c1 = haystack[i]; - c2 = needle[i]; - if (c1 >= 'a' && c1 <= 'z') - c1 -= ('a' - 'A'); - if (c2 >= 'a' && c2 <= 'z') - c2 -= ('a' - 'A'); - if (!c2) - return (char*)haystack; //end of needle means we found a complete match - if (!c1) //end of haystack means we can't possibly find needle in it any more - return NULL; - if (c1 != c2) //mismatch means no match starting at haystack[0] - break; - } - } - haystack++; + if (!q_strncasecmp(haystack, needle, len)) + return (char *)haystack; + + ++haystack; } - return NULL; //didn't find it + + return NULL; } char *q_strlwr (char *str) @@ -1043,6 +1021,37 @@ void SZ_Print (sizebuf_t *buf, const char *data) //============================================================================ +/* +============ +COM_FirstPathSep + +Returns a pointer to the first path separator, if any, or the end of the string +============ +*/ +const char *COM_FirstPathSep (const char *path) +{ + while (*path && !Sys_IsPathSep (*path)) + path++; + return path; +} + +/* +============ +COM_NormalizePath + +Replaces all path separators with forward slashes +============ +*/ +void COM_NormalizePath (char *path) +{ + while (*path) + { + if (Sys_IsPathSep (*path)) + *path = '/'; + path++; + } +} + /* ============ COM_SkipPath @@ -1314,7 +1323,7 @@ const char *COM_ParseEx (const char *data, cpe_mode mode) com_token[len] = 0; return data; } - if (len < countof (com_token) - 1) + if (len < Q_COUNTOF(com_token) - 1) com_token[len++] = c; else if (mode == CPE_NOTRUNC) return NULL; @@ -1324,7 +1333,7 @@ const char *COM_ParseEx (const char *data, cpe_mode mode) // parse single characters if (c == '{' || c == '}'|| c == '('|| c == ')' || c == '\'' || c == ':') { - if (len < countof (com_token) - 1) + if (len < Q_COUNTOF(com_token) - 1) com_token[len++] = c; else if (mode == CPE_NOTRUNC) return NULL; @@ -1335,7 +1344,7 @@ const char *COM_ParseEx (const char *data, cpe_mode mode) // parse a regular word do { - if (len < countof (com_token) - 1) + if (len < Q_COUNTOF(com_token) - 1) com_token[len++] = c; else if (mode == CPE_NOTRUNC) return NULL; @@ -1424,13 +1433,17 @@ static void COM_CheckRegistered (void) return; } - Sys_FileRead (h, check, sizeof(check)); + i = Sys_FileRead (h, check, sizeof(check)); COM_CloseFile (h); + if (i != (int) sizeof(check)) + goto corrupt; for (i = 0; i < 128; i++) { if (pop[i] != (unsigned short)BigShort (check[i])) + { corrupt: Sys_Error ("Corrupted data file."); + } } for (i = 0; com_cmdline[i]; i++) @@ -1500,6 +1513,22 @@ void COM_InitArgv (int argc, char **argv) } } +/* +================ +COM_AddArg + +Returns the index of the new argument or -1 on overflow +================ +*/ +int COM_AddArg (const char *arg) +{ + if (com_argc >= MAX_NUM_ARGVS) + return -1; + com_argv[com_argc] = arg; + com_argv[com_argc + 1] = argvdummy; + return com_argc++; +} + /* ================ COM_Init @@ -1691,6 +1720,43 @@ char *COM_TempSuffix (unsigned seq) return buf; } +/* +============ +COM_DescribeDuration + +Describes the given duration, e.g. "3 minutes" +============ +*/ +void COM_DescribeDuration (char *out, size_t outsize, double seconds) +{ + const double SECOND = 1; + const double MINUTE = 60 * SECOND; + const double HOUR = 60 * MINUTE; + const double DAY = 24 * HOUR; + const double WEEK = 7 * DAY; + const double MONTH = 30.436875 * DAY; + const double YEAR = 365.2425 * DAY; + + seconds = fabs (seconds); + + if (seconds < 1) + q_strlcpy (out, "moments", outsize); + else if (seconds < 60 * SECOND) + q_snprintf (out, outsize, "%i second%s", PLURAL (seconds)); + else if (seconds < 90 * MINUTE) + q_snprintf (out, outsize, "%i minute%s", PLURAL (seconds / MINUTE)); + else if (seconds < DAY) + q_snprintf (out, outsize, "%i hour%s", PLURAL (seconds / HOUR)); + else if (seconds < WEEK) + q_snprintf (out, outsize, "%i day%s", PLURAL (seconds / DAY)); + else if (seconds < MONTH) + q_snprintf (out, outsize, "%i week%s", PLURAL (seconds / WEEK)); + else if (seconds < YEAR) + q_snprintf (out, outsize, "%i month%s", PLURAL (seconds / MONTH)); + else + q_snprintf (out, outsize, "%i year%s", PLURAL (seconds / YEAR)); +} + /* ============ COM_CreatePath @@ -1920,7 +1986,7 @@ byte *COM_LoadFile (const char *path, int usehunk, unsigned int *path_id) int h; byte *buf; char base[32]; - int len; + int len, nread; buf = NULL; // quiet compiler warning @@ -1964,8 +2030,10 @@ byte *COM_LoadFile (const char *path, int usehunk, unsigned int *path_id) ((byte *)buf)[len] = 0; - Sys_FileRead (h, buf, len); + nread = Sys_FileRead (h, buf, len); COM_CloseFile (h); + if (nread != len) + Sys_Error ("COM_LoadFile: Error reading %s", path); return buf; } @@ -2140,8 +2208,8 @@ static pack_t *COM_LoadPackFile (const char *packfile) if (Sys_FileOpenRead (packfile, &packhandle) == -1) return NULL; - Sys_FileRead (packhandle, (void *)&header, sizeof(header)); - if (header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') + if (Sys_FileRead(packhandle, &header, sizeof(header)) != (int) sizeof(header) || + header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') Sys_Error ("%s is not a packfile", packfile); header.dirofs = LittleLong (header.dirofs); @@ -2169,7 +2237,8 @@ static pack_t *COM_LoadPackFile (const char *packfile) newfiles = (packfile_t *) Z_Malloc(numpackfiles * sizeof(packfile_t)); Sys_FileSeek (packhandle, header.dirofs); - Sys_FileRead (packhandle, (void *)info, header.dirlen); + if (Sys_FileRead(packhandle, info, header.dirlen) != header.dirlen) + Sys_Error ("Error reading %s", packfile); // crc the directory to check for modifications if (!com_modified) @@ -2262,7 +2331,7 @@ static void COM_AddEnginePak (void) COM_AddGameDirectory -- johnfitz -- modified based on topaz's tutorial ================= */ -static void COM_AddGameDirectory (const char *dir) +void COM_AddGameDirectory (const char *dir) { const char *base; int i, j; @@ -2328,9 +2397,9 @@ static void COM_AddGameDirectory (const char *dir) } } -void COM_ResetGameDirectories(char *newgamedirs) +void COM_ResetGameDirectories(const char *newgamedirs) { - char *newpath, *path; + const char *newpath, *path; searchpath_t *search; //Kill the extra game if it is loaded while (com_searchpaths != com_base_searchpaths) @@ -2377,11 +2446,73 @@ void COM_ResetGameDirectories(char *newgamedirs) //============================================================================== //johnfitz -- dynamic gamedir stuff -- modified by QuakeSpasm team. //============================================================================== + +/* +================= +COM_SwitchGame +================= +*/ +void COM_SwitchGame (const char *paths) +{ + extern cvar_t max_edicts; + if (!q_strcasecmp(paths, COM_GetGameNames(true))) + { + Con_Printf("\"game\" is already \"%s\"\n", COM_GetGameNames(true)); + return; + } + + Host_WaitForSaveThread (); + + com_modified = true; + + //Kill the server + CL_Disconnect (); + Host_ShutdownServer(true); + + //Write config file + Host_WriteConfiguration (); + + // stop parsing map files before changing file system search paths + ExtraMaps_Clear (); + + COM_ResetGameDirectories(paths); + + //clear out and reload appropriate data + Cache_Flush (); + Mod_ResetAll(); + Sky_ClearAll(); + if (!isDedicated) + { + TexMgr_NewGame (); + Draw_NewGame (); + R_NewGame (); + } + ExtraMaps_Init (); + Host_Resetdemos (); + DemoList_Rebuild (); + SaveList_Rebuild (); + SkyList_Rebuild (); + M_CheckMods (); + Cvar_SetQuick (&max_edicts, max_edicts.default_string); + + Con_Printf("\n%s\n\"game\" changed to \"%s\"\n", Con_Quakebar (40), COM_GetGameNames(true)); + + VID_Lock (); + Cbuf_AddText ("unaliasall\n"); + Cbuf_AddText ("exec quake.rc\n"); + Cbuf_AddText ("vid_unlock\n"); +} + + +/* +================= +COM_Game_f +================= +*/ static void COM_Game_f (void) { if (Cmd_Argc() > 1) { - extern cvar_t max_edicts; int i, pri; char paths[1024]; @@ -2424,52 +2555,8 @@ static void COM_Game_f (void) } } - if (!q_strcasecmp(paths, COM_GetGameNames(true))) - { - Con_Printf("\"game\" is already \"%s\"\n", COM_GetGameNames(true)); - return; - } - - Host_WaitForSaveThread (); - - com_modified = true; + COM_SwitchGame (paths); - //Kill the server - CL_Disconnect (); - Host_ShutdownServer(true); - - //Write config file - Host_WriteConfiguration (); - - // stop parsing map files before changing file system search paths - ExtraMaps_Clear (); - - COM_ResetGameDirectories(paths); - - //clear out and reload appropriate data - Cache_Flush (); - Mod_ResetAll(); - Sky_ClearAll(); - if (!isDedicated) - { - TexMgr_NewGame (); - Draw_NewGame (); - R_NewGame (); - } - ExtraMaps_Init (); - Host_Resetdemos (); - DemoList_Rebuild (); - SaveList_Rebuild (); - SkyList_Rebuild (); - M_CheckMods (); - Cvar_SetQuick (&max_edicts, max_edicts.default_string); - - Con_Printf("\n%s\n\"game\" changed to \"%s\"\n", Con_Quakebar (40), COM_GetGameNames(true)); - - VID_Lock (); - Cbuf_AddText ("unaliasall\n"); - Cbuf_AddText ("exec quake.rc\n"); - Cbuf_AddText ("vid_unlock\n"); } else //Diplay the current gamedir Con_Printf("\"game\" is \"%s\"\n", COM_GetGameNames(true)); @@ -2649,6 +2736,206 @@ static void COM_MigrateNightdiveUserFiles (void) VEC_FREE (subdirs); } +/* +================= +COM_SetBaseDirRec + +Looks for a valid basedir in all the ancestors of the supplied path +Returns the path relative to that basedir if successful, NULL otherwise +================= +*/ +static const char *COM_SetBaseDirRec (const char *start) +{ + char buf[MAX_OSPATH]; + size_t i, len; + + q_strlcpy (buf, start, sizeof (buf)); + len = strlen (start); + + for (i = len - 1; i > 1; i--) + { + if (Sys_IsPathSep (buf[i])) + { + buf[i] = '\0'; + if (COM_SetBaseDir (buf)) + return start + i + 1; + } + } + + return NULL; +} + +/* +================= +COM_MakeRelative +================= +*/ +static const char *COM_MakeRelative (const char *basepath, const char *fullpath) +{ + for (; *basepath && *fullpath; ++basepath, ++fullpath) + { + if (Sys_IsPathSep (*basepath) != Sys_IsPathSep (*fullpath)) + return NULL; + if (*basepath != *fullpath) + return NULL; + } + + while (Sys_IsPathSep (*fullpath)) + ++fullpath; + + return fullpath; +} + +/* +================= +COM_PatchCmdLine + +Tries to initialize basedir from a single command-line argument +(either a mod dir or a map/save/demo file) + +Returns true if successful, false otherwise +================= +*/ +static qboolean COM_PatchCmdLine (const char *fullpath) +{ + static char game[MAX_QPATH]; + char qpath[MAX_QPATH]; + char printpath[MAX_OSPATH]; + const char *relpath; + const char *sep; + int type; + int i; + + // The path (file or directory) must exist + type = Sys_FileType (fullpath); + if (type == FS_ENT_NONE) + { + UTF8_ToQuake (printpath, sizeof (printpath), fullpath); + Con_SafePrintf ("\"%s\" does not exist\n", printpath); + return false; + } + + // Look for the corresponding basedir + relpath = NULL; + for (i = 0; i < com_numbasedirs; i++) + { + relpath = COM_MakeRelative (com_basedirs[i], fullpath); + if (relpath) + break; + } + if (!relpath) + { + UTF8_ToQuake (printpath, sizeof (printpath), fullpath); + Con_SafePrintf ("\"%s\" does not belong to an existing Quake installation\n", printpath); + return false; + } + + // Game dir is the first component of the relative path + sep = COM_FirstPathSep (relpath); + if ((uintptr_t)(sep - relpath) >= sizeof (game)) + { + UTF8_ToQuake (printpath, sizeof (printpath), relpath); + Con_SafePrintf ("\"%s\" is too long\n", printpath); + return false; + } + + UTF8_ToQuake (printpath, sizeof (printpath), relpath); + + // Apply game dir + if (*sep) + { + Q_strncpy (game, relpath, (int)(sep - relpath)); + COM_AddArg ("-game"); + COM_AddArg (game); + relpath = sep + 1; + } + else if (type == FS_ENT_DIRECTORY) + { + COM_AddArg ("-game"); + COM_AddArg (relpath); + return true; + } + else + { + game[0] = '\0'; + } + + q_strlcpy (qpath, relpath, sizeof (qpath)); + COM_NormalizePath (qpath); + + // Check argument type + switch (type) + { + case FS_ENT_DIRECTORY: + if (qpath[0]) + { + if (q_strcasecmp (qpath, "maps") == 0) + { + Cbuf_AddText ("menu_maps\n"); + return true; + } + UTF8_ToQuake (printpath, sizeof (printpath), qpath); + Con_SafePrintf ("\x02subdir \"%s\" ignored\n", printpath); + } + return true; + + case FS_ENT_FILE: + { + const char *ext = COM_FileGetExtension (qpath); + + // Map file + if (q_strcasecmp (ext, "bsp") == 0) + { + if (!game[0]) + { + Con_SafePrintf ("Map \"%s\" not in a mod dir, ignoring.\n", printpath); + return false; + } + if (q_strncasecmp (qpath, "maps/", 5) != 0) + { + Con_SafePrintf ("Map \"%s\" not in the \"maps\" dir, ignoring.\n", printpath); + return false; + } + memmove (qpath, qpath + 5, strlen (qpath + 5) + 1); + Cbuf_AddText (va ("menu_maps \"%s\"\n", qpath)); + return true; + } + + // Save file + if (q_strcasecmp (ext, "sav") == 0) + { + const char *kex = game[0] ? "" : "kex"; + Cbuf_AddText (va ("load \"%s\" %s\n", qpath, kex)); + return true; + } + + // Demo file + if (q_strcasecmp (ext, "dem") == 0) + { + if (!game[0]) + { + Con_SafePrintf ("Demo \"%s\" not in a mod dir, ignoring.\n", printpath); + return false; + } + Cbuf_AddText (va ("playdemo \"%s\"\n", qpath)); + return true; + } + + break; + } + + default: + break; + } + + if (!game[0]) + Con_SafePrintf ("File \"%s\" not in a mod dir, ignoring.\n", printpath); + else + Con_SafePrintf ("Unsupported file type \"%s\", ignoring.\n", printpath); + + return false; +} + /* ================= COM_InitBaseDir @@ -2832,6 +3119,49 @@ static void COM_InitBaseDir (void) ); } +/* +================= +COM_ChooseStartArgFlavor + +Checks if the supplied path belongs to the user dir +of a specific Quake flavor (original/remastered) +and adds the corresponding command-line argument if needed +================= +*/ +static void COM_ChooseStartArgFlavor (const char *startarg) +{ + steamgame_t steamquake; + char steampath[MAX_OSPATH]; + char userdir[MAX_OSPATH]; + + if (Sys_GetAltUserPrefDir (true, userdir, sizeof (userdir)) && COM_MakeRelative (userdir, startarg)) + { + COM_AddArg ("-prefremaster"); + return; + } + + if (Sys_GetAltUserPrefDir (false, userdir, sizeof (userdir)) && COM_MakeRelative (userdir, startarg)) + { + COM_AddArg ("-preforiginal"); + return; + } + + if (Steam_FindGame (&steamquake, QUAKE_STEAM_APPID) && + Steam_ResolvePath (steampath, sizeof (steampath), &steamquake) && + Sys_GetSteamQuakeUserDir (userdir, sizeof (userdir), steamquake.library) && + COM_MakeRelative (userdir, startarg)) + { + COM_AddArg ("-prefremaster"); + return; + } + + if (Sys_GetGOGQuakeEnhancedUserDir (userdir, sizeof (userdir)) && COM_MakeRelative (userdir, startarg)) + { + COM_AddArg ("-prefremaster"); + return; + } +} + /* ================= COM_InitFilesystem @@ -2840,18 +3170,26 @@ COM_InitFilesystem void COM_InitFilesystem (void) //johnfitz -- modified based on topaz's tutorial { int i; - const char *p; + const char *p, *startarg; Cvar_RegisterVariable (®istered); Cvar_RegisterVariable (&cmdline); Cmd_AddCommand ("path", COM_Path_f); Cmd_AddCommand ("game", COM_Game_f); //johnfitz - COM_InitBaseDir (); + startarg = (com_argc == 2 && Sys_FileType (com_argv[1]) != FS_ENT_NONE) ? com_argv[1] : NULL; + if (startarg) + COM_ChooseStartArgFlavor (startarg); + + if (!startarg || !COM_SetBaseDirRec (startarg)) + COM_InitBaseDir (); if (host_parms->userdir != host_parms->basedir) COM_AddBaseDir (host_parms->userdir); + if (startarg) + COM_PatchCmdLine (startarg); + i = COM_CheckParm ("-basegame"); if (i) { //-basegame: @@ -2883,6 +3221,8 @@ void COM_InitFilesystem (void) //johnfitz -- modified based on topaz's tutorial com_base_searchpaths = com_searchpaths; COM_ResetGameDirectories(""); + Modlist_Init (); + // add mission pack requests (only one should be specified) if (COM_CheckParm ("-rogue")) COM_AddGameDirectory ("rogue"); @@ -3713,6 +4053,31 @@ static const uint32_t qchar_to_unicode[256] = ---------------------------------------------------------------------------------------------------------------------------------- */}; +/* +================== +UTF8_CodePointLength + +Returns the number of bytes needed to encode the codepoint +using UTF-8 (max 4), or 0 for an invalid code point +================== +*/ +size_t UTF8_CodePointLength (uint32_t codepoint) +{ + if (codepoint < 0x80) + return 1; + + if (codepoint < 0x800) + return 2; + + if (codepoint < 0x10000) + return 3; + + if (codepoint < 0x110000) + return 4; + + return 0; +} + /* ================== UTF8_WriteCodePoint @@ -3836,14 +4201,30 @@ uint32_t UTF8_ReadCodePoint (const char **src) UTF8_FromQuake Converts a string from Quake encoding to UTF-8 + +Returns the number of written characters (including the NUL terminator) +if a valid output buffer is provided (dst is non-NULL, maxbytes > 0), +or the total amount of space necessary to encode the entire src string +if dst is NULL and maxbytes is 0. ================== */ -void UTF8_FromQuake (char *dst, size_t maxbytes, const char *src) +size_t UTF8_FromQuake (char *dst, size_t maxbytes, const char *src) { size_t i, j, written; if (!maxbytes) - return; + { + if (dst) + return 0; // error + for (i = 0, j = 0; src[i]; i++) + { + uint32_t codepoint = qchar_to_unicode[(unsigned char) src[i]]; + if (codepoint) + j += UTF8_CodePointLength (codepoint); + } + return j + 1; // include terminator + } + --maxbytes; for (i = 0, j = 0; j < maxbytes && src[i]; i++) @@ -3857,7 +4238,9 @@ void UTF8_FromQuake (char *dst, size_t maxbytes, const char *src) j += written; } - dst[j] = '\0'; + dst[j++] = '\0'; + + return j; } /* @@ -3868,11 +4251,16 @@ Transliterates a string from UTF-8 to Quake encoding Note: only single-character transliterations are used for now, mainly to remove diacritics + +Returns the number of written characters (including the NUL terminator) +if a valid output buffer is provided (dst is non-NULL, maxbytes > 0), +or the total amount of space necessary to encode the entire src string +if dst is NULL and maxbytes is 0. ================== */ -void UTF8_ToQuake (char *dst, size_t maxbytes, const char *src) +size_t UTF8_ToQuake (char *dst, size_t maxbytes, const char *src) { - size_t i; + size_t i, j; if (!unicode_translit_init) { @@ -3896,7 +4284,32 @@ void UTF8_ToQuake (char *dst, size_t maxbytes, const char *src) } if (!maxbytes) - return; + { + if (dst) + return 0; // error + + // Determine necessary output buffer size + for (i = 0, j = 0; *src; i++) + { + // ASCII fast path + while (*src && (byte)*src < 0x80) + { + src++; + j++; + } + + if (!*src) + break; + + // Every codepoint maps to a single Quake character + UTF8_ReadCodePoint (&src); + + j++; + } + + return j + 1; // include terminator + } + --maxbytes; for (i = 0; i < maxbytes && *src; i++) @@ -3924,4 +4337,6 @@ void UTF8_ToQuake (char *dst, size_t maxbytes, const char *src) } dst[i++] = '\0'; + + return i; } diff --git a/Quake/common.h b/Quake/common.h index 12ad57a39..fb65c1e1d 100644 --- a/Quake/common.h +++ b/Quake/common.h @@ -263,7 +263,7 @@ extern char *q_strupr (char *str); extern int q_snprintf (char *str, size_t size, const char *format, ...) FUNC_PRINTF(3,4); extern int q_vsnprintf(char *str, size_t size, const char *format, va_list args) FUNC_PRINTF(3,0); -#define PLURAL(count) (&"s"[(count)==1]) +#define PLURAL(count) ((int)(count)), (&"s"[((int)(count))==1]) //============================================================================ @@ -280,8 +280,8 @@ const char *COM_Parse (const char *data); const char *COM_ParseEx (const char *data, cpe_mode mode); -extern int com_argc; -extern char **com_argv; +extern int com_argc; +extern const char **com_argv; extern int safemode; /* safe mode: in true, the engine will behave as if one @@ -296,6 +296,10 @@ void COM_Init (void); void COM_InitArgv (int argc, char **argv); void COM_InitFilesystem (void); +void COM_ResetGameDirectories (const char *newgamedirs); +void COM_AddGameDirectory (const char *dir); +void COM_SwitchGame (const char *paths); + const char *COM_SkipPath (const char *pathname); void COM_StripExtension (const char *in, char *out, size_t outsize); void COM_FileBase (const char *in, char *out, size_t outsize); @@ -308,6 +312,9 @@ void COM_ExtractExtension (const char *in, char *out, size_t outsize); char *COM_TempSuffix (unsigned seq); void COM_CreatePath (char *path); +// Describes the given duration, e.g. "3 minutes" +void COM_DescribeDuration (char *out, size_t outsize, double seconds); + char *va (const char *format, ...) FUNC_PRINTF(1,2); // does a varargs printf into a temp buffer @@ -328,8 +335,8 @@ size_t LOC_Format (const char *format, const char* (*getarg_fn)(int idx, void* u // Unicode size_t UTF8_WriteCodePoint (char *dst, size_t maxbytes, uint32_t codepoint); uint32_t UTF8_ReadCodePoint (const char **src); -void UTF8_FromQuake (char *dst, size_t maxbytes, const char *src); -void UTF8_ToQuake (char *dst, size_t maxbytes, const char *src); +size_t UTF8_FromQuake (char *dst, size_t maxbytes, const char *src); +size_t UTF8_ToQuake (char *dst, size_t maxbytes, const char *src); #define UNICODE_UNKNOWN 0xFFFD #define UNICODE_MAX 0x10FFFF diff --git a/Quake/console.c b/Quake/console.c index 4783adf8c..5f7efe5f4 100644 --- a/Quake/console.c +++ b/Quake/console.c @@ -34,6 +34,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <unistd.h> #endif +extern qboolean keydown[256]; + int con_linewidth; float con_cursorspeed = 4; @@ -65,9 +67,38 @@ typedef struct conofs_t end; } conlink_t; +typedef struct +{ + conofs_t begin; + conofs_t end; +} conselection_t; + +typedef enum +{ + // Used for link hover/clicking: + // - picks the character that contains the cursor + // - rejects areas outside the visible console region + CT_INSIDE, + + // Used for text selection: + // - picks the closest edge horizontally, on whichever line contains the cursor vertically + // - clamps to the margins of the visible console region + CT_NEAREST, +} contest_t; // Console hit testing mode + +typedef enum +{ + CMS_NOTPRESSED, + CMS_PRESSED, + CMS_DRAGGING, +} conmouse_t; + static conlink_t **con_links = NULL; static conlink_t *con_hotlink = NULL; +static conmouse_t con_mousestate = CMS_NOTPRESSED; +static conselection_t con_selection; + cvar_t con_notifytime = {"con_notifytime","3",CVAR_NONE}; //seconds cvar_t con_logcenterprint = {"con_logcenterprint", "1", CVAR_NONE}; //johnfitz cvar_t con_notifycenter = {"con_notifycenter", "0", CVAR_ARCHIVE}; @@ -82,39 +113,76 @@ double con_times[NUM_CON_TIMES]; // realtime time the line was generated int con_vislines; -qboolean con_debuglog = false; - qboolean con_initialized; /* ================ -Con_ScreenToOffset +Con_GetLine +================ +*/ +static const char *Con_GetLine (int line) +{ + return con_text + (line%con_totallines)*con_linewidth; +} -Converts screen (pixel) coordinates to a console offset -Returns true if the offset is inside the visible portion of the console +/* +================ +Con_StrLen ================ */ -static qboolean Con_ScreenToOffset (int x, int y, conofs_t *ofs) +static size_t Con_StrLen (int line) +{ + const char *text = Con_GetLine (line); + size_t len = con_linewidth; + while (len > 0 && (char)(text[len - 1] & 0x7f) == ' ') + len--; + return len; +} + +static void Con_ScreenToCanvas (int x, int y, int *outx, int *outy) { drawtransform_t transform; float px, py; - qboolean ret = true; -// screen space to [-1..1] + // screen space to [-1..1] px = (x - glx) * 2.f / (float) glwidth - 1.f; py = (y - gly) * 2.f / (float) glheight - 1.f; py = -py; - -// [-1..1] to console canvas + + // [-1..1] to console canvas Draw_GetCanvasTransform (CANVAS_CONSOLE, &transform); px = (px - transform.offset[0]) / transform.scale[0]; py = (py - transform.offset[1]) / transform.scale[1]; x = (int) (px + 0.5f); y = (int) (py + 0.5f); + *outx = x; + *outy = y; +} + + +/* +================ +Con_ScreenToOffset + +Converts screen (pixel) coordinates to a console offset +Returns true if the offset is inside the visible portion of the console +================ +*/ +static qboolean Con_ScreenToOffset (int x, int y, conofs_t *ofs, contest_t testmode) +{ + qboolean ret = true; + + Con_ScreenToCanvas (x, y, &x, &y); + +// Start from the bottom of the console y = vid.conheight - y; +// Apply rounding + if (testmode == CT_NEAREST) + x += 4; + // pixels to characters x >>= 3; y >>= 3; @@ -122,12 +190,36 @@ static qboolean Con_ScreenToOffset (int x, int y, conofs_t *ofs) // apply margins and scrolling x -= CON_MARGIN; y -= 2; - if (x < 0 || x >= con_linewidth) - ret = false; - if (y < 0 || y >= con_vislines) - ret = false; - if (con_backscroll && y < 2) - ret = false; + + if (testmode == CT_INSIDE) + { + if (x < 0 || x >= con_linewidth) + ret = false; + if (y < 0 || y >= con_vislines) + ret = false; + if (con_backscroll && y < 2) + ret = false; + } + else + { + // Allow the cursor to move one character past the end of the line + // by clamping to con_linewidth instead of con_linewidth - 1 + x = CLAMP (0, x, con_linewidth); + + // Enable selecting the entire bottom line by allowing the cursor + // to move to the beginning of the line below it (line -1) + y = CLAMP (-1, y, con_vislines); + if (y < 0) + x = 0; + + // Enable selecting the entire line above the backscroll cutoff by + // allowing the cursor to move to the beginning of the line below it + if (con_backscroll && y < 2) + { + x = 0; + y = 1; + } + } y += con_backscroll; y = con_current - y; @@ -164,6 +256,39 @@ static qboolean Con_OfsInRange (const conofs_t *ofs, const conofs_t *begin, cons return Con_OfsCompare (ofs, begin) >= 0 && Con_OfsCompare (ofs, end) < 0; } +/* +================ +Con_GetCurrentRange +================ +*/ +static void Con_GetCurrentRange (conofs_t *begin, conofs_t *end) +{ + begin->line = con_current - con_totallines + 1; + begin->col = 0; + end->line = con_current + 1; + end->col = 0; +} + +/* +================ +Con_IntersectRanges +================ +*/ +static qboolean Con_IntersectRanges (conofs_t *begin, conofs_t *end, const conofs_t *selbegin, const conofs_t *selend) +{ + if (Con_OfsCompare (selend, begin) <= 0) + return false; + if (Con_OfsCompare (end, selbegin) <= 0) + return false; + + if (Con_OfsCompare (begin, selbegin) < 0) + *begin = *selbegin; + if (Con_OfsCompare (selend, end) < 0) + *end = *selend; + + return true; +} + /* ================ Con_GetLinkAtOfs @@ -206,7 +331,7 @@ Returns the link at the given pixel coordinates, if any, or NULL otherwise static conlink_t *Con_GetLinkAtPixel (int x, int y) { conofs_t ofs; - if (!Con_ScreenToOffset (x, y, &ofs)) + if (!Con_ScreenToOffset (x, y, &ofs, CT_INSIDE)) return NULL; return Con_GetLinkAtOfs (&ofs); } @@ -223,7 +348,6 @@ static void Con_SetHotLink (conlink_t *link) if (link == con_hotlink) return; con_hotlink = link; - VID_SetMouseCursor (con_hotlink ? MOUSECURSOR_HAND : MOUSECURSOR_DEFAULT); } /* @@ -234,11 +358,11 @@ Computes the console offset corresponding to the current mouse position Returns true if the offset is inside the visible portion of the console ================ */ -static qboolean Con_GetMousePos (conofs_t *ofs) +static qboolean Con_GetMousePos (conofs_t *ofs, contest_t testmode) { int x, y; SDL_GetMouseState (&x, &y); - return Con_ScreenToOffset (x, y, ofs); + return Con_ScreenToOffset (x, y, ofs, testmode); } /* @@ -251,11 +375,91 @@ Returns the link at the current mouse position, if any, or NULL otherwise static conlink_t *Con_GetMouseLink (void) { conofs_t ofs; - if (Con_GetMousePos (&ofs)) + if (Con_GetMousePos (&ofs, CT_INSIDE)) return Con_GetLinkAtOfs (&ofs); return NULL; } +/* +================ +Con_ClearSelection +================ +*/ +static void Con_ClearSelection (void) +{ + memset (&con_selection, 0, sizeof (con_selection)); +} + +/* +================ +Con_HasSelection +================ +*/ +static qboolean Con_HasSelection (void) +{ + return Con_OfsCompare (&con_selection.begin, &con_selection.end) != 0; +} + +/* +================ +Con_GetNormalizedSelection +================ +*/ +static qboolean Con_GetNormalizedSelection (conofs_t *begin, conofs_t *end) +{ + conofs_t *selbegin = &con_selection.begin; + conofs_t *selend = &con_selection.end; + conofs_t tbegin, tend; + + if (Con_OfsCompare (selbegin, selend) > 0) + { + conofs_t *tmp = selbegin; + selbegin = selend; + selend = tmp; + } + *begin = *selbegin; + *end = *selend; + + Con_GetCurrentRange (&tbegin, &tend); + + return Con_IntersectRanges (begin, end, &tbegin, &tend); +} + +/* +================ +Con_SetMouseState +================ +*/ +static void Con_SetMouseState (conmouse_t state) +{ + if (con_mousestate == state) + return; + + switch (state) + { + case CMS_PRESSED: + Con_GetMousePos (&con_selection.begin, CT_NEAREST); + con_selection.end = con_selection.begin; + break; + + case CMS_DRAGGING: + Con_SetHotLink (NULL); + VID_SetMouseCursor (MOUSECURSOR_IBEAM); + break; + + case CMS_NOTPRESSED: + if (con_mousestate != CMS_DRAGGING && con_hotlink && !Sys_Explore (con_hotlink->path)) + S_LocalSound ("misc/menu2.wav"); + break; + + default: + break; + } + + con_mousestate = state; + Con_ForceMouseMove (); +} + /* ================ Con_Mousemove @@ -264,21 +468,50 @@ Mouse movement callback */ void Con_Mousemove (int x, int y) { - Con_SetHotLink (Con_GetLinkAtPixel (x, y)); + if (con_mousestate == CMS_NOTPRESSED) + { + Con_SetHotLink (Con_GetLinkAtPixel (x, y)); + VID_SetMouseCursor (con_hotlink ? MOUSECURSOR_HAND : MOUSECURSOR_DEFAULT); + } + else + { + Con_ScreenToOffset (x, y, &con_selection.end, CT_NEAREST); + if (Con_OfsCompare (&con_selection.begin, &con_selection.end) != 0) + Con_SetMouseState (CMS_DRAGGING); + } } /* ================ -Con_Click +Con_ForceMouseMove +================ +*/ +void Con_ForceMouseMove (void) +{ + int x, y; + SDL_GetMouseState (&x, &y); + Con_Mousemove (x, y); +} -Mouse click callback +/* +================ +Con_UpdateMouseState ================ */ -void Con_Click (void) +static void Con_UpdateMouseState (void) { - conlink_t *link = Con_GetMouseLink (); - if (link && !Sys_Explore (link->path)) - S_LocalSound ("misc/menu2.wav"); + if (key_dest != key_console) + { + Con_SetHotLink (NULL); + Con_SetMouseState (CMS_NOTPRESSED); + Con_ClearSelection (); + return; + } + + if (!keydown[K_MOUSE1]) + Con_SetMouseState (CMS_NOTPRESSED); + else if (con_mousestate == CMS_NOTPRESSED) + Con_SetMouseState (CMS_PRESSED); } /* @@ -370,6 +603,56 @@ static void Con_Clear_f (void) VEC_CLEAR (con_links); } +/* +================ +Con_CopySelectionToClipboard +================ +*/ +qboolean Con_CopySelectionToClipboard (void) +{ + conofs_t selbegin, selend; + conofs_t cursor, eol; + char *qtext = NULL; + char *utf8 = NULL; + size_t maxsize; + + S_LocalSound ("misc/menu2.wav"); + + // Get forward selection range + if (!Con_GetNormalizedSelection (&selbegin, &selend)) + return false; + + // Iterate through all lines in the selection + for (cursor = selbegin; Con_OfsCompare (&cursor, &selend) <= 0; cursor.line++, cursor.col = 0) + { + const char *text = Con_GetLine (cursor.line); + eol.line = cursor.line; + eol.col = Con_StrLen (cursor.line); + if (cursor.line == selend.line) + eol.col = q_min (eol.col, selend.col); + Vec_Append ((void **)&qtext, 1, text + cursor.col, eol.col - cursor.col); + if (eol.line != selend.line) + VEC_PUSH (qtext, '\n'); + } + VEC_PUSH (qtext, '\0'); + + // Convert to UTF-8 + maxsize = UTF8_FromQuake (NULL, 0, qtext); + utf8 = (char *) malloc (maxsize); + UTF8_FromQuake (utf8, maxsize, qtext); + + // Copy the UTF-8 text to clipboard + SDL_SetClipboardText (utf8); + + // Clean up temporary buffers + free (utf8); + VEC_FREE (qtext); + + Con_ClearSelection (); + + return true; +} + /* ================ Con_Dump_f -- johnfitz -- adapted from quake2 source @@ -541,6 +824,33 @@ void Con_CheckResize (void) } +/* +================ +Con_Scroll +================ +*/ +void Con_Scroll (int lines) +{ + if (!lines) + return; + + con_backscroll += lines; + + if (lines > 0) + { + if (con_backscroll > con_totallines - (vid.height>>3) - 1) + con_backscroll = con_totallines - (vid.height>>3) - 1; + } + else + { + if (con_backscroll < 0) + con_backscroll = 0; + } + + Con_ForceMouseMove (); +} + + /* ================ Con_Init @@ -716,6 +1026,10 @@ static int log_fd = -1; // log file descriptor /* ================ Con_DebugLog + +Writes msg to log if -condebug was specified on the command line + +Note: msg is expected to be in UTF-8, not Quake charset ================ */ void Con_DebugLog(const char *msg) @@ -723,7 +1037,31 @@ void Con_DebugLog(const char *msg) if (log_fd == -1) return; - write(log_fd, msg, strlen(msg)); + if (write(log_fd, msg, strlen(msg)) < 0) + { + close (log_fd); + log_fd = -1; + fprintf (stderr, "Error writing to log file\n"); + } +} + + +/* +================ +Con_StripControlPrefixes +================ +*/ +static const char *Con_StripControlPrefixes (const char *txt) +{ + // colored text + if (txt[0] == 1 || txt[0] == 2) + txt++; + + // [skipnotify] + if (!Q_strncmp (txt, "[skipnotify]", 12)) + txt += 12; + + return txt; } @@ -746,11 +1084,7 @@ void Con_Printf (const char *fmt, ...) va_end (argptr); // also echo to debugging console - Sys_Printf ("%s", msg); - -// log all messages to file - if (con_debuglog) - Con_DebugLog(msg); + Sys_Printf ("%s", Con_StripControlPrefixes (msg)); if (!con_initialized) return; @@ -1026,7 +1360,6 @@ typedef struct tab_s tab_t *tablist; //defs from elsewhere -extern qboolean keydown[256]; extern cmd_function_t *cmd_functions; #define MAX_ALIAS_NAME 32 typedef struct cmdalias_s @@ -1293,8 +1626,7 @@ static const arg_completion_type_t arg_completion_types[] = { "unbind", CompleteUnbindKeys, NULL }, }; -static const int num_arg_completion_types = - sizeof(arg_completion_types)/sizeof(arg_completion_types[0]); +static const int num_arg_completion_types = Q_COUNTOF(arg_completion_types); /* ============ @@ -1670,6 +2002,39 @@ void Con_DrawInput (void) } } +/* +================ +Con_DrawSelectionHighlight +================ +*/ +void Con_DrawSelectionHighlight (int x, int y, int line) +{ + conofs_t selbegin, selend; + conofs_t begin, end; + size_t len; + + if (!Con_GetNormalizedSelection (&selbegin, &selend)) + return; + + len = Con_StrLen (line); + begin.line = line; + begin.col = 0; + end.line = line; + end.col = len; + + if (!Con_IntersectRanges (&begin, &end, &selbegin, &selend)) + return; + + // Highlight line ends (as in Notepad, Visual Studio etc.) + if (end.line != selend.line && end.col == len) + end.col++; + + // ...unless we would end up overlapping the console margin + end.col = q_min (end.col, con_linewidth); + + Draw_Fill (x + begin.col*8, y, (end.col-begin.col)*8, 8, 220, 1.f); +} + /* ================ Con_DrawConsole -- johnfitz -- heavy revision @@ -1683,6 +2048,8 @@ void Con_DrawConsole (int lines, qboolean drawinput) int i, x, y, j, sb, rows; const char *text; + Con_UpdateMouseState (); + if (lines <= 0) return; @@ -1698,6 +2065,16 @@ void Con_DrawConsole (int lines, qboolean drawinput) rows -= 2; //for input and version lines sb = (con_backscroll) ? 2 : 0; + for (i = con_current - rows + 1; i <= con_current - sb; i++, y += 8) + { + j = i - con_backscroll; + if (j < 0) + j = 0; + text = con_text + (j % con_totallines)*con_linewidth; + Con_DrawSelectionHighlight (8, y, j); + } + + y = vid.conheight - (rows+2)*8; // +2 for input and version lines for (i = con_current - rows + 1; i <= con_current - sb; i++, y += 8) { conofs_t ofs; @@ -1800,7 +2177,6 @@ void LOG_Init (quakeparms_t *parms) return; } - con_debuglog = true; Con_DebugLog (va("LOG started on: %s \n", session)); } diff --git a/Quake/console.h b/Quake/console.h index 12d6d9e0b..acb8f4d5c 100644 --- a/Quake/console.h +++ b/Quake/console.h @@ -35,6 +35,7 @@ extern byte *con_chars; extern char con_lastcenterstring[]; //johnfitz void Con_CheckResize (void); +void Con_Scroll (int lines); void Con_Init (void); void Con_DrawConsole (int lines, qboolean drawinput); void Con_Printf (const char *fmt, ...) FUNC_PRINTF(1,2); @@ -62,7 +63,8 @@ qboolean Con_Match (const char *str, const char *partial); void Con_LogCenterPrint (const char *str); void Con_Mousemove (int x, int y); -void Con_Click (void); +void Con_ForceMouseMove (void); +qboolean Con_CopySelectionToClipboard (void); // // debuglog diff --git a/Quake/default_cfg.h b/Quake/default_cfg.h index 8001ca335..2984d51f8 100644 --- a/Quake/default_cfg.h +++ b/Quake/default_cfg.h @@ -1,6 +1,6 @@ // keep in sync with Misc/qs_pak/default.cfg -static char default_cfg[] = +static const char default_cfg[] = "unbindall\n" "bind ALT +strafe\n" diff --git a/Quake/gl_draw.c b/Quake/gl_draw.c index cf328e758..553954738 100644 --- a/Quake/gl_draw.c +++ b/Quake/gl_draw.c @@ -911,7 +911,7 @@ Fills a box of pixels with a single color void Draw_FillEx (float x, float y, float w, float h, const float *rgb, float alpha) { guivertex_t *verts; - + GL_SetCanvasColor (rgb[0], rgb[1], rgb[2], alpha); //johnfitz -- added alpha Draw_SetTexture (whitetexture); @@ -1121,12 +1121,19 @@ void Draw_GetCanvasTransform (canvastype type, drawtransform_t *transform) Draw_Transform (vid.guiwidth/s, vid.guiheight/s, s, CANVAS_ALIGN_CENTERX, CANVAS_ALIGN_CENTERY, transform); break; case CANVAS_SBAR: - s = CLAMP (1.0f, scr_sbarscale.value, (float)vid.guiwidth / 320.0f); - if (cl.gametype == GAME_DEATHMATCH && scr_hudstyle.value < 1) + if (scr_hudstyle.value > 2) // qw hud could cut off if too short + s = CLAMP (1.0f, scr_sbarscale.value, (float)vid.guiheight / 240.0f); + else + s = CLAMP(1.0f, scr_sbarscale.value, (float)vid.guiwidth / 320.0f); + if (cl.gametype == GAME_DEATHMATCH && (scr_hudstyle.value < 1 || scr_hudstyle.value > 2) ) Draw_Transform (320, 48, s, CANVAS_ALIGN_LEFT, CANVAS_ALIGN_BOTTOM, transform); else Draw_Transform (320, 48, s, CANVAS_ALIGN_CENTERX, CANVAS_ALIGN_BOTTOM, transform); break; + case CANVAS_SBAR_QW_INV: + s = CLAMP(1.0f, scr_sbarscale.value, (float)vid.guiheight / 240.0f); + Draw_Transform (48, 48, s, CANVAS_ALIGN_RIGHT, CANVAS_ALIGN_BOTTOM, transform); + break; case CANVAS_SBAR2: s = q_min (vid.guiwidth / 400.0f, vid.guiheight / 225.0f); s = CLAMP (1.0f, scr_sbarscale.value, s); diff --git a/Quake/gl_fog.c b/Quake/gl_fog.c index 4173b4282..14f801c0c 100644 --- a/Quake/gl_fog.c +++ b/Quake/gl_fog.c @@ -32,18 +32,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define DEFAULT_DENSITY 0.0 #define DEFAULT_GRAY 0.3 -float fog_density; -float fog_red; -float fog_green; -float fog_blue; - -float old_density; -float old_red; -float old_green; -float old_blue; - -float fade_time; //duration of fade -float fade_done; //time when fade will be done +static float fog_density; +static float fog_red; +static float fog_green; +static float fog_blue; + +static float old_density; +static float old_red; +static float old_green; +static float old_blue; + +static float fade_time; //duration of fade +static float fade_done; //time when fade will be done extern float skyfog; diff --git a/Quake/gl_mesh.c b/Quake/gl_mesh.c index e8b94aa15..425124696 100644 --- a/Quake/gl_mesh.c +++ b/Quake/gl_mesh.c @@ -122,9 +122,6 @@ void GL_MakeAliasModelDisplayLists (qmodel_t *aliasmodel, aliashdr_t *paliashdr) GLMesh_LoadVertexBuffer (aliasmodel, pheader); } -#define NUMVERTEXNORMALS 162 -extern float r_avertexnormals[NUMVERTEXNORMALS][3]; - /* ================ GLMesh_LoadVertexBuffer diff --git a/Quake/gl_model.c b/Quake/gl_model.c index 766299b38..036f46d5f 100644 --- a/Quake/gl_model.c +++ b/Quake/gl_model.c @@ -3234,7 +3234,7 @@ static void *Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int fram Mod_LoadSpriteGroup ================= */ -static void *Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +static void *Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, spriteframetype_t type) { dspritegroup_t *pingroup; mspritegroup_t *pspritegroup; @@ -3246,6 +3246,8 @@ static void *Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int fram pingroup = (dspritegroup_t *)pin; numframes = LittleLong (pingroup->numframes); + if (type == SPR_ANGLED && numframes != 8) + Sys_Error ("Mod_LoadSpriteGroup: Bad # of frames: %d", numframes); pspritegroup = (mspritegroup_t *) Hunk_AllocName (sizeof (mspritegroup_t) + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); @@ -3349,7 +3351,7 @@ static void Mod_LoadSpriteModel (qmodel_t *mod, void *buffer) else { pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, &psprite->frames[i].frameptr, i); + Mod_LoadSpriteGroup (pframetype + 1, &psprite->frames[i].frameptr, i, frametype); } } diff --git a/Quake/gl_rmain.c b/Quake/gl_rmain.c index f9c54355d..1f9e0d935 100644 --- a/Quake/gl_rmain.c +++ b/Quake/gl_rmain.c @@ -92,7 +92,7 @@ cvar_t r_clearcolor = {"r_clearcolor","2",CVAR_ARCHIVE}; cvar_t r_flatlightstyles = {"r_flatlightstyles", "0", CVAR_NONE}; cvar_t r_lerplightstyles = {"r_lerplightstyles", "1", CVAR_ARCHIVE}; // 0=off; 1=skip abrupt transitions; 2=always lerp cvar_t gl_fullbrights = {"gl_fullbrights", "1", CVAR_ARCHIVE}; -cvar_t gl_farclip = {"gl_farclip", "16384", CVAR_ARCHIVE}; +cvar_t gl_farclip = {"gl_farclip", "65536", CVAR_ARCHIVE}; cvar_t gl_overbright_models = {"gl_overbright_models", "1", CVAR_ARCHIVE}; cvar_t r_oldskyleaf = {"r_oldskyleaf", "0", CVAR_NONE}; cvar_t r_drawworld = {"r_drawworld", "1", CVAR_NONE}; diff --git a/Quake/gl_rmisc.c b/Quake/gl_rmisc.c index dad1b52e4..70ca6a326 100644 --- a/Quake/gl_rmisc.c +++ b/Quake/gl_rmisc.c @@ -224,8 +224,6 @@ R_Init */ void R_Init (void) { - extern cvar_t gl_finish; - Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); Cmd_AddCommand ("pointfile", R_ReadPointFile_f); Cmd_AddCommand ("r_showbboxes_filter", R_ShowbboxesFilter_f); @@ -310,8 +308,10 @@ void R_TranslatePlayerSkin (int playernum) //FIXME: if gl_nocolors is on, then turned off, the textures may be out of sync with the scoreboard colors. if (!gl_nocolors.value) + { if (playertextures[playernum]) TexMgr_ReloadImage (playertextures[playernum], top, bottom); + } } /* @@ -394,6 +394,7 @@ static void R_ParseWorldspawn (void) return; // error if (com_token[0] != '{') return; // error + while (1) { data = COM_Parse(data); @@ -652,7 +653,7 @@ This must be called if you do anything that could make the cached bindings invalid (e.g. manually binding, destroying the context). ==================== */ -void GL_ClearBufferBindings () +void GL_ClearBufferBindings (void) { int i; diff --git a/Quake/gl_texmgr.c b/Quake/gl_texmgr.c index 41a318ded..b0f2ef662 100644 --- a/Quake/gl_texmgr.c +++ b/Quake/gl_texmgr.c @@ -55,9 +55,10 @@ static int numgltextures; static gltexture_t *active_gltextures, *free_gltextures; gltexture_t *notexture, *nulltexture, *whitetexture, *greytexture, *blacktexture; +unsigned int d_8to24table_opaque[256]; //standard palette with alpha 255 for all colors unsigned int d_8to24table[256]; //standard palette, 255 is transparent unsigned int d_8to24table_fbright[256]; //fullbright palette, 0-223 are black (for additive blending) -unsigned int d_8to24table_alphabright[256]; //palette with lighting mask in alpha channel (0=fullbright, 1=lit) +unsigned int d_8to24table_alphabright[256]; //palette with lighting mask in alpha channel (0=fullbright, 255=lit) unsigned int d_8to24table_fbright_fence[256]; //fullbright palette, for fence textures unsigned int d_8to24table_nobright[256]; //nobright palette, 224-255 are black (for additive blending) unsigned int d_8to24table_nobright_fence[256]; //nobright palette, for fence textures @@ -89,7 +90,7 @@ static const glmode_t glmodes[] = { {GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, "GL_LINEAR_MIPMAP_NEAREST"}, {GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, "GL_LINEAR_MIPMAP_LINEAR"}, }; -#define NUM_GLMODES (int)(sizeof(glmodes)/sizeof(glmodes[0])) +#define NUM_GLMODES (int)Q_COUNTOF(glmodes) static int glmode_idx = 2; /* nearest with linear mips */ static GLuint gl_samplers[NUM_GLMODES * 2]; // x2: nomip + mip @@ -148,10 +149,8 @@ TexMgr_DescribeTextureModes_f -- report available texturemodes static void TexMgr_DescribeTextureModes_f (void) { int i; - for (i = 0; i < NUM_GLMODES; i++) Con_SafePrintf (" %2i: %s\n", i + 1, glmodes[i].name); - Con_Printf ("%i modes\n", i); } @@ -742,7 +741,7 @@ void TexMgr_LoadPalette (void) mark = Hunk_LowMark (); pal = (byte *) Hunk_Alloc (768); if (fread (pal, 768, 1, f) != 1) - Sys_Error ("TexMgr_LoadPalette: read error"); + Sys_Error ("Failed reading gfx/palette.lmp"); fclose(f); COM_FOpenFile ("gfx/colormap.lmp", &f, NULL); @@ -779,7 +778,7 @@ void TexMgr_LoadPalette (void) src = pal; for (i = 0; i < 256; i++, src += 3) { - SetColor (&d_8to24table[i], src[0], src[1], src[2], 255); + SetColor (&d_8to24table_opaque[i], src[0], src[1], src[2], 255); if (GetBit (is_fullbright, i)) { SetColor (&d_8to24table_alphabright[i], src[0], src[1], src[2], 0); @@ -793,6 +792,8 @@ void TexMgr_LoadPalette (void) SetColor (&d_8to24table_nobright[i], src[0], src[1], src[2], 255); } } + + memcpy(d_8to24table, d_8to24table_opaque, 256*4); ((byte *) &d_8to24table[255]) [3] = 0; //standard palette, 255 is transparent //fullbright palette, for fence textures @@ -933,8 +934,7 @@ int TexMgr_PadConditional (int s) { if (s < TexMgr_SafeTextureSize(s)) return TexMgr_Pad(s); - else - return s; + return s; } /* @@ -1436,7 +1436,7 @@ static void TexMgr_LoadImage8 (gltexture_t *glt, byte *data) // choose palette and padbyte if (glt->flags & TEXPREF_ALPHABRIGHT) { - usepal = gl_fullbrights.value ? d_8to24table_alphabright : d_8to24table; + usepal = gl_fullbrights.value ? d_8to24table_alphabright : d_8to24table_opaque; padbyte = 0; } else if (glt->flags & TEXPREF_FULLBRIGHT) @@ -1643,6 +1643,7 @@ void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants) byte translation[256]; byte *src, *dst, *data = NULL, *translated; int mark, size, i; + // // get source data // @@ -1651,6 +1652,7 @@ void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants) if (glt->source_file[0] && glt->source_offset) { //lump inside file FILE *f; + int sz; COM_FOpenFile(glt->source_file, &f, NULL); if (!f) goto invalid; fseek (f, glt->source_offset, SEEK_CUR); @@ -1663,12 +1665,12 @@ void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants) size *= lightmap_bytes; } data = (byte *) Hunk_Alloc (size); - if (fread (data, size, 1, f) != 1) - { - fclose (f); - goto invalid; - } + sz = (int) fread (data, 1, size, f); fclose (f); + if (sz != size) { + Hunk_FreeToLowMark(mark); + Host_Error("Read error for %s", glt->name); + } } else if (glt->source_file[0] && !glt->source_offset) { data = Image_LoadImage (glt->source_file, (int *)&glt->source_width, (int *)&glt->source_height); //simple file diff --git a/Quake/gl_vidsdl.c b/Quake/gl_vidsdl.c index 42c79d90e..2d57787cf 100644 --- a/Quake/gl_vidsdl.c +++ b/Quake/gl_vidsdl.c @@ -67,6 +67,7 @@ static SDL_Window *draw_context; static SDL_GLContext gl_context; static SDL_Cursor *cursor_arrow; static SDL_Cursor *cursor_hand; +static SDL_Cursor *cursor_ibeam; static qboolean vid_locked = false; //johnfitz static qboolean vid_changed = false; @@ -181,14 +182,17 @@ static void VID_InitMouseCursors (void) { cursor_arrow = SDL_CreateSystemCursor (SDL_SYSTEM_CURSOR_ARROW); cursor_hand = SDL_CreateSystemCursor (SDL_SYSTEM_CURSOR_HAND); + cursor_ibeam = SDL_CreateSystemCursor (SDL_SYSTEM_CURSOR_IBEAM); } static void VID_FreeMouseCursors (void) { SDL_FreeCursor (cursor_arrow); SDL_FreeCursor (cursor_hand); + SDL_FreeCursor (cursor_ibeam); cursor_arrow = NULL; cursor_hand = NULL; + cursor_ibeam = NULL; } void VID_SetMouseCursor (mousecursor_t cursor) @@ -203,6 +207,10 @@ void VID_SetMouseCursor (mousecursor_t cursor) SDL_SetCursor (cursor_hand); return; + case MOUSECURSOR_IBEAM: + SDL_SetCursor (cursor_ibeam); + return; + default: return; } @@ -771,7 +779,7 @@ VID_Test -- johnfitz -- like vid_restart, but asks for confirmation after switch */ static void VID_Test (void) { - int old_width, old_height, old_refreshrate, old_bpp, old_fullscreen; + int old_width, old_height, old_refreshrate, old_fullscreen; if (vid_locked || !vid_changed) return; @@ -781,7 +789,6 @@ static void VID_Test (void) old_width = VID_GetCurrentWidth(); old_height = VID_GetCurrentHeight(); old_refreshrate = VID_GetCurrentRefreshRate(); - old_bpp = VID_GetCurrentBPP(); old_fullscreen = VID_GetFullscreen() ? true : false; VID_Restart (); @@ -1280,10 +1287,10 @@ static void GL_Init (void) gl_version = (const char *) glGetString (GL_VERSION); glGetIntegerv (GL_NUM_EXTENSIONS, &gl_num_extensions); - Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor); + Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor); Con_SafePrintf ("GL_RENDERER: %s\n", gl_renderer); - Con_SafePrintf ("GL_VERSION: %s\n", gl_version); - + Con_SafePrintf ("GL_VERSION: %s\n", gl_version); + if (gl_version == NULL || sscanf(gl_version, "%d.%d", &gl_version_major, &gl_version_minor) < 2) { gl_version_major = 0; @@ -1412,6 +1419,10 @@ void VID_Shutdown (void) if (vid_initialized) { VID_FreeMouseCursors(); + SDL_GL_DeleteContext(gl_context); + gl_context = NULL; + SDL_DestroyWindow(draw_context); + draw_context = NULL; SDL_QuitSubSystem(SDL_INIT_VIDEO); draw_context = NULL; gl_context = NULL; @@ -1585,7 +1596,7 @@ void VID_Init (void) { static char vid_center[] = "SDL_VIDEO_CENTERED=center"; int p, width, height, refreshrate; - int display_width, display_height, display_refreshrate, display_bpp; + int display_width, display_height, display_refreshrate; qboolean fullscreen; cmd_function_t *cmd; const char *read_vars[] = @@ -1603,7 +1614,7 @@ void VID_Init (void) "r_softemu_metric", "scr_pixelaspect", }; -#define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) ) +#define num_readvars Q_COUNTOF(read_vars) Con_SafePrintf ("\nVideo initialization\n"); @@ -1663,7 +1674,6 @@ void VID_Init (void) display_width = mode.w; display_height = mode.h; display_refreshrate = mode.refresh_rate; - display_bpp = SDL_BITSPERPIXEL(mode.format); } Cvar_SetValueQuick (&vid_width, (float)display_width); diff --git a/Quake/glquake.h b/Quake/glquake.h index 6e05218be..ce5c2a320 100644 --- a/Quake/glquake.h +++ b/Quake/glquake.h @@ -105,6 +105,7 @@ extern cvar_t r_scale; extern cvar_t gl_clear; extern cvar_t gl_polyblend; extern cvar_t gl_nocolors; +extern cvar_t gl_finish; extern cvar_t gl_playermip; @@ -360,6 +361,9 @@ extern qboolean r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheats extern float map_wateralpha, map_lavaalpha, map_telealpha, map_slimealpha; //ericw extern float map_fallbackalpha; //spike -- because we might want r_wateralpha to apply to teleporters while water itself wasn't watervised +#define NUMVERTEXNORMALS 162 +extern const float r_avertexnormals[NUMVERTEXNORMALS][3]; + //johnfitz -- fog functions called from outside gl_fog.c void Fog_ParseServerMessage (void); float *Fog_GetColor (void); diff --git a/Quake/host.c b/Quake/host.c index 926c0b4d5..bd4ce7922 100644 --- a/Quake/host.c +++ b/Quake/host.c @@ -629,7 +629,7 @@ void Host_ClearMemory (void) PR_ClearProgs(&cl.qcvm); /* host_hunklevel MUST be set at this point */ Hunk_FreeToLowMark (host_hunklevel); - CL_ClearSignons (); + cls.signon = 0; // not CL_ClearSignons() memset (&sv, 0, sizeof(sv)); CL_FreeState (); @@ -830,6 +830,7 @@ static void Host_CheckAutosave (void) if (cls.signon == SIGNONS) { + // Track new secrets if (pr_global_struct->found_secrets != sv.autosave.prev_secrets) { sv.autosave.prev_secrets = pr_global_struct->found_secrets; @@ -839,41 +840,65 @@ static void Host_CheckAutosave (void) sv.autosave.secret_boost = q_max (0.f, sv.autosave.secret_boost - host_frametime / 1.5f); } + // Track health changes if (!sv.autosave.prev_health) sv.autosave.prev_health = sv_player->v.health; health_change = sv_player->v.health - sv.autosave.prev_health; - if (health_change < 0.f && sv_player->v.health < 100.f) // megahealth decay doesn't count as getting hurt - sv.autosave.hurt_time = qcvm->time; + if (health_change < 0.f) + if (health_change < -3.f || sv_player->v.health < 100.f || sv_player->v.watertype == CONTENTS_SLIME || sv_player->v.watertype == CONTENTS_LAVA) + sv.autosave.hurt_time = qcvm->time; sv.autosave.prev_health = sv_player->v.health; + // Track attacking if (sv_player->v.button0) sv.autosave.shoot_time = qcvm->time; + // Time spent with cheats active doesn't count if (sv_player->v.movetype == MOVETYPE_NOCLIP || (int)sv_player->v.flags & (FL_GODMODE|FL_NOTARGET)) { sv.autosave.cheat += host_frametime; return; } + // Don't save if the player has been hurt recently if (qcvm->time - sv.autosave.hurt_time < 3.f) return; + + // Don't save if the player has fired recently if (qcvm->time - sv.autosave.shoot_time < 3.f) return; + // Only save when the player slows down a bit speed = VectorLength (sv_player->v.velocity); if (speed > 100.f) return; + // Copper's func_void holds the player at the bottom for a bit before inflicting damage, + // so we can't assume it's safe to save just because we're no longer falling + if ((int)sv_player->v.movetype == MOVETYPE_NONE) + return; + + // Don't save too often elapsed = qcvm->time - sv.autosave.time - sv.autosave.cheat; if (elapsed < 3.f) return; + // Compute a normalized autosave score + + // Base value is the fraction of the autosave interval already passed score = elapsed / sv_autosave_interval.value; + // Scale down the score if health + armor is below 100 (save less often with lower health) score *= q_min (100.f, (sv_player->v.health + sv_player->v.armortype * sv_player->v.armorvalue)) / 100.f; + // Boost the score right after picking up health score += q_max (0.f, health_change) / 100.f; + // Lower score a bit based on speed (favor standing still/slowing down) score -= (speed / 100.f) * 0.25f; + // Boost the score after finding a secret score += sv.autosave.secret_boost * 0.25f; + // Boost the score after teleporting score += CLAMP (0.f, 1.f - (qcvm->time - sv_player->v.teleport_time) / 1.5f, 1.f) * 0.5f; + + // Only save if the score is high enough if (score < 1.f) return; @@ -1308,10 +1333,8 @@ void Host_Init (void) if (host_parms->memsize < minimum_memory) Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms->memsize / (float)0x100000); - com_argc = host_parms->argc; - com_argv = host_parms->argv; - Memory_Init (host_parms->membase, host_parms->memsize); + AsyncQueue_Init (&async_queue, 1024); Cbuf_Init (); Cmd_Init (); LOG_Init (host_parms); @@ -1329,7 +1352,6 @@ void Host_Init (void) Mod_Init (); NET_Init (); SV_Init (); - AsyncQueue_Init (&async_queue, 1024); Con_Printf ("Exe: " __TIME__ " " __DATE__ " (%s %d-bit)\n", SDL_GetPlatform (), (int)sizeof(void*)*8); Con_Printf ("%4.1f megabyte heap\n", host_parms->memsize/ (1024*1024.0)); @@ -1354,7 +1376,6 @@ void Host_Init (void) BGM_Init(); Sbar_Init (); CL_Init (); - Modlist_Init (); //johnfitz ExtraMaps_Init (); //johnfitz DemoList_Init (); //ericw SaveList_Init (); diff --git a/Quake/host_cmd.c b/Quake/host_cmd.c index 180bd8d3b..300446fab 100644 --- a/Quake/host_cmd.c +++ b/Quake/host_cmd.c @@ -24,8 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "q_ctype.h" #include "json.h" - +#include <time.h> +#ifndef WITHOUT_CURL #include <curl/curl.h> +#endif #define MAX_URL 2048 extern cvar_t pausable; @@ -569,6 +571,10 @@ typedef struct download_s static qboolean Download (const char *url, download_t *download) { +#ifdef WITHOUT_CURL + download->error = "download support disabled at compile time."; + return false; +#else CURL *curl; CURLM *multi_handle; CURLMcode mc; @@ -647,6 +653,7 @@ static qboolean Download (const char *url, download_t *download) curl_multi_cleanup (multi_handle); return !download->error && !still_running && download->response == 200; +#endif } typedef struct @@ -673,7 +680,11 @@ static SDL_Thread* extramods_install_thread; const char *Modlist_GetFullName (const filelist_item_t *item) { const modinfo_t *info = (const modinfo_t *) (item + 1); - return info->full_name; + const char *full_name = info->full_name; + // 2021 rerelease episode names are localized + if (full_name && full_name[0] == '$') + full_name = LOC_GetRawString (full_name); + return full_name; } const char *Modlist_GetDescription (const filelist_item_t *item) @@ -786,8 +797,8 @@ static void Modlist_RegisterAddons (void *param) "Add-on server status:\n" "%3d add-on%s available for download\n" "%3d add-on%s already installed\n\n", - total - installed, PLURAL (total - installed), - installed, PLURAL (installed) + PLURAL (total - installed), + PLURAL (installed) ); extramods_json = json; @@ -1076,6 +1087,7 @@ static void Modlist_Add (const char *name) filelist_item_t *item; modinfo_t *info; int i; + unsigned int path_id; memset (&info, 0, sizeof (info)); item = FileList_AddWithData (name, NULL, sizeof (*info), &modlist); @@ -1113,6 +1125,50 @@ static void Modlist_Add (const char *name) } } + // look for mapdb.json file + if (!info->full_name) + { + char *mapdb = (char *) COM_LoadMallocFile ("mapdb.json", &path_id); + if (mapdb) + { + qboolean is_base_mapdb = !com_searchpaths || path_id < com_searchpaths->path_id; + json_t *json = JSON_Parse (mapdb); + free (mapdb); + if (json) + { + const jsonentry_t *episodes = JSON_Find (json->root, "episodes", JSON_ARRAY); + if (episodes) + { + const jsonentry_t *entry; + for (entry = episodes->firstchild; entry; entry = entry->next) + { + const char *mod_name = JSON_FindString (entry, "name"); + const char *mod_dir = JSON_FindString (entry, "dir"); + if (!mod_name || !mod_dir) + continue; + + // The 2021 rerelease has a single mapdb.json file in id1 with definitions + // for all the included episodes (id1, hipnotic, rogue, dopa & mg1). + // If the mapdb file comes from a base dir we only use the episode name + // if the local mod dir matches the episode dir. + // We also perform a dir check if the name of the episode is "copper" + // in order to avoid showing all Copper-based mods as "Underdark Overbright" + // if they include Copper's mapdb.json unmodified. + // In all other cases we skip the dir check so that players can rename mod dirs + // as they please without losing their descriptions in the add-on menu. + if (is_base_mapdb || q_strcasecmp (mod_dir, "copper") != 0) + if (q_strcasecmp (mod_dir, name) != 0) + continue; + + info->full_name = strdup (mod_name); + break; + } + } + JSON_Free (json); + } + } + } + // look for mod in hard-coded list if (!info->full_name) { @@ -1182,7 +1238,11 @@ static void Modlist_FindLocal (void) continue; #endif if (Modlist_Check (find->name, com_basedirs[i])) + { + COM_AddGameDirectory (find->name); Modlist_Add (find->name); + COM_ResetGameDirectories (""); + } } } } @@ -1246,6 +1306,15 @@ void Modlist_ShutDown (void) } } +qboolean Modlist_IsInstalled (const char *game) +{ + filelist_item_t *item; + for (item = modlist; item; item = item->next) + if (q_strcasecmp (item->name, game) == 0 && Modlist_GetStatus (item) == MODSTATUS_INSTALLED) + return true; + return false; +} + //============================================================================== //ericw -- demo list management //============================================================================== @@ -1376,12 +1445,22 @@ static qboolean SkyList_AddFile (const char *path) char skyname[MAX_QPATH]; size_t len; + // Check that the file is in the right directory + // We need this for pak files, which are all passed to this function + // without any kind of path filtering + len = strlen (path); + if (len <= sizeof (prefix) - 1 || q_strncasecmp (path, prefix, sizeof (prefix) - 1)) + return false; + path += sizeof (prefix) - 1; + len -= sizeof (prefix) - 1; + + // Only accept TGA files ext = COM_FileGetExtension (path); if (q_strcasecmp (ext, "tga") != 0) return false; + // Check that the image has the right suffix COM_StripExtension (path, skyname, sizeof (skyname)); - len = strlen (skyname); if (len < sizeof (suffix) - 1) return false; len -= sizeof (suffix) - 1; @@ -1389,11 +1468,7 @@ static qboolean SkyList_AddFile (const char *path) return false; skyname[len] = '\0'; - SDL_assert (len > sizeof (prefix) - 1); - SDL_assert (!q_strncasecmp (skyname, prefix, sizeof (prefix) - 1)); - if (len <= sizeof (prefix) - 1) - return false; - + // All ok, add skybox to the list FileList_Add (skyname + (sizeof (prefix) - 1), &skylist); return true; @@ -1714,12 +1789,12 @@ static void Host_SetPos_f(void) SV_ClientPrintf(" setpos <x> <y> <z> <pitch> <yaw> <roll>\n"); SV_ClientPrintf("current values:\n"); SV_ClientPrintf(" %i %i %i %i %i %i\n", - (int)sv_player->v.origin[0], - (int)sv_player->v.origin[1], - (int)sv_player->v.origin[2], - (int)sv_player->v.v_angle[0], - (int)sv_player->v.v_angle[1], - (int)sv_player->v.v_angle[2]); + Q_rint (sv_player->v.origin[0]), + Q_rint (sv_player->v.origin[1]), + Q_rint (sv_player->v.origin[2]), + Q_rint (sv_player->v.v_angle[0]), + Q_rint (sv_player->v.v_angle[1]), + Q_rint (sv_player->v.v_angle[2])); return; } @@ -2120,38 +2195,39 @@ Host_SavegameComment Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current =============== */ -void Host_SavegameComment (char *text) +void Host_SavegameComment (char text[SAVEGAME_COMMENT_LENGTH + 1]) { int i; char *levelname; char kills[20]; - char *p1, *p2; + char *p; for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) text[i] = ' '; + text[SAVEGAME_COMMENT_LENGTH] = '\0'; -// Remove CR/LFs from level name to avoid broken saves, e.g. with autumn_sp map: -// https://celephais.net/board/view_thread.php?id=60452&start=3666 levelname = cl.levelname[0] ? cl.levelname : cl.mapname; - p1 = strchr(levelname, '\n'); - p2 = strchr(levelname, '\r'); - if (p1 != NULL) *p1 = 0; - if (p2 != NULL) *p2 = 0; i = (int) strlen(levelname); if (i > 22) i = 22; memcpy (text, levelname, (size_t)i); + +// Remove CR/LFs from level name to avoid broken saves, e.g. with autumn_sp map: +// https://celephais.net/board/view_thread.php?id=60452&start=3666 + while ((p = strchr(text, '\n')) != NULL) + *p = ' '; + while ((p = strchr(text, '\r')) != NULL) + *p = ' '; + sprintf (kills,"kills:%3i/%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); memcpy (text+22, kills, strlen(kills)); + // convert space to _ to make stdio happy for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) { if (text[i] == ' ') text[i] = '_'; } - if (p1 != NULL) *p1 = '\n'; - if (p2 != NULL) *p2 = '\r'; - text[SAVEGAME_COMMENT_LENGTH] = '\0'; } static void Host_InvalidateSave (const char *relname) @@ -2397,11 +2473,12 @@ static void Host_Loadgame_f (void) int entnum; int version; float spawn_parms[NUM_SPAWN_PARMS]; + qboolean kexonly = false; if (cmd_source != src_command) return; - if (Cmd_Argc() != 2) + if (Cmd_Argc() < 2) { Con_Printf ("load <savename> : load a game\n"); return; @@ -2413,6 +2490,10 @@ static void Host_Loadgame_f (void) return; } + // When loading a file that doesn't belong to a mod dir we only accept KEX saves + if (Cmd_Argc () >= 3 && q_strcasecmp (Cmd_Argv (2), "kex") == 0) + kexonly = true; + if (nomonsters.value) { Con_Warning ("\"%s\" disabled automatically.\n", nomonsters.name); @@ -2425,6 +2506,21 @@ static void Host_Loadgame_f (void) COM_AddExtension (relname, ".sav", sizeof(relname)); q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, relname); + + // Look for savefile in basedirs instead of gamedir + if (kexonly || !Sys_FileExists (name)) + { + for (i = com_numbasedirs - 1; i >= 0; i--) + { + q_snprintf (name, sizeof(name), "%s/%s", com_basedirs[i], relname); + if (Sys_FileExists (name)) + { + kexonly = true; + break; + } + } + } + if (!Sys_FileExists (name)) { Con_Printf ("ERROR: %s not found.\n", relname); @@ -2453,14 +2549,33 @@ static void Host_Loadgame_f (void) data = start; data = COM_ParseIntNewline (data, &version); - if (version != SAVEGAME_VERSION) + if (version == SAVEGAME_VERSION_KEX) { + extern char com_gamenames[]; + const char *game = *com_gamenames ? com_gamenames : GAMENAME; + data = COM_ParseStringNewline (data); + if (strcmp (game, com_token) != 0) + { + if (!Modlist_IsInstalled (com_token)) + { + Con_Printf ("ERROR: mod \"%s\" is not installed.\n", com_token); + return; + } + COM_SwitchGame (com_token); + Cbuf_Execute (); + if (key_dest == key_menu) + M_ToggleMenu_f (); + } + } + else if (version != SAVEGAME_VERSION || kexonly) + { + int expected = kexonly ? SAVEGAME_VERSION_KEX : SAVEGAME_VERSION; free (start); start = NULL; if (sv.autoloading) - Con_Printf ("ERROR: Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); + Con_Printf ("ERROR: Savegame is version %i, not %i\n", version, expected); else - Host_Error ("Savegame is version %i, not %i", version, SAVEGAME_VERSION); + Host_Error ("Savegame is version %i, not %i", version, expected); Host_InvalidateSave (relname); SCR_EndLoadingPlaque (); return; @@ -2539,6 +2654,10 @@ static void Host_Loadgame_f (void) entnum++; } + // Free edicts allocated during map loading but no longer used after restoring saved game state + for (i = entnum; i < qcvm->num_edicts; i++) + ED_Free (EDICT_NUM (i)); + qcvm->num_edicts = entnum; qcvm->time = time; sv.autosave.time = time; @@ -2558,6 +2677,9 @@ static void Host_Loadgame_f (void) CL_EstablishConnection ("local"); Host_Reconnect_f (); } + + if (cls.state != ca_dedicated && key_dest == key_game) + IN_Activate(); // moved to here from M_Load_Key() } //============================================================================ @@ -3017,7 +3139,7 @@ static void Host_Spawn_f (void) MSG_WriteByte (&host_client->message, svc_signonnum); MSG_WriteByte (&host_client->message, 3); - host_client->sendsignon = true; + host_client->sendsignon = PRESPAWN_FLUSH; } /* diff --git a/Quake/image.c b/Quake/image.c index a4857907d..4451b83c3 100644 --- a/Quake/image.c +++ b/Quake/image.c @@ -454,7 +454,7 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height) start = ftell (f); //save start of file (since we might be inside a pak file, SEEK_SET might not be the start of the pcx) if (fread(&pcx, sizeof(pcx), 1, f) != 1) - Sys_Error ("Image_LoadPCX: can't read header for '%s'", loadfilename); + Sys_Error ("Failed reading header from '%s'", loadfilename); pcx.xmin = (unsigned short)LittleShort (pcx.xmin); pcx.ymin = (unsigned short)LittleShort (pcx.ymin); @@ -479,7 +479,7 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height) //load palette fseek (f, start + com_filesize - 768, SEEK_SET); if (fread (palette, 768, 1, f) != 1) - Sys_Error ("'%s' has invalid palette", loadfilename); + Sys_Error ("Failed reading palette from '%s'", loadfilename); //back to start of image data fseek (f, start + sizeof(pcx), SEEK_SET); diff --git a/Quake/in_sdl.c b/Quake/in_sdl.c index 1c8784000..7bc917e87 100644 --- a/Quake/in_sdl.c +++ b/Quake/in_sdl.c @@ -19,6 +19,9 @@ 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. +gyro related code is based on +https://github.com/yquake2/yquake2/blob/master/src/client/input/sdl.c + */ #include "quakedef.h" @@ -31,7 +34,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern cvar_t ui_mouse; extern cvar_t language; -static qboolean textmode; +static qboolean windowhasfocus = true; //just in case sdl fails to tell us... +static textmode_t textmode = TEXTMODE_OFF; static cvar_t in_debugkeys = {"in_debugkeys", "0", CVAR_NONE}; @@ -61,6 +65,16 @@ cvar_t joy_exponent_move = { "joy_exponent_move", "2", CVAR_ARCHIVE }; cvar_t joy_swapmovelook = { "joy_swapmovelook", "0", CVAR_ARCHIVE }; cvar_t joy_enable = { "joy_enable", "1", CVAR_ARCHIVE }; +cvar_t gyro_mode = {"gyro_mode", "0", CVAR_ARCHIVE}; +cvar_t gyro_turning_axis = {"gyro_turning_axis", "0", CVAR_ARCHIVE}; + +cvar_t gyro_yawsensitivity = {"gyro_yawsensitivity", "2.5", CVAR_ARCHIVE}; +cvar_t gyro_pitchsensitivity= {"gyro_pitchsensitivity", "2.5", CVAR_ARCHIVE}; + +cvar_t gyro_calibration_x = {"gyro_calibration_x", "0", CVAR_ARCHIVE}; +cvar_t gyro_calibration_y = {"gyro_calibration_y", "0", CVAR_ARCHIVE}; +cvar_t gyro_calibration_z = {"gyro_calibration_z", "0", CVAR_ARCHIVE}; + static SDL_JoystickID joy_active_instaceid = -1; static SDL_GameController *joy_active_controller = NULL; @@ -77,6 +91,15 @@ static int buttonremap[] = /* total accumulated mouse movement since last frame */ static int total_dx, total_dy = 0; +static float gyro_yaw, gyro_pitch = 0; +static float gyro_dir = 1; + +// used for gyro calibration +static float gyro_accum[3]; +static unsigned int num_samples; +static unsigned int updates_countdown = 0; + +static qboolean gyro_active = false; static int SDLCALL IN_FilterMouseEvents (const SDL_Event *event) { @@ -292,7 +315,30 @@ void IN_StartupJoystick (void) joy_active_instaceid = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller)); joy_active_controller = gamecontroller; + +#if SDL_VERSION_ATLEAST(2, 0, 14) + + if (SDL_GameControllerHasLED(joy_active_controller)) + { + // orange LED, seemed fitting for Quake + SDL_GameControllerSetLED(joy_active_controller, 80, 20, 0); + } + if (SDL_GameControllerHasSensor(joy_active_controller, SDL_SENSOR_GYRO) + && !SDL_GameControllerSetSensorEnabled(joy_active_controller, SDL_SENSOR_GYRO, SDL_TRUE)) + { +#if SDL_VERSION_ATLEAST(2, 0, 16) + Con_Printf("Gyro sensor enabled at %.2f Hz\n", SDL_GameControllerGetSensorDataRate(joy_active_controller, SDL_SENSOR_GYRO)); +#else + Con_printf("Gyro sensor enabled.\n") +#endif // SDL_VERSION_ATLEAST(2, 0, 16) + } + else + { + Con_Printf("Gyro sensor not found\n"); + } break; + +#endif // SDL_VERSION_ATLEAST(2, 0, 14) } else { @@ -311,11 +357,55 @@ void IN_ShutdownJoystick (void) SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); } +void IN_GyroActionDown (void) +{ + switch ((int)gyro_mode.value) + { + case 1: + gyro_active = true; + return; + case 2: + gyro_active = false; + return; + case 4: + gyro_dir = -1; + } +} +void IN_GyroActionUp (void) +{ + switch ((int)gyro_mode.value) + { + case 1: + gyro_active = false; + return; + case 2: + gyro_active = true; + return; + case 4: + gyro_dir = 1; + } +} + +void IN_UpdateGyroActive(cvar_t *var) +{ + switch ((int)var->value) + { + case 0: + case 1: + gyro_active = false; + return; + case 2: + case 3: + case 4: + gyro_active = true; + } +} + void IN_Init (void) { textmode = Key_TextEntry(); - if (textmode) + if (textmode == TEXTMODE_ON) SDL_StartTextInput(); else SDL_StopTextInput(); @@ -344,9 +434,28 @@ void IN_Init (void) Cvar_RegisterVariable(&joy_swapmovelook); Cvar_RegisterVariable(&joy_enable); + Cvar_RegisterVariable(&gyro_mode); + Cvar_SetCallback(&gyro_mode, IN_UpdateGyroActive); + Cvar_RegisterVariable(&gyro_turning_axis); + + Cvar_RegisterVariable(&gyro_yawsensitivity); + Cvar_RegisterVariable(&gyro_pitchsensitivity); + + Cvar_RegisterVariable(&gyro_calibration_x); + Cvar_RegisterVariable(&gyro_calibration_y); + Cvar_RegisterVariable(&gyro_calibration_z); + + Cmd_AddCommand ("+gyroaction", IN_GyroActionDown); + Cmd_AddCommand ("-gyroaction", IN_GyroActionUp); + IN_Activate(); IN_StartupJoystick(); Sys_ActivateKeyFilter(true); + + if ((int)gyro_mode.value == 2) + { + gyro_active = true; + } } void IN_Shutdown (void) @@ -363,7 +472,9 @@ extern cvar_t scr_fov; void IN_MouseMotion(int dx, int dy) { - if (cls.state != ca_connected || cls.signon != SIGNONS || key_dest != key_game || cl.fixangle) + if (!windowhasfocus) + dx = dy = 0; //don't change view angles etc while unfocused. + if (cls.state != ca_connected || cls.signon != SIGNONS || key_dest != key_game || CL_InCutscene ()) { total_dx = 0; total_dy = 0; @@ -507,6 +618,9 @@ Adapted from DarkPlaces by lordhavoc */ static void IN_JoyKeyEvent(qboolean wasdown, qboolean isdown, int key, double *timer) { + static const double repeatdelay = 0.5; // time (in seconds) between initial press and first repetition + static const double repeatrate = 32.0; // ticks per second + // we can't use `realtime` for key repeats because it is not monotomic const double currenttime = Sys_DoubleTime(); @@ -516,7 +630,7 @@ static void IN_JoyKeyEvent(qboolean wasdown, qboolean isdown, int key, double *t { if (currenttime >= *timer) { - *timer = currenttime + 0.1; + *timer = currenttime + 1.0 / repeatrate; Key_Event(key, true); } } @@ -530,7 +644,7 @@ static void IN_JoyKeyEvent(qboolean wasdown, qboolean isdown, int key, double *t { if (isdown) { - *timer = currenttime + 0.5; + *timer = currenttime + repeatdelay; Key_Event(key, true); } } @@ -576,12 +690,49 @@ void IN_Commands (void) // emit emulated arrow keys so the analog sticks can be used in the menu if (key_dest != key_game) { - IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[0]); - IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[1]); - IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[2]); - IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[3]); + int xaxis = joy_swapmovelook.value ? SDL_CONTROLLER_AXIS_RIGHTX : SDL_CONTROLLER_AXIS_LEFTX; + int yaxis = joy_swapmovelook.value ? SDL_CONTROLLER_AXIS_RIGHTY : SDL_CONTROLLER_AXIS_LEFTY; + IN_JoyKeyEvent(joy_axisstate.axisvalue[xaxis] < -stickthreshold, newaxisstate.axisvalue[xaxis] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[0]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[xaxis] > stickthreshold, newaxisstate.axisvalue[xaxis] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[1]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[yaxis] < -stickthreshold, newaxisstate.axisvalue[yaxis] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[2]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[yaxis] > stickthreshold, newaxisstate.axisvalue[yaxis] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[3]); } - + + // scroll console with look stick + if (key_dest == key_console) + { + const float scrollthreshold = 0.1f; + const float maxscrollspeed = 72.f; // lines per second + const float scrollinterval = 1.f / maxscrollspeed; + static double timer = 0.0; + joyaxis_t raw, deadzone, eased; + float scale; + + raw.x = newaxisstate.axisvalue[joy_swapmovelook.value ? SDL_CONTROLLER_AXIS_LEFTX : SDL_CONTROLLER_AXIS_RIGHTX]; + raw.y = newaxisstate.axisvalue[joy_swapmovelook.value ? SDL_CONTROLLER_AXIS_LEFTY : SDL_CONTROLLER_AXIS_RIGHTY]; + deadzone = IN_ApplyDeadzone (raw, joy_deadzone_look.value, joy_outer_threshold_look.value); + eased = IN_ApplyEasing (deadzone, joy_exponent.value); + if (joy_invert.value) + eased.y = -eased.y; + + scale = fabs (eased.y); + if (scale > scrollthreshold) + { + scale = (scale - scrollthreshold) / (1.f - scrollthreshold); + timer -= scale * host_rawframetime; + if (timer < 0.0) + { + int ticks = (int) ceil (-timer / scrollinterval); + timer += ticks * scrollinterval; + Con_Scroll (eased.y < 0.0f ? ticks : -ticks); + } + } + else + { + timer = 0.0; + } + } + // emit emulated keys for the analog triggers IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, K_LTRIGGER, &joy_emulatedkeytimer[4]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, K_RTRIGGER, &joy_emulatedkeytimer[5]); @@ -641,7 +792,7 @@ void IN_JoyMove (usercmd_t *cmd) cmd->sidemove += speed * moveEased.x; cmd->forwardmove -= speed * moveEased.y; - if (cl.fixangle) + if (CL_InCutscene ()) return; cl.viewangles[YAW] -= lookEased.x * joy_sensitivity_yaw.value * host_frametime; @@ -657,6 +808,32 @@ void IN_JoyMove (usercmd_t *cmd) cl.viewangles[PITCH] = cl_minpitch.value; } +void IN_GyroMove(usercmd_t *cmd) +{ + float scale; + if (!joy_enable.value) + return; + + if (!joy_active_controller) + return; + + if (cl.paused || key_dest != key_game) + return; + + if (CL_InCutscene ()) + return; + + scale = (180.f / M_PI) * gyro_dir * host_frametime; + cl.viewangles[YAW] += scale * gyro_yaw * gyro_yawsensitivity.value; + cl.viewangles[PITCH] -= scale * gyro_pitch * gyro_pitchsensitivity.value; + + /* johnfitz -- variable pitch clamping */ + if (cl.viewangles[PITCH] > cl_maxpitch.value) + cl.viewangles[PITCH] = cl_maxpitch.value; + if (cl.viewangles[PITCH] < cl_minpitch.value) + cl.viewangles[PITCH] = cl_minpitch.value; +} + void IN_MouseMove(usercmd_t *cmd) { float dmx, dmy; @@ -704,6 +881,7 @@ void IN_MouseMove(usercmd_t *cmd) void IN_Move(usercmd_t *cmd) { IN_JoyMove(cmd); + IN_GyroMove(cmd); IN_MouseMove(cmd); } @@ -713,11 +891,11 @@ void IN_ClearStates (void) void IN_UpdateInputMode (void) { - qboolean want_textmode = Key_TextEntry(); + textmode_t want_textmode = Key_TextEntry(); if (textmode != want_textmode) { textmode = want_textmode; - if (textmode) + if (textmode == TEXTMODE_ON) { SDL_StartTextInput(); if (in_debugkeys.value) @@ -732,6 +910,11 @@ void IN_UpdateInputMode (void) } } +textmode_t IN_GetTextMode (void) +{ + return textmode; +} + static inline int IN_SDL2_ScancodeToQuakeKey(SDL_Scancode scancode) { switch (scancode) @@ -873,6 +1056,45 @@ static void IN_DebugKeyEvent(SDL_Event *event) Sys_DoubleTime()); } +void IN_StartGyroCalibration (void) +{ + Con_Printf ("Calibrating, please wait...\n"); + + gyro_accum[0] = 0.0; + gyro_accum[1] = 0.0; + gyro_accum[2] = 0.0; + + num_samples = 0; + updates_countdown = 300; +} + +static void IN_UpdateGyroCalibration (void) +{ + if (!updates_countdown) + return; + + updates_countdown--; + if (!updates_countdown) + { + const float inverseSamples = 1.f / num_samples; + Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples); + Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples); + Cvar_SetValue("gyro_calibration_z", gyro_accum[2] * inverseSamples); + + Con_Printf("Calibration results:\n X=%f Y=%f Z=%f\n", + gyro_calibration_x.value, + gyro_calibration_y.value, + gyro_calibration_z.value); + + Con_Printf("Calibration finished\n"); + } +} + +qboolean IN_IsCalibratingGyro (void) +{ + return updates_countdown != 0; +} + void IN_SendKeyEvents (void) { SDL_Event event; @@ -887,10 +1109,12 @@ void IN_SendKeyEvents (void) if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { Sys_ActivateKeyFilter(true); + windowhasfocus = true; S_UnblockSound(); } else if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { + windowhasfocus = false; S_BlockSound(); Sys_ActivateKeyFilter(false); } @@ -923,13 +1147,15 @@ void IN_SendKeyEvents (void) // SDL2: we interpret the keyboard as the US layout, so keybindings // are based on key position, not the label on the key cap. key = IN_SDL2_ScancodeToQuakeKey(event.key.keysym.scancode); - Key_Event (key, down); + + // also pass along the underlying keycode using the proper current layout for Y/N prompts. + Key_EventWithKeycode (key, down, event.key.keysym.sym); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if (event.button.button < 1 || - event.button.button > sizeof(buttonremap) / sizeof(buttonremap[0])) + event.button.button > Q_COUNTOF(buttonremap)) { Con_Printf ("Ignored event for mouse button %d\n", event.button.button); @@ -959,6 +1185,40 @@ void IN_SendKeyEvents (void) IN_MouseMotion(event.motion.xrel, event.motion.yrel); break; +#if SDL_VERSION_ATLEAST(2, 0, 14) + case SDL_CONTROLLERSENSORUPDATE: + if (event.csensor.sensor != SDL_SENSOR_GYRO) + { + break; + } + if (updates_countdown) + { + gyro_accum[0] += event.csensor.data[0]; + gyro_accum[1] += event.csensor.data[1]; + gyro_accum[2] += event.csensor.data[2]; + num_samples++; + break; + } + if (gyro_active && gyro_mode.value) + { + if (!gyro_turning_axis.value) + { + gyro_yaw = event.csensor.data[1] - gyro_calibration_y.value; // yaw + } + else + { + gyro_yaw = -(event.csensor.data[2] - gyro_calibration_z.value); // roll + } + gyro_pitch = event.csensor.data[0] - gyro_calibration_x.value; + } + else + { + gyro_yaw = gyro_pitch = 0; + } + break; + +#endif // SDL_VERSION_ATLEAST(2, 0, 14) + case SDL_CONTROLLERDEVICEADDED: if (joy_active_instaceid == -1) { @@ -970,6 +1230,11 @@ void IN_SendKeyEvents (void) SDL_Joystick *joy; joy = SDL_GameControllerGetJoystick(joy_active_controller); joy_active_instaceid = SDL_JoystickInstanceID(joy); + if (SDL_GameControllerHasLED(joy_active_controller)) + { + // orange LED, seemed fitting for Quake + SDL_GameControllerSetLED(joy_active_controller, 80, 20, 0); + } } } else @@ -1004,5 +1269,7 @@ void IN_SendKeyEvents (void) break; } } + + IN_UpdateGyroCalibration (); } diff --git a/Quake/input.h b/Quake/input.h index f2131d495..38a1fb4a9 100644 --- a/Quake/input.h +++ b/Quake/input.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _QUAKE_INPUT_H -#define _QUAKE_INPUT_H +#ifndef QUAKE_INPUT_H +#define QUAKE_INPUT_H // input.h -- external (non-keyboard) input devices @@ -34,6 +34,9 @@ void IN_Commands (void); // mouse moved by dx and dy pixels void IN_MouseMotion(int dx, int dy); +void IN_StartGyroCalibration (void); +qboolean IN_IsCalibratingGyro (void); + void IN_SendKeyEvents (void); // used as a callback for Sys_SendKeyEvents() by some drivers @@ -41,6 +44,8 @@ void IN_SendKeyEvents (void); void IN_UpdateInputMode (void); // do stuff if input mode (text/non-text) changes matter to the keyboard driver +enum textmode_t IN_GetTextMode (void); + void IN_Move (usercmd_t *cmd); // add additional movement on top of the keyboard move cmd @@ -55,5 +60,4 @@ void IN_Deactivate (qboolean free_cursor); void IN_DeactivateForConsole (void); void IN_DeactivateForMenu (void); -#endif /* _QUAKE_INPUT_H */ - +#endif diff --git a/Quake/keys.c b/Quake/keys.c index f3cd2bcea..c18c47dff 100644 --- a/Quake/keys.c +++ b/Quake/keys.c @@ -52,7 +52,7 @@ typedef struct int keynum; } keyname_t; -keyname_t keynames[] = +static const keyname_t keynames[] = { {"TAB", K_TAB}, {"ENTER", K_ENTER}, @@ -295,6 +295,7 @@ void Key_Console (int key) { case K_ENTER: case K_KP_ENTER: + case K_ABUTTON: key_tabpartial[0] = 0; Cbuf_AddText (workline + 1); // skip the prompt Cbuf_AddText ("\n"); @@ -369,6 +370,7 @@ void Key_Console (int key) } else key_linepos = 1; Con_TabComplete (TABCOMPLETE_AUTOHINT); + Con_ForceMouseMove (); return; case K_END: @@ -376,20 +378,17 @@ void Key_Console (int key) con_backscroll = 0; else key_linepos = strlen(workline); Con_TabComplete (TABCOMPLETE_AUTOHINT); + Con_ForceMouseMove (); return; case K_PGUP: case K_MWHEELUP: - con_backscroll += keydown[K_CTRL] ? ((con_vislines>>3) - 4) : 2; - if (con_backscroll > con_totallines - (vid.height>>3) - 1) - con_backscroll = con_totallines - (vid.height>>3) - 1; + Con_Scroll (keydown[K_CTRL] ? ((con_vislines>>3) - 4) : 2); return; case K_PGDN: case K_MWHEELDOWN: - con_backscroll -= keydown[K_CTRL] ? ((con_vislines>>3) - 4) : 2; - if (con_backscroll < 0) - con_backscroll = 0; + Con_Scroll (keydown[K_CTRL] ? -((con_vislines>>3) - 4) : -2); return; case K_LEFTARROW: @@ -478,6 +477,11 @@ void Key_Console (int key) case K_INS: if (keydown[K_SHIFT]) /* Shift-Ins paste */ PasteToConsole(); + else if (keydown[K_CTRL]) + { + Con_CopySelectionToClipboard (); + return; + } else key_insert ^= 1; Con_TabComplete (TABCOMPLETE_AUTOHINT); return; @@ -501,6 +505,8 @@ void Key_Console (int key) case 'c': case 'C': if (keydown[K_CTRL]) { /* Ctrl+C: abort the line -- S.A */ + if (Con_CopySelectionToClipboard ()) + return; Con_Printf ("%s\n", workline); workline[0] = ']'; workline[1] = 0; @@ -619,7 +625,7 @@ the K_* names are matched up. */ int Key_StringToKeynum (const char *str) { - keyname_t *kn; + const keyname_t *kn; if (!str || !str[0]) return -1; @@ -646,7 +652,7 @@ FIXME: handle quote special (general escape sequence?) const char *Key_KeynumToString (int keynum) { static char tinystr[128][2]; - keyname_t *kn; + const keyname_t *kn; if (keynum == -1) return "<KEY NOT FOUND>"; @@ -968,6 +974,7 @@ void Key_Init (void) #endif consolekeys[K_MWHEELUP] = true; consolekeys[K_MWHEELDOWN] = true; + consolekeys[K_ABUTTON] = true; // // initialize menubound[] @@ -1044,6 +1051,21 @@ Should NOT be called during an interrupt! =================== */ void Key_Event (int key, qboolean down) +{ + Key_EventWithKeycode (key, down, 0); +} + +/* +=================== +Key_EventWithKeycode + +Called by the system between frames for both key up and key down events +Should NOT be called during an interrupt! +keycode parameter should have the key's actual keycode using the current keyboard layout, +not necessarily the US-keyboard-based scancode. Pass 0 if not applicable. +=================== +*/ +void Key_EventWithKeycode (int key, qboolean down, int keycode) { char *kb; char cmd[1024]; @@ -1085,10 +1107,19 @@ void Key_Event (int key, qboolean down) if (key_inputgrab.active) { if (down) + { key_inputgrab.lastkey = key; + if (keycode > 0) + key_inputgrab.lastchar = keycode; + } return; } +// generate char events if we want text input without popping up an on-screen keyboard +// when a physical one isn't present, e.g. when using a searchable menu on the Steam Deck + if (down && IN_GetTextMode () == TEXTMODE_NOPOPUP) + Char_Event (keycode); + // handle escape specialy, so the user can never unbind it if (key == K_ESCAPE) { @@ -1138,11 +1169,9 @@ void Key_Event (int key, qboolean down) kb = keybindings[key]; if (kb && kb[0] == '+') { - sprintf (cmd, "-%s %i\n", kb+1, key); + q_snprintf (cmd, sizeof (cmd), "-%s %i\n", kb+1, key); Cbuf_AddText (cmd); } - if (key_dest == key_console && key == K_MOUSE1 && !down) - Con_Click (); return; } @@ -1163,7 +1192,7 @@ void Key_Event (int key, qboolean down) { if (kb[0] == '+') { // button commands add keynum as a parm - sprintf (cmd, "%s %i\n", kb, key); + q_snprintf (cmd, sizeof (cmd), "%s %i\n", kb, key); Cbuf_AddText (cmd); } else @@ -1246,25 +1275,30 @@ void Char_Event (int key) Key_TextEntry =================== */ -qboolean Key_TextEntry (void) +textmode_t Key_TextEntry (void) { if (key_inputgrab.active) - return true; + { + // This path is used for simple single-letter inputs (y/n prompts) that also + // accept controller input, so we don't want an onscreen keyboard for this case. + return TEXTMODE_NOPOPUP; + } switch (key_dest) { case key_message: - return true; + return TEXTMODE_ON; case key_menu: return M_TextEntry(); case key_game: - if (!con_forcedup) - return false; - /* fallthrough */ + // Don't return true even during con_forcedup, because that happens while starting a + // game and we don't to trigger text input (and the onscreen keyboard on some devices) + // during this. + return TEXTMODE_OFF; case key_console: - return true; + return TEXTMODE_ON; default: - return false; + return TEXTMODE_OFF; } } diff --git a/Quake/keys.h b/Quake/keys.h index bf68d57fc..4ef723adc 100644 --- a/Quake/keys.h +++ b/Quake/keys.h @@ -163,6 +163,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAXCMDLINE 256 typedef enum {key_game, key_console, key_message, key_menu} keydest_t; +typedef enum textmode_t +{ + TEXTMODE_OFF, // no char events + TEXTMODE_ON, // char events, show on-screen keyboard + TEXTMODE_NOPOPUP, // char events, don't show on-screen keyboard +} textmode_t; extern keydest_t key_dest; extern char *keybindings[MAX_KEYS]; @@ -187,8 +193,9 @@ void Key_EndInputGrab (void); void Key_GetGrabbedInput (int *lastkey, int *lastchar); void Key_Event (int key, qboolean down); +void Key_EventWithKeycode (int key, qboolean down, int keycode); void Char_Event (int key); -qboolean Key_TextEntry (void); +textmode_t Key_TextEntry (void); void Key_SetBinding (int keynum, const char *binding); int Key_GetKeysForCommand (const char *command, int *keys, int maxkeys); diff --git a/Quake/menu.c b/Quake/menu.c index 6fc4b3878..98718d7ea 100644 --- a/Quake/menu.c +++ b/Quake/menu.c @@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "bgmusic.h" #include "q_ctype.h" +#include <time.h> + cvar_t ui_mouse = {"ui_mouse", "1", CVAR_ARCHIVE}; cvar_t ui_mouse_sound = {"ui_mouse_sound", "0", CVAR_ARCHIVE}; cvar_t ui_sound_throttle = {"ui_sound_throttle", "0.1", CVAR_ARCHIVE}; @@ -57,6 +59,20 @@ extern cvar_t r_oit; extern cvar_t r_alphasort; extern cvar_t r_lerpmodels; extern cvar_t r_lerpmove; +extern cvar_t joy_deadzone_look; +extern cvar_t joy_deadzone_move; +extern cvar_t joy_deadzone_trigger; +extern cvar_t joy_sensitivity_yaw; +extern cvar_t joy_sensitivity_pitch; +extern cvar_t joy_invert; +extern cvar_t joy_exponent; +extern cvar_t joy_exponent_move; +extern cvar_t joy_swapmovelook; +extern cvar_t joy_enable; +extern cvar_t gyro_mode; +extern cvar_t gyro_turning_axis; +extern cvar_t gyro_pitchsensitivity; +extern cvar_t gyro_yawsensitivity; extern char crosshair_char; @@ -86,6 +102,7 @@ void M_Menu_Main_f (void); void M_Menu_Options_f (void); void M_Menu_Keys_f (void); void M_Menu_Video_f (void); + void M_Menu_Gamepad_f (void); void M_Menu_Mods_f (void); void M_Menu_ModInfo_f (const filelist_item_t *item); void M_Menu_Help_f (void); @@ -106,7 +123,8 @@ void M_Main_Draw (void); void M_ServerList_Draw (void); void M_Options_Draw (void); void M_Keys_Draw (void); - void M_Video_Draw (void); + //void M_Video_Draw (void); + //void M_Gamepad_Draw (void); void M_Mods_Draw (void); void M_ModInfo_Draw (void); void M_Help_Draw (void); @@ -127,7 +145,8 @@ void M_Main_Key (int key); void M_ServerList_Key (int key); void M_Options_Key (int key); void M_Keys_Key (int key); - void M_Video_Key (int key); + //void M_Video_Key (int key); + //void M_Gamepad_Key (int key); void M_Mods_Key (int key); void M_ModInfo_Key (int key); void M_Help_Key (int key); @@ -148,7 +167,8 @@ void M_Main_Mousemove (int cx, int cy); void M_ServerList_Mousemove (int cx, int cy); void M_Options_Mousemove (int cx, int cy); void M_Keys_Mousemove (int cx, int cy); - void M_Video_Mousemove (int cx, int cy); + //void M_Video_Mousemove (int cx, int cy); + //void M_Gamepad_Mousemove (int cx, int cy); void M_Mods_Mousemove (int cx, int cy); //void M_Help_Mousemove (int cx, int cy); //void M_Quit_Mousemove (int cx, int cy); @@ -174,8 +194,6 @@ void M_SetSkillMenuMap (const char *name); void M_Options_SelectMods (void); void M_Options_Init (enum m_state_e state); -#define DESCRIPTION_SCROLL_WAIT_TIME 1.0 - #define SEARCH_FADE_TIMEOUT 0.5 #define SEARCH_TYPE_TIMEOUT 1.5 #define SEARCH_ERASE_TIMEOUT 1.5 @@ -334,7 +352,7 @@ static int M_WordLength (const char *text) static int M_LineWrap (const char **text, int maxchars) { const char *str = *text; - int i, lastspace = 0; + int i; for (i = 0; i < maxchars && str[i]; /**/) { @@ -1045,6 +1063,50 @@ void M_List_Mousemove (menulist_t *list, int yrel) } +//============================================================================= +/* Scrolling ticker */ + +typedef struct +{ + double scroll_time; + double scroll_wait_time; +} menuticker_t; + +static void M_Ticker_Init (menuticker_t *ticker) +{ + ticker->scroll_time = 0.0; + ticker->scroll_wait_time = 1.0; +} + +static void M_Ticker_Update (menuticker_t *ticker) +{ + if (ticker->scroll_wait_time <= 0.0) + ticker->scroll_time += host_rawframetime; + else + ticker->scroll_wait_time = q_max (0.0, ticker->scroll_wait_time - host_rawframetime); +} + +static qboolean M_Ticker_Key (menuticker_t *ticker, int key) +{ + switch (key) + { + case K_RIGHTARROW: + ticker->scroll_time += 0.25; + ticker->scroll_wait_time = 1.5; + M_ThrottledSound ("misc/menu3.wav"); + return true; + + case K_LEFTARROW: + ticker->scroll_time -= 0.25; + ticker->scroll_wait_time = 1.5; + M_ThrottledSound ("misc/menu3.wav"); + return true; + + default: + return false; + } +} + //============================================================================= int m_save_demonum; @@ -1300,7 +1362,7 @@ void M_SinglePlayer_Key (int key) { case 0: if (sv.active) - if (!SCR_ModalMessage("Are you sure you want to\nstart a new game?\n", 0.0f)) + if (!SCR_ModalMessage("Are you sure you want to\nstart a new game? (y/n)\n", 0.0f)) break; if (quake64) { @@ -1319,15 +1381,15 @@ void M_SinglePlayer_Key (int key) break; case 1: - M_Menu_Load_f (); + Cbuf_AddText ("menu_load\n"); break; case 2: - M_Menu_Save_f (); + Cbuf_AddText ("menu_save\n"); break; case 3: - M_Menu_Maps_f (); + Cbuf_AddText ("menu_maps\n"); break; } } @@ -1364,10 +1426,14 @@ void M_ScanSaves (void) loadable[i] = false; q_snprintf (name, sizeof(name), "%s/s%i.sav", com_gamedir, i); f = Sys_fopen (name, "r"); - if (!f) + if (!f) { continue; - fscanf (f, "%i\n", &version); - fscanf (f, "%79s\n", name); + } + if (fscanf(f, "%i\n", &version) != 1 || + fscanf(f, "%79s\n", name) != 1) { + fclose(f); + continue; + } q_strlcpy (m_filenames[i], name, SAVEGAME_COMMENT_LENGTH+1); // change _ back to space @@ -1460,7 +1526,6 @@ void M_Load_Key (int k) if (!loadable[load_cursor]) return; m_state = m_none; - IN_Activate(); key_dest = key_game; // issue the load command @@ -1558,12 +1623,11 @@ typedef struct static struct { menulist_t list; + menuticker_t ticker; int x, y, cols; int mapcount; // not all items represent actual maps! qboolean scrollbar_grab; int prev_cursor; - double scroll_time; - double scroll_wait_time; mapitem_t *items; } mapsmenu; @@ -1664,11 +1728,11 @@ static void M_Maps_Init (void) mapsmenu.list.cursor = -1; mapsmenu.list.scroll = 0; mapsmenu.list.numitems = 0; - mapsmenu.scroll_time = 0; - mapsmenu.scroll_wait_time = DESCRIPTION_SCROLL_WAIT_TIME; mapsmenu.mapcount = 0; VEC_CLEAR (mapsmenu.items); + M_Ticker_Init (&mapsmenu.ticker); + for (i = 0, active = -1, prev_type = -1; extralevels_sorted[i]; i++) { mapitem_t map; @@ -1708,6 +1772,29 @@ void M_Menu_Maps_f (void) m_state = m_maps; m_entersound = true; M_Maps_Init (); + + // Handle optional map argument + if (Cmd_Argc() >= 2) + { + char mapname[MAX_QPATH]; + size_t i; + + COM_StripExtension (Cmd_Argv (1), mapname, sizeof (mapname)); + + for (i = 0; i < VEC_SIZE (mapsmenu.items); i++) + if (q_strcasecmp (mapname, mapsmenu.items[i].name) == 0) + break; + + if (i == VEC_SIZE (mapsmenu.items)) + { + Con_SafePrintf ("Couldn't find map \"%s\".\n", mapname); + return; + } + + mapsmenu.list.cursor = i; + M_SetSkillMenuMap (mapname); + M_Menu_Skill_f (); + } } void M_Maps_Draw (void) @@ -1731,16 +1818,10 @@ void M_Maps_Draw (void) if (mapsmenu.prev_cursor != mapsmenu.list.cursor) { mapsmenu.prev_cursor = mapsmenu.list.cursor; - mapsmenu.scroll_time = 0.0; - mapsmenu.scroll_wait_time = DESCRIPTION_SCROLL_WAIT_TIME; + M_Ticker_Init (&mapsmenu.ticker); } else - { - if (mapsmenu.scroll_wait_time <= 0.0) - mapsmenu.scroll_time += host_rawframetime; - else - mapsmenu.scroll_wait_time = q_max (0.0, mapsmenu.scroll_wait_time - host_rawframetime); - } + M_Ticker_Update (&mapsmenu.ticker); x = mapsmenu.x; y = mapsmenu.y; @@ -1801,7 +1882,7 @@ void M_Maps_Draw (void) GL_SetCanvasColor (1, 1, 1, 1); M_PrintScroll (x + namecols*8, y + i*8, desccols*8, buf, - selected ? mapsmenu.scroll_time : 0.0, true); + selected ? mapsmenu.ticker.scroll_time : 0.0, true); if (!message) GL_SetCanvasColor (1, 1, 1, 1); @@ -1833,9 +1914,9 @@ void M_Maps_Char (int key) M_List_Char (&mapsmenu.list, key); } -qboolean M_Maps_TextEntry (void) +textmode_t M_Maps_TextEntry (void) { - return !mapsmenu.scrollbar_grab; + return mapsmenu.scrollbar_grab ? TEXTMODE_OFF : TEXTMODE_NOPOPUP; } void M_Maps_Key (int key) @@ -1859,6 +1940,12 @@ void M_Maps_Key (int key) if (M_List_Key (&mapsmenu.list, key)) return; + if (M_Ticker_Key (&mapsmenu.ticker, key)) + { + M_List_KeepSearchVisible (&mapsmenu.list, 1.0); + return; + } + switch (key) { case K_ESCAPE: @@ -1869,19 +1956,6 @@ void M_Maps_Key (int key) M_Menu_SinglePlayer_f (); break; - case K_RIGHTARROW: - mapsmenu.scroll_time += 0.25; - mapsmenu.scroll_wait_time = 1.5; - M_List_KeepSearchVisible (&mapsmenu.list, 1.0); - M_ThrottledSound ("misc/menu3.wav"); - break; - case K_LEFTARROW: - mapsmenu.scroll_time -= 0.25; - mapsmenu.scroll_wait_time = 1.5; - M_List_KeepSearchVisible (&mapsmenu.list, 1.0); - M_ThrottledSound ("misc/menu3.wav"); - break; - case K_ENTER: case K_KP_ENTER: case K_ABUTTON: @@ -1932,41 +2006,85 @@ void M_Maps_Mousemove (int cx, int cy) //============================================================================= /* SKILL MENU */ -int m_skill_cursor; -qboolean m_skill_usegfx; -qboolean m_skill_usecustomtitle; -char m_skill_mapname[MAX_QPATH]; +int m_skill_cursor; +qboolean m_skill_usegfx; +qboolean m_skill_usecustomtitle; +qboolean m_skill_canresume; +time_t m_skill_lastplayed; +int m_skill_numoptions; +char m_skill_mapname[MAX_QPATH]; +char m_skill_maptitle[1024]; +menuticker_t m_skill_ticker; + enum m_state_e m_skill_prevmenu; void M_SetSkillMenuMap (const char *name) { q_strlcpy (m_skill_mapname, name, sizeof (m_skill_mapname)); + if (!Mod_LoadMapDescription (m_skill_maptitle, sizeof (m_skill_maptitle), name) || !m_skill_maptitle[0]) + q_strlcpy (m_skill_maptitle, name, sizeof (m_skill_maptitle)); } void M_Menu_Skill_f (void) { + char autosave[MAX_OSPATH]; + + m_skill_canresume = false; + m_skill_lastplayed = 0; + q_snprintf (autosave, sizeof (autosave), "%s/autosave/%s.sav", com_gamedir, m_skill_mapname); + if (Sys_FileExists (autosave)) + { + time_t now, lastplayed; + m_skill_canresume = true; + time (&now); + if (Sys_GetFileTime (autosave, &lastplayed) && lastplayed <= now) + m_skill_lastplayed = lastplayed; + } + IN_DeactivateForMenu(); key_dest = key_menu; m_skill_prevmenu = m_state; m_state = m_skill; m_entersound = true; - m_skill_cursor = (int)skill.value; - m_skill_cursor = CLAMP (0, m_skill_cursor, 3); + M_Ticker_Init (&m_skill_ticker); + + if (m_skill_canresume) + { + // Select "Resume" option initially if available + m_skill_cursor = 4; + } + else + { + // Select current skill level initially if there's no autosave + m_skill_cursor = (int)skill.value; + m_skill_cursor = CLAMP (0, m_skill_cursor, 3); + } + m_skill_numoptions = 4 + m_skill_canresume; } void M_Skill_Draw (void) { - int f; + int x, y, f; qpic_t *p; M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); - p = Draw_CachePic (m_skill_usecustomtitle ? "gfx/p_skill.lmp" : "gfx/ttl_sgl.lmp"); + p = Draw_CachePic (m_skill_usecustomtitle && !m_skill_canresume ? "gfx/p_skill.lmp" : "gfx/ttl_sgl.lmp"); M_DrawPic ( (320-p->width)/2, 4, p); + x = 72; + y = 32; + + M_Ticker_Update (&m_skill_ticker); + M_PrintScroll (x, 32, 30*8, m_skill_maptitle, m_skill_ticker.scroll_time, false); + + y += 16; + if (m_skill_usegfx) { - M_DrawTransPic (72, 32, Draw_CachePic ("gfx/skillmenu.lmp") ); - M_DrawQuakeCursor (54, 32 + m_skill_cursor * 20); + M_DrawTransPic (x, y, Draw_CachePic ("gfx/skillmenu.lmp") ); + if (m_skill_cursor < 4) + M_DrawQuakeCursor (x - 18, y + m_skill_cursor * 20); + y += 4 * 20; } else { @@ -1979,13 +2097,35 @@ void M_Skill_Draw (void) }; for (f = 0; f < 4; f++) - M_Print (88, 44+4 + f*16, skills[f]); - M_DrawArrowCursor (72, 44+4 + m_skill_cursor*16); + M_PrintEx (x, y + f*16 + 2, 12, skills[f]); + if (m_skill_cursor < 4) + M_DrawArrowCursor (x - 16, y + m_skill_cursor*16 + 4); + y += 4 * 16; + } + + if (m_skill_canresume) + { + y += 8; + M_Print (x, y, "Resume last game"); + if (m_skill_lastplayed) + { + char duration[32]; + time_t now; + + time (&now); + COM_DescribeDuration (duration, sizeof (duration), difftime (m_skill_lastplayed, now)); + M_Print (x, y + 8, va ("from %s ago", duration)); + } + if (m_skill_cursor == 4) + M_DrawArrowCursor (x - 16, y); } } void M_Skill_Key (int key) { + if (M_Ticker_Key (&m_skill_ticker, key)) + return; + switch (key) { case K_ESCAPE: @@ -1998,14 +2138,14 @@ void M_Skill_Key (int key) case K_DOWNARROW: M_ThrottledSound ("misc/menu1.wav"); - if (++m_skill_cursor > 3) + if (++m_skill_cursor > m_skill_numoptions - 1) m_skill_cursor = 0; break; case K_UPARROW: M_ThrottledSound ("misc/menu1.wav"); if (--m_skill_cursor < 0) - m_skill_cursor = 3; + m_skill_cursor = m_skill_numoptions - 1; break; case K_ENTER: @@ -2016,22 +2156,35 @@ void M_Skill_Key (int key) key_dest = key_game; if (sv.active) Cbuf_AddText ("disconnect\n"); - Cbuf_AddText (va ("skill %d\n", m_skill_cursor)); - Cbuf_AddText ("maxplayers 1\n"); - Cbuf_AddText ("deathmatch 0\n"); //johnfitz - Cbuf_AddText ("coop 0\n"); //johnfitz - Cbuf_AddText (va ("map \"%s\"\n", m_skill_mapname)); + if (m_skill_cursor == 4) + { + // Resume autosave + Cbuf_AddText (va ("load \"autosave/%s\"\n", m_skill_mapname)); + } + else + { + // Fresh start + Cbuf_AddText (va ("skill %d\n", m_skill_cursor)); + Cbuf_AddText ("maxplayers 1\n"); + Cbuf_AddText ("deathmatch 0\n"); //johnfitz + Cbuf_AddText ("coop 0\n"); //johnfitz + Cbuf_AddText (va ("map \"%s\"\n", m_skill_mapname)); + } break; } } void M_Skill_Mousemove (int cx, int cy) { + int ybase = 48; + int itemheight = m_skill_usegfx ? 20 : 16; int prev = m_skill_cursor; - if (m_skill_usegfx) - M_UpdateCursor (cy, 32, 20, 4, &m_skill_cursor); + + if (m_skill_numoptions > 4 && cy > ybase + 4 * itemheight + 8/2) + m_skill_cursor = 4; else - M_UpdateCursor (cy, 44, 16, 4, &m_skill_cursor); + M_UpdateCursor (cy, ybase, itemheight, 4, &m_skill_cursor); + if (m_skill_cursor != prev) M_MouseSound ("misc/menu1.wav"); } @@ -2311,9 +2464,9 @@ void M_Setup_Char (int k) } -qboolean M_Setup_TextEntry (void) +textmode_t M_Setup_TextEntry (void) { - return (setup_cursor == 0 || setup_cursor == 1); + return (setup_cursor == 0 || setup_cursor == 1) ? TEXTMODE_ON : TEXTMODE_OFF; } @@ -2979,6 +3132,112 @@ void M_Menu_Video_f (void) M_Options_Init (m_video); } +//============================================================================= +/* CALIBRATION SCREEN */ + +static enum +{ + CALIBRATION_INTRO_TEXT, + CALIBRATION_IN_ROGRESS, + CALIBRATION_FINISHED, +} calibration_state; + +static double calibration_finished_delay; + +void M_Menu_Calibration_f (void) +{ + IN_DeactivateForMenu(); + m_state = m_calibration; + calibration_state = CALIBRATION_INTRO_TEXT; + calibration_finished_delay = 1.0; +} + +void M_Calibration_Draw (void) +{ + int y = 72; + + switch (calibration_state) + { + case CALIBRATION_INTRO_TEXT: + M_PrintAligned (160, y - 8, ALIGN_CENTER, "Before calibration,"); + M_PrintAligned (160, y, ALIGN_CENTER, "place the controller"); + M_PrintAligned (160, y + 8, ALIGN_CENTER, "on a flat, stable surface"); + y += 24; + M_DrawTextBox (160 - 5*8, y, 8, 1); + M_DrawArrowCursor (160 - 6*8, y + 8); + M_PrintAligned (160, y + 8, ALIGN_CENTER, "Continue"); + break; + + case CALIBRATION_IN_ROGRESS: + M_PrintAligned (160, y, ALIGN_CENTER, "Calibrating, please wait..."); + if (!IN_IsCalibratingGyro ()) + calibration_state = CALIBRATION_FINISHED; + break; + + case CALIBRATION_FINISHED: + M_PrintAligned (160, y, ALIGN_CENTER, "Calibration complete!"); + calibration_finished_delay -= host_rawframetime; + if (calibration_finished_delay < 0.0) + M_Menu_Gamepad_f (); + break; + + default: + break; + } +} + +void M_Calibration_Key (int key) +{ + if (calibration_state != CALIBRATION_INTRO_TEXT) + return; + + switch (key) + { + case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: + case K_MOUSE1: + calibration_state = CALIBRATION_IN_ROGRESS; + M_ThrottledSound ("misc/menu2.wav"); + IN_StartGyroCalibration (); + break; + + case K_ESCAPE: + case K_BBUTTON: + case K_MOUSE4: + case K_MOUSE2: + M_Menu_Gamepad_f (); + break; + + default: + break; + } +} + +//============================================================================= +/* GAMEPAD MENU */ + +#define MIN_JOY_SENS 60.f +#define MAX_JOY_SENS 720.f +#define MIN_JOY_EXPONENT 1.f +#define MAX_JOY_EXPONENT 5.f +#define MIN_STICK_DEADZONE 0.f +#define MAX_STICK_DEADZONE 0.75f +#define MIN_TRIGGER_DEADZONE 0.f +#define MAX_TRIGGER_DEADZONE 0.75f +#define MIN_GYRO_SENS 0.1f +#define MAX_GYRO_SENS 8.f + +/* +================ +M_Menu_Gamepad_f +================ +*/ +void M_Menu_Gamepad_f (void) +{ + M_Options_Init (m_gamepad); +} + //============================================================================= /* OPTIONS MENU */ @@ -2986,6 +3245,7 @@ void M_Menu_Video_f (void) #define OPTIONS_LIST(def) \ def (OPT_VIDEO, "Video Options") \ def (OPT_CUSTOMIZE, "Controls") \ + def (OPT_GAMEPAD, "Gamepad") \ def (OPT_MODS, "Mods") \ def (OPT_CONSOLE, "Go To Console") \ def (OPT_DEFAULTS, "Reset Config") \ @@ -3044,12 +3304,42 @@ void M_Menu_Video_f (void) def (VID_OPT_FPSLIMIT, "FPS Limit") \ def (VID_OPT_SHOWFPS, "Show FPS") \ //////////////////////////////////////////////////// +#define GPAD_OPTIONS_LIST(def) \ + def(GPAD_OPT_ENABLE, "Gamepad") \ + \ + def(GPAD_OPT_SPACE1, "") \ + \ + def(GPAD_OPT_SENSX, "Yaw Speed") \ + def(GPAD_OPT_SENSY, "Pitch Speed") \ + def(GPAD_OPT_INVERT, "Invert Pitch") \ + def(GPAD_OPT_SWAP_MOVELOOK, "Look Stick") \ + \ + def(GPAD_OPT_SPACE2, "") \ + \ + def(GPAD_OPT_EXPONENT_LOOK, "Look Accel") \ + def(GPAD_OPT_EXPONENT_MOVE, "Move Accel") \ + \ + def(GPAD_OPT_SPACE3, "") \ + \ + def(GPAD_OPT_DEADZONE_LOOK, "Look Deadzone") \ + def(GPAD_OPT_DEADZONE_MOVE, "Move Deadzone") \ + def(GPAD_OPT_DEADZONE_TRIG, "Trigger Thresh") \ + \ + def(GPAD_OPT_SPACE4, "") \ + \ + def(GPAD_OPT_GYROMODE, "Gyro Mode") \ + def(GPAD_OPT_GYROAXIS, "Gyro Axis") \ + def(GPAD_OPT_GYROSENSX, "Gyro Yaw Speed") \ + def(GPAD_OPT_GYROSENSY, "Gyro Pitch Speed") \ + def(GPAD_OPT_CALIBRATE, "Calibrate") \ +//////////////////////////////////////////////////// enum { #define ADD_OPTION_ENUM(id, name) id, OPTIONS_LIST (ADD_OPTION_ENUM) VIDEO_OPTIONS_LIST(ADD_OPTION_ENUM) + GPAD_OPTIONS_LIST(ADD_OPTION_ENUM) #undef ADD_OPTION_ENUM #define COUNT_OPTION(id, name) +1 @@ -3057,6 +3347,8 @@ enum OPTIONS_ITEMS = OPTIONS_LIST (COUNT_OPTION), VIDEO_OPTIONS_FIRST = OPTIONS_ITEMS, VIDEO_OPTIONS_ITEMS = VIDEO_OPTIONS_LIST (COUNT_OPTION), + GPAD_OPTIONS_FIRST = OPTIONS_ITEMS + VIDEO_OPTIONS_ITEMS, + GPAD_OPTIONS_ITEMS = GPAD_OPTIONS_LIST (COUNT_OPTION), #undef COUNT_OPTION }; @@ -3065,6 +3357,7 @@ static const char *const options_names[] = #define ADD_OPTION_NAME(id, name) name, OPTIONS_LIST (ADD_OPTION_NAME) VIDEO_OPTIONS_LIST(ADD_OPTION_NAME) + GPAD_OPTIONS_LIST(ADD_OPTION_NAME) #undef ADD_OPTION_NAME }; @@ -3093,6 +3386,7 @@ struct int first_item; int options_cursor; int video_cursor; + int gamepad_cursor; int *last_cursor; } optionsmenu; @@ -3119,6 +3413,9 @@ static void M_Options_UpdateLayout (void) optionsmenu.yofs = 0; height = OPTIONS_LISTOFS + optionsmenu.yofs + optionsmenu.list.numitems * 8; + // Enforce a minimum height, so that if the number of items is relatively small + // the title pic doesn't get drawn below its usual position + height = q_max (height, 192); if (height <= m_height) { optionsmenu.y = (m_top + (m_height - height) / 2) & ~7; @@ -3191,6 +3488,13 @@ void M_Options_Init (enum m_state_e state) // set up the display mode selector. VID_Menu_InitDisplayMode (); } + else if (state == m_gamepad) + { + optionsmenu.first_item = GPAD_OPTIONS_FIRST; + optionsmenu.list.numitems = GPAD_OPTIONS_ITEMS; + optionsmenu.last_cursor = &optionsmenu.gamepad_cursor; + optionsmenu.subtitle = "Gamepad Options"; + } else { Sys_Error ("M_Options_Init: invalid state %d", state); @@ -3322,7 +3626,7 @@ void M_AdjustSliders (int dir) break; case OPT_HUDSTYLE: // hud style - Cvar_SetValueQuick (&scr_hudstyle, ((int) q_max (scr_hudstyle.value, 0.f) + 3 + dir) % 3); + Cvar_SetValueQuick (&scr_hudstyle, ((int) q_max (scr_hudstyle.value, 0.f) + 4 + dir) % 4); break; case OPT_ALWAYRUN: // always run @@ -3457,6 +3761,55 @@ void M_AdjustSliders (int dir) Cbuf_AddText ("toggle scr_showfps\n"); break; + // + // Gamepad Options + // + case GPAD_OPT_ENABLE: + Cvar_SetValueQuick (&joy_enable, !joy_enable.value); + break; + case GPAD_OPT_SENSX: + Cvar_SetValueQuick (&joy_sensitivity_yaw, CLAMP (MIN_JOY_SENS, joy_sensitivity_yaw.value + dir * 10.f, MAX_JOY_SENS)); + break; + case GPAD_OPT_SENSY: + Cvar_SetValueQuick (&joy_sensitivity_pitch, CLAMP (MIN_JOY_SENS, joy_sensitivity_pitch.value + dir * 10.f, MAX_JOY_SENS)); + break; + case GPAD_OPT_INVERT: + Cvar_SetValueQuick (&joy_invert, !joy_invert.value); + break; + case GPAD_OPT_SWAP_MOVELOOK: + Cvar_SetValueQuick (&joy_swapmovelook, !joy_swapmovelook.value); + break; + case GPAD_OPT_EXPONENT_LOOK: + Cvar_SetValueQuick (&joy_exponent, CLAMP (MIN_JOY_EXPONENT, joy_exponent.value + dir * 0.5f, MAX_JOY_EXPONENT)); + break; + case GPAD_OPT_EXPONENT_MOVE: + Cvar_SetValueQuick (&joy_exponent_move, CLAMP (MIN_JOY_EXPONENT, joy_exponent_move.value + dir * 0.5f, MAX_JOY_EXPONENT)); + break; + case GPAD_OPT_DEADZONE_LOOK: + Cvar_SetValueQuick (&joy_deadzone_look, CLAMP (MIN_STICK_DEADZONE, joy_deadzone_look.value + dir * 0.05f, MAX_STICK_DEADZONE)); + break; + case GPAD_OPT_DEADZONE_MOVE: + Cvar_SetValueQuick (&joy_deadzone_move, CLAMP (MIN_STICK_DEADZONE, joy_deadzone_move.value + dir * 0.05f, MAX_STICK_DEADZONE)); + break; + case GPAD_OPT_DEADZONE_TRIG: + Cvar_SetValueQuick (&joy_deadzone_trigger, CLAMP (MIN_TRIGGER_DEADZONE, joy_deadzone_trigger.value + dir * 0.05f, MAX_TRIGGER_DEADZONE)); + break; + case GPAD_OPT_GYROMODE: + Cvar_SetValueQuick (&gyro_mode, (int)(q_max (gyro_mode.value, 0.f) + 5 + dir) % 5); + break; + case GPAD_OPT_GYROAXIS: + Cvar_SetValueQuick (&gyro_turning_axis, !gyro_turning_axis.value); + break; + case GPAD_OPT_GYROSENSX: + Cvar_SetValueQuick (&gyro_yawsensitivity, CLAMP (MIN_GYRO_SENS, gyro_yawsensitivity.value + dir * .1f, MAX_GYRO_SENS)); + break; + case GPAD_OPT_GYROSENSY: + Cvar_SetValueQuick (&gyro_pitchsensitivity, CLAMP (MIN_GYRO_SENS, gyro_pitchsensitivity.value + dir * .1f, MAX_GYRO_SENS)); + break; + case GPAD_OPT_CALIBRATE: + M_Menu_Calibration_f (); + break; + default: break; } @@ -3544,6 +3897,42 @@ qboolean M_SetSliderValue (int option, float f) case OPT_FOVDISTORT: // FOV distortion Cvar_SetValue ("cl_gun_fovscale", 1.f - f); return true; + case GPAD_OPT_SENSX: + f = LERP (MIN_JOY_SENS, MAX_JOY_SENS, f); + Cvar_SetValueQuick (&joy_sensitivity_yaw, f); + return true; + case GPAD_OPT_SENSY: + f = LERP (MIN_JOY_SENS, MAX_JOY_SENS, f); + Cvar_SetValueQuick (&joy_sensitivity_pitch, f); + return true; + case GPAD_OPT_EXPONENT_LOOK: + f = LERP (MIN_JOY_EXPONENT, MAX_JOY_EXPONENT, f); + Cvar_SetValueQuick (&joy_exponent, f); + return true; + case GPAD_OPT_EXPONENT_MOVE: + f = LERP (MIN_JOY_EXPONENT, MAX_JOY_EXPONENT, f); + Cvar_SetValueQuick (&joy_exponent_move, f); + return true; + case GPAD_OPT_DEADZONE_LOOK: + f = LERP (MIN_STICK_DEADZONE, MAX_STICK_DEADZONE, f); + Cvar_SetValueQuick (&joy_deadzone_look, f); + return true; + case GPAD_OPT_DEADZONE_MOVE: + f = LERP (MIN_STICK_DEADZONE, MAX_STICK_DEADZONE, f); + Cvar_SetValueQuick (&joy_deadzone_move, f); + return true; + case GPAD_OPT_DEADZONE_TRIG: + f = LERP (MIN_TRIGGER_DEADZONE, MAX_TRIGGER_DEADZONE, f); + Cvar_SetValueQuick (&joy_deadzone_trigger, f); + return true; + case GPAD_OPT_GYROSENSX: + f = LERP (MIN_GYRO_SENS, MAX_GYRO_SENS, f); + Cvar_SetValueQuick (&gyro_yawsensitivity, f); + return true; + case GPAD_OPT_GYROSENSY: + f = LERP (MIN_GYRO_SENS, MAX_GYRO_SENS, f); + Cvar_SetValueQuick (&gyro_pitchsensitivity, f); + return true; default: return false; } @@ -3604,7 +3993,9 @@ static void M_Options_DrawItem (int y, int item) { case OPT_VIDEO: case OPT_CUSTOMIZE: + case OPT_GAMEPAD: case OPT_MODS: + case GPAD_OPT_CALIBRATE: M_Print (x - 4, y, "..."); break; @@ -3669,8 +4060,10 @@ static void M_Options_DrawItem (int y, int item) M_Print (x, y, "Classic"); else if (scr_hudstyle.value < 2) M_Print (x, y, "Modern 1"); - else + else if (scr_hudstyle.value < 3) M_Print (x, y, "Modern 2"); + else + M_Print(x, y, "QuakeWorld"); break; case OPT_SNDVOL: @@ -3803,6 +4196,68 @@ static void M_Options_DrawItem (int y, int item) M_Print (x, y, scr_showfps.value ? "On" : "Off"); break; + // + // Gamepad Options + // + case GPAD_OPT_ENABLE: + M_DrawCheckbox (x, y, joy_enable.value); + break; + case GPAD_OPT_SENSX: + r = (joy_sensitivity_yaw.value - MIN_JOY_SENS) / (MAX_JOY_SENS - MIN_JOY_SENS); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_SENSY: + r = (joy_sensitivity_pitch.value - MIN_JOY_SENS) / (MAX_JOY_SENS - MIN_JOY_SENS); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_INVERT: + M_DrawCheckbox (x, y, joy_invert.value); + break; + case GPAD_OPT_SWAP_MOVELOOK: + M_Print (x, y, joy_swapmovelook.value ? "Left" : "Right"); + break; + case GPAD_OPT_EXPONENT_LOOK: + r = (joy_exponent.value - MIN_JOY_EXPONENT) / (MAX_JOY_EXPONENT - MIN_JOY_EXPONENT); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_EXPONENT_MOVE: + r = (joy_exponent_move.value - MIN_JOY_EXPONENT) / (MAX_JOY_EXPONENT - MIN_JOY_EXPONENT); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_DEADZONE_LOOK: + r = (joy_deadzone_look.value - MIN_STICK_DEADZONE) / (MAX_STICK_DEADZONE - MIN_STICK_DEADZONE); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_DEADZONE_MOVE: + r = (joy_deadzone_move.value - MIN_STICK_DEADZONE) / (MAX_STICK_DEADZONE - MIN_STICK_DEADZONE); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_DEADZONE_TRIG: + r = (joy_deadzone_trigger.value - MIN_TRIGGER_DEADZONE) / (MAX_TRIGGER_DEADZONE - MIN_TRIGGER_DEADZONE); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_GYROMODE: + switch ((int)gyro_mode.value) + { + case 1: M_Print (x, y, "off, button enables"); break; + case 2: M_Print (x, y, "on, button disables"); break; + case 3: M_Print (x, y, "always on"); break; + case 4: M_Print (x, y, "on, button inverts direction"); break; + default: M_Print (x, y, "off"); break; + } + break; + case GPAD_OPT_GYROAXIS: + M_Print(x, y, gyro_turning_axis.value ? "roll (lean)" : "yaw (turn)"); + break; + case GPAD_OPT_GYROSENSX: + r = (gyro_yawsensitivity.value - MIN_GYRO_SENS) / (MAX_GYRO_SENS - MIN_GYRO_SENS); + M_DrawSlider (x, y, r); + break; + case GPAD_OPT_GYROSENSY: + r = (gyro_pitchsensitivity.value - MIN_GYRO_SENS) / (MAX_GYRO_SENS - MIN_GYRO_SENS); + M_DrawSlider (x, y, r); + break; + default: break; } @@ -3921,6 +4376,9 @@ void M_Options_Key (int k) case OPT_VIDEO: M_Menu_Video_f (); break; + case OPT_GAMEPAD: + M_Menu_Gamepad_f (); + break; case VID_OPT_TEST: Cbuf_AddText ("vid_test\n"); @@ -3958,9 +4416,9 @@ void M_Options_Key (int k) } } -qboolean M_Options_TextEntry (void) +textmode_t M_Options_TextEntry (void) { - return !slider_grab; + return slider_grab ? TEXTMODE_OFF : TEXTMODE_NOPOPUP; } void M_Options_Char (int key) @@ -4010,6 +4468,7 @@ static const char* const bindnames[][2] = {"centerview", "Center view"}, {"zoom_in", "Toggle zoom"}, {"+zoom", "Quick zoom"}, + {"+gyroaction", "Gyro Off / On"}, {"", ""}, {"+attack", "Attack"}, {"impulse 10", "Next weapon"}, @@ -4026,7 +4485,7 @@ static const char* const bindnames[][2] = {"impulse 226", "Mjolnir"}, }; -#define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0])) +#define NUMCOMMANDS Q_COUNTOF(bindnames) #define KEYLIST_OFS 48 static struct @@ -4259,9 +4718,9 @@ void M_Keys_Mousemove (int cx, int cy) M_List_Mousemove (&keysmenu.list, cy - keysmenu.y - KEYLIST_OFS); } -qboolean M_Keys_TextEntry (void) +textmode_t M_Keys_TextEntry (void) { - return !bind_grab; + return bind_grab ? TEXTMODE_OFF : TEXTMODE_NOPOPUP; } void M_Keys_Char (int key) @@ -4397,10 +4856,12 @@ void M_Menu_Quit_f (void) void M_Quit_Key (int key) { - if (key == K_ESCAPE || - key == K_MOUSE2 || - key == K_MOUSE4) + switch (key) { + case K_ESCAPE: + case K_BBUTTON: + case K_MOUSE4: + case K_MOUSE2: if (wasInMenus) { m_state = m_quit_prevstate; @@ -4412,6 +4873,16 @@ void M_Quit_Key (int key) key_dest = key_game; m_state = m_none; } + break; + + case K_ABUTTON: + IN_DeactivateForConsole(); + key_dest = key_console; + Host_Quit_f (); + break; + + default: + break; } } @@ -4449,9 +4920,9 @@ void M_Quit_Char (int key) } -qboolean M_Quit_TextEntry (void) +textmode_t M_Quit_TextEntry (void) { - return true; + return TEXTMODE_NOPOPUP; } @@ -4701,9 +5172,9 @@ void M_LanConfig_Char (int key) } -qboolean M_LanConfig_TextEntry (void) +textmode_t M_LanConfig_TextEntry (void) { - return (lanConfig_cursor == 0 || lanConfig_cursor == 2); + return (lanConfig_cursor == 0 || lanConfig_cursor == 2) ? TEXTMODE_ON : TEXTMODE_OFF; } @@ -5364,11 +5835,10 @@ typedef struct static struct { menulist_t list; + menuticker_t ticker; int x, y, cols; int modcount; int prev_cursor; - double scroll_time; - double scroll_wait_time; double download_flash_time; enum m_state_e prev; qboolean scrollbar_grab; @@ -5500,6 +5970,8 @@ static void M_Mods_Init (void) modsmenu.modcount = 0; VEC_CLEAR (modsmenu.items); + M_Ticker_Init (&modsmenu.ticker); + for (pass = 0; pass < 2; pass++) { count = 0; @@ -5559,16 +6031,10 @@ void M_Mods_Draw (void) if (modsmenu.prev_cursor != modsmenu.list.cursor) { modsmenu.prev_cursor = modsmenu.list.cursor; - modsmenu.scroll_time = 0.0; - modsmenu.scroll_wait_time = 1.0; + M_Ticker_Init (&modsmenu.ticker); } else - { - if (modsmenu.scroll_wait_time <= 0.0) - modsmenu.scroll_time += host_rawframetime; - else - modsmenu.scroll_wait_time = q_max (0.0, modsmenu.scroll_wait_time - host_rawframetime); - } + M_Ticker_Update (&modsmenu.ticker); modsmenu.download_flash_time = q_max (0.0, modsmenu.download_flash_time - host_rawframetime); flash = (int)(modsmenu.download_flash_time * 8.0) & 1; @@ -5636,7 +6102,7 @@ void M_Mods_Draw (void) GL_SetCanvasColor (1, 1, 1, 1); M_PrintScroll (x + namecols*8, y + i*8, desccols*8, buf, - selected ? modsmenu.scroll_time : 0.0, true); + selected ? modsmenu.ticker.scroll_time : 0.0, true); if (!message) GL_SetCanvasColor (1, 1, 1, 1); @@ -5669,9 +6135,9 @@ void M_Mods_Char (int key) M_List_Char (&modsmenu.list, key); } -qboolean M_Mods_TextEntry (void) +textmode_t M_Mods_TextEntry (void) { - return !modsmenu.scrollbar_grab; + return modsmenu.scrollbar_grab ? TEXTMODE_OFF : TEXTMODE_NOPOPUP; } void M_Mods_Key (int key) @@ -5696,6 +6162,12 @@ void M_Mods_Key (int key) if (M_List_Key (&modsmenu.list, key)) return; + if (M_Ticker_Key (&modsmenu.ticker, key)) + { + M_List_KeepSearchVisible (&modsmenu.list, 1.0); + return; + } + switch (key) { case K_ESCAPE: @@ -5733,19 +6205,6 @@ void M_Mods_Key (int key) M_Mods_Mousemove (m_mousex, m_mousey); break; - case K_RIGHTARROW: - modsmenu.scroll_time += 0.25; - modsmenu.scroll_wait_time = 1.5; - M_List_KeepSearchVisible (&modsmenu.list, 1.0); - M_ThrottledSound ("misc/menu3.wav"); - break; - case K_LEFTARROW: - modsmenu.scroll_time -= 0.25; - modsmenu.scroll_wait_time = 1.5; - M_List_KeepSearchVisible (&modsmenu.list, 1.0); - M_ThrottledSound ("misc/menu3.wav"); - break; - default: break; } @@ -6028,6 +6487,7 @@ void M_Init (void) Cmd_AddCommand ("menu_options", M_Menu_Options_f); Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); Cmd_AddCommand ("menu_video", M_Menu_Video_f); + Cmd_AddCommand ("menu_gamepad", M_Menu_Gamepad_f); Cmd_AddCommand ("help", M_Menu_Help_f); Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); Cmd_AddCommand ("menu_credits", M_Menu_Credits_f); // needed by the 2021 re-release @@ -6130,8 +6590,13 @@ void M_Draw (void) M_Net_Draw (); break; + case m_calibration: + M_Calibration_Draw (); + break; + case m_options: case m_video: + case m_gamepad: M_Options_Draw (); break; @@ -6234,8 +6699,13 @@ void M_Keydown (int key) M_Net_Key (key); return; + case m_calibration: + M_Calibration_Key (key); + break; + case m_options: case m_video: + case m_gamepad: M_Options_Key (key); return; @@ -6344,6 +6814,7 @@ void M_Mousemove (int x, int y) case m_options: case m_video: + case m_gamepad: M_Options_Mousemove (x, y); return; @@ -6403,6 +6874,7 @@ void M_Charinput (int key) return; case m_options: case m_video: + case m_gamepad: M_Options_Char (key); return; case m_keys: @@ -6414,7 +6886,7 @@ void M_Charinput (int key) } -qboolean M_TextEntry (void) +textmode_t M_TextEntry (void) { switch (m_state) { @@ -6430,11 +6902,12 @@ qboolean M_TextEntry (void) return M_Mods_TextEntry (); case m_options: case m_video: + case m_gamepad: return M_Options_TextEntry (); case m_keys: return M_Keys_TextEntry (); default: - return false; + return TEXTMODE_OFF; } } diff --git a/Quake/menu.h b/Quake/menu.h index b7004e2a7..795a3f912 100644 --- a/Quake/menu.h +++ b/Quake/menu.h @@ -37,6 +37,8 @@ enum m_state_e { m_options, m_video, m_keys, + m_calibration, + m_gamepad, m_mods, m_modinfo, m_help, @@ -59,7 +61,7 @@ void M_Init (void); void M_Keydown (int key); void M_Charinput (int key); void M_Mousemove (int x, int y); -qboolean M_TextEntry (void); +enum textmode_t M_TextEntry (void); qboolean M_KeyBinding (void); void M_ToggleMenu_f (void); diff --git a/Quake/net_bsd.c b/Quake/net_bsd.c index 59487e7e6..52d99a322 100644 --- a/Quake/net_bsd.c +++ b/Quake/net_bsd.c @@ -63,7 +63,7 @@ net_driver_t net_drivers[] = } }; -const int net_numdrivers = (sizeof(net_drivers) / sizeof(net_drivers[0])); +const int net_numdrivers = Q_COUNTOF(net_drivers); #include "net_udp.h" @@ -93,5 +93,4 @@ net_landriver_t net_landrivers[] = } }; -const int net_numlandrivers = (sizeof(net_landrivers) / sizeof(net_landrivers[0])); - +const int net_numlandrivers = Q_COUNTOF(net_landrivers); diff --git a/Quake/net_main.c b/Quake/net_main.c index 4c7184b14..4a090399b 100644 --- a/Quake/net_main.c +++ b/Quake/net_main.c @@ -25,7 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "net_sys.h" #include "net_defs.h" +#ifndef WITHOUT_CURL #include <curl/curl.h> +#endif qsocket_t *net_activeSockets = NULL; qsocket_t *net_freeSockets = NULL; @@ -835,7 +837,9 @@ void NET_Init (void) Con_DPrintf("TCP/IP address %s\n", my_tcpip_address); } +#ifndef WITHOUT_CURL curl_global_init (CURL_GLOBAL_DEFAULT); +#endif } /* @@ -848,8 +852,9 @@ void NET_Shutdown (void) { qsocket_t *sock; +#ifndef WITHOUT_CURL curl_global_cleanup (); - +#endif SetNetTime(); for (sock = net_activeSockets; sock; sock = sock->next) diff --git a/Quake/net_sys.h b/Quake/net_sys.h index 77727e3b8..bc334dc1c 100644 --- a/Quake/net_sys.h +++ b/Quake/net_sys.h @@ -31,7 +31,8 @@ #if defined(PLATFORM_BSD) || defined(PLATFORM_OSX) || \ defined(PLATFORM_AMIGA) /* bsdsocket.library */ || \ - defined(__GNU__) /* GNU/Hurd */ || defined(__riscos__) + defined(__GNU__) /* GNU/Hurd */ || defined(__riscos__) || \ + defined(PLATFORM_HAIKU) /* Haiku OS */ /* struct sockaddr has unsigned char sa_len as the first member in BSD * variants and the family member is also an unsigned char instead of an * unsigned short. This should matter only when PLATFORM_UNIX is defined, @@ -47,7 +48,7 @@ #endif /* BSD, sockaddr */ /* unix includes and compatibility macros */ -#if defined(PLATFORM_UNIX) || defined(PLATFORM_RISCOS) +#if defined(PLATFORM_UNIX) || defined(PLATFORM_RISCOS) || defined(PLATFORM_HAIKU) #include <sys/param.h> #include <sys/ioctl.h> diff --git a/Quake/net_win.c b/Quake/net_win.c index 64bf083ac..41857e26c 100644 --- a/Quake/net_win.c +++ b/Quake/net_win.c @@ -63,7 +63,7 @@ net_driver_t net_drivers[] = } }; -const int net_numdrivers = (sizeof(net_drivers) / sizeof(net_drivers[0])); +const int net_numdrivers = Q_COUNTOF(net_drivers); #include "net_wins.h" @@ -118,5 +118,4 @@ net_landriver_t net_landrivers[] = } }; -const int net_numlandrivers = (sizeof(net_landrivers) / sizeof(net_landrivers[0])); - +const int net_numlandrivers = Q_COUNTOF(net_landrivers); diff --git a/Quake/net_wipx.c b/Quake/net_wipx.c index 31c08874c..86e17310d 100644 --- a/Quake/net_wipx.c +++ b/Quake/net_wipx.c @@ -36,7 +36,7 @@ static sys_socket_t net_controlsocket; static struct sockaddr_ipx broadcastaddr; /* externs from net_wins.c: */ -extern qboolean winsock_initialized; +extern int winsock_initialized; extern WSADATA winsockdata; extern const char *__WSAE_StrError (int); diff --git a/Quake/pl_osx.m b/Quake/pl_osx.m index e3a5b98bb..792afd1b1 100644 --- a/Quake/pl_osx.m +++ b/Quake/pl_osx.m @@ -55,14 +55,22 @@ void PL_VID_Shutdown (void) if ([types containsObject: NSPasteboardTypeString]) { NSString* clipboardString = [pasteboard stringForType: NSPasteboardTypeString]; if (clipboardString != NULL && [clipboardString length] > 0) { - size_t sz = [clipboardString length] + 1; - sz = q_min((size_t)(MAX_CLIPBOARDTXT), sz); - data = (char *) Z_Malloc((int)sz); + const char* srcdata = NULL; + #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1040) /* for ppc builds targeting 10.3 and older */ - q_strlcpy (data, [clipboardString cString], sz); + if ([clipboardString canBeConvertedToEncoding:NSASCIIStringEncoding]) + srcdata = [clipboardString cString]; #else - q_strlcpy (data, [clipboardString cStringUsingEncoding: NSASCIIStringEncoding], sz); + srcdata = [clipboardString cStringUsingEncoding: NSASCIIStringEncoding]; #endif + + if (srcdata != NULL) + { + size_t sz = [clipboardString length] + 1; + sz = q_min((size_t)(MAX_CLIPBOARDTXT), sz); + data = (char *) Z_Malloc((int)sz); + q_strlcpy (data, srcdata, sz); + } } } return data; diff --git a/Quake/platform.h b/Quake/platform.h index 679ecffb8..5927a0005 100644 --- a/Quake/platform.h +++ b/Quake/platform.h @@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _QUAKE_PLATFORM_H #define _QUAKE_PLATFORM_H +#ifdef __cplusplus +extern "C" { +#endif + /* platform dependent way to set the window icon */ void PL_SetWindowIcon(void); @@ -36,5 +40,9 @@ char *PL_GetClipboardData (void); /* show an error dialog */ void PL_ErrorDialog(const char *text); +#ifdef __cplusplus +} +#endif + #endif /* _QUAKE_PLATFORM_H */ diff --git a/Quake/pr_cmds.c b/Quake/pr_cmds.c index a896e9271..fbfde525f 100644 --- a/Quake/pr_cmds.c +++ b/Quake/pr_cmds.c @@ -3638,6 +3638,6 @@ builtindef_t pr_builtindefs[] = {"sprintf", PF_BOTH(PF_sprintf), 627, DP_QC_SPRINTF}, // string(string fmt, ...) }; -int pr_numbuiltindefs = countof (pr_builtindefs); +int pr_numbuiltindefs = Q_COUNTOF(pr_builtindefs); COMPILE_TIME_ASSERT (builtin_buffer_size, countof (pr_builtindefs) + 1 <= MAX_BUILTINS); diff --git a/Quake/pr_edict.c b/Quake/pr_edict.c index 5c7c7fae9..3f9723078 100644 --- a/Quake/pr_edict.c +++ b/Quake/pr_edict.c @@ -34,6 +34,8 @@ int type_size[8] = { 1 // sizeof(void *) / 4 // ev_pointer }; +#define NUM_TYPE_SIZES (int)Q_COUNTOF(type_size) + static ddef_t *ED_FieldAtOfs (int ofs); static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s, qboolean zoned); @@ -599,6 +601,7 @@ padded to 20 field width const char *PR_GlobalString (int ofs) { static char line[512]; + static const int lastchari = Q_COUNTOF(line) - 2; const char *s; int i; ddef_t *def; @@ -617,7 +620,11 @@ const char *PR_GlobalString (int ofs) i = strlen(line); for ( ; i < 20; i++) strcat (line, " "); - strcat (line, " "); + + if (i < lastchari) + strcat (line, " "); + else + line[lastchari] = ' '; return line; } @@ -625,6 +632,7 @@ const char *PR_GlobalString (int ofs) const char *PR_GlobalStringNoContents (int ofs) { static char line[512]; + static const int lastchari = Q_COUNTOF(line) - 2; int i; ddef_t *def; @@ -637,7 +645,11 @@ const char *PR_GlobalStringNoContents (int ofs) i = strlen(line); for ( ; i < 20; i++) strcat (line, " "); - strcat (line, " "); + + if (i < lastchari) + strcat (line, " "); + else + line[lastchari] = ' '; return line; } @@ -680,6 +692,9 @@ void ED_Print (edict_t *ed) // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; + if (type >= NUM_TYPE_SIZES) + continue; + for (j = 0; j < type_size[type]; j++) { if (v[j]) @@ -734,6 +749,10 @@ void ED_Write (savedata_t *save, edict_t *ed) // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; + + if (type >= NUM_TYPE_SIZES) + continue; + for (j = 0; j < type_size[type]; j++) { if (v[j]) @@ -1187,7 +1206,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent) } if (!init) - ED_AddToFreeList (ent); + ED_Free (ent); return data; } diff --git a/Quake/pr_exec.c b/Quake/pr_exec.c index 8ff624e92..5b8a882ca 100644 --- a/Quake/pr_exec.c +++ b/Quake/pr_exec.c @@ -148,7 +148,7 @@ static void PR_PrintStatement (dstatement_t *s) { int i; - if ((unsigned int)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0])) + if ((unsigned int)s->op < Q_COUNTOF(pr_opnames)) { Con_Printf("%s ", pr_opnames[s->op]); i = strlen(pr_opnames[s->op]); @@ -422,7 +422,7 @@ void PR_ExecuteProgram (func_t fnum) { st++; /* next statement */ - if (++profile > 100000) + if (++profile > 0x1000000) /* was 100000 */ { qcvm->xstatement = st - qcvm->statements; PR_RunError("runaway loop error"); diff --git a/Quake/progs.h b/Quake/progs.h index 9d9c2a176..dcf1e963c 100644 --- a/Quake/progs.h +++ b/Quake/progs.h @@ -279,7 +279,8 @@ typedef struct savedata_s int buffersize; } savedata_t; -#define SAVEGAME_VERSION 5 +#define SAVEGAME_VERSION 5 +#define SAVEGAME_VERSION_KEX 6 extern THREAD_LOCAL globalvars_t *pr_global_struct; extern THREAD_LOCAL qcvm_t *qcvm; @@ -329,7 +330,7 @@ int SAVE_NUM_FOR_EDICT (savedata_t *save, edict_t *e); #define NEXT_EDICT(e) ((edict_t *)( (byte *)e + qcvm->edict_size)) -#define EDICT_TO_PROG(e) ((byte *)e - (byte *)qcvm->edicts) +#define EDICT_TO_PROG(e) (int)((byte *)e - (byte *)qcvm->edicts) #define PROG_TO_EDICT(e) ((edict_t *)((byte *)qcvm->edicts + e)) #define SAVE_PROG_TO_EDICT(s, e) ((edict_t *)((byte *)s->edicts + e)) diff --git a/Quake/q_stdinc.h b/Quake/q_stdinc.h index 66090684c..0c557273a 100644 --- a/Quake/q_stdinc.h +++ b/Quake/q_stdinc.h @@ -117,6 +117,9 @@ typedef enum { COMPILE_TIME_ASSERT(enum, sizeof(THE_DUMMY_ENUM) == sizeof(int)); +/* for array size: */ +#define Q_COUNTOF(x) (sizeof(x) / sizeof((x)[0])) + /* Provide a substitute for offsetof() if we don't have one. * This variant works on most (but not *all*) systems... */ @@ -159,6 +162,10 @@ typedef int fixed4_t; typedef int fixed8_t; typedef int fixed16_t; +/* natvis helpers */ +typedef struct { float data[2]; } float2_t; +typedef struct { float data[3]; } float3_t; +typedef struct { float data[4]; } float4_t; /*==========================================================================*/ diff --git a/Quake/quakedef.h b/Quake/quakedef.h index 883476bd9..3ee40bbdf 100644 --- a/Quake/quakedef.h +++ b/Quake/quakedef.h @@ -36,7 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define X11_VERSION 1.10 #define FITZQUAKE_VERSION 0.85 //johnfitz -#define QUAKESPASM_VERSION 0.95 +#define QUAKESPASM_VERSION 0.96 #define QUAKESPASM_VER_PATCH 1 // helper to print a string like 0.94.7 #ifndef QUAKESPASM_VER_SUFFIX #define QUAKESPASM_VER_SUFFIX // optional version suffix string literal like "-beta1" @@ -115,90 +115,103 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // stats are integers communicated to the client by the server // -#define MAX_CL_BASE_STATS 32 -#define MAX_CL_STATS 256 -#define STAT_HEALTH 0 -#define STAT_FRAGS 1 -#define STAT_WEAPON 2 -#define STAT_AMMO 3 -#define STAT_ARMOR 4 -#define STAT_WEAPONFRAME 5 -#define STAT_SHELLS 6 -#define STAT_NAILS 7 -#define STAT_ROCKETS 8 -#define STAT_CELLS 9 -#define STAT_ACTIVEWEAPON 10 -#define STAT_NONCLIENT 11 // first stat not included in svc_clientdata -#define STAT_TOTALSECRETS 11 -#define STAT_TOTALMONSTERS 12 -#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret -#define STAT_MONSTERS 14 // bumped by svc_killedmonster -#define STAT_ITEMS 15 //replaces clc_clientdata info +typedef enum +{ + MAX_CL_BASE_STATS = 32, + MAX_CL_STATS = 256, + + STAT_HEALTH = 0, + STAT_FRAGS = 1, + STAT_WEAPON = 2, + STAT_AMMO = 3, + STAT_ARMOR = 4, + STAT_WEAPONFRAME = 5, + STAT_SHELLS = 6, + STAT_NAILS = 7, + STAT_ROCKETS = 8, + STAT_CELLS = 9, + STAT_ACTIVEWEAPON = 10, + STAT_NONCLIENT = 11, // first stat not included in svc_clientdata + STAT_TOTALSECRETS = 11, + STAT_TOTALMONSTERS = 12, + STAT_SECRETS = 13, // bumped on client side by svc_foundsecret + STAT_MONSTERS = 14, // bumped by svc_killedmonster + STAT_ITEMS = 15, //replaces clc_clientdata info +} stat_t; // stock defines // -#define IT_SHOTGUN 1 -#define IT_SUPER_SHOTGUN 2 -#define IT_NAILGUN 4 -#define IT_SUPER_NAILGUN 8 -#define IT_GRENADE_LAUNCHER 16 -#define IT_ROCKET_LAUNCHER 32 -#define IT_LIGHTNING 64 -#define IT_SUPER_LIGHTNING 128 -#define IT_SHELLS 256 -#define IT_NAILS 512 -#define IT_ROCKETS 1024 -#define IT_CELLS 2048 -#define IT_AXE 4096 -#define IT_ARMOR1 8192 -#define IT_ARMOR2 16384 -#define IT_ARMOR3 32768 -#define IT_SUPERHEALTH 65536 -#define IT_KEY1 131072 -#define IT_KEY2 262144 -#define IT_INVISIBILITY 524288 -#define IT_INVULNERABILITY 1048576 -#define IT_SUIT 2097152 -#define IT_QUAD 4194304 -#define IT_SIGIL1 (1<<28) -#define IT_SIGIL2 (1<<29) -#define IT_SIGIL3 (1<<30) -#define IT_SIGIL4 (1<<31) +typedef enum +{ + IT_SHOTGUN = 1, + IT_SUPER_SHOTGUN = 2, + IT_NAILGUN = 4, + IT_SUPER_NAILGUN = 8, + IT_GRENADE_LAUNCHER = 16, + IT_ROCKET_LAUNCHER = 32, + IT_LIGHTNING = 64, + IT_SUPER_LIGHTNING = 128, + IT_SHELLS = 256, + IT_NAILS = 512, + IT_ROCKETS = 1024, + IT_CELLS = 2048, + IT_AXE = 4096, + IT_ARMOR1 = 8192, + IT_ARMOR2 = 16384, + IT_ARMOR3 = 32768, + IT_SUPERHEALTH = 65536, + IT_KEY1 = 131072, + IT_KEY2 = 262144, + IT_INVISIBILITY = 524288, + IT_INVULNERABILITY = 1048576, + IT_SUIT = 2097152, + IT_QUAD = 4194304, + IT_SIGIL1 = (1<<28), + IT_SIGIL2 = (1<<29), + IT_SIGIL3 = (1<<30), + IT_SIGIL4 = (1<<31), +} items_t; //=========================================== //rogue changed and added defines -#define RIT_SHELLS 128 -#define RIT_NAILS 256 -#define RIT_ROCKETS 512 -#define RIT_CELLS 1024 -#define RIT_AXE 2048 -#define RIT_LAVA_NAILGUN 4096 -#define RIT_LAVA_SUPER_NAILGUN 8192 -#define RIT_MULTI_GRENADE 16384 -#define RIT_MULTI_ROCKET 32768 -#define RIT_PLASMA_GUN 65536 -#define RIT_ARMOR1 8388608 -#define RIT_ARMOR2 16777216 -#define RIT_ARMOR3 33554432 -#define RIT_LAVA_NAILS 67108864 -#define RIT_PLASMA_AMMO 134217728 -#define RIT_MULTI_ROCKETS 268435456 -#define RIT_SHIELD 536870912 -#define RIT_ANTIGRAV 1073741824 -#define RIT_SUPERHEALTH 2147483648 +typedef enum +{ + RIT_SHELLS = 128, + RIT_NAILS = 256, + RIT_ROCKETS = 512, + RIT_CELLS = 1024, + RIT_AXE = 2048, + RIT_LAVA_NAILGUN = 4096, + RIT_LAVA_SUPER_NAILGUN = 8192, + RIT_MULTI_GRENADE = 16384, + RIT_MULTI_ROCKET = 32768, + RIT_PLASMA_GUN = 65536, + RIT_ARMOR1 = 8388608, + RIT_ARMOR2 = 16777216, + RIT_ARMOR3 = 33554432, + RIT_LAVA_NAILS = 67108864, + RIT_PLASMA_AMMO = 134217728, + RIT_MULTI_ROCKETS = 268435456, + RIT_SHIELD = 536870912, + RIT_ANTIGRAV = 1073741824, + RIT_SUPERHEALTH = 2147483648, +} rogueitems_t; //MED 01/04/97 added hipnotic defines //=========================================== //hipnotic added defines -#define HIT_PROXIMITY_GUN_BIT 16 -#define HIT_MJOLNIR_BIT 7 -#define HIT_LASER_CANNON_BIT 23 -#define HIT_PROXIMITY_GUN (1<<HIT_PROXIMITY_GUN_BIT) -#define HIT_MJOLNIR (1<<HIT_MJOLNIR_BIT) -#define HIT_LASER_CANNON (1<<HIT_LASER_CANNON_BIT) -#define HIT_WETSUIT (1<<(23+2)) -#define HIT_EMPATHY_SHIELDS (1<<(23+3)) +typedef enum +{ + HIT_PROXIMITY_GUN_BIT = 16, + HIT_MJOLNIR_BIT = 7, + HIT_LASER_CANNON_BIT = 23, + HIT_PROXIMITY_GUN = (1<<HIT_PROXIMITY_GUN_BIT), + HIT_MJOLNIR = (1<<HIT_MJOLNIR_BIT), + HIT_LASER_CANNON = (1<<HIT_LASER_CANNON_BIT), + HIT_WETSUIT = (1<<(23+2)), + HIT_EMPATHY_SHIELDS = (1<<(23+3)), +} hipnoticitems_t; //=========================================== @@ -388,7 +401,7 @@ void Host_ShutdownServer (qboolean crash); void Host_WriteConfiguration (void); void Host_Resetdemos (void); -void Host_SavegameComment (char *text); +void Host_SavegameComment (char text[SAVEGAME_COMMENT_LENGTH + 1]); void Host_WaitForSaveThread (void); void Host_ShutdownSave (void); qboolean Host_IsSaving (void); diff --git a/Quake/r_alias.c b/Quake/r_alias.c index 466ad3c46..0f881685f 100644 --- a/Quake/r_alias.c +++ b/Quake/r_alias.c @@ -31,16 +31,13 @@ extern cvar_t r_oit; //up to 16 color translated skins gltexture_t *playertextures[MAX_SCOREBOARD]; //johnfitz -- changed to an array of pointers -#define NUMVERTEXNORMALS 162 - -float r_avertexnormals[NUMVERTEXNORMALS][3] = -{ +const float r_avertexnormals[NUMVERTEXNORMALS][3] = { #include "anorms.h" }; extern vec3_t lightcolor; //johnfitz -- replaces "float shadelight" for lit support -float entalpha; //johnfitz +static float entalpha; //johnfitz //johnfitz -- struct for passing lerp information to drawing functions typedef struct { diff --git a/Quake/r_part.c b/Quake/r_part.c index 9c84fe157..bee686924 100644 --- a/Quake/r_part.c +++ b/Quake/r_part.c @@ -28,9 +28,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's // on the command line -int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}; -int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; -int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; +static int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}; +static int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; +static int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; particle_t *particles; int r_numparticles, r_numactiveparticles; @@ -91,9 +91,9 @@ void R_InitParticles (void) i = COM_CheckParm ("-particles"); - if (i) + if (i && i < com_argc - 1) { - r_numparticles = (int)(Q_atoi(com_argv[i+1])); + r_numparticles = atoi(com_argv[i + 1]); if (r_numparticles < ABSOLUTE_MIN_PARTICLES) r_numparticles = ABSOLUTE_MIN_PARTICLES; } @@ -116,13 +116,8 @@ void R_InitParticles (void) R_EntityParticles =============== */ -#define NUMVERTEXNORMALS 162 -extern float r_avertexnormals[NUMVERTEXNORMALS][3]; -vec3_t avelocities[NUMVERTEXNORMALS]; -float beamlength = 16; -vec3_t avelocity = {23, 7, 3}; -float partstep = 0.01; -float timescale = 0.01; +static vec3_t avelocities[NUMVERTEXNORMALS]; +static float beamlength = 16; void R_EntityParticles (entity_t *ent) { diff --git a/Quake/r_sprite.c b/Quake/r_sprite.c index 90ced637a..2ca008024 100644 --- a/Quake/r_sprite.c +++ b/Quake/r_sprite.c @@ -89,6 +89,19 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currentent) { pspriteframe = psprite->frames[frame].frameptr; } + else if (psprite->frames[frame].type == SPR_ANGLED) + { + // erysdren - angled sprites code backported from FTEQW + vec3_t axis[3]; + AngleVectors(currentent->angles, axis[0], axis[1], axis[2]); + { + float f = DotProduct(vpn, axis[0]); + float r = DotProduct(vright, axis[0]); + int dir = (atan2(r, f)+1.125*M_PI)*(4/M_PI); + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pspriteframe = pspritegroup->frames[dir&7]; + } + } else { pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; @@ -143,9 +156,9 @@ static void R_FlushSpriteInstances (void) GL_UseProgram (glprogs.sprites[dither]); if (showtris) - GL_SetState (GLS_BLEND_OPAQUE | GLS_NO_ZWRITE | GLS_CULL_NONE | GLS_ATTRIBS(2)); + GL_SetState (GLS_BLEND_OPAQUE | GLS_NO_ZWRITE | GLS_CULL_BACK | GLS_ATTRIBS(2)); else - GL_SetState (GLS_BLEND_OPAQUE | GLS_CULL_NONE | GLS_ATTRIBS(2)); + GL_SetState (GLS_BLEND_OPAQUE | GLS_CULL_BACK | GLS_ATTRIBS(2)); GL_Bind (GL_TEXTURE0, showtris ? whitetexture : batchtexture); diff --git a/Quake/render.h b/Quake/render.h index 963c9f45d..b2bab22f3 100644 --- a/Quake/render.h +++ b/Quake/render.h @@ -147,4 +147,3 @@ extern int reinit_surfcache; // if 1, surface cache is currently empty and void D_FlushCaches (void); #endif /* _QUAKE_RENDER_H */ - diff --git a/Quake/sbar.c b/Quake/sbar.c index a852ff9ae..58ec916bb 100644 --- a/Quake/sbar.c +++ b/Quake/sbar.c @@ -23,48 +23,48 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -int sb_updates; // if >= vid.numpages, no update needed +static int sb_updates; // if >= vid.numpages, no update needed #define STAT_MINUS 10 // num frame for '-' stats digit #define SBAR2_MARGIN_X 16 #define SBAR2_MARGIN_Y 10 -qpic_t *sb_nums[2][11]; -qpic_t *sb_colon, *sb_slash; -qpic_t *sb_ibar; -qpic_t *sb_sbar; -qpic_t *sb_scorebar; +static qpic_t *sb_nums[2][11]; +static qpic_t *sb_colon, *sb_slash; +static qpic_t *sb_ibar; +static qpic_t *sb_sbar; +static qpic_t *sb_scorebar; -qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes -qpic_t *sb_ammo[4]; -qpic_t *sb_sigil[4]; -qpic_t *sb_armor[3]; -qpic_t *sb_items[32]; +static qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes +static qpic_t *sb_ammo[4]; +static qpic_t *sb_sigil[4]; +static qpic_t *sb_armor[3]; +static qpic_t *sb_items[32]; -qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive +static qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive // 0 is static, 1 is temporary animation -qpic_t *sb_face_invis; -qpic_t *sb_face_quad; -qpic_t *sb_face_invuln; -qpic_t *sb_face_invis_invuln; +static qpic_t *sb_face_invis; +static qpic_t *sb_face_quad; +static qpic_t *sb_face_invuln; +static qpic_t *sb_face_invis_invuln; -qboolean sb_showscores; +static qboolean sb_showscores; int sb_lines; // scan lines to draw -qpic_t *rsb_invbar[2]; -qpic_t *rsb_weapons[5]; -qpic_t *rsb_items[2]; -qpic_t *rsb_ammo[3]; -qpic_t *rsb_teambord; // PGM 01/19/97 - team color border +static qpic_t *rsb_invbar[2]; +static qpic_t *rsb_weapons[5]; +static qpic_t *rsb_items[2]; +static qpic_t *rsb_ammo[3]; +static qpic_t *rsb_teambord; // PGM 01/19/97 - team color border //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher -qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes +static qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes //MED 01/04/97 added array to simplify weapon parsing -int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT}; +static int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT}; //MED 01/04/97 added hipnotic items array -qpic_t *hsb_items[2]; +static qpic_t *hsb_items[2]; void Sbar_MiniDeathmatchOverlay (void); void Sbar_DeathmatchOverlay (void); @@ -421,11 +421,6 @@ void Sbar_DrawSmallNum (int x, int y, int num) //============================================================================= int fragsort[MAX_SCOREBOARD]; - -char scoreboardtext[MAX_SCOREBOARD][20]; -int scoreboardtop[MAX_SCOREBOARD]; -int scoreboardbottom[MAX_SCOREBOARD]; -int scoreboardcount[MAX_SCOREBOARD]; int scoreboardlines; /* @@ -467,35 +462,6 @@ int Sbar_ColorForMap (int m) return m < 128 ? m + 8 : m + 8; } -/* -=============== -Sbar_UpdateScoreboard -=============== -*/ -void Sbar_UpdateScoreboard (void) -{ - int i, k; - int top, bottom; - scoreboard_t *s; - - Sbar_SortFrags (); - -// draw the text - memset (scoreboardtext, 0, sizeof(scoreboardtext)); - - for (i = 0; i < scoreboardlines; i++) - { - k = fragsort[i]; - s = &cl.scores[k]; - sprintf (&scoreboardtext[i][1], "%3i %s", s->frags, s->name); - - top = s->colors & 0xf0; - bottom = (s->colors & 15) <<4; - scoreboardtop[i] = Sbar_ColorForMap (top); - scoreboardbottom[i] = Sbar_ColorForMap (bottom); - } -} - /* =============== Sbar_SoloScoreboard -- johnfitz -- new layout @@ -508,17 +474,17 @@ void Sbar_SoloScoreboard (void) int left, right, len; sprintf (str,"Kills: %i/%i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); - left = 8 + strlen (str)*8; + left = 8 + strlen (str) * 8; Sbar_DrawString (8, 12, str); sprintf (str,"Secrets: %i/%i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); - right = 312 - strlen (str)*8; + right = 312 - strlen (str) * 8; Sbar_DrawString (right, 12, str); if (!fitzmode) { /* QuakeSpasm customization: */ q_snprintf (str, sizeof(str), "skill %i", (int)(skill.value + 0.5)); - Sbar_DrawString ((left + right)/2 - strlen(str)*4, 12, str); + Sbar_DrawString ((left + right) / 2 - strlen (str) * 4, 12, str); if (cl.levelname[0]) q_snprintf (str, sizeof(str), "%s (%s)", cl.levelname, cl.mapname); @@ -557,6 +523,24 @@ void Sbar_DrawScoreboard (void) Sbar_DeathmatchOverlay (); } +/* +=============== +Sbar_MiniScoreboardSizeCheck +=============== +*/ +int Sbar_MiniScoreboardSizeCheck(void) +{ + float scale; + + scale = CLAMP(1.0f, scr_sbarscale.value, (float)glwidth / 320.0f); //johnfitz + + //MAX_SCOREBOARDNAME = 32, so total width for this overlay plus sbar is 632, but we can cut off some i guess + if (glwidth / scale < 512 || scr_viewsize.value >= 120) //johnfitz -- test should consider scr_sbarscale + return 0; + + return 1; +} + //============================================================================= /* @@ -773,6 +757,263 @@ void Sbar_DrawInventory (void) } } +/* +==================== +Sbar_DrawInventoryQW +==================== +*/ +void Sbar_DrawInventoryQW (void) +{ + int i; + float time; + int flashon; + int scoreboard_y_gap = 0; + qpic_t *pic; + + pic = Sbar_InventoryBarPic(); + + // handle sigil overlap w/ side scoreboard + if (cl.gametype == GAME_DEATHMATCH && Sbar_MiniScoreboardSizeCheck() ) + { + if (rogue || hipnotic) + scoreboard_y_gap = 0; // no sigils so can move weps down a bit + else + scoreboard_y_gap = 24; + } + + // draw weapons, ammo, sigils on right side if full hud + if(scr_viewsize.value < 110) + { + int extraguns = 2 * hipnotic; + + GL_SetCanvas (CANVAS_SBAR_QW_INV); + + // weapons + for (i = 0; i < 7; i++) + { + if (cl.items & (IT_SHOTGUN<<i) ) + { + time = cl.item_gettime[i]; + flashon = (int)((cl.time - time)*10); + if (flashon >= 10) + { + if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) ) + flashon = 1; + else + flashon = 0; + } + else + flashon = (flashon%5) + 2; + + Sbar_DrawPic (24, -69 - scoreboard_y_gap - (16 * (7 + extraguns) ) + i*16, sb_weapons[flashon][i]); + + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } + + // MED 01/04/97 + // hipnotic weapons + if (hipnotic) + { + int grenadeflashing = 0; + for (i = 0; i < 4; i++) + { + if (cl.items & (1<<hipweapons[i])) + { + time = cl.item_gettime[hipweapons[i]]; + flashon = (int)((cl.time - time)*10); + if (flashon >= 10) + { + if (cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])) + flashon = 1; + else + flashon = 0; + } + else + flashon = (flashon%5) + 2; + + // check grenade launcher + if (i == 2) + { + if (cl.items & HIT_PROXIMITY_GUN) + { + if (flashon) + { + grenadeflashing = 1; + Sbar_DrawPic(24, -69 - scoreboard_y_gap - (16 * 9) + 4 * 16, hsb_weapons[flashon][2]); + } + } + } + else if (i == 3) + { + if (cl.items & (IT_SHOTGUN<<4)) + { + if (flashon && !grenadeflashing) + { + Sbar_DrawPic(24, -69 - scoreboard_y_gap - (16 * 9) + 4 * 16, hsb_weapons[flashon][3]); + } + else if (!grenadeflashing) + { + Sbar_DrawPic(24, -69 - scoreboard_y_gap - (16 * 9) + 4 * 16, hsb_weapons[0][3]); + } + } + else + Sbar_DrawPic(24, -69 - scoreboard_y_gap - (16 * 9) + 4 * 16, hsb_weapons[flashon][4]); + } + else + Sbar_DrawPic(24, -69 - scoreboard_y_gap - (16 * 9) + (7 + i) * 16, hsb_weapons[flashon][i]); + + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } + } + + if (rogue) + { + // check for powered up weapon. + if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) + { + for (i=0;i<5;i++) + { + if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i)) + { + Sbar_DrawPic (24, -69 - scoreboard_y_gap - (16 * 7) + (i+2) * 16, rsb_weapons[i]); + } + } + } + } + + // ammo counts bgs + if (rogue) // ammo bar bg is slightly wider + { + for (i = 0; i < 4; i++) + { + Draw_SubPic(4, -45 - scoreboard_y_gap + (i * 11), 44, 11, pic, 1 / 320.f + i * (48 / 320.f), 0.f, 44 / 320.f, 11 / 24.f, NULL, scr_sbaralpha.value); + } + } + else + { + for (i = 0; i < 4; i++) + { + Draw_SubPic(6, -45 - scoreboard_y_gap + (i * 11), 42 , 11, pic, 3 / 320.f + i * (48 / 320.f), 0.f, 42 / 320.f, 11 / 24.f, NULL, scr_sbaralpha.value); + } + } + + // ammo counts + for (i = 0; i < 4; i++) + { + Sbar_DrawSmallNum(13, -69 - scoreboard_y_gap + (i * 11), cl.stats[STAT_SHELLS + i]); + } + + if (!rogue) + { + flashon = 0; + + // sigils bg - hide if none + int has_a_sigil = 0; + + for (i = 0; i < 4; i++) + { + if (cl.items & (1<<(28+i))) + has_a_sigil = 1; + } + + if (has_a_sigil) + Draw_SubPic (16, -16 - scoreboard_y_gap + 24, 32, 16, sb_ibar, 1.f-32/320.f, 8/24.f, 32/320.f, 16/24.f, NULL, 1.f); + + // sigils + for (i = 0; i < 4; i++) + { + if (cl.items & (1<<(28+i))) + { + time = cl.item_gettime[28+i]; + if (time && time > cl.time - 2 && flashon) + { // flash frame + sb_updates = 0; + } + else + Sbar_DrawPic (16 + i*8, -16 - scoreboard_y_gap, sb_sigil[i]); + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } + } + + // draw items/powerups with main hud + GL_SetCanvas (CANVAS_SBAR); + + flashon = 0; + // items + for (i = 0; i < 6; i++) + { + if (cl.items & (1<<(17+i))) + { + time = cl.item_gettime[17+i]; + if (time && time > cl.time - 2 && flashon) + { // flash frame + sb_updates = 0; + } + else + { + //MED 01/04/97 changed keys + if (!hipnotic || (i > 1)) + { + Sbar_DrawPic (192 + i*16, -16, sb_items[i]); + } + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + //MED 01/04/97 added hipnotic items + // hipnotic items + if (hipnotic) + { + for (i = 0; i < 2; i++) + { + if (cl.items & (1<<(24+i))) + { + time = cl.item_gettime[24+i]; + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, hsb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } + + if (rogue) + { + // new rogue items + for (i = 0; i < 2; i++) + { + if (cl.items & (1<<(29+i))) + { + time = cl.item_gettime[29+i]; + if (time && time > cl.time - 2 && flashon) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } +} + /* =============== Sbar_DrawInventory2 @@ -1009,6 +1250,7 @@ static void Sbar_DrawSigils (void) for (i = 0; i < 4; i++) if (cl.items & (1<<(28+i))) t = q_max (t, cl.item_gettime[28+i]); + t = q_max (t, cl.spawntime); if (!sb_showscores && (cl.time - t > 3.f || scr_viewsize.value >= 120)) return; @@ -1028,7 +1270,7 @@ static void Sbar_DrawSigils (void) { if (cl.items & (1<<(28+i))) { - t = (cl.time - cl.item_gettime[28+i]); + t = (cl.time - q_max (cl.item_gettime[28+i], cl.spawntime)); t = q_max (t, 0.f); if (t >= 1.f) t = 1.f; @@ -1089,6 +1331,53 @@ void Sbar_DrawFrags (void) } } +/* +================ +Sbar_DrawFragsQW +================ +*/ +void Sbar_DrawFragsQW(void) +{ + int numscores, i, x, color; + char num[12]; + scoreboard_t *s; + + Sbar_SortFrags(); + + // draw the text + numscores = q_min(scoreboardlines, 4); + + for (i = 0, x = -88 + ( (4 - numscores) * 32) ; i < numscores; i++, x += 32) // fill from the right + { + s = &cl.scores[fragsort[i]]; + if (!s->name[0]) + continue; + + // top color + color = s->colors & 0xf0; + color = Sbar_ColorForMap(color); + Draw_Fill(x + 10, 0, 28, 4, color, 1); + + // bottom color + color = (s->colors & 15) << 4; + color = Sbar_ColorForMap(color); + Draw_Fill(x + 10, 4, 28, 3, color, 1); + + // number + sprintf(num, "%3i", s->frags); + Sbar_DrawCharacter(x + 12, -25, num[0]); + Sbar_DrawCharacter(x + 20, -25, num[1]); + Sbar_DrawCharacter(x + 28, -25, num[2]); + + // brackets + if (fragsort[i] == cl.viewentity - 1) + { + Sbar_DrawCharacter(x + 6, -25, 16); + Sbar_DrawCharacter(x + 32, -25, 17); + } + } +} + /* =============== Sbar_DrawFrags2 @@ -1397,15 +1686,34 @@ void Sbar_Draw (void) invuln = (cl.items & IT_INVULNERABILITY) != 0; armor = invuln ? 666 : cl.stats[STAT_ARMOR]; - if (scr_hudstyle.value < 1) + if (scr_hudstyle.value < 1 || scr_hudstyle.value > 2) { GL_SetCanvas (CANVAS_SBAR); //johnfitz - if (scr_viewsize.value < 110) //johnfitz -- check viewsize instead of sb_lines + if (scr_hudstyle.value < 1) //classic hud { - Sbar_DrawInventory (); - if (cl.maxclients != 1) - Sbar_DrawFrags (); + if (scr_viewsize.value < 110) //johnfitz -- check viewsize instead of sb_lines + { + Sbar_DrawInventory (); + if (cl.maxclients != 1) + Sbar_DrawFrags (); + } + } + else //qw hud + { + if (scr_viewsize.value < 120) + { + Sbar_DrawInventoryQW(); + } + if (cl.maxclients != 1 && scr_viewsize.value < 110) // qw hides frag count if MiniDeathmatchOverlay is showing + { + if (!Sbar_MiniScoreboardSizeCheck() || cl.gametype != GAME_DEATHMATCH) + { + GL_SetCanvas(CANVAS_SBAR_QW_INV); + Sbar_DrawFragsQW(); + GL_SetCanvas(CANVAS_SBAR); + } + } } if (sb_showscores || cl.stats[STAT_HEALTH] <= 0) @@ -1416,7 +1724,8 @@ void Sbar_Draw (void) } else if (scr_viewsize.value < 120) //johnfitz -- check viewsize instead of sb_lines { - Sbar_DrawPicAlpha (0, 0, sb_sbar, scr_sbaralpha.value); //johnfitz -- scr_sbaralpha + if (scr_hudstyle.value < 1) + Sbar_DrawPicAlpha (0, 0, sb_sbar, scr_sbaralpha.value); //johnfitz -- scr_sbaralpha // keys (hipnotic only) //MED 01/04/97 moved keys here so they would not be overwritten @@ -1581,6 +1890,8 @@ void Sbar_IntermissionText (int x, int y, const char *str, int color) while (*str) { qpic_t *pic = Sbar_IntermissionPicForChar (*str++, color); + if (!pic) + continue; Draw_Pic (x, y, pic); x += pic ? pic->width : 24; } @@ -1676,13 +1987,9 @@ void Sbar_MiniDeathmatchOverlay (void) { int i, k, top, bottom, x, y, f, numlines; char num[12]; - float scale; //johnfitz scoreboard_t *s; - scale = CLAMP (1.0f, scr_sbarscale.value, (float)glwidth / 320.0f); //johnfitz - - //MAX_SCOREBOARDNAME = 32, so total width for this overlay plus sbar is 632, but we can cut off some i guess - if (glwidth/scale < 512 || scr_viewsize.value >= 120) //johnfitz -- test should consider scr_sbarscale + if (!Sbar_MiniScoreboardSizeCheck()) return; // scores @@ -1790,12 +2097,12 @@ void Sbar_IntermissionOverlay (void) GL_SetCanvas (CANVAS_MENU); //johnfitz - q_snprintf (time, sizeof (time), "%d:%02d", cl.completed_time/60, cl.completed_time%60); - q_snprintf (secrets, sizeof (secrets), "%d/%2d", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); - q_snprintf (monsters, sizeof (monsters), "%d/%2d", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); + q_snprintf (time, sizeof (time), "%d:%02d", cl.completed_time / 60, cl.completed_time % 60); + q_snprintf (secrets, sizeof (secrets), "%d/%2d", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); + q_snprintf (monsters, sizeof (monsters), "%d/%2d", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); - ltime = Sbar_IntermissionTextWidth (time, 0); - lsecrets = Sbar_IntermissionTextWidth (secrets, 0); + ltime = Sbar_IntermissionTextWidth (time, 0); + lsecrets = Sbar_IntermissionTextWidth (secrets, 0); lmonsters = Sbar_IntermissionTextWidth (monsters, 0); total = q_max (ltime, lsecrets); @@ -1804,14 +2111,14 @@ void Sbar_IntermissionOverlay (void) pic = Draw_CachePic ("gfx/inter.lmp"); total += pic->width + 24; total = q_min (320, total); - Draw_Pic (160 - total/2, 56, pic); + Draw_Pic (160 - total / 2, 56, pic); pic = Draw_CachePic ("gfx/complete.lmp"); - Draw_Pic (160 - pic->width/2, 24, pic); + Draw_Pic (160 - pic->width / 2, 24, pic); - Sbar_IntermissionText (160 + total/2 - ltime, 64, time, 0); - Sbar_IntermissionText (160 + total/2 - lsecrets, 104, secrets, 0); - Sbar_IntermissionText (160 + total/2 - lmonsters, 144, monsters, 0); + Sbar_IntermissionText (160 + total / 2 - ltime, 64, time, 0); + Sbar_IntermissionText (160 + total / 2 - lsecrets, 104, secrets, 0); + Sbar_IntermissionText (160 + total / 2 - lmonsters, 144, monsters, 0); } diff --git a/Quake/screen.h b/Quake/screen.h index f655f7e89..bbcde4d1c 100644 --- a/Quake/screen.h +++ b/Quake/screen.h @@ -58,6 +58,7 @@ typedef enum { CANVAS_CONSOLE, CANVAS_MENU, CANVAS_SBAR, + CANVAS_SBAR_QW_INV, CANVAS_SBAR2, CANVAS_CROSSHAIR, CANVAS_BOTTOMLEFT, diff --git a/Quake/server.h b/Quake/server.h index 4c8ebc1f0..59af5e6c4 100644 --- a/Quake/server.h +++ b/Quake/server.h @@ -20,8 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _QUAKE_SERVER_H -#define _QUAKE_SERVER_H +#ifndef QUAKE_SERVER_H +#define QUAKE_SERVER_H // server.h @@ -103,18 +103,20 @@ typedef struct #define NUM_PING_TIMES 16 +enum sendsignon_e +{ + PRESPAWN_DONE, + PRESPAWN_FLUSH=1, + PRESPAWN_SIGNONBUFS, + PRESPAWN_SIGNONMSG, +}; + typedef struct client_s { qboolean active; // false = client is free qboolean spawned; // false = don't send datagrams qboolean dropasap; // has been told to go to another level - enum - { - PRESPAWN_DONE, - PRESPAWN_FLUSH=1, - PRESPAWN_SIGNONBUFS, - PRESPAWN_SIGNONMSG, - } sendsignon; // only valid before spawned + enum sendsignon_e sendsignon; // only valid before spawned int signonidx; double last_message; // reliable messages must be sent @@ -150,62 +152,84 @@ typedef struct client_s //============================================================================= // edict->movetype values -#define MOVETYPE_NONE 0 // never moves -#define MOVETYPE_ANGLENOCLIP 1 -#define MOVETYPE_ANGLECLIP 2 -#define MOVETYPE_WALK 3 // gravity -#define MOVETYPE_STEP 4 // gravity, special edge handling -#define MOVETYPE_FLY 5 -#define MOVETYPE_TOSS 6 // gravity -#define MOVETYPE_PUSH 7 // no clip to world, push and crush -#define MOVETYPE_NOCLIP 8 -#define MOVETYPE_FLYMISSILE 9 // extra size to monsters -#define MOVETYPE_BOUNCE 10 -#define MOVETYPE_GIB 11 // 2021 rerelease gibs +typedef enum +{ + MOVETYPE_NONE = 0, // never moves + MOVETYPE_ANGLENOCLIP = 1, + MOVETYPE_ANGLECLIP = 2, + MOVETYPE_WALK = 3, // gravity + MOVETYPE_STEP = 4, // gravity, special edge handling + MOVETYPE_FLY = 5, + MOVETYPE_TOSS = 6, // gravity + MOVETYPE_PUSH = 7, // no clip to world, push and crush + MOVETYPE_NOCLIP = 8, + MOVETYPE_FLYMISSILE = 9, // extra size to monsters + MOVETYPE_BOUNCE = 10, + MOVETYPE_GIB = 11, // 2021 rerelease gibs +} emovetype_t; // edict->solid values -#define SOLID_NOT 0 // no interaction with other objects -#define SOLID_TRIGGER 1 // touch on edge, but not blocking -#define SOLID_BBOX 2 // touch on edge, block -#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground -#define SOLID_BSP 4 // bsp clip, touch on edge, block +typedef enum +{ + SOLID_NOT = 0, // no interaction with other objects + SOLID_TRIGGER = 1, // touch on edge, but not blocking + SOLID_BBOX = 2, // touch on edge, block + SOLID_SLIDEBOX = 3, // touch on edge, but not an onground + SOLID_BSP = 4, // bsp clip, touch on edge, block +} esolid_t; // edict->deadflag values -#define DEAD_NO 0 -#define DEAD_DYING 1 -#define DEAD_DEAD 2 +typedef enum +{ + DEAD_NO = 0, + DEAD_DYING = 1, + DEAD_DEAD = 2, +} edeadflag_t; -#define DAMAGE_NO 0 -#define DAMAGE_YES 1 -#define DAMAGE_AIM 2 +// edict->takedamage +typedef enum +{ + DAMAGE_NO = 0, + DAMAGE_YES = 1, + DAMAGE_AIM = 2, +} etakedamage_t; // edict->flags -#define FL_FLY 1 -#define FL_SWIM 2 -//#define FL_GLIMPSE 4 -#define FL_CONVEYOR 4 -#define FL_CLIENT 8 -#define FL_INWATER 16 -#define FL_MONSTER 32 -#define FL_GODMODE 64 -#define FL_NOTARGET 128 -#define FL_ITEM 256 -#define FL_ONGROUND 512 -#define FL_PARTIALGROUND 1024 // not all corners are valid -#define FL_WATERJUMP 2048 // player jumping out of water -#define FL_JUMPRELEASED 4096 // for jump debouncing +typedef enum +{ + FL_FLY = 1, + FL_SWIM = 2, +// FL_GLIMPSE = 4, + FL_CONVEYOR = 4, + FL_CLIENT = 8, + FL_INWATER = 16, + FL_MONSTER = 32, + FL_GODMODE = 64, + FL_NOTARGET = 128, + FL_ITEM = 256, + FL_ONGROUND = 512, + FL_PARTIALGROUND = 1024, // not all corners are valid + FL_WATERJUMP = 2048, // player jumping out of water + FL_JUMPRELEASED = 4096, // for jump debouncing +} eflags_t; // entity effects - -#define EF_BRIGHTFIELD 1 -#define EF_MUZZLEFLASH 2 -#define EF_BRIGHTLIGHT 4 -#define EF_DIMLIGHT 8 - -#define SPAWNFLAG_NOT_EASY 256 -#define SPAWNFLAG_NOT_MEDIUM 512 -#define SPAWNFLAG_NOT_HARD 1024 -#define SPAWNFLAG_NOT_DEATHMATCH 2048 +typedef enum +{ + EF_BRIGHTFIELD = 1, + EF_MUZZLEFLASH = 2, + EF_BRIGHTLIGHT = 4, + EF_DIMLIGHT = 8, +} efx_t; + +// spawnflags +typedef enum +{ + SPAWNFLAG_NOT_EASY = 256, + SPAWNFLAG_NOT_MEDIUM = 512, + SPAWNFLAG_NOT_HARD = 1024, + SPAWNFLAG_NOT_DEATHMATCH = 2048, +} spawnflags_t; //============================================================================ @@ -261,8 +285,7 @@ void SV_MoveToGoal (void); void SV_CheckForNewClients (void); void SV_RunClients (void); -void SV_SaveSpawnparms (); +void SV_SaveSpawnparms (void); void SV_SpawnServer (const char *server); -#endif /* _QUAKE_SERVER_H */ - +#endif /* QUAKE_SERVER_H */ diff --git a/Quake/snd_dma.c b/Quake/snd_dma.c index e9bb7e132..2125fa722 100644 --- a/Quake/snd_dma.c +++ b/Quake/snd_dma.c @@ -1043,7 +1043,7 @@ static void S_SoundList (void) int i; sfx_t *sfx; sfxcache_t *sc; - int size, total; + int size, total; total = 0; for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) @@ -1086,12 +1086,10 @@ void S_ClearPrecache (void) { } - void S_BeginPrecaching (void) { } - void S_EndPrecaching (void) { } diff --git a/Quake/snd_xmp.c b/Quake/snd_xmp.c index d73149db8..3e9fd9b4a 100644 --- a/Quake/snd_xmp.c +++ b/Quake/snd_xmp.c @@ -26,7 +26,7 @@ #include "snd_codec.h" #include "snd_codeci.h" #include "snd_xmp.h" -#if defined(_WIN32) && defined(XMP_NO_DLL) +#if defined(_WIN32) && defined(LIBXMP_STATIC) #define BUILDING_STATIC #endif #include <xmp.h> diff --git a/Quake/spritegn.h b/Quake/spritegn.h index 1065052f0..817484286 100644 --- a/Quake/spritegn.h +++ b/Quake/spritegn.h @@ -104,7 +104,7 @@ typedef struct { float interval; } dspriteinterval_t; -typedef enum { SPR_SINGLE=0, SPR_GROUP } spriteframetype_t; +typedef enum { SPR_SINGLE=0, SPR_GROUP, SPR_ANGLED } spriteframetype_t; typedef struct { spriteframetype_t type; diff --git a/Quake/strl_fn.h b/Quake/strl_fn.h index af7fc146f..3be2a32a1 100644 --- a/Quake/strl_fn.h +++ b/Quake/strl_fn.h @@ -1,11 +1,16 @@ -/* header file for BSD strlcat and strlcpy */ +/* strl_fn.h - header file for BSD strlcat and strlcpy */ #ifndef __STRLFUNCS_H #define __STRLFUNCS_H /* use our own copies of strlcpy and strlcat taken from OpenBSD */ +#ifdef __cplusplus +extern "C" { +#endif extern size_t q_strlcpy (char *dst, const char *src, size_t size); extern size_t q_strlcat (char *dst, const char *src, size_t size); +#ifdef __cplusplus +} +#endif #endif /* __STRLFUNCS_H */ - diff --git a/Quake/sv_main.c b/Quake/sv_main.c index bdd0c5a46..e4d03ec9a 100644 --- a/Quake/sv_main.c +++ b/Quake/sv_main.c @@ -456,7 +456,7 @@ void SV_SendServerinfo (client_t *client) MSG_WriteByte (&client->message, svc_signonnum); MSG_WriteByte (&client->message, 1); - client->sendsignon = true; + client->sendsignon = PRESPAWN_FLUSH; client->spawned = false; // need prespawn, spawn, etc } diff --git a/Quake/sys.h b/Quake/sys.h index b5f97bb97..fa5b38210 100644 --- a/Quake/sys.h +++ b/Quake/sys.h @@ -126,5 +126,14 @@ void Sys_SendKeyEvents (void); void Sys_ActivateKeyFilter (qboolean active); +static inline qboolean Sys_IsPathSep (char c) +{ +#ifdef _WIN32 + return c == '/' || c == '\\'; +#else + return c == '/'; +#endif +} + #endif /* _QUAKE_SYS_H */ diff --git a/Quake/sys_sdl_unix.c b/Quake/sys_sdl_unix.c index cad59d92b..85d51b551 100644 --- a/Quake/sys_sdl_unix.c +++ b/Quake/sys_sdl_unix.c @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <errno.h> #include <unistd.h> #include <string.h> -#ifdef PLATFORM_OSX +#if defined(PLATFORM_OSX) || defined(PLATFORM_HAIKU) #include <libgen.h> /* dirname() and basename() */ #endif #include <sys/stat.h> @@ -53,6 +53,7 @@ qboolean isDedicated; #define MAX_HANDLES 32 /* johnfitz -- was 10 */ static FILE *sys_handles[MAX_HANDLES]; +static qboolean stdinIsATTY; /* from ioquake3 source */ static double rcp_counter_freq; @@ -360,6 +361,23 @@ static char cwd[MAX_OSPATH]; #ifdef DO_USERDIRS static char userdir[MAX_OSPATH]; +#ifdef PLATFORM_HAIKU +#include <FindDirectory.h> +#include <fs_info.h> + +static void Sys_GetUserdir (char *dst, size_t dstsize) +{ + dev_t volume = dev_for_path("/boot"); + char buffer[B_PATH_NAME_LENGTH]; + status_t result; + + result = find_directory(B_USER_NONPACKAGED_DATA_DIRECTORY, volume, false, buffer, sizeof(buffer)); + if (result != B_OK) + Sys_Error ("Couldn't determine userspace directory"); + + q_snprintf (dst, dstsize, "%s/%s", buffer, SYS_USERDIR); +} +#else static void Sys_GetUserdir (char *dst, size_t dstsize) { size_t n; @@ -386,6 +404,7 @@ static void Sys_GetUserdir (char *dst, size_t dstsize) q_snprintf (dst, dstsize, "%s/%s", home_dir, SYS_USERDIR); } +#endif /* PLATFORM_HAIKU */ #endif /* DO_USERDIRS */ qboolean Sys_GetAltUserPrefDir (qboolean remastered, char *dst, size_t dstsize) @@ -529,6 +548,21 @@ static void Sys_GetBasedir (char *argv0, char *dst, size_t dstsize) { char *tmp; + #ifdef PLATFORM_HAIKU + if (realpath(argv0, dst) == NULL) + { + perror("realpath"); + if (getcwd(dst, dstsize - 1) == NULL) + _fail: Sys_Error ("Couldn't determine current directory"); + } + else + { + /* strip off the binary name */ + if (! (tmp = strdup (dst))) goto _fail; + q_strlcpy (dst, dirname(tmp), dstsize); + free (tmp); + } + #else if (getcwd(dst, dstsize - 1) == NULL) Sys_Error ("Couldn't determine current directory"); @@ -541,6 +575,7 @@ static void Sys_GetBasedir (char *argv0, char *dst, size_t dstsize) if (tmp != dst && *tmp == '/') *tmp = 0; } + #endif } #endif @@ -644,6 +679,12 @@ void Sys_FindClose (findfile_t *find) void Sys_Init (void) { + const char* term = getenv("TERM"); + stdinIsATTY = isatty(STDIN_FILENO) && + !(term && (!strcmp(term, "raw") || !strcmp(term, "dumb"))); + if (!stdinIsATTY) + Sys_Printf("Terminal input not available.\n"); + memset (cwd, 0, sizeof(cwd)); Sys_GetBasedir(host_parms->argv[0], cwd, sizeof(cwd)); host_parms->basedir = cwd; @@ -715,6 +756,9 @@ void Sys_Printf (const char *fmt, ...) UTF8_FromQuake (u8text, sizeof (u8text), qtext); printf ("%s", u8text); + + // log all messages to file as well if -condebug was specified + Con_DebugLog (u8text); } void Sys_Quit (void) @@ -731,12 +775,16 @@ double Sys_DoubleTime (void) const char *Sys_ConsoleInput (void) { + static qboolean con_eof = false; static char con_text[256]; static int textlen; char c; fd_set set; struct timeval timeout; + if (!stdinIsATTY || con_eof) + return NULL; + FD_ZERO (&set); FD_SET (0, &set); // stdin timeout.tv_sec = 0; @@ -744,7 +792,13 @@ const char *Sys_ConsoleInput (void) while (select (1, &set, NULL, NULL, &timeout)) { - read (0, &c, 1); + if (read(0, &c, 1) <= 0) + { + // Finish processing whatever is already in the + // buffer (if anything), then stop reading + con_eof = true; + c = '\n'; + } if (c == '\n' || c == '\r') { con_text[textlen] = '\0'; diff --git a/Quake/sys_sdl_win.c b/Quake/sys_sdl_win.c index 4d21b3a27..caec34646 100644 --- a/Quake/sys_sdl_win.c +++ b/Quake/sys_sdl_win.c @@ -912,6 +912,10 @@ void Sys_Printf (const char *fmt, ...) va_end (argptr); UTF8_FromQuake (u8text, sizeof (u8text), qtext); + + // log all messages to file as well if -condebug was specified + Con_DebugLog (u8text); + len = MultiByteToWideChar (CP_UTF8, 0, u8text, -1, wtext, countof (wtext)); if (!len) return; diff --git a/Quake/vid.h b/Quake/vid.h index 5134d8208..efac76047 100644 --- a/Quake/vid.h +++ b/Quake/vid.h @@ -89,6 +89,7 @@ typedef enum { MOUSECURSOR_DEFAULT, MOUSECURSOR_HAND, + MOUSECURSOR_IBEAM, } mousecursor_t; void *VID_GetWindow (void); diff --git a/Quake/view.c b/Quake/view.c index 538e647c4..1ba4e4c4e 100644 --- a/Quake/view.c +++ b/Quake/view.c @@ -68,10 +68,6 @@ cvar_t gl_cshiftpercent_powerup = {"gl_cshiftpercent_powerup", "100", CVAR_NONE} cvar_t r_viewmodel_quake = {"r_viewmodel_quake", "0", CVAR_ARCHIVE}; -float v_dmg_time, v_dmg_roll, v_dmg_pitch; - -extern int in_forward, in_forward2, in_back; - vec3_t v_punchangles[2]; //johnfitz -- copied from cl.punchangle. 0 is current, 1 is previous value. never the same unless map just loaded /* @@ -253,10 +249,12 @@ void V_DriftPitch (void) ============================================================================== */ -cshift_t cshift_empty = { {130,80,50}, 0 }; -cshift_t cshift_water = { {130,80,50}, 128 }; -cshift_t cshift_slime = { {0,25,5}, 150 }; -cshift_t cshift_lava = { {255,80,0}, 150 }; +static cshift_t cshift_empty = { {130,80,50}, 0 }; +static cshift_t cshift_water = { {130,80,50}, 128 }; +static cshift_t cshift_slime = { {0,25,5}, 150 }; +static cshift_t cshift_lava = { {255,80,0}, 150 }; + +static float v_dmg_time, v_dmg_roll, v_dmg_pitch; float v_blend[4]; // rgba 0.0 - 1.0; see note in V_PolyBlend for more info diff --git a/Quake/zone.h b/Quake/zone.h index 393e322fe..74da9c741 100644 --- a/Quake/zone.h +++ b/Quake/zone.h @@ -91,10 +91,16 @@ Zone block void Memory_Init (void *buf, int size); +#ifdef __cplusplus +extern "C" { +#endif void Z_Free (void *ptr); void *Z_Malloc (int size); // returns 0 filled memory void *Z_Realloc (void *ptr, int size); char *Z_Strdup (const char *s); +#ifdef __cplusplus +} +#endif void *Hunk_Alloc (int size); // returns 0 filled memory void *Hunk_AllocName (int size, const char *name); diff --git a/Quakespasm.html b/Quakespasm.html index e35575765..12ce9279d 100644 --- a/Quakespasm.html +++ b/Quakespasm.html @@ -7,8 +7,7 @@ <BODY> <H1>QuakeSpasm</H1> -<H2></H2> -<P><EM>Page last edited: October 2022.</EM></P> +<P><EM>Page last edited: September 2023.</EM></P> <P> <H2><A NAME="toc1">1.</A> <A HREF="Quakespasm.html#s1">About</A></H2> @@ -31,33 +30,35 @@ <H2><A NAME="toc4">4.</A> <A HREF="Quakespasm.html#s4">Compiling and Installatio <P> <H2><A NAME="toc5">5.</A> <A HREF="Quakespasm.html#s5">Changes</A></H2> <UL> -<LI><A NAME="toc5.1">5.1</A> <A HREF="Quakespasm.html#ss5.1">Changes in 0.95.1</A> -<LI><A NAME="toc5.2">5.2</A> <A HREF="Quakespasm.html#ss5.2">Changes in 0.95.0</A> -<LI><A NAME="toc5.3">5.3</A> <A HREF="Quakespasm.html#ss5.3">Changes in 0.94.7</A> -<LI><A NAME="toc5.4">5.4</A> <A HREF="Quakespasm.html#ss5.4">Changes in 0.94.6</A> -<LI><A NAME="toc5.5">5.5</A> <A HREF="Quakespasm.html#ss5.5">Changes in 0.94.5</A> -<LI><A NAME="toc5.6">5.6</A> <A HREF="Quakespasm.html#ss5.6">Changes in 0.94.4</A> -<LI><A NAME="toc5.7">5.7</A> <A HREF="Quakespasm.html#ss5.7">Changes in 0.94.3</A> -<LI><A NAME="toc5.8">5.8</A> <A HREF="Quakespasm.html#ss5.8">Changes in 0.94.2</A> -<LI><A NAME="toc5.9">5.9</A> <A HREF="Quakespasm.html#ss5.9">Changes in 0.94.1</A> -<LI><A NAME="toc5.10">5.10</A> <A HREF="Quakespasm.html#ss5.10">Changes in 0.94.0</A> -<LI><A NAME="toc5.11">5.11</A> <A HREF="Quakespasm.html#ss5.11">Changes in 0.93.2</A> -<LI><A NAME="toc5.12">5.12</A> <A HREF="Quakespasm.html#ss5.12">Changes in 0.93.1</A> -<LI><A NAME="toc5.13">5.13</A> <A HREF="Quakespasm.html#ss5.13">Changes in 0.93.0</A> -<LI><A NAME="toc5.14">5.14</A> <A HREF="Quakespasm.html#ss5.14">Changes in 0.92.1</A> -<LI><A NAME="toc5.15">5.15</A> <A HREF="Quakespasm.html#ss5.15">Changes in 0.92.0</A> -<LI><A NAME="toc5.16">5.16</A> <A HREF="Quakespasm.html#ss5.16">Changes in 0.91.0</A> -<LI><A NAME="toc5.17">5.17</A> <A HREF="Quakespasm.html#ss5.17">Changes in 0.90.1</A> -<LI><A NAME="toc5.18">5.18</A> <A HREF="Quakespasm.html#ss5.18">Changes in 0.90.0</A> -<LI><A NAME="toc5.19">5.19</A> <A HREF="Quakespasm.html#ss5.19">Changes in 0.85.9</A> -<LI><A NAME="toc5.20">5.20</A> <A HREF="Quakespasm.html#ss5.20">Changes in 0.85.8</A> -<LI><A NAME="toc5.21">5.21</A> <A HREF="Quakespasm.html#ss5.21">Changes in 0.85.7</A> -<LI><A NAME="toc5.22">5.22</A> <A HREF="Quakespasm.html#ss5.22">Changes in 0.85.6</A> -<LI><A NAME="toc5.23">5.23</A> <A HREF="Quakespasm.html#ss5.23">Changes in 0.85.5</A> -<LI><A NAME="toc5.24">5.24</A> <A HREF="Quakespasm.html#ss5.24">Changes in 0.85.4</A> -<LI><A NAME="toc5.25">5.25</A> <A HREF="Quakespasm.html#ss5.25">Changes in 0.85.3</A> -<LI><A NAME="toc5.26">5.26</A> <A HREF="Quakespasm.html#ss5.26">Changes in 0.85.2</A> -<LI><A NAME="toc5.27">5.27</A> <A HREF="Quakespasm.html#ss5.27">Changes in 0.85.1</A> +<LI><A NAME="toc5.1">5.1</A> <A HREF="Quakespasm.html#ss5.1">Changes in 0.96.1</A> +<LI><A NAME="toc5.2">5.2</A> <A HREF="Quakespasm.html#ss5.2">Changes in 0.96.0</A> +<LI><A NAME="toc5.3">5.3</A> <A HREF="Quakespasm.html#ss5.3">Changes in 0.95.1</A> +<LI><A NAME="toc5.4">5.4</A> <A HREF="Quakespasm.html#ss5.4">Changes in 0.95.0</A> +<LI><A NAME="toc5.5">5.5</A> <A HREF="Quakespasm.html#ss5.5">Changes in 0.94.7</A> +<LI><A NAME="toc5.6">5.6</A> <A HREF="Quakespasm.html#ss5.6">Changes in 0.94.6</A> +<LI><A NAME="toc5.7">5.7</A> <A HREF="Quakespasm.html#ss5.7">Changes in 0.94.5</A> +<LI><A NAME="toc5.8">5.8</A> <A HREF="Quakespasm.html#ss5.8">Changes in 0.94.4</A> +<LI><A NAME="toc5.9">5.9</A> <A HREF="Quakespasm.html#ss5.9">Changes in 0.94.3</A> +<LI><A NAME="toc5.10">5.10</A> <A HREF="Quakespasm.html#ss5.10">Changes in 0.94.2</A> +<LI><A NAME="toc5.11">5.11</A> <A HREF="Quakespasm.html#ss5.11">Changes in 0.94.1</A> +<LI><A NAME="toc5.12">5.12</A> <A HREF="Quakespasm.html#ss5.12">Changes in 0.94.0</A> +<LI><A NAME="toc5.13">5.13</A> <A HREF="Quakespasm.html#ss5.13">Changes in 0.93.2</A> +<LI><A NAME="toc5.14">5.14</A> <A HREF="Quakespasm.html#ss5.14">Changes in 0.93.1</A> +<LI><A NAME="toc5.15">5.15</A> <A HREF="Quakespasm.html#ss5.15">Changes in 0.93.0</A> +<LI><A NAME="toc5.16">5.16</A> <A HREF="Quakespasm.html#ss5.16">Changes in 0.92.1</A> +<LI><A NAME="toc5.17">5.17</A> <A HREF="Quakespasm.html#ss5.17">Changes in 0.92.0</A> +<LI><A NAME="toc5.18">5.18</A> <A HREF="Quakespasm.html#ss5.18">Changes in 0.91.0</A> +<LI><A NAME="toc5.19">5.19</A> <A HREF="Quakespasm.html#ss5.19">Changes in 0.90.1</A> +<LI><A NAME="toc5.20">5.20</A> <A HREF="Quakespasm.html#ss5.20">Changes in 0.90.0</A> +<LI><A NAME="toc5.21">5.21</A> <A HREF="Quakespasm.html#ss5.21">Changes in 0.85.9</A> +<LI><A NAME="toc5.22">5.22</A> <A HREF="Quakespasm.html#ss5.22">Changes in 0.85.8</A> +<LI><A NAME="toc5.23">5.23</A> <A HREF="Quakespasm.html#ss5.23">Changes in 0.85.7</A> +<LI><A NAME="toc5.24">5.24</A> <A HREF="Quakespasm.html#ss5.24">Changes in 0.85.6</A> +<LI><A NAME="toc5.25">5.25</A> <A HREF="Quakespasm.html#ss5.25">Changes in 0.85.5</A> +<LI><A NAME="toc5.26">5.26</A> <A HREF="Quakespasm.html#ss5.26">Changes in 0.85.4</A> +<LI><A NAME="toc5.27">5.27</A> <A HREF="Quakespasm.html#ss5.27">Changes in 0.85.3</A> +<LI><A NAME="toc5.28">5.28</A> <A HREF="Quakespasm.html#ss5.28">Changes in 0.85.2</A> +<LI><A NAME="toc5.29">5.29</A> <A HREF="Quakespasm.html#ss5.29">Changes in 0.85.1</A> </UL> <P> <H2><A NAME="toc6">6.</A> <A HREF="Quakespasm.html#s6">Copyright</A></H2> @@ -129,13 +130,17 @@ <H2><A NAME="ss3.2">3.2</A> <A HREF="#toc3.2">Controller Support</A> <H3>Cvars</H3> <P> <UL> -<LI>joy_deadzone - Fraction of the stick travel to be deadzone, between 0 and 1. Default 0.175.</LI> +<LI>joy_deadzone_look - Fraction of look stick travel to be deadzone, between 0 and 1. Default is 0.175.</LI> +<LI>joy_deadzone_move - Same as above, but for the move stick. Default is 0.175.</LI> <LI>joy_deadzone_trigger - Fraction of trigger range required to register a button press on the analog triggers, between 0 and 1. Default 0.2.</LI> -<LI>joy_sensitivity_yaw/pitch - Max angular speed in degrees/second when looking. Defaults are 300 for yaw (turning left/right) and 150 for pitch (up/down).</LI> -<LI>joy_exponent - For the look stick, the stick displacement (between 0 and 1) is raised to this power. Default is 3. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed.</LI> +<LI>joy_outer_threshold_look - Outer deadzone for the look stick, between 0 and 1. Default 0.02.</LI> +<LI>joy_outer_threshold_move - Outer deadzone for the move stick, between 0 and 1. Default 0.02.</LI> +<LI>joy_sensitivity_yaw/pitch - Max angular speed in degrees/second when looking. Defaults are 240 for yaw (turning left/right) and 130 for pitch (up/down).</LI> +<LI>joy_exponent - For the look stick, the stick displacement (between 0 and 1) is raised to this power. Default is 2. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed.</LI> +<LI>joy_exponent_move - Same as joy_exponent but for the move stick. Default is 2.</LI> <LI>joy_invert - Set to 1 to invert the vertical axis of the look stick.</LI> -<LI>joy_swapmovelook - Set to 1 to swap the left and right analog stick functions. Default 0, move on the left stick, look on the right stick.</LI> -<LI>joy_enable - Set to 0 to disable controller support. Default 1.</LI> +<LI>joy_swapmovelook - Set to 1 to swap the left and right analog stick functions. Default is 0, move on the left stick, look on the right stick.</LI> +<LI>joy_enable - Set to 0 to disable controller support. Default is 1.</LI> </UL> </P> <H3>Buttons</H3> @@ -164,6 +169,7 @@ <H3>Buttons</H3> <LI>YBUTTON</LI> </UL> </P> + <P>quakespasm.pak contains a default.cfg which has been updated to give some default bindings. L/R shoulder buttons are bound to weapon switching, and L/R triggers are jump and attack.</P> <P>The controller support started as Jeremiah Sypult's implementation in Quakespasm-Rift, and also uses ideas/code from LordHavoc's DarkPlaces.</P> @@ -206,7 +212,54 @@ <H2><A NAME="ss4.4">4.4</A> <A HREF="#toc4.4">Quake '2021 re-release'</A> <H2><A NAME="s5">5.</A> <A HREF="#toc5">Changes</A></H2> -<H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Changes in 0.95.1</A> +<H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Changes in 0.96.1</A> +</H2> +<P> +<UL> +<LI> Fix demo recording as client-only after connection to server (was broken by signon changes in 0.96.0. Thanks to Jozsef Szalontai for issue report.)</LI> +<LI> Fix potential buffer overflow in COM_Parse(), e.g. with maps with oversized 'wad' fields. (Thanks to Andrei Drexler.)</LI> +<LI> Minor code cleanups.</LI> +</UL> +</P> + +<H2><A NAME="ss5.2">5.2</A> <A HREF="#toc5.2">Changes in 0.96.0</A> +</H2> +<P> +<UL> +<LI> <A HREF="https://github.com/sezero/quakespasm/pull/51">Adjustments</A> to joystick defaults and behaviour. See the <A HREF="Quakespasm.html#ss3.2">"Controller support / Cvars"</A> section above.</LI> +<LI> Fix for a mouse grabbing issue on macOS.</LI> +<LI> Add missing support for <EM>-ip</EM> command line option on unix / macOS.</LI> +<LI> Backport angled sprites code from FTEQW (spriteframetype: 2, must have 8 frames per group.)</LI> +<LI> Bump the progs execution runaway loop limit to 16M.</LI> +<LI> Add signon buffer fragmentation to fix SZ_GetSpace errors on certain maps when using protocol 999.</LI> +<LI> Increased MAX_DATAGRAM to 64000 to overcome packet overflows.</LI> +<LI> Bump the MAXALIASFRAMES limit to 1024.</LI> +<LI> Fix arrays to have proper sizes in gl mesh code, reflecting MAXALIASTRIS and MAXALIASVERTS correctly. (fixes SIGSEGV in mj4m4/mj4m5.)</LI> +<LI> Increased default value of gl_farclip to 65536.</LI> +<LI> Increase chase cam target trace distance to allow for chasecam to function in large open maps (useful e.g. for the func_vehicle mod.)</LI> +<LI> Raised default maximum number of particles to 16384 (can be set up to 32768 with -particles on the command line.)</LI> +<LI> Fix on-screen keyboard showing up suddenly on Steam Deck when starting a map.</LI> +<LI> Fix viewmodel interpolation with >10Hz animations.</LI> +<LI> Fix a memory leak when exiting game in SDL2 builds.</LI> +<LI> Fix a possible crash when handling clipboard data on macOS.</LI> +<LI> Fix a potential crash after loading of saved game.</LI> +<LI> Fix possible out-of-bound reads when handling progs type sizes.</LI> +<LI> Fix Dutch angle VP_PARALLEL_UPRIGHT sprites.</LI> +<LI> Fix an issue with lights blending by using 10 bit color depth for lightmaps. (For GLSL mode only.) Disable with "-nopackedpixels", if necessary.</LI> +<LI> No relative motions when the window is not focused.</LI> +<LI> Status bar and intermission screen tweaks.</LI> +<LI> Properly display monster counts > 3 digits.</LI> +<LI> Fix console animation with scr_conspeed <= 0.</LI> +<LI> Fix mouselook not working upon game quickload during a demo play.</LI> +<LI> Haiku operating system support.</LI> +<LI> Fix console when server is run noninteractively with stdin redirected from /dev/null.</LI> +<LI> Updated Visual Studio project files.</LI> +<LI> Minor code cleanups. Updated third party code, e.g. SDL, music codecs, etc.</LI> +<LI> Thanks to Andrei Drexler, Alexey Lysiuk, Andrey Budko, Boris I. Bendovsky, Chris Cowan, Maciej Olędzki, Simon McVittie, OscarL, Eric Wasylishen, Jaycie Ewald and Spike for patches.</LI> +</UL> +</P> + +<H2><A NAME="ss5.3">5.3</A> <A HREF="#toc5.3">Changes in 0.95.1</A> </H2> <P> <UL> @@ -220,7 +273,7 @@ <H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Changes in 0.95.1</A> </UL> </P> -<H2><A NAME="ss5.2">5.2</A> <A HREF="#toc5.2">Changes in 0.95.0</A> +<H2><A NAME="ss5.4">5.4</A> <A HREF="#toc5.4">Changes in 0.95.0</A> </H2> <P> <UL> @@ -233,7 +286,7 @@ <H2><A NAME="ss5.2">5.2</A> <A HREF="#toc5.2">Changes in 0.95.0</A> </UL> </P> -<H2><A NAME="ss5.3">5.3</A> <A HREF="#toc5.3">Changes in 0.94.7</A> +<H2><A NAME="ss5.5">5.5</A> <A HREF="#toc5.5">Changes in 0.94.7</A> </H2> <P> <UL> @@ -244,7 +297,7 @@ <H2><A NAME="ss5.3">5.3</A> <A HREF="#toc5.3">Changes in 0.94.7</A> </UL> </P> -<H2><A NAME="ss5.4">5.4</A> <A HREF="#toc5.4">Changes in 0.94.6</A> +<H2><A NAME="ss5.6">5.6</A> <A HREF="#toc5.6">Changes in 0.94.6</A> </H2> <P> <UL> @@ -257,7 +310,7 @@ <H2><A NAME="ss5.4">5.4</A> <A HREF="#toc5.4">Changes in 0.94.6</A> </UL> </P> -<H2><A NAME="ss5.5">5.5</A> <A HREF="#toc5.5">Changes in 0.94.5</A> +<H2><A NAME="ss5.7">5.7</A> <A HREF="#toc5.7">Changes in 0.94.5</A> </H2> <P> <UL> @@ -270,7 +323,7 @@ <H2><A NAME="ss5.5">5.5</A> <A HREF="#toc5.5">Changes in 0.94.5</A> </UL> </P> -<H2><A NAME="ss5.6">5.6</A> <A HREF="#toc5.6">Changes in 0.94.4</A> +<H2><A NAME="ss5.8">5.8</A> <A HREF="#toc5.8">Changes in 0.94.4</A> </H2> <P> <UL> @@ -292,7 +345,7 @@ <H2><A NAME="ss5.6">5.6</A> <A HREF="#toc5.6">Changes in 0.94.4</A> </UL> </P> -<H2><A NAME="ss5.7">5.7</A> <A HREF="#toc5.7">Changes in 0.94.3</A> +<H2><A NAME="ss5.9">5.9</A> <A HREF="#toc5.9">Changes in 0.94.3</A> </H2> <P> <UL> @@ -302,7 +355,7 @@ <H2><A NAME="ss5.7">5.7</A> <A HREF="#toc5.7">Changes in 0.94.3</A> </UL> </P> -<H2><A NAME="ss5.8">5.8</A> <A HREF="#toc5.8">Changes in 0.94.2</A> +<H2><A NAME="ss5.10">5.10</A> <A HREF="#toc5.10">Changes in 0.94.2</A> </H2> <P> <UL> @@ -313,7 +366,7 @@ <H2><A NAME="ss5.8">5.8</A> <A HREF="#toc5.8">Changes in 0.94.2</A> </UL> </P> -<H2><A NAME="ss5.9">5.9</A> <A HREF="#toc5.9">Changes in 0.94.1</A> +<H2><A NAME="ss5.11">5.11</A> <A HREF="#toc5.11">Changes in 0.94.1</A> </H2> <P> <UL> @@ -321,7 +374,7 @@ <H2><A NAME="ss5.9">5.9</A> <A HREF="#toc5.9">Changes in 0.94.1</A> </UL> </P> -<H2><A NAME="ss5.10">5.10</A> <A HREF="#toc5.10">Changes in 0.94.0</A> +<H2><A NAME="ss5.12">5.12</A> <A HREF="#toc5.12">Changes in 0.94.0</A> </H2> <P> <UL> @@ -346,7 +399,7 @@ <H2><A NAME="ss5.10">5.10</A> <A HREF="#toc5.10">Changes in 0.94.0</A> </UL> </P> -<H2><A NAME="ss5.11">5.11</A> <A HREF="#toc5.11">Changes in 0.93.2</A> +<H2><A NAME="ss5.13">5.13</A> <A HREF="#toc5.13">Changes in 0.93.2</A> </H2> <P> <UL> @@ -359,7 +412,7 @@ <H2><A NAME="ss5.11">5.11</A> <A HREF="#toc5.11">Changes in 0.93.2</A> </UL> </P> -<H2><A NAME="ss5.12">5.12</A> <A HREF="#toc5.12">Changes in 0.93.1</A> +<H2><A NAME="ss5.14">5.14</A> <A HREF="#toc5.14">Changes in 0.93.1</A> </H2> <P> <UL> @@ -373,7 +426,7 @@ <H2><A NAME="ss5.12">5.12</A> <A HREF="#toc5.12">Changes in 0.93.1</A> </UL> </P> -<H2><A NAME="ss5.13">5.13</A> <A HREF="#toc5.13">Changes in 0.93.0</A> +<H2><A NAME="ss5.15">5.15</A> <A HREF="#toc5.15">Changes in 0.93.0</A> </H2> <P> <UL> @@ -416,7 +469,7 @@ <H2><A NAME="ss5.13">5.13</A> <A HREF="#toc5.13">Changes in 0.93.0</A> </UL> </P> -<H2><A NAME="ss5.14">5.14</A> <A HREF="#toc5.14">Changes in 0.92.1</A> +<H2><A NAME="ss5.16">5.16</A> <A HREF="#toc5.16">Changes in 0.92.1</A> </H2> <P> <UL> @@ -426,7 +479,7 @@ <H2><A NAME="ss5.14">5.14</A> <A HREF="#toc5.14">Changes in 0.92.1</A> </UL> </P> -<H2><A NAME="ss5.15">5.15</A> <A HREF="#toc5.15">Changes in 0.92.0</A> +<H2><A NAME="ss5.17">5.17</A> <A HREF="#toc5.17">Changes in 0.92.0</A> </H2> <P> <UL> @@ -446,7 +499,7 @@ <H2><A NAME="ss5.15">5.15</A> <A HREF="#toc5.15">Changes in 0.92.0</A> </UL> </P> -<H2><A NAME="ss5.16">5.16</A> <A HREF="#toc5.16">Changes in 0.91.0</A> +<H2><A NAME="ss5.18">5.18</A> <A HREF="#toc5.18">Changes in 0.91.0</A> </H2> <H3>Bugfixes</H3> <P> @@ -496,7 +549,7 @@ <H3>Raised limits</H3> </UL> </P> -<H2><A NAME="ss5.17">5.17</A> <A HREF="#toc5.17">Changes in 0.90.1</A> +<H2><A NAME="ss5.19">5.19</A> <A HREF="#toc5.19">Changes in 0.90.1</A> </H2> <H3>Bugfixes</H3> <P> @@ -546,7 +599,7 @@ <H3>Code cleanup</H3> </UL> </P> -<H2><A NAME="ss5.18">5.18</A> <A HREF="#toc5.18">Changes in 0.90.0</A> +<H2><A NAME="ss5.20">5.20</A> <A HREF="#toc5.20">Changes in 0.90.0</A> </H2> <P> <UL> @@ -592,7 +645,7 @@ <H2><A NAME="ss5.18">5.18</A> <A HREF="#toc5.18">Changes in 0.90.0</A> </UL> </P> -<H2><A NAME="ss5.19">5.19</A> <A HREF="#toc5.19">Changes in 0.85.9</A> +<H2><A NAME="ss5.21">5.21</A> <A HREF="#toc5.21">Changes in 0.85.9</A> </H2> <P> <UL> @@ -616,7 +669,7 @@ <H2><A NAME="ss5.19">5.19</A> <A HREF="#toc5.19">Changes in 0.85.9</A> </UL> </P> -<H2><A NAME="ss5.20">5.20</A> <A HREF="#toc5.20">Changes in 0.85.8</A> +<H2><A NAME="ss5.22">5.22</A> <A HREF="#toc5.22">Changes in 0.85.8</A> </H2> <P> <UL> @@ -641,7 +694,7 @@ <H2><A NAME="ss5.20">5.20</A> <A HREF="#toc5.20">Changes in 0.85.8</A> </UL> </P> -<H2><A NAME="ss5.21">5.21</A> <A HREF="#toc5.21">Changes in 0.85.7</A> +<H2><A NAME="ss5.23">5.23</A> <A HREF="#toc5.23">Changes in 0.85.7</A> </H2> <P> <UL> @@ -659,7 +712,7 @@ <H2><A NAME="ss5.21">5.21</A> <A HREF="#toc5.21">Changes in 0.85.7</A> </UL> </P> -<H2><A NAME="ss5.22">5.22</A> <A HREF="#toc5.22">Changes in 0.85.6</A> +<H2><A NAME="ss5.24">5.24</A> <A HREF="#toc5.24">Changes in 0.85.6</A> </H2> <P> <UL> @@ -670,7 +723,7 @@ <H2><A NAME="ss5.22">5.22</A> <A HREF="#toc5.22">Changes in 0.85.6</A> </UL> </P> -<H2><A NAME="ss5.23">5.23</A> <A HREF="#toc5.23">Changes in 0.85.5</A> +<H2><A NAME="ss5.25">5.25</A> <A HREF="#toc5.25">Changes in 0.85.5</A> </H2> <P> <UL> @@ -689,7 +742,7 @@ <H2><A NAME="ss5.23">5.23</A> <A HREF="#toc5.23">Changes in 0.85.5</A> </UL> </P> -<H2><A NAME="ss5.24">5.24</A> <A HREF="#toc5.24">Changes in 0.85.4</A> +<H2><A NAME="ss5.26">5.26</A> <A HREF="#toc5.26">Changes in 0.85.4</A> </H2> <P> <UL> @@ -707,7 +760,7 @@ <H2><A NAME="ss5.24">5.24</A> <A HREF="#toc5.24">Changes in 0.85.4</A> </UL> </P> -<H2><A NAME="ss5.25">5.25</A> <A HREF="#toc5.25">Changes in 0.85.3</A> +<H2><A NAME="ss5.27">5.27</A> <A HREF="#toc5.27">Changes in 0.85.3</A> </H2> <P> <UL> @@ -729,7 +782,7 @@ <H2><A NAME="ss5.25">5.25</A> <A HREF="#toc5.25">Changes in 0.85.3</A> </UL> </P> -<H2><A NAME="ss5.26">5.26</A> <A HREF="#toc5.26">Changes in 0.85.2</A> +<H2><A NAME="ss5.28">5.28</A> <A HREF="#toc5.28">Changes in 0.85.2</A> </H2> <P> <UL> @@ -746,7 +799,7 @@ <H2><A NAME="ss5.26">5.26</A> <A HREF="#toc5.26">Changes in 0.85.2</A> </UL> </P> -<H2><A NAME="ss5.27">5.27</A> <A HREF="#toc5.27">Changes in 0.85.1</A> +<H2><A NAME="ss5.29">5.29</A> <A HREF="#toc5.29">Changes in 0.85.1</A> </H2> <P> <UL> diff --git a/Quakespasm.txt b/Quakespasm.txt index 9d00c4fbd..5780bf79b 100644 --- a/Quakespasm.txt +++ b/Quakespasm.txt @@ -3,7 +3,7 @@ ______________________________________________________________________ - Page last edited: October 2022. + Page last edited: September 2023. 1. About @@ -98,30 +98,42 @@ Controller Support - Cvars: - - joy_deadzone - Fraction of the stick travel to be deadzone, between - 0 and 1. Default 0.175. + - joy_deadzone_look - Fraction of look stick travel to be deadzone, + between 0 and 1. Default is 0.175. + + - joy_deadzone_move - Same as above, but for the move stick. Default + is 0.175. - joy_deadzone_trigger - Fraction of trigger range required to register a button press on the analog triggers, between 0 and 1. Default 0.2. + - joy_outer_threshold_look - Outer deadzone for the look stick, + between 0 and 1. Default 0.02. + + - joy_outer_threshold_move - Outer deadzone for the move stick, + between 0 and 1. Default 0.02. + - joy_sensitivity_yaw/pitch - Max angular speed in degrees/second - when looking. Defaults are 300 for yaw (turning left/right) and 150 + when looking. Defaults are 240 for yaw (turning left/right) and 130 for pitch (up/down). - joy_exponent - For the look stick, the stick displacement (between - 0 and 1) is raised to this power. Default is 3. A value of 1 would + 0 and 1) is raised to this power. Default is 2. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed. + - joy_exponent_move - Same as joy_exponent but for the move stick. + Default is 2. + - joy_invert - Set to 1 to invert the vertical axis of the look stick. - joy_swapmovelook - Set to 1 to swap the left and right analog stick - functions. Default 0, move on the left stick, look on the right + functions. Default is 0, move on the left stick, look on the right stick. - - joy_enable - Set to 0 to disable controller support. Default 1. + - joy_enable - Set to 0 to disable controller support. Default is 1. Controller Support - Buttons: @@ -209,6 +221,95 @@ 5. Changes + Changes in 0.96.1: + + - Fix demo recording as client-only after connection to server (was + broken by signon changes in 0.96.0. Thanks to Jozsef Szalontai for + issue report.) + + - Fix potential buffer overflow in COM_Parse(), e.g. with maps with + oversized 'wad' fields. (Thanks to Andrei Drexler.) + + - Minor code cleanups. + + + Changes in 0.96.0: + + - Adjustments to joystick defaults and behaviour. See the + "Controller support / Cvars" section above. + + - Fix for a mouse grabbing issue on macOS. + + - Add missing support for -ip command line option on unix / macOS. + + - Backport angled sprites code from FTEQW (spriteframetype: 2, must + have 8 frames per group.) + + - Bump the progs execution runaway loop limit to 16M. + + - Add signon buffer fragmentation to fix SZ_GetSpace errors on + certain maps when using protocol 999. + + - Increased MAX_DATAGRAM to 64000 to overcome packet overflows. + + - Bump the MAXALIASFRAMES limit to 1024. + + - Fix arrays to have proper sizes in gl mesh code, reflecting + MAXALIASTRIS and MAXALIASVERTS correctly. (fixes SIGSEGV in + mj4m4/mj4m5.) + + - Increased default value of gl_farclip to 65536. + + - Increase chase cam target trace distance to allow for chasecam to + function in large open maps (useful e.g. for the func_vehicle mod.) + + - Raised default maximum number of particles to 16384 (can be set + up to 32768 with -particles on the command line.) + + - Fix on-screen keyboard showing up suddenly on Steam Deck when + starting a map. + + - Fix viewmodel interpolation with >10Hz animations. + + - Fix a memory leak when exiting game in SDL2 builds. + + - Fix a possible crash when handling clipboard data on macOS. + + - Fix a potential crash after loading of saved game. + + - Fix possible out-of-bound reads when handling progs type sizes. + + - Fix Dutch angle VP_PARALLEL_UPRIGHT sprites. + + - Fix an issue with lights blending by using 10 bit color depth for + lightmaps. (For GLSL mode only.) Disable with "-nopackedpixels", + if necessary. + + - No relative motions when the window is not focused. + + - Status bar and intermission screen tweaks. + + - Properly display monster counts > 3 digits. + + - Fix console animation with scr_conspeed <= 0. + + - Fix mouselook not working upon game quickload during a demo play. + + - Haiku operating system support. + + - Fix console when server is run noninteractively with stdin + redirected from /dev/null. + + - Updated Visual Studio project files. + + - Minor code cleanups. Updated third party code, e.g. SDL, music + codecs, etc. + + - Thanks to Andrei Drexler, Alexey Lysiuk, Andrey Budko, Boris I. + Bendovsky, Chris Cowan, Maciej Olędzki, Simon McVittie, OscarL, + Eric Wasylishen, Jaycie Ewald and Spike for patches. + + Changes in 0.95.1: - Allow mixing lit and unlit textures in the same map. diff --git a/Windows/SDL2/WhatsNew.txt b/Windows/SDL2/WhatsNew.txt index 1f95f0592..1d7c27e20 100644 --- a/Windows/SDL2/WhatsNew.txt +++ b/Windows/SDL2/WhatsNew.txt @@ -1,6 +1,23 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.28.2: +--------------------------------------------------------------------------- +General: +* Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers + + +--------------------------------------------------------------------------- +2.28.0: +--------------------------------------------------------------------------- + +General: +* Added SDL_HasWindowSurface() and SDL_DestroyWindowSurface() to switch between the window surface and rendering APIs +* Added a display event SDL_DISPLAYEVENT_MOVED which is sent when the primary monitor changes or displays change position relative to each other +* Added the hint SDL_HINT_ENABLE_SCREEN_KEYBOARD to control whether the on-screen keyboard should be shown when text input is active + + --------------------------------------------------------------------------- 2.26.0: --------------------------------------------------------------------------- @@ -24,7 +41,7 @@ General: * Added access to the individual left and right gyro sensors of the combined Joy-Cons controller * Added a microsecond timestamp to SDL_SensorEvent and SDL_ControllerSensorEvent, when the hardware provides that information * Added SDL_SensorGetDataWithTimestamp() and SDL_GameControllerGetSensorDataWithTimestamp() to retrieve the last sensor data with the associated microsecond timestamp -* Added the hint SDL_HINT_HIDAPI_IGNORE_DEVICES to have the SDL HID API ignore specific devices +* Added the hint SDL_HINT_HIDAPI_IGNORE_DEVICES to have the SDL HID API ignore specific devices * SDL_GetRevision() now includes more information about the SDL build, including the git commit hash if available Windows: @@ -645,7 +662,7 @@ iOS: tvOS: * Added support for Apple TV -* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. +* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. Android: * Fixed SDL not resizing window when Android screen resolution changes @@ -790,8 +807,8 @@ Linux: * Added experimental Wayland and Mir support, disabled by default Android: -* Joystick support (minimum SDK version required to build SDL is now 12, - the required runtime version remains at 10, but on such devices joystick +* Joystick support (minimum SDK version required to build SDL is now 12, + the required runtime version remains at 10, but on such devices joystick support won't be available). * Hotplugging support for joysticks * Added a hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK to control whether the accelerometer should be listed as a 3 axis joystick, which it will by default. @@ -844,7 +861,7 @@ iOS: Android: IMPORTANT: You MUST get the updated SDLActivity.java to match C code -* Moved EGL initialization to native code +* Moved EGL initialization to native code * Fixed the accelerometer axis rotation relative to the device rotation * Fixed race conditions when handling the EGL context on pause/resume * Touch devices are available for enumeration immediately after init diff --git a/Windows/SDL2/bin/sdl2-config b/Windows/SDL2/bin/sdl2-config index 1b5111525..808f43569 100755 --- a/Windows/SDL2/bin/sdl2-config +++ b/Windows/SDL2/bin/sdl2-config @@ -40,7 +40,7 @@ while test $# -gt 0; do lib_suffix=$optarg ;; --version) - echo 2.26.3 + echo 2.28.4 ;; --cflags) echo -I${prefix}/include -Dmain=SDL_main diff --git a/Windows/SDL2/include/SDL_assert.h b/Windows/SDL2/include/SDL_assert.h index ba6dcd17c..7ce823ec5 100644 --- a/Windows/SDL2/include/SDL_assert.h +++ b/Windows/SDL2/include/SDL_assert.h @@ -55,6 +55,8 @@ assert can have unique static variables associated with it. #define SDL_TriggerBreakpoint() __builtin_debugtrap() #elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" ) #elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) #elif defined(__APPLE__) && defined(__arm__) @@ -125,12 +127,10 @@ typedef struct SDL_AssertData const struct SDL_AssertData *next; } SDL_AssertData; -#if (SDL_ASSERT_LEVEL > 0) - /* Never call this directly. Use the SDL_assert* macros. */ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, - const char *, - const char *, int) + const char *, + const char *, int) #if defined(__clang__) #if __has_feature(attribute_analyzer_noreturn) /* this tells Clang's static analysis that we're a custom assert function, @@ -151,9 +151,7 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, #define SDL_enabled_assert(condition) \ do { \ while ( !(condition) ) { \ - static struct SDL_AssertData sdl_assert_data = { \ - 0, 0, #condition, 0, 0, 0, 0 \ - }; \ + static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ continue; /* go again. */ \ @@ -164,8 +162,6 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, } \ } while (SDL_NULL_WHILE_LOOP_CONDITION) -#endif /* enabled assertions support code */ - /* Enable various levels of assertions. */ #if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ # define SDL_assert(condition) SDL_disabled_assert(condition) diff --git a/Windows/SDL2/include/SDL_atomic.h b/Windows/SDL2/include/SDL_atomic.h index 22ea0191a..1dd816a38 100644 --- a/Windows/SDL2/include/SDL_atomic.h +++ b/Windows/SDL2/include/SDL_atomic.h @@ -240,7 +240,7 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); /* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */ #if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */ -#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) +#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__) #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory") #elif (defined(__powerpc__) || defined(__powerpc64__)) #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27"); @@ -249,9 +249,8 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) #define SDL_CPUPauseInstruction() __yield() #elif defined(__WATCOMC__) && defined(__386__) - /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */ extern __inline void SDL_CPUPauseInstruction(void); - #pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h" + #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause" #else #define SDL_CPUPauseInstruction() #endif diff --git a/Windows/SDL2/include/SDL_audio.h b/Windows/SDL2/include/SDL_audio.h index 2c0f21191..ccd35982d 100644 --- a/Windows/SDL2/include/SDL_audio.h +++ b/Windows/SDL2/include/SDL_audio.h @@ -169,13 +169,13 @@ typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, * The calculated values in this structure are calculated by SDL_OpenAudio(). * * For multi-channel audio, the default SDL channel mapping is: - * 2: FL FR (stereo) - * 3: FL FR LFE (2.1 surround) - * 4: FL FR BL BR (quad) - * 5: FL FR LFE BL BR (4.1 surround) - * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) - * 7: FL FR FC LFE BC SL SR (6.1 surround) - * 8: FL FR FC LFE BL BR SL SR (7.1 surround) + * 2: FL FR (stereo) + * 3: FL FR LFE (2.1 surround) + * 4: FL FR BL BR (quad) + * 5: FL FR LFE BL BR (4.1 surround) + * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) + * 7: FL FR FC LFE BC SL SR (6.1 surround) + * 8: FL FR FC LFE BL BR SL SR (7.1 surround) */ typedef struct SDL_AudioSpec { diff --git a/Windows/SDL2/include/SDL_blendmode.h b/Windows/SDL2/include/SDL_blendmode.h index b8621165d..4ecbe5078 100644 --- a/Windows/SDL2/include/SDL_blendmode.h +++ b/Windows/SDL2/include/SDL_blendmode.h @@ -52,7 +52,7 @@ typedef enum dstA = dstA */ SDL_BLENDMODE_MUL = 0x00000008, /**< color multiply dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) - dstA = (srcA * dstA) + (dstA * (1-srcA)) */ + dstA = dstA */ SDL_BLENDMODE_INVALID = 0x7FFFFFFF /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ diff --git a/Windows/SDL2/include/SDL_endian.h b/Windows/SDL2/include/SDL_endian.h index 582c3a8b8..71bc06729 100644 --- a/Windows/SDL2/include/SDL_endian.h +++ b/Windows/SDL2/include/SDL_endian.h @@ -140,7 +140,7 @@ extern "C" { #if HAS_BUILTIN_BSWAP16 #define SDL_Swap16(x) __builtin_bswap16(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ushort) #define SDL_Swap16(x) _byteswap_ushort(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP @@ -189,7 +189,7 @@ SDL_Swap16(Uint16 x) #if HAS_BUILTIN_BSWAP32 #define SDL_Swap32(x) __builtin_bswap32(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ulong) #define SDL_Swap32(x) _byteswap_ulong(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP @@ -241,7 +241,7 @@ SDL_Swap32(Uint32 x) #if HAS_BUILTIN_BSWAP64 #define SDL_Swap64(x) __builtin_bswap64(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_uint64) #define SDL_Swap64(x) _byteswap_uint64(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP diff --git a/Windows/SDL2/include/SDL_gamecontroller.h b/Windows/SDL2/include/SDL_gamecontroller.h index d66e1b060..140054d36 100644 --- a/Windows/SDL2/include/SDL_gamecontroller.h +++ b/Windows/SDL2/include/SDL_gamecontroller.h @@ -724,10 +724,10 @@ typedef enum SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ - SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 */ - SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 */ - SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 */ - SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 */ + SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 (upper left, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 (upper right, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 (lower left, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 (lower right, facing the back) */ SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ SDL_CONTROLLER_BUTTON_MAX } SDL_GameControllerButton; diff --git a/Windows/SDL2/include/SDL_hints.h b/Windows/SDL2/include/SDL_hints.h index 1317924ee..00beef51e 100644 --- a/Windows/SDL2/include/SDL_hints.h +++ b/Windows/SDL2/include/SDL_hints.h @@ -92,7 +92,7 @@ extern "C" { * By default this hint is not set and the APK expansion files are not searched. */ #define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" - + /** * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. * @@ -132,13 +132,13 @@ extern "C" { * \brief A variable to control whether we trap the Android back button to handle it manually. * This is necessary for the right mouse button to work on some Android devices, or * to be able to trap the back button for use in your code reliably. If set to true, - * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of + * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of * SDL_SCANCODE_AC_BACK. * * The variable can be set to the following values: * "0" - Back button will be handled as usual for system. (default) * "1" - Back button will be trapped, allowing you to handle the key press - * manually. (This will also let right mouse click work on systems + * manually. (This will also let right mouse click work on systems * where the right mouse button functions as back.) * * The value of this hint is used at runtime, so it can be changed at any time. @@ -147,7 +147,7 @@ extern "C" { /** * \brief Specify an application name. - * + * * This hint lets you specify the application name sent to the OS when * required. For example, this will often appear in volume control applets for * audio streams, and in lists of applications which are inhibiting the @@ -377,6 +377,17 @@ extern "C" { */ #define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" +/** + * \brief A variable that controls whether the on-screen keyboard should be shown when text input is active + * + * The variable can be set to the following values: + * "0" - Do not show the on-screen keyboard + * "1" - Show the on-screen keyboard + * + * The default value is "1". This hint must be set before text input is activated. + */ +#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD" + /** * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs * @@ -507,7 +518,7 @@ extern "C" { /** * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. - * + * * For example, on Nintendo Switch controllers, normally you'd get: * * (Y) @@ -569,9 +580,9 @@ extern "C" { * * The variable can be set to the following values: * "0" - SDL_TEXTEDITING events are sent, and it is the application's - * responsibility to render the text from these events and + * responsibility to render the text from these events and * differentiate it somehow from committed text. (default) - * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, * and text that is being composed will be rendered in its own UI. */ #define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" @@ -996,6 +1007,15 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD" +/** + * \brief A variable controlling whether Windows.Gaming.Input should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - WGI is not used + * "1" - WGI is used (the default) + */ +#define SDL_HINT_JOYSTICK_WGI "SDL_JOYSTICK_WGI" + /** * \brief Determines whether SDL enforces that DRM master is required in order * to initialize the KMSDRM video backend. @@ -1310,6 +1330,8 @@ extern "C" { * * This variable can be one of the following values: * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" + * + * Since SDL 2.0.22 this variable accepts a comma-separated list of values above. */ #define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" @@ -1452,6 +1474,17 @@ extern "C" { */ #define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" +/** + * \brief A variable controlling whether the Metal render driver select low power device over default one + * + * This variable can be set to the following values: + * "0" - Use the prefered OS device + * "1" - Select a low power one + * + * By default the prefered OS device is used. + */ +#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE" + /** * \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS * @@ -1495,7 +1528,7 @@ extern "C" { * disabled. You should use a string that describes what your program is doing * (and, therefore, why the screensaver is disabled). For example, "Playing a * game" or "Watching a video". - * + * * Setting this to "" or leaving it unset will have SDL use a reasonable * default: "Playing a game" or something similar. * @@ -1509,13 +1542,13 @@ extern "C" { * On some platforms, like Linux, a realtime priority thread may be subject to restrictions * that require special handling by the application. This hint exists to let SDL know that * the app is prepared to handle said restrictions. - * + * * On Linux, SDL will apply the following configuration to any thread that becomes realtime: * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy, * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit. * * Exceeding this limit will result in the kernel sending SIGKILL to the app, * * Refer to the man pages for more information. - * + * * This variable can be set to the following values: * "0" - default platform specific behaviour * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy @@ -1603,7 +1636,7 @@ extern "C" { #define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" /** - * \brief A variable controlling whether the screensaver is enabled. + * \brief A variable controlling whether the screensaver is enabled. * * This variable can be set to the following values: * "0" - Disable screensaver @@ -1616,7 +1649,7 @@ extern "C" { /** * \brief Tell the video driver that we only want a double buffer. * - * By default, most lowlevel 2D APIs will use a triple buffer scheme that + * By default, most lowlevel 2D APIs will use a triple buffer scheme that * wastes no CPU time on waiting for vsync after issuing a flip, but * introduces a frame of latency. On the other hand, using a double buffer * scheme instead is recommended for cases where low latency is an important @@ -1747,9 +1780,9 @@ extern "C" { /** * \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). -* +* * If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has -* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly * created SDL_Window: * * 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is @@ -1815,13 +1848,13 @@ extern "C" { /** * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. - * + * * This variable can be set to the following values: * "0" - Disable _NET_WM_BYPASS_COMPOSITOR * "1" - Enable _NET_WM_BYPASS_COMPOSITOR - * + * * By default SDL will use _NET_WM_BYPASS_COMPOSITOR - * + * */ #define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" @@ -1955,7 +1988,29 @@ extern "C" { #define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" /** - * \brief A variable controlling whether the windows message loop is processed by SDL + * \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic). + * + * If the mnemonics are enabled, then menus can be opened by pressing the Alt + * key and the corresponding mnemonic (for example, Alt+F opens the File menu). + * However, in case an invalid mnemonic is pressed, Windows makes an audible + * beep to convey that nothing happened. This is true even if the window has + * no menu at all! + * + * Because most SDL applications don't have menus, and some want to use the Alt + * key for other purposes, SDL disables mnemonics (and the beeping) by default. + * + * Note: This also affects keyboard events: with mnemonics enabled, when a + * menu is opened from the keyboard, you will not receive a KEYUP event for + * the mnemonic key, and *might* not receive one for Alt. + * + * This variable can be set to the following values: + * "0" - Alt+mnemonic does nothing, no beeping. (default) + * "1" - Alt+mnemonic opens menus, invalid mnemonics produce a beep. + */ +#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL * * This variable can be set to the following values: * "0" - The window message loop is not run @@ -1996,7 +2051,7 @@ extern "C" { #define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL" /** - * \brief A variable to specify custom icon resource id from RC file on Windows platform + * \brief A variable to specify custom icon resource id from RC file on Windows platform */ #define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" #define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" @@ -2035,16 +2090,16 @@ extern "C" { * * This hint must be set before initializing the video subsystem. * - * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with + * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with * a DPI scale factor. - * + * * This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext) * and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel * even on high-DPI displays. - * + * * For more information, see: * https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows - * + * * This variable can be set to the following values: * "" - Do not change the DPI awareness (default). * "unaware" - Declare the process as DPI unaware. (Windows 8.1 and later). @@ -2062,16 +2117,16 @@ extern "C" { /** * \brief Uses DPI-scaled points as the SDL coordinate system on Windows. - * + * * This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere. * This means windows will be appropriately sized, even when created on high-DPI displays with scaling. - * + * * e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings, * will create a window with an 800x600 client area (in pixels). * * Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary), * and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows. - * + * * This variable can be set to the following values: * "0" - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging * between monitors with different scale factors (unless this is performed by @@ -2082,7 +2137,7 @@ extern "C" { #define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING" /** - * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden * * This variable can be set to the following values: * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) @@ -2093,7 +2148,7 @@ extern "C" { #define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" /** -* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called +* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called * * This variable can be set to the following values: * "0" - The window is activated when the SDL_ShowWindow function is called diff --git a/Windows/SDL2/include/SDL_joystick.h b/Windows/SDL2/include/SDL_joystick.h index 07d6a2e0a..b9b4f6228 100644 --- a/Windows/SDL2/include/SDL_joystick.h +++ b/Windows/SDL2/include/SDL_joystick.h @@ -44,6 +44,7 @@ #include "SDL_stdinc.h" #include "SDL_error.h" #include "SDL_guid.h" +#include "SDL_mutex.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -66,6 +67,9 @@ extern "C" { /** * The joystick structure used to identify an SDL joystick */ +#ifdef SDL_THREAD_SAFETY_ANALYSIS +extern SDL_mutex *SDL_joystick_lock; +#endif struct _SDL_Joystick; typedef struct _SDL_Joystick SDL_Joystick; @@ -131,7 +135,7 @@ typedef enum * * \since This function is available since SDL 2.0.7. */ -extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock); /** @@ -146,7 +150,7 @@ extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); * * \since This function is available since SDL 2.0.7. */ -extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock); /** * Count the number of joysticks attached to the system. @@ -284,13 +288,12 @@ extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_in /** * Get the instance ID of a joystick. * - * This can be called before any joysticks are opened. If the index is out of - * range, this function will return -1. + * This can be called before any joysticks are opened. * * \param device_index the index of the joystick to query (the N'th joystick * on the system * \returns the instance id of the selected joystick. If called on an invalid - * index, this function returns zero + * index, this function returns -1. * * \since This function is available since SDL 2.0.6. */ diff --git a/Windows/SDL2/include/SDL_keycode.h b/Windows/SDL2/include/SDL_keycode.h index 2523506d7..710622302 100644 --- a/Windows/SDL2/include/SDL_keycode.h +++ b/Windows/SDL2/include/SDL_keycode.h @@ -40,7 +40,7 @@ * an SDLK_* constant for those keys that do not generate characters. * * A special exception is the number keys at the top of the keyboard which - * always map to SDLK_0...SDLK_9, regardless of layout. + * map to SDLK_0...SDLK_9 on AZERTY layouts. */ typedef Sint32 SDL_Keycode; diff --git a/Windows/SDL2/include/SDL_main.h b/Windows/SDL2/include/SDL_main.h index 14d39f1ec..5cc8e5913 100644 --- a/Windows/SDL2/include/SDL_main.h +++ b/Windows/SDL2/include/SDL_main.h @@ -263,6 +263,13 @@ extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_fun */ extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved); +/** + * Callback from the application to let the suspend continue. + * + * \since This function is available since SDL 2.28.0. + */ +extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void); + #endif /* __GDK__ */ #ifdef __cplusplus diff --git a/Windows/SDL2/include/SDL_mouse.h b/Windows/SDL2/include/SDL_mouse.h index c5712efc5..aa0757573 100644 --- a/Windows/SDL2/include/SDL_mouse.h +++ b/Windows/SDL2/include/SDL_mouse.h @@ -198,13 +198,9 @@ extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); /** * Set relative mouse mode. * - * While the mouse is in relative mode, the cursor is hidden, and the driver - * will try to report continuous motion in the current window. Only relative - * motion events will be delivered, the mouse position will not change. - * - * Note that this function will not be able to provide continuous relative - * motion when used over Microsoft Remote Desktop, instead motion is limited - * to the bounds of the screen. + * While the mouse is in relative mode, the cursor is hidden, the mouse + * position is constrained to the window, and SDL will report continuous + * relative mouse motion even if the mouse is at the edge of the window. * * This function will flush any pending mouse motion. * @@ -389,6 +385,9 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); /** * Get the default cursor. * + * You do not have to call SDL_FreeCursor() on the return value, but it is + * safe to do so. + * * \returns the default cursor on success or NULL on failure. * * \since This function is available since SDL 2.0.0. diff --git a/Windows/SDL2/include/SDL_mutex.h b/Windows/SDL2/include/SDL_mutex.h index 54b6a53a3..e679d3808 100644 --- a/Windows/SDL2/include/SDL_mutex.h +++ b/Windows/SDL2/include/SDL_mutex.h @@ -31,6 +31,80 @@ #include "SDL_stdinc.h" #include "SDL_error.h" +/******************************************************************************/ +/* Enable thread safety attributes only with clang. + * The attributes can be safely erased when compiling with other compilers. + */ +#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \ + defined(__clang__) && (!defined(SWIG)) +#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) /* no-op */ +#endif + +#define SDL_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) + +#define SDL_SCOPED_CAPABILITY \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +#define SDL_GUARDED_BY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +#define SDL_PT_GUARDED_BY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +#define SDL_ACQUIRED_BEFORE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x)) + +#define SDL_ACQUIRED_AFTER(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x)) + +#define SDL_REQUIRES(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x)) + +#define SDL_REQUIRES_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x)) + +#define SDL_ACQUIRE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x)) + +#define SDL_ACQUIRE_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x)) + +#define SDL_RELEASE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x)) + +#define SDL_RELEASE_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x)) + +#define SDL_RELEASE_GENERIC(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x)) + +#define SDL_TRY_ACQUIRE(x, y) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y)) + +#define SDL_TRY_ACQUIRE_SHARED(x, y) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y)) + +#define SDL_EXCLUDES(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x)) + +#define SDL_ASSERT_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) + +#define SDL_ASSERT_SHARED_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) + +#define SDL_RETURN_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +#define SDL_NO_THREAD_SAFETY_ANALYSIS \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +/******************************************************************************/ + + #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus @@ -96,7 +170,7 @@ extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); * * \since This function is available since SDL 2.0.0. */ -extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex); #define SDL_mutexP(m) SDL_LockMutex(m) /** @@ -119,7 +193,7 @@ extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); * \sa SDL_LockMutex * \sa SDL_UnlockMutex */ -extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex); /** * Unlock the mutex. @@ -138,7 +212,7 @@ extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); * * \since This function is available since SDL 2.0.0. */ -extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex); +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex); #define SDL_mutexV(m) SDL_UnlockMutex(m) /** @@ -276,7 +350,7 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); * successful it will atomically decrement the semaphore value. * * \param sem the semaphore to wait on - * \param ms the length of the timeout, in milliseconds + * \param timeout the length of the timeout, in milliseconds * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not * succeed in the allotted time, or a negative error code on failure; * call SDL_GetError() for more information. @@ -290,7 +364,7 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); * \sa SDL_SemValue * \sa SDL_SemWait */ -extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms); +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout); /** * Atomically increment a semaphore's value and wake waiting threads. diff --git a/Windows/SDL2/include/SDL_opengl_glext.h b/Windows/SDL2/include/SDL_opengl_glext.h index 8527e1744..ff6ad12ce 100644 --- a/Windows/SDL2/include/SDL_opengl_glext.h +++ b/Windows/SDL2/include/SDL_opengl_glext.h @@ -1,4 +1,8 @@ -#ifndef __gl_glext_h_ +/* SDL modified the include guard to be compatible with Mesa and Apple include guards: + * - Mesa uses: __gl_glext_h_ + * - Apple uses: __glext_h_ */ +#if !defined(__glext_h_) && !defined(__gl_glext_h_) +#define __glext_h_ 1 #define __gl_glext_h_ 1 #ifdef __cplusplus diff --git a/Windows/SDL2/include/SDL_power.h b/Windows/SDL2/include/SDL_power.h index be06c8b4f..1d75704c4 100644 --- a/Windows/SDL2/include/SDL_power.h +++ b/Windows/SDL2/include/SDL_power.h @@ -48,7 +48,6 @@ typedef enum SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ } SDL_PowerState; - /** * Get the current power supply details. * @@ -65,17 +64,17 @@ typedef enum * It's possible a platform can only report battery percentage or time left * but not both. * - * \param secs seconds of battery life left, you can pass a NULL here if you - * don't care, will return -1 if we can't determine a value, or - * we're not running on a battery - * \param pct percentage of battery life left, between 0 and 100, you can pass - * a NULL here if you don't care, will return -1 if we can't - * determine a value, or we're not running on a battery + * \param seconds seconds of battery life left, you can pass a NULL here if + * you don't care, will return -1 if we can't determine a + * value, or we're not running on a battery + * \param percent percentage of battery life left, between 0 and 100, you can + * pass a NULL here if you don't care, will return -1 if we + * can't determine a value, or we're not running on a battery * \returns an SDL_PowerState enum representing the current battery state. * * \since This function is available since SDL 2.0.0. */ -extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *seconds, int *percent); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/Windows/SDL2/include/SDL_render.h b/Windows/SDL2/include/SDL_render.h index c72950142..2d3f07366 100644 --- a/Windows/SDL2/include/SDL_render.h +++ b/Windows/SDL2/include/SDL_render.h @@ -1731,6 +1731,11 @@ extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, * * \param renderer the rendering context * + * \threadsafety You may only call this function on the main thread. If this + * happens to work on a background thread on any given platform + * or backend, it's purely by luck and you should not rely on it + * to work next time. + * * \since This function is available since SDL 2.0.0. * * \sa SDL_RenderClear @@ -1885,7 +1890,7 @@ extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give * SDL a drawable to render to, which might happen if the window is * hidden/minimized/offscreen. This doesn't apply to command encoders for - * render targets, just the window's backbacker. Check your return values! + * render targets, just the window's backbuffer. Check your return values! * * \param renderer The renderer to query * \returns an `id<MTLRenderCommandEncoder>` on success, or NULL if the diff --git a/Windows/SDL2/include/SDL_revision.h b/Windows/SDL2/include/SDL_revision.h index 99af2a5b0..453ccb3d2 100644 --- a/Windows/SDL2/include/SDL_revision.h +++ b/Windows/SDL2/include/SDL_revision.h @@ -1,7 +1,7 @@ /* Generated by updaterev.sh, do not edit */ #ifdef SDL_VENDOR_INFO -#define SDL_REVISION "SDL-release-2.26.3-0-gadf31f6ec (" SDL_VENDOR_INFO ")" +#define SDL_REVISION "SDL-release-2.28.4-0-gcc016b004 (" SDL_VENDOR_INFO ")" #else -#define SDL_REVISION "SDL-release-2.26.3-0-gadf31f6ec" +#define SDL_REVISION "SDL-release-2.28.4-0-gcc016b004" #endif #define SDL_REVISION_NUMBER 0 diff --git a/Windows/SDL2/include/SDL_sensor.h b/Windows/SDL2/include/SDL_sensor.h index 3010e497e..9ecce44b1 100644 --- a/Windows/SDL2/include/SDL_sensor.h +++ b/Windows/SDL2/include/SDL_sensor.h @@ -84,7 +84,7 @@ typedef enum * The accelerometer returns the current acceleration in SI meters per * second squared. This measurement includes the force of gravity, so * a device at rest will have an value of SDL_STANDARD_GRAVITY away - * from the center of the earth. + * from the center of the earth, which is a positive Y value. * * values[0]: Acceleration on the x axis * values[1]: Acceleration on the y axis diff --git a/Windows/SDL2/include/SDL_stdinc.h b/Windows/SDL2/include/SDL_stdinc.h index bbce3d06f..182ed86ee 100644 --- a/Windows/SDL2/include/SDL_stdinc.h +++ b/Windows/SDL2/include/SDL_stdinc.h @@ -30,12 +30,6 @@ #include "SDL_config.h" -#ifdef __APPLE__ -#ifndef _DARWIN_C_SOURCE -#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */ -#endif -#endif - #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -85,7 +79,9 @@ Visual Studio. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx for more information. */ -# define _USE_MATH_DEFINES +# ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +# endif # endif # include <math.h> #endif @@ -528,9 +524,7 @@ extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, /* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) { -#ifdef __APPLE__ - memset_pattern4(dst, &val, dwords * 4); -#elif defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(__i386__) int u0, u1, u2; __asm__ __volatile__ ( "cld \n\t" @@ -694,7 +688,7 @@ extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t * outbytesleft); /** - * This function converts a string between encodings in one pass, returning a + * This function converts a buffer or string between encodings in one pass, returning a * string that must be freed with SDL_free() or NULL on error. * * \since This function is available since SDL 2.0.0. @@ -722,6 +716,20 @@ size_t strlcpy(char* dst, const char* src, size_t size); size_t strlcat(char* dst, const char* src, size_t size); #endif +#ifndef HAVE_WCSLCPY +size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size); +#endif + +#ifndef HAVE_WCSLCAT +size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size); +#endif + +/* Starting LLVM 16, the analyser errors out if these functions do not have + their prototype defined (clang-diagnostic-implicit-function-declaration) */ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + #define SDL_malloc malloc #define SDL_calloc calloc #define SDL_realloc realloc diff --git a/Windows/SDL2/include/SDL_thread.h b/Windows/SDL2/include/SDL_thread.h index 849f70bd4..b829bbad5 100644 --- a/Windows/SDL2/include/SDL_thread.h +++ b/Windows/SDL2/include/SDL_thread.h @@ -35,7 +35,7 @@ #include "SDL_atomic.h" #include "SDL_mutex.h" -#if defined(__WIN32__) || defined(__GDK__) +#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) #include <process.h> /* _beginthreadex() and _endthreadex() */ #endif #if defined(__OS2__) /* for _beginthread() and _endthread() */ @@ -88,7 +88,7 @@ typedef enum { typedef int (SDLCALL * SDL_ThreadFunction) (void *data); -#if defined(__WIN32__) || defined(__GDK__) +#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) /** * \file SDL_thread.h * diff --git a/Windows/SDL2/include/SDL_version.h b/Windows/SDL2/include/SDL_version.h index 739134a73..57c171ccd 100644 --- a/Windows/SDL2/include/SDL_version.h +++ b/Windows/SDL2/include/SDL_version.h @@ -58,8 +58,8 @@ typedef struct SDL_version /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL */ #define SDL_MAJOR_VERSION 2 -#define SDL_MINOR_VERSION 26 -#define SDL_PATCHLEVEL 3 +#define SDL_MINOR_VERSION 28 +#define SDL_PATCHLEVEL 4 /** * Macro to determine SDL version program was compiled against. diff --git a/Windows/SDL2/include/SDL_video.h b/Windows/SDL2/include/SDL_video.h index c70facb5e..c8b2d7a0d 100644 --- a/Windows/SDL2/include/SDL_video.h +++ b/Windows/SDL2/include/SDL_video.h @@ -187,7 +187,8 @@ typedef enum SDL_DISPLAYEVENT_NONE, /**< Never used */ SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */ - SDL_DISPLAYEVENT_DISCONNECTED /**< Display has been removed from the system */ + SDL_DISPLAYEVENT_DISCONNECTED, /**< Display has been removed from the system */ + SDL_DISPLAYEVENT_MOVED /**< Display has changed position */ } SDL_DisplayEventID; /** @@ -1274,6 +1275,17 @@ extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags); +/** + * Return whether the window has a surface associated with it. + * + * \returns SDL_TRUE if there is a surface associated with the window, or SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.28.0. + * + * \sa SDL_GetWindowSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window); + /** * Get the SDL surface associated with the window. * @@ -1294,6 +1306,8 @@ extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, * * \since This function is available since SDL 2.0.0. * + * \sa SDL_DestroyWindowSurface + * \sa SDL_HasWindowSurface * \sa SDL_UpdateWindowSurface * \sa SDL_UpdateWindowSurfaceRects */ @@ -1328,7 +1342,7 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); * * \param window the window to update * \param rects an array of SDL_Rect structures representing areas of the - * surface to copy + * surface to copy, in pixels * \param numrects the number of rectangles * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. @@ -1342,6 +1356,20 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, int numrects); +/** + * Destroy the surface associated with the window. + * + * \param window the window to update + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.28.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_HasWindowSurface + */ +extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window); + /** * Set a window's input grab mode. * diff --git a/Windows/SDL2/include/begin_code.h b/Windows/SDL2/include/begin_code.h index 1f01e0bc6..4142ffeba 100644 --- a/Windows/SDL2/include/begin_code.h +++ b/Windows/SDL2/include/begin_code.h @@ -28,10 +28,10 @@ */ /* This shouldn't be nested -- included it around code only. */ -#ifdef _begin_code_h +#ifdef SDL_begin_code_h #error Nested inclusion of begin_code.h #endif -#define _begin_code_h +#define SDL_begin_code_h #ifndef SDL_DEPRECATED # if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ @@ -171,17 +171,17 @@ #define SDL_FALLTHROUGH [[fallthrough]] #else #if defined(__has_attribute) -#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__) +#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__) #else -#define _HAS_FALLTHROUGH 0 +#define SDL_HAS_FALLTHROUGH 0 #endif /* __has_attribute */ -#if _HAS_FALLTHROUGH && \ +#if SDL_HAS_FALLTHROUGH && \ ((defined(__GNUC__) && __GNUC__ >= 7) || \ (defined(__clang_major__) && __clang_major__ >= 10)) #define SDL_FALLTHROUGH __attribute__((__fallthrough__)) #else #define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ -#endif /* _HAS_FALLTHROUGH */ -#undef _HAS_FALLTHROUGH +#endif /* SDL_HAS_FALLTHROUGH */ +#undef SDL_HAS_FALLTHROUGH #endif /* C++17 or C2x */ #endif /* SDL_FALLTHROUGH not defined */ diff --git a/Windows/SDL2/include/close_code.h b/Windows/SDL2/include/close_code.h index 874a926b7..b5ff3e204 100644 --- a/Windows/SDL2/include/close_code.h +++ b/Windows/SDL2/include/close_code.h @@ -26,10 +26,10 @@ * after you finish any function and structure declarations in your headers */ -#ifndef _begin_code_h +#ifndef SDL_begin_code_h #error close_code.h included without matching begin_code.h #endif -#undef _begin_code_h +#undef SDL_begin_code_h /* Reset structure packing at previous byte alignment */ #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) diff --git a/Windows/SDL2/lib/SDL2.dll b/Windows/SDL2/lib/SDL2.dll index 431a05437..b2d97acad 100644 Binary files a/Windows/SDL2/lib/SDL2.dll and b/Windows/SDL2/lib/SDL2.dll differ diff --git a/Windows/SDL2/lib/SDL2.lib b/Windows/SDL2/lib/SDL2.lib index a3583601d..b35ba62a2 100644 Binary files a/Windows/SDL2/lib/SDL2.lib and b/Windows/SDL2/lib/SDL2.lib differ diff --git a/Windows/SDL2/lib/libSDL2.dll.a b/Windows/SDL2/lib/libSDL2.dll.a index 7e5750f65..91ac2b8b9 100644 Binary files a/Windows/SDL2/lib/libSDL2.dll.a and b/Windows/SDL2/lib/libSDL2.dll.a differ diff --git a/Windows/SDL2/lib/libSDL2main.a b/Windows/SDL2/lib/libSDL2main.a index 8e67e9eda..e38628c5f 100644 Binary files a/Windows/SDL2/lib/libSDL2main.a and b/Windows/SDL2/lib/libSDL2main.a differ diff --git a/Windows/SDL2/lib64/SDL2.dll b/Windows/SDL2/lib64/SDL2.dll index 71f5b89a3..58b02a20c 100644 Binary files a/Windows/SDL2/lib64/SDL2.dll and b/Windows/SDL2/lib64/SDL2.dll differ diff --git a/Windows/SDL2/lib64/SDL2.lib b/Windows/SDL2/lib64/SDL2.lib index a237dfcda..99c5321ca 100644 Binary files a/Windows/SDL2/lib64/SDL2.lib and b/Windows/SDL2/lib64/SDL2.lib differ diff --git a/Windows/SDL2/lib64/libSDL2.dll.a b/Windows/SDL2/lib64/libSDL2.dll.a index 1aca6b8d6..fb3322496 100644 Binary files a/Windows/SDL2/lib64/libSDL2.dll.a and b/Windows/SDL2/lib64/libSDL2.dll.a differ diff --git a/Windows/SDL2/lib64/libSDL2main.a b/Windows/SDL2/lib64/libSDL2main.a index 4a1069e49..517f6a43c 100644 Binary files a/Windows/SDL2/lib64/libSDL2main.a and b/Windows/SDL2/lib64/libSDL2main.a differ diff --git a/Windows/SDL2/main/SDL_windows.h b/Windows/SDL2/main/SDL_windows.h index 13b0f2fa8..3842e082b 100644 --- a/Windows/SDL2/main/SDL_windows.h +++ b/Windows/SDL2/main/SDL_windows.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> + Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org> This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,31 +34,97 @@ #ifndef UNICODE #define UNICODE 1 #endif +#undef WINVER #undef _WIN32_WINNT -#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ +#if defined(SDL_VIDEO_RENDER_D3D12) +#define _WIN32_WINNT 0xA00 /* For D3D12, 0xA00 is required */ +#elif defined(HAVE_SHELLSCALINGAPI_H) +#define _WIN32_WINNT 0x603 /* For DPI support */ +#else +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ +#endif +#define WINVER _WIN32_WINNT + +#elif defined(__WINGDK__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#undef _WIN32_WINNT +#define _WIN32_WINNT 0xA00 +#define WINVER _WIN32_WINNT + +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#undef _WIN32_WINNT +#define _WIN32_WINNT 0xA00 +#define WINVER _WIN32_WINNT +#endif + +/* See https://github.com/libsdl-org/SDL/pull/7607 */ +/* force_align_arg_pointer attribute requires gcc >= 4.2.x. */ +#if defined(__clang__) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#endif +#if defined(__GNUC__) && defined(__i386__) && defined(HAVE_FORCE_ALIGN_ARG_POINTER) +#define MINGW32_FORCEALIGN __attribute__((force_align_arg_pointer)) +#else +#define MINGW32_FORCEALIGN #endif #include <windows.h> -#include <basetyps.h> /* for REFIID with broken mingw.org headers */ +#include <basetyps.h> /* for REFIID with broken mingw.org headers */ + +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +#ifndef DWORD_PTR +#define DWORD_PTR DWORD +#endif +#ifndef LONG_PTR +#define LONG_PTR LONG +#endif +#endif #include "SDL_rect.h" /* Routines to convert from UTF8 to native Windows text */ -#define WIN_StringToUTF8W(S) SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) -#define WIN_UTF8ToStringW(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)(S), SDL_strlen(S)+1) +#define WIN_StringToUTF8W(S) SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)(S), (SDL_wcslen(S) + 1) * sizeof(WCHAR)) +#define WIN_UTF8ToStringW(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)(S), SDL_strlen(S) + 1) /* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */ -#define WIN_StringToUTF8A(S) SDL_iconv_string("UTF-8", "ASCII", (const char *)(S), (SDL_strlen(S)+1)) -#define WIN_UTF8ToStringA(S) SDL_iconv_string("ASCII", "UTF-8", (const char *)(S), SDL_strlen(S)+1) +#define WIN_StringToUTF8A(S) SDL_iconv_string("UTF-8", "ASCII", (const char *)(S), (SDL_strlen(S) + 1)) +#define WIN_UTF8ToStringA(S) SDL_iconv_string("ASCII", "UTF-8", (const char *)(S), SDL_strlen(S) + 1) #if UNICODE #define WIN_StringToUTF8 WIN_StringToUTF8W #define WIN_UTF8ToString WIN_UTF8ToStringW -#define SDL_tcslen SDL_wcslen -#define SDL_tcsstr SDL_wcsstr +#define SDL_tcslen SDL_wcslen +#define SDL_tcsstr SDL_wcsstr #else #define WIN_StringToUTF8 WIN_StringToUTF8A #define WIN_UTF8ToString WIN_UTF8ToStringA -#define SDL_tcslen SDL_strlen -#define SDL_tcsstr SDL_strstr +#define SDL_tcslen SDL_strlen +#define SDL_tcsstr SDL_strstr +#endif + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { #endif /* Sets an error message based on a given HRESULT */ @@ -93,13 +159,21 @@ extern BOOL WIN_IsWindows8OrGreater(void); extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid); /* Checks to see if two GUID are the same. */ -extern BOOL WIN_IsEqualGUID(const GUID * a, const GUID * b); +extern BOOL WIN_IsEqualGUID(const GUID *a, const GUID *b); extern BOOL WIN_IsEqualIID(REFIID a, REFIID b); /* Convert between SDL_rect and RECT */ extern void WIN_RECTToRect(const RECT *winrect, SDL_Rect *sdlrect); extern void WIN_RectToRECT(const SDL_Rect *sdlrect, RECT *winrect); +/* Returns SDL_TRUE if the rect is empty */ +extern BOOL WIN_IsRectEmpty(const RECT *rect); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #endif /* _INCLUDED_WINDOWS_H */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Windows/SDL2/main/SDL_windows_main.c b/Windows/SDL2/main/SDL_windows_main.c index d00989c3a..0ce41a20d 100644 --- a/Windows/SDL2/main/SDL_windows_main.c +++ b/Windows/SDL2/main/SDL_windows_main.c @@ -8,7 +8,7 @@ #ifdef __WIN32__ /* Include this so we define UNICODE properly */ -#include "SDL_windows.h" /* copied here from the SDL2 source tree */ +#include "SDL_windows.h" #include <shellapi.h> /* CommandLineToArgvW() */ /* Include the SDL main definition header */ @@ -16,12 +16,11 @@ #include "SDL_main.h" #ifdef main -# undef main +#undef main #endif /* main */ /* Pop up an out of memory message, returns to Windows */ -static BOOL -OutOfMemory(void) +static BOOL OutOfMemory(void) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); return FALSE; @@ -29,16 +28,15 @@ OutOfMemory(void) #if defined(_MSC_VER) /* The VC++ compiler needs main/wmain defined */ -# define console_ansi_main main -# if UNICODE -# define console_wmain wmain -# endif +#define console_ansi_main main +#if UNICODE +#define console_wmain wmain +#endif #endif /* Gets the arguments with GetCommandLine, converts them to argc and argv and calls SDL_main */ -static int -main_getcmdline(void) +static int main_getcmdline(void) { LPWSTR *argvw; char **argv; @@ -56,17 +54,17 @@ main_getcmdline(void) /* Parse it into argv and argc */ argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); - if (!argv) { + if (argv == NULL) { return OutOfMemory(); } for (i = 0; i < argc; ++i) { DWORD len; char *arg = WIN_StringToUTF8W(argvw[i]); - if (!arg) { + if (arg == NULL) { return OutOfMemory(); } len = (DWORD)SDL_strlen(arg); - argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 1); + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)len + 1); if (!argv[i]) { return OutOfMemory(); } @@ -91,25 +89,22 @@ main_getcmdline(void) } /* This is where execution begins [console apps, ansi] */ -int -console_ansi_main(int argc, char *argv[]) +int console_ansi_main(int argc, char *argv[]) { return main_getcmdline(); } - #if UNICODE /* This is where execution begins [console apps, unicode] */ -int -console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) +int console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) { return main_getcmdline(); } #endif /* This is where execution begins [windowed apps] */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +int WINAPI MINGW32_FORCEALIGN +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) /* NOLINT(readability-inconsistent-declaration-parameter-name) */ { return main_getcmdline(); } diff --git a/Windows/SDL2/watcom/SDL2.def b/Windows/SDL2/watcom/SDL2.def index ed849a0b6..5904992bc 100644 --- a/Windows/SDL2/watcom/SDL2.def +++ b/Windows/SDL2/watcom/SDL2.def @@ -843,3 +843,6 @@ SDL_GameControllerGetSensorDataWithTimestamp SDL_SensorGetDataWithTimestamp SDL_ResetHints SDL_strcasestr +SDL_HasWindowSurface +SDL_DestroyWindowSurface + diff --git a/Windows/SDL2/watcom/SDL2.exp b/Windows/SDL2/watcom/SDL2.exp index f3b21e1c8..066acebb9 100644 --- a/Windows/SDL2/watcom/SDL2.exp +++ b/Windows/SDL2/watcom/SDL2.exp @@ -840,3 +840,5 @@ ++'_SDL_SensorGetDataWithTimestamp'.'SDL2.dll'..'SDL_SensorGetDataWithTimestamp' ++'_SDL_ResetHints'.'SDL2.dll'..'SDL_ResetHints' ++'_SDL_strcasestr'.'SDL2.dll'..'SDL_strcasestr' +++'_SDL_HasWindowSurface'.'SDL2.dll'..'SDL_HasWindowSurface' +++'_SDL_DestroyWindowSurface'.'SDL2.dll'..'SDL_DestroyWindowSurface' diff --git a/Windows/SDL2/watcom/SDL2.lib b/Windows/SDL2/watcom/SDL2.lib index badd61308..577131a7e 100644 Binary files a/Windows/SDL2/watcom/SDL2.lib and b/Windows/SDL2/watcom/SDL2.lib differ diff --git a/Windows/VisualStudio/custom_build.props b/Windows/VisualStudio/custom_build.props new file mode 100644 index 000000000..c8632be23 --- /dev/null +++ b/Windows/VisualStudio/custom_build.props @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemDefinitionGroup Condition="'$(VER_SUFFIX)' != ''"> + <ClCompile> + <AdditionalOptions>/DIRONWAIL_VER_SUFFIX=\"$(VER_SUFFIX)\" %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + </ItemDefinitionGroup> + <PropertyGroup Condition="'$(BUILD_DIR)' != ''"> + <OutDir>$(SolutionDir)$(BUILD_DIR)\</OutDir> + <IntDir>$(BUILD_DIR)\Out\</IntDir> + </PropertyGroup> +</Project> diff --git a/Windows/VisualStudio/ironwail.natvis b/Windows/VisualStudio/ironwail.natvis new file mode 100644 index 000000000..88a8be9cf --- /dev/null +++ b/Windows/VisualStudio/ironwail.natvis @@ -0,0 +1,386 @@ +<?xml version="1.0" encoding="utf-8"?> +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> + + <!-- + ================================================================================================================================ + 3D vector + ================================================================================================================================ + --> + <Type Name="float3_t"> + <DisplayString>[{data[0],g} {data[1],g} {data[2],g}]</DisplayString> + <Expand HideRawView="true"> + <Item Name="x">data[0]</Item> + <Item Name="y">data[1]</Item> + <Item Name="z">data[2]</Item> + </Expand> + </Type> + + + <!-- + ================================================================================================================================ + QuakeC function + ================================================================================================================================ + --> + <Type Name="dfunction_t"> + <!--Helpers--> + <Intrinsic Name="PR_GetString" Expression="((unsigned int)num < qcvm->stringssize) ? qcvm->strings + num : + (num < 0 && num >= -qcvm->numknownstrings) ? qcvm->knownstrings[-1 - num] : 0" ReturnType="const char*"> + <Parameter Name="num" Type="int" /> + </Intrinsic> + + <Intrinsic Name="IsBuiltin" Expression="first_statement < 0"/> + + <Intrinsic Name="IsValidBuiltin" Expression="IsBuiltin() && -first_statement < qcvm->numbuiltins"/> + + <!--Inline view - builtin--> + <DisplayString Condition="IsValidBuiltin()">#{-first_statement} {PR_GetString(s_name),sb} ({qcvm->builtins[-first_statement],na})</DisplayString> + <DisplayString Condition="IsBuiltin()">#{-first_statement} {PR_GetString(s_name),sb} (INVALID)</DisplayString> + <!--Inline view - QuakeC--> + <DisplayString>{PR_GetString(s_name),sb} ({PR_GetString(s_file),sb})</DisplayString> + + <Expand> + <Item Name="name">PR_GetString(s_name),sb</Item> + <Item Name="file">PR_GetString(s_file),sb</Item> + <Synthetic Name="type"> + <DisplayString Condition="IsBuiltin()">builtin</DisplayString> + <DisplayString>QuakeC</DisplayString> + </Synthetic> + + <Synthetic Name="id" Condition="IsBuiltin()"> + <DisplayString>#{-first_statement}</DisplayString> + </Synthetic> + <Item Name="function" Condition="IsValidBuiltin()">qcvm->builtins[-first_statement],na</Item> + <Synthetic Name="function" Condition="IsBuiltin() && !IsValidBuiltin()"> + <DisplayString>INVALID</DisplayString> + </Synthetic> + + <Item Name="[parm sizes]" Condition="numparms > 0">parm_size,[numparms]</Item> + </Expand> + </Type> + + + <!-- + ================================================================================================================================ + QuakeC field + ================================================================================================================================ + --> + <Type Name="ddef_t"> + <!--Helpers--> + <Intrinsic Name="PR_GetString" Expression="((unsigned int)num < qcvm->stringssize) ? qcvm->strings + num : + (num < 0 && num >= -qcvm->numknownstrings) ? qcvm->knownstrings[-1 - num] : 0" ReturnType="const char*"> + <Parameter Name="num" Type="int" /> + </Intrinsic> + + <Intrinsic Name="Type" Expression="(etype_t)(type & 0x7fff)" ReturnType="etype_t"/> + <Intrinsic Name="IsSaved" Expression="(type & 0x8000) != 0" ReturnType="bool"/> + + <!--Inline view--> + <DisplayString Condition="Type() == ev_void">.void {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_string">.string {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_float">.float {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_vector">.vector {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_entity">.entity {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_field">.field {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_function">.void() {PR_GetString(s_name),sb}</DisplayString> + <DisplayString Condition="Type() == ev_pointer">.pointer {PR_GetString(s_name),sb}</DisplayString> + <DisplayString>.??? {PR_GetString(s_name),sb}</DisplayString> + + <Expand> + <Item Name="name">PR_GetString(s_name),sb</Item> + <Item Name="type">Type(),en</Item> + <Item Name="saved">IsSaved()</Item> + <Item Name="offset">ofs*4</Item> + </Expand> + </Type> + + + <!-- + ================================================================================================================================ + Edict + ================================================================================================================================ + --> + <Type Name="edict_s"> + <!--Helpers--> + <Intrinsic Name="PR_GetString" Expression="((unsigned int)num < qcvm->stringssize) ? qcvm->strings + num : + (num < 0 && num >= -qcvm->numknownstrings) ? qcvm->knownstrings[-1 - num] : 0" ReturnType="const char*"> + <Parameter Name="num" Type="int" /> + </Intrinsic> + + <Intrinsic Name="EntNum" Expression="((uintptr_t)this-(uintptr_t)qcvm->edicts)/qcvm->edict_size"/> + + <Intrinsic Name="IsValidProgEnt" Expression="(uintptr_t)ofs <= (uintptr_t)((qcvm->num_edicts-1)*qcvm->edict_size)" ReturnType="bool"> + <Parameter Name="ofs" Type="int"/> + </Intrinsic> + + <Intrinsic Name="PROG_TO_EDICT" Expression="IsValidProgEnt(ofs) ? (edict_s*)((char*)qcvm->edicts + ofs) : 0" ReturnType="edict_s*"> + <Parameter Name="ofs" Type="int"/> + </Intrinsic> + + <Intrinsic Name="EDICT_TO_PROG" Expression="(uintptr_t)ent - (uintptr_t)qcvm->edicts" ReturnType="uintptr_t"> + <Parameter Name="ent" Type="edict_t*"/> + </Intrinsic> + + <Intrinsic Name="IsLinked" Expression="area.next != 0"/> + + <Intrinsic Name="HullForSize" Expression="size < 3.0 ? 0 : size <= 32.0 ? 1 : 2" ReturnType="int"> + <Parameter Name="size" Type="float"/> + </Intrinsic> + + <Intrinsic Name="IsValidFunction" Expression="(unsigned int)(num - 1) < (qcvm->progs->numfunctions - 1)" ReturnType="bool"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="GetFunction" Expression="IsValidFunction(num) ? qcvm->functions + num : 0" ReturnType="dfunction_t*"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="IsValidField" Expression="num >= 1 && num < qcvm->progs->numfielddefs"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="FieldName" Expression="PR_GetString(qcvm->fielddefs[num].s_name)"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="SafeFieldPtr" Expression="IsValidField(num) ? qcvm->fielddefs + num : 0"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="FieldType" Expression="(etype_t)(qcvm->fielddefs[num].type & 0x7FFF)"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="FieldData" Expression="((char*)&v + qcvm->fielddefs[num].ofs * 4)"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <Intrinsic Name="IsVecField" Expression=" num >= 1 && FieldType(num - 1) == ev_vector || + num >= 2 && FieldType(num - 2) == ev_vector || + num >= 3 && FieldType(num - 3) == ev_vector"> + <Parameter Name="num" Type="int"/> + </Intrinsic> + + <!--Inline view--> + <DisplayString Condition="free && IsLinked()">#{EntNum(),i} FREE LINKED</DisplayString> + <DisplayString Condition="free">#{EntNum(),i} FREE LINKED</DisplayString> + <DisplayString>#{EntNum(),i} {PR_GetString(v.classname),sb} {v.health,g}hp</DisplayString> + + <!--Expanded view--> + <Expand> + <Item Name="index">EntNum()</Item> + <Item Name="classname">PR_GetString(v.classname),s</Item> + <Item Name="free">free,en</Item> + <Item Name="linked">IsLinked(),b</Item> + + <!--Spatial properties--> + <Synthetic Name="[position]"> + <Expand> + <Item Name="solid">(esolid_t)v.solid</Item> + <Item Name="movetype">(emovetype_t)v.movetype</Item> + <Item Name="flags">(eflags_t)v.flags</Item> + <Item Name="origin">*(float3_t*)v.origin,g</Item> + <Item Name="oldorigin">*(float3_t*)v.oldorigin,g</Item> + <Item Name="angles">*(float3_t*)v.angles,g</Item> + <Item Name="fixangle">v.fixangle,g</Item> + <Item Name="v_angle">*(float3_t*)v.v_angle,g</Item> + <Item Name="view_ofs">*(float3_t*)v.view_ofs,g</Item> + <Item Name="idealpitch">v.idealpitch,g</Item> + <Item Name="punchangle">*(float3_t*)v.punchangle,g</Item> + <Item Name="velocity">*(float3_t*)v.velocity,g</Item> + <Item Name="avelocity">*(float3_t*)v.avelocity,g</Item> + <Item Name="movedir">*(float3_t*)v.movedir,g</Item> + <Item Name="size">*(float3_t*)v.size,g</Item> + <Item Name="hull" Condition="v.solid != SOLID_BSP">HullForSize(v.absmax[0]-v.absmin[0])</Item> + <Item Name="absmin">*(float3_t*)v.absmin,g</Item> + <Item Name="absmax">*(float3_t*)v.absmax,g</Item> + <Synthetic Name="abscenter"> + <DisplayString>[{(v.absmin[0]+v.absmax[0])*0.5f,g} {(v.absmin[1]+v.absmax[1])*0.5f,g} {(v.absmin[2]+v.absmax[2])*0.5f,g}]</DisplayString> + </Synthetic> + <Item Name="mins">*(float3_t*)v.mins,g</Item> + <Item Name="maxs">*(float3_t*)v.maxs,g</Item> + <Item Name="groundentity">PROG_TO_EDICT(v.groundentity),na</Item> + <Item Name="waterlevel">v.waterlevel,g</Item> + <Item Name="watertype">v.watertype,g</Item> + <Item Name="ideal_yaw">v.ideal_yaw,g</Item> + <Item Name="yaw_speed">v.yaw_speed,g</Item> + <Item Name="teleport_time">v.teleport_time,g</Item> + </Expand> + </Synthetic> + + <!--Visual properties--> + <Synthetic Name="[visuals]"> + <Expand> + <Item Name="model">PR_GetString(v.model),s</Item> + <Item Name="modelindex">v.modelindex,g</Item> + <Item Name="skin">v.skin,g</Item> + <Item Name="frame">v.frame,g</Item> + <Item Name="effects">(efx_t)v.flags</Item> + <Item Name="weaponmodel">PR_GetString(v.weaponmodel),s</Item> + <Item Name="weaponframe">v.weaponframe,g</Item> + <Item Name="colormap">v.colormap,g</Item> + </Expand> + </Synthetic> + + <!--Audio properties--> + <Synthetic Name="[audio]"> + <Expand> + <Item Name="sounds">v.sounds,g</Item> + <Item Name="noise">PR_GetString(v.noise),s</Item> + <Item Name="noise1">PR_GetString(v.noise1),s</Item> + <Item Name="noise2">PR_GetString(v.noise2),s</Item> + <Item Name="noise3">PR_GetString(v.noise3),s</Item> + </Expand> + </Synthetic> + + <!--Scripting properties--> + <Synthetic Name="[scripting]"> + <Expand> + <Item Name="target">PR_GetString(v.target),s</Item> + <Item Name="targetname">PR_GetString(v.targetname),s</Item> + <Item Name="netname">PR_GetString(v.netname),s</Item> + <Item Name="message">PR_GetString(v.message),s</Item> + <Item Name="nextthink">v.nextthink,g</Item> + <Item Name="ltime">v.ltime,g</Item> + <Item Name="qcvm time">qcvm->time,g</Item> + <Item Name="think">GetFunction(v.think),na</Item> + <Item Name="use">GetFunction(v.use),na</Item> + <Item Name="touch">GetFunction(v.touch),na</Item> + <Item Name="blocked">GetFunction(v.blocked),na</Item> + <Item Name="owner">PROG_TO_EDICT(v.owner),na</Item> + <Item Name="goalentity">PROG_TO_EDICT(v.goalentity),na</Item> + </Expand> + </Synthetic> + + <!--Damage-related properties--> + <Synthetic Name="[damage]"> + <Expand> + <Item Name="health">v.health,g</Item> + <Item Name="max_health">v.max_health,g</Item> + <Item Name="armortype">v.armortype,g</Item> + <Item Name="armorvalue">v.armorvalue,g</Item> + <Item Name="takedamage">(etakedamage_t)v.takedamage</Item> + <Item Name="deadflag">(edeadflag_t)v.deadflag</Item> + <Item Name="dmg_inflictor">PROG_TO_EDICT(v.dmg_inflictor),na</Item> + <Item Name="dmg_take">v.dmg_take,g</Item> + <Item Name="dmg_save">v.dmg_save,g</Item> + <Item Name="enemy">PROG_TO_EDICT(v.enemy),na</Item> + <Item Name="aiment">PROG_TO_EDICT(v.aiment),na</Item> + <Item Name="frags">v.frags,g</Item> + <Item Name="currentammo">v.currentammo,g</Item> + <Item Name="ammo_shells">v.ammo_shells,g</Item> + <Item Name="ammo_nails">v.ammo_nails,g</Item> + <Item Name="ammo_rockets">v.ammo_rockets,g</Item> + <Item Name="ammo_cells">v.ammo_cells,g</Item> + <Item Name="items">v.items,g</Item> + </Expand> + </Synthetic> + + <!--Full entity chain, if present, including the current entity--> + <Synthetic Name="[chain]" Condition="!free && v.chain != 0"> + <Expand> + <CustomListItems> + <Variable Name="iter" InitialValue="EDICT_TO_PROG(this)"/> + <Variable Name="index" InitialValue="0"/> + <Loop> + <Break Condition="iter == 0"/> + <Item Name="[{index}]">PROG_TO_EDICT(iter),na</Item> + <Exec>iter = PROG_TO_EDICT(iter)->v.chain</Exec> + <Exec>index++</Exec> + </Loop> + </CustomListItems> + </Expand> + </Synthetic> + + <!--All QuakeC fields--> + <Synthetic Name="[all fields]" Condition="!free"> + <Expand> + <CustomListItems> + <Variable Name="i" InitialValue="1"/> + <Loop> + <Break Condition="i == qcvm->progs->numfielddefs"/> + + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_string">PR_GetString(*(int*)FieldData(i)),s</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_entity">PROG_TO_EDICT(*(int*)FieldData(i)),na</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_function">GetFunction(*(int*)FieldData(i)),na</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_field">SafeFieldPtr(*(int*)FieldData(i)),na</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_float && !IsVecField(i)">*(float*)FieldData(i),g</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_vector">*(float3_t*)FieldData(i),g</Item> + <Item Name="{FieldName(i),sb}" Condition="FieldType(i)==ev_pointer">(void*)FieldData(i)</Item> + + <Exec>i++</Exec> + </Loop> + </CustomListItems> + </Expand> + </Synthetic> + </Expand> + </Type> + + + <!-- + ================================================================================================================================ + Area node + ================================================================================================================================ + --> + <Type Name="areanode_s"> + <!--Helpers--> + <Intrinsic Name="PR_GetString" Expression="((unsigned int)num < qcvm->stringssize) ? qcvm->strings + num : + (num < 0 && num >= -qcvm->numknownstrings) ? qcvm->knownstrings[-1 - num] : 0" ReturnType="const char*"> + <Parameter Name="num" Type="int" /> + </Intrinsic> + + <Intrinsic Name="EdictFromLink" Expression="((edict_t*)((char*)link - (uintptr_t)(&((edict_t*)0)->area)))"> + <Parameter Name="link" Type="link_t*"/> + </Intrinsic> + + <Intrinsic Name="HasSolids" Expression="solid_edicts.next != &solid_edicts" ReturnType="bool"/> + + <Intrinsic Name="HasTriggers" Expression="trigger_edicts.next != &trigger_edicts" ReturnType="bool"/> + + <Intrinsic Name="IsLeaf" Expression="axis == -1" ReturnType="bool"/> + + <!--Inline view--> + <DisplayString Condition="IsLeaf()" >type=LEAF solids={HasSolids()} triggers={HasTriggers()}</DisplayString> + <DisplayString >type=NODE axis={axis} dist={dist,g} solids={HasSolids()} triggers={HasTriggers()}</DisplayString> + + <!--Expanded view--> + <Expand> + <!--solid_edicts linked list--> + <Synthetic Name="[solid edicts]" Condition="HasSolids()"> + <Expand> + <CustomListItems> + <Variable Name="end" InitialValue="&solid_edicts"/> + <Variable Name="iter" InitialValue="solid_edicts.next"/> + <Variable Name="index" InitialValue="0"/> + <Loop> + <Break Condition="iter == end"/> + <Item Name="[{index}]">EdictFromLink(iter),na</Item> + <Exec>iter = iter->next</Exec> + <Exec>index++</Exec> + </Loop> + </CustomListItems> + </Expand> + </Synthetic> + + <!--trigger_edicts linked list--> + <Synthetic Name="[trigger edicts]" Condition="HasTriggers()"> + <Expand> + <CustomListItems> + <Variable Name="end" InitialValue="&trigger_edicts"/> + <Variable Name="iter" InitialValue="trigger_edicts.next"/> + <Variable Name="index" InitialValue="0"/> + <Loop> + <Break Condition="iter == end || !iter"/> + <Item Name="[{index}]">EdictFromLink(iter),na</Item> + <Exec>iter = iter->next</Exec> + <Exec>index++</Exec> + </Loop> + </CustomListItems> + </Expand> + </Synthetic> + + <Item Name="children" Condition="!IsLeaf()">children</Item> + </Expand> + </Type> + + +</AutoVisualizer> diff --git a/Windows/VisualStudio/ironwail.vcxproj b/Windows/VisualStudio/ironwail.vcxproj index 5a6507ec1..0bb359b13 100644 --- a/Windows/VisualStudio/ironwail.vcxproj +++ b/Windows/VisualStudio/ironwail.vcxproj @@ -324,6 +324,12 @@ copy "$(SolutionDir)..\zlib\$(PlatformShortName)\*.dll" "$(TargetDir)"</Command> <ClCompile Include="..\..\Quake\sv_move.c" /> <ClCompile Include="..\..\Quake\sv_phys.c" /> <ClCompile Include="..\..\Quake\sv_user.c" /> + <ClCompile Include="..\..\Quake\sys_sdl_unix.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\Quake\sys_sdl_win.c" /> <ClCompile Include="..\..\Quake\view.c" /> <ClCompile Include="..\..\Quake\wad.c" /> @@ -405,6 +411,9 @@ copy "$(SolutionDir)..\zlib\$(PlatformShortName)\*.dll" "$(TargetDir)"</Command> <ItemGroup> <ResourceCompile Include="..\QuakeSpasm.rc" /> </ItemGroup> + <ItemGroup> + <Natvis Include="ironwail.natvis" /> + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/Windows/VisualStudio/ironwail.vcxproj.filters b/Windows/VisualStudio/ironwail.vcxproj.filters index 5a944f3ac..023e0873e 100644 --- a/Windows/VisualStudio/ironwail.vcxproj.filters +++ b/Windows/VisualStudio/ironwail.vcxproj.filters @@ -261,6 +261,9 @@ <ClCompile Include="..\..\Quake\json.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\Quake\sys_sdl_unix.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Quake\anorm_dots.h"> @@ -479,4 +482,7 @@ <Filter>Resource Files</Filter> </ResourceCompile> </ItemGroup> + <ItemGroup> + <Natvis Include="ironwail.natvis" /> + </ItemGroup> </Project> \ No newline at end of file diff --git a/Windows/codecs/include/xmp.h b/Windows/codecs/include/xmp.h index e38857836..22db2a3da 100644 --- a/Windows/codecs/include/xmp.h +++ b/Windows/codecs/include/xmp.h @@ -9,26 +9,40 @@ extern "C" { #endif -#define XMP_VERSION "4.5.1" -#define XMP_VERCODE 0x040501 +#define XMP_VERSION "4.6.0" +#define XMP_VERCODE 0x040600 #define XMP_VER_MAJOR 4 -#define XMP_VER_MINOR 5 -#define XMP_VER_RELEASE 1 +#define XMP_VER_MINOR 6 +#define XMP_VER_RELEASE 0 #if defined(_WIN32) && !defined(__CYGWIN__) -# if defined(BUILDING_STATIC) +# if defined(LIBXMP_STATIC) # define LIBXMP_EXPORT # elif defined(BUILDING_DLL) # define LIBXMP_EXPORT __declspec(dllexport) # else # define LIBXMP_EXPORT __declspec(dllimport) # endif -#elif defined(__OS2__) && defined(__WATCOMC__) && defined(__SW_BD) +#elif defined(__OS2__) && defined(__WATCOMC__) +# if defined(LIBXMP_STATIC) +# define LIBXMP_EXPORT +# elif defined(BUILDING_DLL) # define LIBXMP_EXPORT __declspec(dllexport) +# else +# define LIBXMP_EXPORT +# endif #elif (defined(__GNUC__) || defined(__clang__) || defined(__HP_cc)) && defined(XMP_SYM_VISIBILITY) -# define LIBXMP_EXPORT __attribute__((visibility ("default"))) +# if defined(LIBXMP_STATIC) +# define LIBXMP_EXPORT +# else +# define LIBXMP_EXPORT __attribute__((visibility("default"))) +# endif #elif defined(__SUNPRO_C) && defined(XMP_LDSCOPE_GLOBAL) -# define LIBXMP_EXPORT __global +# if defined(LIBXMP_STATIC) +# define LIBXMP_EXPORT +# else +# define LIBXMP_EXPORT __global +# endif #elif defined(EMSCRIPTEN) # define LIBXMP_EXPORT EMSCRIPTEN_KEEPALIVE # define LIBXMP_EXPORT_VAR @@ -36,7 +50,7 @@ extern "C" { # define LIBXMP_EXPORT #endif -#if !defined (LIBXMP_EXPORT_VAR) +#if !defined(LIBXMP_EXPORT_VAR) # define LIBXMP_EXPORT_VAR LIBXMP_EXPORT #endif @@ -241,6 +255,7 @@ struct xmp_sample { #define XMP_SAMPLE_LOOP_FULL (1 << 4) /* Play full sample before looping */ #define XMP_SAMPLE_SLOOP (1 << 5) /* Sample has sustain loop */ #define XMP_SAMPLE_SLOOP_BIDIR (1 << 6) /* Bidirectional sustain loop */ +#define XMP_SAMPLE_STEREO (1 << 7) /* Interlaced stereo sample */ #define XMP_SAMPLE_SYNTH (1 << 15) /* Data contains synth patch */ int flg; /* Flags */ unsigned char *data; /* Sample data */ diff --git a/Windows/codecs/x64/libmpg123-0.dll b/Windows/codecs/x64/libmpg123-0.dll index 1eb100c3f..8b7de4dfd 100644 Binary files a/Windows/codecs/x64/libmpg123-0.dll and b/Windows/codecs/x64/libmpg123-0.dll differ diff --git a/Windows/codecs/x64/libopusfile-0.dll b/Windows/codecs/x64/libopusfile-0.dll index 92b3cdb5b..72b19c9ef 100644 Binary files a/Windows/codecs/x64/libopusfile-0.dll and b/Windows/codecs/x64/libopusfile-0.dll differ diff --git a/Windows/codecs/x64/libxmp.dll b/Windows/codecs/x64/libxmp.dll index 588da83b0..aa62e7f9f 100644 Binary files a/Windows/codecs/x64/libxmp.dll and b/Windows/codecs/x64/libxmp.dll differ diff --git a/Windows/codecs/x86-watcom/libxmp.lib b/Windows/codecs/x86-watcom/libxmp.lib index bf0c70a71..1a82ce9f2 100644 Binary files a/Windows/codecs/x86-watcom/libxmp.lib and b/Windows/codecs/x86-watcom/libxmp.lib differ diff --git a/Windows/codecs/x86-watcom/mpg123.lib b/Windows/codecs/x86-watcom/mpg123.lib index 53fc127f9..a7e20b874 100644 Binary files a/Windows/codecs/x86-watcom/mpg123.lib and b/Windows/codecs/x86-watcom/mpg123.lib differ diff --git a/Windows/codecs/x86-watcom/opusfile.lib b/Windows/codecs/x86-watcom/opusfile.lib index c0c477557..5219e7277 100644 Binary files a/Windows/codecs/x86-watcom/opusfile.lib and b/Windows/codecs/x86-watcom/opusfile.lib differ diff --git a/Windows/codecs/x86/libmpg123-0.dll b/Windows/codecs/x86/libmpg123-0.dll index 81e6bd29b..49ddfecee 100644 Binary files a/Windows/codecs/x86/libmpg123-0.dll and b/Windows/codecs/x86/libmpg123-0.dll differ diff --git a/Windows/codecs/x86/libopusfile-0.dll b/Windows/codecs/x86/libopusfile-0.dll index 3cb063e0c..292cd5041 100644 Binary files a/Windows/codecs/x86/libopusfile-0.dll and b/Windows/codecs/x86/libopusfile-0.dll differ diff --git a/Windows/codecs/x86/libxmp.dll b/Windows/codecs/x86/libxmp.dll index aa30bb2e8..9d5cee7ad 100644 Binary files a/Windows/codecs/x86/libxmp.dll and b/Windows/codecs/x86/libxmp.dll differ