From 15d59cbbd86f9dba3c20f0b390e2b1ecddebd006 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Wed, 30 Aug 2023 22:20:07 +0200 Subject: [PATCH 01/28] i dont want any special music no to grow and star music! --- src/d_netcmd.c | 3 +++ src/g_game.c | 4 ++++ src/g_game.h | 1 + src/p_user.c | 4 ++-- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cb2123e45..35e6857b1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -976,6 +976,9 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_saltyhop); CV_RegisterVar(&cv_saltyhopsfx); CV_RegisterVar(&cv_saltysquish); + + CV_RegisterVar(&cv_growmusic); + CV_RegisterVar(&cv_supermusic); //CV_RegisterVar(&cv_crosshair); //CV_RegisterVar(&cv_crosshair2); diff --git a/src/g_game.c b/src/g_game.c index 0cb897b52..01037f3c6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -468,6 +468,10 @@ consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL // Show "FREE PLAY" when you're alone. :( consvar_t cv_showfreeplay = { "showfreeplay", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +// We can disable special tunes! +consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + /*consvar_t cv_crosshair = {"crosshair", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair3 = {"crosshair3", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.h b/src/g_game.h index 67618296f..ceb8e1f9f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -113,6 +113,7 @@ extern INT16 rw_maximums[NUM_WEAPONS]; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/; extern consvar_t cv_songcredits; extern consvar_t cv_showfreeplay; +extern consvar_t cv_growmusic, cv_supermusic; extern consvar_t cv_pauseifunfocused; //extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/; diff --git a/src/p_user.c b/src/p_user.c index 700671ef6..feed77bd7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1278,13 +1278,13 @@ void P_RestoreMusic(player_t *player) } // Item - Grow - if (wantedmus == 2) + if (wantedmus == 2 && cv_growmusic.value) { S_ChangeMusicInternal("kgrow", true); S_SetRestoreMusicFadeInCvar(&cv_growmusicfade); } // Item - Invincibility - else if (wantedmus == 1) + else if (wantedmus == 1 && cv_supermusic.value) { S_ChangeMusicInternal("kinvnc", true); S_SetRestoreMusicFadeInCvar(&cv_invincmusicfade); -- 2.54.0 From 1ab243d93a0294cc7063f1c35f5bba89b6377a7c Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Wed, 30 Aug 2023 22:26:38 +0200 Subject: [PATCH 02/28] add shit to menu --- src/m_menu.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3c67d86ce..ec4f2ebd7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1414,12 +1414,17 @@ static menuitem_t OP_SoundAdvancedMenu[] = { {IT_HEADER, NULL, "Tracker Module Options", NULL, 10}, - {IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 42}, - {IT_STRING | IT_CVAR, NULL, "Amiga Resampler", &cv_amigafilter, 62}, + {IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 22}, + {IT_STRING | IT_CVAR, NULL, "Amiga Resampler", &cv_amigafilter, 42}, #if OPENMPT_API_VERSION_MAJOR < 1 && OPENMPT_API_VERSION_MINOR > 4 - {IT_STRING | IT_CVAR, NULL, "Amiga Type", &cv_amigatype, 82}, + {IT_STRING | IT_CVAR, NULL, "Amiga Type", &cv_amigatype, 62}, #endif - {IT_STRING | IT_CVAR, NULL, "Stereo Seperation", &cv_stereosep, 102}, + {IT_STRING | IT_CVAR, NULL, "Stereo Seperation", &cv_stereosep, 82}, + + {IT_HEADER, NULL, "Misc", NULL, 105}, + + {IT_STRING | IT_CVAR, NULL, "Grow Music", &cv_growmusic, 117}, + {IT_STRING | IT_CVAR, NULL, "Invulnerability Music", &cv_supermusic, 137}, }; #endif -- 2.54.0 From f47cb885cc909604d6f69f8a60bc94c9d5ef16db Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Wed, 30 Aug 2023 22:27:52 +0200 Subject: [PATCH 03/28] eeeeheheheeheheh ifdefs --- src/m_menu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ec4f2ebd7..980a4c694 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1404,14 +1404,13 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 125}, {IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 135}, -#ifdef HAVE_OPENMPT {IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 155} -#endif }; -#ifdef HAVE_OPENMPT + static menuitem_t OP_SoundAdvancedMenu[] = { +#ifdef HAVE_OPENMPT {IT_HEADER, NULL, "Tracker Module Options", NULL, 10}, {IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 22}, @@ -1420,13 +1419,13 @@ static menuitem_t OP_SoundAdvancedMenu[] = {IT_STRING | IT_CVAR, NULL, "Amiga Type", &cv_amigatype, 62}, #endif {IT_STRING | IT_CVAR, NULL, "Stereo Seperation", &cv_stereosep, 82}, - +#endif {IT_HEADER, NULL, "Misc", NULL, 105}, {IT_STRING | IT_CVAR, NULL, "Grow Music", &cv_growmusic, 117}, {IT_STRING | IT_CVAR, NULL, "Invulnerability Music", &cv_supermusic, 137}, }; -#endif + static menuitem_t OP_DataOptionsMenu[] = { -- 2.54.0 From bd41bbb304d9606418bf6ac01ace65c7f891dcd3 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Thu, 31 Aug 2023 00:24:16 +0200 Subject: [PATCH 04/28] fix the speedometer things got swapped X) also removed the extra number, kart adds a 3rd one if needed --- src/k_kart.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 36bb9a57a..fd3a46afe 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8321,11 +8321,11 @@ static void K_drawKartSpeedometer(void) speedtype = 1; break; case 2: - convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapobjectscale)/FRACUNIT; // 2.172409058 + convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapobjectscale)/FRACUNIT; // 1.349868774 speedtype = 2; break; case 3: - convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapobjectscale)/FRACUNIT; // 1.349868774 + convSpeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT; speedtype = 3; break; case 4: @@ -8342,19 +8342,19 @@ static void K_drawKartSpeedometer(void) { switch (speedtype) { case 1: - V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%03d km/h", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d km/h", convSpeed)); break; case 2: - V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%03d mph", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d mph", convSpeed)); break; case 3: - V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%03d fu/t", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d fu/t", convSpeed)); break; case 4: // if extra.kart is found, use its included % symbol if (!found_extra_kart) - V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%03d P", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%4d P", convSpeed)); else - V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%03d %%", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%4d %%", convSpeed)); } } else if (cv_newspeedometer.value && found_extra_kart) { // why bother if we dont? -- 2.54.0 From 97058bfcf63e2516284441a9fa6cd8b95c74c429 Mon Sep 17 00:00:00 2001 From: haya <126386046+hayaunderscore@users.noreply.github.com> Date: Thu, 31 Aug 2023 07:05:06 +0800 Subject: [PATCH 05/28] try being consistent --- README.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c0b66de8d..b090b5d4b 100644 --- a/README.md +++ b/README.md @@ -6,29 +6,34 @@ - Sprites player rotation on slopes; going on hills, levitate, going down, and so on alters your sprites (configurable) - You can alter all the base kart HUD element offsets on the fly in the Saturn Options settings menu -- "addfilelocal" Command, for those who want to use things like their custom hud in netgames (Same as addfile but completely client sided) -- OpenMPT for Tracker module playback (Complete with filters) fixed looping issues while even sounding better than the old GME playback +- `addfilelocal` Command, for those who want to use things like their custom hud in netgames (Same as addfile but completely client sided) +- OpenMPT for Tracker module playback instead of GME + - Fixes looping and sounds better + - Allows filter configuration - The minimal brightness with Shaders can be configured, now you can seeeee in dark areas (0-255 , uses Sector brightness values) -- Lua hooks for Intermission (ex: You can make hostmod votes still visible during intermission!) +- Lua HUD hooks for Intermission (ex: You can make hostmod votes still visible during intermission!) - Lua HUD hooks for Vote Screen (ex: You can make hostmod votes still visible during map vote screen!) - Saltyhop! do a funny hop - Smaller Speedometer (optional / requieres extra.kart file) - Record Attack input display can now be used everywhere - Smaller minimap icons and also show player names on the minimap (toggable) -- "showmusiccredits" command, shows you the current music track again -- "listskins" show a list of all skins currently loaded -- Visual Portals from Haya´s HEP Client -- Toggable lowercase menu´s also from Haya´s HEP client +- `showmusiccredit` command, shows you the current music track again +- `listskins` show a list of all skins currently loaded +- Visual Portals from Haya's HEP Client +- Toggable lowercase menu's also from Haya's HEP client - Everything that Galaxy has ## Improvements / Bug fixes -- Replay size has been increased to 10MiB minimum, to make replay overflows very unlikely to happen (can be set to 100MiB max with "maxdemosize" command in console) -- Music changes now properly show the music credits (ex: Kart maps with easter eggs that alter the music) *The mapper still has to provide a MusicDEF for this to work. +- Replay size has been increased to 10MiB minimum, to make replay overflows very unlikely to happen + - can be set to 100MiB max with `maxdemosize` command in console +- Music changes now properly show the music credits (ex: Kart maps with easter eggs that alter the music) + - The mapper still has to provide a MusicDEF for this to work. - Configurable chatlog length (yay can read those messages from 30 mins ago without opening log.txt) - Configurable timeout for waiting to join a full server (in vanilla this is capped to 5 minutes before it boots you out) - Characters now spin in skin selection menu (configurable) -- HTTP Addon download speed has been raised dramatically (configurable with "downloadspeed" command) +- HTTP Addon download speed has been raised dramatically + - configurable with `downloadspeed` command - HWR Drawnodes have been refactored, this should fix a few rare crashes esp in regards to OpenGL Visportals - The Position Number in the corner is alot smaller now (half the size!) - Toggable Lap animation @@ -40,17 +45,18 @@ - Access for `mobj_t` and `player_t` fields from Lua has been completely rewritten, for much better performance with many Lua scripts - Lua shows Tracebacks whenever an error occurs - The Lua Perfstats page now has multiple pages and is more organized (ps_thinkframe_page X in console) -- People with lower end hardware can disable "screen textures" with "gr_screentextures" command, huge performance gain with minimal visual loss (Note intermission screen background is broken with this) -- Software mode has gotten "ffloorclip", which boosts performance on maps with many Floor over Floor roads +- People with lower end hardware can disable "screen textures" with "gr_screentextures" command, huge performance gain with minimal visual loss + - Intermission backgrounds, heat wave effects and etc are broken with this +- `ffloorclip`, exclusive to Software, which boosts performance on maps with many Floor over Floor sectors ## Technical fixes - ZFigthing Textures in Opengl mode have been fixed in engine (well almost all of it) -- Fof's intersecting with slopes have less issues and now render correctly in Opengl +- FOFs intersecting with slopes have less issues and now render correctly in Opengl - Midtextures on slopes in Opengl are fixed, many weird guardrails and fences, aswell as some of those sticking out textures from the ground on some maps should be gone -- The annoying depraction messages for "P_TeleportMove" and "P_AproxDistance" have been silenced +- The annoying depraction messages for `P_TeleportMove` and `P_AproxDistance` have been silenced - Silenced the annoying "cant find next map..." messages as theyre super useless and annoying anyways -- Added a small cooldown on "map" command due to spamming causing a SIGSEGV +- Added a small cooldown on `map` command due to spamming causing a SIGSEGV ## MISC - Bird's Camara Tilting feature is no longer turned on by default -- 2.54.0 From 1a9f30a328ebf8110b076c5c56bbd21de2d2500f Mon Sep 17 00:00:00 2001 From: haya <126386046+hayaunderscore@users.noreply.github.com> Date: Thu, 31 Aug 2023 07:06:17 +0800 Subject: [PATCH 06/28] ok github markdown --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b090b5d4b..2f1f60f22 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ - You can alter all the base kart HUD element offsets on the fly in the Saturn Options settings menu - `addfilelocal` Command, for those who want to use things like their custom hud in netgames (Same as addfile but completely client sided) - OpenMPT for Tracker module playback instead of GME - - Fixes looping and sounds better - - Allows filter configuration + - Fixes looping and sounds better + - Allows filter configuration - The minimal brightness with Shaders can be configured, now you can seeeee in dark areas (0-255 , uses Sector brightness values) - Lua HUD hooks for Intermission (ex: You can make hostmod votes still visible during intermission!) - Lua HUD hooks for Vote Screen (ex: You can make hostmod votes still visible during map vote screen!) @@ -26,14 +26,14 @@ ## Improvements / Bug fixes - Replay size has been increased to 10MiB minimum, to make replay overflows very unlikely to happen - - can be set to 100MiB max with `maxdemosize` command in console + - can be set to 100MiB max with `maxdemosize` command in console - Music changes now properly show the music credits (ex: Kart maps with easter eggs that alter the music) - The mapper still has to provide a MusicDEF for this to work. - Configurable chatlog length (yay can read those messages from 30 mins ago without opening log.txt) - Configurable timeout for waiting to join a full server (in vanilla this is capped to 5 minutes before it boots you out) - Characters now spin in skin selection menu (configurable) - HTTP Addon download speed has been raised dramatically - - configurable with `downloadspeed` command + - configurable with `downloadspeed` command - HWR Drawnodes have been refactored, this should fix a few rare crashes esp in regards to OpenGL Visportals - The Position Number in the corner is alot smaller now (half the size!) - Toggable Lap animation @@ -46,7 +46,7 @@ - Lua shows Tracebacks whenever an error occurs - The Lua Perfstats page now has multiple pages and is more organized (ps_thinkframe_page X in console) - People with lower end hardware can disable "screen textures" with "gr_screentextures" command, huge performance gain with minimal visual loss - - Intermission backgrounds, heat wave effects and etc are broken with this + - Intermission backgrounds, heat wave effects and etc are broken with this - `ffloorclip`, exclusive to Software, which boosts performance on maps with many Floor over Floor sectors ## Technical fixes -- 2.54.0 From d48b08856e43ccadd779c54f3da863c697fd6051 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Thu, 31 Aug 2023 10:42:43 +0200 Subject: [PATCH 07/28] Support for Animated Votingscreens i hate the interpolation i hate it no idea honestly if those play correctly atm but atleast they dont freak out with uncapped https://gitlab.com/blondedradio/srb-2-k-cep/-/commit/776a547087cdef46b2bdbfc3ddc9d4d963bbea4b --- src/y_inter.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 8 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 3fb2d3aa3..16a5dae72 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -116,6 +116,18 @@ static INT32 intertic; static INT32 endtic = -1; static INT32 sorttic = -1; +patch_t *animVoteFramesPatches = NULL; +// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch) +// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch) +// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch used in software) +// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch used in software) +char animPrefix[] = "INTSC"; +char animWidePrefix[] = "INTSW"; + +INT32 currentAnimFrame = 0; +static INT32 foundAnimVoteFrames = 0; +static INT32 foundAnimVoteWideFrames = 0; + intertype_t intertype = int_none; @@ -325,6 +337,44 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) } } +// +// Y_AnimatedVoteScreenCheck +// +// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle) +void Y_AnimatedVoteScreenCheck(void) +{ + char tmpPrefix[] = "INTS"; + if(G_BattleGametype()) { + strcpy(animPrefix, "BTLSC"); + strcpy(animWidePrefix, "BTLSW"); + + strcpy(tmpPrefix, "BTLS"); + } + boolean stopSearching = false; + + foundAnimVoteFrames = 0; + foundAnimVoteWideFrames = 0; + currentAnimFrame = 0; + + INT32 i = 1; + while(!stopSearching){ + boolean normalLumpExists = W_LumpExists(va("%sC%d", tmpPrefix, i)); + boolean wideLumpExists = W_LumpExists(va("%sW%d", tmpPrefix, i)); + + if(normalLumpExists || wideLumpExists){ + if(normalLumpExists){ + foundAnimVoteFrames++; + } + if(wideLumpExists){ + foundAnimVoteWideFrames++; + } + } else { // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking + stopSearching = true; + } + i++; + } +} + // // Y_IntermissionDrawer // @@ -978,6 +1028,41 @@ static void Y_UnloadData(void) // SRB2Kart: Voting! +// Y_DrawAnimatedVoteScreenPatch +// +// Draw animated patch based on frame counter on vote screen +// +void Y_DrawAnimatedVoteScreenPatch(boolean widePatch){ + char tempAnimPrefix[7]; + (widePatch) ? strcpy(tempAnimPrefix, animWidePrefix) : strcpy(tempAnimPrefix, animPrefix); + INT32 tempFoundAnimVoteFrames = (widePatch) ? foundAnimVoteWideFrames : foundAnimVoteFrames; + INT32 flags = V_SNAPTOBOTTOM | V_SNAPTOTOP; + UINT8 patchframe = (votetic / 4) % 16; + + // Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0 + if(widePatch) { + if(currentAnimFrame > foundAnimVoteWideFrames-1){ + currentAnimFrame = 0; + } + } else { + if(currentAnimFrame > foundAnimVoteFrames-1){ + currentAnimFrame = 0; + } + } + + /*patch_t *currPatch = W_CachePatchName(va("%s%d", tempAnimPrefix, currentAnimFrame+1), PU_CACHE); + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(currPatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + (vid.height / vid.dupy) - SHORT(currPatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, currPatch); + if(votetic % 3 == 0 && !paused){*/ + + { + currentAnimFrame = (currentAnimFrame+1 > tempFoundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1; // jeez no fucking idea how to make this shit not go nuts with interpolation + patch_t *background = W_CachePatchName(va("%s%d", tempAnimPrefix, patchframe + 1), PU_CACHE); + V_DrawScaledPatch(160 - (background->width / 2), (200 - (background->height)), flags, background); + } +} + // // Y_VoteDrawer // @@ -1006,14 +1091,34 @@ void Y_VoteDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) - V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), - (vid.height / vid.dupy) - SHORT(widebgpatch->height), - V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch); - else - V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) - (vid.height / vid.dupy) - SHORT(bgpatch->height), - V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch); + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) { + + if(foundAnimVoteWideFrames == 0){ + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), + (vid.height / vid.dupy) - SHORT(widebgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch); + } else { + // patch_t *currPatch = W_CachePatchName(va("%s%d", animPrefix, currentAnimFrame+1), PU_CACHE); + // V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(currPatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + // (vid.height / vid.dupy) - SHORT(currPatch->height), + // V_SNAPTOTOP|V_SNAPTOLEFT, currPatch); + // if(votetic % 4 == 0 && !paused){ + // currentAnimFrame = (currentAnimFrame+1 > foundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1; + // } + Y_DrawAnimatedVoteScreenPatch(true); + } + } else { + if(foundAnimVoteFrames == 0) { + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + (vid.height / vid.dupy) - SHORT(bgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch); + } else { + Y_DrawAnimatedVoteScreenPatch(false); + } + + + } + for (i = 0; i < 4; i++) // First, we need to figure out the height of this thing... { @@ -1487,6 +1592,8 @@ void Y_StartVote(void) I_Error("voteendtic is dirty"); #endif + Y_AnimatedVoteScreenCheck(); + widebgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCW" : "INTERSCW"), PU_STATIC); bgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCR" : "INTERSCR"), PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC); -- 2.54.0 From 3147dfb01206a1982c8f9d3e0a84fef17989378f Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Thu, 31 Aug 2023 11:18:38 +0200 Subject: [PATCH 08/28] 2.1 --- src/doomdef.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 266d5a16d..5a914f218 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -149,8 +149,8 @@ extern char logfilename[1024]; #else #define VERSION 1 // Game version #define SUBVERSION 6 // more precise version number -#define VERSIONSTRING "Saturn v2 " -#define VERSIONSTRINGW L"Saturn v2" +#define VERSIONSTRING "Saturn v2.1 " +#define VERSIONSTRINGW L"Saturn v2.1" // Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates! // And change CMakeLists.txt (not src/, but in root), for CMake users! // AND appveyor.yml, for the build bots! -- 2.54.0 From c4ff1a3acabf6fd4c65d35eebaa3bf89d79c3bb0 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Fri, 1 Sep 2023 10:12:06 +0200 Subject: [PATCH 09/28] forgor to readd those --- src/p_enemy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 01b1e8f56..ef0255f3b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -7444,10 +7444,10 @@ void A_RollAngle(mobj_t *actor) INT32 locvar2 = var2; const angle_t angle = FixedAngle(locvar1*FRACUNIT); -/*#ifdef HAVE_BLUA +#ifdef HAVE_BLUA if (LUA_CallAction("A_RollAngle", actor)) return; -#endif*/ +#endif // relative (default) if (!locvar2) @@ -7470,10 +7470,10 @@ void A_ChangeRollAngleRelative(mobj_t *actor) INT32 locvar2 = var2; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; -/*#ifdef HAVE_BLUA +#ifdef HAVE_BLUA if (LUA_CallAction("A_ChangeRollAngleRelative", actor)) return; -#endif*/ +#endif #ifdef PARANOIA if (amin > amax) @@ -7496,10 +7496,10 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor) INT32 locvar2 = var2; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; -/*#ifdef HAVE_BLUA +#ifdef HAVE_BLUA if (LUA_CallAction("A_ChangeRollAngleAbsolute", actor)) return; -#endif*/ +#endif #ifdef PARANOIA if (amin > amax) -- 2.54.0 From e79bf24bcd39d08c49eea41d467c04a35db33158 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 1 Sep 2023 18:34:06 +0300 Subject: [PATCH 10/28] Add lua memory usage in memfree command output --- src/z_zone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/z_zone.c b/src/z_zone.c index b92707ef4..199eefd08 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -622,6 +622,7 @@ void Command_Memfree_f(void) CONS_Printf("\x82%s", M_GetText("Memory Info\n")); CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)); CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); + CONS_Printf(M_GetText("Lua : %7s KB\n"), sizeu1(Z_TagUsage(PU_LUA)>>10)); CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10)); -- 2.54.0 From ca9277366cdb9eeff329d5e72a259e9c42be8bfb Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Fri, 1 Sep 2023 19:43:24 +0200 Subject: [PATCH 11/28] anim screen stuff --- src/y_inter.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 16a5dae72..41c96c9ce 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -171,6 +171,7 @@ typedef struct static y_votelvlinfo levelinfo[5]; static y_voteclient voteclient; static INT32 votetic; +static INT32 lastvotetic; static INT32 voteendtic = -1; static patch_t *cursor = NULL; static patch_t *cursor1 = NULL; @@ -1037,7 +1038,6 @@ void Y_DrawAnimatedVoteScreenPatch(boolean widePatch){ (widePatch) ? strcpy(tempAnimPrefix, animWidePrefix) : strcpy(tempAnimPrefix, animPrefix); INT32 tempFoundAnimVoteFrames = (widePatch) ? foundAnimVoteWideFrames : foundAnimVoteFrames; INT32 flags = V_SNAPTOBOTTOM | V_SNAPTOTOP; - UINT8 patchframe = (votetic / 4) % 16; // Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0 if(widePatch) { @@ -1057,10 +1057,12 @@ void Y_DrawAnimatedVoteScreenPatch(boolean widePatch){ if(votetic % 3 == 0 && !paused){*/ { - currentAnimFrame = (currentAnimFrame+1 > tempFoundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1; // jeez no fucking idea how to make this shit not go nuts with interpolation - patch_t *background = W_CachePatchName(va("%s%d", tempAnimPrefix, patchframe + 1), PU_CACHE); + patch_t *background = W_CachePatchName(va("%s%d", tempAnimPrefix, currentAnimFrame + 1), PU_CACHE); V_DrawScaledPatch(160 - (background->width / 2), (200 - (background->height)), flags, background); } + if (lastvotetic != votetic && lastvotetic % 2 == 0) { + currentAnimFrame = (currentAnimFrame+1 > tempFoundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1; // jeez no fucking idea how to make this shit not go nuts with interpolation + } } // @@ -1336,6 +1338,8 @@ void Y_VoteDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, va("Vote ends in %d", tickdown)); } + + lastvotetic = votetic; #ifdef HAVE_BLUA if (renderisnewtic) -- 2.54.0 From 3675fdd3613e0a378ac0642a564b0f41fde1912c Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Tue, 5 Sep 2023 09:13:12 +0200 Subject: [PATCH 12/28] smoother slope rotation for players dont snap player directly to whatever theyre standing on instead make the sprite rotate a bit smoother see: https://git.do.srb2.org/haya_/Kart-Public/-/commit/8448d75b031fa86cdb854d13eda4712352d35a89 --- src/d_player.h | 1 + src/k_kart.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index d7bfb80eb..a12fff93b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -371,6 +371,7 @@ typedef struct player_s angle_t viewrollangle; angle_t tilt; + angle_t tilt_sprite; // Mouse aiming, where the guy is looking at! // It is updated with cmd->aiming. diff --git a/src/k_kart.c b/src/k_kart.c index fd3a46afe..ffd759bbb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3132,6 +3132,7 @@ static angle_t K_GetSlopeRollAngle(player_t *p, boolean dontflip, boolean useRes angle_t zangle = 0; angle_t xydirection = 0; angle_t an; + angle_t final_slope; INT32 pNum = K_FindPlayerNum(p); I_Assert(p != NULL); @@ -3171,7 +3172,14 @@ static angle_t K_GetSlopeRollAngle(player_t *p, boolean dontflip, boolean useRes zangle = InvAngle(zangle); an = (lookAngle - xydirection); - return FixedMul(zangle, FINESINE(an>>ANGLETOFINESHIFT)); + final_slope = -(FixedMul(FINESINE(an>>ANGLETOFINESHIFT), zangle)); + an = (INT32)(final_slope - p->tilt_sprite) / 2; // instead of just a direct snap + + if (an) + p->tilt_sprite += an; + else + p->tilt_sprite = final_slope; + return -p->tilt_sprite; } static void K_RollPlayerBySlopes(player_t *p, boolean usedistance) -- 2.54.0 From 7f05d27f42a437e28f293829e849c5fbdfc7dfb6 Mon Sep 17 00:00:00 2001 From: Indev Date: Tue, 5 Sep 2023 12:47:49 +0300 Subject: [PATCH 13/28] Allow lua to change vote background via hud.setVoteBackground --- src/lua_hudlib.c | 36 ++++++++++++++++++++++++++++++++++++ src/y_inter.c | 23 +++++++++++++++++------ src/y_inter.h | 1 + 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 470fad9b7..bd3fb19c8 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -15,6 +15,7 @@ #include "r_defs.h" #include "r_local.h" #include "st_stuff.h" // hudinfo[] +#include "y_inter.h" #include "g_game.h" #include "i_video.h" // rendermode #include "p_local.h" // camera_t @@ -966,11 +967,46 @@ static int lib_hudadd(lua_State *L) return 0; } +static int lib_hudsetvotebackground(lua_State *L) +{ + if (lua_isnoneornil(L, 1)) + { + if (luaVoteScreen) + { + free(luaVoteScreen); + } + + luaVoteScreen = NULL; + + return 0; + } + + const char *prefix = luaL_checkstring(L, 1); + + if (strlen(prefix) != 4) + { + return luaL_argerror(L, 1, "prefix should 4 characters wide"); + } + + if (!luaVoteScreen) + { + luaVoteScreen = (char*)malloc(5); + luaVoteScreen[4] = 0; + } + + strncpy(luaVoteScreen, prefix, 4); + + strupr(luaVoteScreen); + + return 0; +} + static luaL_Reg lib_hud[] = { {"enable", lib_hudenable}, {"disable", lib_huddisable}, {"enabled", lib_hudenabled}, {"add", lib_hudadd}, + {"setVoteBackground", lib_hudsetvotebackground}, {NULL, NULL} }; diff --git a/src/y_inter.c b/src/y_inter.c index 41c96c9ce..bda60dde2 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -123,6 +123,7 @@ patch_t *animVoteFramesPatches = NULL; // VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch used in software) char animPrefix[] = "INTSC"; char animWidePrefix[] = "INTSW"; +char *luaVoteScreen = NULL; INT32 currentAnimFrame = 0; static INT32 foundAnimVoteFrames = 0; @@ -345,14 +346,24 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) void Y_AnimatedVoteScreenCheck(void) { char tmpPrefix[] = "INTS"; - if(G_BattleGametype()) { - strcpy(animPrefix, "BTLSC"); - strcpy(animWidePrefix, "BTLSW"); - - strcpy(tmpPrefix, "BTLS"); - } boolean stopSearching = false; + if (luaVoteScreen) + { + strncpy(tmpPrefix, luaVoteScreen, 4); + } + else + { + if(G_BattleGametype()) { + strcpy(tmpPrefix, "BTLS"); + } + } + + strncpy(animPrefix, tmpPrefix, 4); + animPrefix[4] = 'C'; + strncpy(animWidePrefix, tmpPrefix, 4); + animWidePrefix[4] = 'W'; + foundAnimVoteFrames = 0; foundAnimVoteWideFrames = 0; currentAnimFrame = 0; diff --git a/src/y_inter.h b/src/y_inter.h index 6162dc282..ee320d474 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -10,6 +10,7 @@ /// \brief Tally screens, or "Intermissions" as they were formally called in Doom extern boolean usebuffer; +extern char *luaVoteScreen; void Y_IntermissionDrawer(void); void Y_Ticker(void); -- 2.54.0 From 78d50e4c43f1e85af6ae54c23d28da05e0c8455e Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Tue, 5 Sep 2023 23:01:03 +0200 Subject: [PATCH 14/28] just a bit more looks even better like this imo --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index ffd759bbb..04dcb4cb7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3173,7 +3173,7 @@ static angle_t K_GetSlopeRollAngle(player_t *p, boolean dontflip, boolean useRes an = (lookAngle - xydirection); final_slope = -(FixedMul(FINESINE(an>>ANGLETOFINESHIFT), zangle)); - an = (INT32)(final_slope - p->tilt_sprite) / 2; // instead of just a direct snap + an = (INT32)(final_slope - p->tilt_sprite) / 3; // instead of just a direct snap if (an) p->tilt_sprite += an; -- 2.54.0 From 228a9325986b96b86225c2b945950e2a70eb72bb Mon Sep 17 00:00:00 2001 From: Indev Date: Wed, 6 Sep 2023 19:54:14 +0300 Subject: [PATCH 15/28] Fix few typos --- src/d_netcmd.c | 2 +- src/k_kart.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 35e6857b1..debee58eb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -512,7 +512,7 @@ consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_ consvar_t cv_showtrackaddon = {"showtrackaddon", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t skinselectmenu_t[] = {{SKINMENUTYPE_SCROLL, "Scoll"}, {SKINMENUTYPE_2D, "2d"}, {SKINMENUTYPE_GRID, "Grid"}, {0, NULL}}; +static CV_PossibleValue_t skinselectmenu_t[] = {{SKINMENUTYPE_SCROLL, "Scroll"}, {SKINMENUTYPE_2D, "2d"}, {SKINMENUTYPE_GRID, "Grid"}, {0, NULL}}; consvar_t cv_skinselectmenu = {"skinselectmenu", "Grid", CV_SAVE, skinselectmenu_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t skinselectgridsort_t[] ={ diff --git a/src/k_kart.c b/src/k_kart.c index fd3a46afe..3208c5f79 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6647,7 +6647,7 @@ void K_CheckBumpers(void) if (winnernum > -1 && playeringame[winnernum]) { players[winnernum].marescore += winnerscoreadd; - CONS_Printf(M_GetText("%s recieved %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); + CONS_Printf(M_GetText("%s received %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); } for (i = 0; i < MAXPLAYERS; i++) // This can't go in the earlier loop because winning adds points -- 2.54.0 From 09f79a693460aadc49b4cc2ca3fe51aa7f121bd8 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Thu, 7 Sep 2023 17:24:06 +0200 Subject: [PATCH 16/28] Addfile per drag and drop https://git.do.srb2.org/SteelT/SRB2/-/commit/01cc2b91e189e4d268eddd38f3ba917133a07adc --- src/sdl/i_video.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 3fd96819c..09ed77658 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -969,6 +969,7 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint void I_GetEvent(void) { SDL_Event evt; + char* dropped_filedir; // We only want the first motion event, // otherwise we'll end up catching the warp back to center. //int mouseMotionOnce = 0; @@ -1293,6 +1294,11 @@ void I_GetEvent(void) if (currentMenu == &OP_JoystickSetDef) M_SetupJoystickMenu(0); break; + case SDL_DROPFILE: + dropped_filedir = evt.drop.file; + COM_BufInsertText(va("addfile \"%s\"", dropped_filedir)); + SDL_free(dropped_filedir); // Free dropped_filedir memory + break; case SDL_QUIT: I_Quit(); M_QuitResponse('y'); -- 2.54.0 From b883d02abb4b972af761f94e7aa677d6d3dd7c13 Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 7 Sep 2023 19:28:53 +0300 Subject: [PATCH 17/28] Use P_AddWadFile directly instead of command so non-ansii file names also supported --- src/sdl/i_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 09ed77658..d08b267f0 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -59,6 +59,7 @@ #endif #include "../doomstat.h" +#include "../p_setup.h" #include "../i_system.h" #include "../v_video.h" #include "../m_argv.h" @@ -1296,7 +1297,7 @@ void I_GetEvent(void) break; case SDL_DROPFILE: dropped_filedir = evt.drop.file; - COM_BufInsertText(va("addfile \"%s\"", dropped_filedir)); + P_AddWadFile(dropped_filedir); SDL_free(dropped_filedir); // Free dropped_filedir memory break; case SDL_QUIT: -- 2.54.0 From 71ce5be570bfb2ba593b5f1c507c51647be139d9 Mon Sep 17 00:00:00 2001 From: lug420 Date: Thu, 7 Sep 2023 23:54:22 +0200 Subject: [PATCH 18/28] me wondering why the hw sprite perfstats were broken + removing some stuff we dont need --- src/hardware/hw_main.c | 102 +++++++++++++++++++++-------------------- src/hardware/hw_main.h | 2 +- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 834f617bf..258573578 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -196,8 +196,6 @@ FTransform atransform; static float gr_viewx, gr_viewy, gr_viewz; float gr_viewsin, gr_viewcos; -static fixed_t dup_viewx, dup_viewy, dup_viewz; - static angle_t gr_aimingangle; static float gr_viewludsin, gr_viewludcos; @@ -528,7 +526,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t // HWR_RenderPlane // Render a floor or ceiling convex polygon -void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap, subsector_t *subsector) +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { polyvertex_t * pv; float height; //constant y for all points on the convex flat polygon @@ -629,6 +627,9 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei // reference point for flat texture coord for each vertex around the polygon flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize); flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); + + // transform + v3d = planeVerts; if (FOFsector != NULL) { @@ -681,32 +682,39 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } -#define SETUP3DVERT(vert, vx, vy) {\ - /* Hurdler: add scrolling texture on floor/ceiling */\ - vert->s = (float)(((vx) / fflatsize) - flatxref + scrollx);\ - vert->t = (float)(flatyref - ((vy) / fflatsize) + scrolly);\ -\ - /* Need to rotate before translate */\ - if (angle) /* Only needs to be done if there's an altered angle */\ - {\ - tempxsow = FLOAT_TO_FIXED(vert->s);\ - tempytow = FLOAT_TO_FIXED(vert->t);\ - vert->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\ - vert->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\ - }\ -\ - vert->x = (vx);\ - vert->y = height;\ - vert->z = (vy);\ -\ - if (slope)\ - {\ - fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ - vert->y = FIXED_TO_FLOAT(fixedheight);\ - }\ -} - for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++) - SETUP3DVERT(v3d, pv->x, pv->y); + for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) + { + // Hurdler: add scrolling texture on floor/ceiling + v3d->s = (float)((pv->x / fflatsize) - flatxref + scrollx); + v3d->t = (float)(flatyref - (pv->y / fflatsize) + scrolly); + + //v3d->s = (float)(pv->x / fflatsize); + //v3d->t = (float)(pv->y / fflatsize); + + // Need to rotate before translate + if (angle) // Only needs to be done if there's an altered angle + { + tempxsow = FLOAT_TO_FIXED(v3d->s); + tempytow = FLOAT_TO_FIXED(v3d->t); + v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + } + + //v3d->s = (float)(v3d->s - flatxref + scrollx); + //v3d->t = (float)(flatyref - v3d->t + scrolly); + + v3d->x = pv->x; + v3d->y = height; + v3d->z = pv->y; + +#ifdef ESLOPE + if (slope) + { + fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y)); + v3d->y = FIXED_TO_FLOAT(fixedheight); + } +#endif + } HWR_Lighting(&Surf, lightlevel, planecolormap); @@ -3172,7 +3180,7 @@ void HWR_Subsector(size_t num) // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap, sub); + PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap); } } } @@ -3188,7 +3196,7 @@ void HWR_Subsector(size_t num) // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap, sub); + PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap); } } } @@ -3254,7 +3262,7 @@ void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gr_frontsector, false)); light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_RenderPlane(&extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); } } @@ -3306,7 +3314,7 @@ void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gr_frontsector, true)); light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_RenderPlane(&extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); } } } @@ -5453,11 +5461,6 @@ void HWR_SetTransform(float fpov, player_t *player) postimg_t *postprocessor = &postimgtype[0]; INT32 i; - // copy view cam position for local use - dup_viewx = viewx; - dup_viewy = viewy; - dup_viewz = viewz; - gr_viewx = FIXED_TO_FLOAT(viewx); gr_viewy = FIXED_TO_FLOAT(viewy); gr_viewz = FIXED_TO_FLOAT(viewz); @@ -5657,7 +5660,6 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * HWR_PortalFrame(rootportal);// for portalclipsector, it could have gone null from search HWR_PortalClipping(rootportal); } - //drawcount = 0; validcount++; if (cv_grbatching.value) HWD.pfnStartBatching(); @@ -5696,8 +5698,18 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * HWR_SetTransform(fpov, player);// restore transform } gr_collect_skywalls = false; + + ps_numsprites.value.i = gr_visspritecount; + PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); + PS_STOP_TIMING(ps_hw_spritesorttime); + PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); + PS_STOP_TIMING(ps_hw_spritedrawtime); + + ps_numdrawnodes.value.i = 0; + ps_hw_nodesorttime.value.p = 0; + ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } // free memory from portal list allocated by calls to Add2Lines @@ -5713,6 +5725,7 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * // TODO: is it okay if stencil test is on all the time even when its not needed? } + // ========================================================================== // Render the current frame. // ========================================================================== @@ -5870,19 +5883,8 @@ void HWR_RenderSinglePortal(portal_t *portal, size_t portalnum, float fpov, play // Render the BSP from the new viewpoint. portalcullsector = gr_portalcullsectors[portalnum]; HWR_RenderBSPNode((INT32)numnodes - 1); - - // Draw MD2 and sprites - ps_numsprites.value.i = gr_visspritecount; - PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); - PS_STOP_TIMING(ps_hw_spritesorttime); - PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); - PS_STOP_TIMING(ps_hw_spritedrawtime); - - ps_numdrawnodes.value.i = 0; - ps_hw_nodesorttime.value.p = 0; - ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 51a362c9e..4c1f893c1 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -111,7 +111,7 @@ void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); // hw_main.c: Planes -void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap, subsector_t *subsector); +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); #ifdef POLYOBJECTS -- 2.54.0 From 8737a40a4de107ffc0770f360111539670030ef4 Mon Sep 17 00:00:00 2001 From: lug420 Date: Thu, 7 Sep 2023 23:55:26 +0200 Subject: [PATCH 19/28] bleh --- src/hardware/hw_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 258573578..9e91e53cd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5846,7 +5846,6 @@ void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox) HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); HWD.pfnSetShader(0); - //drawcount = 0; validcount++; portalclipline = NULL; -- 2.54.0 From b1b592f88d4ed15ad01a0d219eb201a3525a873d Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Fri, 8 Sep 2023 10:38:48 +0200 Subject: [PATCH 20/28] readd the stuff blubuabb --- src/hardware/hw_main.c | 101 ++++++++++++++++++++--------------------- src/hardware/hw_main.h | 2 +- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9e91e53cd..2db41707f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -196,6 +196,8 @@ FTransform atransform; static float gr_viewx, gr_viewy, gr_viewz; float gr_viewsin, gr_viewcos; +static fixed_t dup_viewx, dup_viewy, dup_viewz; + static angle_t gr_aimingangle; static float gr_viewludsin, gr_viewludcos; @@ -526,7 +528,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t // HWR_RenderPlane // Render a floor or ceiling convex polygon -void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap, subsector_t *subsector) { polyvertex_t * pv; float height; //constant y for all points on the convex flat polygon @@ -627,9 +629,6 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei // reference point for flat texture coord for each vertex around the polygon flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize); flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); - - // transform - v3d = planeVerts; if (FOFsector != NULL) { @@ -682,39 +681,32 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } - for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) - { - // Hurdler: add scrolling texture on floor/ceiling - v3d->s = (float)((pv->x / fflatsize) - flatxref + scrollx); - v3d->t = (float)(flatyref - (pv->y / fflatsize) + scrolly); - - //v3d->s = (float)(pv->x / fflatsize); - //v3d->t = (float)(pv->y / fflatsize); - - // Need to rotate before translate - if (angle) // Only needs to be done if there's an altered angle - { - tempxsow = FLOAT_TO_FIXED(v3d->s); - tempytow = FLOAT_TO_FIXED(v3d->t); - v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); - } - - //v3d->s = (float)(v3d->s - flatxref + scrollx); - //v3d->t = (float)(flatyref - v3d->t + scrolly); - - v3d->x = pv->x; - v3d->y = height; - v3d->z = pv->y; - -#ifdef ESLOPE - if (slope) - { - fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y)); - v3d->y = FIXED_TO_FLOAT(fixedheight); - } -#endif - } +#define SETUP3DVERT(vert, vx, vy) {\ + /* Hurdler: add scrolling texture on floor/ceiling */\ + vert->s = (float)(((vx) / fflatsize) - flatxref + scrollx);\ + vert->t = (float)(flatyref - ((vy) / fflatsize) + scrolly);\ +\ + /* Need to rotate before translate */\ + if (angle) /* Only needs to be done if there's an altered angle */\ + {\ + tempxsow = FLOAT_TO_FIXED(vert->s);\ + tempytow = FLOAT_TO_FIXED(vert->t);\ + vert->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\ + vert->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\ + }\ +\ + vert->x = (vx);\ + vert->y = height;\ + vert->z = (vy);\ +\ + if (slope)\ + {\ + fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ + vert->y = FIXED_TO_FLOAT(fixedheight);\ + }\ +} + for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++) + SETUP3DVERT(v3d, pv->x, pv->y); HWR_Lighting(&Surf, lightlevel, planecolormap); @@ -3180,7 +3172,7 @@ void HWR_Subsector(size_t num) // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap); + PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap, sub); } } } @@ -3196,7 +3188,7 @@ void HWR_Subsector(size_t num) // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap); + PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap, sub); } } } @@ -3262,7 +3254,7 @@ void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gr_frontsector, false)); light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_RenderPlane(&extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); } } @@ -3314,7 +3306,7 @@ void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gr_frontsector, true)); light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_RenderPlane(&extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap, sub); } } } @@ -5461,6 +5453,11 @@ void HWR_SetTransform(float fpov, player_t *player) postimg_t *postprocessor = &postimgtype[0]; INT32 i; + // copy view cam position for local use + dup_viewx = viewx; + dup_viewy = viewy; + dup_viewz = viewz; + gr_viewx = FIXED_TO_FLOAT(viewx); gr_viewy = FIXED_TO_FLOAT(viewy); gr_viewz = FIXED_TO_FLOAT(viewz); @@ -5660,6 +5657,7 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * HWR_PortalFrame(rootportal);// for portalclipsector, it could have gone null from search HWR_PortalClipping(rootportal); } + //drawcount = 0; validcount++; if (cv_grbatching.value) HWD.pfnStartBatching(); @@ -5698,18 +5696,8 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * HWR_SetTransform(fpov, player);// restore transform } gr_collect_skywalls = false; - - ps_numsprites.value.i = gr_visspritecount; - PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); - PS_STOP_TIMING(ps_hw_spritesorttime); - PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); - PS_STOP_TIMING(ps_hw_spritedrawtime); - - ps_numdrawnodes.value.i = 0; - ps_hw_nodesorttime.value.p = 0; - ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } // free memory from portal list allocated by calls to Add2Lines @@ -5882,8 +5870,19 @@ void HWR_RenderSinglePortal(portal_t *portal, size_t portalnum, float fpov, play // Render the BSP from the new viewpoint. portalcullsector = gr_portalcullsectors[portalnum]; HWR_RenderBSPNode((INT32)numnodes - 1); + + // Draw MD2 and sprites + ps_numsprites.value.i = gr_visspritecount; + PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); + PS_STOP_TIMING(ps_hw_spritesorttime); + PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); + PS_STOP_TIMING(ps_hw_spritedrawtime); + + ps_numdrawnodes.value.i = 0; + ps_hw_nodesorttime.value.p = 0; + ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4c1f893c1..51a362c9e 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -111,7 +111,7 @@ void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); // hw_main.c: Planes -void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap, subsector_t *subsector); void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); #ifdef POLYOBJECTS -- 2.54.0 From 7beab3b582f0c7455a9676f3ae15ebe987e8aa23 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Fri, 8 Sep 2023 10:42:31 +0200 Subject: [PATCH 21/28] fix the sprite renderstats again aAAaaa --- src/hardware/hw_main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2db41707f..49bdaa499 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5696,8 +5696,18 @@ void RecursivePortalRendering(portal_t *rootportal, const float fpov, player_t * HWR_SetTransform(fpov, player);// restore transform } gr_collect_skywalls = false; + + ps_numsprites.value.i = gr_visspritecount; + PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); + PS_STOP_TIMING(ps_hw_spritesorttime); + PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); + PS_STOP_TIMING(ps_hw_spritedrawtime); + + ps_numdrawnodes.value.i = 0; + ps_hw_nodesorttime.value.p = 0; + ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } // free memory from portal list allocated by calls to Add2Lines @@ -5871,18 +5881,8 @@ void HWR_RenderSinglePortal(portal_t *portal, size_t portalnum, float fpov, play portalcullsector = gr_portalcullsectors[portalnum]; HWR_RenderBSPNode((INT32)numnodes - 1); - // Draw MD2 and sprites - ps_numsprites.value.i = gr_visspritecount; - PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); - PS_STOP_TIMING(ps_hw_spritesorttime); - PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); - PS_STOP_TIMING(ps_hw_spritedrawtime); - - ps_numdrawnodes.value.i = 0; - ps_hw_nodesorttime.value.p = 0; - ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); } -- 2.54.0 From 1c9ea1eb2e9bb9e210d93f568dc5797083198cf7 Mon Sep 17 00:00:00 2001 From: lug420 Date: Sat, 9 Sep 2023 01:38:23 +0200 Subject: [PATCH 22/28] fix a crash with rotsprites + clean up this absolute mess --- src/hardware/hw_main.c | 2 +- src/r_patch.c | 2120 +++++++++++++++++++--------------------- src/r_patch.h | 137 ++- src/r_things.c | 2 +- 4 files changed, 1088 insertions(+), 1173 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 49bdaa499..aa9a921e2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5065,7 +5065,7 @@ void HWR_ProjectSprite(mobj_t *thing) rollsum = (thing->rollangle)+(thing->sloperoll); rollangle = R_GetRollAngle(rollsum); - rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle); + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); if (rotsprite != NULL) { diff --git a/src/r_patch.c b/src/r_patch.c index 881ca41de..efd49f5e2 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1,1102 +1,1018 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 2005-2009 by Andrey "entryway" Budko. -// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019-2020 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file r_patch.c -/// \brief Patch generation. - -#include "byteptr.h" -#include "dehacked.h" -#include "i_video.h" -#include "r_data.h" -#include "r_draw.h" -#include "r_patch.h" -#include "r_things.h" -#include "z_zone.h" -#include "w_wad.h" - -#ifdef HWRENDER -#include "hardware/hw_glob.h" -#endif - -static unsigned char imgbuf[1<<26]; - -// -// R_CheckIfPatch -// -// Returns true if the lump is a valid patch. -// -boolean R_CheckIfPatch(lumpnum_t lump) -{ - size_t size; - INT16 width, height; - patch_t *patch; - boolean result; - - size = W_LumpLength(lump); - - // minimum length of a valid Doom patch - if (size < 13) - return false; - - patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); - - width = patch->width; - height = patch->height; - - result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4)); - - if (result) - { - // The dimensions seem like they might be valid for a patch, so - // check the column directory for extra security. All columns - // must begin after the column directory, and none of them must - // point past the end of the patch. - INT16 x; - - for (x = 0; x < width; x++) - { - UINT32 ofs = LONG(patch->columnofs[x]); - - // Need one byte for an empty column (but there's patches that don't know that!) - if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size) - { - result = false; - break; - } - } - } - - return result; -} - -// -// R_TextureToFlat -// -// Convert a texture to a flat. -// -void R_TextureToFlat(size_t tex, UINT8 *flat) -{ - texture_t *texture = textures[tex]; - - fixed_t col, ofs; - column_t *column; - UINT8 *desttop, *dest, *deststop; - UINT8 *source; - - // yea - R_CheckTextureCache(tex); - - desttop = flat; - deststop = desttop + (texture->width * texture->height); - - for (col = 0; col < texture->width; col++, desttop++) - { - // no post_t info - if (!texture->holes) - { - column = (column_t *)(R_GetColumn(tex, col)); - source = (UINT8 *)(column); - dest = desttop; - for (ofs = 0; dest < deststop && ofs < texture->height; ofs++) - { - if (source[ofs] != TRANSPARENTPIXEL) - *dest = source[ofs]; - dest += texture->width; - } - } - else - { - INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3); - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - - dest = desttop + (topdelta * texture->width); - source = (UINT8 *)column + 3; - for (ofs = 0; dest < deststop && ofs < column->length; ofs++) - { - if (source[ofs] != TRANSPARENTPIXEL) - *dest = source[ofs]; - dest += texture->width; - } - column = (column_t *)((UINT8 *)column + column->length + 4); - } - } - } -} - -// -// R_PatchToFlat -// -// Convert a patch to a flat. -// -void R_PatchToFlat(patch_t *patch, UINT8 *flat) -{ - fixed_t col, ofs; - column_t *column; - UINT8 *desttop, *dest, *deststop; - UINT8 *source; - - desttop = flat; - deststop = desttop + (SHORT(patch->width) * SHORT(patch->height)); - - for (col = 0; col < SHORT(patch->width); col++, desttop++) - { - INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); - - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - - dest = desttop + (topdelta * SHORT(patch->width)); - source = (UINT8 *)(column) + 3; - for (ofs = 0; dest < deststop && ofs < column->length; ofs++) - { - *dest = source[ofs]; - dest += SHORT(patch->width); - } - column = (column_t *)((UINT8 *)column + column->length + 4); - } - } -} - -// -// R_PatchToMaskedFlat -// -// Convert a patch to a masked flat. -// Now, what is a "masked" flat anyway? -// It means the flat uses two bytes to store image data. -// The upper byte is used to store the transparent pixel, -// and the lower byte stores a palette index. -// -void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip) -{ - fixed_t col, ofs; - column_t *column; - UINT16 *desttop, *dest, *deststop; - UINT8 *source; - - desttop = raw; - deststop = desttop + (SHORT(patch->width) * SHORT(patch->height)); - - for (col = 0; col < SHORT(patch->width); col++, desttop++) - { - INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-col) : col])); - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - dest = desttop + (topdelta * SHORT(patch->width)); - source = (UINT8 *)(column) + 3; - for (ofs = 0; dest < deststop && ofs < column->length; ofs++) - { - *dest = source[ofs]; - dest += SHORT(patch->width); - } - column = (column_t *)((UINT8 *)column + column->length + 4); - } - } -} - -// -// R_FlatToPatch -// -// Convert a flat to a patch. -// -patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency) -{ - UINT32 x, y; - UINT8 *img; - UINT8 *imgptr = imgbuf; - UINT8 *colpointers, *startofspan; - size_t size = 0; - - if (!raw) - return NULL; - - // Write image size and offset - WRITEINT16(imgptr, width); - WRITEINT16(imgptr, height); - WRITEINT16(imgptr, leftoffset); - WRITEINT16(imgptr, topoffset); - - // Leave placeholder to column pointers - colpointers = imgptr; - imgptr += width*4; - - // Write columns - for (x = 0; x < width; x++) - { - int lastStartY = 0; - int spanSize = 0; - startofspan = NULL; - - // Write column pointer - WRITEINT32(colpointers, imgptr - imgbuf); - - // Write pixels - for (y = 0; y < height; y++) - { - UINT8 paletteIndex = raw[((y * width) + x)]; - boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true; - - // End span if we have a transparent pixel - if (!opaque) - { - if (startofspan) - WRITEUINT8(imgptr, 0); - startofspan = NULL; - continue; - } - - // Start new column if we need to - if (!startofspan || spanSize == 255) - { - int writeY = y; - - // If we reached the span size limit, finish the previous span - if (startofspan) - WRITEUINT8(imgptr, 0); - - if (y > 254) - { - // Make sure we're aligned to 254 - if (lastStartY < 254) - { - WRITEUINT8(imgptr, 254); - WRITEUINT8(imgptr, 0); - imgptr += 2; - lastStartY = 254; - } - - // Write stopgap empty spans if needed - writeY = y - lastStartY; - - while (writeY > 254) - { - WRITEUINT8(imgptr, 254); - WRITEUINT8(imgptr, 0); - imgptr += 2; - writeY -= 254; - } - } - - startofspan = imgptr; - WRITEUINT8(imgptr, writeY); - imgptr += 2; - spanSize = 0; - - lastStartY = y; - } - - // Write the pixel - WRITEUINT8(imgptr, paletteIndex); - spanSize++; - startofspan[1] = spanSize; - } - - if (startofspan) - WRITEUINT8(imgptr, 0); - - WRITEUINT8(imgptr, 0xFF); - } - - size = imgptr-imgbuf; - img = Z_Malloc(size, PU_STATIC, NULL); - memcpy(img, imgbuf, size); - - Z_Free(raw); - - if (destsize != NULL) - *destsize = size; - return (patch_t *)img; -} - -// -// R_MaskedFlatToPatch -// -// Convert a masked flat to a patch. -// Explanation of "masked" flats in R_PatchToMaskedFlat. -// -patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) -{ - UINT32 x, y; - UINT8 *img; - UINT8 *imgptr = imgbuf; - UINT8 *colpointers, *startofspan; - size_t size = 0; - - if (!raw) - return NULL; - - // Write image size and offset - WRITEINT16(imgptr, width); - WRITEINT16(imgptr, height); - WRITEINT16(imgptr, leftoffset); - WRITEINT16(imgptr, topoffset); - - // Leave placeholder to column pointers - colpointers = imgptr; - imgptr += width*4; - - // Write columns - for (x = 0; x < width; x++) - { - int lastStartY = 0; - int spanSize = 0; - startofspan = NULL; - - // Write column pointer - WRITEINT32(colpointers, imgptr - imgbuf); - - // Write pixels - for (y = 0; y < height; y++) - { - UINT16 pixel = raw[((y * width) + x)]; - UINT8 paletteIndex = (pixel & 0xFF); - UINT8 opaque = (pixel != 0xFF00); // If 1, we have a pixel - - // End span if we have a transparent pixel - if (!opaque) - { - if (startofspan) - WRITEUINT8(imgptr, 0); - startofspan = NULL; - continue; - } - - // Start new column if we need to - if (!startofspan || spanSize == 255) - { - int writeY = y; - - // If we reached the span size limit, finish the previous span - if (startofspan) - WRITEUINT8(imgptr, 0); - - if (y > 254) - { - // Make sure we're aligned to 254 - if (lastStartY < 254) - { - WRITEUINT8(imgptr, 254); - WRITEUINT8(imgptr, 0); - imgptr += 2; - lastStartY = 254; - } - - // Write stopgap empty spans if needed - writeY = y - lastStartY; - - while (writeY > 254) - { - WRITEUINT8(imgptr, 254); - WRITEUINT8(imgptr, 0); - imgptr += 2; - writeY -= 254; - } - } - - startofspan = imgptr; - WRITEUINT8(imgptr, writeY); - imgptr += 2; - spanSize = 0; - - lastStartY = y; - } - - // Write the pixel - WRITEUINT8(imgptr, paletteIndex); - spanSize++; - startofspan[1] = spanSize; - } - - if (startofspan) - WRITEUINT8(imgptr, 0); - - WRITEUINT8(imgptr, 0xFF); - } - - size = imgptr-imgbuf; - img = Z_Malloc(size, PU_STATIC, NULL); - memcpy(img, imgbuf, size); - - if (destsize != NULL) - *destsize = size; - return (patch_t *)img; -} - -// -// R_ParseSpriteInfoFrame -// -// Parse a SPRTINFO frame. -// -static void R_ParseSpriteInfoFrame(spriteinfo_t *info) -{ - char *sprinfoToken; - size_t sprinfoTokenLength; - char *frameChar = NULL; - UINT8 frameFrame = 0xFF; - INT16 frameXPivot = 0; - INT16 frameYPivot = 0; - rotaxis_t frameRotAxis = 0; - - // Sprite identifier - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite frame should be"); - } - sprinfoTokenLength = strlen(sprinfoToken); - if (sprinfoTokenLength != 1) - { - I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken); - } - else - frameChar = sprinfoToken; - - frameFrame = R_Char2Frame(frameChar[0]); - Z_Free(sprinfoToken); - - // Left Curly Brace - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - I_Error("Error parsing SPRTINFO lump: Missing sprite info"); - else - { - if (strcmp(sprinfoToken,"{")==0) - { - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info should be"); - } - while (strcmp(sprinfoToken,"}")!=0) - { - if (stricmp(sprinfoToken, "XPIVOT")==0) - { - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - frameXPivot = atoi(sprinfoToken); - } - else if (stricmp(sprinfoToken, "YPIVOT")==0) - { - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - frameYPivot = atoi(sprinfoToken); - } - else if (stricmp(sprinfoToken, "ROTAXIS")==0) - { - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - if ((stricmp(sprinfoToken, "X")==0) || (stricmp(sprinfoToken, "XAXIS")==0) || (stricmp(sprinfoToken, "ROLL")==0)) - frameRotAxis = ROTAXIS_X; - else if ((stricmp(sprinfoToken, "Y")==0) || (stricmp(sprinfoToken, "YAXIS")==0) || (stricmp(sprinfoToken, "PITCH")==0)) - frameRotAxis = ROTAXIS_Y; - else if ((stricmp(sprinfoToken, "Z")==0) || (stricmp(sprinfoToken, "ZAXIS")==0) || (stricmp(sprinfoToken, "YAW")==0)) - frameRotAxis = ROTAXIS_Z; - } - Z_Free(sprinfoToken); - - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace should be"); - } - } - } - Z_Free(sprinfoToken); - } - - // set fields - info->pivot[frameFrame].x = frameXPivot; - info->pivot[frameFrame].y = frameYPivot; - info->pivot[frameFrame].rotaxis = frameRotAxis; -} - -// -// R_ParseSpriteInfo -// -// Parse a SPRTINFO lump. -// -static void R_ParseSpriteInfo(boolean spr2) -{ - spriteinfo_t *info; - char *sprinfoToken; - size_t sprinfoTokenLength; - char newSpriteName[5]; // no longer dynamically allocated - spritenum_t sprnum = NUMSPRITES; - //playersprite_t spr2num = NUMPLAYERSPRITES; - INT32 i; - INT32 skinnumbers[MAXSKINS]; // >variable 'skinnumbers' set but not used >compile error when commented out - INT32 foundskins = 0; - - // Sprite name - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be"); - } - sprinfoTokenLength = strlen(sprinfoToken); - if (sprinfoTokenLength != 4) - { - I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" isn't 4 characters long",sprinfoToken); - } - else - { - memset(&newSpriteName, 0, 5); - M_Memcpy(newSpriteName, sprinfoToken, sprinfoTokenLength); - // ^^ we've confirmed that the token is == 4 characters so it will never overflow a 5 byte char buffer - strupr(newSpriteName); // Just do this now so we don't have to worry about it - } - Z_Free(sprinfoToken); - - if (!spr2) - { - for (i = 0; i <= NUMSPRITES; i++) - { - if (i == NUMSPRITES) - I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); - if (!memcmp(newSpriteName,sprnames[i],4)) - { - sprnum = i; - break; - } - } - } - else - { - /*for (i = 0; i <= NUMPLAYERSPRITES; i++) - { - if (i == NUMPLAYERSPRITES) - I_Error("Error parsing SPRTINFO lump: Unknown sprite2 name \"%s\"", newSpriteName); - if (!memcmp(newSpriteName,spr2names[i],4)) - { - spr2num = i; - break; - } - }*/ - // Fuckal: 2.1; playersprites don't exist - } - - // allocate a spriteinfo - info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL); - info->available = true; - - // Left Curly Brace - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where open curly brace for sprite \"%s\" should be",newSpriteName); - } - if (strcmp(sprinfoToken,"{")==0) - { - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where definition for sprite \"%s\" should be",newSpriteName); - } - while (strcmp(sprinfoToken,"}")!=0) - { - if (stricmp(sprinfoToken, "SKIN")==0) - { - INT32 skinnum; - char *skinName = NULL; - if (!spr2) - I_Error("Error parsing SPRTINFO lump: \"SKIN\" token found outside of a sprite2 definition"); - - Z_Free(sprinfoToken); - - // Skin name - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be"); - } - - // copy skin name yada yada - sprinfoTokenLength = strlen(sprinfoToken); - skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL); - M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char)); - skinName[sprinfoTokenLength] = '\0'; - strlwr(skinName); - Z_Free(sprinfoToken); - - skinnum = R_SkinAvailable(skinName); - if (skinnum == -1) - I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName); - - skinnumbers[foundskins] = skinnum; - foundskins++; - } - else if (stricmp(sprinfoToken, "FRAME")==0) - { - R_ParseSpriteInfoFrame(info); - Z_Free(sprinfoToken); - /*if (spr2) - { - if (!foundskins) - I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition"); - for (i = 0; i < foundskins; i++) - { - size_t skinnum = skinnumbers[i]; - skin_t *skin = &skins[skinnum]; - spriteinfo_t *sprinfo = skin->sprinfo; -#ifdef ROTSPRITE - R_FreeSkinRotSprite(skinnum); -#endif - M_Memcpy(&sprinfo[spr2num], info, sizeof(spriteinfo_t)); - } - } - else*/ - M_Memcpy(&spriteinfo[sprnum], info, sizeof(spriteinfo_t)); - } - else - { - I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\" in sprite %s",sprinfoToken,newSpriteName); - } - - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) - { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace for sprite \"%s\" should be",newSpriteName); - } - } - } - else - { - I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken); - } - Z_Free(sprinfoToken); - Z_Free(info); -} - -// -// R_ParseSPRTINFOLump -// -// Read a SPRTINFO lump. -// -void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum) -{ - char *sprinfoLump; - size_t sprinfoLumpLength; - char *sprinfoText; - char *sprinfoToken; - - // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll - // need to make a space of memory where I can ensure that it will terminate - // correctly. Start by loading the relevant data from the WAD. - sprinfoLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); - // If that didn't exist, we have nothing to do here. - if (sprinfoLump == NULL) return; - // If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly. - sprinfoLumpLength = W_LumpLengthPwad(wadNum, lumpNum); - sprinfoText = (char *)Z_Malloc((sprinfoLumpLength+1)*sizeof(char),PU_STATIC,NULL); - // Now move the contents of the lump into this new location. - memmove(sprinfoText,sprinfoLump,sprinfoLumpLength); - // Make damn well sure the last character in our new memory location is \0. - sprinfoText[sprinfoLumpLength] = '\0'; - // Finally, free up the memory from the first data load, because we really - // don't need it. - Z_Free(sprinfoLump); - - sprinfoToken = M_GetToken(sprinfoText); - while (sprinfoToken != NULL) - { - if (!stricmp(sprinfoToken, "SPRITE")) - R_ParseSpriteInfo(false); - else if (!stricmp(sprinfoToken, "SPRITE2")) - R_ParseSpriteInfo(true); - else - I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\"", sprinfoToken); - Z_Free(sprinfoToken); - sprinfoToken = M_GetToken(NULL); - } - Z_Free((void *)sprinfoText); -} - -// -// R_LoadSpriteInfoLumps -// -// Load and read every SPRTINFO lump from the specified file. -// -void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) -{ - lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo; - UINT16 i; - char *name; - - for (i = 0; i < numlumps; i++, lumpinfo++) - { - name = lumpinfo->name; - // Load SPRTINFO and SPR_ lumps as SpriteInfo - if (!memcmp(name, "SPRTINFO", 8) || !memcmp(name, "SPR_", 4)) - R_ParseSPRTINFOLump(wadnum, i); - } -} - -static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) -{ - fixed_t ofs; - column_t *column; - UINT8 *source; - - if (x >= 0 && x < SHORT(patch->width)) - { - INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-x) : x])); - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (UINT8 *)(column) + 3; - for (ofs = 0; ofs < column->length; ofs++) - { - if ((topdelta + ofs) == y) - return source[ofs]; - } - column = (column_t *)((UINT8 *)column + column->length + 4); - } - } - - return 0xFF00; -} - -#ifdef ROTSPRITE -// -// R_GetRollAngle -// -// Angles precalculated in R_InitSprites. -// -fixed_t rollcosang[ROTANGLES]; -fixed_t rollsinang[ROTANGLES]; -INT32 R_GetRollAngle(angle_t rollangle) -{ - INT32 ra = AngleFixed(rollangle)>>FRACBITS; -#if (ROTANGDIFF > 1) - ra += (ROTANGDIFF/2); -#endif - ra /= ROTANGDIFF; - ra %= ROTANGLES; - return ra; -} - -patch_t *Patch_GetRotatedSprite( - spriteframe_t *sprite, - size_t frame, size_t spriteangle, - boolean flip, void *info, - INT32 rotationangle) -{ - rotsprite_t *rotsprite; - spriteinfo_t *sprinfo = (spriteinfo_t *)info; - boolean adjustfeet; - - adjustfeet = (rendermode == render_none); - - INT32 idx = rotationangle; - UINT8 type = (adjustfeet ? 1 : 0); - - if (rotationangle < 1 || rotationangle >= ROTANGLES) - return NULL; - - rotsprite = sprite->rotated[type][spriteangle]; - - if (rotsprite == NULL) - { - rotsprite = RotatedPatch_Create(ROTANGLES); - sprite->rotated[type][spriteangle] = rotsprite; - } - - if (flip) - idx += rotsprite->angles; - - if (rotsprite->patches[idx] == NULL) - { - patch_t *patch; - INT32 xpivot = 0, ypivot = 0; - lumpnum_t lump = sprite->lumppat[spriteangle]; - - if (lump == LUMPERROR) - return NULL; - - patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); - - if (sprinfo->available) - { - xpivot = sprinfo->pivot[frame].x; - ypivot = sprinfo->pivot[frame].y; - } - else - { - xpivot = patch->leftoffset; - ypivot = patch->height / 2; - } - - RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip); - - //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer - if (adjustfeet) - ((patch_t *)rotsprite->patches[idx])->topoffset += FEETADJUST>>FRACBITS; - - // free image data - Z_Free(patch); - } - - return rotsprite->patches[idx]; -} - -rotsprite_t *RotatedPatch_Create(INT32 numangles) -{ - rotsprite_t *rotsprite = Z_Calloc(sizeof(rotsprite_t), PU_STATIC, NULL); - rotsprite->angles = numangles; - rotsprite->patches = Z_Calloc(rotsprite->angles * 2 * sizeof(void *), PU_STATIC, NULL); - return rotsprite; -} - -static void RotatedPatch_CalculateDimensions( - INT32 width, INT32 height, - fixed_t ca, fixed_t sa, - INT32 *newwidth, INT32 *newheight) -{ - fixed_t fixedwidth = (width * FRACUNIT); - fixed_t fixedheight = (height * FRACUNIT); - - fixed_t w1 = abs(FixedMul(fixedwidth, ca) - FixedMul(fixedheight, sa)); - fixed_t w2 = abs(FixedMul(-fixedwidth, ca) - FixedMul(fixedheight, sa)); - fixed_t h1 = abs(FixedMul(fixedwidth, sa) + FixedMul(fixedheight, ca)); - fixed_t h2 = abs(FixedMul(-fixedwidth, sa) + FixedMul(fixedheight, ca)); - - w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2))); - w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2))); - h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2))); - h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2))); - - *newwidth = max(width, max(w1, w2)); - *newheight = max(height, max(h1, h2)); -} - -static patch_t *R_CreateHardwarePatch(patch_t *patch) -{ - GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - grPatch->rawpatch = patch; - //sprframe->rotsprite.patch[rot][angle] = (patch_t *)grPatch; - HWR_MakePatch(patch, grPatch, grPatch->mipmap, false); - return (patch_t *)grPatch; -} - -// -// R_CacheRotSprite -// -// Create a rotated sprite. -// -void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, UINT8 flip) -{ - UINT32 i; - patch_t *rotated, *hwpatch; - UINT16 *rawdst, *rawconv; - size_t size; - INT32 bflip = (flip != 0x00); - - INT32 width = patch->width; - INT32 height = patch->height; - INT32 leftoffset = patch->leftoffset; - INT32 newwidth, newheight; - - fixed_t ca = rollcosang[angle]; - fixed_t sa = rollsinang[angle]; - fixed_t xcenter, ycenter; - INT32 idx = angle; - INT32 x, y; - INT32 sx, sy; - INT32 dx, dy; - INT32 ox, oy; - INT32 minx, miny, maxx, maxy; - - // Don't cache angle = 0 - if (angle < 1 || angle >= ROTANGLES) - return; - - if (flip) - { - idx += rotsprite->angles; - xpivot = width - xpivot; - leftoffset = width - leftoffset; - } - - - if (rotsprite->patches[idx]) - return; - - // Find the dimensions of the rotated patch. - RotatedPatch_CalculateDimensions(width, height, ca, sa, &newwidth, &newheight); - - xcenter = (xpivot * FRACUNIT); - ycenter = (ypivot * FRACUNIT); - - if (xpivot != width / 2 || ypivot != height / 2) - { - newwidth *= 2; - newheight *= 2; - } - - minx = newwidth; - miny = newheight; - maxx = 0; - maxy = 0; - - - // Draw the rotated sprite to a temporary buffer. - size = (newwidth * newheight); - if (!size) - size = (width * height); - - rawdst = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL); - for (i = 0; i < size; i++) - rawdst[i] = 0xFF00; - - for (dy = 0; dy < newheight; dy++) - { - for (dx = 0; dx < newwidth; dx++) - { - x = (dx - (newwidth / 2)) * FRACUNIT; - y = (dy - (newheight / 2)) * FRACUNIT; - sx = FixedMul(x, ca) + FixedMul(y, sa) + xcenter; - sy = -FixedMul(x, sa) + FixedMul(y, ca) + ycenter; - - sx >>= FRACBITS; - sy >>= FRACBITS; - - if (sx >= 0 && sy >= 0 && sx < width && sy < height) - rawdst[(dy*newwidth)+dx] = GetPatchPixel(patch, sx, sy, bflip); - } - } - - - ox = (newwidth / 2) + (leftoffset - xpivot); - oy = (newheight / 2) + (patch->topoffset - ypivot); - width = (maxx+1 - minx); - height = (maxy+1 - miny); - - if ((unsigned)(width * height) > size) - { - UINT16 *src, *dest; - - - size = (width * height); - rawconv = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL); - - src = &rawdst[(miny * newwidth) + minx]; - dest = rawconv; - dy = height; - - - while (dy--) - { - M_Memcpy(dest, src, width * sizeof(UINT16)); - dest += width; - src += newwidth; - } - - - ox -= minx; - oy -= miny; - - - Z_Free(rawdst); - } - else - { - rawconv = rawdst; - width = newwidth; - height = newheight; - } - - // make patch - rotated = R_MaskedFlatToPatch(rawconv, width, height, 0, 0, &size); - { - rotated->leftoffset = ox; - rotated->topoffset = oy; - } -#ifdef HWRENDER - if (rendermode == render_opengl) - { - hwpatch = R_CreateHardwarePatch(rotated); - } -#endif // HWRENDER - - //Z_ChangeTag(rotated, PU_PATCH_ROTATED); // important for memory clearing -#ifdef HWRENDER - if (rendermode == render_opengl) - Z_SetUser(hwpatch, (void **)(&rotsprite->patches[idx])); - else -#endif - Z_SetUser(rotated, (void **)(&rotsprite->patches[idx])); - - Z_Free(rawconv); - - //rotated->leftoffset = ox; - //rotated->topoffset = oy; - -} - -// -// R_FreeSingleRotSprite -// -// IS DEAD BECAUSE OF SIGSEG HELL -// - -// -// R_FreeSkinRotSprite -// -// Free sprite rotation data from memory, for a skin. -// Calls R_FreeSingleRotSprite. -// -/*void R_FreeSkinRotSprite(size_t skinnum) -{ - size_t i; - skin_t *skin = &skins[skinnum]; - spritedef_t *skinsprites = skin->sprites; - for (i = 0; i < NUMPLAYERSPRITES*2; i++) - { - R_FreeSingleRotSprite(skinsprites); - skinsprites++; - } -}*/ - -// -// R_FreeAllRotSprite -// -// Free ALL sprite rotation data from memory. -// -void R_FreeAllRotSprite(void) -{ - //INT32 i; - size_t s; - /*for (i = 0; i < numskins; ++i) - R_FreeSkinRotSprite(i);*/ -} -#endif +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 2005-2009 by Andrey "entryway" Budko. +// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_patch.c +/// \brief Patch generation. + +#include "byteptr.h" +#include "dehacked.h" +#include "i_video.h" +#include "r_data.h" +#include "r_draw.h" +#include "r_patch.h" +#include "r_things.h" +#include "z_zone.h" +#include "w_wad.h" + +#ifdef HWRENDER +#include "hardware/hw_glob.h" +#endif + +static unsigned char imgbuf[1<<26]; + +// +// R_CheckIfPatch +// +// Returns true if the lump is a valid patch. +// +boolean R_CheckIfPatch(lumpnum_t lump) +{ + size_t size; + INT16 width, height; + patch_t *patch; + boolean result; + + size = W_LumpLength(lump); + + // minimum length of a valid Doom patch + if (size < 13) + return false; + + patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); + + width = patch->width; + height = patch->height; + + result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4)); + + if (result) + { + // The dimensions seem like they might be valid for a patch, so + // check the column directory for extra security. All columns + // must begin after the column directory, and none of them must + // point past the end of the patch. + INT16 x; + + for (x = 0; x < width; x++) + { + UINT32 ofs = LONG(patch->columnofs[x]); + + // Need one byte for an empty column (but there's patches that don't know that!) + if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size) + { + result = false; + break; + } + } + } + + return result; +} + +// +// R_TextureToFlat +// +// Convert a texture to a flat. +// +void R_TextureToFlat(size_t tex, UINT8 *flat) +{ + texture_t *texture = textures[tex]; + + fixed_t col, ofs; + column_t *column; + UINT8 *desttop, *dest, *deststop; + UINT8 *source; + + // yea + R_CheckTextureCache(tex); + + desttop = flat; + deststop = desttop + (texture->width * texture->height); + + for (col = 0; col < texture->width; col++, desttop++) + { + // no post_t info + if (!texture->holes) + { + column = (column_t *)(R_GetColumn(tex, col)); + source = (UINT8 *)(column); + dest = desttop; + for (ofs = 0; dest < deststop && ofs < texture->height; ofs++) + { + if (source[ofs] != TRANSPARENTPIXEL) + *dest = source[ofs]; + dest += texture->width; + } + } + else + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3); + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + + dest = desttop + (topdelta * texture->width); + source = (UINT8 *)column + 3; + for (ofs = 0; dest < deststop && ofs < column->length; ofs++) + { + if (source[ofs] != TRANSPARENTPIXEL) + *dest = source[ofs]; + dest += texture->width; + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } + } +} + +// +// R_PatchToFlat +// +// Convert a patch to a flat. +// +void R_PatchToFlat(patch_t *patch, UINT8 *flat) +{ + fixed_t col, ofs; + column_t *column; + UINT8 *desttop, *dest, *deststop; + UINT8 *source; + + desttop = flat; + deststop = desttop + (SHORT(patch->width) * SHORT(patch->height)); + + for (col = 0; col < SHORT(patch->width); col++, desttop++) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); + + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + + dest = desttop + (topdelta * SHORT(patch->width)); + source = (UINT8 *)(column) + 3; + for (ofs = 0; dest < deststop && ofs < column->length; ofs++) + { + *dest = source[ofs]; + dest += SHORT(patch->width); + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } +} + +// +// R_PatchToMaskedFlat +// +// Convert a patch to a masked flat. +// Now, what is a "masked" flat anyway? +// It means the flat uses two bytes to store image data. +// The upper byte is used to store the transparent pixel, +// and the lower byte stores a palette index. +// +void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip) +{ + fixed_t col, ofs; + column_t *column; + UINT16 *desttop, *dest, *deststop; + UINT8 *source; + + desttop = raw; + deststop = desttop + (SHORT(patch->width) * SHORT(patch->height)); + + for (col = 0; col < SHORT(patch->width); col++, desttop++) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-col) : col])); + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + dest = desttop + (topdelta * SHORT(patch->width)); + source = (UINT8 *)(column) + 3; + for (ofs = 0; dest < deststop && ofs < column->length; ofs++) + { + *dest = source[ofs]; + dest += SHORT(patch->width); + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } +} + +// +// R_FlatToPatch +// +// Convert a flat to a patch. +// +patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency) +{ + UINT32 x, y; + UINT8 *img; + UINT8 *imgptr = imgbuf; + UINT8 *colpointers, *startofspan; + size_t size = 0; + + if (!raw) + return NULL; + + // Write image size and offset + WRITEINT16(imgptr, width); + WRITEINT16(imgptr, height); + WRITEINT16(imgptr, leftoffset); + WRITEINT16(imgptr, topoffset); + + // Leave placeholder to column pointers + colpointers = imgptr; + imgptr += width*4; + + // Write columns + for (x = 0; x < width; x++) + { + int lastStartY = 0; + int spanSize = 0; + startofspan = NULL; + + // Write column pointer + WRITEINT32(colpointers, imgptr - imgbuf); + + // Write pixels + for (y = 0; y < height; y++) + { + UINT8 paletteIndex = raw[((y * width) + x)]; + boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true; + + // End span if we have a transparent pixel + if (!opaque) + { + if (startofspan) + WRITEUINT8(imgptr, 0); + startofspan = NULL; + continue; + } + + // Start new column if we need to + if (!startofspan || spanSize == 255) + { + int writeY = y; + + // If we reached the span size limit, finish the previous span + if (startofspan) + WRITEUINT8(imgptr, 0); + + if (y > 254) + { + // Make sure we're aligned to 254 + if (lastStartY < 254) + { + WRITEUINT8(imgptr, 254); + WRITEUINT8(imgptr, 0); + imgptr += 2; + lastStartY = 254; + } + + // Write stopgap empty spans if needed + writeY = y - lastStartY; + + while (writeY > 254) + { + WRITEUINT8(imgptr, 254); + WRITEUINT8(imgptr, 0); + imgptr += 2; + writeY -= 254; + } + } + + startofspan = imgptr; + WRITEUINT8(imgptr, writeY); + imgptr += 2; + spanSize = 0; + + lastStartY = y; + } + + // Write the pixel + WRITEUINT8(imgptr, paletteIndex); + spanSize++; + startofspan[1] = spanSize; + } + + if (startofspan) + WRITEUINT8(imgptr, 0); + + WRITEUINT8(imgptr, 0xFF); + } + + size = imgptr-imgbuf; + img = Z_Malloc(size, PU_STATIC, NULL); + memcpy(img, imgbuf, size); + + Z_Free(raw); + + if (destsize != NULL) + *destsize = size; + return (patch_t *)img; +} + +// +// R_MaskedFlatToPatch +// +// Convert a masked flat to a patch. +// Explanation of "masked" flats in R_PatchToMaskedFlat. +// +patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) +{ + UINT32 x, y; + UINT8 *img; + UINT8 *imgptr = imgbuf; + UINT8 *colpointers, *startofspan; + size_t size = 0; + + if (!raw) + return NULL; + + // Write image size and offset + WRITEINT16(imgptr, width); + WRITEINT16(imgptr, height); + WRITEINT16(imgptr, leftoffset); + WRITEINT16(imgptr, topoffset); + + // Leave placeholder to column pointers + colpointers = imgptr; + imgptr += width*4; + + // Write columns + for (x = 0; x < width; x++) + { + int lastStartY = 0; + int spanSize = 0; + startofspan = NULL; + + // Write column pointer + WRITEINT32(colpointers, imgptr - imgbuf); + + // Write pixels + for (y = 0; y < height; y++) + { + UINT16 pixel = raw[((y * width) + x)]; + UINT8 paletteIndex = (pixel & 0xFF); + UINT8 opaque = (pixel != 0xFF00); // If 1, we have a pixel + + // End span if we have a transparent pixel + if (!opaque) + { + if (startofspan) + WRITEUINT8(imgptr, 0); + startofspan = NULL; + continue; + } + + // Start new column if we need to + if (!startofspan || spanSize == 255) + { + int writeY = y; + + // If we reached the span size limit, finish the previous span + if (startofspan) + WRITEUINT8(imgptr, 0); + + if (y > 254) + { + // Make sure we're aligned to 254 + if (lastStartY < 254) + { + WRITEUINT8(imgptr, 254); + WRITEUINT8(imgptr, 0); + imgptr += 2; + lastStartY = 254; + } + + // Write stopgap empty spans if needed + writeY = y - lastStartY; + + while (writeY > 254) + { + WRITEUINT8(imgptr, 254); + WRITEUINT8(imgptr, 0); + imgptr += 2; + writeY -= 254; + } + } + + startofspan = imgptr; + WRITEUINT8(imgptr, writeY); + imgptr += 2; + spanSize = 0; + + lastStartY = y; + } + + // Write the pixel + WRITEUINT8(imgptr, paletteIndex); + spanSize++; + startofspan[1] = spanSize; + } + + if (startofspan) + WRITEUINT8(imgptr, 0); + + WRITEUINT8(imgptr, 0xFF); + } + + size = imgptr-imgbuf; + img = Z_Malloc(size, PU_STATIC, NULL); + memcpy(img, imgbuf, size); + + if (destsize != NULL) + *destsize = size; + return (patch_t *)img; +} + +// +// R_ParseSpriteInfoFrame +// +// Parse a SPRTINFO frame. +// +static void R_ParseSpriteInfoFrame(spriteinfo_t *info) +{ + char *sprinfoToken; + size_t sprinfoTokenLength; + char *frameChar = NULL; + UINT8 frameFrame = 0xFF; + INT16 frameXPivot = 0; + INT16 frameYPivot = 0; + rotaxis_t frameRotAxis = 0; + + // Sprite identifier + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite frame should be"); + } + sprinfoTokenLength = strlen(sprinfoToken); + if (sprinfoTokenLength != 1) + { + I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken); + } + else + frameChar = sprinfoToken; + + frameFrame = R_Char2Frame(frameChar[0]); + Z_Free(sprinfoToken); + + // Left Curly Brace + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + I_Error("Error parsing SPRTINFO lump: Missing sprite info"); + else + { + if (strcmp(sprinfoToken,"{")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info should be"); + } + while (strcmp(sprinfoToken,"}")!=0) + { + if (stricmp(sprinfoToken, "XPIVOT")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + frameXPivot = atoi(sprinfoToken); + } + else if (stricmp(sprinfoToken, "YPIVOT")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + frameYPivot = atoi(sprinfoToken); + } + else if (stricmp(sprinfoToken, "ROTAXIS")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + if ((stricmp(sprinfoToken, "X")==0) || (stricmp(sprinfoToken, "XAXIS")==0) || (stricmp(sprinfoToken, "ROLL")==0)) + frameRotAxis = ROTAXIS_X; + else if ((stricmp(sprinfoToken, "Y")==0) || (stricmp(sprinfoToken, "YAXIS")==0) || (stricmp(sprinfoToken, "PITCH")==0)) + frameRotAxis = ROTAXIS_Y; + else if ((stricmp(sprinfoToken, "Z")==0) || (stricmp(sprinfoToken, "ZAXIS")==0) || (stricmp(sprinfoToken, "YAW")==0)) + frameRotAxis = ROTAXIS_Z; + } + Z_Free(sprinfoToken); + + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace should be"); + } + } + } + Z_Free(sprinfoToken); + } + + // set fields + info->pivot[frameFrame].x = frameXPivot; + info->pivot[frameFrame].y = frameYPivot; + info->pivot[frameFrame].rotaxis = frameRotAxis; +} + +// +// R_ParseSpriteInfo +// +// Parse a SPRTINFO lump. +// +static void R_ParseSpriteInfo(boolean spr2) +{ + spriteinfo_t *info; + char *sprinfoToken; + size_t sprinfoTokenLength; + char newSpriteName[5]; // no longer dynamically allocated + spritenum_t sprnum = NUMSPRITES; + //playersprite_t spr2num = NUMPLAYERSPRITES; + INT32 i; + INT32 skinnumbers[MAXSKINS]; // >variable 'skinnumbers' set but not used >compile error when commented out + INT32 foundskins = 0; + + // Sprite name + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be"); + } + sprinfoTokenLength = strlen(sprinfoToken); + if (sprinfoTokenLength != 4) + { + I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" isn't 4 characters long",sprinfoToken); + } + else + { + memset(&newSpriteName, 0, 5); + M_Memcpy(newSpriteName, sprinfoToken, sprinfoTokenLength); + // ^^ we've confirmed that the token is == 4 characters so it will never overflow a 5 byte char buffer + strupr(newSpriteName); // Just do this now so we don't have to worry about it + } + Z_Free(sprinfoToken); + + if (!spr2) + { + for (i = 0; i <= NUMSPRITES; i++) + { + if (i == NUMSPRITES) + I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); + if (!memcmp(newSpriteName,sprnames[i],4)) + { + sprnum = i; + break; + } + } + } + + // allocate a spriteinfo + info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL); + info->available = true; + + // Left Curly Brace + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where open curly brace for sprite \"%s\" should be",newSpriteName); + } + if (strcmp(sprinfoToken,"{")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where definition for sprite \"%s\" should be",newSpriteName); + } + while (strcmp(sprinfoToken,"}")!=0) + { + if (stricmp(sprinfoToken, "SKIN")==0) + { + INT32 skinnum; + char *skinName = NULL; + if (!spr2) + I_Error("Error parsing SPRTINFO lump: \"SKIN\" token found outside of a sprite2 definition"); + + Z_Free(sprinfoToken); + + // Skin name + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be"); + } + + // copy skin name yada yada + sprinfoTokenLength = strlen(sprinfoToken); + skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL); + M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char)); + skinName[sprinfoTokenLength] = '\0'; + strlwr(skinName); + Z_Free(sprinfoToken); + + skinnum = R_SkinAvailable(skinName); + if (skinnum == -1) + I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName); + + skinnumbers[foundskins] = skinnum; + foundskins++; + } + else if (stricmp(sprinfoToken, "FRAME")==0) + { + R_ParseSpriteInfoFrame(info); + Z_Free(sprinfoToken); + M_Memcpy(&spriteinfo[sprnum], info, sizeof(spriteinfo_t)); + } + else + { + I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\" in sprite %s",sprinfoToken,newSpriteName); + } + + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace for sprite \"%s\" should be",newSpriteName); + } + } + } + else + { + I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken); + } + Z_Free(sprinfoToken); + Z_Free(info); +} + +// +// R_ParseSPRTINFOLump +// +// Read a SPRTINFO lump. +// +void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum) +{ + char *sprinfoLump; + size_t sprinfoLumpLength; + char *sprinfoText; + char *sprinfoToken; + + // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll + // need to make a space of memory where I can ensure that it will terminate + // correctly. Start by loading the relevant data from the WAD. + sprinfoLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); + // If that didn't exist, we have nothing to do here. + if (sprinfoLump == NULL) return; + // If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly. + sprinfoLumpLength = W_LumpLengthPwad(wadNum, lumpNum); + sprinfoText = (char *)Z_Malloc((sprinfoLumpLength+1)*sizeof(char),PU_STATIC,NULL); + // Now move the contents of the lump into this new location. + memmove(sprinfoText,sprinfoLump,sprinfoLumpLength); + // Make damn well sure the last character in our new memory location is \0. + sprinfoText[sprinfoLumpLength] = '\0'; + // Finally, free up the memory from the first data load, because we really + // don't need it. + Z_Free(sprinfoLump); + + sprinfoToken = M_GetToken(sprinfoText); + while (sprinfoToken != NULL) + { + if (!stricmp(sprinfoToken, "SPRITE")) + R_ParseSpriteInfo(false); + else if (!stricmp(sprinfoToken, "SPRITE2")) + R_ParseSpriteInfo(true); + else + I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\"", sprinfoToken); + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + } + Z_Free((void *)sprinfoText); +} + +// +// R_LoadSpriteInfoLumps +// +// Load and read every SPRTINFO lump from the specified file. +// +void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) +{ + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo; + UINT16 i; + char *name; + + for (i = 0; i < numlumps; i++, lumpinfo++) + { + name = lumpinfo->name; + // Load SPRTINFO and SPR_ lumps as SpriteInfo + if (!memcmp(name, "SPRTINFO", 8) || !memcmp(name, "SPR_", 4)) + R_ParseSPRTINFOLump(wadnum, i); + } +} + +static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) +{ + fixed_t ofs; + column_t *column; + UINT8 *source; + + if (x >= 0 && x < SHORT(patch->width)) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-x) : x])); + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (UINT8 *)(column) + 3; + for (ofs = 0; ofs < column->length; ofs++) + { + if ((topdelta + ofs) == y) + return source[ofs]; + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } + + return 0xFF00; +} + +#ifdef ROTSPRITE +// +// R_GetRollAngle +// +// Angles precalculated in R_InitSprites. +// +fixed_t rollcosang[ROTANGLES]; +fixed_t rollsinang[ROTANGLES]; + +INT32 R_GetRollAngle(angle_t rollangle) +{ + INT32 ra = AngleFixed(rollangle)>>FRACBITS; +#if (ROTANGDIFF > 1) + ra += (ROTANGDIFF/2); +#endif + ra /= ROTANGDIFF; + ra %= ROTANGLES; + return ra; +} + +patch_t *Patch_GetRotatedSprite( + spriteframe_t *sprite, + size_t frame, size_t spriteangle, + boolean flip, boolean adjustfeet, + void *info, INT32 rotationangle) +{ + rotsprite_t *rotsprite; + spriteinfo_t *sprinfo = (spriteinfo_t *)info; + INT32 idx = rotationangle; + UINT8 type = (adjustfeet ? 1 : 0); + + if (rotationangle < 1 || rotationangle >= ROTANGLES) + return NULL; + + rotsprite = sprite->rotated[type][spriteangle]; + + if (rotsprite == NULL) + { + rotsprite = RotatedPatch_Create(ROTANGLES); + sprite->rotated[type][spriteangle] = rotsprite; + } + + if (flip) + idx += rotsprite->angles; + + if (rotsprite->patches[idx] == NULL) + { + patch_t *patch; + INT32 xpivot = 0, ypivot = 0; + lumpnum_t lump = sprite->lumppat[spriteangle]; + + if (lump == LUMPERROR) + return NULL; + + patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); + + if (sprinfo->available) + { + xpivot = sprinfo->pivot[frame].x; + ypivot = sprinfo->pivot[frame].y; + } + else + { + xpivot = patch->leftoffset; + ypivot = patch->height / 2; + } + + RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip); + + //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer + if (adjustfeet) + ((patch_t *)rotsprite->patches[idx])->topoffset += FEETADJUST>>FRACBITS; + + // free image data + Z_Free(patch); + } + + return rotsprite->patches[idx]; +} + +rotsprite_t *RotatedPatch_Create(INT32 numangles) +{ + rotsprite_t *rotsprite = Z_Calloc(sizeof(rotsprite_t), PU_STATIC, NULL); + rotsprite->angles = numangles; + rotsprite->patches = Z_Calloc(rotsprite->angles * 2 * sizeof(void *), PU_STATIC, NULL); + return rotsprite; +} + +static void RotatedPatch_CalculateDimensions( + INT32 width, INT32 height, + fixed_t ca, fixed_t sa, + INT32 *newwidth, INT32 *newheight) +{ + fixed_t fixedwidth = (width * FRACUNIT); + fixed_t fixedheight = (height * FRACUNIT); + + fixed_t w1 = abs(FixedMul(fixedwidth, ca) - FixedMul(fixedheight, sa)); + fixed_t w2 = abs(FixedMul(-fixedwidth, ca) - FixedMul(fixedheight, sa)); + fixed_t h1 = abs(FixedMul(fixedwidth, sa) + FixedMul(fixedheight, ca)); + fixed_t h2 = abs(FixedMul(-fixedwidth, sa) + FixedMul(fixedheight, ca)); + + w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2))); + w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2))); + h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2))); + h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2))); + + *newwidth = max(width, max(w1, w2)); + *newheight = max(height, max(h1, h2)); +} + +static patch_t *R_CreateHardwarePatch(patch_t *patch) +{ + GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); + grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); + grPatch->rawpatch = patch; + HWR_MakePatch(patch, grPatch, grPatch->mipmap, false); + return (patch_t *)grPatch; +} + +void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip) +{ + UINT32 i; + patch_t *rotated, *hwpatch; + UINT16 *rawdst, *rawconv; + size_t size; + INT32 bflip = (flip != 0x00); + + INT32 width = patch->width; + INT32 height = patch->height; + INT32 leftoffset = patch->leftoffset; + INT32 newwidth, newheight; + + fixed_t ca = rollcosang[angle]; + fixed_t sa = rollsinang[angle]; + fixed_t xcenter, ycenter; + INT32 idx = angle; + INT32 x, y; + INT32 sx, sy; + INT32 dx, dy; + INT32 ox, oy; + INT32 minx, miny, maxx, maxy; + + // Don't cache angle = 0 + if (angle < 1 || angle >= ROTANGLES) + return; + + if (flip) + { + idx += rotsprite->angles; + xpivot = width - xpivot; + leftoffset = width - leftoffset; + } + + if (rotsprite->patches[idx]) + return; + + // Find the dimensions of the rotated patch. + RotatedPatch_CalculateDimensions(width, height, ca, sa, &newwidth, &newheight); + + xcenter = (xpivot * FRACUNIT); + ycenter = (ypivot * FRACUNIT); + + if (xpivot != width / 2 || ypivot != height / 2) + { + newwidth *= 2; + newheight *= 2; + } + + minx = newwidth; + miny = newheight; + maxx = 0; + maxy = 0; + + // Draw the rotated sprite to a temporary buffer. + size = (newwidth * newheight); + if (!size) + size = (width * height); + rawdst = Z_Calloc(size * sizeof(UINT16), PU_STATIC, NULL); + + for (i = 0; i < size; i++) + rawdst[i] = 0xFF00; + + for (dy = 0; dy < newheight; dy++) + { + for (dx = 0; dx < newwidth; dx++) + { + x = (dx - (newwidth / 2)) * FRACUNIT; + y = (dy - (newheight / 2)) * FRACUNIT; + sx = FixedMul(x, ca) + FixedMul(y, sa) + xcenter; + sy = -FixedMul(x, sa) + FixedMul(y, ca) + ycenter; + + sx >>= FRACBITS; + sy >>= FRACBITS; + + if (sx >= 0 && sy >= 0 && sx < width && sy < height) + rawdst[(dy*newwidth)+dx] = GetPatchPixel(patch, sx, sy, bflip); + } + } + + ox = (newwidth / 2) + (leftoffset - xpivot); + oy = (newheight / 2) + (patch->topoffset - ypivot); + width = (maxx - minx); + height = (maxy - miny); + + if ((unsigned)(width * height) > size) + { + UINT16 *src, *dest; + + size = (width * height); + rawconv = Z_Calloc(size * sizeof(UINT16), PU_STATIC, NULL); + + src = &rawdst[(miny * newwidth) + minx]; + dest = rawconv; + dy = height; + + while (dy--) + { + M_Memcpy(dest, src, width * sizeof(UINT16)); + dest += width; + src += newwidth; + } + + ox -= minx; + oy -= miny; + + Z_Free(rawdst); + } + else + { + rawconv = rawdst; + width = newwidth; + height = newheight; + } + + // make patch + rotated = R_MaskedFlatToPatch(rawconv, width, height, 0, 0, &size); + { + rotated->leftoffset = ox; + rotated->topoffset = oy; + } +#ifdef HWRENDER + if (rendermode == render_opengl) + { + hwpatch = R_CreateHardwarePatch(rotated); + } +#endif // HWRENDER + + //Z_ChangeTag(rotated, PU_PATCH_ROTATED); // important for memory clearing +#ifdef HWRENDER + if (rendermode == render_opengl) + Z_SetUser(hwpatch, (void **)(&rotsprite->patches[idx])); + else +#endif + Z_SetUser(rotated, (void **)(&rotsprite->patches[idx])); + + Z_Free(rawconv); + + rotated->leftoffset = ox; + rotated->topoffset = oy; +} +#endif diff --git a/src/r_patch.h b/src/r_patch.h index 054e28e11..ac8072a43 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -1,69 +1,68 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file r_patch.h -/// \brief Patch generation. - -#ifndef __R_PATCH__ -#define __R_PATCH__ - -#include "r_defs.h" -#include "doomdef.h" - -// Structs -typedef enum -{ - ROTAXIS_X, // Roll (the default) - ROTAXIS_Y, // Pitch - ROTAXIS_Z // Yaw -} rotaxis_t; - -typedef struct -{ - INT32 x, y; - rotaxis_t rotaxis; -} spriteframepivot_t; - -typedef struct -{ - spriteframepivot_t pivot[64]; - boolean available; -} spriteinfo_t; - -// Conversions between patches / flats / textures... -boolean R_CheckIfPatch(lumpnum_t lump); -void R_TextureToFlat(size_t tex, UINT8 *flat); -void R_PatchToFlat(patch_t *patch, UINT8 *flat); -void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip); -patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); -patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); - -// SpriteInfo -extern spriteinfo_t spriteinfo[NUMSPRITES]; -void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps); -void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); - -// Sprite rotation -#ifdef ROTSPRITE -INT32 R_GetRollAngle(angle_t rollangle); -patch_t *Patch_GetRotatedSprite( - spriteframe_t *sprite, - size_t frame, size_t spriteangle, - boolean flip, void *info, - INT32 rotationangle); -rotsprite_t *RotatedPatch_Create(INT32 numangles); -void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, UINT8 flip); -//void R_FreeSkinRotSprite(size_t skinnum); -extern fixed_t rollcosang[ROTANGLES]; -extern fixed_t rollsinang[ROTANGLES]; -void R_FreeAllRotSprite(void); -#endif - -#endif // __R_PATCH__ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_patch.h +/// \brief Patch generation. + +#ifndef __R_PATCH__ +#define __R_PATCH__ + +#include "r_defs.h" +#include "doomdef.h" + +// Structs +typedef enum +{ + ROTAXIS_X, // Roll (the default) + ROTAXIS_Y, // Pitch + ROTAXIS_Z // Yaw +} rotaxis_t; + +typedef struct +{ + INT32 x, y; + rotaxis_t rotaxis; +} spriteframepivot_t; + +typedef struct +{ + spriteframepivot_t pivot[64]; + boolean available; +} spriteinfo_t; + +// Conversions between patches / flats / textures... +boolean R_CheckIfPatch(lumpnum_t lump); +void R_TextureToFlat(size_t tex, UINT8 *flat); +void R_PatchToFlat(patch_t *patch, UINT8 *flat); +void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip); +patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); +patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); + +// SpriteInfo +extern spriteinfo_t spriteinfo[NUMSPRITES]; +void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps); +void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); + +// Sprite rotation +#ifdef ROTSPRITE +INT32 R_GetRollAngle(angle_t rollangle); +patch_t *Patch_GetRotatedSprite( + spriteframe_t *sprite, + size_t frame, size_t spriteangle, + boolean flip, boolean adjustfeet, + void *info, INT32 rotationangle); +rotsprite_t *RotatedPatch_Create(INT32 numangles); +void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip); + +extern fixed_t rollcosang[ROTANGLES]; +extern fixed_t rollsinang[ROTANGLES]; +#endif + +#endif // __R_PATCH__ diff --git a/src/r_things.c b/src/r_things.c index 26dad2f0b..66c583259 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1373,7 +1373,7 @@ static void R_ProjectSprite(mobj_t *thing) rollsum = (thing->rollangle) + (thing->sloperoll); rollangle = R_GetRollAngle(rollsum); - rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle); + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); if (rotsprite != NULL) { -- 2.54.0 From 35cfdea9e71209e1987435a6c1284295035232e2 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Mon, 11 Sep 2023 15:55:59 +0200 Subject: [PATCH 23/28] allow opengl to also use widescreen backgrounds for votes thanks kk for locking this to software mode only despite this working without issues in opengl aswell --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index bda60dde2..c20ef30e3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1104,7 +1104,7 @@ void Y_VoteDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) { + if (widebgpatch && vid.width / vid.dupx > 320) { if(foundAnimVoteWideFrames == 0){ V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), -- 2.54.0 From 4455ebe58f08fdeb95da06efe639986c9e8eeafd Mon Sep 17 00:00:00 2001 From: hayaunderscore Date: Sat, 2 Sep 2023 13:07:13 +0800 Subject: [PATCH 24/28] Fix issue with upside-down salty hop --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7878a19b5..1ff3f031d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3100,7 +3100,7 @@ static void K_QuiteSaltyHop(player_t *p) p->mo->spriteyscale += (mos/8); p->mo->spritexscale -= (mos/8); } - p->mo->spriteyoffset = p->mo->salty_zoffset*P_MobjFlip(p->mo); + p->mo->spriteyoffset = p->mo->salty_zoffset; if (S_SoundPlaying(p->mo, sfx_screec)) S_StopSoundByID(p->mo, sfx_screec); if (S_SoundPlaying(p->mo, sfx_drift)) -- 2.54.0 From f91687209ba243be16db2aed532ed8ec3941f9dc Mon Sep 17 00:00:00 2001 From: hayaunderscore Date: Fri, 8 Sep 2023 10:15:57 +0800 Subject: [PATCH 25/28] fix horizon lines on batching somewhat --- src/hardware/hw_draw.c | 22 ++++---- src/hardware/hw_drv.h | 3 +- src/hardware/hw_main.c | 97 ++++++++++++++++++++++++++++---- src/hardware/r_opengl/r_opengl.c | 35 ++++++++---- 4 files changed, 123 insertions(+), 34 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 68aba1be0..8f94abbba 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -122,7 +122,7 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) flags |= PF_ForceWrapY; // clip it since it is used for bunny scroll in doom I - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, false); } void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap) @@ -300,10 +300,10 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; - HWD.pfnDrawPolygon(&Surf, v, 4, flags); + HWD.pfnDrawPolygon(&Surf, v, 4, flags, false); } else - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, false); } void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) @@ -454,10 +454,10 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; - HWD.pfnDrawPolygon(&Surf, v, 4, flags); + HWD.pfnDrawPolygon(&Surf, v, 4, flags, false); } else - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, false); } // ========================================================================== @@ -533,7 +533,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // BTW, I see we put 0 for PFs, and If I'm right, that // means we take the previous PFs as default // how can we be sure they are ok? - HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent); + HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest, false); //PF_Translucent); } @@ -570,7 +570,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) Surf.PolyColor.rgba = pLocalPalette[color].rgba; Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f); } - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, false); } // Draw the console background with translucency support @@ -597,7 +597,7 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) Surf.PolyColor.rgba = UINT2RGBA(color); Surf.PolyColor.s.alpha = 0x80; - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, false); } @@ -846,7 +846,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color) Surf.PolyColor = V_GetColor(color); HWD.pfnDrawPolygon(&Surf, v, 4, - PF_Modulated|PF_NoTexture|PF_NoDepthTest); + PF_Modulated|PF_NoTexture|PF_NoDepthTest, false); } // -------------------+ @@ -954,7 +954,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 Surf.PolyColor.rgba = UINT2RGBA(color); Surf.PolyColor.s.alpha = 0x80; - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, false); } // -----------------+ @@ -1062,7 +1062,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) Surf.PolyColor = V_GetColor(color); HWD.pfnDrawPolygon(&Surf, v, 4, - PF_Modulated|PF_NoTexture|PF_NoDepthTest); + PF_Modulated|PF_NoTexture|PF_NoDepthTest, false); } #ifdef HAVE_PNG diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index c7786670a..204c79dc1 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -21,6 +21,7 @@ #include "hw_md2.h" #include "hw_dll.h" +#include "../doomdef.h" // ========================================================================== // STANDARD DLL EXPORTS @@ -34,7 +35,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma); #endif EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, boolean horizonSpecial); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FBOOLEAN StencilMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index aa9a921e2..07f74f6a5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -725,7 +725,80 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei else HWD.pfnSetShader(1); // floor shader - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); + HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, false); + + if (subsector) + { + // Horizon lines + FOutVector horizonpts[6]; + float dist, vx, vy; + float x1, y1, xd, yd; + UINT8 numplanes, j; + vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion; + + const float renderdist = 27000.0f; // How far out to properly render the plane + const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion + + seg_t *line = &segs[subsector->firstline]; + + for (i = 0; i < subsector->numlines; i++, line++) + { + if (line->linedef->special == 41 && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0) + { + P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); + dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); + + x1 = ((polyvertex_t *)line->pv1)->x; + y1 = ((polyvertex_t *)line->pv1)->y; + xd = ((polyvertex_t *)line->pv2)->x - x1; + yd = ((polyvertex_t *)line->pv2)->y - y1; + + // Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion + dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f; + if (dist > 100.0f) + numplanes = 100; + else + numplanes = (UINT8)dist + 1; + + for (j = 0; j < numplanes; j++) + { + // Left side + vx = x1 + xd * j / numplanes; + vy = y1 + yd * j / numplanes; + SETUP3DVERT((&horizonpts[1]), vx, vy); + + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[0]), vx, vy); + + // Right side + vx = x1 + xd * (j+1) / numplanes; + vy = y1 + yd * (j+1) / numplanes; + SETUP3DVERT((&horizonpts[2]), vx, vy); + + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[3]), vx, vy); + + // Horizon fills + vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + SETUP3DVERT((&horizonpts[5]), vx, vy); + horizonpts[5].y = gr_viewz; + + vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + SETUP3DVERT((&horizonpts[4]), vx, vy); + horizonpts[4].y = gr_viewz; + + // Draw + HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags, true); + } + } + } + } } #ifdef WALLSPLATS @@ -789,7 +862,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) } HWD.pfnSetShader(2); // wall shader - HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal); + HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal, false); } } #endif @@ -831,7 +904,7 @@ void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend blendmode &= ~PF_Masked; } - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude); + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, false); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -1125,7 +1198,7 @@ void HWR_DrawSkyWallList() HWD.pfnUnSetShader(); for (i = 0; i < skyWallVertexArraySize; i++) { - HWD.pfnDrawPolygon(&surf, skyWallVertexArray + i * 4, 4, PF_Occlude|PF_Invisible|PF_NoTexture); + HWD.pfnDrawPolygon(&surf, skyWallVertexArray + i * 4, 4, PF_Occlude|PF_Invisible|PF_NoTexture, false); } } @@ -2951,7 +3024,7 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t blendmode |= PF_Masked|PF_Modulated; HWD.pfnSetShader(1); // floor shader - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode); + HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, false); } void HWR_AddPolyObjectPlanes(void) @@ -3750,7 +3823,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t { sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4); HWD.pfnSetShader(1); // floor shader - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated); + HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated, false); } } @@ -4117,7 +4190,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false); top = bot; #ifdef ESLOPE @@ -4157,7 +4230,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false); } // -----------------+ @@ -4310,7 +4383,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) } HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false); } } @@ -4404,7 +4477,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) } HWD.pfnSetShader(3); // sprite shader - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false); } // -------------------------------------------------------------------------- @@ -6027,7 +6100,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode); + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode, false); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -6078,7 +6151,7 @@ void HWR_DoPostProcessor(player_t *player) Surf.PolyColor.s.alpha = 0xc0; // match software mode - HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest, false); } if (!cv_grscreentextures.value) // screen textures are needed for the rest of the effects diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d1690e9ee..8f740dd1b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1822,6 +1822,8 @@ typedef struct FBITFIELD polyFlags; GLuint texNum; GLuint shader; + // this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls + boolean horizonSpecial; } PolygonArrayEntry; FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu @@ -1861,21 +1863,27 @@ EXPORT void HWRAPI(StartBatching) (void) static int comparePolygons(const void *p1, const void *p2) { - PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; - PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; + unsigned int index1 = *(const unsigned int*)p1; + unsigned int index2 = *(const unsigned int*)p2; + PolygonArrayEntry* poly1 = &polygonArray[index1]; + PolygonArrayEntry* poly2 = &polygonArray[index2]; int diff; INT64 diff64; int shader1 = poly1->shader; int shader2 = poly2->shader; - // make skywalls first in order - if (poly1->polyFlags & PF_NoTexture) + // make skywalls and horizon lines first in order + if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) shader1 = -1; - if (poly2->polyFlags & PF_NoTexture) + if (poly2->polyFlags & PF_NoTexture || poly1->horizonSpecial) shader2 = -1; diff = shader1 - shader2; if (diff != 0) return diff; + // skywalls and horizon lines must retain their order for horizon lines to work + if (shader1 == -1 && shader2 == -1) + return index1 - index2; + diff = poly1->texNum - poly2->texNum; if (diff != 0) return diff; @@ -1899,20 +1907,26 @@ static int comparePolygons(const void *p1, const void *p2) static int comparePolygonsNoShaders(const void *p1, const void *p2) { - PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; - PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; + unsigned int index1 = *(const unsigned int*)p1; + unsigned int index2 = *(const unsigned int*)p2; + PolygonArrayEntry* poly1 = &polygonArray[index1]; + PolygonArrayEntry* poly2 = &polygonArray[index2]; int diff; INT64 diff64; GLuint texNum1 = poly1->texNum; GLuint texNum2 = poly2->texNum; - if (poly1->polyFlags & PF_NoTexture) + if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) texNum1 = 0; - if (poly2->polyFlags & PF_NoTexture) + if (poly2->polyFlags & PF_NoTexture || poly1->horizonSpecial) texNum2 = 0; diff = texNum1 - texNum2; if (diff != 0) return diff; + // skywalls and horizon lines must retain their order for horizon lines to work + if (texNum1 == 0 && texNum2 == 0) + return index1 - index2; + diff = poly1->polyFlags - poly2->polyFlags; if (diff != 0) return diff; @@ -2269,7 +2283,7 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i // -----------------+ // DrawPolygon : Render a polygon, set the texture, set render mode // -----------------+ -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, boolean horizonSpecial) { if (gl_batching) { @@ -2309,6 +2323,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI polygonArray[polygonArraySize].polyFlags = PolyFlags; polygonArray[polygonArraySize].texNum = tex_downloaded; polygonArray[polygonArraySize].shader = gl_currentshaderprogram; + polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; polygonArraySize++; memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector)); -- 2.54.0 From dd4a9ae8909df63cc538e9f701728dd489ec000f Mon Sep 17 00:00:00 2001 From: haya <126386046+hayaunderscore@users.noreply.github.com> Date: Fri, 8 Sep 2023 10:24:37 +0800 Subject: [PATCH 26/28] i may be stupid --- src/hardware/r_opengl/r_opengl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 8f740dd1b..b0c6ec8f6 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1875,7 +1875,7 @@ static int comparePolygons(const void *p1, const void *p2) // make skywalls and horizon lines first in order if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) shader1 = -1; - if (poly2->polyFlags & PF_NoTexture || poly1->horizonSpecial) + if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) shader2 = -1; diff = shader1 - shader2; if (diff != 0) return diff; @@ -1918,7 +1918,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2) GLuint texNum2 = poly2->texNum; if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) texNum1 = 0; - if (poly2->polyFlags & PF_NoTexture || poly1->horizonSpecial) + if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) texNum2 = 0; diff = texNum1 - texNum2; if (diff != 0) return diff; -- 2.54.0 From b6ef6eb8018a383fe27189755fcc2836ea4d7df9 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Tue, 12 Sep 2023 21:03:58 +0200 Subject: [PATCH 27/28] revert sloped midtexture fix for now huge performance regression on some maps ill look into it in the future again maybe --- src/hardware/hw_main.c | 148 +++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 58 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 07f74f6a5..66adf3522 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -951,9 +951,6 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa pegb = wallVerts[0].t; pegmul = (pegb - pegt) / (top - bot); - if (fpclassify(pegmul) == FP_NAN) - pegmul = 0.0; - #ifdef ESLOPE endrealtop = endtop = wallVerts[2].y; endrealbot = endbot = wallVerts[1].y; @@ -962,8 +959,6 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa endpegmul = (endpegb - endpegt) / (endtop - endbot); #endif - if (fpclassify(endpegmul) == FP_NAN) - endpegmul = 0.0; for (i = 0; i < sector->numlights; i++) { @@ -1074,10 +1069,24 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa } #endif - // Found a break - bot = min(max(bheight, realbot), top); - endbot = min(max(endbheight, endrealbot), endtop); +#ifdef ESLOPE + if (endbheight >= endtop) +#endif + if (bheight >= top) + continue; + //Found a break; + bot = bheight; + + if (bot < realbot) + bot = realbot; + +#ifdef ESLOPE + endbot = endbheight; + + if (endbot < endrealbot) + endbot = endrealbot; +#endif Surf->PolyColor.s.alpha = alpha; #ifdef ESLOPE @@ -1671,7 +1680,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture || gr_portal == GRPORTAL_STENCIL || gr_portal == GRPORTAL_DEPTH || gl_drawing_stencil) { + FBITFIELD blendmode; sector_t *front, *back; + fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; + fixed_t texturevpeg = 0; INT32 repeats; if (gr_linedef->frontsector->heightsec != -1) @@ -1707,10 +1719,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else repeats = 1; - fixed_t midtexheight = textureheight[gr_midtexture] * repeats; - fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; - fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; - // SoM: a little note: This code re-arranging will // fix the bug in Nimrod map02. popentop and popenbottom // record the limits the texture can be displayed in. @@ -1724,8 +1732,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // From CB if (gr_curline->polyseg) { - popentop = popentopslope = back->ceilingheight; - popenbottom = popenbottomslope = back->floorheight; + popentop = back->ceilingheight; + popenbottom = back->floorheight; } else #endif @@ -1733,9 +1741,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom #ifdef ESLOPE popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); - - popentopslope = min(worldtopslope, worldhighslope); - popenbottomslope = max(worldbottomslope, worldlowslope); +#else + popentop = min(front->ceilingheight, back->ceilingheight); + popenbottom = max(front->floorheight, back->floorheight); +#endif } #ifdef ESLOPE @@ -1744,16 +1753,12 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) { polybottom = max(front->floorheight, back->floorheight) + gr_sidedef->rowoffset; - polybottomslope = polybottom; - polytop = polybottom + midtexheight; - polytopslope = polytop; + polytop = polybottom + textureheight[gr_midtexture]*repeats; } else { polytop = min(front->ceilingheight, back->ceilingheight) + gr_sidedef->rowoffset; - polytopslope = polytop; - polybottom = polytop - midtexheight; - polybottomslope = polybottom; + polybottom = polytop - textureheight[gr_midtexture]*repeats; } } else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) @@ -1762,17 +1767,12 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom #endif { polybottom = popenbottom + gr_sidedef->rowoffset; - polytop = polybottom + midtexheight; - polybottomslope = popenbottomslope + gr_sidedef->rowoffset; - polytopslope = polybottomslope + midtexheight; + polytop = polybottom + textureheight[gr_midtexture]*repeats; } else { polytop = popentop + gr_sidedef->rowoffset; polybottom = polytop - textureheight[gr_midtexture]*repeats; - polybottom = polytop - midtexheight; - polytopslope = popentopslope + gr_sidedef->rowoffset; - polybottomslope = polytopslope - midtexheight; } // CB @@ -1783,8 +1783,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { lowcut = polybottom; highcut = polytop; - lowcutslope = polybottomslope; - highcutslope = polytopslope; } #endif else @@ -1792,49 +1790,83 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector lowcut = popenbottom; highcut = popentop; - lowcutslope = popenbottomslope; - highcutslope = popentopslope; } h = min(highcut, polytop); l = max(polybottom, lowcut); - hS = min(highcutslope, polytopslope); - lS = max(polybottomslope, lowcutslope); - // PEGGING - fixed_t texturevpeg, texturevpegslope; - - if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) { - texturevpeg = midtexheight - h + polybottom; - texturevpegslope = midtexheight - hS + polybottomslope; - } - else - { - texturevpeg = polytop - h; - texturevpegslope = polytopslope - hS; - } + // PEGGING +#ifdef ESLOPE + if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) +#else + if (gr_linedef->flags & ML_DONTPEGBOTTOM) +#endif + texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom; + else + texturevpeg = polytop - h; grTex = HWR_GetTexture(gr_midtexture); - wallVerts[3].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[2].t = texturevpegslope * grTex->scaleY; - wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + } // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past // where the polygon might not be. - wallVerts[3].y = FIXED_TO_FLOAT(h); - wallVerts[0].y = FIXED_TO_FLOAT(l); - wallVerts[2].y = FIXED_TO_FLOAT(hS); - wallVerts[1].y = FIXED_TO_FLOAT(lS); + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h); + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l); + +#ifdef ESLOPE + // Correct to account for slopes + { + fixed_t midtextureslant; + + if (gr_linedef->flags & ML_EFFECT2) + midtextureslant = 0; + else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) + midtextureslant = worldlow < worldbottom + ? worldbottomslope-worldbottom + : worldlowslope-worldlow; + else + midtextureslant = worldtop < worldhigh + ? worldtopslope-worldtop + : worldhighslope-worldhigh; + + polytop += midtextureslant; + polybottom += midtextureslant; + + highcut += worldtop < worldhigh + ? worldtopslope-worldtop + : worldhighslope-worldhigh; + lowcut += worldlow < worldbottom + ? worldbottomslope-worldbottom + : worldlowslope-worldlow; + + // Texture stuff + h = min(highcut, polytop); + l = max(polybottom, lowcut); + + { + // PEGGING + if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) + texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom; + else + texturevpeg = polytop - h; + wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; + } + + wallVerts[2].y = FIXED_TO_FLOAT(h); + wallVerts[1].y = FIXED_TO_FLOAT(l); + } #endif // set alpha for transparent walls (new boom and legacy linedef types) - FBITFIELD blendmode; + // ooops ! this do not work at all because render order we should render it in backtofront order switch (gr_linedef->special) { -- 2.54.0 From 538de7d2d2b439331949320a31a99bc8ca37b041 Mon Sep 17 00:00:00 2001 From: lug420 Date: Wed, 13 Sep 2023 04:42:35 +0200 Subject: [PATCH 28/28] fix memfree command on 64bit --- src/android/i_system.c | 2 +- src/dummy/i_system.c | 2 +- src/i_system.h | 2 +- src/sdl/i_system.c | 13 ++++++------- src/z_zone.c | 10 +++++----- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index 51a96d93a..c0b49a886 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -24,7 +24,7 @@ static INT64 start_time; // as microseconds since the epoch // I should probably return how much memory is remaining // for this process, considering Android's process memory limit. -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { // what the heck? sysinfo() is partially missing in bionic? /* struct sysinfo si; */ diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 1696672b8..cf8144b90 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -5,7 +5,7 @@ UINT8 graphics_started = 0; UINT8 keyboard_started = 0; -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { *total = 0; return 0; diff --git a/src/i_system.h b/src/i_system.h index 89ea1ae2d..05826c79e 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -40,7 +40,7 @@ extern UINT8 keyboard_started; \return free memory in the system */ -UINT32 I_GetFreeMem(UINT32 *total); +size_t I_GetFreeMem(size_t *total); /** \brief Returns precise time value for performance measurement. The precise time should be a monotonically increasing counter, and will wrap. diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 5b76edddf..d1add12b4 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3806,8 +3806,7 @@ static long get_entry(const char* name, const char* buf) } #endif -// quick fix for compil -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { #ifdef FREEBSD struct vmmeter sum; @@ -3855,8 +3854,8 @@ UINT32 I_GetFreeMem(UINT32 *total) info.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus( &info ); if (total) - *total = (UINT32)info.dwTotalPhys; - return (UINT32)info.dwAvailPhys; + *total = (size_t)info.dwTotalPhys; + return (size_t)info.dwAvailPhys; #elif defined (__OS2__) UINT32 pr_arena; @@ -3871,8 +3870,8 @@ UINT32 I_GetFreeMem(UINT32 *total) /* Linux */ char buf[1024]; char *memTag; - UINT32 freeKBytes; - UINT32 totalKBytes; + size_t freeKBytes; + size_t totalKBytes; INT32 n; INT32 meminfo_fd = -1; long Cached; @@ -3903,7 +3902,7 @@ UINT32 I_GetFreeMem(UINT32 *total) } memTag += sizeof (MEMTOTAL); - totalKBytes = atoi(memTag); + totalKBytes = (size_t)atoi(memTag); if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL) { diff --git a/src/z_zone.c b/src/z_zone.c index 199eefd08..1eb9ba42e 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -140,14 +140,14 @@ static void Command_Memdump_f(void); void Z_Init(void) { - UINT32 total, memfree; + size_t total, memfree; memset(&head, 0x00, sizeof(head)); head.next = head.prev = &head; memfree = I_GetFreeMem(&total)>>20; - CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); + CONS_Printf("System memory: %sMB - Free: %sMB\n", sizeu1(total>>20), sizeu2(memfree)); // Note: This allocates memory. Watch out. COM_AddCommand("memfree", Command_Memfree_f); @@ -616,7 +616,7 @@ size_t Z_TagUsage(INT32 tagnum) void Command_Memfree_f(void) { - UINT32 freebytes, totalbytes; + size_t freebytes, totalbytes; Z_CheckHeap(-1); CONS_Printf("\x82%s", M_GetText("Memory Info\n")); @@ -644,8 +644,8 @@ void Command_Memfree_f(void) CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); freebytes = I_GetFreeMem(&totalbytes); - CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); - CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); + CONS_Printf(M_GetText(" Total physical memory: %s KB\n"), sizeu1(totalbytes>>10)); + CONS_Printf(M_GetText("Available physical memory: %s KB\n"), sizeu1(freebytes>>10)); } #ifdef ZDEBUG -- 2.54.0