From c4ff1a3acabf6fd4c65d35eebaa3bf89d79c3bb0 Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Fri, 1 Sep 2023 10:12:06 +0200 Subject: [PATCH 01/21] 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 2c1201ff34f28d9c4fd9ee585f4fc5ba1e60e9d4 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 1 Sep 2023 12:45:23 +0300 Subject: [PATCH 02/21] Add mo.rollsum and player.sliproll fields. Rendering and frame interpolation code was used, so they are NOT synch safe! --- src/lua_mobjlib.c | 31 ++++++++++++++++++++++++++ src/lua_playerlib.c | 16 ++++++++++++++ src/r_defs.h | 1 + src/r_main.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ src/r_main.h | 1 + 5 files changed, 103 insertions(+) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 91c2158e8..22cb0f00a 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -16,6 +16,7 @@ #ifdef HAVE_BLUA #include "fastcmp.h" #include "r_things.h" +#include "r_main.h" #include "p_local.h" #include "g_game.h" #include "p_setup.h" @@ -65,6 +66,8 @@ int mobj_mobjnum_unimplemented(lua_State *L); int mobj_scale_setter(lua_State *L); int mobj_destscale_setter(lua_State *L); int mobj_standingslope_noset(lua_State *L); +int mobj_rollsum_getter(lua_State *L); +int mobj_rollsum_noset(lua_State *L); static const char *const array_opt[] ={"iterate",NULL}; @@ -78,6 +81,8 @@ static const udata_field_t mobj_fields[] = { FIELD(mobj_t, angle, udatalib_getter_angle, mobj_angle_setter), FIELD(mobj_t, rollangle, udatalib_getter_angle, udatalib_setter_angle), FIELD(mobj_t, sloperoll, udatalib_getter_angle, mobj_sloperoll_noop), + // Macro fails here + { "rollsum", 0, mobj_rollsum_getter, mobj_rollsum_noset }, FIELD(mobj_t, sprite, udatalib_getter_spritenum, udatalib_setter_spritenum), FIELD(mobj_t, frame, udatalib_getter_uint32, udatalib_setter_uint32), FIELD(mobj_t, anim_duration, udatalib_getter_uint16, udatalib_setter_uint16), @@ -174,13 +179,21 @@ int mobj_ ## field ## _noset(lua_State *L) \ return luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", #field); \ } +#define NOSET_USE(field, use) \ +int mobj_ ## field ## _noset(lua_State *L) \ +{ \ + return luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL(use) " instead.", #field); \ +} + NOSET(snext) NOSET(bnext) NOSET(info) NOSET(player) NOSET(standingslope) +NOSET_USE(rollsum, "rollangle") #undef NOSET +#undef NOSET_USE // Unimplemented fields (why would you need to set them like that explicitly? // No idea, i'm keeping it for synch reasons) @@ -539,6 +552,24 @@ int mobj_destscale_setter(lua_State *L) return 0; } +// WARNING: Not synch safe! +// Don't use this field in game logic code! +int mobj_rollsum_getter(lua_State *L) +{ + mobj_t *mo = GETMO(); + + angle_t rollsum = mo->rollangle + cv_sloperoll.value ? mo->sloperoll : 0; + + if (mo->player) + { + rollsum += R_PlayerSliptideAngle(mo->player); + } + + lua_pushangle(L, rollsum); + + return 1; +} + static int mobj_get(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c687921ec..8ce7840f3 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -13,6 +13,7 @@ #include "doomdef.h" #ifdef HAVE_BLUA #include "fastcmp.h" +#include "r_main.h" #include "p_mobj.h" #include "d_player.h" #include "g_game.h" @@ -44,6 +45,10 @@ int player_splitscreenindex_noset(lua_State *L); int player_ping_getter(lua_State *L); int player_ping_noset(lua_State *L); +// Non synch safe! +int player_sliproll_getter(lua_State *L); +int player_sliproll_noset(lua_State *L); + #define FIELD(type, field_name, getter, setter) { #field_name, offsetof(type, field_name), getter, setter } static const udata_field_t player_fields[] = { // Player doesn't actually have field "name" so macro fails. Need to declare field manually. @@ -150,6 +155,7 @@ static const udata_field_t player_fields[] = { FIELD(player_t, fovadd, udatalib_getter_fixed, udatalib_setter_fixed), // Mmm yeah thats definitely synch safe #endif // Same as player.name + { "sliproll", 0, player_sliproll_getter, player_sliproll_noset }, { "ping", 0, player_ping_getter, player_ping_noset }, // Hmm originally setter doesn't exist so data is written as unreachable custom field... { NULL }, }; @@ -207,6 +213,7 @@ NOSET(kartstuff) NOSET(bot) NOSET(splitscreenindex) NOSET(ping) +NOSET(sliproll) #undef NOSET @@ -331,6 +338,15 @@ int player_ping_getter(lua_State *L) return 1; } +int player_sliproll_getter(lua_State *L) +{ + player_t *plr = GETPLAYER(); + + lua_pushangle(L, R_PlayerSliptideAngle(plr)); + + return 1; +} + static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; diff --git a/src/r_defs.h b/src/r_defs.h index 559e3646b..26a11a6c0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -19,6 +19,7 @@ // We rely on the thinker data struct to handle sound origins in sectors. #include "d_think.h" + // SECTORS do store MObjs anyway. #include "p_mobj.h" diff --git a/src/r_main.c b/src/r_main.c index dc914e79a..c381c9860 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -439,6 +439,60 @@ fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) return FixedHypot(px1 - px2, py1 - py2); } +angle_t R_PlayerSliptideAngle(player_t *player) +{ + mobj_t *mo = player->mo; + + if (!cv_sliptideroll.value || !mo || P_MobjWasRemoved(mo)) return 0; + + size_t rot = mo->frame&FF_FRAMEMASK; + boolean papersprite = (mo->frame & FF_PAPERSPRITE); + + spritedef_t *sprdef; + spriteframe_t *sprframe; + angle_t ang = 0; + + interpmobjstate_t interp = {0}; + + // Yes. + if (R_UsingFrameInterpolation() && !paused) + { + R_InterpolateMobjState(mo, rendertimefrac, &interp); + } + else + { + R_InterpolateMobjState(mo, FRACUNIT, &interp); + } + + if (mo->skin && mo->sprite == SPR_PLAY) + { + sprdef = &((skin_t *)mo->skin)->spritedef; + + if (rot >= sprdef->numframes) + sprdef = &sprites[mo->sprite]; + } + else + { + sprdef = &sprites[mo->sprite]; + } + + if (rot >= sprdef->numframes) + { + sprdef = &sprites[states[S_UNKNOWN].sprite]; + rot = states[S_UNKNOWN].frame&FF_FRAMEMASK; + } + + sprframe = &sprdef->spriteframes[rot]; + + // No sprite frame? I guess it is possible + if (!sprframe) return 0; + + if (sprframe->rotate != SRF_SINGLE || papersprite) + ang = R_PointToAngle(interp.x, interp.y) - interp.angle; + + return FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mo->player->sliproll*(mo->player->sliptidemem)); +} + // Little extra utility. Works in the same way as R_PointToAngle2 fixed_t R_PointToDist(fixed_t x, fixed_t y) { diff --git a/src/r_main.h b/src/r_main.h index 70adf1bb5..d6c966857 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -73,6 +73,7 @@ angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); fixed_t R_PointToDist(fixed_t x, fixed_t y); fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); +angle_t R_PlayerSliptideAngle(player_t *player); fixed_t R_ScaleFromGlobalAngle(angle_t visangle); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); -- 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 03/21] 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 3675fdd3613e0a378ac0642a564b0f41fde1912c Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Tue, 5 Sep 2023 09:13:12 +0200 Subject: [PATCH 04/21] 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 78d50e4c43f1e85af6ae54c23d28da05e0c8455e Mon Sep 17 00:00:00 2001 From: alufolie91 Date: Tue, 5 Sep 2023 23:01:03 +0200 Subject: [PATCH 05/21] 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 06/21] 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 07/21] 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 08/21] 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 09/21] 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 10/21] 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 11/21] 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 12/21] 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 a47aea4c9f01b411372b95d28dfc57866ef6bb55 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Sep 2023 18:29:05 +0300 Subject: [PATCH 13/21] Fix 'error in error handling' for cases when error happens in cvar.func right when cvar is registered --- src/lua_consolelib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index dc965851f..584fc2ef8 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -293,6 +293,8 @@ static void Lua_OnChange(void) //lua_settop(gL, 0); // Just in case... lua_pushcfunction(gL, LUA_GetErrorMessage); + int error_handler_i = abs_index(gL, -1); + // From CV_OnChange registry field, get the function for this cvar by name. lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange"); I_Assert(lua_istable(gL, -1)); @@ -304,7 +306,7 @@ static void Lua_OnChange(void) lua_getfield(gL, -1, cvname); // get consvar_t* userdata. lua_remove(gL, -2); // pop the CV_Vars table. - LUA_Call(gL, 1, 0, 1); // call function(cvar) + LUA_Call(gL, 1, 0, error_handler_i); // call function(cvar) lua_pop(gL, 2); // pop CV_OnChange table and error handler } -- 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 14/21] 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 4455ebe58f08fdeb95da06efe639986c9e8eeafd Mon Sep 17 00:00:00 2001 From: hayaunderscore Date: Sat, 2 Sep 2023 13:07:13 +0800 Subject: [PATCH 15/21] 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 16/21] 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 17/21] 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 18/21] 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 19/21] 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 From 679a8387c90c060875eef96440697652cf0e0ecf Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 14 Sep 2023 00:09:33 +0300 Subject: [PATCH 20/21] Add logo (WIP) --- logo.png | Bin 0 -> 4303 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logo.png diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2f84c3321152c32a77735b482f6c72c57d2c0d64 GIT binary patch literal 4303 zcmeHKeNfVO9R8uL*TcN6tSrN}U1nyi7he*?UM%Z2C6}nZh}9w(saTod3refYrB~jq z)H4-q^x`5V<3JOEiom6*y&Ezhtt=8mFcC#!U%0m2?sm67pudVcK6h~3eO{jD_dE|L zw!}oir+QC?APByBQ{?v$go;(qJb3Gxd5`sKSH%G3GqgLvk){_)JddYh3@A>9d zsCSUNyAgidH?HPBzH!sJv}uPs0?)Sw-mWUt>^wh+Z;V|qp#z@ixrz0=Y;r<(CS~_* zA#+B4>2SEUr*d|S4WTBBVW7pQ*T;5&^w-|J>2w=qRZ|UZo%ZdEMyko6$r4Jo(%sXu z5AGbd=H+IqUi!}!c&p>&)5N#LBm_8-C31~Bv}TPHr8?FE;W%ygHC0vFthsz<-6Vq)bektmR1HI7O=kT8#%EtupYLX_mD2U7mW+W}Fl zYCAZnAw}?b$pBY+5ZgRL%H0~CLu__}NB?jTFp6H5xvFUqBemhIlw0(YloY1WXBLhO zuvDYlN`%k*6}@sKGeSG~IX(H+^Gh5lm({bYpe!XVo05zt2LjGf`AU*kgL2RH#j2bj zkv~Hjg{y`^zP`?udo{E*Cji$St22_8B=kR!=QV6?rXYqpIxlM-$eucW)CYI%y2>IM zQ$qX@YcS^;1!0rL=m*%^TKw_=o016DN@`53D;&X{Bo`9)8(j1N)Jp#cPapUsRP&3} zeqqEFHNiadqPmZVc{))UX;7DLxo}SK@(966=fJx`lQubj@ zidf;V5)@~@B4ACYIApdKf9N53sM`-p*;_$wC5A3yDEsDy2?a<-ExuwScnYMcPttNqFHT^n=<%noz{3JfkVlQ$Lq~we5z@L(!Non?JO{=;gE`vD)P6p%`uaY z@{MBk`}NAWN} zM~mC{Ga+p`ZG1;U8#=FzYIV)y{jA0WYsT3Zq?$lKADodttfG*Z(BQt&QbPds$V7-v zr#o40!~!?qZIrAvXw74pNnsX?U>_^P^h$C$V+K9sH9)ynu8){sD8?&t*JmkQxf!dc znwptQ6R3Lpp?O!C)7gMN!RqB^lxrj?J%*Qp?7j1{Zu|Bk1zQaCk7wzz@wMto8Cj#J?Lq^#2 zU1O*$B7ZbVXxO5aLIH>7M!vT<80qlN z4`DJocUBfpCd64SeMq_aZ(*)AKruNdgGZ{ v2ZBUk8qOJ)7{bT)_vzEV_6yK&+{F#pEqxaiL6_<>!&{fCV^aF literal 0 HcmV?d00001 -- 2.54.0 From 8ee4fc2fa118d5fa19762185d82b0ca29def8af5 Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 14 Sep 2023 00:18:22 +0300 Subject: [PATCH 21/21] Oops used upscaled image >< --- logo.png | Bin 4303 -> 480 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/logo.png b/logo.png index 2f84c3321152c32a77735b482f6c72c57d2c0d64..a950aa51fd9dd2e47e679af9f3b68b5d8242d3c3 100644 GIT binary patch literal 480 zcmV<60U!Q}P)TmbIjG+B=<>t`j) zW-{5YGAmj8o+TtLAP9mW2!il`nGJclEb=CWh(mRZ))D-oDtf(KwDHfcTQ6q9)Q@5@ zM%XWqa9to*xQ@#Rz&GRVWD~x6enjoG;f-AMUI; z8_ObZOu_;5#1DZ?05BSHnXooYC7y^iVGR1jQ=-*V*t)lI{=W6b=9=gQxZ*qQkw!?k zN~np>51)7dMgu9)^Y~26>A@#{$YB%8p*qgU2x%bJ%SGobn#01q#1k$PDi5IptLxpg zhGQ7A83Y?hl{gjFB}5e4EZLZYXt0000go;(qJb3Gxd5`sKSH%G3GqgLvk){_)JddYh3@A>9d zsCSUNyAgidH?HPBzH!sJv}uPs0?)Sw-mWUt>^wh+Z;V|qp#z@ixrz0=Y;r<(CS~_* zA#+B4>2SEUr*d|S4WTBBVW7pQ*T;5&^w-|J>2w=qRZ|UZo%ZdEMyko6$r4Jo(%sXu z5AGbd=H+IqUi!}!c&p>&)5N#LBm_8-C31~Bv}TPHr8?FE;W%ygHC0vFthsz<-6Vq)bektmR1HI7O=kT8#%EtupYLX_mD2U7mW+W}Fl zYCAZnAw}?b$pBY+5ZgRL%H0~CLu__}NB?jTFp6H5xvFUqBemhIlw0(YloY1WXBLhO zuvDYlN`%k*6}@sKGeSG~IX(H+^Gh5lm({bYpe!XVo05zt2LjGf`AU*kgL2RH#j2bj zkv~Hjg{y`^zP`?udo{E*Cji$St22_8B=kR!=QV6?rXYqpIxlM-$eucW)CYI%y2>IM zQ$qX@YcS^;1!0rL=m*%^TKw_=o016DN@`53D;&X{Bo`9)8(j1N)Jp#cPapUsRP&3} zeqqEFHNiadqPmZVc{))UX;7DLxo}SK@(966=fJx`lQubj@ zidf;V5)@~@B4ACYIApdKf9N53sM`-p*;_$wC5A3yDEsDy2?a<-ExuwScnYMcPttNqFHT^n=<%noz{3JfkVlQ$Lq~we5z@L(!Non?JO{=;gE`vD)P6p%`uaY z@{MBk`}NAWN} zM~mC{Ga+p`ZG1;U8#=FzYIV)y{jA0WYsT3Zq?$lKADodttfG*Z(BQt&QbPds$V7-v zr#o40!~!?qZIrAvXw74pNnsX?U>_^P^h$C$V+K9sH9)ynu8){sD8?&t*JmkQxf!dc znwptQ6R3Lpp?O!C)7gMN!RqB^lxrj?J%*Qp?7j1{Zu|Bk1zQaCk7wzz@wMto8Cj#J?Lq^#2 zU1O*$B7ZbVXxO5aLIH>7M!vT<80qlN z4`DJocUBfpCd64SeMq_aZ(*)AKruNdgGZ{ v2ZBUk8qOJ)7{bT)_vzEV_6yK&+{F#pEqxaiL6_<>!&{fCV^aF -- 2.54.0